java - 如何在鼠标位置添加面板?

标签 java swing jpanel

我想在鼠标位置添加一个面板(位于其他面板上)。当我现在添加时,面板的位置位于上一个面板的旁边。

  jPanel1.setLayout(new FlowLayout());
  JPanel newPanel = new JPanel();
  newPanel.setBackground(Color.red);
  jPanel1.add(newPanel);

  newPanel.setLocation(300,300);
  jPanel1.revalidate();
  jPanel1.repaint();


  Point point = newPanel.getLocation();
  int x = point.x;
  int y = point.y;
  newPanel.setLocation(x+5,y+5);

最佳答案

如果您需要将 Swing 组件放置在随机位置,那么您将需要一个允许这样做的布局管理器,而 FlowLayout 以及大多数标准管理器则不允许。最常用的也是最简单的——空布局,例如,someJPanel.setLayout(null);——完全没有布局管理器,但是它有自己的主机麻烦,所以我尽量避免使用这些。

但是,如果您的目标是移动红色方 block ,那么最好让事情尽可能简单,而不是创建和移动 JPanel,而是创建和移动重量更轻的矩形。

例如,

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.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;

public class MovingRect extends JPanel {
    private static final long serialVersionUID = 1L;
    private static final Color RECT_COLOR = Color.RED;
    private static final int RECT_W = 300;
    private Rectangle rect = new Rectangle(0, 0, RECT_W, RECT_W);

    public MovingRect() {
        setPreferredSize(new Dimension(800, 650));

        MyMouse myMouse = new MyMouse();
        addMouseListener(myMouse);
        addMouseMotionListener(myMouse);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(RECT_COLOR);
        ((Graphics2D) g).fill(rect);
    }

    private class MyMouse extends MouseAdapter {
        private Point p0;
        private Point pRect;

        @Override
        public void mousePressed(MouseEvent e) {
            if (e.getButton() != MouseEvent.BUTTON1) {
                return;
            }

            if (rect.contains(e.getPoint())) {
                p0 = e.getPoint();
                pRect = rect.getLocation();
            }
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            if (p0 != null) {
                drag(e);
            }
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            if (p0 != null) {
                drag(e);
                p0 = null;
            }
        }

        private void drag(MouseEvent e) {
            // use simple geometry to move the rectangle
            Point p1 = e.getPoint();
            int x = p1.x - p0.x + pRect.x;
            int y = p1.y - p0.y + pRect.y;
            rect = new Rectangle(x, y, RECT_W, RECT_W);
            repaint();
        }

    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }

    private static void createAndShowGui() {
        MovingRect mainPanel = new MovingRect();
        JFrame frame = new JFrame("Moving Rectangle");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}
<小时/>

代码说明

要绘制的矩形,最初放置在 0, 0:

private Rectangle rect = new Rectangle(0, 0, RECT_W, RECT_W);

在构造函数中,设置绘图 JPanel 的首选大小,并创建将移动矩形的鼠标监听器(实际上是 MouseAdapter),并将 MouseAdapter 作为 MouseListener 和 MouseMotionListener 添加到我们的绘图(主)JPanel 中:

public MovingRect() {
    setPreferredSize(new Dimension(800, 650));

    MyMouse myMouse = new MyMouse();
    addMouseListener(myMouse);
    addMouseMotionListener(myMouse);
}

通过调用 super 方法进行清理绘制后,在此 JPanel 的 PaintComponent 方法中绘制矩形:

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.setColor(RECT_COLOR);
    ((Graphics2D) g).fill(rect);
}

进行移动的鼠标适配器。它使用简单的 vector 加法几何来计算移动位置

private class MyMouse extends MouseAdapter {
    private Point p0;
    private Point pRect;

    @Override
    public void mousePressed(MouseEvent e) {
        if (e.getButton() != MouseEvent.BUTTON1) {
            // if not button 1, then get out of here
            return;
        }

        if (rect.contains(e.getPoint())) {
            // get the first point of the mouse press and the rectangle's first position
            p0 = e.getPoint();
            pRect = rect.getLocation();
        }
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        if (p0 != null) {
            drag(e);
        }
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        if (p0 != null) {
            drag(e);
            p0 = null; // set the first pressed point to null -- stop the listener
        }
    }

    private void drag(MouseEvent e) {
        // use simple geometry to move the rectangle
        Point p1 = e.getPoint();
        int x = p1.x - p0.x + pRect.x;
        int y = p1.y - p0.y + pRect.y;

        // create a new Rectangle with the position calculated above
        rect = new Rectangle(x, y, RECT_W, RECT_W);

        // ask Java to repaint the main JPanel
        repaint();
    }

}

关于java - 如何在鼠标位置添加面板?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56090262/

相关文章:

java - 如何在 iCal google-rfc-2445 的 java 中使日期每年重复二月的最后一天

java - 如何保存文件名然后使其出现在文本区域中

java - JSP 的 JTable 替代品

java - JPanel 的精确副本或撤消..建议

java - 不知道为什么我无法让 addMouseListener(this())、addMouseMotionListener(this()) 工作

java - Travis CI 失败并警告有关旧 jdk 下的 -Xdoclint 标志

java - 当应用程序处于前台状态时无法接收来自 FCM 的通知

java - LinkList,检查双值

java - 将数据附加到 JTextArea 以进行运行模拟

java - 球不会在屏幕上移动