未调用其中一个 Jbutton 的 ActionListener

ActionListener for one of the Jbuttons doesn't get called

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;



@SuppressWarnings("serial")
public class Gui extends JFrame {

private ExpPanel panel1;
private Expression expression;
private ColorPanel panel2;
private SetValsPanel panel3;
int xIndex;
int cIndex;

public Gui(){
    setLayout(new GridLayout(3,1,0,0));
    panel1 = new ExpPanel();
    panel2 = new ColorPanel();
    panel3 = new SetValsPanel();

    add(panel1);
    add(panel2);
    add(panel3);

    panel1.setExp.addActionListener(
            new ActionListener() {

                public void actionPerformed(ActionEvent arg0) {
                    String temp = panel1.setExp.getText();
                    expression = new Expression(temp);
                    boolean[] isValid = expression.checkValid();
                    if(isValid[0]){
                        panel1.setExp.setText(expression.getExpression());
                        panel1.valid.setText("");
                        getContentPane().remove(panel2);
                        getContentPane().remove(panel3);
                        if (expression.getVars().length==0)
                            panel1.valid.setText("There's no variables in the entered expression.");
                        else if(expression.getVars().length==1){
                            panel3 = new SetValsPanel(expression);
                            add(panel3);

                        }
                        else {
                        panel2 = new ColorPanel(expression);
                        add(panel2);

                    }
                    }
                    else {


                        if(!isValid[1])
                            panel1.valid.setText("Invalid Expression (The prantheses don't match). Re-enter the expression." );

                        if(!isValid[3])
                            panel1.valid.setText("Invalid Expression (The expression must not continue after the last pranthes OR Invalid function name). Re-enter the expression." );

                        if(!isValid[2])
                            panel1.valid.setText("Invalid Expression (At least one argument of one of the functions is not entered). Re-enter the expression." );

                        if(!isValid[4])
                            panel1.valid.setText("Invalid Expression (You've entered two arguments for a single argument function). Re-enter the expression." );

                        getContentPane().remove(panel2);
                        getContentPane().remove(panel3);

                    }
                    validate();
                    repaint();
                }
            }
            );

    panel1.setbtn.addActionListener(
            new ActionListener() {

                public void actionPerformed(ActionEvent arg0) {
                    System.out.println("in this shit");
                    String temp = panel1.setExp.getText();
                    expression = new Expression(temp);
                    boolean[] isValid = expression.checkValid();
                    if(isValid[0]){
                        panel1.setExp.setText(expression.getExpression());
                        panel1.valid.setText("");
                        getContentPane().remove(panel2);
                        getContentPane().remove(panel3);
                        if (expression.getVars().length==0)
                            panel1.valid.setText("There's no variables in the entered expression.");
                        else if(expression.getVars().length==1){
                            panel3 = new SetValsPanel(expression);
                            add(panel3);

                        }
                        else {
                        panel2 = new ColorPanel(expression);
                        add(panel2);

                    }
                    }
                    else {


                        if(!isValid[1])
                            panel1.valid.setText("Invalid Expression (The prantheses don't match or don't exist). Re-enter the expression." );

                        if(!isValid[3])
                            panel1.valid.setText("Invalid Expression (The expression must not continue after the last pranthes OR Invalid function name). Re-enter the expression." );

                        if(!isValid[2])
                            panel1.valid.setText("Invalid Expression (At least one argument of one of the functions is not entered). Re-enter the expression." );

                        if(!isValid[4])
                            panel1.valid.setText("Invalid Expression (You've entered two arguments for a single argument function). Re-enter the expression." );

                        getContentPane().remove(panel2);
                        getContentPane().remove(panel3);

                    }
                    validate();
                    repaint();
                }
            }
            );

    panel2.setbtn.addActionListener(
            new ActionListener() {


                public void actionPerformed(ActionEvent arg1) {
                    if (panel2.cIndex == panel2.xIndex)
                        JOptionPane.showMessageDialog(null, "You can't choose the same variable for x-axis and color", "Error!", JOptionPane.ERROR_MESSAGE);
                    else {
                        String temp;
                        temp = expression.getVars()[xIndex];
                        expression.setVars(xIndex,expression.getVars()[0]);
                        expression.setVars(0,temp);
                        temp = expression.getVars()[cIndex];
                        expression.setVars(xIndex,expression.getVars()[1]);
                        expression.setVars(1,temp);
                        temp = null;
                        getContentPane().remove(panel3);
                        panel3 = new SetValsPanel(expression);
                        add(panel3);
                        validate();
                        repaint();
                    }
                }
            }
            );

}



}


@SuppressWarnings("serial")
class ExpPanel extends JPanel{

String expression;
JTextField setExp;
JButton setbtn;
JLabel instruction;
JLabel valid;
boolean isValid;
public ExpPanel(){

    setLayout(new GridLayout(2, 1, 5, 5));
    setExp = new JTextField(10);
    setbtn = new JButton("Set");    
    instruction = new JLabel("Enter Expression : ");
    valid = new JLabel("", JLabel.CENTER);

    JPanel up = new JPanel();
    up.add(instruction,BorderLayout.WEST);
    up.add(setExp,BorderLayout.CENTER);
    up.add(setbtn,BorderLayout.EAST);

    add(up);
    add(valid);

}



 }

