简体   繁体   English

JButton和JMenuItem在ActionListener中不配合

[英]JButtons and JMenuItems not cooperating in ActionListener

Hi all this is my first post! 大家好,这是我的第一篇文章!

I'm using this calculator project as tool to teach my self java. 我正在使用这个计算器项目作为工具来教我自己的Java。

I am generally trying to reproduce Microsoft Windows 7 Calculator program. 我通常试图重现Microsoft Windows 7计算器程序。

So far so good, all the buttons work the way they are supposed to, apart from the more complex button functions in Microsoft Calculator everything is pretty much identical. 到目前为止,所有按钮均按预期方式工作,除了Microsoft计算器中更复杂的按钮功能外,其他所有功能都几乎相同。

Here is my problem, Upon implementing an actionlistener/event for the JMenuBar with the following code 这是我的问题,使用以下代码为JMenuBar实现一个动作侦听器/事件后

String menuText = ((JMenuItem) evt.getSource()).getText();

    if(menuText.equals("info")){
        System.out.println("it works");
        JOptionPane.showMessageDialog(null, "aha it works");

everything collapses around me! 一切都崩溃了!

here is the full code 这是完整的代码

public class Calculator extends JFrame implements ActionListener {

JButton backSpace, clear, one, two, three, four, five, six, seven, eight,
        nine, zero, period, devision, modulas, subtraction, addition,
        negative, equals;

Font myFont = new Font("ARIAL", Font.BOLD, 40);

JTextArea answerBox = new JTextArea("");

static double numberOne = 0;
static double numberTwo = 0;
static double result;
static String operator = null;

public Calculator() {
    super("Calculator");
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true);

    // set up components
    addition = new JButton("+");
    backSpace = new JButton("BACKSPACE");
    clear = new JButton("CLEAR");
    one = new JButton("1");
    two = new JButton("2");
    three = new JButton("3");
    four = new JButton("4");
    five = new JButton("5");
    six = new JButton("6");
    seven = new JButton("7");
    eight = new JButton("8");
    nine = new JButton("9");
    zero = new JButton("0");
    period = new JButton(".");
    devision = new JButton("/");
    modulas = new JButton("*");
    subtraction = new JButton("-");
    negative = new JButton("-N");
    equals = new JButton("=");

    // set up answerbox
    answerBox.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
    answerBox.setFont(myFont);
    answerBox.setEditable(false);

    // set up actionListener
    backSpace.addActionListener(this);
    clear.addActionListener(this);
    one.addActionListener(this);
    two.addActionListener(this);
    three.addActionListener(this);
    four.addActionListener(this);
    five.addActionListener(this);
    six.addActionListener(this);
    seven.addActionListener(this);
    eight.addActionListener(this);
    nine.addActionListener(this);
    zero.addActionListener(this);
    period.addActionListener(this);
    devision.addActionListener(this);
    addition.addActionListener(this);
    modulas.addActionListener(this);
    subtraction.addActionListener(this);
    negative.addActionListener(this);
    equals.addActionListener(this);

    // menu
    JMenuBar menuBar = new JMenuBar();
    JMenu menu = new JMenu("About");
    JMenuItem info = new JMenuItem("Info");

    info.addActionListener(this);
    menu.add(info);
    menuBar.add(menu);
    setJMenuBar(menuBar);

    // set up layout
    GridBagLayout gridBag = new GridBagLayout();
    GridBagConstraints constraints = new GridBagConstraints();
    JPanel pane = new JPanel();
    pane.setLayout(gridBag);

    // default
    constraints.fill = GridBagConstraints.BOTH;
    constraints.anchor = GridBagConstraints.WEST;
    constraints.gridy = 0;
    constraints.gridx = 0;
    constraints.gridwidth = 1;
    constraints.gridheight = 1;
    constraints.weightx = 10;
    constraints.weighty = 10;
    constraints.insets = new Insets(2, 2, 2, 2);

    // answer box
    constraints.gridx = 0;
    constraints.gridy = 0;
    constraints.gridwidth = 6;
    answerBox.append("0");

    gridBag.setConstraints(answerBox, constraints);
    pane.add(answerBox);

    // backSPace
    constraints.gridx = 0;
    constraints.gridy = 1;
    constraints.gridwidth = 3;

    gridBag.setConstraints(backSpace, constraints);
    pane.add(backSpace);

    // clear

    constraints.anchor = GridBagConstraints.EAST;
    constraints.gridx = 3;
    constraints.gridy = 1;
    constraints.weightx = 10;
    gridBag.setConstraints(clear, constraints);
    pane.add(clear);

    // nine
    constraints.gridwidth = 1;
    constraints.weightx = 1;
    constraints.gridx = 0;
    constraints.gridy = 3;
    gridBag.setConstraints(nine, constraints);
    pane.add(nine);

    // eight
    constraints.gridx = 1;
    constraints.gridy = 3;
    gridBag.setConstraints(eight, constraints);
    pane.add(eight);

    // seven
    constraints.gridx = 2;
    constraints.gridy = 3;
    gridBag.setConstraints(seven, constraints);
    pane.add(seven);

    // devision
    constraints.gridwidth = 1;
    constraints.weightx = 1;
    constraints.gridx = 3;
    constraints.gridy = 3;
    constraints.anchor = GridBagConstraints.SOUTH;
    gridBag.setConstraints(devision, constraints);
    pane.add(devision);

    // EQUALS
    constraints.gridx = 4;
    constraints.gridy = 3;
    constraints.gridwidth = 2;
    constraints.gridheight = 4;
    constraints.weighty = 30;
    constraints.anchor = GridBagConstraints.SOUTH;
    gridBag.setConstraints(equals, constraints);
    pane.add(equals);

    // six
    constraints.weighty = 10;
    constraints.gridwidth = 1;
    constraints.gridheight = 1;
    constraints.gridx = 0;
    constraints.gridy = 4;
    gridBag.setConstraints(six, constraints);
    pane.add(six);

    // five
    constraints.gridx = 1;
    constraints.gridy = 4;
    gridBag.setConstraints(five, constraints);
    pane.add(five);

    // four
    constraints.gridwidth = 1;

    constraints.gridx = 2;
    constraints.gridy = 4;
    gridBag.setConstraints(four, constraints);
    pane.add(four);

    // Addition
    constraints.gridwidth = 1;
    constraints.weightx = 1;
    constraints.gridx = 3;
    constraints.gridy = 4;
    gridBag.setConstraints(addition, constraints);
    pane.add(addition);

    // three
    constraints.gridx = 0;
    constraints.gridy = 5;
    gridBag.setConstraints(three, constraints);
    pane.add(three);

    // two
    constraints.gridx = 1;
    constraints.gridy = 5;
    gridBag.setConstraints(two, constraints);
    pane.add(two);

    // one
    constraints.gridx = 2;
    constraints.gridy = 5;
    gridBag.setConstraints(one, constraints);
    pane.add(one);

    // subtraction
    constraints.gridx = 3;
    constraints.gridy = 5;
    gridBag.setConstraints(subtraction, constraints);
    pane.add(subtraction);

    // zero
    constraints.gridx = 0;
    constraints.gridy = 6;
    constraints.gridwidth = 2;
    gridBag.setConstraints(zero, constraints);
    pane.add(zero);

    // period
    constraints.gridx = 2;
    constraints.gridy = 6;
    constraints.gridwidth = 1;
    gridBag.setConstraints(period, constraints);
    pane.add(period);

    // multiplication
    constraints.gridx = 3;
    constraints.gridy = 6;
    constraints.gridwidth = 1;
    gridBag.setConstraints(modulas, constraints);
    pane.add(modulas);

    pack();
    add(pane);

}

public static void main(String[] args) {
    Calculator frame = new Calculator();
    frame.setSize(300, 350);
}

public void actionPerformed(ActionEvent evt){       
    Object source = evt.getSource();
    String menuText = ((JMenuItem) evt.getSource()).getText();

    if(menuText.equals("info")){
        System.out.println("it works");
        JOptionPane.showMessageDialog(null, "aha it works");
    }

    else if(source == one){
        answerBox.append("1");


    }else if (source == two){
        answerBox.append("2");
    }

    else if (source == three){
        answerBox.append("3");
    }

    else if (source == four){
        answerBox.append("4");
    }

    else if (source == five){
        answerBox.append("5");
    }

    else if (source == six){
        answerBox.append("6");
    }

    else if (source == seven){
        answerBox.append("7");
    }

    else if (source == eight){
        answerBox.append("8");
    }

    else if (source == nine){
        answerBox.append("9");
    }

    else if (source == zero){
        answerBox.append("0");
    }

    else if (source == addition){
        numberOne=Double.parseDouble(answerBox.getText());
        operator="+";
        answerBox.setText("");
    }   

    else if (source == subtraction){
        numberOne=Double.parseDouble(answerBox.getText());
        operator="-";
        answerBox.setText("");
        }

    else if (source == modulas){
        numberOne=Double.parseDouble(answerBox.getText());
        operator="*";
        answerBox.setText("");

    }
    else if (source == devision){
        numberOne=Double.parseDouble(answerBox.getText());
        operator="/";
        answerBox.setText("");

    }
    else if (source == period){
        answerBox.append(".");
    }

    else if(source == equals){

           numberTwo=Double.parseDouble(answerBox.getText());
           if(operator.equals("+"))
               result=numberOne+numberTwo;
           else if(operator.equals("-"))
               result=numberOne-numberTwo;
           else if(operator.equals("*"))
               result=numberOne-numberTwo;
           else if(operator.equals("/"))
               result=numberOne/numberTwo;

           answerBox.setText(" "+result);
           operator="=";

    }

    else if(source == clear){       
        numberOne=0;
        numberTwo=0;
        answerBox.setText("");
    }


}


}
String menuText = ((JMenuItem) evt.getSource()).getText();

