在我处理现有框架并设置新框架(重新实例化另一个框架)后,JButton 根本不起作用

JButton doesn't work at all after i dispose existing frame and sets the new frame(re instantiate another frame)

我做了一个计算器,为了增加它的功能和简单性,我做了三个框架,支持简单、科学和转换计算器

计算器工作完美,直到我使用它一次但是当我将我的计算器类型从简单更改为科学和科学转换然后再次更改为简单计算器时,程序根本不执行任何操作,jbutton 不执行任何操作action even actionPerformed 被调用 我通过将 println 语句放在方法 actionPerformed 中检查了这一点。

我在构造函数中实例化了我的三个框架,并且我为每个计算器类型创建了三种方法来实例化按钮和其他内容并将其添加到 JPanels 并将面板添加到 JFrame

//Constructor
public Calculator()
{

    //instantiating buttons
            buttons = new JButton[15];
            optionButtons = new JButton[5];
            scientificOptionButtons = new JButton[20];
            constantButtons = new JButton[5];

            //instantiating calculatorFrames
            simpleCalculatorFrame = new JFrame("Calculator");
            scientificCalculatorFrame = new JFrame("Scientific Calculator");
            convertCalculatorFrame = new JFrame("Conversion Calculator");

    } // end of the constructor

当我从我的 JMenuItems 中选择计算器类型时,我处理活动框架并调用其他计算器类型方法来创建和添加内容到面板并设置框架,例如

//if statements inside method actionPerformed to check which type of calculator should run
if(event.getSource() == scientificMenuItem)
        {
            if(simpleCalculatorFrame.isActive())
            {
                simpleCalculatorFrame.dispose();
                scientificCalculatorBuilder();
            }
            else if(convertCalculatorFrame.isActive())
            {
                convertCalculatorFrame.dispose();
                scientificCalculatorBuilder();
            }

        }
        else if(event.getSource() == simpleMenuItem)
        {
            if(scientificCalculatorFrame.isActive())
            {
                scientificCalculatorFrame.dispose();
                simpleCalculatorBuilder();
            }
            else if(convertCalculatorFrame.isActive())
            {
                convertCalculatorFrame.dispose();
                simpleCalculatorBuilder();
            }

        }
        else if(event.getSource() == convertMenuItem)
        {
            if(simpleCalculatorFrame.isActive())
            {
                simpleCalculatorFrame.dispose();
                convertCalculatorBuilder();
            }
            else if(scientificCalculatorFrame.isActive())
            {

                scientificCalculatorFrame.dispose();
                convertCalculatorBuilder();
            }

        }
        else if(event.getSource() == exitMenuItem)
        {
            System.exit(0);
        }

一切看起来都很好,只是没有找到问题所在

这是实例化组件的方法代码

