我用一个按钮打开一个 window 。在 window 里面是另一个按钮,它关闭刚刚打开的 window 并启用第一个按钮
I use a button to open a window . And inside that window is another button which closes the window just opened and enables the first button
我制作了一个创建新 window 的按钮,但已禁用。在我创建的新 window 中,我输入另一个按钮关闭这个新打开的 window 并启用第一个按钮。我不知道该怎么做
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == button) {
button.setEnabled(false);
JButton button3 = new JButton();
button3.setBounds(1,1,50,25);
button3.addActionListener(this);
JFrame y = new JFrame();
y.setVisible(true);
y.setSize(240,240);
y.setLocationRelativeTo(null);
y.add(button3);
71. //here I want to use button3 to close window y and enable button 1 again, but how I
//make the button 3 do that?
if (e.getSource() == button3) {
button.setEnabled(true);
y.setVisible(false);
}
我无法读取 button3 的操作。
如果你能告诉我怎么做,我将不胜感激。
您必须在 class 中初始化 Jbutton button3,而不是在方法 actionPerformed() 中,并且您必须将 if(e.getSource() == button3) 放在方法中,而不是在第一个范围if-branch
谢谢约翰,非常棒。
我现在分享我的代码,(因为我知道它没用)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
//go to line 71 and I am extremely sorry for including this long code
public class w extends JFrame implements ActionListener {
private static final long serialVersionUID = 1005007250764256307L;
public JButton button = new JButton();
public JButton button2;
JPanel panel;
boolean b = true;
w(){
button.setBounds(100,100,100,50);
button.addActionListener(this);
button.setBackground(Color.blue);
button.setText("Settings");
button.setFocusable(false);
button.setForeground(Color.green);
button.setEnabled(b);
button2 = new JButton();
button2.setBounds(200,200,100,50);
button2.addActionListener(this);
button2.setBackground(Color.red);
button2.setText("About");
button2.setFocusable(false);
button2.setForeground(Color.blue);
button2.setEnabled(true);
panel = new JPanel();
panel.setBounds(0, 0, 420, 420);
panel.setBackground(Color.GREEN);
this.setVisible(true);
this.setSize(420,420);
this.setLocationRelativeTo(null);
this.setTitle("Kukur er Maa");
this.setResizable(false);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.add(button);
this.add(button2);
this.setLayout(null);
}
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == button) {
button.setEnabled(false);
JFrame y = new JFrame();
JButton button3 = new JButton();
button3.setBounds(0,0,100,50);
button3.setBackground(Color.blue);
button3.setText("Back");
button3.setFocusable(false);
button3.setForeground(Color.green);
button3.setEnabled(true);
button3.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == button3) {
y.setVisible(false);
button.setEnabled(true);
}
}
});
y.setVisible(true);
y.setSize(420,420);
y.setLocationRelativeTo(null);
y.add(button3);
y.setLayout(null);
//here I want to use button3 to close window y and enable button 1 again, but how I
//make the button 3 do that?
if (e.getSource() == button3) {
button.setEnabled(true);
y.setVisible(false);
}
}
else if(e.getSource()== button2) {
JFrame ne = new JFrame("About");
ne.setVisible(true);
ne.setSize(240,240);
ne.setLocationRelativeTo(null);
button2.setEnabled(false);
}
}
}
您的代码和问题可以改进,包括:
- 任何“child”windows 不应是 JFrames,而是对话框 windows。 JFrames 用于 application windows,并且一次只应显示其中一个(实际上,只应创建一个),而当您的应用程序需要依赖 sub-windows 或 "child" windows,那么标准做法是使用对话框,Swing 将其实现为
JDialog
s。这些不会显示在 OS 的任务栏中(而 JFrames 会显示),并且单个应用程序应该只在 OS 的任务栏中显示一个任务。
- Swing JDialogs 有两种主要类型,模态和 non-modal。模态对话框,如 JOptionPane,阻止用户与 parent window 交互,直到对话框不再可见,而 non-modal 对话框(例如绘图程序的编辑器工具箱)允许与 parent window 互动。您的应用程序可能应该使用 modal 对话框。
- JDialogs 的创建方式与 JFrame 的创建方式大致相同,不同之处在于您应该将对 parent window 的引用传递到 JDialog 的构造函数中,并且如果对话框是否是模态的,通过 ModalityType 参数。
- 如果childwindow是模态JDialog,如果你想re-activate主parentwindow,你所要做的就是在下面的示例中通过
window.dispose()
关闭 child window
- 最好为程序的不同部分创建单独的 classes,例如 class(或经常不止一个)主要 window 和 classes 用于任何 child windows。如果需要,您可以将侦听器添加到其构造函数中的 child window classes(如下所示)。
其他更小的问题:
- 最好避免空布局和
setBounds(...)
,而是学习和使用 Swing 布局管理器来帮助您构建更容易构建、在所有 OS 上看起来都不错的 GUI以后很容易改变
- 如果您使用 modal JDialog,则无需禁用主要 window 的按钮,因为通过模态,用户无法与主要 window 直到对话框不再可见。
- 让 class 扩展 JFrame 可能会让您陷入困境,迫使您创建和显示 JFrame,而这通常需要更大的灵活性。事实上,我敢说我创建的和看到的大多数 Swing GUI 代码 没有 扩展 JFrame,事实上,您很少会想做这个。更常见的是,您的 GUI classes 将适用于创建 JPanel,然后可以将其放入 JFrames 或 JDialogs,或 JTabbedPanes,或通过 CardLayouts 在任何需要的地方进行交换。这将大大增加您的 GUI 编码的灵活性。
例如(请参阅代码中的注释):
import java.awt.Font;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.Dialog.ModalityType;
import javax.swing.*;
@SuppressWarnings("serial")
// Avoid extending JFrame and instead extend JPanel. Even this is not necessary
public class W2Panel extends JPanel {
// I like using larger fonts if I want my buttons to be larger
private static final Font BTN_FONT = new Font(Font.SANS_SERIF, Font.BOLD, 24);
// variables for the 2 JButtons:
private JButton settingsButton = new JButton("Settings");
private JButton aboutButton = new JButton("About");
// variable for the sub window
private W2SettingsPanel w2SettingsPanel;
public W2Panel() {
// avoid setting sizes and instead set properties and let the GUI size itself
int gap = 120;
setBorder(BorderFactory.createEmptyBorder(gap, gap, gap, gap));
settingsButton.setFont(BTN_FONT);
aboutButton.setFont(BTN_FONT);
// add an ActionListener to the JButton
settingsButton.addActionListener(e -> settingsAction());
// use layouts to set position of things
JPanel innerPanel = new JPanel(new GridLayout(3, 2));
innerPanel.add(settingsButton);
innerPanel.add(new JLabel(" "));
innerPanel.add(new JLabel(" "));
innerPanel.add(new JLabel(" "));
innerPanel.add(new JLabel(" "));
innerPanel.add(aboutButton);
// nest JPanels where needed
setLayout(new GridBagLayout());
add(innerPanel);
}
private void settingsAction() {
// if settings panel not yet created, then create it
if (w2SettingsPanel == null) {
// this gets a reference to the main JFrame:
Window window = SwingUtilities.getWindowAncestor(this);
// call the W2SettingsPanel constructor, passing in the JFrame's reference
w2SettingsPanel = new W2SettingsPanel(window);
}
w2SettingsPanel.display();
}
@SuppressWarnings("unused") // TODO: remove this
private void aboutActions() {
// TODO: create and display a modal dialog to display here as well
}
public static void main(String[] args) {
// create and display the main GUI in a Swing safe manner
SwingUtilities.invokeLater(() -> {
// create an instance of this class
W2Panel mainPanel = new W2Panel();
// create a JFrame, and add this instance into it
JFrame frame = new JFrame("GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(mainPanel);
frame.pack(); // let layouts do their thing and size the GUI
frame.setLocationRelativeTo(null); // center the GUI
frame.setVisible(true); // show it!
});
}
}
@SuppressWarnings("serial")
class W2SettingsPanel extends JPanel {
private static final Font BTN_FONT = new Font(Font.SANS_SERIF, Font.BOLD, 24);
private JDialog dialog;
private JButton backButton = new JButton("Back");
public W2SettingsPanel(Window window) {
int gap = 200;
setBorder(BorderFactory.createEmptyBorder(0, 0, gap, gap));
backButton.setFont(BTN_FONT);
backButton.addActionListener(e -> backAction());
add(backButton);
dialog = new JDialog(window, "Settings", ModalityType.APPLICATION_MODAL);
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.add(this);
dialog.pack();
dialog.setLocationRelativeTo(window);
}
public void backAction() {
// get the enclosing window (here a JDialog)
Window window = SwingUtilities.getWindowAncestor(this);
window.dispose(); // and dispose of it, make it disappear
}
public void display() {
dialog.setVisible(true);
}
}
我制作了一个创建新 window 的按钮,但已禁用。在我创建的新 window 中,我输入另一个按钮关闭这个新打开的 window 并启用第一个按钮。我不知道该怎么做
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == button) {
button.setEnabled(false);
JButton button3 = new JButton();
button3.setBounds(1,1,50,25);
button3.addActionListener(this);
JFrame y = new JFrame();
y.setVisible(true);
y.setSize(240,240);
y.setLocationRelativeTo(null);
y.add(button3);
71. //here I want to use button3 to close window y and enable button 1 again, but how I
//make the button 3 do that?
if (e.getSource() == button3) {
button.setEnabled(true);
y.setVisible(false);
}
我无法读取 button3 的操作。 如果你能告诉我怎么做,我将不胜感激。
您必须在 class 中初始化 Jbutton button3,而不是在方法 actionPerformed() 中,并且您必须将 if(e.getSource() == button3) 放在方法中,而不是在第一个范围if-branch
谢谢约翰,非常棒。 我现在分享我的代码,(因为我知道它没用)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
//go to line 71 and I am extremely sorry for including this long code
public class w extends JFrame implements ActionListener {
private static final long serialVersionUID = 1005007250764256307L;
public JButton button = new JButton();
public JButton button2;
JPanel panel;
boolean b = true;
w(){
button.setBounds(100,100,100,50);
button.addActionListener(this);
button.setBackground(Color.blue);
button.setText("Settings");
button.setFocusable(false);
button.setForeground(Color.green);
button.setEnabled(b);
button2 = new JButton();
button2.setBounds(200,200,100,50);
button2.addActionListener(this);
button2.setBackground(Color.red);
button2.setText("About");
button2.setFocusable(false);
button2.setForeground(Color.blue);
button2.setEnabled(true);
panel = new JPanel();
panel.setBounds(0, 0, 420, 420);
panel.setBackground(Color.GREEN);
this.setVisible(true);
this.setSize(420,420);
this.setLocationRelativeTo(null);
this.setTitle("Kukur er Maa");
this.setResizable(false);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.add(button);
this.add(button2);
this.setLayout(null);
}
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == button) {
button.setEnabled(false);
JFrame y = new JFrame();
JButton button3 = new JButton();
button3.setBounds(0,0,100,50);
button3.setBackground(Color.blue);
button3.setText("Back");
button3.setFocusable(false);
button3.setForeground(Color.green);
button3.setEnabled(true);
button3.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == button3) {
y.setVisible(false);
button.setEnabled(true);
}
}
});
y.setVisible(true);
y.setSize(420,420);
y.setLocationRelativeTo(null);
y.add(button3);
y.setLayout(null);
//here I want to use button3 to close window y and enable button 1 again, but how I
//make the button 3 do that?
if (e.getSource() == button3) {
button.setEnabled(true);
y.setVisible(false);
}
}
else if(e.getSource()== button2) {
JFrame ne = new JFrame("About");
ne.setVisible(true);
ne.setSize(240,240);
ne.setLocationRelativeTo(null);
button2.setEnabled(false);
}
}
}
您的代码和问题可以改进,包括:
- 任何“child”windows 不应是 JFrames,而是对话框 windows。 JFrames 用于 application windows,并且一次只应显示其中一个(实际上,只应创建一个),而当您的应用程序需要依赖 sub-windows 或 "child" windows,那么标准做法是使用对话框,Swing 将其实现为
JDialog
s。这些不会显示在 OS 的任务栏中(而 JFrames 会显示),并且单个应用程序应该只在 OS 的任务栏中显示一个任务。 - Swing JDialogs 有两种主要类型,模态和 non-modal。模态对话框,如 JOptionPane,阻止用户与 parent window 交互,直到对话框不再可见,而 non-modal 对话框(例如绘图程序的编辑器工具箱)允许与 parent window 互动。您的应用程序可能应该使用 modal 对话框。
- JDialogs 的创建方式与 JFrame 的创建方式大致相同,不同之处在于您应该将对 parent window 的引用传递到 JDialog 的构造函数中,并且如果对话框是否是模态的,通过 ModalityType 参数。
- 如果childwindow是模态JDialog,如果你想re-activate主parentwindow,你所要做的就是在下面的示例中通过
window.dispose()
关闭 child window
- 最好为程序的不同部分创建单独的 classes,例如 class(或经常不止一个)主要 window 和 classes 用于任何 child windows。如果需要,您可以将侦听器添加到其构造函数中的 child window classes(如下所示)。
其他更小的问题:
- 最好避免空布局和
setBounds(...)
,而是学习和使用 Swing 布局管理器来帮助您构建更容易构建、在所有 OS 上看起来都不错的 GUI以后很容易改变 - 如果您使用 modal JDialog,则无需禁用主要 window 的按钮,因为通过模态,用户无法与主要 window 直到对话框不再可见。
- 让 class 扩展 JFrame 可能会让您陷入困境,迫使您创建和显示 JFrame,而这通常需要更大的灵活性。事实上,我敢说我创建的和看到的大多数 Swing GUI 代码 没有 扩展 JFrame,事实上,您很少会想做这个。更常见的是,您的 GUI classes 将适用于创建 JPanel,然后可以将其放入 JFrames 或 JDialogs,或 JTabbedPanes,或通过 CardLayouts 在任何需要的地方进行交换。这将大大增加您的 GUI 编码的灵活性。
例如(请参阅代码中的注释):
import java.awt.Font;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.Dialog.ModalityType;
import javax.swing.*;
@SuppressWarnings("serial")
// Avoid extending JFrame and instead extend JPanel. Even this is not necessary
public class W2Panel extends JPanel {
// I like using larger fonts if I want my buttons to be larger
private static final Font BTN_FONT = new Font(Font.SANS_SERIF, Font.BOLD, 24);
// variables for the 2 JButtons:
private JButton settingsButton = new JButton("Settings");
private JButton aboutButton = new JButton("About");
// variable for the sub window
private W2SettingsPanel w2SettingsPanel;
public W2Panel() {
// avoid setting sizes and instead set properties and let the GUI size itself
int gap = 120;
setBorder(BorderFactory.createEmptyBorder(gap, gap, gap, gap));
settingsButton.setFont(BTN_FONT);
aboutButton.setFont(BTN_FONT);
// add an ActionListener to the JButton
settingsButton.addActionListener(e -> settingsAction());
// use layouts to set position of things
JPanel innerPanel = new JPanel(new GridLayout(3, 2));
innerPanel.add(settingsButton);
innerPanel.add(new JLabel(" "));
innerPanel.add(new JLabel(" "));
innerPanel.add(new JLabel(" "));
innerPanel.add(new JLabel(" "));
innerPanel.add(aboutButton);
// nest JPanels where needed
setLayout(new GridBagLayout());
add(innerPanel);
}
private void settingsAction() {
// if settings panel not yet created, then create it
if (w2SettingsPanel == null) {
// this gets a reference to the main JFrame:
Window window = SwingUtilities.getWindowAncestor(this);
// call the W2SettingsPanel constructor, passing in the JFrame's reference
w2SettingsPanel = new W2SettingsPanel(window);
}
w2SettingsPanel.display();
}
@SuppressWarnings("unused") // TODO: remove this
private void aboutActions() {
// TODO: create and display a modal dialog to display here as well
}
public static void main(String[] args) {
// create and display the main GUI in a Swing safe manner
SwingUtilities.invokeLater(() -> {
// create an instance of this class
W2Panel mainPanel = new W2Panel();
// create a JFrame, and add this instance into it
JFrame frame = new JFrame("GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(mainPanel);
frame.pack(); // let layouts do their thing and size the GUI
frame.setLocationRelativeTo(null); // center the GUI
frame.setVisible(true); // show it!
});
}
}
@SuppressWarnings("serial")
class W2SettingsPanel extends JPanel {
private static final Font BTN_FONT = new Font(Font.SANS_SERIF, Font.BOLD, 24);
private JDialog dialog;
private JButton backButton = new JButton("Back");
public W2SettingsPanel(Window window) {
int gap = 200;
setBorder(BorderFactory.createEmptyBorder(0, 0, gap, gap));
backButton.setFont(BTN_FONT);
backButton.addActionListener(e -> backAction());
add(backButton);
dialog = new JDialog(window, "Settings", ModalityType.APPLICATION_MODAL);
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.add(this);
dialog.pack();
dialog.setLocationRelativeTo(window);
}
public void backAction() {
// get the enclosing window (here a JDialog)
Window window = SwingUtilities.getWindowAncestor(this);
window.dispose(); // and dispose of it, make it disappear
}
public void display() {
dialog.setVisible(true);
}
}