@SuppressWarnings("serial")
class ColorPanel extends JPanel{

JButton setbtn = new JButton("Set");
JRadioButton[] xAxisbtns;
JRadioButton[] colorbtns;
int xIndex= -1;
int cIndex = -1;
public ColorPanel(){

}

public ColorPanel(Expression a){
    int num = a.getVars().length;
    xAxisbtns = new JRadioButton[num];
    colorbtns = new JRadioButton[num];
    ButtonGroup colorgroup = new ButtonGroup();
    ButtonGroup axisgroup= new ButtonGroup();
    setLayout( new GridLayout(4,1,0,0));
    JLabel instr = new JLabel("Select the variables for x-Axis and Color : ",JLabel.CENTER);
    JPanel cPanel = new JPanel();
    JPanel xPanel = new JPanel();
    cPanel.setLayout(new GridLayout(1, num + 1, 1, 1));
    xPanel.setLayout(new GridLayout(1, num + 1, 1, 1));
    cPanel.add(new JLabel("Select the variable for Color :",JLabel.CENTER));
    xPanel.add(new JLabel("Select the variable for x-Axis :",JLabel.CENTER));
    for(int i =0;i<num;i++){
        xAxisbtns[i] = new JRadioButton(a.getVars()[i]);    
        colorbtns[i] = new JRadioButton(a.getVars()[i]);
        colorgroup.add(colorbtns[i]);
        axisgroup.add(xAxisbtns[i]);
        xPanel.add(xAxisbtns[i]);
        cPanel.add(colorbtns[i]);
        xAxisbtns[i].addItemListener(new xhandler(i));
        colorbtns[i].addItemListener(new chandler(i));
    }
    JPanel btnPanel = new JPanel();
    btnPanel.add(setbtn,JPanel.LEFT_ALIGNMENT);
    add(instr);
    add(xPanel);
    add(cPanel);
    add(btnPanel);
}

  private class xhandler implements ItemListener{
    private int index;

    @Override
    public void itemStateChanged(ItemEvent arg0) {

        xIndex = index;
    }
    public xhandler(int i){
        index = i;
    }

}

  private class chandler implements ItemListener{
    private int index;

    @Override
    public void itemStateChanged(ItemEvent arg0) {

        cIndex = index;
    }
    public chandler(int i){
        index = i;
    }

 }
 }
@SuppressWarnings("serial")
class SetValsPanel extends JPanel{

 JTextField[][] vals;
 JButton drawIt = new JButton("Draw this shit");
 JLabel[][] labels;

 public SetValsPanel(){

    drawIt.setEnabled(false);

}

public SetValsPanel(Expression a){

    int num = a.getVars().length;
    vals = new JTextField[3][num];
    labels = new JLabel[3][num];
    JPanel[] rows = new JPanel[num];
    setLayout(new GridLayout(num+2,1,5,5));
    add(new JLabel("Set the Range and the inital value for each variable : "));
    for(int i=0;i<num;i++){
        labels[0][i] = new JLabel("Range for " + a.getVars()[i] + " :",JLabel.CENTER);
        labels[1][i] = new JLabel(" to ",JLabel.CENTER);
        labels[2][i] = new JLabel(" Inital value = " + a.getVars()[i] + " :",JLabel.CENTER);
        vals[0][i] = new JTextField(3);
        vals[1][i] = new JTextField(3);
        vals[2][i] = new JTextField(3);
        rows[i] = new JPanel();
        rows[i].setLayout(new GridLayout(1, 6, 2, 2));
        rows[i].add(labels[0][i]);
        rows[i].add(vals[0][i]);
        rows[i].add(labels[1][i]);
        rows[i].add(vals[1][i]);
        if (i!=0) {
            rows[i].add(labels[2][i]);
            rows[i].add(vals[2][i]);
        }
        add(rows[i]);
    }

    add(drawIt);

}

}

第二个按钮的动作侦听器不工作,而第一个动作侦听器工作正常。我试图通过向 actionPerformed 方法添加 system.out 来检查它是否被调用,该方法向我展示了当我单击按钮时 actionlistener 甚至没有被调用。

编辑 = panel2.setbtn.addActionListener 这个不行。

编辑 = 这是表达式 class

