如何从JPanel触发ActionEvent

时间:2013-10-06 13:20:34

标签: java swing event-handling actionlistener actionevent

我试图通过触发ActionEvent在面板中重新绘制一个简单的按摩。

我有MessagePanel扩展JPanel,其中我定义了addActionListener方法和processEvent方法来处理事件:

import java.awt.Graphics;
import javax.swing.JPanel; 
import java.util.*;
import java.awt.event.*;

public class MessagePanel extends JPanel {
    private String message = new Date().toString();
    ArrayList<ActionListener> actionListenerList;

    public MessagePanel(String message) {
        this.message = message;
    }

    public void setMessage(String message){
        this.message = message;
    }

    public void addActionListener(ActionListener listener) {
        if (actionListenerList == null) {
            actionListenerList = new ArrayList<>(2);
        }
        if (!actionListenerList.contains(listener)) {
            actionListenerList.add(listener);
        }
    }

    public void removeActionListener(ActionListener listener) {
        if (actionListenerList != null &&
                actionListenerList.contains(listener)) {
            actionListenerList.remove(listener);
        }
    }

    public void processEvent(ActionEvent e) {
        ArrayList<ActionListener> list;

        synchronized(this) {
            if (actionListenerList == null) {
                return;
            }
            list = (ArrayList<ActionListener>)actionListenerList.clone();
        }

        for (int i = 0; i < list.size(); i++) {
            ActionListener listener = (ActionListener)list.get(i);
            listener.actionPerformed(e);
        }     
    }

    @Override
    protected void paintComponent(Graphics g){
         super.paintComponent(g);
         g.drawString(message, 0, 0);
    }
}

这是我的测试类:

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

public TestMessaePanel extends JFrame {
    MessagePanel messagePanel = new MessagePanel(new Date().toString());

    public TestMessagePanel() {
        add(messagePanel);
        messagePanel.setCentered(true);

        messagePanel.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e){
                messagePanel.setMessage(new Date().toString());
            }
        });
    }

    public static void main(String[] args) {
        JFrame frame = new TestMessagePanelWithActionEvent();
        frame.setSize(300, 200);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

我正在尝试让面板在每次单击面板时重新绘制当前时间(不使用任何其他事件集)但是我无法弄清楚应该触发什么事件并调用我的processEvent方法。如果我能在其他地方实施这个过程,我甚至不确定我是否需要processEvent

EDIT WITH TEXTBOOK PROBLEM (below)

(启用MessagePanel以激活ActionEvent)中的MessagePanel类 清单15.7是JPanel的子类;它可以触发MouseEvent, KeyEvent和ComponentEvent,但不是ActionEvent。修改 MessagePanel类,以便它可以在实例时触发ActionEvent 单击MessagePanel类。命名新类 MessagePanelWithActionEvent。使用显示的Java小程序对其进行测试 消息面板的每个消息面板中的当前时间 单击,如图36.9所示。

1 个答案:

答案 0 :(得分:2)

  

我试图让面板在每次点击面板时重新绘制当前时间(不使用任何其他事件集)

ActionListener仅用于应该触发它的事件,例如Timer或AbstractButton。您应该使用MouseListener来处理响应鼠标事件的组件。


修改您的作业:

  

清单15.7中的MessagePanel类是JPanel的子类;它可以触发MouseEvent,KeyEvent和ComponentEvent,但不能激活ActionEvent。修改MessagePanel类,以便在单击MessagePanel类的实例时触发ActionEvent。将新类命名为MessagePanelWithActionEvent。使用Java applet测试它,只要单击消息面板,就会在消息面板中显示当前时间,如图36.9所示。

  • 你将不得不给你的MessagePanel一个MouseListener,一个在mousePressed上调用你的ActionListener。
  • 在此MouseListener中,您将不得不创建一个ActionEvent对象。由于这是一项任务,我不会向您展示如何执行此操作,而是建议您转到ActionEvent API以查看此对象需要的内容,并尝试使用。
  • 然后,您必须使用刚刚在需要调用的任何ActionListener上创建的ActionEvent对象调用actionPerformed(...)