public void simpleCalculatorBuilder()
{


        //instantiating menuBar , fileMenu and menuItems and adding functionality
        menuBar = new JMenuBar();
        fileMenu = new JMenu("File");
        scientificMenuItem = new JMenuItem("Scientific Calculator");
        convertMenuItem = new JMenuItem("Conversion Calculator");
        convertMenuItem.addActionListener(handler);
        scientificMenuItem.addActionListener(handler);
        exitMenuItem = new JMenuItem("Exit");
        exitMenuItem.addActionListener(handler);
        menuBar.add(fileMenu);
        fileMenu.add(scientificMenuItem);
        fileMenu.add(convertMenuItem);
        fileMenu.add(exitMenuItem);

        //instantiating and adding textField appearing at the top of calculator to show ongoing processes and results
        myField = new JTextField();
        myField.setPreferredSize(new Dimension(this.getWidth() , 40));
        myField.setEditable(false);
        simpleCalculatorFrame.add(myField , BorderLayout.NORTH);

        //instantiating panels to hold buttons
        buttonsPanel = new JPanel(new GridLayout(5 , 3 , 3 , 6));
        optionButtonsPanel = new JPanel(new GridLayout(5, 1 , 3 , 3));


        //loop to add buttons to panel , adding eventListeners to buttons , setting background color of buttons
        for(int i = 0 ; i<buttons.length ; i++)
        {
            buttons[i] = new JButton(buttonTitles[i]);
            buttons[i].setBackground(Color.BLACK);
            buttons[i].setForeground(Color.WHITE);
            buttons[i].addActionListener(handler);
            buttons[i].addMouseListener(handler);
            buttonsPanel.add(buttons[i]);
            if(i<5)
            {
                optionButtons[i] = new JButton(optionButtonTitles[i]);
                optionButtons[i].setBackground(Color.BLACK);
                optionButtons[i].setForeground(Color.WHITE);
                optionButtons[i].addActionListener(handler);
                optionButtons[i].addMouseListener(handler);
                optionButtonsPanel.add(optionButtons[i]);
            }
        } 

        //setting background color of panels

        buttonsPanel.setBackground(Color.DARK_GRAY);
        optionButtonsPanel.setBackground(Color.DARK_GRAY);

        //adding items and panels to the frame and setting the simpleCalculatorFrame
        simpleCalculatorFrame.setJMenuBar(menuBar);
        simpleCalculatorFrame.add(buttonsPanel , BorderLayout.CENTER);
        simpleCalculatorFrame.add(optionButtonsPanel , BorderLayout.EAST);
        simpleCalculatorFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        simpleCalculatorFrame.setSize(240 , 270);
        simpleCalculatorFrame.setLocationRelativeTo(null);
        simpleCalculatorFrame.setVisible(true);
        simpleCalculatorFrame.setResizable(false);

} // end of simple calculator builder

public void scientificCalculatorBuilder()
{

    //instantiating menuBar , fileMenu and menuItems and adding functionality
    menuBar = new JMenuBar();
    fileMenu = new JMenu("File");
    simpleMenuItem = new JMenuItem("Simple Calculator");
    simpleMenuItem.addActionListener(handler);
    convertMenuItem = new JMenuItem("Conversion Calculator");
    convertMenuItem.addActionListener(handler);
    exitMenuItem = new JMenuItem("Exit");
    exitMenuItem.addActionListener(handler);
    menuBar.add(fileMenu);
    fileMenu.add(simpleMenuItem);
    fileMenu.add(convertMenuItem);
    fileMenu.add(exitMenuItem);

    //instantiating and adding textField appearing at the top of calculator to show ongoing processes and results
    myField = new JTextField();
    myField.setPreferredSize(new Dimension(this.getWidth() , 40));
    myField.setEditable(false);
    scientificCalculatorFrame.add(myField , BorderLayout.NORTH);

    //instantiating panels to hold buttons
    buttonsPanel = new JPanel(new GridLayout(5 , 3 , 3 , 6));
    optionButtonsPanel = new JPanel(new GridLayout(5, 1 , 3 , 3));
    scientificOptionButtonsPanel = new JPanel(new GridLayout(5 , 4 , 3 , 3));
    constantButtonsPanel = new JPanel(new GridLayout(5, 1 , 3 , 3));
    scientificPanelManager = new JPanel(new GridLayout(1 , 2));



    //loop to add buttons to panel , adding eventListeners to buttons , setting background color of buttons
    for(int i = 0 ; i<scientificOptionButtons.length ; i++)
    {
        if(i<5)
        {
            optionButtons[i] = new JButton(optionButtonTitles[i]);
            optionButtons[i].setBackground(Color.BLACK);
            optionButtons[i].setForeground(Color.WHITE);
            optionButtons[i].addActionListener(handler);
            optionButtons[i].addMouseListener(handler);
            optionButtonsPanel.add(optionButtons[i]);

            constantButtons[i] = new JButton(constantButtonTitles[i]);
            constantButtons[i].setBackground(Color.BLACK);
            constantButtons[i].setForeground(Color.WHITE);
            constantButtons[i].addActionListener(handler);
            constantButtons[i].addMouseListener(handler);
            constantButtonsPanel.add(constantButtons[i]);
        }
        if(i<15)
        {
            buttons[i] = new JButton(buttonTitles[i]);
            buttons[i].setBackground(Color.BLACK);
            buttons[i].setForeground(Color.WHITE);
            buttons[i].addActionListener(handler);
            buttons[i].addMouseListener(handler);
            buttonsPanel.add(buttons[i]);
        }
            scientificOptionButtons[i] = new JButton(scientificOptionButtonTitles[i]);
            scientificOptionButtons[i].setBackground(Color.BLACK);
            scientificOptionButtons[i].setForeground(Color.WHITE);
            scientificOptionButtons[i].addActionListener(handler);
            scientificOptionButtons[i].addMouseListener(handler);
            scientificOptionButtonsPanel.add(scientificOptionButtons[i]);
    }// end of for loop

    //setting background color of panels
    buttonsPanel.setBackground(Color.DARK_GRAY);
    optionButtonsPanel.setBackground(Color.DARK_GRAY);
    scientificOptionButtonsPanel.setBackground(Color.DARK_GRAY);
    constantButtonsPanel.setBackground(Color.DARK_GRAY);

    scientificPanelManager.add(scientificOptionButtonsPanel);
    scientificPanelManager.add(buttonsPanel);
    scientificCalculatorFrame.setJMenuBar(menuBar);
    scientificCalculatorFrame.add(constantButtonsPanel , BorderLayout.WEST);
    scientificCalculatorFrame.add(optionButtonsPanel , BorderLayout.EAST);
    scientificCalculatorFrame.add(scientificPanelManager , BorderLayout.CENTER);
    scientificCalculatorFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    scientificCalculatorFrame.setSize(580 , 300);
    scientificCalculatorFrame.setLocationRelativeTo(null);
    scientificCalculatorFrame.setVisible(true);
    scientificCalculatorFrame.setResizable(false);

} // end of scientificCalculatorBuilder


