Why does a JOptionPane cause JFrame to disappear from taskbar? - java

I have a problem where I create two separate JFrames (one is my main application, the other shows task progress using console output...).
However, subsequently bringing up a dialog box has a strange effect on the two taskbar icons (i.e. for the JFrames). Namely it causes one taskbar icon to disappear, although both windows still exist. Note that the missing taskbar icon can be "restored" by minimising or maximising the corresponding window.
The following example code generates the problem:
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class taskbarExample {
private static JFrame frame1;
private static JFrame frame2;
public static void main (String[] args) {
frame1 = new JFrame("Frame 1");
frame1.setSize(200,600);
frame1.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame1.setVisible(true);
frame2 = new JFrame("Frame 2");
frame2.setSize(600,200);
frame2.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame2.setVisible(true);
JOptionPane.showMessageDialog(null, "Dialog box");
}
}
For comparison, try commenting out the JOptionPane line... results in no problems.
Can anyone explain what is going on here? I have seen a previous question referring to a similar problem, but without example code and no answer that helped me. Found here

This is basic property, JOptionPane
blocked code executions untill is visible on the screen,
this container is Modal and locking for mouse and keyboeard event outside of JOptionPane bounds

The showMessageDialog brings up an information-message dialog. The first parameters determines the Frame in which the dialog is displayed. if null, or if the parentComponent has no Frame, a default Frame is used.
When this function (showMessageDialog) is started the mouse and keyboard is blocked until you close the dialog information.
This effect is natural and does not mean that icon disappeared.

Related

Problems with JFrame: it shows a list of number instead of the image

I wanted to try to use JFrame and I tried with many code-examples on Internet and on video tutorial (like the one below).
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class test extends JFrame {
public static void main(String[] args){
//1. Create the frame.
JFrame frame = new JFrame("FrameDemo");
//2. Optional: What happens when the frame closes?
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//3. Create components and put them in the frame.
JLabel emptyLabel = new JLabel("BLAHBLAHBHALBAHLKKDJF");
frame.getContentPane().add(emptyLabel, BorderLayout.CENTER);
//4. Size the frame.
frame.pack();
//5. Show it.
frame.setVisible(true);
}
}
Eclipse doesn't show me any error in the code but when I run it frame always show me the image below (a list of numbers). And I totally don't understand why.
On the run button in Eclipse appear in yellow the writing "Run AnnotatedMemoryPanel".
I don't find any discussion on internet about this.
Hope someone could explain me what is wrong.
You're probably running some completely different application by accident, not the one you posted the source code for. In Eclipse try right clicking the source code, then select Run As, then Java Application. The shortcut for this is Shift + Alt + X J.

Focussing in Java swing

I'm developing an application using java swing. When I click a button, I want another window to be opened. This works fine. But it is possible to alt+tab to the original window and then interact with it even after the new window is open. Is there any way not to let the user focus the original window after the new window appears? By window I'm referring to Jframe/Jdialog.
Assuming the instance of your main JFrame window is called mainWindow:, the following code will prevent switching the focus.
// the second parameter makes the dialog modal and will prevent
// switching the focus to the mainWindow
JDialog dialog = new JDialog(mainWindow, true);
...
dialog.setVisible(true);
Documentation on JDialog: http://docs.oracle.com/javase/6/docs/api/javax/swing/JDialog.html
You may try to use a JDialog instead of JFrame and pass the instance of JFrame to JDialog constructor
You may also try to check
frame.setAlwaysOnTop(true);
or may be like this:-
frame.toFront();
frame.setState(Frame.NORMAL);

JButton needs to be clicked twice after JDialog

I've been struggling with some problem while creating my app based on Swing. I have a main JFrame which consists of:
JMenu
JPanel containing a JButton and a JLabel
JButton is linked with ActionListener. Clicking JMenu (MenuListener) brings up a JDialog with some form. The problem is, when the JDialog is closed (it doesn't make difference whether I do it with dispose() or rather showVisible(false)) I need to click the JButton two times before it triggers for the first time. From now it normally works with one click.
Every time the JDialog is in front, the problem appears.
PS. The JDialog is set to be modal, with JFrame as parent.
It sounds like a focus issue.
The first click restores focus to the app and the second clicks the button. Typically, I have seen this when the JDialog has the wrong parent and focus can not be returned.
Thank you for your answers.
I have considered posting some code, but it involves 4 classes so will be quite long.
I have also tried things with focus before, but nothing helped. What is interesting: if I display the JDialog by new myDialog.showVisible(true) it behaves like I've described. But if I use construction like this:
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new JDialog.setVisible(true);
}
});
it closes normally and parent frame doesn't need to be clicked before responding, but on the other hand the displayed Dialog needs so. Additonally, what I do not understand, after opening the Dialog cursor is placed in the text field and I can write normally, but to click some button on it I must click once on the Dialog, only second and next clicks behave like I want to.
PS. Closing the dialog like in the second included example changes nothing.

