I have created one GUI in which I have used a JFrame. How should I make it Modal?
This question is related to
java
swing
modal-dialog
jframe
The most simple way is to use pack() method before visualizing the JFrame object. here is an example:
myFrame frm = new myFrame();
frm.pack();
frm.setVisible(true);
As others mentioned, you could use JDialog. If you don't have access to the parent frame or you want to freeze the hole application just pass null as a parent:
final JDialog frame = new JDialog((JFrame)null, frameTitle, true);
frame.setModal(true);
frame.getContentPane().add(panel);
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
frame.pack();
frame.setVisible(true);
You can create a class that is passed a reference to the parent JFrame
and holds it in a JFrame
variable. Then you can lock the frame that created your new frame.
parentFrame.disable();
//Some actions
parentFrame.enable();
The only code that have worked for me:
childFrame.setAlwaysOnTop(true);
This code should be called on the main/parent frame before making the child/modal frame visible. Your child/modal frame should also have this code:
parentFrame.setFocusableWindowState(false);
this.mainFrame.setEnabled(false);
If you're prepared to use a JDialog instead of a JFrame, you can set the ModalityType to APPLICATION_MODAL.
This provides identical behaviour to your typical JOptionPane:
import java.awt.event.ActionEvent;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
public class MyDialog extends JFrame {
public MyDialog() {
setBounds(300, 300, 300, 300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setLayout(new FlowLayout());
JButton btn = new JButton("TEST");
add(btn);
btn.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e) {
showDialog();
}
});
}
private void showDialog()
{
JDialog dialog = new JDialog(this, Dialog.ModalityType.APPLICATION_MODAL);
//OR, you can do the following...
//JDialog dialog = new JDialog();
//dialog.setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
dialog.setBounds(350, 350, 200, 200);
dialog.setVisible(true);
}
public static void main(String[] args)
{
new MyDialog();
}
}
What I've done in this case is, in the primary jframe that I want to keep visible (for example, a menu frame), I deselect the option focusableWindowState
in the property window so It will be FALSE
. Once that is done, the jframes I call donĀ“t lose focus until I close them.
As far as I know, JFrame cannot do Modal mode. Use JDialog instead and call setModalityType(Dialog.ModalityType type)
to set it to be modal (or not modal).
not sure the contetns of your JFrame, if you ask some input from users, you can use JOptionPane, this also can set JFrame as modal
JFrame frame = new JFrame();
String bigList[] = new String[30];
for (int i = 0; i < bigList.length; i++) {
bigList[i] = Integer.toString(i);
}
JOptionPane.showInputDialog(
frame,
"Select a item",
"The List",
JOptionPane.PLAIN_MESSAGE,
null,
bigList,
"none");
}
There's a bit of code that might help:
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
public class ModalJFrame extends JFrame {
Object currentWindow = this;
public ModalJFrame()
{
super();
super.setTitle("Main JFrame");
super.setSize(500, 500);
super.setResizable(true);
super.setLocationRelativeTo(null);
JMenuBar menuBar = new JMenuBar();
super.setJMenuBar(menuBar);
JMenu fileMenu = new JMenu("File");
JMenu editMenu = new JMenu("Edit");
menuBar.add(fileMenu);
menuBar.add(editMenu);
JMenuItem newAction = new JMenuItem("New");
JMenuItem openAction = new JMenuItem("Open");
JMenuItem exitAction = new JMenuItem("Exit");
JMenuItem cutAction = new JMenuItem("Cut");
JMenuItem copyAction = new JMenuItem("Copy");
JMenuItem pasteAction= new JMenuItem("Paste");
fileMenu.add(newAction);
fileMenu.add(openAction);
fileMenu.addSeparator();
fileMenu.add(exitAction);
editMenu.add(cutAction);
editMenu.add(copyAction);
editMenu.addSeparator();
editMenu.add(pasteAction);
newAction.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent arg0)
{
JFrame popupJFrame = new JFrame();
popupJFrame.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
((Component) currentWindow).setEnabled(true); }
});
((Component) currentWindow).setEnabled(false);
popupJFrame.setTitle("Pop up JFrame");
popupJFrame.setSize(400, 500);
popupJFrame.setAlwaysOnTop(true);
popupJFrame.setResizable(false);
popupJFrame.setLocationRelativeTo(getRootPane());
popupJFrame.setVisible(true);
popupJFrame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
}
});
exitAction.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent arg0)
{
System.exit(0);
}
});
}
public static void main(String[] args) {
ModalJFrame myWindow = new ModalJFrame();
myWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myWindow.setVisible(true);
}
}
This static utility method shows a modal JFrame by secretly opening a modal JDialog, too. I used this successfully and with proper behavior on Windows 7, 8, and 10-with-multiple-desktops.
It's a nice example for the very rarely used feature of local classes.
import javax.swing.*;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
// ... (class declaration)
/**
* Shows an already existing JFrame as if it were a modal JDialog. JFrames have the upside that they can be
* maximized.
* <p>
* A hidden modal JDialog is "shown" to effect the modality.
* <p>
* When the JFrame is closed, this method's listener will pick up on that, close the modal JDialog, and remove the
* listener.
*
* made by dreamspace-president.com
*
* @param window the JFrame to be shown
* @param owner the owner window (can be null)
* @throws IllegalArgumentException if argument "window" is null
*/
public static void showModalJFrame(final JFrame window, final Frame owner) {
if (window == null) {
throw new IllegalArgumentException();
}
window.setModalExclusionType(Dialog.ModalExclusionType.APPLICATION_EXCLUDE);
window.setVisible(true);
window.setAlwaysOnTop(true);
final JDialog hiddenDialogForModality = new JDialog(owner, true);
final class MyWindowCloseListener extends WindowAdapter {
@Override
public void windowClosed(final WindowEvent e) {
window.dispose();
hiddenDialogForModality.dispose();
}
}
final MyWindowCloseListener myWindowCloseListener = new MyWindowCloseListener();
window.addWindowListener(myWindowCloseListener);
final Dimension smallSize = new Dimension(80, 80);
hiddenDialogForModality.setMinimumSize(smallSize);
hiddenDialogForModality.setSize(smallSize);
hiddenDialogForModality.setMaximumSize(smallSize);
hiddenDialogForModality.setLocation(-smallSize.width * 2, -smallSize.height * 2);
hiddenDialogForModality.setVisible(true);
window.removeWindowListener(myWindowCloseListener);
}
YourJPanelForm stuff = new YourJPanelForm();
JOptionPane.showMessageDialog(null,stuff,"Your title here bro",JOptionPane.PLAIN_MESSAGE);
Your modal dialog awaits...
just replace JFrame
to JDialog
in class
public class MyDialog extends JFrame // delete JFrame and write JDialog
and then write setModal(true);
in constructor
After that you will be able to construct your Form in netbeans and the form becomes modal
Source: Stackoverflow.com