Domanda

ho creato un'interfaccia grafica in cui ho usato un JFrame. Come dovrei farlo modale?

È stato utile?

Soluzione

La cosa migliore è quella di utilizzare un JDialog invece di un JFrame, se si vuole fare il modal finestra. Visualizza il sull'introduzione delle API Modalità in Java 6 per info. C'è anche un tutorial .

Ecco alcuni esempi di codice che verrà visualizzato un JPanel panel in un JDialog che è modale Frame parentFrame. Fatta eccezione per il costruttore, questo segue lo stesso modello come apertura di un JFrame.

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

Edit: aggiornato Modalità collegamento API e aggiunto il link tutorial (cenno al @spork per l'urto).

Altri suggerimenti

È possibile creare una classe che viene passato un riferimento al JFrame genitore e lo tiene in una variabile JFrame. Poi si può bloccare il telaio che ha creato il nuovo telaio.

parentFrame.disable();

//Some actions

parentFrame.enable();

basta sostituire JFrame a JDialog in classe

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

e poi scrivere setModal(true); nel costruttore

Dopo che si sarà in grado di costruire il tuo modulo in NetBeans e la forma diventa modale

  1. Crea un nuovo modulo JPanel
  2. Aggiungi i componenti e il codice desiderati ad esso

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


La vostra finestra di dialogo modale attende ...

Per quanto ne so, JFrame non può fare modalità modale. Usa JDialog invece e chiamare setModalityType(Dialog.ModalityType type) per impostare per essere modale (o non modale).

Se siete pronti ad utilizzare un JDialog invece di un JFrame, è possibile impostare il ModalityType a APPLICATION_MODAL .

Questo fornisce un comportamento identico al vostro JOptionPane tipico:

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

Questo metodo di utilità statico mostra un JFrame modale segretamente l'apertura di un JDialog modale, anche. Ho usato questo con successo e con un comportamento corretto su Windows 7, 8, e multiple-desktop-10 con-.

E 'un bel esempio per la caratteristica molto raramente utilizzato di locali classi.

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

C'è un po 'di codice che potrebbe aiutare:

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

Quello che ho fatto in questo caso è, nel JFrame principale che voglio mantenere visibile (ad esempio, un riquadro del menu), ho deselezionare l'opzione focusableWindowState nella finestra delle proprietà così sarà FALSE. Una volta fatto ciò, i jframes mi chiamano Non tiratevi attenzione perdere fino a quando li chiudo.

Come altri hanno detto, è possibile utilizzare JDialog. Se non si ha accesso alla struttura genitore o si desidera bloccare l'applicazione buco proprio passare null come un genitore:

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

Non è sicuro il contenuto della JFrame, se chiedete qualche input da parte degli utenti, è possibile utilizzare JOptionPane, anche questo può impostare IFrame come modale

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

Il modo più semplice è usare pacco () metodo prima della visualizzazione della JFrame oggetto. ecco un esempio:

myFrame frm = new myFrame();
frm.pack();
frm.setVisible(true);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top