public class Expression {

private String expression;
protected String[] vars;
private String[] varValues;

public Expression(String expression){

    this.expression = ExpressionFunctions.toValid(expression);


    vars = new String[0];
    varValues = new String[0];

    extractVars();
}

public void extractVars() {

    String temp = expression;
    temp = temp.toLowerCase();

    String[] names1 = {"div\(" , "idiv\(" , "mod\(" , "pow\("};
    String[] names2 = {"cotan\(" , "arccos\(" , "arccosh\(" , "arcsinh\(" , "cos\(", "arccot\(" , "arccoth\(" , 
            "arcsin\(" , "arcsinh\(" , "arccosh\(", "arctanh\(" , "cosh\(" , "exp\(" , "ln\(", "fact\(" , 
            "fib\(" , "sinh\(" , "tanh\(" };
    for(String x : names1)
        temp = temp.replaceAll(x, "add\(");
    for(String x : names2)
        temp = temp.replaceAll(x, "sin\(");

    EvalExperession a = new EvalExperession(temp, vars, varValues);
    boolean rep = true;


    while (rep) {
        try {
            a.run();
            rep = false;
        } catch (IllegalArgumentException e) {

            add(e.getMessage());

         a = new EvalExperession(temp, vars, varValues);

        }
    }



}

private void add(String message) {
    String[] temp1 = new String[vars.length];
    String[] temp2 = new String[vars.length];
    for(int i =0;i<vars.length;i++){
        temp1[i] = vars[i];
        temp2[i] = varValues[i];
}
    vars = new String[temp1.length+1];
    varValues = new String[temp2.length+1];
    for(int i =0;i<temp1.length;i++){
        varValues[i] = temp2[i];

        vars[i] = temp1[i];}
    vars[temp1.length] = message;
    varValues[temp1.length] = "1.0";

    temp1=null;
    temp2 = null;
}

public String getExpression() {
    return expression.toLowerCase();
}

public void setExpression(String expression) {
    this.expression = expression;
}

public String[] getVars() {
    return vars;
}

public void setVars(int i,String a) {
    this.vars[i] = a;
}

public String[] getVarValues() {
    return varValues;
}

public void setVarValues(String[] varValues) {
    this.varValues = varValues;
}

public boolean[] checkValid(){

    int right=0;
    int left=0;

    boolean[] res = new boolean[5];
    for (int i =0;i<5;i++)
        res[i] = true;



    for (int i=0; i<expression.length(); i++){



        if(expression.charAt(i) == '(')
            left++;
        if(expression.charAt(i) == ')')
            right++;
        if (right>left){
            res[0] = false;
            res[1] = false;
            return res;}
    }

    if (right!=left || (right == 0 && left == 0))
    {
        res[0] = false;
        res[1] = false;
        return res;}

    for (String x : vars){
        if((x + "a").equals("a") || x.indexOf("(")!= -1 || x.indexOf(",")!= -1 || x.indexOf(")")!= -1){
            if((x + "a").equals("a")){
                res[0] = false;
                res[2] = false;
                return res;
            }

            if(x.indexOf("(")!= -1 || x.indexOf(")")!= -1 ){

                res[0] = false;
                res[3] = false;
                return res;
            }

            if(x.indexOf(",")!= -1){
                res[0] = false;
                res[4] = false;
                return res;
            }

        }

    }

    return res;

}


}

toValid函数只是对一个字符串进行更正,可以忽略。

您永远不会向 drawIt 按钮添加任何 listener。对 setbtn 按钮执行相同的操作。编译器不会自己猜测它需要添加一个监听器...

您可能想要添加

SetValsPanel.drawIt.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent arg0) {
    ...
    }
}

这是我认为正在发生的事情。开始时,您使用 ColorPanel() 创建一个 ColorPanel,并将一个 ActionListener 添加到其 setbtn。

然后,在顶部面板中输入表达式并按下其按钮后,使用 ColorPanel(string) 创建一个新的 ColorPanel。但是,新的ColorPanel中的新的setbtn并没有给ActionListener。

可能的快速解决方案:向构造函数添加一个 Button 参数并将旧的 setbtn 传递给新的实例。那将是快速而肮脏的。

panel2 = new ColorPanel(expression, panel2.setbtn);

在对新面板 2 的调用中,并且

public ColorPanel(Expression a, JButton setbtn){
    this.setbtn = setbtn;

在颜色面板中。这对我有用。

建议:

  • 您将需要阅读并使用 CardLayout,这将使您能够轻松交换 JPanel 或任何其他组件,并有助于简化您的程序。
  • 您可能不想创建和交换多个 SetValPanel,对于 ColorPanel 也是如此。我敢打赌,您只想创建一个并在需要时交换它们。如果需要,请确保将新的 Expression 对象传递到面板中,但如果不需要,请避免创建和丢弃。这将有助于简化您的代码并避免您的 ActionListener 问题。
  • 避免让一个 class 直接操纵其他 class 的字段,例如您的代码中有一个 class 直接将 ActionListener 添加到另一个 class 持有的 JButton class,因为这会增加 connections/coupling。相反,将您的字段设为私有,并且如果您计划允许其他 class 将侦听器添加到包含的组件,请为此目的为 class 提供一个 public 方法。例如public void addSetBtnActionListener(ActionListener listener) {...}
  • 另请阅读 MVC,模型-视图-控制设计模式,因为它可以帮助您降低代码的复杂性。