简体   繁体   English

如何从JPanel触发ActionEvent

[英]How to fire an ActionEvent from a JPanel

I'm trying to repaint a simple massage in a panel by firing an ActionEvent. 我正在尝试通过触发ActionEvent重绘面板中的简单按摩。

I Have a MessagePanel that extends JPanel , in which I defined an addActionListener method and a processEvent method to process the event: 我有一个扩展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);
    }
}

Here's my test class: 这是我的测试课:

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);
    }
}

I'm trying to have the panel repaint the current time with every click of the panel (without using any other event sets) but I can't figure out what event is supposed to fire and invoke my processEvent method. 我试图让面板每次单击面板都重新绘制当前时间(不使用任何其他事件集),但是我无法弄清楚应该触发哪个事件并调用我的processEvent方法。 I'm not even really sure if I even need the processEvent , if I can just implement the process elsewhere. 我什至不能确定我是否甚至需要processEvent ,是否可以在其他地方实现该过程。

EDIT WITH TEXTBOOK PROBLEM (below)

(Enable MessagePanel to fire ActionEvent) The MessagePanel class in Listing 15.7 is a subclass of JPanel; (使MessagePanel能够触发ActionEvent)清单15.7中的MessagePanel类是JPanel的子类。 it can fire a MouseEvent, KeyEvent, and ComponentEvent, but not an ActionEvent. 它可以触发MouseEvent,KeyEvent和ComponentEvent,但不能触发ActionEvent。 Modify the MessagePanel class so that it can fire an ActionEvent when an instance of the MessagePanel class is clicked. 修改MessagePanel类,以便在单击MessagePanel类的实例时可以触发ActionEvent。 Name the new class MessagePanelWithActionEvent. 将新类命名为MessagePanelWithActionEvent。 Test it with a Java applet that displays the current time in a message panel whenever the message panel is clicked, as shown in Figure 36.9. 使用Java小程序对其进行测试,每当单击消息面板时,该Java小程序就会在消息面板中显示当前时间,如图36.9所示。

I'm trying to have the panel repaint the current time with every click of the panel (without using any other event sets) 我正在尝试使面板在每次单击面板时都重新绘制当前时间(不使用任何其他事件集)

An ActionListener is to be used only for events that are supposed to trigger it, such as a Timer or an AbstractButton. ActionListener仅用于应该触发它的事件,例如Timer或AbstractButton。 You should instead use a MouseListener for components that respond to mouse events. 您应该将MouseListener用于响应鼠标事件的组件。


Edit Your assignment: 编辑您的作业:

The MessagePanel class in Listing 15.7 is a subclass of JPanel; 清单15.7中的MessagePanel类是JPanel的子类。 it can fire a MouseEvent, KeyEvent, and ComponentEvent, but not an ActionEvent. 它可以触发MouseEvent,KeyEvent和ComponentEvent,但不能触发ActionEvent。 Modify the MessagePanel class so that it can fire an ActionEvent when an instance of the MessagePanel class is clicked. 修改MessagePanel类,以便在单击MessagePanel类的实例时可以触发ActionEvent。 Name the new class MessagePanelWithActionEvent. 将新类命名为MessagePanelWithActionEvent。 Test it with a Java applet that displays the current time in a message panel whenever the message panel is clicked, as shown in Figure 36.9. 使用Java小程序对其进行测试,每当单击消息面板时,该Java小程序就会在消息面板中显示当前时间,如图36.9所示。

  • You're going to have to give your MessagePanel a MouseListener, one that on mousePressed calls your ActionListener(s). 您将必须为您的MessagePanel提供一个MouseListener,在mousePressed上它会调用您的ActionListener。
  • In this MouseListener, you're going to have to create an ActionEvent object. 在此MouseListener中,您将必须创建一个ActionEvent对象。 Since this is an assignment, I'm not going to show you how to do this but instead will suggest that you go to the ActionEvent API to see what this object needs, and give it try. 由于这是一项任务,因此我不向您展示如何执行此操作,而是建议您转到ActionEvent API来查看此对象的需求,然后尝试一下。
  • Then you will have to call actionPerformed(...) with the ActionEvent object you've just created on any ActionListeners that need to be called. 然后,您必须使用刚刚在需要调用的所有ActionListener上创建的ActionEvent对象来调用actionPerformed(...)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM