【问题标题】:How to fire an ActionEvent from a JPanel如何从 JPanel 触发 ActionEvent
【发布时间】:2013-10-06 13:20:33
【问题描述】:

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

我有一个扩展JPanelMessagePanel,我在其中定义了一个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)

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

【问题讨论】:

    标签: java swing event-handling actionlistener actionevent


    【解决方案1】:

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

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


    编辑你的作业:

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

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

    【讨论】:

    • 是的。我正在做一个教科书问题(处理实现监听器的事件)。问题清楚地表明 JPanel 使用鼠标事件而不是动作事件。所以它要求你将动作事件实现到 JPanel 中。
    • @peeskillet:请在您的问题中逐字发布实际作业。希望是英文的。
    • 我已经把问题贴在我的帖子底部了
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-04
    • 2015-01-20
    • 1970-01-01
    • 2017-07-24
    • 1970-01-01
    相关资源
    最近更新 更多