2011-02-04 70 views
8

所以我想单击并拖动一个JLabel在JFrame周围。下面的代码允许JLabel在屏幕上的任意点按下/拖动鼠标时在屏幕上移动,但我不确定如何添加第二个ActionListener来检查鼠标是否点击标签,假设是解决方案。在屏幕上拖动一个jlabel

我想在屏幕上有多个JLabel,以便唯一移动的标签是鼠标点击并拖动的标签。

谢谢。

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 

@SuppressWarnings("serial") 
public class test extends JFrame implements MouseMotionListener { 

private JPanel panel = new JPanel(null);  
private JLabel dragLabel = new JLabel("drag test"); 
private int mouseX = 200; 
private int mouseY = 200; 

public test() { 
    this.add(panel); 
    panel.setBackground(Color.WHITE); 
    panel.add(dragLabel); 
    dragLabel.setForeground(Color.RED); 
    dragLabel.setBounds(mouseX, mouseY, 100, 50); 
    panel.addMouseMotionListener(this); 
} 

@Override 
public void mouseDragged(MouseEvent e) { 
    mouseX = e.getX(); 
    mouseY = e.getY(); 
    dragLabel.setBounds(mouseX, mouseY, 100, 50); 
} 

@Override 
public void mouseMoved(MouseEvent e) {} 

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

请参阅我的回答除了 – 2011-02-05 16:04:56

回答

3

将鼠标监听器添加到标签而不是面板。 (您可能仍然需要在面板上使用鼠标侦听器进行拖动,但至少标签上的可以告诉您它是否被选中)。

19

另一种方法是将JLabel添加到JLayeredPane或JLayeredPane拥有的JPanel中,并将MouseAdapter添加为JLayeredPane的MouseListener和MouseMotionListener。然后,当点击标签时,将其移至JLayeredPane的JLayeredPane.DRAG_LAYER,以便移动至其他位置,然后将JLabel放在鼠标释放时最合适的级别上。例如,在棋盘上移动棋子时,我发现这种方法可以很好地工作,并且您要确保在移动时您移动的棋子显示在所有其他棋子之上。

此外:您可能已离开此主题,但如果您回来或为了其他人的利益,我想通过发布示例来阐明使用JLayeredPane意味着什么。

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 

public class DragLabelOnLayeredPane extends JLayeredPane { 
    public static final int WIDTH = 680; 
    public static final int HEIGHT = 480; 
    private static final int GRID_ROWS = 8; 
    private static final int GRID_COLS = 6; 
    private static final int GAP = 3; 
    private static final Dimension LAYERED_PANE_SIZE = new Dimension(WIDTH, HEIGHT); 
    private static final Dimension LABEL_SIZE = new Dimension(60, 40); 
    private GridLayout gridlayout = new GridLayout(GRID_ROWS, GRID_COLS, GAP, GAP); 
    private JPanel backingPanel = new JPanel(gridlayout); 
    private JPanel[][] panelGrid = new JPanel[GRID_ROWS][GRID_COLS]; 
    private JLabel redLabel = new JLabel("Red", SwingConstants.CENTER); 
    private JLabel blueLabel = new JLabel("Blue", SwingConstants.CENTER); 

