Слушатель вызывает другого слушателя - PullRequest
1 голос
/ 18 октября 2011

В классе, который создает меню с использованием Swing, я добавил 4 элемента, каждый из которых отвечает за рисование круга разного цвета.Я назначил каждому пункту этого меню ActionListener просто чтобы указать цвет желаемого круга.Мне нужно следовать, чтобы щелкнуть мышью в любом месте панели и там круг, который будет создан.Для этого я создал еще один класс ScrollPane, который реализует mouseListener и отвечает за рисование круга.Я не знаю, однако, как вызвать mouseListener для второго класса, который будет делать эту работу.Это должно быть сделано только после того, как прослушиватель меню был вызван.Мне нужна явно ссылка на класс ScrollPane, а затем назначить на него mouseListener.

Однако я не знаю, какой параметр мне следует использовать для метода addMouseListener.Или это объявлено в классе ScrollPane?Я думаю, что это просто, если все задачи выполняются в одном классе, который реализует оба слушателя, но что, если я хочу разделить их?Вот соответствующий код:

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

Ответы [ 2 ]

2 голосов
/ 18 октября 2011

Не пытайтесь повторно отправить вызов слушателя мыши, если это то, что вы пытаетесь сделать.Ты не мышь.Вместо этого попросите методы слушателя мыши просто вызывать другие методы на ваших объектах, которые выполняют фактическую работу.Ваши процедуры прослушивания мыши должны быть тривиальными: «Если это, вызовите это, если это, вызовите это.»

Затем, если есть связь между объектами, пусть один из них получит щелчки слушателя мыши.Затем вызовите методы для всех объектов, на которые должен повлиять этот щелчок.

То, что я делал в прошлом, когда, скажем, сетка помещалась внутри другого объекта свинга, - это создание моих собственных шаблонов слушателей.Затем, когда с объектом X происходит что-то, что необходимо передать объекту Y, я использую свой шаблон слушателя.Таким образом, становится ясно, какую работу необходимо выполнять при каждом вызове данного метода.И это более многоразового использования.Так что, если это не щелчок мышью, а меню, которое вызывает что-то, мне не нужно дублировать логику.

Извините, если это не очень ясно.

1 голос
/ 19 октября 2011

Вы всегда можете переслать события от одного компонента к другому, как показано здесь Action является предпочтительным способом инкапсуляции поведения, общего для меню и компонентов.

В этом случае, похоже, что вы хотите рисовать и манипулировать мышью самостоятельно.Возможно, вы захотите изучить этот простой GraphPanel, который вместо этого полагается на обычных слушателей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...