JButton Action Listener无法正常工作

时间:2015-07-14 05:38:54

标签: java swing actionlistener

我正在制作一个短文本冒险游戏作为我的第一个大型应用程序,我遇到了一个问题。我正在为我的游戏使用GUI,而我的问题在于我用于第二个按钮proceed的动作监听器。除了方法buttonAction之外,所有其他代码都有效。我向proceed添加了一个动作监听器,每当我运行代码并单击继续时,没有任何反应,我无法弄清楚原因。我从init2()移动了actionPerformed()中现在找到的代码,但它没有效果。我也尝试在@Override上使用buttonAction,但它给出了错误“SimpleGui类型的方法buttonAction(ActionEvent)必须覆盖或实现超类型方法”。请记住,我的java技能充其量只是基本的,所以请尽量解释。任何帮助将不胜感激。我的申请代码如下。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

import Classes.Rogue;
import Classes.Warrior;
import Classes.Wizard;

public class SimpleGui extends JFrame implements ActionListener {

public JPanel panelControl, panel, panel2, panel3, panel4;
public JButton create, proceed;
public JTextField name;
public final JTextField textField = new JTextField();
public JComboBox playerClass;
public Char player1;
public String[] classOptions = { "Rogue", "Wizard", "Warrior" };
public JLabel textObject;

SimpleGui() {

    super("RPG Quest");
    name = new JTextField(20);
    init();
    this.setVisible(true);
    this.setSize(455, 250);
    this.setResizable(false);
}// end SimpleGui

public void init() {

    panel = new JPanel();
    panel3 = new JPanel();
    panel2 = new JPanel();
    playerClass = new JComboBox(classOptions);
    create = new JButton("Create Character");
    create.addActionListener(this);
    textObject = new JLabel("Name");

    panel.setBorder(BorderFactory
            .createTitledBorder("<html><font color:black>Create Your Character</font></html>"));
    panel.add(textObject);
    panel.add(name);
    panel.add(playerClass);
    panel.setBackground(Color.WHITE);

    panel3.setBorder(BorderFactory
            .createTitledBorder("<html><font color:black>Class Descriptions</font></html>"));
    panel3.add(new JLabel(
            "<html><font color:black>The Rogue has a 20% chance to land Critical Hits on enemies.</font></html>"));
    panel3.add(new JLabel(
            "<html><font color:black>The Wizard can only cast spells and has only a 70% chance of landing a hit,</font></html>"));
    panel3.add(new JLabel(
            "<html><font color:black>but spells do more damage than melee attacks.</font></html>"));
    panel3.add(new JLabel(
            "<html><font color:black>The Warrior has a 30% chance to block an incoming attack.</font></html>"));
    panel3.setBackground(Color.WHITE);

    panel2.add(create);
    panel2.setBackground(Color.WHITE);

    this.add(panel);
    this.add(panel3);
    this.add(panel2);
    this.pack();
    this.setResizable(true);
    this.setLayout(new BorderLayout());

    this.add(panel, BorderLayout.NORTH);
    this.add(panel3);
    this.add(panel2, BorderLayout.SOUTH);
}// end void

@Override
public void actionPerformed(ActionEvent event) {
    if (event.getSource() == create) {

        String type = classOptions[playerClass.getSelectedIndex()];

        if (type == "Rogue") {
            player1 = new Rogue();
        }
        if (type == "Wizard") {
            player1 = new Wizard();
        }
        if (type == "Warrior") {
            player1 = new Warrior();
        }
        player1.name = name.getText();

        JOptionPane.showMessageDialog(this, "You are a " + type
                + ". Your name is " + player1.name + ".");

        init2();
    }
}

public void init2() {

    this.remove(panel);
    this.remove(panel2);
    this.remove(panel3);

    panel.remove(textObject);
    panel.remove(name);
    panel.remove(playerClass);
    panel.setBorder(BorderFactory
            .createTitledBorder("<html><font color:black>Info</font></html>"));
    panel.setBackground(Color.WHITE);
    proceed = new JButton("Proceed");
    proceed.addActionListener(this);
    panel.add(proceed);

    textField.setText("Hello There");
    textField.setEditable(false);

    panelControl = new JPanel();
    panelControl.setBackground(Color.WHITE);
    panelControl.setBorder(BorderFactory.createBevelBorder(NORMAL));
    panelControl.add(textField);

    this.add(panelControl, BorderLayout.NORTH);
    this.add(panel, BorderLayout.SOUTH);
    this.pack();
}

public void buttonAction(ActionEvent event) {
    proceed.addActionListener(this);

    if (event.getSource() == proceed) {
        JOptionPane.showMessageDialog(this, "It Works!");
        System.out.println("hi");
    }
}
}

// end class

3 个答案:

答案 0 :(得分:2)

You have written

proceed.addActionListener(this);

So whenever you are clicking on the JButton proceed you are basically calling actionPerformed(ActionEvent event) of the class SimpleGui. Now the actionPerformed method does not have any code for proceed. So, it does nothing.

I would here suggest that you add the code for proceed variable in the actionPerformed method of the class SimpleGui. You could add the following after the existing code of you actionPerformed as illustrated below:

@Override
public void actionPerformed(ActionEvent event) {
    if (event.getSource() == create) {
        //Your existing code;
    } else if (event.getSource() == proceed){
        //put the code for proceed action here.
    }
}

I hope that this will solve your problem.

答案 1 :(得分:2)

由于您的类实现了ActionListener,因此必须为actionPerformed定义一个您已正确完成的实现。现在当你说

proceed.addActionListener(this);

您实际上是将按钮连接到类中定义的actionPerformed,而不是您希望连接到的buttonAction()方法。这与create连接的侦听器相同。您应该可以使用

解决此问题
public void actionPerformed(ActionEvent event) {
if (event.getSource() == create) {

    String type = classOptions[playerClass.getSelectedIndex()];

    if (type == "Rogue") {
        player1 = new Rogue();
    }
    if (type == "Wizard") {
        player1 = new Wizard();
    }
    if (type == "Warrior") {
        player1 = new Warrior();
    }
    player1.name = name.getText();

    JOptionPane.showMessageDialog(this, "You are a " + type
            + ". Your name is " + player1.name + ".");

    init2();


} else if (event.getSource() == proceed)
{
    JOptionPane.showMessageDialog(this, "It Works!");
    System.out.println("hi");
{

}

这会使buttonAction()变得不必要。我将添加,而不是实现ActionListener,您可以将侦听器定义为内部类,并将按钮分别连接到它们,使代码更清晰。你可以研究的东西:)

答案 2 :(得分:0)

您将事件处理程序设为'this',表示单击按钮时

  

@Override public void actionPerformed(ActionEvent event)

将被触发。

  

public void buttonAction(ActionEvent event)

在您的代码中无用。并且您不能在其上使用 @Override ,因为没有任何接口具有此方法签名。

  

if(event.getSource()== create)

只允许创建按钮通过。

因此,解决方案可以添加另一个条件,并在 actionPerformed 方法中添加继续按钮的代码。

if (event.getSource() == create){...}
else if (event.getSource() == proceed){...}