    public DragLabelOnLayeredPane() { 
     backingPanel.setSize(LAYERED_PANE_SIZE); 
     backingPanel.setLocation(2 * GAP, 2 * GAP); 
     backingPanel.setBackground(Color.black); 
     for (int row = 0; row < GRID_ROWS; row++) { 
      for (int col = 0; col < GRID_COLS; col++) { 
       panelGrid[row][col] = new JPanel(new GridBagLayout()); 
       backingPanel.add(panelGrid[row][col]); 
      } 
     } 

     redLabel.setOpaque(true); 
     redLabel.setBackground(Color.red.brighter().brighter()); 
     redLabel.setPreferredSize(LABEL_SIZE); 
     panelGrid[4][3].add(redLabel); 

     blueLabel.setOpaque(true); 
     blueLabel.setBackground(Color.blue.brighter().brighter()); 
     blueLabel.setPreferredSize(LABEL_SIZE); 
     panelGrid[1][1].add(blueLabel); 

     backingPanel.setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP)); 
     setPreferredSize(LAYERED_PANE_SIZE); 
     add(backingPanel, JLayeredPane.DEFAULT_LAYER); 
     MyMouseAdapter myMouseAdapter = new MyMouseAdapter(); 
     addMouseListener(myMouseAdapter); 
     addMouseMotionListener(myMouseAdapter); 
    } 

    private class MyMouseAdapter extends MouseAdapter { 
     private JLabel dragLabel = null; 
     private int dragLabelWidthDiv2; 
     private int dragLabelHeightDiv2; 
     private JPanel clickedPanel = null; 

     @Override 
     public void mousePressed(MouseEvent me) { 
      clickedPanel = (JPanel) backingPanel.getComponentAt(me.getPoint()); 
      Component[] components = clickedPanel.getComponents(); 
      if (components.length == 0) { 
       return; 
      } 
      // if we click on jpanel that holds a jlabel 
      if (components[0] instanceof JLabel) { 

       // remove label from panel 
       dragLabel = (JLabel) components[0]; 
       clickedPanel.remove(dragLabel); 
       clickedPanel.revalidate(); 
       clickedPanel.repaint(); 

       dragLabelWidthDiv2 = dragLabel.getWidth()/2; 
       dragLabelHeightDiv2 = dragLabel.getHeight()/2; 

       int x = me.getPoint().x - dragLabelWidthDiv2; 
       int y = me.getPoint().y - dragLabelHeightDiv2; 
       dragLabel.setLocation(x, y); 
       add(dragLabel, JLayeredPane.DRAG_LAYER); 
       repaint(); 
      } 
     } 

     @Override 
     public void mouseDragged(MouseEvent me) { 
      if (dragLabel == null) { 
       return; 
      } 
      int x = me.getPoint().x - dragLabelWidthDiv2; 
      int y = me.getPoint().y - dragLabelHeightDiv2; 
      dragLabel.setLocation(x, y); 
      repaint(); 
     } 

     @Override 
     public void mouseReleased(MouseEvent me) { 
      if (dragLabel == null) { 
       return; 
      } 
      remove(dragLabel); // remove dragLabel for drag layer of JLayeredPane 
      JPanel droppedPanel = (JPanel) backingPanel.getComponentAt(me.getPoint()); 
      if (droppedPanel == null) { 
       // if off the grid, return label to home 
       clickedPanel.add(dragLabel); 
       clickedPanel.revalidate(); 
      } else { 
       int r = -1; 
       int c = -1; 
       searchPanelGrid: for (int row = 0; row < panelGrid.length; row++) { 
        for (int col = 0; col < panelGrid[row].length; col++) { 
         if (panelGrid[row][col] == droppedPanel) { 
          r = row; 
          c = col; 
          break searchPanelGrid; 
         } 
        } 
       } 

       if (r == -1 || c == -1) { 
        // if off the grid, return label to home 
        clickedPanel.add(dragLabel); 
        clickedPanel.revalidate(); 
       } else { 
        droppedPanel.add(dragLabel); 
        droppedPanel.revalidate(); 
       } 
      } 

      repaint(); 
      dragLabel = null; 
     } 
    } 

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

    public static void main(String[] args) { 
     java.awt.EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       createAndShowUI(); 
      } 
     }); 
    } 
} 

请随时张贴任何问题,需要澄清或更正。

+1

对不起,我还不知道这个代码的大小。 :( – 2011-02-05 16:05:40

+3

不需要抱歉,这很有用:) – 2012-09-03 01:01:26

1

创建两个全局变量:

int x_pressed = 0; 
int y_pressed = 0; 

再创建两个事件(的mousePressed和的mouseDragged过的JLabel):

lbl_banner.addMouseListener(new MouseAdapter() 
{ 
    @Override 
    public void mousePressed(MouseEvent e) { 
     //catching the current values for x,y coordinates on screen 
     x_pressed = e.getX(); 
     y_pressed = e.getY(); 
    } 
}); 

lbl_banner.addMouseMotionListener(new MouseMotionAdapter(){ 
    @Override 
    public void mouseDragged(MouseEvent e){ 
     //and when the Jlabel is dragged 
     setLocation(e.getXOnScreen() - x_pressed, e.getYOnScreen() - y_pressed); 
    } 
}); 
2

您的代码和user compilex's answer启发,如下演示:

Screenshot

Full code:

import java.awt.Color; 
import java.awt.Component; 
import java.awt.Dimension; 
import java.awt.Point; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.util.Random; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.border.LineBorder; 

