java - 动态添加多个 MouseListener JPanel

标签 java swing mouselistener

我正在尝试使用 JPanel 将形状添加到窗口上,然后能够在窗口周围单击并拖动它们。如果我只有一种形状,这就有效;但当我添加更多形状时,单击和拖动非常时髦。它确实拖动但不使用鼠标拖动,它不成比例并且不使用鼠标拖动。

感谢任何帮助。谢谢!

public class SimpleDraw {

    public static void main(String[] args) {

        JFrame frame = new UMLWindow();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setBounds(30, 30, 1000, 700);
        frame.getContentPane().setBackground(Color.white);
        frame.setVisible(true);
        frame.setLocationRelativeTo(null);

        // Display the window.
        frame.setVisible(true);

    }
}

class UMLWindow extends JFrame {
    Squares squares = new Squares();

    private static final long serialVersionUID = 1L;

    public UMLWindow() {
        addMenus();
    }

    public void addMenus() {

        getContentPane().add(squares);

        JMenuBar menubar = new JMenuBar();

        JMenu shapes = new JMenu("Shapes");

        JMenuItem rectangleMenuItem = new JMenuItem("New Rectangle");
        rectangleMenuItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                squares.addSquare(10, 10, 100, 100);
            }
        });

        shapes.add(rectangleMenuItem);

        menubar.add(shapes);

        setJMenuBar(menubar);

        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

}

class Squares extends JPanel {
    private static final long serialVersionUID = 1L;

    private List<Path2D> squares = new ArrayList<Path2D>();
    // private Path2D rect = new Path2D.Double();
    int currentIndex;

    public void addSquare(int x, int y, int width, int height) {
        Path2D rect2 = new Path2D.Double();
        rect2.append(new Rectangle(getWidth() / 2 - width / 2, getHeight() / 2
                - height / 2, width, height), true);

        squares.add(rect2);
        // rect = rect2;
        MyMouseAdapter myMouseAdapter = new MyMouseAdapter();
        addMouseListener(myMouseAdapter);
        addMouseMotionListener(myMouseAdapter);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        this.setOpaque(true);
        this.setBackground(Color.WHITE);
        Graphics2D g2 = (Graphics2D) g;
        for (Path2D rect : squares) {
            g2.draw(rect);
        }
        repaint();
    }

    class MyMouseAdapter extends MouseAdapter {
        private boolean pressed = false;
        private Point point;

        @Override
        public void mousePressed(MouseEvent e) {
            if (e.getButton() != MouseEvent.BUTTON1) {
                return;
            }
            for (int i = 0; i < squares.size(); i++) {
                if (squares.get(i) != null
                        && squares.get(i).contains(e.getPoint())) {
                    currentIndex = i;
                    pressed = true;
                    this.point = e.getPoint();
                }
            }
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            if (pressed) {
                int deltaX = e.getX() - point.x;
                int deltaY = e.getY() - point.y;
                squares.get(currentIndex).transform(
                        AffineTransform.getTranslateInstance(deltaX, deltaY));
                point = e.getPoint();
                repaint();
            }
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            pressed = false;
        }
    }

}

最佳答案

问题很多...

  • 最重要的是,不,您不想向 JPanel 添加一堆 MouseListeners/MouseMotionListeners。您只想添加一个,并让它控制 JPanel 拥有的任何和所有方 block 。
  • 不要在您的paintComponent方法中放置repaint(),因为这是尝试创建动画循环(您完全无法控制的循环)的糟糕方法。还有就是没必要。 MouseAdapter 应自行驱动所有动画。
<小时/>
class Squares extends JPanel {
   private static final long serialVersionUID = 1L;

   public Squares() {
      MyMouseAdapter myMouseAdapter = new MyMouseAdapter();
      addMouseListener(myMouseAdapter);
      addMouseMotionListener(myMouseAdapter);
   }

   private List<Path2D> squares = new ArrayList<Path2D>();
   // private Path2D rect = new Path2D.Double();
   int currentIndex;

   public void addSquare(int x, int y, int width, int height) {
      Path2D rect2 = new Path2D.Double();
      rect2.append(new Rectangle(getWidth() / 2 - width / 2, getHeight() / 2
            - height / 2, width, height), true);

      squares.add(rect2);
      repaint(); // !!
      // rect = rect2;
      // !! MyMouseAdapter myMouseAdapter = new MyMouseAdapter();
      // addMouseListener(myMouseAdapter);
      // addMouseMotionListener(myMouseAdapter);
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      this.setOpaque(true);
      this.setBackground(Color.WHITE);
      Graphics2D g2 = (Graphics2D) g;
      for (Path2D rect : squares) {
         g2.draw(rect);
      }
      // !! repaint();

}

关于java - 动态添加多个 MouseListener JPanel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26080417/

相关文章:

java - 如何为JAXB创建的java文件创建jar?

java - 尝试将 recylerview 添加到 fragment 时未找到资源异常

swing - 如何在 JEditorPane 中使用 Netbeans 平台语法高亮?

java - 无需调整应用程序大小即可显示 Swing 组件

java - 当我点击图像时如何使图像消失?

java - Java Swing中的鼠标指针问题

java - 在 maven 测试运行中执行时,使用 Spring 注释进行测试会导致 ClosedByInterruptException

java - 从布局中包含的 ListView 接收字符串。安卓

java - FlowLayout 不与周围的 JScrollPane 一起流动

java - 在 JButton 上模拟 JMenuItem MouseListener