Frage

Ich habe eine GUI erstellt, in dem ich ein JFrame verwendet haben. Wie soll ich machen es Modal?

War es hilfreich?

Lösung

Ihre beste Wette ist eine JDialog anstelle eines JFrame zu verwenden, wenn Sie das Fenster modal machen wollen. Schauen Sie sich Details über die Einführung des Modality-API in Java 6 zur Information. Es gibt auch ein Tutorial .

Hier ist ein Beispielcode, der eine JPanel panel in einem JDialog angezeigt werden, die Frame parentFrame modal ist. Mit Ausnahme des Konstruktor, folgt dies das gleiche Muster wie ein JFrame öffnen.

final JDialog frame = new JDialog(parentFrame, frameTitle, true);
frame.getContentPane().add(panel);
frame.pack();
frame.setVisible(true);

Edit: aktualisiert Modality API Link & hinzugefügt Tutorial Link (Nicken für die Beule @spork).

Andere Tipps

Sie können eine Klasse erstellen, die einen Verweis auf das übergeordnete JFrame geleitet wird und hält sie in einer JFrame variabel. Dann können Sie den Rahmen sperren, die Ihren neuen Rahmen geschaffen.

parentFrame.disable();

//Some actions

parentFrame.enable();

nur ersetzen JFrame in der Klasse JDialog

public class MyDialog extends JFrame // delete JFrame and write JDialog

und dann setModal(true); in Konstruktor schreiben

Danach können Sie Ihr Formular in Netbeans konstruieren und die Form wird modal

  1. Erstellen Sie eine neue JPanel Form
  2. Fügen Sie die gewünschten Komponenten und Code, um es

YourJPanelForm stuff = new YourJPanelForm();
JOptionPane.showMessageDialog(null,stuff,"Your title here bro",JOptionPane.PLAIN_MESSAGE);


Ihr modaler Dialog erwartet ...

Soweit ich weiß, kann JFrame nicht Modal-Modus tun. Verwenden JDialog statt und rufen Sie setModalityType(Dialog.ModalityType type) setzt es modal zu sein (oder nicht modal).

Wenn Sie bereit sind, eine JDialog anstelle eines JFrame zu verwenden, können Sie die ModalityType auf APPLICATION_MODAL .

Dies stellt ein identisches Verhalten auf Ihre typische 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();
}
}

Diese statische Hilfsmethode zeigt ein modaler JFrame heimlich eine modale JDialog, zu öffnen. Ich habe diese erfolgreich und mit dem richtigen Verhalten auf Windows 7, 8 und 10 mit Multiple-Desktops.

Es ist ein schönes Beispiel für das sehr selten genutztes Feature von local Klassen.

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);
}

Es ist ein Stück Code, die helfen können:

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);
    }
}

Was ich in diesem Fall getan habe, in der primären JFrame, die ich will sichtbar halten (zum Beispiel eines Menü-Rahmen), habe ich die Möglichkeit, focusableWindowState im Eigenschaftsfenster deaktivieren, damit es FALSE werden. Sobald dies geschehen ist, rufen Sie die jframes ich verlieren Fokus dont, bis ich sie schließen.

Wie andere erwähnt, könnten Sie JDialog verwenden. Wenn Sie keinen Zugriff auf den Rahmen Elternteil haben oder möchten Sie das Loch Anwendung einzufrieren nur null als Eltern übergeben:

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);

nicht sicher, dass die Inhalte Ihrer JFrame, wenn Sie einige Eingaben von Benutzern fragen, können Sie JOptionPane verwenden, dies auch IFrame als modal einstellen

            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");
            }

Die einfachste Art und Weise zu verwenden, ist pack () Verfahren vor Visualisierungen des JFrame Objekts. hier ist ein Beispiel:

myFrame frm = new myFrame();
frm.pack();
frm.setVisible(true);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top