Java: Dispose ActionEvent from different JFrame

I want one JFrame to have a method like this:
private void someEvent(java.awt.event.ActionEvent evt){
//initialize another JFrame
//set the new JFrame to be visible
//set this JFrame to be disabled
}
Which is possible, but I also want the main JFrame to perform something when the newly created JFrame is disposed. I don't want to pass in the main JFrame to the new JFrame however. Is this possible?
Instead, use CardLayout to switch between the two desired content panes. There's an example here.
Don't have one JFrame create and display another JFrame. Instead the second window should be a JDialog, either modal if you want the first window frozen until the second has been dealt with or non-modal if otherwise. If modal then the first window's code will resume once the JDialog has been disposed of, and the code flow will start right after the setVisible(true) call on the dialog. If non-Modal, you'll likely want to add a WindowListener to the dialog.
For example, please check out my code here, here, and here.

Disable default ALT key action in JFrame under Windows

I would like to let my JFrame under Windows not act upon an ALT key press. To clarify, when you execute the following snippet of code:
import javax.swing.*;
public class FrameTest {
public static void main(String[] args) throws Exception {
JFrame frame = new JFrame();
frame.setSize(400, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
and press the ALT key and then the arrow down key, you get a menu in the upper left corner in which you can choose to minimize, move, close etc. the frame (at least I get that). I would like to disable this: ie. the JFrame should not "listen" to these ALT presses.
I believe that certain Windows components react by default on the ALT key because when I add a menu bar to my frame, and explicitly set the look & feel to the system look & feel, the menu (File) is now automatically selected after pressing the ALT key:
import javax.swing.*;
public class FrameTest {
public static void main(String[] args) throws Exception {
JFrame frame = new JFrame();
frame.setSize(400, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("File");
menuBar.add(menu);
frame.setJMenuBar(menuBar);
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); // set Windows look and feel
frame.setVisible(true);
}
}
and when I remove UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()) from the example above, this behaviour is not exhibited when pressing the ALT key: the menu is not selected, but the JFrame is.
When no look & feel is set, the "Metal" look and feel is used. It is clear by looking at the menu bar in my previous example that you go from "native look" to "Metal look" when you remove UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()) from the code. However, I don't see a change in the JFrame, no matter what look & feel I set, it always looks like a native Windows frame.
So, my question is: how can I disable this ALT behaviour on my JFrame? I guess I can do it by actually changing the look and feel of the JFrame. Is that possible? If so, how?
Thanks!
Just for history:
You can do this. Window manger handles all the events to the current keyboard focus manager and it decides what to do with the particular key. Every swing application has only one keyboard focus manager that's why your changes will affect the whole application and not the particular frame. The code below should do the trick:
frame.addFocusListener(new FocusListener() {
private final KeyEventDispatcher altDisabler = new KeyEventDispatcher() {
#Override
public boolean dispatchKeyEvent(KeyEvent e) {
return e.getKeyCode() == 18;
}
};
#Override
public void focusGained(FocusEvent e) {
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(altDisabler);
}
#Override
public void focusLost(FocusEvent e) {
KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(altDisabler);
}
});
Actually, what you are seeing here is pretty much outside your nice, Swing-y Java world. The window frame (except for MDI interfaces) will always be drawn by the window manager of the underlying operating system. And that's also the reason why the Alt key behaves like you observe. This key is intercepted by the WM in this case and it decides that you want to bring up the system menu of the program. That's totally unrelated to Java.
For several reasons you can't change the "look and feel" of the window frame, the main one being that this is outside Swing's PLAF system. You can remove the window frame, leaving behind a naked window (freezing in the cold November wind), then you also shouldn't get a system menu anymore.
Furthermore you could try handling the Alt keypress and not delegating that very keypress further (the application gets it before the WM does, so you can mess with these things). My Java-Fu is a little rusty right now, though, so no idea if and how this can be achieved.
It sounds like you're hitting upon some default interactions with the Windows window manager. It is possible that if you draw your own titlebar and borders that Windows will no longer set these default handlers on the Alt key.
You might want to try Substance, which gives you much more control over these sorts of things, while still working with the standard Swing components.
Or, try this before you make your frame visible:
JFrame.setDefaultLookAndFeelDecorated(true);

Categories