J'ai créé une interface graphique dans laquelle j'ai utilisé un cadre JFrame. Comment devrais-je le rendre modal?
Votre meilleur pari est d'utiliser un JDialog au lieu d'un JFrame si vous voulez rendre la fenêtre modale. Consultez les détails sur l'introduction de l'API Modality en Java 6 pour plus d'informations. Il y a aussi un tutoriel .
Voici un exemple de code qui affichera un JPanel panel
dans une JDialog
modale de Frame parentFrame
. À l'exception du constructeur, cela suit le même modèle que l'ouverture d'une JFrame
.
final JDialog frame = new JDialog(parentFrame, frameTitle, true);
frame.getContentPane().add(panel);
frame.pack();
frame.setVisible(true);
Edit: mise à jour du lien API de modalité et ajout du lien vers le tutoriel (nod à @spork pour la bosse)
Vous pouvez créer une classe à laquelle est transmise une référence au parent JFrame
et la conserver dans une variable JFrame
. Ensuite, vous pouvez verrouiller le cadre qui a créé votre nouveau cadre.
parentFrame.disable();
//Some actions
parentFrame.enable();
remplacez simplement JFrame
par JDialog
en classe
public class MyDialog extends JFrame // delete JFrame and write JDialog
puis écrivez setModal(true);
dans le constructeur
Après cela, vous pourrez construire votre formulaire dans netbeans Et le formulaire deviendra modal.
YourJPanelForm stuff = new YourJPanelForm();
JOptionPane.showMessageDialog(null,stuff,"Your title here bro",JOptionPane.PLAIN_MESSAGE);
Votre dialogue modal vous attend ...
Pour autant que je sache, JFrame ne peut pas utiliser le mode modal. Utilisez plutôt JDialog et appelez setModalityType(Dialog.ModalityType type)
pour le définir comme modal (ou non modal).
Si vous êtes prêt à utiliser un JDialog au lieu d'un JFrame, vous pouvez définir ModalityType sur APPLICATION_MODAL.
Cela fournit un comportement identique à votre JOptionPane typique:
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();
}
}
Cette méthode d’utilité statique montre un JFrame modal en ouvrant secrètement un JDialog modal. Je l'ai utilisé avec succès et avec le comportement approprié sous Windows 7, 8 et 10 avec plusieurs bureaux.
C'est un bel exemple de la fonctionnalité très rarement utilisée de local classes.
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);
}
Ce que j’ai fait dans ce cas-ci, c’est que, dans le cadre principal j que je souhaite garder visible (par exemple, un cadre de menu), je désélectionne l’option focusableWindowState
dans la fenêtre de propriété afin qu’elle soit FALSE
. Une fois que cela est fait, les jframes que j’appelle ne perdent pas le focus jusqu’à ce que je les ferme.
Comme d'autres l'ont mentionné, vous pouvez utiliser JDialog. Si vous n'avez pas accès au cadre parent ou si vous souhaitez figer l'application de trou, passez simplement null en tant que parent:
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);
Il y a un peu de code qui pourrait aider:
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);
}
}