Disable SpreadsheetView cell selection via mouse/key events, but retain ability to scroll the view - controlsfx

I'm writing an Excel import wizard which loads a user's spreadsheet into a ControlsFX SpreadsheetView. The user can then identify the relevant columns (i.e., first and last name, etc.) to be imported into the app via a set of combo boxes. Each combo box contains a list of the available columns. When the user makes a choice in a combo box, the respective column is added to the selection model's range of selections.
Column selection should only be done via the combo boxes, and user clicks on cells in the spreadsheet view should be ignored (i.e, not change the selection model contents).
However, I cannot find a way to disable mouse clicks on cells or column headers. The solution to a related question about how to disable clicks on TableView doesn't provide a satisfactory answer: setMouseTransparent(true) essentially disables the entire view.
In my case, the user must be able to scroll the view in order to find relevant columns, since not all users of the app have structured their spreadsheet in the same column order and the column may not be visible without scrolling horizontally.
So to re-iterate: I need to consume mouse clicks on cells and column headers to prevent changing the column selections made using the combo boxes. How do I do this? (FYI: consuming mouse events on the spreadsheet view [setOnMousePressed|Released|Clicked(mEvent -> mEvent.consume()] has no effect.)

Actually, when you use the setOnMousePressed methods, you are adding an EventHandler.
EventHandler are happening in the later chain of bubbling event.
What you want is to add an EventFilter that will catch the event before the SpreadsheetView has it.
For example, I've made this :
spreadSheetView.addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
event.consume();
}
});
spreadSheetView.addEventFilter(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
event.consume();
}
});
spreadSheetView.addEventFilter(MouseEvent.MOUSE_RELEASED, new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
event.consume();
}
});
And it's working. Although I really don't know the side effect of such a manipulation..

Related

Windows Form Listview is not visually showing selected items

We have a tool that is being integrated into our application. We have some strict borders around us too in that we cannot modify the application except for our extensions. I have searched here, I've searched the internet, but cannot find any postings about this problem.
I have a Windows Form that contains a ListView and our user requires we create a checkbox to Select/Deselect all. I have the event handler for when the check box state changes and call the routine to set everything to Selected.
private void SelectAllEventHandler(object sender, EventArgs e)
{
ChangeState(RadCapListView, SelectAllRadcap.Checked);
}
private void ChangeState(SWF.ListView control, bool state)
{
if (control.CheckBoxes)
{
control.Items.OfType<SWF.ListViewItem>().ToList()
.ForEach(item => item.Checked = state);
}
else
{
control.Items.OfType<SWF.ListViewItem>().ToList()
.ForEach(item => item.Selected = state);
}
control.Refresh();
}
Going into debug mode all items are marked as selected.
Also at the control level SelectedItems is properly updated.
The issue is that visually the control just will not highlight the selected items like we have our WPF forms doing. As you can see in the code I also tried to refresh the control hoping that would show items selected, but no joy.
Has anyone solved this problem in getting selected items to display properly?
Thank!
Instead of using control.Refresh(), try control.Focus().

Why RecyclerView is not working setBackground function?

I tried many Times for setting backgroundColor on RecyclerView. but i try to scroll then background was removed.So I can fix backgroundColor in RecyclerView. Help me please.
Or I Want to change ForegroundColor.
My Issue Video
https://www.youtube.com/watch?v=C29qhPb44FE
I don't know the reason...
You need to first understand how RecyclerView works.
As you scroll through the cells, the views that gets out of the screen will be RECYCLED, and they will subsequently be reused to display the incoming views. Hence the name RecyclerView. This way, views will always be recycled and reused, thus saving memory.
What you need to do is something like this:
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
//mList and mSelectedObjects are array lists
View yourView = holder.itemView.findViewById(R.id.your_view);
Object object = mList.get(position);
yourView.setTag(object);
yourView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Object object = (Object) v.getTag();
if (mSelectedObjects.contains(object)) {
mSelectedObjects.remove(object);
v.setBackground(null);
} else {
mSelectedObjects.add(object);
v.setBackgroundColor(Color.GRAY);
}
}
});
}
If you set programmatically the background color. You have to set every time the normal color and the selected color.
RecyclerViews are reusing their views. When an item leaves the screen it will be reused to increase the performance of the recycler view.
In this case when one set programmatically a background color and the item leaves the screen. It will be reused in the new item and the background color is still the same as when the item has left the screen.

GWT: Event fired multiple times onClick

