J'ai une application Java Netbeans qui doit afficher une image JFrame (classe StartUpWindow (extension de JFrame)) avec certaines options au lancement de l'application, puis l'utilisateur clique sur un bouton. JFrame doit être fermé et une nouvelle (classe MainWindow) doit être ouverte.
Alors, comment puis-je faire cela correctement. J'ai évidemment défini un gestionnaire de clics sur le bouton dans StartupWindow, mais que dois-je mettre dans ce gestionnaire pour pouvoir fermer la fenêtre StartUpWindow et ouvrir la fenêtre principale? Il semble que les threads entrent aussi dans ce domaine car chaque fenêtre semble avoir son propre thread ... ou des problèmes de threads sont automatiquement gérés par JFrames eux-mêmes ...
Voici un exemple:
StartupWindow.Java
import Java.awt.event.ActionEvent;
import Java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class StartupWindow extends JFrame implements ActionListener
{
private JButton btn;
public StartupWindow()
{
super("Simple GUI");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
btn = new JButton("Open the other JFrame!");
btn.addActionListener(this);
btn.setActionCommand("Open");
add(btn);
pack();
}
@Override
public void actionPerformed(ActionEvent e)
{
String cmd = e.getActionCommand();
if(cmd.equals("Open"))
{
dispose();
new AnotherJFrame();
}
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run()
{
new StartupWindow().setVisible(true);
}
});
}
}
AnotherJFrame.Java
import javax.swing.JFrame;
import javax.swing.JLabel;
public class AnotherJFrame extends JFrame
{
public AnotherJFrame()
{
super("Another GUI");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(new JLabel("Empty JFrame"));
pack();
setVisible(true);
}
}
Vous pouvez appeler dispose()
sur la fenêtre actuelle et setVisible(true)
sur celle que vous souhaitez afficher.
Ceci est évidemment le cas où vous devriez utiliser CardLayout . Ici, au lieu d'ouvrir deux JFrame, vous pouvez simplement changer les JPanels en utilisant CardLayout.
Et le code responsable de la création et de l'affichage de votre interface graphique doit se trouver dans SwingUtilities.invokeLater (...); méthode pour qu'il soit Thread Safe. Pour plus d'informations, vous devez lire à propos de Concurrency in Swing .
Mais si vous souhaitez vous en tenir à votre approche, voici un exemple de code pour votre aide.
import Java.awt.*;
import Java.awt.event.*;
import javax.swing.*;
public class TwoFrames
{
private JFrame frame1, frame2;
private ActionListener action;
private JButton showButton, hideButton;
public void createAndDisplayGUI()
{
frame1 = new JFrame("FRAME 1");
frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame1.setLocationByPlatform(true);
JPanel contentPane1 = new JPanel();
contentPane1.setBackground(Color.BLUE);
showButton = new JButton("OPEN FRAME 2");
hideButton = new JButton("HIDE FRAME 2");
action = new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
JButton button = (JButton) ae.getSource();
/*
* If this button is clicked, we will create a new JFrame,
* and hide the previous one.
*/
if (button == showButton)
{
frame2 = new JFrame("FRAME 2");
frame2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame2.setLocationByPlatform(true);
JPanel contentPane2 = new JPanel();
contentPane2.setBackground(Color.DARK_GRAY);
contentPane2.add(hideButton);
frame2.getContentPane().add(contentPane2);
frame2.setSize(300, 300);
frame2.setVisible(true);
frame1.setVisible(false);
}
/*
* Here we will dispose the previous frame,
* show the previous JFrame.
*/
else if (button == hideButton)
{
frame1.setVisible(true);
frame2.setVisible(false);
frame2.dispose();
}
}
};
showButton.addActionListener(action);
hideButton.addActionListener(action);
contentPane1.add(showButton);
frame1.getContentPane().add(contentPane1);
frame1.setSize(300, 300);
frame1.setVisible(true);
}
public static void main(String... args)
{
/*
* Here we are Scheduling a JOB for Event Dispatcher
* Thread. The code which is responsible for creating
* and displaying our GUI or call to the method which
* is responsible for creating and displaying your GUI
* goes into this SwingUtilities.invokeLater(...) thingy.
*/
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new TwoFrames().createAndDisplayGUI();
}
});
}
}
Et le résultat sera:
et
final File open = new File("PicDic.exe");
if (open.exists() == true) {
if (Desktop.isDesktopSupported()) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
Desktop.getDesktop().open(open);
} catch (IOException ex) {
return;
}
}
});
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
//DocumentEditorView.this.getFrame().dispose();
System.exit(0);
}
});
} else {
JOptionPane.showMessageDialog(this.getFrame(), "Desktop is not support to open editor\n You should try manualy");
}
} else {
JOptionPane.showMessageDialog(this.getFrame(), "PicDic.exe is not found");
}
// vous pouvez démarrer une autre application en l'utilisant et diviser votre projet en plusieurs applications. ça marche beaucoup
Vous pouvez masquer une partie de JFrame contenant les commandes de basculement souhaitées sur un autre JFrame.
Lorsque l'utilisateur clique sur un Jbutton, la largeur de JFrame augmente et, lorsqu'il clique sur un autre type de Jbutton, le JFrame reprend sa taille par défaut.
JFrame myFrame = new JFrame("");
JButton button1 = new JButton("Basic");
JButton button2 = new JButton("More options");
// actionPerformed block code for button1 (Default size)
myFrame.setSize(400, 400);
// actionPerformed block code for button2 (Increase width)
myFrame.setSize(600, 400);
Appelez la méthode juste après avoir appelé la méthode d'ouverture d'une nouvelle fenêtre, la fenêtre actuelle sera fermée.
private void close(){
WindowEvent windowEventClosing = new WindowEvent(this, WindowEvent.WINDOW_CLOSING);
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(windowEventClosing);
}
Toujours dans les propriétés de JFrame, assurez-vous que defaultCloseOperation est défini surDISPOSE.