我用一个按钮打开一个 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 将其实现为 JDialogs。这些不会显示在 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);
    }
}