Pregunta

He creado una interfaz gráfica de usuario en el que he utilizado un JFrame. ¿Cómo debo hacerlo modales?

¿Fue útil?

Solución

Su mejor opción es utilizar un JDialog en lugar de un JFrame si desea hacer el modal ventana. Echa un vistazo a en la introducción de la API en Java Modalidad 6 para información. También hay un tutorial .

Aquí hay algunos ejemplos de código el cual mostrará una JPanel panel en un JDialog que es modal para Frame parentFrame. Excepto por el constructor, esto sigue el mismo patrón que la apertura de una JFrame.

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

Editar: Modalidad actualizado enlace de la API y agregó un vínculo tutorial (guiño a @spork de la protuberancia).

Otros consejos

Puede crear una clase que se pasa una referencia a la JFrame padres y lo mantiene en una variable JFrame. A continuación, puede bloquear el marco que crea el nuevo marco.

parentFrame.disable();

//Some actions

parentFrame.enable();

basta con sustituir a JFrame JDialog en la clase

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

y luego escribir setModal(true); en el constructor

Después de que usted será capaz de construir su formulario en NetBeans y se convierte en la forma modal

  1. Crea una nueva forma JPanel
  2. Añadir sus componentes y código deseado a ella

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


Su diálogo modal espera ...

Por lo que yo sé, JFrame no puede funcionar en modo modal. Uso JDialog lugar y llamar a setModalityType(Dialog.ModalityType type) para establecer que sea modal (o no modal).

Si está preparado para utilizar un JDialog en lugar de un JFrame, se puede establecer el ModalityType APPLICATION_MODAL .

Esto proporciona un comportamiento idéntico a su JOptionPane típica:

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

Este método de utilidad estática muestra una JFrame modal mediante la apertura en secreto un JDialog modal, también. He utilizado este éxito y con un comportamiento adecuado en Windows 7, 8, y 10-con-varios equipos de escritorio.

Es un buen ejemplo para la característica muy rara vez se utiliza de locales clases.

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

Hay un poco de código que podría ayudar:

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

Lo que he hecho en este caso es, en el JFrame principal que quiero mantener visible (por ejemplo, un marco de menús), que desactive la opción focusableWindowState en la ventana de propiedades por lo que será FALSE. Una vez hecho esto, los JFrames me llaman ¡No perder el foco hasta que los cierro.

Como otros han mencionado, se puede usar JDialog. Si no tiene acceso a la estructura padre o desea congelar la aplicación del orificio situado justo pasar null como padre:

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

no está seguro de los contenidos de su JFrame, si le preguntas a algunas aportaciones de los usuarios, puede utilizar JOptionPane, esto también puede establecer IFrame como 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");
            }

La forma más sencilla es utilizar pack () método antes de la visualización de la JFrame objeto. aquí es un ejemplo:

myFrame frm = new myFrame();
frm.pack();
frm.setVisible(true);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top