监听器调用另一个监听器

发布于 2024-12-10 18:03:34 字数 3913 浏览 0 评论 0原文

在使用 Swing 创建菜单的类中,我添加了 4 个项目,每个项目负责绘制一个不同颜色的圆圈。我已经为该菜单的每个项目分配了一个 ActionListener,只是为了指定所需圆圈的颜色。我需要在面板中的任意位置单击鼠标,然后创建圆圈。为此,我创建了另一个 ScrollPane 类,它实现 mouseListener 并负责绘制圆圈。但我不知道如何触发第二个类的 mouseListener 来完成这项工作。仅应在调用菜单侦听器后执行此操作。显然我需要对类 ScrollPane 的引用,然后在其上分配 mouseListener。

但是我不知道应该对 addMouseListener 方法使用什么样的参数。或者这是在 ScrollPane 类中声明的?我认为如果所有任务都在一个实现两个侦听器的类中执行,那么这很简单,但是如果我想将它们分开怎么办?actionPerformed 还应该做什么? 这是相关代码:

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

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. I have assigned to each item of that menu an ActionListener just to specify the color of the desired circle. 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. I do not know though, how to trigger the mouseListener to the second class which will do the job. 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.

I do not know however what kind of parameter I should use to the method addMouseListener. Or this is declared in ScrollPane class? 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?
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;
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

烦人精 2024-12-17 18:03:34

如果您想要这样做,请不要尝试重新发送鼠标侦听器调用。你不是老鼠。相反,让鼠标侦听器方法只需调用对象上执行实际工作的其他方法。您的鼠标侦听器例程应该很简单:“如果是这个,则调用这个,如果是那个,则调用那个”。

然后,如果对象之间存在关系,则让其中之一接收鼠标侦听器单击。然后调用应受该单击影响的所有对象上的方法。

过去,当我将网格放置在另一个摇摆对象内时,我所做的就是创建我自己的侦听器模式。然后,当对象 X 发生需要传递给对象 Y 的情况时,我使用侦听器模式。这样,每当调用给定方法时需要完成哪些工作就很清楚了。而且它更可重复使用。因此,如果不是鼠标点击而是触发某些内容的菜单,我就不必重复逻辑。

抱歉,如果这不是很清楚。

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. 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.

紙鸢 2024-12-17 18:03:34

您始终可以将事件从一个组件转发到另一个组件,如此处所示;并且 Action 是首选封装菜单和组件共享行为的方法。

在这种情况下,您似乎想自己进行绘图和鼠标处理。您可能想检查一下这个简单的 GraphPanel,它依赖于而是针对普通听众。

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.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文