拖动屏幕周围的jlabel

所以我试图在JFrame周围单击并拖动JLabel。 以下代码允许在屏幕上的任何位置按下/拖动鼠标时在屏幕上移动JLabel,但我不知道如何添加第二个ActionListener以检查鼠标是否在标签上单击,假设是解决方案。

我想在屏幕上有多个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); } } 

另一种方法是将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(); } }); } } 

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

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

受您的代码和用户compilex的答案的启发,遵循以下演示:

截图

完整代码:

 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. * 

* Some labels show up layed out in a grid. Then the * user can drag any label anywhere on the panel. *

*/ 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); } }

解释被添加为注释。

小贴士

如果要在dragP Container上添加Component ,而不是“draggable”标签,请查看documentation on Container.findComponentAt(int x, int y)documentation on Container.findComponentAt(int x, int y)

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

创建两个全局变量:

 int x_pressed = 0; int y_pressed = 0; 

然后创建两个事件(mousePressed和mouseDragged over 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); } });