//method which starts convertCalculatorFrame and initializes frame needs
public void convertCalculatorBuilder()
{

    convertCalculatorTopPanel = new JPanel(new GridLayout(2 , 1 , 0 , 4));
    convertCalculatorCenterPanel = new JPanel(new GridLayout(2 , 2 , 5 , 3));
    convertCalculatorEastPanel = new JPanel(new GridLayout(2 , 1 ,1 , 3));
    convertCalculatorSouthPanel = new JPanel(new GridLayout(1 , 2 , 5 , 2));


    //instantiating menuBar , fileMenu and menuItems and adding functionality
            menuBar = new JMenuBar();
            fileMenu = new JMenu("File");
            simpleMenuItem = new JMenuItem("Simple Calculator");
            simpleMenuItem.addActionListener(handler);
            scientificMenuItem = new JMenuItem("Scientific Calculator");
            scientificMenuItem.addActionListener(handler);
            exitMenuItem = new JMenuItem("Exit");
            exitMenuItem.addActionListener(handler);
            menuBar.add(fileMenu);
            fileMenu.add(simpleMenuItem);
            fileMenu.add(scientificMenuItem);
            fileMenu.add(exitMenuItem);

    typeConvertCalculatorComboBox = new JComboBox<String>();
    typeConvertCalculatorComboBox.setBackground(Color.BLACK);
    typeConvertCalculatorComboBox.setForeground(Color.WHITE);
    typeConvertCalculatorComboBox.setMaximumRowCount(3);

    typeConvertCalculatorComboBox.addItem("Choose type of conversion");
    typeConvertCalculatorComboBox.addItem("Distance Conversion");
    typeConvertCalculatorComboBox.addItem("Memory Conversion");
    typeConvertCalculatorComboBox.addItem("Temperature Conversion");
    typeConvertCalculatorComboBox.addItem("Mass Conversion");

    typeConvertCalculatorComboBox.addActionListener(
            new ActionListener()
            {
                public void actionPerformed(ActionEvent event)
                {
                    if(typeConvertCalculatorComboBox.getSelectedItem() == "Distance Conversion")
                    {
                        fromConvertCalculatorComboBox.setEnabled(true);
                        toConvertCalculatorComboBox.setEnabled(true);

                        fromConvertCalculatorComboBox.removeAllItems();
                        fromConvertCalculatorComboBox.setMaximumRowCount(3);
                        fromConvertCalculatorComboBox.addItem("Centimeter(s)");
                        fromConvertCalculatorComboBox.addItem("Meter(s)");
                        fromConvertCalculatorComboBox.addItem("Kilometer(s)");
                        fromConvertCalculatorComboBox.addItem("Mile(s)");

                        toConvertCalculatorComboBox.removeAllItems();
                        toConvertCalculatorComboBox.setMaximumRowCount(2);
                        toConvertCalculatorComboBox.addItem("Centimeter(s)");
                        toConvertCalculatorComboBox.addItem("Meter(s)");
                        toConvertCalculatorComboBox.addItem("Kilometer(s)");
                        toConvertCalculatorComboBox.addItem("Mile(s)");

                    }
                    else if(typeConvertCalculatorComboBox.getSelectedItem() == "Memory Conversion")
                    {
                        fromConvertCalculatorComboBox.setEnabled(true);
                        toConvertCalculatorComboBox.setEnabled(true);

                        fromConvertCalculatorComboBox.removeAllItems();
                        fromConvertCalculatorComboBox.setMaximumRowCount(3);
                        fromConvertCalculatorComboBox.addItem("Kilobyte(s)");
                        fromConvertCalculatorComboBox.addItem("Megabyte(s)");
                        fromConvertCalculatorComboBox.addItem("Gigabyte(s)");
                        fromConvertCalculatorComboBox.addItem("Terabyte(s)");

                        toConvertCalculatorComboBox.removeAllItems();
                        toConvertCalculatorComboBox.setMaximumRowCount(2);
                        toConvertCalculatorComboBox.addItem("Kilobyte(s)");
                        toConvertCalculatorComboBox.addItem("Megabyte(s)");
                        toConvertCalculatorComboBox.addItem("Gigabyte(s)");
                        toConvertCalculatorComboBox.addItem("Terabyte(s)");
                    }
                    else if(typeConvertCalculatorComboBox.getSelectedItem() == "Temperature Conversion")
                    {
                        fromConvertCalculatorComboBox.setEnabled(true);
                        toConvertCalculatorComboBox.setEnabled(true);

                        fromConvertCalculatorComboBox.removeAllItems();
                        fromConvertCalculatorComboBox.addItem("Centigrade");
                        fromConvertCalculatorComboBox.addItem("Fahrenheit");
                        fromConvertCalculatorComboBox.addItem("Kelvin");

                        toConvertCalculatorComboBox.removeAllItems();
                        toConvertCalculatorComboBox.setMaximumRowCount(2);
                        toConvertCalculatorComboBox.addItem("Centigrade");
                        toConvertCalculatorComboBox.addItem("Fahrenheit");
                        toConvertCalculatorComboBox.addItem("Kelvin");
                    }
                    else if(typeConvertCalculatorComboBox.getSelectedItem() == "Mass Conversion")
                    {
                        fromConvertCalculatorComboBox.setEnabled(true);
                        toConvertCalculatorComboBox.setEnabled(true);

                        fromConvertCalculatorComboBox.removeAllItems();
                        fromConvertCalculatorComboBox.setMaximumRowCount(3);
                        fromConvertCalculatorComboBox.addItem("Milligram(s)");
                        fromConvertCalculatorComboBox.addItem("Pound(s) (lbs)");
                        fromConvertCalculatorComboBox.addItem("Kilogram(s)");

                        toConvertCalculatorComboBox.removeAllItems();
                        toConvertCalculatorComboBox.setMaximumRowCount(2);
                        toConvertCalculatorComboBox.addItem("Milligram(s)");
                        toConvertCalculatorComboBox.addItem("Pound(s) (lbs)");
                        toConvertCalculatorComboBox.addItem("Kilogram(s)");

                    }
                }
            }
            );

    fromConvertCalculatorComboBox = new JComboBox<String>();
    fromConvertCalculatorComboBox.setMaximumRowCount(3);
    fromConvertCalculatorComboBox.setBackground(Color.BLACK);
    fromConvertCalculatorComboBox.setForeground(Color.WHITE);
    fromConvertCalculatorComboBox.setEnabled(false);

    toConvertCalculatorComboBox = new JComboBox<String>();
    toConvertCalculatorComboBox.setMaximumRowCount(2);
    toConvertCalculatorComboBox.setBackground(Color.BLACK);
    toConvertCalculatorComboBox.setForeground(Color.WHITE);
    toConvertCalculatorComboBox.setEnabled(false);


        topConvertCalculatorLabel = new JLabel("What type of conversion you want ?");
        topConvertCalculatorLabel.setForeground(Color.WHITE);
        fromConvertCalculatorLabel = new JLabel("From");
        fromConvertCalculatorLabel.setForeground(Color.WHITE);
        toConvertCalculatorLabel = new JLabel("To");
        toConvertCalculatorLabel.setForeground(Color.WHITE);

        fromConvertCalculatorField = new JTextField();
        fromConvertCalculatorField.setPreferredSize(new Dimension(120 , 2));
        fromConvertCalculatorField.addActionListener(convertHandler);
        ansConvertCalculatorField = new JTextField();
        ansConvertCalculatorField.setEditable(false);

        convertButton = new JButton("Convert");
        convertButton.setBackground(Color.BLACK);
        convertButton.setForeground(Color.WHITE);
        convertButton.addMouseListener(handler);

        convertButton.addActionListener(convertHandler);



        convertCalculatorFrame.setJMenuBar(menuBar);

    //adding components to panel and adding panels to frame
    {
        convertCalculatorTopPanel.add(topConvertCalculatorLabel);
        convertCalculatorTopPanel.add(typeConvertCalculatorComboBox);
        convertCalculatorTopPanel.setBackground(Color.DARK_GRAY);
        convertCalculatorFrame.add(convertCalculatorTopPanel , BorderLayout.NORTH);

        convertCalculatorCenterPanel.add(fromConvertCalculatorLabel);
        convertCalculatorCenterPanel.add(fromConvertCalculatorComboBox);
        convertCalculatorCenterPanel.add(toConvertCalculatorLabel);
        convertCalculatorCenterPanel.add(toConvertCalculatorComboBox);
        convertCalculatorCenterPanel.setBackground(Color.DARK_GRAY);
        convertCalculatorFrame.add(convertCalculatorCenterPanel , BorderLayout.CENTER);

        convertCalculatorEastPanel.add(fromConvertCalculatorField);
        convertCalculatorEastPanel.setBackground(Color.DARK_GRAY);
        convertCalculatorFrame.add(convertCalculatorEastPanel , BorderLayout.EAST);

        convertCalculatorSouthPanel.add(convertButton);
        convertCalculatorSouthPanel.add(ansConvertCalculatorField);
        convertCalculatorSouthPanel.setBackground(Color.DARK_GRAY);
        convertCalculatorFrame.add(convertCalculatorSouthPanel , BorderLayout.SOUTH);

        convertCalculatorFrame.getContentPane().validate();
        convertCalculatorFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        convertCalculatorFrame.setSize(390 , 200);
        convertCalculatorFrame.setLocationRelativeTo(null);
        convertCalculatorFrame.setVisible(true);
        convertCalculatorFrame.setResizable(false);
    }
}//end of convertCalculatorBuilder

