如何在静态实例中为JButton添加ActionListener?

3
没有任何我能找到的东西是有效的,而且代码似乎与我熟悉的小程序不同。我是新手,如何向我的JButtons添加ActionListener(是这样吗?还是我在寻找其他东西?)?(我不确定是什么导致代码块变得奇怪,我无法修复它。)
import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

public class Main implements ActionListener{

static String answerOne = "";
static String answerTwo = "";
static boolean answerable = false;
static int labelX = 240, labelY = 48;
static int questionWrite = 0;
static String text = "Welcome! I will ask simple, two-answer questions, and you will answer them. Simple as that. ";
static int charIndex = 0;

private static void createAndShowGUI() {
    JFrame frame = new JFrame("FrameDemo");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JLabel emptyLabel = new JLabel("");
    emptyLabel.setPreferredSize(new Dimension(300, 225));
    frame.getContentPane().add(emptyLabel, BorderLayout.CENTER);

    frame.pack();
    frame.setVisible(true);

    frame.setLayout(null);
    frame.setResizable(false);

    JPanel buttons = new JPanel(new FlowLayout());
    final JButton buttonOne = new JButton(answerOne);
    final JButton buttonTwo = new JButton(answerTwo);
    final JButton buttonThree = new JButton("Continue");
    buttonThree.setActionCommand("continue");

    if (answerable == true) {
    buttons.add(buttonOne);
    buttons.add(buttonTwo);
    } else {
        buttons.add(buttonThree);
    }

    frame.add(buttons);

    final JLabel centerText = new JLabel("<html>");
    frame.add(centerText);

    buttons.reshape(50, 185, 200, 40);
    centerText.reshape(10, 10, 280, 160);

    Timer timer = new Timer(50, new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        String labelText = centerText.getText();
        labelText += text.charAt(charIndex);
        centerText.setText(labelText);
        charIndex++;
        if (charIndex >= text.length()) {
            ((Timer)e.getSource()).stop();
        }

        Object buttonClicked = e.getSource();
        if(buttonClicked == buttonOne) {
            System.out.println("One.");
        }
        else if(buttonClicked == buttonTwo) {
            System.out.println("Two.");
        }
        else if(buttonClicked == buttonThree) {
            System.out.println("Continuing.");
        }

        //writeNext(Text to write, button one text, button two text, yes/no or "continue"); 
        switch(questionWrite) {
        case 0:
            writeNext("Welcome! I will ask simple, two-answer questions, and you will answer them. Simple as that. ", null, null, false);
            break;
        case 1:
            writeNext("Is Canada the largest country?", "Yes", "No,", true);
            break;
        case 2:
            writeNext("Have humans been to Mars?", "Yes", "No", true);
            break;
        }
    }

});

    timer.start();
}

public static void main(String[] args) {
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            createAndShowGUI();
        }
    });



}
public static void writeNext(String textM, String answerOneM, String answerTwoM, boolean answerableM) {
        text = textM;
        answerOne = answerOneM;
        answerTwo = answerTwoM;
        answerable = answerableM;
    }

@Override
public void actionPerformed(ActionEvent arg0) {

}

}`


1
不要使用静态方法和静态变量,这是一种糟糕的设计。你的大部分代码似乎来自Swing教程示例,那么为什么不完全按照示例的方式来呢?这样就不会有这个问题了。示例创建一个面板添加到框架中,然后你的所有代码都包含在面板类中。 - camickr
1
在添加组件后应该调用frame.pack()frame.setVisible() - nachokk
你说得对,这是我第一次使用Swing。之前我一直在做Applets和LWJGL。那么我在哪里调用createAndShowGUI()呢?唯一它能够工作的地方就是在main方法中... - IHazABone
1个回答

5
button.addActionListener(new ActionListener()
{
    public void actionPerformed(ActionEvent e)
    {
        //action listener here
    }
});

由于你必须传递一个对象给 addActionListener,所以你无法在静态上下文中执行该操作。因此,你需要创建一个匿名类的实例,并将其与你的动作事件处理程序一起传递。

或者,你可以在你的类中编写 actionPerformed 方法。最好为其提供一个构造函数来进行标识。

private int button;
public Main(int button)
{
    this.button = button;
}

然后添加动作监听器:

button.addActionListener(new Main(1)); //or pass it 2, 3, 4 ... just some unique integer

在你的actionPerformed方法中,你可以读取你传入的整数。

if(this.button==1)
{
    //do button 1 stuff
}

@IHazABone 是的,那么你需要为每个按钮设置不同的动作监听器。 - Cruncher
那么对于另一种选择,在actionPerformed方法中,我要做什么来检测哪个按钮被按下以及该执行什么操作? - IHazABone
@IHazABone,你可以为主函数创建一个构造函数,接受某种变量来标识它所属的按钮,并将其赋值给一个实例变量。然后在actionPerformed中读取该实例变量,以便知道它所属的按钮是哪个。 - Cruncher
@IHazABone 更新了答案,稍微概述了一下这个过程。 - Cruncher
1
如果所有按钮上的文本都不同,那么 e.getActionCommand() 也会获取按钮上的文本。因此,您也可以使用它来识别它们。 - Cruncher

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接