[英]How to implement ActionListener using an outer class?
当我将ActionListener实现为已注册的侦听器类的内部类时,它可以正常工作,但是当我尝试在已注册的类(即外部类)之外进行操作时,则按钮操作无效。
谁能解释我为什么? 或有任何建议将ActionListener实现为外部类?
代码如下。 提前致谢。
// MainMethod.java
import java.awt.Dimension;
import java.awt.Toolkit;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MainMethod
{
public static void main(String[] args)
{
Dimension size = Toolkit.getDefaultToolkit().getScreenSize();
JFrame frame = new Framework("Tic Tac Toe", size.width / 4,
size.height / 3, 950, size.height / 8);
JPanel panel = new ButtonPanel();
frame.getContentPane().add(panel);
frame.setVisible(true);
}
}
// ButtonPanel.java
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;
public class ButtonPanel extends JPanel
{
private static final long serialVersionUID = -4829885180501818987L;
JButton buttons[] = new JButton[9];
ButtonPanel()
{
String name[] = { "button1", "button2", "button3", "button4", "button5",
"button6", "button7", "button8", "button9" };
Border lineBorder = new LineBorder(Color.black, 2);
GridLayout panelLayout = new GridLayout(3, 3);
setLayout(panelLayout);
for (int i = 0; i < name.length; i++)
{
buttons[i] = new JButton(name[i]);
buttons[i].setBackground(Color.white);
buttons[i].setBorder(lineBorder);
buttons[i].addActionListener(new ButtonActionListener());
add(buttons[i]);
}
}
// Inner class implementation
class ButtonActionListener implements ActionListener
{
public void actionPerformed(ActionEvent ae)
{
if (ae.getActionCommand().equals("button1"))
{
buttons[0].setText("X");
}
}
}
}
以下是外部类实现,该实现在使用时不起作用:
// ButtonActionListener.java
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
class ButtonActionListener implements ActionListener
{
public void actionPerformed(ActionEvent ae)
{
ButtonPanel buttonPanel = new ButtonPanel();
if (ae.getActionCommand() == "button1")
{
buttonPanel.buttons[0].setText("X");
}
}
}
在您的外部ButtonActionListener
类中,编写类似以下内容的内容:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
public class ButtonActionListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
if (event.getActionCommand().equals("button1"))
{
((JButton) (event.getSource())).setText("X");
}
}
}
您可以调用getSource()
方法来获取调用此actionPerformed(ActionEvent)
方法的ButtonActionListener
,然后将其ButtonActionListener
为JButton
,因为我们知道它的ButtonActionListener
,然后设置其适当的文本。
更新:
这是如何使用外部ActionListener类的演示:
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class Demo
{
public static final String BUTTON_1 = "Demo.BUTTON_1";
public static final String BUTTON_2 = "Demo.BUTTON_2";
public Demo()
{
JFrame frame = new JFrame("Outer ActionListener");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout(FlowLayout.CENTER));
ButtonActionListener buttonActionListener = new ButtonActionListener();
JButton button1 = new JButton("Button 1");
button1.setActionCommand(Demo.BUTTON_1);
button1.addActionListener(buttonActionListener);
JButton button2 = new JButton("Button 2");
button2.setActionCommand(Demo.BUTTON_2);
button2.addActionListener(buttonActionListener);
frame.add(button1);
frame.add(button2);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setVisible(true);
}
public static void main(String[] args)
{
// Doing this because Swing is not thread safe.
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
new Demo();
}
});
}
}
class ButtonActionListener implements ActionListener
{
@Override
public void actionPerformed(ActionEvent event)
{
String actionCommand = event.getActionCommand();
// Since Java 7, String can be used in switch statements
switch (actionCommand)
{
case Demo.BUTTON_1:
System.out.println("Button 1 is clicked.");
break;
case Demo.BUTTON_2:
System.out.println("Button 2 is clicked.");
break;
default:
System.out.println("I don't know!");
break;
}
}
}
希望您的疑问现在已经清除。
顺便说一句,您还可以使用Anonymous Inner类来添加组件上的侦听器,并且自JDK 8开始,使用Lambda Expressions。 您可以搜索这些事情如何在线完成(如果您想了解实现同一件事的其他方法)。
您正在外部ActionListener中创建一个新的ButtonPanel对象。 这个新的ButtonPanel对象与正在显示并与用户交互的对象完全不同。
一个解决方案:通过侦听器的构造函数将对真正的ButtonPanel实例的引用传递到外部侦听器中。
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
class ButtonActionListener implements ActionListener
{
private ButtonPanel buttonPanel;
public ButtonActionListener(ButtonPanel buttonPanel)
{
this.buttonPanel = buttonPanel;
}
public void actionPerformed(ActionEvent actionEvent)
{
// ButtonPanel bp=new ButtonPanel();
if (actionEvent.getActionCommand().equals("button1"))
{
buttonPanel.buttons[0].setText("X");
}
}
}
然后,您可以通过以下方式进行设置:
buttons[i].addActionListener(
new ButtonActionListener(/*pass in the valid ButtonPanel reference here*/));
另一个更好的选择是将按钮链接到Model对象,为控件提供对Model对象的引用,并让其对模型进行方法调用或对其模型侦听器进行通知调用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.