Приложение Java swing, закройте одно окно и откройте другое, когда нажата кнопка
У меня есть приложение Java netbeans, которое должно отображать JFrame (класс StartUpWindow расширяет JFrame) с некоторыми параметрами при запуске приложения, затем пользователь нажимает кнопку и что JFrame должен быть закрыт, а новый (класс MainWindow) должен открывается.
Итак, как мне это сделать правильно. Я, очевидно, устанавливаю обработчик щелчка на кнопке в StartupWindow, но что я помещаю в этот обработчик, чтобы я мог закрыть StartUpWindow и открыть MainWindow? Похоже, что в это тоже входит нить, так как каждое окно, похоже, имеет собственный поток... или проблемы с потоками, которые автоматически обрабатываются самими JFrames...
Ответы
Ответ 1
Вот пример:
![enter image description here]()
![enter image description here]()
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);
}
}
Ответ 2
Вы можете вызвать dispose()
в текущем окне и setVisible(true)
на тот, который вы хотите отобразить.
Ответ 3
Это, очевидно, сценарий, в котором вы должны использовать CardLayout. Здесь вместо того, чтобы открывать два JFrame, вы можете просто изменить JPanels, используя CardLayout.
И код, который отвечает за создание и отображение вашего графического интерфейса, должен находиться внутри SwingUtilities.invokeLater(...); метод для обеспечения безопасности потоков. Для получения дополнительной информации вы должны прочитать о Concurrency в Swing.
Но если вы хотите придерживаться своего подхода, вот пример кода для вашей справки.
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();
}
});
}
}
И выход будет:
и ![Frame2]()
Ответ 4
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");
}
//вы можете запускать другие приложения, используя его, и можете разрезать весь проект во многих приложениях. Это
будет работать много
Ответ 5
Используйте this.dispose
для закрытия текущего окна и next_window.setVisible(true)
, чтобы отобразить следующее окно позади свойства кнопки ActionPerformed
. Пример показан ниже в pic для вашей помощи.
![введите описание изображения здесь]()
Ответ 6
Вызов метода ниже сразу после вызова метода для открытия нового окна, это закроет текущее окно.
private void close(){
WindowEvent windowEventClosing = new WindowEvent(this, WindowEvent.WINDOW_CLOSING);
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(windowEventClosing);
}
Также в свойствах JFrame убедитесь, что defaultCloseOperation установлено как DISPOSE.