我没有太多编程经验希望大家不介意帮忙

这是一个 MCVE

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Test { 
public static void main(String[] args) {
        Practice application = new Practice();
        application.forFrame1();
}
}

class Practice extends JPanel
{
Handler handler = new Handler();

private JButton[] buttons;
private JButton[] moreButtons;

private JMenuBar menuBar;
private JMenu myMenu;
private JMenuItem firstItem;
private JMenuItem secondItem;

private JFrame frame1;
private JFrame frame2;

private JPanel panel1;
private JPanel panel2;

public Practice()
{
    buttons = new JButton[3];
    moreButtons = new JButton[5];

    frame1 = new JFrame();
    frame2 = new JFrame();
}
public void forFrame1()
{
    menuBar = new JMenuBar();
    myMenu = new JMenu("menu");
    secondItem = new JMenuItem("goto 2nd frame");
    secondItem.addActionListener(handler);
    menuBar.add(myMenu);
    myMenu.add(secondItem);

    frame1.setJMenuBar(menuBar);

    panel1 = new JPanel(new GridLayout(3 , 1));

    for(int i = 0 ; i<buttons.length ; i++)
    {
        buttons[i] = new JButton(""+ i);
        buttons[i].addActionListener(handler);
        panel1.add(buttons[i]);
    }
    frame1.add(panel1);
    frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame1.setSize(200 , 200);
    frame1.setVisible(true);
}

public void forFrame2()
{
    menuBar = new JMenuBar();
    myMenu = new JMenu("menu");
    firstItem = new JMenuItem("goto 1st frame");
    firstItem.addActionListener(handler);
    menuBar.add(myMenu);
    myMenu.add(firstItem);
    frame2.setJMenuBar(menuBar);

    panel2 = new JPanel(new GridLayout(1 , 5));
    for(int i = 0 ; i<moreButtons.length ; i++)
    {   
        moreButtons[i] = new JButton(""+ i);
        moreButtons[i].addActionListener(handler);
        panel2.add(moreButtons[i]);
    }
    frame2.add(panel2);
    frame2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame2.setSize(200 , 200);
    frame2.setVisible(true);
}

private class Handler implements ActionListener
{
    public void actionPerformed(ActionEvent event)
    {
        if(event.getSource() == firstItem)
        {
                frame2.dispose();
                forFrame1();

        }
        else if(event.getSource() == secondItem)
        {
                frame1.dispose();
                forFrame2();    
        }

        for(int i = 0 ; i< moreButtons.length ; i++)
        {
            if(i<buttons.length)
            {
                if(event.getSource() == buttons[i])
        JOptionPane.showMessageDialog(null, "frame1 component working");
            }
            if(event.getSource() == moreButtons[i])
        JOptionPane.showMessageDialog(null, "frame2 components working");
        }
    }
}


}

