How to prevent a lightweight component receive mouse events? - java

I have some JTextComponents with some CaretEvents. I need to disable all the components to prevent user interaction after a certain actions and when that actions are completed reenable those JTextComponents to allow the user to interact again with the GUI. Obviously when the user clicks on a JTextComponent the caret listener performs it's actions and I want to prevent that.
I currently removed the CaretListeners to prevent that and after my internal operations are completed I re-add those CaretListeners.
Is there any other way to prevent that? Such removing the MouseEvents for those components and reassign that later?

One way to disable user interaction is to not allow the text component to receive the program's focus:
myTextComponent.setFocusable(false);
And then later when you want to re-allow interaction, make the same call with the obvious true parameter:
myTextComponent.setFocusable(true);

Related

Does the following situation needs synchronization?

I have a thread which enables and disables a button in certain random time, if the button clicked when it is enabled an action performed will be executed which will change the image of the button. I am concerned about the synchronization here. Suppose the button is about to get disable and got clicked, so now both threads will execute one to disable it and other to change the image. How should I synchronize this?
All Java GUI toolkits (be it Swing, Apache Pivot, JavaFX, AWT, SWT, Android...) are single-threaded. This means that all listeners will always fire in the same thread. So:
no, you don't need to perform any kind of synchronization,
yes, you need to take care so that disabling and enabling the button happens in the gui thread (wahetever it's called). The exact code is toolkit-specific.

use of multiple actionlistener for a button

I always use one ActionListenr for a button, but I find that one component can be assigned multiple action listeners. How we can do that and what is use of it
Thanks in advance
c.addActionListener(actionlistener1);
c.addActionListener(actionlistener2);
It is useful if you need to do several actions that are not necessarily correlated. For example, changing the background color of a button vs appending the action in a Logger vs informing the controller that the button have been pressed, etc...
This allows to be modular: each actionListener can handle a very specific task for a group of components. For example, you can write a default actionListener for all your buttons, and a specific one for a group of buttons that have the same behaviour.
Finally, some objects already have listeners when you instantiate them (JButton have a default FocusListener, JScrollPane a default MouseWheelListener, etc). This allow you to add other behaviours to your components, without overriding previous ones.
How we can do that
That's the easy part, create multiple instance of ActionListeners and use addActionListener. One would assume that they are all different...
and what is use of it
That's a harder question. One could assume that you would use multiple listeners when you want to apply newer logic to the process but not extend from the existing functionality...
Let's say you have a login form. You have a "Login" button. You write an ActionListener to gather the required details and validate them.
Later on, you decide that the button should be disabled during that process. Normally, you would add that functionality to the original code, but for what ever reason (it's not your code etc), you can't.
You could create another ActionListener whose sole purpose was to disable the button when it was pressed.
As an example...

SWT Text block actions outside of the TextField

I have an SWT Text and I want it to have Focus until the User Enters something.
Currently I´m using a FocusListener and check at focusLost Event, if the User has entered something. If not, I throw him back to the Text Field.
I think this is the wrong way as I don´t want anything to happen which I have to reverse then (e.g. if the user focuses another Part, I have to give focus back to the part with the Text and so on)
Does SWT provide me a way of blocking any other action but entering something into the SWT Text?
Like a Listener that gets triggered before the action happens and in which I can prevent the action to happen? Like a VerifyListener for every event type?

How to indicate that a JComboBox is loading values?

I have a JComboBox whose values are retrieved across the net.
I'm looking for a way to indicate that fact to the user, when the user wants to see the list, expands the drop down, and only then the data is being retrieved.
The basic requirements include:
JComboBox's drop-down shouldn't lock the EDT, but the combo's action should not work until there are values.
User should know when all data has been retrieved.
The size (UI real-estate) of the indication should be as small as possible.
Note that the data isn't retrieved until the user wants to see the combo's values (i.e. expands the drop-down list).
The solution i've used:
I've used a SwingWorker to keep the UI responsive. The combo box was overlayed using JIDE's Overlayable with JIDE's InfiniteProgressPanel that listens to the worker.
To avoid locking the EDT, your data retrieval should be done in a background thread. I would use a SwingWorker to find and load the values since this makes available a background thread with other goodies that make it very Swing-friendly. I would make the JComboBox enabled property false until all values have been loaded, and then enable it via setEnabled(true). You will know the SwingWorker is done either through its done() method (by overriding it), or by adding a PropertyChangeListener to the SwingWorker and being notified when its state is SwingWorker.StateValue.DONE.
One way for the user to know that the process is complete is that they will see when the combo box has been re-enabled. If you want a more obvious indicator, you could display a JProgressBar or a ProgressMonitor. This could be displayed in a dialog if you wish to leave the GUI appearance mostly unchanged.
I implemented it by adding "Loading..." item and a special border around the JComboBox. On click separate thread is started adding new items via SwingUtilities.invokeAndWait. When loading is completed the "Loading..." last item is removed.
to not force my users to wait until the data is loaded, combine the answers by eel and stan :-)
start off with the model containing zero or one real value plus the dummy entry "loading"
register a PopupMenuListener and start a SwingWorker loading the data (into a separate datastructure, might be a new model) in its very first menuWillBecomeVisible
while loading, select the dummy entry (and/or whatever else is appropriate to inform the user what's happening), the action has to be aware of "nothing-to-do-yet" as well
listen to the worker, when receiving the DONE replace/fill the data into the combo's model

JTree selection without generating event

I have a JTree, a JTable and a JList which displays the same set of objects, but in different order and with different information. If an item is selected from one of the Component, I want to select the same object on the other two Components (meaning they should be highlighted). Naturally I monitor the selection events with a Listener. Here is the problem, when a Component retrieves the selected object, I'll have to make sure the object is selected on the other Components by calling selection methods on them. This, will then notify the selection listeners on the other two components. But each of those events will in turn call selection events on components other than itself, causing an infinite loop going among the three Components.
I see one solution is to use a boolean flag, and make the listeners not propagate the selection if the flag is set. However, this seems cumbersome and not elegant. Is there a way to simply tell JTree, JTable and JList to make the selection but not fire any events (as oppose to fire an event and then catching and stopping it with a boolean flag)?
Take a look at SharedModelDemo. I think it does what you're looking for.
I would use a flag indicating whether it's user changes or internal changes but yu can also remove listeners before selection call and add them after to prevent events firing.

Categories