Get left mouse button status without event - java

I need to scale my dialogs, when moving them to a different screen. Since scaling all components is quite expensive, I only want to do it once, when the dialog is moved to its new location.
So I used a timer, which restarts with every incoming componentMoved event, to know, when the dialog stops moving. This works great, as long as the mouse is released when stopping the dialog.
If the dialog stops moving and the mouse is still pressed, scaling works. But as soon, as I release the mouse, my L&F engine resizes the dialog to its previous size, which is very inconvenient.
I tried pack(), setting the size manually (I know, bad practice), I tried setVisible(false) before scaling and setVisible(true) afterwards, but as long as the mouse is pressed, my L&F engine resizes the dialog to its previous size.
Sadly, all MouseEvents concerning the titleBar are swallowed by the engine, so I cannot simply use a mouseReleased event to trigger scaling.
This is why I need to find out, if the mouse is still pressed without having to use an event. Is there any way? JNI somehow?
I cannot show an example, because without the L&F Engine, it works fine. Not using it is also not an option.

I think, you should use ComponentListener. When windows size is changed, your layout manager must trigger relayout and component sizes must be changed.
Also for debugging purposes you can use AWTEventListener to get all events which are thrown in your UI.
Toolkit.getDefaultToolkit().addAWTEventListener(...);
setting the size manually (I know, bad practice)
It's not a bad practice. Especially when you want to restore previous size of your window. pack() is simply preferred way.

Related

Adding tooltip text to JLabel prevents containing JPanel from throwing MouseEvents

I have a JPanel (pNums) which contains another JPanel (pGrid). pGrid itself contains a grid (JLabel[][] in a GridLayout) of labels. There is a mouse listener which catches events from pGrid and does fairly important stuff with them (as in, the entire functionality of the program relies on the mouseClicked() event). This works perfectly, exactly the way I wanted it to... until I add tooltips to the labels.
As soon as I call JLabel.setToolTipText("SomeString") the listener stops reacting to events (I have tried most, if not all of the mouse events, none of them seem to be called).
I am sure that it is the tooltips by the way, commenting out the setToolTipText() completely fixes the problem. Of course, since I needed the tooltips, it also causes a whole host of other problems.
I've looked around and while I haven't found anything quite right, I get the impression that I just chose a really bad way to do what I wanted. But I also want to know for sure.
Can I get both the event and the tooltip or should I go back to the drawing board.
I think you might be able to "fix" this issue, with setting delay on tooltip appearance. But once it will appear user will have to click to hide it anyway.
http://docs.oracle.com/javase/7/docs/api/javax/swing/ToolTipManager.html
The reson for this might be, that tooltip itself needs mouse click, to hide.

AWT Canvas cannot gain focus in the presence of another focusable component

