Вызов MouseListener для двух разных вещей

#java #shapes #mouselistener

#java #формы #mouselistener

Вопрос:

приложение с открытым классом расширяет JFrame { открытый прямоугольник.Обработчик MyMouseHandler;

 public class MyMouseHandler extends MouseAdapter{
    
    public void MouseClicked(MouseEvent e){
        if (e.getModifiers() == MouseEvent.BUTTON3_MASK amp;amp; e.getClickCount() == 1) {
        initUI1();
    }
     if (e.getModifiers() == MouseEvent.BUTTON1_MASK amp;amp; e.getClickCount() == 1){
         initUI2();
     }       
}
}
                 

private void initUI1() {

    add(new Rectangle());

    setSize(800, 800);

    setTitle("Application");
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setLocationRelativeTo(null);
}    
private void initUI2() {

    add(new Circle());

    setSize(800, 800);

    setTitle("Application");
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setLocationRelativeTo(null);
}
/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
     EventQueue.invokeLater(() -> {
        Application ex = new Application();
        ex.setVisible(true);
    });
}
}
 

Я хочу создать программу, в которой я могу нарисовать прямоугольник и круг щелчком левой кнопки мыши и использовать щелчок правой кнопкой мыши для переключения между ними. Я уже создал оба класса Circle и Rectangle.

Ответ №1:

Тривиальным решением является введение переменной- boolean члена, которая служит переключателем между двумя возможными состояниями, т.Е.

  • готовы нарисовать круг
  • готов нарисовать прямоугольник

Это может выглядеть следующим образом:

 // if true then the next shape to be drawn should be a circle
private boolean drawCircleNext = true;
 

Итак, глядя на ваш прослушиватель мыши, вам нужно включить щелчок правой кнопкой мыши и проверить состояние, прежде чем рисовать левой кнопкой мыши:

 public void MouseClicked( MouseEvent e )
{
    // assuming BUTTON3_MASK equals a right-click
    if( e.getModifiers() == MouseEvent.BUTTON3_MASK amp;amp; e.getClickCount() == 1 ) 
    {
        drawCircleNext = !drawCircleNext;
    }
    
    // assuming BUTTON1_MASK equals a left-click
    if( e.getModifiers() == MouseEvent.BUTTON1_MASK amp;amp; e.getClickCount() == 1 )
    {
        if( drawCircleNext ) 
        {
            initUI2();
        }
        else
        {
            initUI1();
        }
    }    
}
 

Этой простой версии уже должно быть достаточно для начала.

Комментарии:

1. И как мне вызвать метод mouseClicked в моем основном классе. Потому что первый класс — это класс Application, а другой класс — MyMouseHandler .

Ответ №2:

Я бы использовал an enum для сохранения фактического режима рисования (легко расширяемый):

     private enum Mode {
        RECTANGLE, CIRCLE;
    }

    private Mode mode = Mode.RECTANGLE;
 

Код для переключения режима, вызываемый из прослушивателя (щелчок правой кнопкой мыши), изменяет режим в соответствии с фактическим режимом:

     private void changeMode(MouseEvent ignored) {
        mode = switch (mode) {
            case CIRCLE -> Mode.RECTANGLE;
            case RECTANGLE -> Mode.CIRCLE;
            default -> throw new IllegalArgumentException(mode   " not implemented");
        };
    }
 

и код из добавления фигуры (щелчок левой кнопкой мыши) проверит режим и добавит соответствующую фигуру:

     private void addShape(MouseEvent ev) {
        var x = ev.getX()-SIZE/2;
        var y = ev.getY()-SIZE/2;
        var shape = switch (mode) {
            case CIRCLE -> new Ellipse2D.Double(x, y, SIZE, SIZE);
            case RECTANGLE -> new Rectangle(x, y, SIZE, SIZE);
            default -> throw new IllegalArgumentException(mode   " not implemented");
        };
        shapes.add(shape);
        repaint();
    }
 

shapes это просто a List<Shape> , содержащий фигуры, которые нужно нарисовать (внутри класса, расширяющего JComponent or JPanel ).

     private final List<Shape> shapes = new ArrayList<>();
    ...
    
    @Override
    protected void paintComponent(Graphics g) {
        shapes.forEach(((Graphics2D)g)::draw);
    }
 

наконец, слушатель мыши ( MouseAdapter ) вызовет:

     private void doMouseClicked(MouseEvent ev) {
        switch (ev.getButton()) {
            case MouseEvent.BUTTON1:
                addShape(ev);
                break;
            case MouseEvent.BUTTON3:
                changeMode(ev);
                break;
            default:
                // empty
                break;
        }
    }