I need to get an event fired after clicking on a grid cell. It works but fires multiple events.
My Code:
private void gridClickHandler(final boolean cardDeterminer) {
gridClickHandler = new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
int cellIndex = view.getGrid().getCellForEvent(event)
.getCellIndex(); // get clicked cell of grid
if (cardDeterminer)
oasisCardRPC(cellIndex); //rpc based on clicked cell
else
desertCardRPC(cellIndex); //rpc based on clicked cell
}
};
view.getGrid().addClickHandler(gridClickHandler);
}
The method gridClickHandler is called in an onSuccess of a RPC and calls a new RPC using a boolean passed. (it works like this: click on some widget, when success then click on grid. Grid should only fire event, when this some widget was clicked directly before)
I don't know how to create a new ClickHandler only once for the grid and still make its clickHandler only fire events, when needed.
Thanks in advance!
Use a boolean : isClickHandlerAttached
Initially false, first time you add the clickhandler put it on true. Only attach if boolean is false.

JavaFX Toggle Group Change

i have a lot of Toggle Buttons! They are all in one toggle group, now i want to add a change listener! If there is one event one a toggle button in this group i want to have a event on the other buttons too!
How can i check that?
I made something like this, but it doesn't work very well:
triangleGroup.selectedToggleProperty().addListener(new ChangeListener<Toggle>()
{
#Override
public void changed(ObservableValue<? extends Toggle> arg0, Toggle arg1, Toggle arg2)
{
if (btnTriangle.getRotate() != iRotateCoord1)
{
closeTriangle();
}
}
});
So the triangleGroup represents my ToggleGroup! There i add a ChangeListener.... If there ia a Event, the current btnTriangle ( ToggleButton ) will close if it has not the rotate value like iRotate...
How can I get the Event when ever there is a Event on this Button Group or when ever there is a change...
Or is there a possibility to get all of the buttons that are in the Group?

Windows Phone 7: How to notify data is updated in ListBox?

I have above scenario: If user click on ListBox, it will either have sub items (again ListBox) or detail view.
So what i did currently is: Whenever user clicks any item, made a web call and filled up the same ListBox if clicked item is having further sub items.
Now, issue comes in picture:
Suppose i am in 4th screen (detail view),
Moved to the 3rd and 2nd screen with data maintained as stack (Its working fine, yes i am maintaining data in ObservableCollection<ObservableCollection<MyObjects>> so while moving back, i am fetching data from there)
Now, if i click any item in screen 2, it will open detail view for the screen 3 ListBox data.
Means that ListBox is not getting notified that we have filled data inside OnBackKeyPress()
FYI, i am filling up ListBox and WebBrowser in the same page., so my problem is that how do i notify ListBox once i filled up data from stack which i have maintained?
Yes i have also implemented INotifyPropertyChanged but don't know why its not working.
Please check my code:
ListBox and WebView screen: http://pastebin.com/K1G27Yji
RootPageItem class file with the implementation of INotifyPropertyChanged: http://pastebin.com/E0uqLtVG
sorry for pasting code in above way, i did as question is being long.
Problem:
How do i notify ListBox that data is changed from OnBackKeyPress?
And what is the behavior if you set:
listBox1.ItemsSource = null;
before
listBox1.ItemsSource = listRootPageItems;
This is just wrong architecture. Instead of reloading the same listbox, please add a single page for each screen. Share data between them inside the App class (internal static) and use the built in navigation stack for handling "going back". Don't override OnBackKeyPress for this purpose.
You will get your desired functionality for "free" with easier to maintain and use codebase.
Oops it was a silly mistake i made.
I forgot to set items[] array inside OnBackKeyPress() but was accessing while clicking item, hence its having items[] data of last step we moved in forward direction, it was executing the same data.
Now, i have just included a single line and it has solved my problem.
items = listRootPageItems.ToArray(); // resolution point
So final code of onBackKeyPress() is:
/**
* While moving back, taking data from stack and displayed inside the same ListBox
* */
protected override void OnBackKeyPress(CancelEventArgs e)
{
listBox1.Visibility = Visibility.Visible;
webBrowser1.Visibility = Visibility.Collapsed;
listBox1.SelectedIndex = -1;
if (dataStack.Count != 0)
{
listBox1.ItemsSource = null;
listRootPageItems = dataStack[dataStack.Count-1];
listBox1.ItemsSource = listRootPageItems;
items = listRootPageItems.ToArray(); // resolution point
dataStack.Remove(listRootPageItems);
e.Cancel = true;
}
}

Resources