Interfering Keylisteners in java - 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.

Related

Elegant solution for cyclical UI updates in 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.

Without extending JTree is there anyway to force the update of the model after changing an object in the tree?

I have a JTree that stores "ShipmentItem"s and the .toString() on them shows the quantity, then the name of the ShipmentItem. At some point I change the quantity of multiple items at once but the toString() doesn't refresh until I've actually clicked on that particular tree node. I don't want to have to extend JTree to use 'Property Fired' I just want to be able to refresh it so that it shows the update.
I tried jtree.setModel(tree.getModel()) this didn't seem to work at all.
When you change something to your TreeModel (which you do by adjusting the ShipmentItem objects) you must make sure your TreeModel fires the correct event. This will cause the JTree to repaint the correct part. If you for example started from the DefaultTreeModel, your extension should call nodeChanged when the object of the node has changed.
Note: you do not have to adjust the toString method for correct rendering. The concept you are looking for is a TreeCellRenderer (check the Swing tutorial for more information)

How to globally modify/access widget in GWT?

I just started yesterday using GWT, so maybe I'm not using the proper mechanism to solve that problem. So, I will try to explain exactly what I'm trying to do (with a simple problem) and 2 solutions I came up with to address that problem.
Problem:
Remember an index that can be updated via other widgets. Let's use focus to represent it.
[button 1]
[button 2] [button A]
[button 3]
The buttons [1..3] and [A] are not in the same class and need to find the element using the id using the DOM. The reason is that those 2 views needs to be orthogonal.
We can use up/down key to move the focus from button 1 to 3.
If we are on the buttons [1..3] and press right, we go to button A.
If we are on the button A and press left, we go to button previously focused.
What we want to do is save or set the focus index when pressing right.
Solution 1: Global variables
I'm not usually fond of global variables, but in some case it's handy. By using, for instance, a dictionary (Dictionary.getDictionary) defined globally in the javascript, I could save the current index in it using the "Focus Event" in that case.
So, in the key press event, when left would be fired, I would just read the value in the dictionary.
I haven't tested yet, but I think it should work.
Solution 2: Set the value with the Element
Element element = DOM.getElementById("button id A");
element.<setFocusLeftKey>("button id [1..3]");
Here what I would like to achieve is just in the "onFocus" Event, I would simply set the value of that button.
So is it possible to cast/find the object with the Element? I think that if there is no easy way, it's probably because it's not recommended.
Is there a simpler way/other method to achieve that?
So, any thought or solutions?
Thanks in advance.
P.S. I haven't found a better title for that, so if any suggestion, just put it in the comments and I'll update it.
Using ID is definitely not the suggested way to do this in GWT. You say you need this mechanism to keep your views orthogonal to one another. This is noble, but in GWT you would achieve by using another resource (an EventBus, implemented in SimpleEventBus) that hides the different components from one another. In fact, I would argue that looking up the element by ID strongly couples the two views and is smelly.
Armed your EventBus you simply create and fire custom events that let the views (or, better, their presenters) communcate with one another. For example here you could have: NavigateRightFromButtonsEvent and NavigagteLeftFromButtonA event.
However, depending on the size of your app (or as a first experiment) you could decide to couple your two views. In this case simply pass the view for the button list into the one for button A and vice-versa. This is not really worse than relying on a global ID.
No matter which mechanism you choose (event bus or wiring the views together), you should now have access directly to the instance of the widget you want to highlight. To focus, just call setFocus(true) on it.

Show/Hide JMenuItems in a JPopupMenu based on a JTree's selection

I have a JTree which displays a JPopupMenu when I right click nodes in the JTree. What is the best way to hide/show or enable/disable certain JMenuItems in my JPopupMenu based on the node selected in the JTree?
The first solution that came to mind was to add a TreeSelectionListener to the JTree for the 'value changed' event. In the event handling code I would use the TreeSelectionEvent's getNewLeadSelectionPath() method to get the path of the most recent selection, and use the resulting TreePath object's getLastPathComponent() to get the selected node. From here I would have a series of IF statements that access my JPopupMenu object and perform the modifications necessary to hide/show specific JMenuItems.
However, something feels off about this, and so I decided I would ask SO if there was a better approach.
The way that I chose to tackle this within my own app was to use the "userObject" property of the DefaultMutableTreeNode class which allows you to just store any data you want along with your node. I have a variety of types of things that extend from an abstract base class which defines a "createPopupMenu()" method. Then, in the selection listener (just as you described in your question) I get the user object and ask it to create a popup menu appropriate for the selected object and display that.
Getting the selected tree node is straight forward and should work as you described it. To modify the popup menu I would recommend using Actions. This way you wouldn’t have to modify your live menu and could also add e.g. a JToolBar that contains the same actions that react the same way the items in your menu do.

How can I create an AutoComplete popup in a JTextPane in Java?

I am creating a SQL editor. I am using JTextPane for the editor. I want to implement AutoCompletion for table name etc. like Eclipse.
I think the appropriate class for displaying info on top of another component is JPopupMenu, which already handles layering correctly to display itself. JPopupMenu has a show() method that takes its 'parent' component as an argument, and it will show itself in that component's coordinate space. Since you want to display a selection of terms for the user to choose from, a menu seems appropriate.
To check for text changes, you'd add a DocumentListener to the document that's wrapped by the JTextPane; you can access it using getDocument().
To find out where the cursor (actually, the caret) is, you can use getCaretPosition(). That returns the caret's position within the text stream as an int. You can use modelToView() to translate that position to actual (x,y) coordinates. That in turn will tell you where to show your menu.
You can use addKeyListener() to catch keyboard events on your JTextPane, like hitting Ctrl-Space.
The combination of all that should allow you to do what you're looking to do.
You can also use http://fifesoft.com/autocomplete/. You can install it on any JTextComponent.
For things like this you probably should consider layered panes so your auto-complete suggestions appear in the correct place and z-order.
Furthermore you will have to look for changes in the JTextPane to know when the user is typing and you will need a parser that understands what is typed so you can offer the feature only at appropriate points.
It's not quite clear what exactly your problem is and what you got so far.
I achieved this by adding a key listener to the JTextPane and checking for CTRL + Space keystrokes. When the appropriate key combo was detected the listener went off and looked up the list of possible matches based on the characters directly to the left of the cursor at the time of the key press and found the best matches and displayed them to the user in a JPopup. If there was an exact match then it simply replaced the partial text with the match. If no matches were found an option was given to the user to add the text that they had already typed, edit it and record it into the list of acceptable data.
We use jide. They have a lot of components that help you do this kind of thing really easily

Categories

Resources