/** 
* A demonstration of moving around labels in a panel. 
* <p> 
* Some labels show up layed out in a grid. Then the 
* user can drag any label anywhere on the panel. 
* </p> 
*/ 
public class LabelDragger { 
    public static void main(final String[] args) { 
     final int labelRows = 5, //How many rows of labels. 
        labelColumns = 5, //How many columns of labels. 
        labelWidth = 55, //Width for each label. 
        labelHeight = 20; //Height for each label. 

     //Border colors for labels: 
     final Color[] colors = new Color[]{Color.BLUE, Color.GREEN, Color.BLACK, Color.GRAY}; 
     final Random prng = new Random(); //For selecting border color for each label. 

     final JPanel dragP = new JPanel(null); //Nicely set to null! :D Did not know that trick. 

     //Creating the listener for the panel: 
     final MouseAdapter ma = new MouseAdapter() { 
      private JLabel selectedLabel = null; //Clicked label. 
      private Point selectedLabelLocation = null; //Location of label in panel when it was clicked. 
      private Point panelClickPoint = null; //Panel's click point. 

      //Selection of label occurs upon pressing on the panel: 
      @Override 
      public void mousePressed(final MouseEvent e) { 

       //Find which label is at the press point: 
       final Component pressedComp = dragP.findComponentAt(e.getX(), e.getY()); 

       //If a label is pressed, store it as selected: 
       if (pressedComp != null && pressedComp instanceof JLabel) { 
        selectedLabel = (JLabel) pressedComp; 
        selectedLabelLocation = selectedLabel.getLocation(); 
        panelClickPoint = e.getPoint(); 
        //Added the following 2 lines in order to make selectedLabel 
        //paint over all others while it is pressed and dragged: 
        dragP.setComponentZOrder(selectedLabel, 0); 
        selectedLabel.repaint(); 
       } 
       else { 
        selectedLabel = null; 
        selectedLabelLocation = null; 
        panelClickPoint = null; 
       } 
      } 

      //Moving of selected label occurs upon dragging in the panel: 
      @Override 
      public void mouseDragged(final MouseEvent e) { 
       if (selectedLabel != null 
         && selectedLabelLocation != null 
         && panelClickPoint != null) { 

        final Point newPanelClickPoint = e.getPoint(); 

        //The new location is the press-location plus the length of the drag for each axis: 
        final int newX = selectedLabelLocation.x + (newPanelClickPoint.x - panelClickPoint.x), 
           newY = selectedLabelLocation.y + (newPanelClickPoint.y - panelClickPoint.y); 

        selectedLabel.setLocation(newX, newY); 
       } 
      } 
     }; 
     dragP.addMouseMotionListener(ma); //For mouseDragged(). 
     dragP.addMouseListener(ma); //For mousePressed(). 

     //Filling the panel with labels: 
     for (int row = 0; row < labelRows; ++row) 
      for (int col = 0; col < labelColumns; ++col) { 

       //Create label for (row, col): 
       final JLabel lbl = new JLabel("Label" + (row * labelColumns + col)); 
       lbl.setHorizontalAlignment(JLabel.CENTER); 
       //lbl.setVerticalAlignment(JLabel.CENTER); 
       lbl.setBounds(col * labelWidth, row * labelHeight, labelWidth, labelHeight); //Grid-like positioning. 
       lbl.setBorder(new LineBorder(colors[prng.nextInt(colors.length)], 2)); //Set a border for clarity. 

       //Add label to panel: 
       dragP.add(lbl); 
      } 

     //Creating and showing the main frame: 
     final JFrame frame = new JFrame(LabelDragger.class.getSimpleName()); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     //The size of the content pane adds some extra room for moving the labels: 
     final Dimension paneSize = new Dimension((int)(1.5 * labelWidth * labelColumns), 
               (int)(1.5 * labelHeight * labelRows)); 
     frame.getContentPane().setPreferredSize(paneSize); 
     frame.getContentPane().add(dragP); 

     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 
} 

解释被添加为注释。

提示

documentation on Container.findComponentAt(int x, int y)看看,如果你要在dragPContainer添加Component S,除了 “拖拽” 标签。

另外,在这种情况下,您可以改为使用Container.getComponentAt(int x, int y)。我建议你先阅读他们的(小)文档。