如何设置优先级鼠标监听器

我有一个包含列表和按钮的面板。 列表使用mouseClick()设置MouseAdapter 。 我使用mousePressed()mouseReleased()以及带有mouseDragged MouseMotionAdapter添加到面板mouseDragged

拖放仅在单击面板时有效。

即使我点击列表,如何使拖动工作?

简单的考试:

 public class DragTest extends JFrame{ private boolean drag; private Point btnCoord; private Point startPoint; public DragTest(){ setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); setSize(500,500); setLayout(null); final JPanel panel = new JPanel(); final JButton button = new JButton(); button.setText("Button"); button.setSize(30,60); button.setLocation(50, 50); panel.setLayout(null); setContentPane(panel); panel.addMouseMotionListener(new MouseMotionAdapter() { @Override public void mouseDragged(MouseEvent e) { if (drag){ panel.setLocation(btnCoord.x-(startPoint.xe.getX()),btnCoord.y-(startPoint.ye.getY())); } } }); panel.addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { drag = true; startPoint = e.getPoint(); btnCoord = panel.getLocation(); } @Override public void mouseReleased(MouseEvent e) { drag = false; } }); getContentPane().add(button); } public static void main(String[] args) { JFrame frame = new DragTest(); frame.setVisible(true); } } 

如果拖动面板,一切正常,如果开始拖动按钮,则按钮拦截事件。

上面的代码有很多错误……

  • 不要使用null / Absolute LayoutManager 。 看看在容器中布置组件 。
  • 不要在组件和JFrame上调用setSize (如果实现了正确的布局管理器,您只需在JFrame上添加组件并调用pack()
  • 在EDT上创建和操作Swing组件。 阅读有关Swing中的并发的更多信息。
  • 在从可见容器中添加/删除组件后,应该在容器上调用revalidate()repaint()

我一直在研究我自己的小ComponentDrag API,它允许我们在一个JComponent或多个JComponent上拖动Swing组件。 它绝不是没有错误的(特别是多个组件部分今天就完成它所以你永远不知道)

您将创建JButton并添加到JPanel

  JButton button = new JButton("Text"); JPanel panel1 = new JPanel() { @Override public Dimension getPreferredSize() { return new Dimension(300, 300); } }; panel1.add(button); 

然后通过传递容器的参数(即JFrame / JDialogJWindow创建ComponentDrag类的实例,并在JPanel上注册可拖动的组件并调用setName("Droppable")以允许正确地进行拖放,尤其是跨多个JComponents等,你只能为你希望能够删除Swing组件的JPanel等执行此操作:

  JFrame frame=..;//has access to setGlassPane same applies for JDialog and JWindow frame.add(panel1); ComponentDrag cd=new ComponentDrag(frame); cd.registerComponent(button); panel1.setName("Droppable");//needed for the dragging and dropping to work correctly especailly over multiple components 

和你的好去:)。

以下是2个完整的分析示例:

1)显示移动JButton并使用ComponentDrag重新定位并重写其componentDropped方法的逻辑:

在拖动之前:

在此处输入图像描述

4拖到1位后:

在此处输入图像描述

 import java.awt.Component; import java.awt.Container; import java.awt.Cursor; import java.awt.Graphics; import java.awt.GridLayout; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import javax.swing.AbstractAction; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.SwingUtilities; import javax.swing.Timer; public class DragButtonsTest { ArrayList buttons = new ArrayList<>(); public DragButtonsTest() { JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); final JPanel panel = new JPanel(new GridLayout(2, 2)); ComponentDrag cd = new ComponentDrag(frame) { @Override protected void componentDropped(MouseEvent me) { HashMap collisions = new HashMap<>(); JButton draggedButton = (JButton) me.getSource(); for (JButton btn : buttons) {//iterate through all buttons and get the number of collsions of each if (btn != draggedButton) {//dont chck button we were dragging int col = checkPerPixelCollision(draggedButton, btn); System.out.println("Button " + btn.getText()); System.out.println(col); collisions.put(col, btn); } } //lets get the button which had most collisions int maxCollisions = 0; JButton intersectingButton = null; for (Map.Entry entry : collisions.entrySet()) { Integer collisionCount = entry.getKey(); JButton button = entry.getValue(); if (collisionCount > maxCollisions) { maxCollisions = collisionCount; intersectingButton = button; } } boolean reLayout = false; if (maxCollisions > 0) {//check if there was any System.out.println("Button " + draggedButton.getText() + " is intersecting more of Button " + intersectingButton.getText()); System.out.println("Collisions: " + maxCollisions); reLayout = true; } else { System.out.println("No change made"); reLayout = false; } ArrayList tmpButtons = (ArrayList) buttons.clone();//create clone of buttons if (reLayout) {//a button as moved and panel needs to be layed out buttons.clear();//clear old buttons for (JButton b : tmpButtons) {//re-order jbuttons if (b == intersectingButton) { buttons.add(draggedButton); } else if (b == draggedButton) { buttons.add(intersectingButton); } else { buttons.add(b); } } panel.removeAll();//remove all buttons for (JButton btn : buttons) {//iterate through all buttons and get the number of collsions of each panel.add(btn);//re-add buttons according to arraylist } panel.revalidate(); panel.repaint(); } super.componentDropped(me); } }; for (int i = 0; i < 4; i++) { JButton b = new JButton(String.valueOf(i + 1)); panel.add(b); buttons.add(b); cd.registerComponent(b); } frame.add(panel); frame.pack(); frame.setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new DragButtonsTest(); } }); } public HashSet getMask(JButton e) { HashSet mask = new HashSet<>(); int pixel, a; BufferedImage bi = componentToImage(e); //gets the current image being shown for (int i = 0; i < bi.getWidth(); i++) { // for every (x,y) component in the given box, for (int j = 0; j < bi.getHeight(); j++) { pixel = bi.getRGB(i, j); // get the RGB value of the pixel a = (pixel >> 24) & 0xff; if (a != 0) { // if the alpha is not 0, it must be something other than transparent mask.add((e.getX() + i) + "," + (e.getY() - j)); // add the absolute x and absolute y coordinates to our set } } } return mask; //return our set } public static BufferedImage componentToImage(Component component) { BufferedImage img = new BufferedImage(component.getWidth(), component.getHeight(), BufferedImage.TRANSLUCENT); Graphics g = img.getGraphics(); component.paintAll(g); return img; } // Returns true if there is a collision between object a and object b public int checkPerPixelCollision(JButton b, JButton b2) { // This method detects to see if the images overlap at all. If they do, collision is possible int ax1 = (int) b2.getX(); int ay1 = (int) b2.getY(); int ax2 = ax1 + (int) b2.getWidth(); int ay2 = ay1 + (int) b2.getHeight(); int bx1 = (int) b.getX(); int by1 = (int) b.getY(); int bx2 = bx1 + (int) b.getWidth(); int by2 = by1 + (int) b.getHeight(); if (by2 < ay1 || ay2 < by1 || bx2 < ax1 || ax2 < bx1) { return 0; // Collision is impossible. } else { // Collision is possible. // get the masks for both images HashSet maskPlayer1 = getMask(b2); HashSet maskPlayer2 = getMask(b); maskPlayer1.retainAll(maskPlayer2); // Check to see if any pixels in maskPlayer2 are the same as those in maskPlayer1 if (maskPlayer1.size() > 0) { // if so, than there exists at least one pixel that is the same in both images, thus return maskPlayer1.size(); } } return 0; } } class ComponentDrag { private MouseAdapter ma; private ArrayList components = new ArrayList<>(); private int startingX, startingY; private boolean autoLayout = true; private final JFrame container; private JPanel glassPane; boolean firstTime = true; private JComponent lastClickedContainer; public ComponentDrag(final JFrame container) { this.container = container; glassPane = new JPanel(); glassPane.setOpaque(false); glassPane.setLayout(null); this.container.setGlassPane(glassPane); new Timer(10, new AbstractAction() { @Override public void actionPerformed(ActionEvent ae) { if (container.isVisible()) { glassPane.setVisible(true); ((Timer) ae.getSource()).stop(); } } }).start(); ma = new MouseAdapter() { @Override public void mousePressed(MouseEvent me) { super.mousePressed(me); componentPressed(me); } @Override public void mouseReleased(MouseEvent me) { super.mouseReleased(me); componentDropped(me); } @Override public void mouseDragged(MouseEvent me) { super.mouseDragged(me); componentDragged(me); } }; } public JComponent findDroppableUnderGlassPane(Point p, Container container, Component source) { JComponent c = null; Component[] comps = container.getComponents(); for (Component com : comps) { if (com.getName() != null) { if (com.getName().equals("Droppable") && com instanceof JComponent) { if (com.contains(SwingUtilities.convertPoint(source, p, com))) { return (JComponent) com; } } else if (com instanceof Container) { findDroppableUnderGlassPane(p, (Container) com, source); } } } return c; } public boolean isAutoLayout() { return autoLayout; } public void setAutoLayout(boolean autoLayout) { this.autoLayout = autoLayout; } protected void componentDropped(MouseEvent me) { firstTime = true; Component droppedComponent = (Component) me.getSource(); droppedComponent.setCursor(null); JComponent jc = findDroppableUnderGlassPane(me.getPoint(), container.getContentPane(), (Component) me.getSource()); if (jc != null) { glassPane.removeAll(); glassPane.revalidate(); glassPane.repaint(); jc.add(droppedComponent); System.out.println("Removed from glasspane and added to: " + jc); if (autoLayout) { if (lastClickedContainer != null) { lastClickedContainer.revalidate(); lastClickedContainer.repaint(); } droppedComponent.revalidate(); droppedComponent.repaint(); jc.revalidate(); jc.repaint(); } } else { glassPane.removeAll(); glassPane.revalidate(); glassPane.repaint(); if (lastClickedContainer != null) { lastClickedContainer.add(droppedComponent); lastClickedContainer.revalidate(); lastClickedContainer.repaint(); } } } protected void componentPressed(MouseEvent me) { JComponent jc = findDroppableUnderGlassPane(me.getPoint(), container.getContentPane(), (Component) me.getSource()); if (jc != null && jc.getName().equals("Droppable")) { lastClickedContainer = jc; System.out.println("Pressed: " + lastClickedContainer); } boolean clickedRegisteredComponent = false; Component clickedComponent = (Component) me.getSource(); for (Component component : ComponentDrag.this.components) { if (component.equals(clickedComponent)) { clickedRegisteredComponent = true; break; } } if (clickedRegisteredComponent) { startingX = me.getX(); startingY = me.getY(); clickedComponent.setCursor(new Cursor(Cursor.MOVE_CURSOR)); } } protected void componentDragged(MouseEvent me) { Component draggedComponent = (Component) me.getSource(); if (firstTime && lastClickedContainer != null) { firstTime = false; lastClickedContainer.remove(draggedComponent); lastClickedContainer.revalidate(); lastClickedContainer.repaint(); glassPane.add(draggedComponent); glassPane.revalidate(); glassPane.repaint(); System.out.println("Removed from: " + lastClickedContainer + " \nAnd added to glasspane for dragging"); } //MouseEvent will refire on each drag with the position being relative to the firing Component draggedComponent.setLocation((me.getX() - startingX) + draggedComponent.getLocation().x, (me.getY() - startingY) + draggedComponent.getLocation().y); } void registerComponent(JComponent draggableComp) { draggableComp.addMouseListener(ma); draggableComp.addMouseMotionListener(ma); components.add(draggableComp); } void deregisterComponent(JComponent draggableComp) { draggableComp.removeMouseListener(ma); draggableComp.removeMouseMotionListener(ma); components.remove(draggableComp); } } 

2)简单地说明如何在JPanel上拖动2个JLabel

拖动之前拖动标签:

在此处输入图像描述

标签拖动后:

在此处输入图像描述

 import java.awt.BorderLayout; import java.awt.Component; import java.awt.Container; import java.awt.Cursor; import java.awt.Dimension; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; import javax.swing.AbstractAction; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JSeparator; import javax.swing.SwingUtilities; import javax.swing.Timer; /** * * @author David */ public class DragOverMultipleComponentsTest { public DragOverMultipleComponentsTest() { createAndShowUI(); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new DragOverMultipleComponentsTest(); } }); } private void createAndShowUI() { final JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JLabel draggableLabel = new JLabel("<- Drag me"); JLabel draggableLabel2 = new JLabel("<- Drag me too"); JLabel labelPanel1 = new JLabel("Drag 'em here"); JPanel panel1 = new JPanel() { @Override public Dimension getPreferredSize() { return new Dimension(300, 300); } }; panel1.add(labelPanel1); panel1.setName("Droppable"); JLabel labelPanel2 = new JLabel("Drag 'em here"); JPanel panel2 = new JPanel(); panel2.add(labelPanel2); panel2.add(draggableLabel); panel2.add(draggableLabel2); panel2.setName("Droppable"); JSeparator js = new JSeparator(JSeparator.VERTICAL); ComponentDrag cd = new ComponentDrag(frame); cd.registerComponent(draggableLabel); cd.registerComponent(draggableLabel2); frame.add(panel1, BorderLayout.WEST); frame.add(js); frame.add(panel2, BorderLayout.EAST); frame.pack(); frame.setVisible(true); } } class ComponentDrag { private MouseAdapter ma; private ArrayList components = new ArrayList<>(); private int startingX, startingY; private boolean autoLayout = true; private final JFrame container; private JPanel glassPane; boolean firstTime = true; private JComponent lastClickedContainer; public ComponentDrag(final JFrame container) { this.container = container; glassPane = new JPanel(); glassPane.setOpaque(false); glassPane.setLayout(null); this.container.setGlassPane(glassPane); new Timer(10, new AbstractAction() { @Override public void actionPerformed(ActionEvent ae) { if (container.isVisible()) { glassPane.setVisible(true); ((Timer) ae.getSource()).stop(); } } }).start(); ma = new MouseAdapter() { @Override public void mousePressed(MouseEvent me) { super.mousePressed(me); componentPressed(me); } @Override public void mouseReleased(MouseEvent me) { super.mouseReleased(me); componentDropped(me); } @Override public void mouseDragged(MouseEvent me) { super.mouseDragged(me); componentDragged(me); } }; } public JComponent findDroppableUnderGlassPane(Point p, Container container, Component source) { JComponent c = null; Component[] comps = container.getComponents(); for (Component com : comps) { if (com.getName() != null) { if (com.getName().equals("Droppable") && com instanceof JComponent) { if (com.contains(SwingUtilities.convertPoint(source, p, com))) { return (JComponent) com; } } else if (com instanceof Container) { findDroppableUnderGlassPane(p, (Container) com, source); } } } return c; } public boolean isAutoLayout() { return autoLayout; } public void setAutoLayout(boolean autoLayout) { this.autoLayout = autoLayout; } protected void componentDropped(MouseEvent me) { firstTime = true; Component droppedComponent = (Component) me.getSource(); droppedComponent.setCursor(null); JComponent jc = findDroppableUnderGlassPane(me.getPoint(), container.getContentPane(), (Component) me.getSource()); if (jc != null) { glassPane.removeAll(); glassPane.revalidate(); glassPane.repaint(); jc.add(droppedComponent); System.out.println("Removed from glasspane and added to: " + jc); if (autoLayout) { if (lastClickedContainer != null) { lastClickedContainer.revalidate(); lastClickedContainer.repaint(); } droppedComponent.revalidate(); droppedComponent.repaint(); jc.revalidate(); jc.repaint(); } } else { glassPane.removeAll(); glassPane.revalidate(); glassPane.repaint(); if (lastClickedContainer != null) { lastClickedContainer.add(droppedComponent); lastClickedContainer.revalidate(); lastClickedContainer.repaint(); } } } protected void componentPressed(MouseEvent me) { JComponent jc = findDroppableUnderGlassPane(me.getPoint(), container.getContentPane(), (Component) me.getSource()); if (jc != null && jc.getName().equals("Droppable")) { lastClickedContainer = jc; System.out.println("Pressed: " + lastClickedContainer); } boolean clickedRegisteredComponent = false; Component clickedComponent = (Component) me.getSource(); for (Component component : ComponentDrag.this.components) { if (component.equals(clickedComponent)) { clickedRegisteredComponent = true; break; } } if (clickedRegisteredComponent) { startingX = me.getX(); startingY = me.getY(); clickedComponent.setCursor(new Cursor(Cursor.MOVE_CURSOR)); } } protected void componentDragged(MouseEvent me) { Component draggedComponent = (Component) me.getSource(); if (firstTime && lastClickedContainer != null) { firstTime = false; lastClickedContainer.remove(draggedComponent); lastClickedContainer.revalidate(); lastClickedContainer.repaint(); glassPane.add(draggedComponent); glassPane.revalidate(); glassPane.repaint(); System.out.println("Removed from: " + lastClickedContainer + " \nAnd added to glasspane for dragging"); } //MouseEvent will refire on each drag with the position being relative to the firing Component draggedComponent.setLocation((me.getX() - startingX) + draggedComponent.getLocation().x, (me.getY() - startingY) + draggedComponent.getLocation().y); } void registerComponent(JComponent draggableComp) { draggableComp.addMouseListener(ma); draggableComp.addMouseMotionListener(ma); components.add(draggableComp); } void deregisterComponent(JComponent draggableComp) { draggableComp.removeMouseListener(ma); draggableComp.removeMouseMotionListener(ma); components.remove(draggableComp); } }