简体   繁体   English

侦听器调用另一个侦听器

[英]Listener invokes another listener

In a class which creates a menu using Swing I have added 4 items, each one of them is responsible for drawing a circle of different color. 在使用Swing创建菜单的类中,我添加了4个项目,每个项目都负责绘制一个不同颜色的圆圈。 I have assigned to each item of that menu an ActionListener just to specify the color of the desired circle. 我已经为该菜单的每个项目分配了一个ActionListener来指定所需圆圈的颜色。 I need following to click the mouse anywhere in the Panel and there the circle to be created. 我需要在面板中的任意位置点击鼠标,然后在那里创建圆圈。 To this effect, I have created another class ScrollPane which implements the mouseListener and it is responsible to draw the circle. 为此,我创建了另一个类ScrollPane,该类实现了mouseListener,它负责绘制圆圈。 I do not know though, how to trigger the mouseListener to the second class which will do the job. 我不知道,如何触发mouseListener到第二个类来完成这项工作。 This should be done only after the listener of the menu has been invoked. 只有在调用菜单的监听器之后才能执行此操作。 I need obviously a reference to class ScrollPane and then to assign on that the mouseListener. 我显然需要对类ScrollPane的引用,然后在其上分配mouseListener。

I do not know however what kind of parameter I should use to the method addMouseListener. 但是我不知道我应该对addMouseListener方法使用什么样的参数。 Or this is declared in ScrollPane class? 或者这是在ScrollPane类中声明的? I think it is simple in case all tasks are carried out in one class which implements both listeners, but what if I want to separate them?What else should the actionPerformed do? 如果所有任务都在一个实现两个侦听器的类中执行,我认为这很简单,但是如果我想将它们分开,该actionPerformed还应该做什么? Here is the relevant code: 这是相关代码:

public class CreateMenu implements ActionListener {
    private ScrollPane scrollPane;

    public void actionPerformed(ActionEvent e) {
        JMenuItem source = (JMenuItem)(e.getSource());
        if(source.getText() == "Green Circle")
            this.scrollPane.setColor(Color.green);
         else if(source.getText() == "Blue Circle")
             this.scrollPane.setColor(Color.blue);
         else if(source.getText() == "Red Circle")
             this.scrollPane.setColor(Color.red);
         else if(source.getText() == "Yellow Circle")
             this.scrollPane.setColor(Color.yellow);
         else
             return;
     }
}

.

public class ScrollPane extends JPanel implements MouseListener {
    private Dimension area;
    private Vector<Circle> circles;
    private Color color;
    private JPanel drawingPane;

    public ScrollPane() {
        super(new BorderLayout());

        area = new Dimension(0,0);
        circles = new Vector<Circle>();

        //Set up the drawing area.
        drawingPane = new DrawingPane();
        drawingPane.setBackground(Color.white);
        drawingPane.addMouseListener(this);

        //Put the drawing area in a scroll pane.
        JScrollPane scroller = new JScrollPane(drawingPane);
        scroller.setPreferredSize(new Dimension(200,200));

        add(scroller, BorderLayout.CENTER);
    }

    public class DrawingPane extends JPanel {
        protected void paintComponent(Graphics g, Color color ) {
            super.paintComponent(g);

            Rectangle rect;
            for (int i = 0; i < circles.size(); i++) {
                rect = circles.elementAt(i).getRect();
                g.setColor(circles.elementAt(i).getTheColor());
                g.fillOval(rect.x, rect.y, rect.width, rect.height);
            }
        }
    }

    public void mouseReleased(MouseEvent e) {
        final int W = 100;
        final int H = 100;
        boolean changed = false;

        if(SwingUtilities.isLeftMouseButton(e)) {
            int x = e.getX() - W/2;
            int y = e.getY() - H/2;
            if (x < 0) x = 0;
            if (y < 0) y = 0;
            Rectangle rect = new Rectangle(x, y, W, H);
            Circle newCircle = new Circle(rect, this.color);
            circles.addElement(newCircle);
            drawingPane.scrollRectToVisible(rect);

            int this_width = (x + W + 2);
            if (this_width > area.width) {
                area.width = this_width; changed=true;
            }

            int this_height = (y + H + 2);
            if (this_height > area.height) {
                area.height = this_height; changed=true;
            }
        }
        if (changed) {
            //Update client's preferred size because
            //the area taken up by the graphics has
            //gotten larger or smaller (if cleared).
            drawingPane.setPreferredSize(area);

            //Let the scroll pane know to update itself
            //and its scrollbars.
            drawingPane.revalidate();
        }
        drawingPane.repaint();
    }
    public void mouseClicked(MouseEvent e){}
    public void mouseEntered(MouseEvent e){}
    public void mouseExited(MouseEvent e){}
    public void mousePressed(MouseEvent e){}


    public void setColor(Color color) {
        this.color = color;
    }

    public JPanel getDrawingPane() {
        return drawingPane;
    }
}

Don't try to resend a mouse-listener call, if that's what you're trying to do. 如果您正在尝试这样做,请不要尝试重新发送鼠标监听器调用。 You're not a mouse. 你不是老鼠。 Instead, have the mouse listener methods simply call other methods on your objects that do the actual work. 相反,让鼠标侦听器方法只需调用对象上执行实际工作的其他方法。 Your mouse listener routines should be trivial "If this, call this, if that, call that." 您的鼠标监听器例程应该是微不足道的“如果是这样,请调用它,如果是这样,请调用它。”

Then, if there's a relationship between objects, let one of them receive the mouse listener clicks. 然后,如果对象之间存在关系,请让其中一个接收鼠标侦听器单击。 Then invoke the methods on all objects that should be affected by that click. 然后在应该受该单击影响的所有对象上调用方法。

What I've done in the past when, say, a grid is placed inside another swing object, is to create my own listener patterns. 过去,将网格放置在另一个摆动对象中时,我所做的就是创建自己的侦听器模式。 Then, when something happens to object X that needs to be passed along to object Y, I use my listener pattern. 然后,当对象X发生需要传递给对象Y的事情时,我使用我的侦听器模式。 That way, it's clear what work needs to be done whenever a given method is called. 这样,很明显每当调用给定方法时都需要完成哪些工作。 AND it's more reusable. 它更可重复使用。 So if it's not a mouse click but a menu that triggers something, I don't have to duplicate logic. 因此,如果它不是鼠标点击而是触发某事的菜单,我不必复制逻辑。

Sorry if that's not very clear. 对不起,如果不是很清楚。

You can always forward events from one component to another, as shown here ; 您可以随时向前如图所示,从一个组件到另一个活动在这里 ; and Action is the preferred way to encapsulate behavior shared by menus and components. Action是封装菜单和组件共享行为的首选方法。

In this case, it looks like you want to do the drawing and mouse handling yourself. 在这种情况下,您似乎想要自己进行绘图和鼠标处理。 You might like to examine this simple GraphPanel , which relies on common listeners instead. 您可能想研究这个简单的GraphPanel ,它依赖于常见的侦听器。

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

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