I'm guessing you are getting a ClassCastException on the above statement. 我猜你在上面的语句上收到ClassCastException。

That code assumes the event is generated by a JMenuItem. 该代码假定事件是由JMenuItem生成的。 The problem is that you are using the same ActionListener for you JButtons and your JMenuItems so you can't assume the source object is a JMenuItem. 问题是您为JButton和JMenuItem使用了相同的ActionListener,因此您不能假定源对象是JMenuItem。

It is not a good idea to implement all your code in a single ActionListener. 在单个ActionListener中实现所有代码不是一个好主意。 You can share an ActionListener for like functions. 您可以为类似的函数共享一个ActionListener。 For example in the following code the pressing of the digit buttons is always the same so you can use the same listener: 例如,在以下代码中,数字键的按下始终相同,因此您可以使用相同的侦听器:

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

public class ButtonCalculator extends JPanel
{
    private JButton[] buttons;
    private JTextField display;

    public ButtonCalculator()
    {
        Action numberAction = new AbstractAction()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                display.replaceSelection(e.getActionCommand());
            }
        };

        display = new JTextField();
        display.setEditable( false );
        display.setHorizontalAlignment(JTextField.RIGHT);

        JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout( new GridLayout(0, 5) );
        buttons = new JButton[10];

        for (int i = 0; i < buttons.length; i++)
        {
            String text = String.valueOf(i);
            JButton button = new JButton( text );
            button.addActionListener( numberAction );
            buttons[i] = button;
            buttonPanel.add( button );

            //  Support Key Bindings

            KeyStroke pressed = KeyStroke.getKeyStroke(text);
            InputMap inputMap = button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
            inputMap.put(pressed, text);
            button.getActionMap().put(text, numberAction);
        }

        setLayout( new BorderLayout() );
        add(display, BorderLayout.NORTH);
        add(buttonPanel, BorderLayout.SOUTH);
    }

    private static void createAndShowUI()
    {
        UIManager.put("Button.margin", new Insets(5, 10, 5, 10) );
        JFrame frame = new JFrame("Button Calculator");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( new ButtonCalculator() );
        frame.setResizable( false );
        frame.pack();
        frame.setLocationByPlatform( true );
        frame.setVisible( true );
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowUI();
            }
        });
    }
}

