I'm working on a Task-Manager like application, where the whole backing list of a TableView gets replaced by the result of periodically running a command line program. I'm using setAll to set the table view to the newest items. It works, but it resets the selection in the view.
Interestingly, the blue focus bar does not move, but a very small outline is shown on the first item of the table view after it was updated with setAll. I guess this is how the selected index is rendered. When I use the arrow keys to navigate, the selection will jump periodically back to the first item of the list.
Does anybody know how to solve this problem?
I found a way to do it, but I'm sure there is a better way. I manually calculate the difference between the new and the previous state. Then I call the removeAll, and addAll methods respectively:
object PortBindingLock
private fun reloadBindings() {
synchronized(PortBindingLock) {
val previous = this.portBindings.toSet()
val current = processService.processPortBindings().toSet()
val toRemove = Sets.difference(previous, current)
val toAdd = Sets.difference(current, previous)
this.portBindings.removeAll(toRemove)
this.portBindings.addAll(toAdd)
}
}
Related
I have a cuttingOperationComboBox ComboBox and a method that changes items and value of this ComboBox:
public void changeGlass(Glass newGlass)
{
ObservableList<Operation> list = new FilteredList<Operation>(ProductGlassCuttingUI.this.operationsDB.getOperationsList(), operation -> operation.getOperationType().toString().equals("RE") &&
operation.getGlassThickness() == newGlass.getGlassThickness());
if(!list.contains(this.cuttingOperationComboBox.getValue()))
cuttingOperationComboBox.setValue(list.get(0));
cuttingOperationComboBox.setItems(list);
}
I also have change listener added to cuttingOperationComboBox.valueProperty().
It is fired first time by cuttingOperationComboBox.setValue(list.get(0)); and here everything is fine. But when cuttingOperationComboBox.setItems(list); fires change listener, newValue in it is null although list is not empty. Moreover it happens only when ComboBox is visible. Tobe more precise: cuttingOperationComboBox is displayed in TreeView as a part of TreeCell graphics. As long as tree view node containing combobox is collapsed everything is ok, but when i expand this node and combobox shows, the above problem appears.
Anybody know what i am doing wrong?
Whenever you call setItems() of a ComboBox (or other controls involving list of items), the ComboBox (or the respective control) will always clear all selection. I believe this is the behavior caused by the underlying selection model, and I believe it is the desired behavior for most use-cases.
Without knowing exactly what you are achieving, it's hard to give you an exact solution. If you simply want to retain the value after setting new list, then you might need to keep a copy of the old selection item, and then manually set it in after setItems(). If you don't want the ChangeListener to respond to setItems(), either check for null newValue in the listener, or keep a boolean flag somewhere that would tell the listener that the particular call was triggered by setItems().
How to disable unselecting Grid row in Vaadin 7, but with permission to select another row using keyboard or mouse click?
Grid grid = new Grid(container);
grid.setSelectionMode(Grid.SelectionMode.SINGLE);
For example this is possible for older Table component - SO answer. But I widely use Grid so I want use it also in this case.
I found one interesting solution, but unfortunately not perfect.
To prevent deselect row we could write a SelectionListener and put there some logic:
grid.setSelectionMode(Grid.SelectionMode.SINGLE);
grid.addSelectionListener(event -> {
Set<Object> selected = event.getSelected();
if (selected == null || selected.isEmpty()) {
Set<Object> removed = event.getRemoved();
removed.stream().filter(Objects::nonNull).forEach(someGrid::select);
}
});
So assuming single selection mode, if current selection is empty, then previous selected row should be selected again. But if current selection isn't empty it means that somebody select another row - this doesn't require any action.
It is cool but not enough - every click (selection) cause http call and network transmission. This is disadvantage.
In Vaadin 8 you may use:
grid.setSelectionMode(SINGLE);
((SingleSelectionModel) grid.getSelectionModel()).setDeselectAllowed(false);
I'm busy on a GUI application in Java in which I sometimes encounter IndexOutOfBoundsExceptions when a value is added to a jList.
The exception seems to occur when a value is selected, and then another is added. I have a listener for selection changes because something needs to happen when the user selects an index, but this event is fired when a new value is added as well. I use a custom ListModel that just extends AbstractListModel and overrides the necessary methods in a perfectly valid way.
Why does the selection change in the program when a value is added to the list? This is not visually represented.
Why does the jList allow selection of an index that is not really there?
I have used jList twice now (we've recently started doing GUI in school) and I've had the problem both times. First time I solved it by clearing selection before a value is added, but that's not a really good solution. I don't think this should be necessary.
I don't know why this occurs, I have no strange code or anything. In pseudo-code, this is what happens:
listmodel.addValue(object);
listmodel.fireIntervalAdded();
//selection event occurs
selectedObject = listmodel.getValueAt(list.getSelectedIndex()); //indexoutofboundsexception
//index = 5, size = 3 (for example) when there are 2 objects in list and first is selected.
I'm not providing more code right now because I think it's not really relevant. I think anyone that understands perfectly how a jList, its listmodel and its selectionmodel work, will understand what's wrong. Any help on this is appreciated.
The problem is most likely that you're calling fireIntervalAdded(this, 0, list.size()) when a single item is added to your list model. The signature is:
protected void fireIntervalAdded(Object source, int index0, int index1)
Note that index0 is the starting index of the added item and index1 is the ending index. Thus for a single item index0 should be the same as index1. When you call fireIntervalAdded with 0, list.size(), you are telling the JList that N items have been added, where N=list.size(). Thus the JList thinks there are more items than are in your list model.
The same goes for when you remove an item.
I'm attempting to create an Android game using AndEngine and have been having some successes. I'm trying to make a Target Tap clone which basically involves tapping a number of different targets on the screen to remove them (a bit like whack-a-mole).
It works perfectly with one target and I can quite easily tap on it to remove it. The problem is that when there is more than one target on the screen they don't always disappear but adding points and everything else that is supposed to happen when you hit one works.
I am removing the sprites in (as far as I know) the correct way which is to do it inside the runOnUpdateThread(...) block.
Game.runOnUpdateThread(new Runnable() {
#Override
public void run() {
// Loop through all targets and check validity
for (Iterator<Target> i = Game.this.mTargets.iterator(); i.hasNext();) {
Target t = i.next(); // Target extends Sprite
// If the target isn't valid, remove it from the scene and ArrayList
if (!t.isValid()) {
scene.unregisterTouchArea(t);
scene.detachChild(t);
Game.this.mTarget.remove(t);
}
}
}
Sorry this is a little brief but because I'm unsure about where the problem lies I don't know what code to supply. I'm currently unable to test it on a real device but was wondering if this is could simply be something to do with the emulator because as far as I can tell the code is correct and I've tried so many things. If you need any help helping me, just let me know!
Thanks
It looks like you're skipping in the ArrayList when you remove one. Say you're on targets(5) and it comes up invalid. It then removes the 5th element from the list and shifts everything from there on down one, so the old 6th is now 5th. Then when you loop back through, you hit next() right past the new 5th element.
Normally what I do in this case is either:
(a) Run through the list backwards, or
(b) set a boolean to true if I remove one, and check it before performing the next() function in the next iteration. Or, more likely..
(c) don't use iterators, and instead use the get() function, ie
for (int i=0;i<Game.this.mTarget.size();i++) {
Target t = Game.this.mTarget.get(i); // Target extends Sprite
// If the target isn't valid, remove it from the scene and ArrayList
if (!t.isValid()) {
scene.unregisterTouchArea(t);
scene.detachChild(t);
Game.this.mTarget.remove(t);
// Decrease i to keep in sync with the new list
i--;
}
}
I have a Jtable on which I called the method
table1.setAutoCreateRowSorter(true);.
So this works on well.
But I also have a methos in my JFrame class which is fired when i push a button. It gets the selected rows indexes using this code
int selectedRows[] = this.table1.getSelectedRows();.
And displays an edit window for the first row corresponding in the selected interval.
The problem is that if I don't click on column's headers (I mean i don't sorte them at all) my method works perfect. But when I sort the row, the indexes of the rows doesn't seems to change at all - thus resulting an edit window for the old row whicn was initially in that position before making any sort.
I am using JDK 6 could anyonw give ma a tip?
The underlying model does not change order. Only the view changes. You can read more about this in Sun's tutorial. You will need to use JTable.convertRowIndexToView() and JTable.convertRowIndexToModel().
You need to use convertRowIndexToView(int) and convertRowIndexToModel(int) to convert model (underlying data) indices and view indices.