I have a simple GUI with a JTextField and an AWT Canvas (to prevent the counter-question as to why I'm using an AWT Canvas: I need to have a window handle).
The Canvas is to process input events, that means it must be focusable. I assure this by using setFocusable(true) in its constructor, later checks using isFocusable() confirm that it is indeed focusable.
Now, the JTextField gains the focus by default when the GUI opens. That's fine by me so far. However, there is no way to get the focus away from that JTextField.
The article "The AWT Focus Subsystem" clearly states that if a focusable component is being clicked on, it will gain the focus. This does not happen, in fact, I receive zero focus change events whatsoever, only if the window gets deactivated and activated again, but then the focus is right back to the JTextField.
Explicit invocations of requestFocus() and requestFocusInWindow() do not help either, the latter always returns false.
I have gotten the same results with any focusable component if I replace the JTextField. If the Canvas is the only focusable container, everything works fine because it will always have the focus.
Am I missing something here? Is there any way I can make my Canvas gain focus in the presence of another focusable component, preferably without making that one unfocusable?
basically in swing focus gained 1st. left(ToRight) JComponents on the top
in most completed GUI, and if there (together with creating JComponents) are added Listeners to the JComponents, then these Listeners (f.e. Document) can take focus...
but works for me on startUp:
last lines in something class about JComponets ..
myFrame.pack();
myFrame.setVisible(true);
Runnable doRun = new Runnable() {
public void run() {
myComponent.grabFocus();
myComponent.requestFocus();//or requestFocusInWindow
}
};
SwingUtilities.invokeLater(doRun);
Sorry for leaving some info out that turned out to be the root of the problem.
As mentioned, I'm using a heavyweight component so I have a window handle. I need one because it is passed to an OpenGL application in a native library, the AWT canvas is then used as a rendering canvas.
In Windows, Java uses the GWLP_USERDATA window field to store a pointer to an AWTComponent object. However, said OpenGL application overrides that field to store its own Window object pointer, which will of course break all AWT related functionality.
I solved this problem by creating a custom window message handler that delegates incoming messages to both the OpenGL application and Java's AWT part.

Globally disable all mouse input when a JDialog is showed

I would like to implement what follows:
when my application perform some critics operations or produce some errors, i want to display an alert JDialog telling the user what is happening.
Now, because some errors may put my application into an inconsistent status, until they are resolved, i would like temporarily disable mouse event dispatch to all components (including JMenu, JToolbar, .. )except the showed JDialog.
Is there anyway to do that? Or I have to manually removed all mouse listeners from all of components of my application, and re-add them later?
Make the dialog "modal" with setModal(true).
Simplest way is to call
frame.setEnabled(false);
where frame is your top-level window.
Note that the above soln may change the look of frame until its enabled again. For real control people play around with EventQueue's.

Help needed in diagnosing a painting issue on alt-tab in Swing

I have been looking into this for a few hours now and haven't found anything to guide my way. I have a Windows Swing GUI program that is performing some background processing in a SwingWorker. This also uses a progress dialog to let the user know how long the background processing will take.
The original designer of this system decided to disable mouse and keyboard input to the user interface, with the exception of the "Cancel" button on the progress dialog. They did this by using a glasspane that ignores all mouse and keyboard events.
The actual issue is that if the user alt-tabs or a screensaver happens, the user interface behind the glasspane never repaints. The progress dialog repaints, but this is due to the SwingWorker calling repaints periodically to update the progress.
I would like any advice for where to look to next. I haven't been able to find anything on alt-tab repainting in Java. Perhaps the progress dialog is modal by definition, preventing the EDT from repainting? Or perhaps the glasspane prevents repaints of "hidden" components?
Thanks,
Ryan
The article How to Write Window Listeners covers this topic. Using this example, you should see pairs of window events on each alt-tab event, similar to these:
java.awt.event.WindowEvent[WINDOW_LOST_FOCUS,opposite=null,oldState=0,newState=0] on One
java.awt.event.WindowEvent[WINDOW_DEACTIVATED,opposite=null,oldState=0,newState=0] on One
java.awt.event.WindowEvent[WINDOW_ACTIVATED,opposite=null,oldState=0,newState=0] on One
java.awt.event.WindowEvent[WINDOW_GAINED_FOCUS,opposite=null,oldState=0,newState=0] on One
If the glass pane's opaque is true, the repaint manager will not repaint the panel below. It's a performance optimization.

Java Swing GUI hour glass

There is a JTabbedPane In my Swing program.
When user clicks on a tab, the program takes a while to get the data and process the results, then shows the results in the selected tab.
How can I display a hour glass, or something of that effect so that user knows it's processing data? Not to click on the tab again before it finishes it job.
The simplest way is to just call setCursor on the appropriate component (probably the top-level window) with the appropriate Cursor.
component.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
And then set it back when you are done.
component.setCursor(Cursor.getDefaultCursor());
A JProgressBar (possibly in indetermiante mode) sounds right - put that on the tab until the data has been fetched. A well-designed UI shouldn't force the user to wait for long-running tasks to complete and instead allow them to do something else inbetween.
setCursor(int) is deprecated. This is probably a bit cleaner:
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
As the other answers mention, you can set a wait cursor, but you also mention preventing additional mouse clicks. You can use a glass pane to prevent clicks on components until the long operation is finished. In addition to the Sun tutorials on the glass pane, there is a nice example at http://www.java2s.com/Code/Java/Swing-JFC/DemonstrateuseofGlassPane.htm
I would as other mentioned
Change the cursor
Use a SwingWorker
Display the progressbar or an animated image in the glasspane
Hide the glasspane when the task is completed
Restore the default cursor

Categories