My question seems to be very much related to How to hide JDialog from JApplet when user switch browser tab? But it does not provide a working solution.
I have developed an applet deployed using JWS/JNLP. It starts with showing "NEW GAME" dialog.
private class NewGameDialog extends CustomDialog implements ActionListener {
...
public NewGameDialog () {
super(topContainer, "NEW GAME", modalityType);
System.out.println(topContainer + " " + modalityType);
//prints JApplet and DOCUMENT_MODAL
...
CustomDialog
just extends JDialog
:
public class CustomDialog extends JDialog implements WindowListener {
public CustomDialog(Container cont, String title, ModalityType modalityType) {
super(windowForComponent(cont), title, modalityType);
}
public static Window windowForComponent(Component c) {
if (c instanceof Window) return (Window) c;
return SwingUtilities.windowForComponent(c);
}
...
This is how JDialog
is invoked from a GUI class:
public void requestNewGame () {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
NewGameDialog dialog = new NewGameDialog();
dialog.setVisible(true);
}
});
}
I have used different types of modality described in How to Use Modality in Dialogs. The goal is to hide JDialog
when user switches to another tab in browser. But none of options does not seems to work. The dialog keeps floating above all tabs.
Please, advice how can I hide the dialog when user moves to another tab and show again once user returns to my applet's tab?
This works on the presumption that the parent component changes location on screen when the tab changes. E.G.
JDialog.getParent().getLocationOnScreen()
Using the other Dialog.ModalityType
values other than MODELESS
either denied access to browser tabs or caused security exceptions.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class DialogApplet extends JApplet {
@Override
public void init() {
Runnable r = new Runnable() {
@Override
public void run() {
initGUI();
}
};
SwingUtilities.invokeLater(r);
}
public void initGUI() {
JButton b = new JButton("Show Dialog");
ActionListener listener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
showDialog();
}
};
b.addActionListener(listener);
add(b);
}
private JDialog d;
JTextArea output;
int currentX = -1;
Timer timer;
public void showDialog() {
if (d==null) {
output = new JTextArea(5,20);
Window w = SwingUtilities.windowForComponent(this);
d = new JDialog(w, "Dialog", Dialog.ModalityType.MODELESS);
//Dialog.ModalityType.TOOLKIT_MODAL); //security
//Dialog.ModalityType.DOCUMENT_MODAL);
//Dialog.ModalityType.APPLICATION_MODAL);
d.add(output, BorderLayout.CENTER);
ActionListener al = new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
StringBuilder sb = new StringBuilder();
sb.append("parent location: \t" +
d.getParent().getLocation() + "\n");
sb.append("parent location - screen: \t" +
d.getParent().getLocationOnScreen() + "\n");
System.out.print(sb.toString());
output.setText(sb.toString());
if (currentX>-1 &&
currentX!=d.getParent().getLocationOnScreen().getX()
) {
System.out.println( "Goodbye world!" );
d.setVisible(false);
timer.stop();
}
}
};
timer = new Timer(1000, al);
d.pack();
d.setLocationRelativeTo(d.getParent());
}
currentX = (int)d.getParent().getLocationOnScreen().getX();
timer.start();
d.setVisible(true);
}
}
Perhaps instead look to JS for this. The trick seems to be in detecting the HTML window focus/blur events. E.G. as detailed in answers to:
Obviously when JS Detects tab change, we would have it call a method in the applet such as tabVisible()
or tabHidden()
to do the appropriate action with the dialog.