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

标签 java swing jframe jbutton

我制作了一个计算器,为了增加其功能和简单性,我制作了三个框架,支持简单计算器、科学计算器和换算计算器

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

我在构造函数中实例化了三个框架,并为计算器类型创建了三种方法来实例化并向 JPanel 添加按钮和其他内容,并向 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 中选择计算器类型时,我会处理 Activity 框架并调用其他计算器类型方法来创建内容并将其添加到面板并设置框架,例如

//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 的过程中,某些正在破坏您的功能,如果是这样,解决方案就是不这样做。如果您绝对需要交换 JFrame(顺便说一句,从用户的角度来看,这是一个非常烦人的 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 具有不同的首选尺寸时更改大小。这意味着删除所有组件、添加新组件以及重新打包 GUI。
  • 如果您必须交换窗口,则只需交换可见性即可,而不要像您正在做的那样重新创建窗口。
  • 其他不相关的问题
    • 通过不设置任何大小并在创建后打包 GUI,让布局管理器和组件自行调整大小。

关于java - 在我处理现有框架并设置新框架(重新实例化另一个框架)后,JButton 根本不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31998027/

相关文章:

Java 格式化以获取最后计数

java - JMenuBar 未显示

java - 在创建新类(class)时,我应该如何将教师添加到新类(class)中?

java - Repaint方法更新太慢

java - JScrollPane位置高的问题

Java:如何在运行时修改 JPanel 的大小?

java - JFrame 滚动条和 Canvas

java - 从 JPanel 创建小图像

java - 如何将 SVG 文本转换为 SVG 路径?

在 JPanel 中实现 Runnable 时出现 java.lang.StackOverflowError - Java Swing