java - 一键按下并拖动?

标签 java swing mouseevent jpanel mousemove

我有一个程序,我可以通过单击创建 JLabel,然后将其拖动到界面的另一部分。

我想要的是单击 JPanel 中的某个位置,让它在那里放置一个 JLabel,然后在同一单击中拖动另一个 JLabel。

我可以做到这一点,但需要多次点击。我可以一键完成吗?

为了说明我的意思,我创建了这个示例程序:

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

public class DragTest extends JFrame implements MouseMotionListener,
        MouseListener {

    private JPanel panel = new JPanel(null);
    private JLabel dragLabel = new JLabel("drag");;
    private final JWindow window = new JWindow();

    public DragTest() {
        this.add(panel);
        panel.addMouseListener(this);

        dragLabel.setFont(new Font("Serif", Font.BOLD, 48));
    }

    @Override
    public void mouseDragged(MouseEvent me) {
        dragLabel = new JLabel("drag");
        dragLabel.setFont(new Font("Serif", Font.BOLD, 48));
        int x = me.getPoint().x;
        int y = me.getPoint().y;
        window.add(dragLabel);
        window.pack();
        Point pt = new Point(x, y);
        Component c = (Component) me.getSource();
        SwingUtilities.convertPointToScreen(pt, c);
        window.setLocation(pt);
        window.setVisible(true);
        repaint();
    }

    @Override
    public void mouseMoved(MouseEvent e) {
    }

    @Override
    public void mouseClicked(MouseEvent e) {

    }

    @Override
    public void mousePressed(MouseEvent e) {

        JLabel dropLabel = new JLabel("drop");
        panel.add(dropLabel);
        dropLabel.setForeground(Color.RED);
        dropLabel.setFont(new Font("Serif", Font.BOLD, 48));
        dropLabel.setBounds(e.getX(), e.getY(), 100, 60);
        dropLabel.addMouseMotionListener(this);
        dropLabel.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseReleased(MouseEvent e) {
                dragLabel.setVisible(false);
                window.setVisible(false);

            }

        });
        repaint();

    }

    @Override
    public void mouseReleased(MouseEvent e) {

    }

    @Override
    public void mouseEntered(MouseEvent e) {

    }

    @Override
    public void mouseExited(MouseEvent e) {

    }

    public static void main(String[] args) {
        DragTest frame = new DragTest();
        frame.setVisible(true);
        frame.setSize(600, 400);
        frame.setResizable(false);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

因此,初始单击将创建“放置”JLabel,然后单击并拖动“放置”JLabel 将创建一个跟随鼠标移动的“拖动”JLabel。

如何通过单击并拖动来完成此操作?

最佳答案

不要在 mouseDragged 方法中创建新的 JLabel,而是使用相同的 JLabel。例如:

import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.*;

public class DragTest2 extends JPanel {
   private static final int PREF_W = 500;
   private static final int PREF_H = 400;
   private static final float LABEL_PTS = 24f;
   private static final String LABEL_TEXT = "My Label";
   private JLabel label = null;

   public DragTest2() {
      setLayout(null);
      MyMouseAdapter myMouseAdapter = new MyMouseAdapter();
      addMouseListener(myMouseAdapter);
      addMouseMotionListener(myMouseAdapter);
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

   class MyMouseAdapter extends MouseAdapter {

      @Override
      public void mousePressed(MouseEvent e) {
         label = new JLabel(LABEL_TEXT);
         label.setFont(label.getFont().deriveFont(LABEL_PTS));
         Dimension labelSize = label.getPreferredSize();
         label.setSize(labelSize);
         int x = e.getX() - labelSize.width / 2;
         int y = e.getY() - labelSize.height / 2;
         label.setLocation(x , y);
         add(label);
         repaint();
      }

      @Override
      public void mouseDragged(MouseEvent e) {
         if (label != null) {
            Dimension labelSize = label.getPreferredSize();
            int x = e.getX() - labelSize.width / 2;
            int y = e.getY() - labelSize.height / 2;
            label.setLocation(x , y);
            repaint();
         }
      }

      @Override
      public void mouseReleased(MouseEvent e) {
         if (label != null) {
            Dimension labelSize = label.getPreferredSize();
            int x = e.getX() - labelSize.width / 2;
            int y = e.getY() - labelSize.height / 2;
            label.setLocation(x , y);
            repaint();
            label = null;
         }
      }
   }

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

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

关于java - 一键按下并拖动?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11459642/

相关文章:

java - Servlet 3.0 异步超时

java - 在 JButton 上绘制椭圆

java - 文件保存强制 jtable 单元提交所有更改

c++ - 在父窗口中捕获 WM_MOUSEMOVE 事件

java - 由于鼠标事件无效,如何将第一个 JLabel 背景颜色分配给下一个 JLabel?

java - 如何从匿名内部类访问非最终变量?

java - 识别java中的空格

java - JPA JBoss 事务未提交

java - 分布式 Java 桌面应用程序 mySQL 数据库

java - 鼠标监听器界面和绘画