2009-09-26 7 views
54

Я создал один GUI, в котором я использовал JFrame. Как мне сделать это модальным?Как сделать JFrame Modal в Swing java

+1

Смотрите также [? Использование нескольких JFrames, хороший/плохой практики] (http://stackoverflow.com/a/9554657/418556) –

ответ

55

Лучше всего использовать JDialog вместо JFrame, если вы хотите сделать мода модальным. Оформить заявку details on the introduction of the Modality API in Java 6. Существует также a tutorial.

Вот пример кода, который будет отображать JPanel panel в JDialog, который является модальным до Frame parentFrame. За исключением конструктора, это следует за тем же шаблоном, что и открытие JFrame.

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

Edit: обновлены модальности API ссылка & добавлен учебник ссылку (эдакое @spork для рельефности).

+3

Боясь, что, как представляется, единственным решением , Я борюсь с той же проблемой с некоторым унаследованным кодом. У меня есть JFrame, что мне действительно нужно быть модальным. Выполнение работы, чтобы преобразовать все это в JDialog, действительно будет уродливым ... :-( –

+0

Можете ли вы его взломать? Создайте невидимый, модальный JDialog, создайте экземпляр JFrame и, когда JFrame будет закрыт, захватите значения, если необходимо, и закрыть JDialog – Redandwhite

+2

Ссылка не работает :(все еще люди пытаются учиться на этом 3 года! Попробуйте это в 2013 году: http://docs.oracle.com/javase/tutorial/uiswing/misc/ modality.html – Spork

4

Насколько я знаю, JFrame не может выполнять модальный режим. Вместо этого используйте JDialog и вызывайте setModalityType(Dialog.ModalityType type), чтобы установить его модальным (или не модальным).

15

Вы можете создать класс, которому передается ссылка на родителя JFrame и удерживает его в переменной JFrame. Затем вы можете заблокировать фрейм, который создал ваш новый фрейм.

parentFrame.disable(); 

//Some actions 

parentFrame.enable(); 
+0

приятно, заставило меня подумать о петле, чтобы «приостановить», (sleep) приложение, пока кадр isVisible(), thx! –

+0

Kamil, Imgonzalves, вы можете уточнить для меня? Вы хотите сказать, что новый класс должен быть создан в JDialog, JFrame или что-то, что создает объект OP JFra меня? –

-2

не уверен, что contetns вашего JFrame, если вы спросите некоторый вклад от пользователей, вы можете использовать JOptionPane, это может также установить JFrame в качестве модального

  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

Если вы готовы использовать JDialog вместо JFrame, вы можете установить ModalityType на APPLICATION_MODAL.

Это обеспечивает идентичное поведение вашего типичного 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(); 
} 
} 
0

Там немного кода, который может помочь:

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. Создать новую JPanel форму
  2. Добавить желаемые компоненты и код к нему

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


Ваш модальным ждет ...

+0

У, но есть кнопка ОК, которую я не хочу. –

+0

Подождите, что? Вы можете просто добавить JPanel в JDialog? – Zizouz212

+0

это не имеет никакого отношения к jFrame –

0

Что я сделал в этом случае, в первичном JFrame, что я хочу, чтобы сохранить видимую (например, рамку меню), Отмените выбор опции focusableWindowState в окне свойств, чтобы оно было FALSE. Как только это будет сделано, jframes, которые я называю, не теряет фокуса, пока я не закрою их.

4

просто заменить JFrame на JDialog в классе

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

, а затем написать setModal(true); в конструкторе

После этого вы сможете построить вашу форму в NetBeans и форма становится модальное

+0

Не знал о 'setModal (true);' это замечательно – db2791

+0

нужно сказать, что это не работает под netbeans, потому что его редактор форм устанавливает закрытие операции при закрытии диалога, который не является разрешено в jdialog –

1

Этот статический метод полезности показывает модальный JFrame, тайно открывая модальный JDialog. Я использовал это успешно и с правильным поведением в Windows 7, 8 и 10-с-несколькими-рабочими столами.

Это очень хороший пример для очень редко используемой функции местных классов.

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

Самый простой способ состоит в использовании пакет() метод визуализации, прежде чем JFrame объект. вот пример:

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

как это даже связано? – Enerccio