通过选择 menuItem 更改框架后尝试使用组件

我不会在没有 mcve 的情况下检查所有代码,但你的症状告诉我总体问题和解决方案:你正在重建一个已经创建的 JFrame,重新填充它与组件,不删除旧组件,不解除旧侦听器,然后组件不起作用。这表明 某些东西 在重建已构建的 GUI 的过程中正在破坏您的功能,如果是这样,解决方案就是不这样做。如果您绝对需要交换 JFrames(顺便说一句,从用户的角度来看,这是一个非常烦人的 GUI 设计),那么只需创建一次 GUI 对象,但如果需要则多次显示它们。换句话说,只调用一次构建器方法,也许在构造函数中,在按钮的 ActionListener 中,不要调用构建器方法,而只调用 .setVisible(true).setVisible(false)


导致错误的错误是您将组件添加到已经填充的 JFrame 而没有打包它,因此显示并按下了旧按钮,但它们的引用与新按钮。要亲自查看,请向 forFrame1()forFrame2() 方法各添加一行:

    frame1.getContentPane().removeAll(); // ****** add this *****
    frame1.add(panel1);
    frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame1.setSize(200, 200);
    frame1.setVisible(true);

通过删除所有旧组件,所有新组件都可以显示和运行,您的代码将正常工作。

说了这么多,我还是觉得你的设计有几个地方不对:

  • 我自己,我会交换 JPanel 以实现所需的 GUI 更改,但我不会使用 CardLayout,因为我希望持有交换 JPanel 的容器在持有的 JPanel 具有不同的 preferredSize 时更改大小.这意味着删除所有组件、添加新组件并重新打包 GUI。
  • 如果你必须交换 windows,那么只需交换可见性,不要像你正在做的那样重新创建你的 windows。
  • 其他不相关的问题
    • 通过不设置任何大小并在创建后打包 GUI,让布局管理器和组件自行调整大小。

我认为你应该使用 JFrame.setVisible(false) 而不是 JFrame.dispose()