[英]How to make a JFrame Modal in Swing java
我創建了一個使用 JFrame 的 GUI。 我應該如何使它成為模態?
如果要使窗口模式化,最好的辦法是使用 JDialog 而不是 JFrame。 查看有關在 Java 6 中引入 Modality API 的詳細信息以獲取信息。 還有一個教程。
這是一些示例代碼,它將在JDialog
顯示一個JPanel panel
,該JPanel panel
是Frame parentFrame
模態。 除了構造函數之外,這與打開JFrame
遵循相同的模式。
final JDialog frame = new JDialog(parentFrame, frameTitle, true);
frame.getContentPane().add(panel);
frame.pack();
frame.setVisible(true);
編輯:更新了 Modality API 鏈接並添加了教程鏈接(向 @spork 致敬)。
您可以創建一個類,該類將引用傳遞給父JFrame
並將其保存在JFrame
變量中。 然后您可以鎖定創建新框架的框架。
parentFrame.disable();
//Some actions
parentFrame.enable();
只需在類中將JFrame
替換為JDialog
public class MyDialog extends JFrame // delete JFrame and write JDialog
然后寫setModal(true);
在構造函數中
之后,您將能夠在 netbeans 中構建您的表單,並且該表單將變為模態
YourJPanelForm stuff = new YourJPanelForm();
JOptionPane.showMessageDialog(null,stuff,"Your title here bro",JOptionPane.PLAIN_MESSAGE);
您的模態對話框等待...
據我所知,JFrame 不能做模態模式。 改用 JDialog 並調用setModalityType(Dialog.ModalityType type)
將其設置為模態(或非模態)。
如果您准備使用 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();
}
}
這個靜態實用方法也通過秘密打開一個模態 JDialog 來顯示一個模態 JFrame。 我在 Windows 7、8 和 10-with-multiple-desktops 上成功地使用了它並且行為正確。
這是本地類很少使用的特性的一個很好的例子。
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);
}
唯一對我有用的代碼:
childFrame.setAlwaysOnTop(true);
在使子/模態框架可見之前,應在主/父框架上調用此代碼。 你的孩子/模態框架也應該有這個代碼:
parentFrame.setFocusableWindowState(false);
this.mainFrame.setEnabled(false);
在這種情況下,我所做的是,在我想要保持可見的主 jframe(例如,菜單框架)中,我取消選擇屬性窗口中的選項focusableWindowState
因此它將是FALSE
。 完成后,我調用的 jframe 不會失去焦點,直到我關閉它們。
正如其他人提到的,您可以使用 JDialog。 如果您無權訪問父框架或者您想凍結孔應用程序,只需將 null 作為父項傳遞:
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);
有一些代碼可能會有所幫助:
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);
}
}
不確定你的 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");
}
最簡單的方法是在可視化JFrame對象之前使用pack()方法。 這是一個例子:
myFrame frm = new myFrame();
frm.pack();
frm.setVisible(true);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.