Ho creato una GUI in cui ho usato un JFrame. Come dovrei renderlo modale?Come creare un JFrame Modal in Swing java
risposta
La soluzione migliore è utilizzare un JDialog anziché un JFrame se si desidera rendere la finestra modale. Controlla details on the introduction of the Modality API in Java 6 per informazioni. C'è anche a tutorial.
Ecco alcuni esempi di codice che visualizzeranno uno JPanel panel
in un JDialog
che è modale su Frame parentFrame
. Ad eccezione del costruttore, questo segue lo stesso schema dell'apertura di JFrame
.
final JDialog frame = new JDialog(parentFrame, frameTitle, true);
frame.getContentPane().add(panel);
frame.pack();
frame.setVisible(true);
Edit: aggiornato collegamento API Modalità & aggiunto il link tutorial (cenno al @spork per l'urto).
Paura che sembra essere l'unica soluzione . Sto combattendo lo stesso problema con un codice ereditato. Ho una JFrame che ho davvero bisogno di essere modale. Fare il lavoro per convertire tutto in JDialog sarà davvero brutto ... :-( –
Puoi hackerarlo? Crea un JDialog invisibile, modale, crea un'istanza di JFrame e, quando JFrame è chiuso, cattura i valori se necessario e chiudi il JDialog – Redandwhite
Il collegamento è interrotto: (ancora le persone cercano di imparare da questo 3 anni in poi! Prova questo nel 2013: http://docs.oracle.com/javase/tutorial/uiswing/misc/ modality.html – Spork
Per quanto ne so, JFrame non può eseguire la modalità modale. Utilizzare invece JDialog e chiamare setModalityType(Dialog.ModalityType type)
per impostarlo come modale (o non modale).
È possibile creare una classe che ha passato un riferimento al genitore JFrame
e la tiene in una variabile JFrame
. Quindi puoi bloccare la cornice che ha creato il tuo nuovo frame.
parentFrame.disable();
//Some actions
parentFrame.enable();
nice, mi ha fatto pensare su un loop per "sospendere" (sleep) l'applicazione mentre il frame isVisible(), thx! –
Kamil, Imgonzalves, puoi chiarire per me? Stai dicendo che la nuova classe dovrebbe essere creata in JDialog, JFrame o qualsiasi altra cosa crei l'oggetto dell'OP JFra me? –
non che i contetns del vostro JFrame, se chiedete qualche input da parte degli utenti, è possibile utilizzare JOptionPane, anche questo può impostare JFrame come modale
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");
}
Se siete pronti ad utilizzare un JDialog anziché JFrame, è possibile impostare il ModalityType su APPLICATION_MODAL.
Questo fornisce un comportamento identico al vostro tipico 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();
}
}
C'è un po 'di codice che potrebbe aiutare:
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);
}
}
- Crea una nuova forma JPanel
- Aggiungi i componenti desiderati e codice
YourJPanelForm stuff = new YourJPanelForm();
JOptionPane.showMessageDialog(null,stuff,"Your title here bro",JOptionPane.PLAIN_MESSAGE);
tua finestra di dialogo modale attende ...
Ou, ma c'è un pulsante OK, che non voglio. –
Aspetta cosa? Puoi semplicemente aggiungere JPanel al JDialog in questo modo? – Zizouz212
questo non ha nulla a che fare con un jFrame –
Quello che ho fatto in questo caso è, nel JFrame principale che voglio mantenere visibile (per esempio, una cornice di menu), Deseleziono l'opzione focusableWindowState
nella finestra delle proprietà, quindi sarà FALSE
. Una volta fatto, i jframes che chiamo non perdono la concentrazione finché non li chiudo.
basta sostituire JFrame
-JDialog
in classe
public class MyDialog extends JFrame // delete JFrame and write JDialog
e poi scrivere setModal(true);
nel costruttore
Dopo che si sarà in grado di costruire il modulo in NetBeans e la forma diventa modale
Non era a conoscenza di 'setModal (true);' .. questo è ottimo – db2791
necessario dire che questo non funziona con netbeans perché il suo editor di form imposta l'operazione di chiusura sul dialogo di chiusura che non è consentito in jdialog –
Questo metodo di utilità statica mostra un JFrame modale aprendo anche un JDialog modale. L'ho usato con successo e con un comportamento corretto su Windows 7, 8 e 10 con più desktop.
È un bell'esempio della funzione utilizzata raramente nelle classi locali.
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);
}
Il modo più semplice è quello di utilizzare pack() metodo prima della visualizzazione della oggetto JFrame. ecco un esempio:
myFrame frm = new myFrame();
frm.pack();
frm.setVisible(true);
come è correlato? – Enerccio
Vedi anche [? L'uso di JFrames multipli, buona/cattiva pratica] (http://stackoverflow.com/a/9554657/418556) –