2012-07-12 77 views
2

我有一个程序,我在点击创建一个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。

我该如何做到这一点点击并拖动?

回答

2

不要在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(); 
     } 
     }); 
    } 
}