Elegant solution for cyclical UI updates in JAVA - java

I was trying to create a new UI component for the user to specify an integer value in two ways: using either a scrollbar, or a textfield. I wanted this to be a single UI component from which I can call something like integerField.getValue() and have it return the current integer value represented by the component.
My problem is, a classic cyclical update situation: when the underlying integer value is changed using the scrollbar, the textfield value needs to be updated, which triggers another event that causes the scrollbar to update - cycle complete.
In other words, scrollbar.setValue()->component.setValue()->textField.setText()->component.valueChanged()->component.setValue()->scrollbar.setValue()
Now, I can prevent this by having the first item in this chain setting a boolean flag and the other items in the component checking the flag before responding to a value change event. However, I'm not convinced that's an elegant solution.
Anyone have any better ideas?
Thanks!

A technical solution to the problem would be to read your text field and the last update time then your slider and the last update time. On the firing of the event, you would read the most recently updated value and if the values match stop updating and reacting.

SpinSlider, seen here and here, may be a good choice. It combines a JSpinner and a JSlider so that each component's ChangeListener listens to the other's ChangeListener.

Related

Getting the selectionLayer.getSelectedCells() as empty but not always

When I select a cell and start typing any value it edits the cell.
But when I am sorting few columns(2 to 3) by default using this code below,
natTable.doCommand(new SortColumnCommand(sortHeaderLayer, i, true, sortColumn.getSortDirection()));
and then select cell and start typing for first time or maybe first few times it edits then it won't.
When I debug the code I found that I was getting the selected Cells as empty after few successful editing, and that happens randomly like sometimes after 1 or 2 or 4 .. successful editing, then the selected Cell becomes empty. The cell is selected and is clearly visible but still we get empty in the code.
ActivateEditorAction.run()
The above code is used for the Action for the cell editing on selection. In the else block of the synchronized block when we are checking for isSelectionAndTypedKeyValidForEditing(), there the selected cells is coming as empty, not always but once it starts coming as empty then it keeps on coming as empty all the time even though selection is visible on the table.
Code for the function isSelectionAndTypedKeyValidForEditing()
There are certain events that cause a selection clearing. By default sorting is causing such an event.
If you are using GlazedLists you should also be aware that there are multiple events that are fired in case of sorting. The GlazedListsEventLayer tries to squash those events to a single event, but for huge lists it can happen that still multiple events are fired if the time frame in which GlazedLists is firing events is longer than the squashing time.
Maybe you are hitting a concurrency issue somewhere. There is not enough information about your NatTable setup and too much custom code that overrides the default configuration.
Apart from this information it seems to be a quite specific issue that depends on your configuration and your custom code. And that seems to be much more complicated than to be solved easily via Stackoverflow. IMHO you need professional support in this area. Some project members offer sponsored support in that area.

JTextPane and undo manager style change

My situation: I have a JTextPane with its own syntax highlighting. I have it set so that when the user stops typing, it updates the style in the text using the setCharacterAttributes() method.
My Issue: When these updates to the style are not performed, the undo manager works as expected. But when I do use it, the undo manager counts those style changes as actual undo-able actions! Meaning hitting Ctrl+z (I have it bound to undo when pressed) it just un-colors the last character i typed. Rather than actually removing/undoing it.
How would I get it so undo-ing and redo-ing only affects text changes and not style/font changes in my StyledDocument?
Thank you.
It sounds like you need to make use of addEdit or the Significant attribute as explained by the UndoManager:
The UndoManager makes use of isSignificant to determine how many edits
should be undone or redone. The UndoManager will undo or redo all
insignificant edits (isSignificant returns false) between the
current edit and the last or next significant edit. addEdit and
replaceEdit can be used to treat multiple edits as a single edit,
returning false from isSignificant allows for treating can be used to
have many smaller edits undone or redone at once. Similar
functionality can also be done using the addEdit method.
Sources:
https://docs.oracle.com/javase/8/docs/api/javax/swing/undo/UndoableEdit.html

Listening for focus on specific JTextFields

I have a panel with multiple JTextFields. One field holds a coordinate value and when it gains focus it becomes set as an active text field singleton. This is done so that when the field loses focus due to the user clicking on the map, the field is still updated with coordinates.
I want to make the field stop updating with coordinates once focus has changed to another text field.
Right now, the only way I can achieve this is by disabling the active text field singleton when any other text field gains focus. This doesn't seem too elegant to me since I will have to add a focus listener to every new text field and then disable the active text field singleton.
With FocusGained and FocusLost you can just do: if (FocusLost from JTextfield) stop updating
(FYI: this is not actual code)
I was able to come up with a solution using the "getOppositeComponent" method on the FocusEvent. This lets me check the instance of the opposite component. If it is the map, I can keep the active text field singleton, if it is anything else, then I can remove it.

Java - Custom JSlider will not update

I have a custom component based on the JSlider. It's essentially the same thing only it has 2 thumbs, which I named a DualSlider.
I need to change the maximum value of the slider once in a while, so every time I do, I call updateUI to reflect this.
public void updateUI() {
this.setUI(new DualSliderUI(this));
this.updateLabelUIs();
}
However, the maximum value of the DualSlider when I try to use it is still set at the original value no matter how many times I try to change it while using my program. I can confirm with a few println statements that a new DualSliderUI is being made with the slider that has the new max value, but for whatever reason the original DualSliderUI I initialized the slider with is the one that is in use.
What other things do I have to make sure I do when I update a property so I can avoid this?
1) I can't see reason for usage updateUI() this should be done once time, only when you built this JSlider, never do that repeately
2) you have look at BoundedRangeModel, maybe

Interfering Keylisteners in java

I have a JXTree and I'd like to add searching to it this way:
As the user types, the model returns the matching elements of the tree and selects the first one of the set in the tree's view.
The problem is, that by default the JXTree has an other keylistener, that selects an element starting with the currently typed letter.
Sometimes the native listener fires last making the outcome wrong. What can be done to prevent this behavior? I don't want to remove the inherent listener because it has arrow based navigation... (Which I have to reimplement.)
I've already read this: Is the order in which KeyListeners will be called guaranteed?, but I don't think that I can create the proposed listener wrapper without great effort, since BasicTreeUI's Handler class is private.
That's not a feature of JXTree but JTree. Overriding JTree#getNextMatch() to always return null should disable the JTree selection on key press.

Categories

Resources