2012-07-12 112 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(); 
     } 
     }); 
    } 
}