Java - 从另一个组件访问 MouseListener 的数据

Java - Access datas of a MouseListener from another Component

我目前正在为一款游戏开发关卡编辑器。目前,要创建实体,您必须单击创建 JButton,然后会出现一个表单,您可以在其中输入其坐标和大小。

我想实现鼠标功能。用户单击创建的 JButton,然后必须在预览级别的 JPanel 上的某处按下鼠标按钮,然后拖动以设置对象的大小,最后释放按钮。然后在按下按钮的位置创建对象。

我将 MouseListener 添加到 previewPanel(以获得正确的坐标)。

我的问题是:单击按钮时我应该做什么?
在 actionPerformed 方法中?

基本上,程序是:
1)等待按钮被按下
2) 获取坐标
3)等待按钮被释放
4) 获取新的坐标使物体的大小
5) 创建对象

我应该如何正确地进行操作?

提前致谢

My problem is : what should I do when I click on the button ? Inside the actionPerformed method ?

激活鼠标监听器。这可以通过在单击按钮时将 MouseListener 和 MouseMotionListener(MouseAdapater 可以同时执行)添加到绘图 JPanel,或者通过更改已添加的 MouseAdapater(我的偏好)的状态,再次添加到 JPanel。这可以像将布尔变量切换为 true 一样简单,然后让 mousePressed、mouseDragged、mouseReleased 方法在执行任何操作之前检查此布尔值的状态。

请注意,如果您采用第一种方法 - 通过在按下按钮时添加 MouseListener/MouseMotionListener,如果您在完成时不注意删除它们,则可能会添加多个侦听器。这就是为什么我更喜欢第二种方法。

例如,

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;

import javax.swing.*;

public class ActivateMouse extends JPanel {
   private static final int PREF_W = 400;
   private static final int PREF_H = PREF_W;
   private static final Color DRAW_RECT_COLOR = Color.pink.brighter();
   private static final Color DRAW_ALL_RECTS_COLOR = Color.red;
   private boolean mouseActive = false;
   private Shape drawRect = null;
   private List<Shape> shapeList = new ArrayList<>();
   private ButtonAction buttonAction = new ButtonAction("Create New Rectangle", KeyEvent.VK_C);

   public ActivateMouse() {
      MyMouseAdapter myMouseAdapter = new MyMouseAdapter();
      addMouseListener(myMouseAdapter);
      addMouseMotionListener(myMouseAdapter);

      add(new JButton(buttonAction));
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2 = (Graphics2D) g;
      if (drawRect != null) {
         g2.setColor(DRAW_RECT_COLOR);
         g2.draw(drawRect);
      }

      g2.setColor(DRAW_ALL_RECTS_COLOR);
      for (Shape shape : shapeList) {
         g2.draw(shape);
      }
   }

   @Override
   public Dimension getPreferredSize() {
      if (isPreferredSizeSet()) {
         return super.getPreferredSize();
      }
      return new Dimension(PREF_W, PREF_H);
   }

   private class MyMouseAdapter extends MouseAdapter {
      private Point firstPt;

      @Override
      public void mousePressed(MouseEvent e) {
         if (mouseActive && e.getButton() == MouseEvent.BUTTON1) {
            firstPt = e.getPoint();
         }
      }

      @Override
      public void mouseDragged(MouseEvent e) {
         if (!mouseActive || firstPt == null) {
            return;
         }
         drawRect = createRect(e.getPoint());
         repaint();
      }

      @Override
      public void mouseReleased(MouseEvent e) {
         if (!mouseActive || firstPt == null) {
            return;
         }
         shapeList.add(createRect(e.getPoint()));
         repaint();
         mouseActive = false;
      }

      private Shape createRect(Point p) {
         int x = Math.min(firstPt.x, p.x);
         int y = Math.min(firstPt.y, p.y);
         int width = Math.abs(firstPt.x - p.x);
         int height = Math.abs(firstPt.y - p.y);
         return new Rectangle(x, y, width, height);
      }
   }

   private class ButtonAction extends AbstractAction {
      public ButtonAction(String name, int mnemonic) {
         super(name);
         putValue(MNEMONIC_KEY, mnemonic);
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         mouseActive = true;
      }
   }

   private static void createAndShowGui() {
      JFrame frame = new JFrame("ActivateMouse");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(new ActivateMouse());
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}