I have a complex and heavy swing client application which contains many modal compponents, jdialogs, internal frames etc. on some cases, a problem occurs and it is impossible to focus on swing textfields anymore. You may click on some jbuttons, jcheckboxes but it is impossible to focus and edit values on editable jtextfields anymore. The gainfocus events of editable textfields are not triggered anymore, only the requestfocus methods are invoked when you perform click on textfields.
I found a way(hack) so resolve the problematic case, when the trouble case occurs, and you show some joptionpane message or modal jdialog and close it by clicking or disposing, the problem goes away any you may click onto the textfields and edit them.
As a solution, i do some check, if you try focusing on a component, i start a timer thread in the requestfocus event of clicked textfield and keep the instance as focusrequesting component. After some time i check the last focused component by
KeyboardManager.getCurrentKeyboardFocusManager().getPermanentFocusOwner()
If no problem occured, and the textfield gained the focus, the returned object (retur value of getPermanentFocusOwner) is the same instance as the focusrequesting component. But if the problematic case occured, the returned object is different from the focus requesting one and i open my temporarily jdialog by:
JDialog dialog=new OptionPane().createDialog(KeyboardFocusManager.getCurrentFocusManager().getActiveWindow(), "");
dialog.setModal(true);
// MUST be modal to fix the lost focus case
// start closing thread, which closes the dialog after some few time by dialog.dispose
new Closer(dialog).start();
dialog.setVisible(true);
This mechanism works, i now it is not very stable. And on some cases,the dialog.dispose() does not work, the temporarily windows remains always on the screen, not closeable, and because it is modal, client can not do any actions anymore. The dialog MUST be modal to solve the focus problem, because non-modal dialogs does not resolve the focus problem declared above. The dispose method of jdialog has many synchronized blocks, mutex objects etc, I think there occurs some deadlocks.
Any better mechanism suggestions, ideas? I know the best solution is to check the current application, analyse it or rewrite it. But it is very complex, heavy and model and view is not well properly organised. I have short time because the client is waiting, need some temporarily solutions, tricks or hacks.
You may click on some jbuttons, jcheckboxes but it is impossible to
focus and edit values on editable jtextfields anymore.
this is issue (quite common) with JTextField in JWindow without parent (JFrame), use undecorated JDialog instead
I saw here some issue with Focus, FocusSubsystem on Linux OS with last Java version, but never caused to block users input to JTextField
the best workaround for a.m. issue is RequestFocusListener by #camickr
dialog.setVisible(true); should be wrapped in invokeLater(), more see in Initial Thread (valid for all Top-Level Containers created on runtime too)
nothing clear from your question without posting an SSCCE, short, runnable, compilable, demonstraded, caused with a.m. issue
Related
I have two seperate JFrames but when i click the X in the topright of one, it will exit out of the other also. I have an "exit" button near the bottom to do setVisible(false), but i still have the tendency to use the x button. How would i make it so that it doesnt cancel out of the entire project?
Also, how would i make it so that the second JFrame locks out of the other JFrame untill the second JFrame is closed, like how a popup message works
Don't give your GUI two JFrames. The GUI ideally should have only one GUI. If a separate window is required, then make it a dialog such as a JDialog, and this won't happen.
Also, how would i make it so that the second JFrame locks out of the other JFrame untill the second JFrame is closed, like how a popup message works
You are perfectly describing the behavior of a modal JDialog or JOptionPane. Just use 'em.
Later we'll chat about using CardLayouts to swap views in a single GUI.
Edit, you state:
Im using Netbeans form editor to create them faster but I only see JFrame and JPanel. Can I edit them in Netbeans? I'd rather not do them through scratch Java
You've touched on another zealous belief of mine, that this is yet another reason not to use a code generator when learning a library as one can get too tied into the code generator, that it prevents one from learning the library. I strongly advise you to put aside your code-generation tool and create by hand, referring to the tutorials and API. Then later when you get more familiar with the library, sure use the tool. By the way, an answer to your direct question here is to gear your GUI's to create JPanels, and then use these JPanels where and how you want them -- in JFrames, or JDialogs, or JOptionPanes, or swapped in CardLayouts, or JTabbedPanes or nested in other JPanels,... etc...
You should be using a modal JDialog, not a second JFrame, because JDialogs provide certain functionality such as not adding another window bar to the taskbar, and automatically setting focus when the parent JFrame receives focus. Modal JDialogs prevent user input to the JFrame while it's open, useful for an "Are you sure you want to exit?" dialog, for example.
As for one JFrame exiting the other, you probably have their default close operation set to EXIT_ON_CLOSE. If you do this:
jframe.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
jframe.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent we){
handleUserWantsToCloseWindow();
}
});
Then you can control what happens when the user wants to close, such as popping up a "Save Changes?" modal JDialog or "Are you sure you want to quit?" modal JDialog. Note that you have to manually dispose of the JFrame if you use this method.
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.
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.
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.
I have JTextField with FocusListener that call textfield.grabFocus() every time when textfield lose focus. But unfortunetly, it allow parent Window to react on user action. Is there any way to don't give the focus to the Window using only JTextField methods?
If I'm understanding you correctly, you don't want any other controls on your program to be usable while this field requires focus. The problem is, each object is likely to have at least one event listener waiting for some action to occur, and stealing your focus away from you.
You can make all objects not focusable by setting setFocusable(false) for each object, but that will still allow events to be captured.
I'd override/replace (or possibly completely remove, if really necessary) the event listeners on all the other objects to only perform actions when the proper conditions are met (when your object doesn't require focus, if that would ever occur). If overridden/replaced, each listener could then return focus to the JTextField if those conditions are not met.
Also, it is better to use requestFocus() or requestFocusInWindow() instead of grabFocus(). See JComponent grabFocus() and JComponent requestFocus() for more information.