For your other Actions ("+" , "-" ...) you should create separate listeners. 对于其他动作(“ +”,“-” ...),应创建单独的侦听器。

Before you cast evt.getSource to JMenuItem you have to check of source is a JMenuItem. 在将evt.getSource强制转换为JMenuItem之前,必须检查源代码是否为JMenuItem。 Change your method actionPerformed in the beginning like my example and it works (You have to ask for 'Info' not for 'info'). 像我的示例一样,更改方法actionPerformed开头,它就可以工作(您必须要求“ Info”而不是“ info”)。 +1 for camickr - different actionListener is the way for better code quality. camickr +1-使用不同的actionListener可以提高代码质量。

@Override
public void actionPerformed(ActionEvent evt) {
    Object source = evt.getSource();

    if (source.getClass() == JMenuItem.class) {
        String menuText = ((JMenuItem) evt.getSource()).getText();

        if (menuText.equals("info")) {
            System.out.println("it works");
            JOptionPane.showMessageDialog(null, "aha it works");
        }
    }
    else if (source == one) {
        answerBox.append("1");
    }

Several things jump out at me... 有几件事突然出现在我身上...

You can't rely on the source type being a given instance of a class... 您不能依赖源类型是类的给定实例...

Object source = evt.getSource();
String menuText = ((JMenuItem) evt.getSource()).getText();

This is likely to cause you a ClassCastException 这很可能导致您ClassCastException

Also, Info != info 另外, Info != info

You define your menu item as .... 您将菜单项定义为...。

JMenuItem info = new JMenuItem("Info");

But you test it's text content with... 但是你用...测试它的文本内容

if(menuText.equals("info")){

String comparison in Java is case sensitive (unless you use equalsIgnoresCase ) Java中的String比较区分大小写(除非您使用equalsIgnoresCase

You should be supply and using the actionCommand properties. 您应该提供并使用actionCommand属性。

For example... 例如...

JMenuItem info = new JMenuItem("Info");
info.setActionComand("infoMenu");

Then in you actionPeformed method you could do something like... 然后在您的actionPeformed方法中,您可以执行以下操作...

if("infoMenu".equals(evt.getActionCommand())){...}

I would also suggest you take a look at the How to use Actions , these are very powerful, isolated actions, which can be applied to multiple different parts of the application, including menus, buttons and the key bindings API 我还建议您看看“ 如何使用动作” ,它们是功能非常强大的隔离动作,可以应用于应用程序的多个不同部分,包括菜单,按钮和按键绑定API

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM