2009-09-26 19 views
54

He creado una GUI en la que he utilizado un JFrame. ¿Cómo debería hacerlo Modal?Cómo hacer un JFrame Modal en Swing java

+1

Véase también [? El uso de múltiples JFrames, Buena Mala Práctica /] (http://stackoverflow.com/a/9554657/418556) –

Respuesta

55

Su mejor opción es utilizar un JDialog en lugar de un JFrame si desea que la ventana sea modal. Consulte details on the introduction of the Modality API in Java 6 para obtener información. También hay a tutorial.

Aquí 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 abrir un JFrame.

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

Editar: Modalidad actualizado enlace API & añadido enlace tutorial (guiño a @spork de la protuberancia).

+3

miedo que parece ser la única solución . Estoy luchando contra este mismo problema con un código heredado. Tengo un JFrame que realmente necesito ser modal. Hacer el trabajo para convertirlo todo en JDialog realmente va a ser feo ... :-( –

+0

¿Puede abrirlo? Cree un JDialog modal e invisible, haga que cree una instancia del JFrame y, cuando el JFrame esté cerrado, capture los valores si es necesario, y cierre el JDialog – Redandwhite

+2

El enlace está roto :(todavía hay personas que intentan aprender a partir de estos 3 años. Pruebe esto en 2013: http://docs.oracle.com/javase/tutorial/uiswing/misc/ modality.html – Spork

15

Puede crear una clase a la que se le pasa una referencia al elemento primario JFrame y la mantiene en una variable JFrame. Luego puede bloquear el marco que creó su nuevo marco.

parentFrame.disable(); 

//Some actions 

parentFrame.enable(); 
+0

nice, me hizo pensar en un ciclo para "suspender" (duerma) la aplicación mientras el marco es Visible(), thx! –

+0

Kamil, Imgonzalves, ¿me puede aclarar? ¿Está diciendo que la nueva clase debería crearse en el JDialog, JFrame o lo que sea que crea el tema del OP JFra ¿yo? –

-2

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

Si está preparado para utilizar una JDialog en lugar de JFrame, puede configurar ModalityType en 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(); 
} 
} 
0

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); 
    } 
} 
5
  1. Crear una nueva forma JPanel
  2. añaden sus componentes deseados y codificarlo

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


espera su diálogo modal ...

+0

Ou, pero hay un botón Aceptar, que no quiero. –

+0

Espera, ¿qué? ¿Simplemente puede agregar el JPanel al JDialog de esa manera? – Zizouz212

+0

esto no tiene nada que ver con un jFrame –

0

Lo que he hecho en este caso es, en el JFrame principal que quiero mantener visible (por ejemplo, un marco de menús), Anulo la opción focusableWindowState en la ventana de propiedades, así será FALSE. Una vez hecho esto, los jframes que llamo no pierden el foco hasta que los cierro.

4

basta con sustituir JFrame a JDialog en 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 la forma se convierte en modal

+0

No tenía conocimiento de 'setModal (true);' .. esto es genial – db2791

+0

necesita decir que esto no funciona en netbeans porque su editor de formularios establece la operación de cierre en el diálogo de cierre que no es permitido en jdialog –

1

Este método de utilidad estática muestra un JFrame modal al abrir secretamente un JDialog modal también. Lo utilicé con éxito y con un comportamiento adecuado en Windows 7, 8 y 10 con múltiples escritorios.

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

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

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

myFrame frm = new myFrame(); 
frm.pack(); 
frm.setVisible(true); 
+0

¿cómo se relaciona esto? – Enerccio