按下鼠标时更改mouseListener

我正在开发Java游戏,并面临以下挑战。

我有2个JPanels ,需要在视觉JPanels形状从一个JPanel拖动到另一个JPanel 。 我使用JFrameGlassPane工作了。 当我按下鼠标拖动形状时, GlassPane激活并将形状传递给glassPane。 因此,您需要将mousePressed状态从JPanels mouseAdapterglassPanes mouseAdapter 。 我通过使用Robot类来解决这个问题,它在glassPane被激活后模拟了另一个mousePressed事件。

现在问题来了,这个解决方法只适用于Windows而不适用于mac osx,在osx上,只要按下鼠标按钮,鼠标就会与JPanels mouseAdapter保持对话。 那么有人知道如何在按下鼠标按钮的同时以适当的方式将mousePressed状态从一个mouseAdapter到另一个mouseAdapter吗? (释放按钮并再次按下它不是一个选项,因为这会破坏拖动的目的。)

为什么不将MouseListener仅添加到glasspane,并在mousePressed方法中获取鼠标的位置(Point),然后通过在包含Component的Container上调用getComponentAt(Point p)来获取可拖动组件? 然后,您可以将组件放入玻璃板并将其拖动到那里。 例如,这是我使用JLayeredPane(类似于使用glasspane)完成此操作的一种方法: DragLabelOnLayeredPane

或者另一个想法:为什么不简单地在拖动的组件上添加MouseAdapter并将其留在组件上? 只要您注意相对于屏幕获取鼠标位置并相对于其容器移动组件,您应该没有问题组件是在contentPane还是glasspane中。

编辑:或者使用MeBigFatGuy的优秀建议。

编辑2:一个半醉的深夜尝试一个不那么简短的概念certificate概念程序,这个程序只通过将MouseListener添加到玻璃窗格来移动形状。

 import java.awt.BasicStroke; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GridLayout; import java.awt.Point; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.Stroke; import java.awt.event.*; import java.awt.geom.*; import java.util.ArrayList; import java.util.List; import java.util.Random; import javax.swing.*; @SuppressWarnings("serial") public class DragShapesMainPanel extends JPanel { private static final Dimension RIGHT_PANEL_SIZE = new Dimension(300, 450); private static final int SHAPE_COUNT = 10; private static final int SHAPE_WIDTH = 40; private static final int SHAPE_HEIGHT = SHAPE_WIDTH; private Shape draggedShape = null; private DragShapesPanel leftPanel = new DragShapesPanel(Color.blue, Color.black); private DragShapesPanel rightPanel = new DragShapesPanel(Color.blue, Color.black); private DragShapesGlassPanel glassPanel = new DragShapesGlassPanel(Color.pink, Color.gray); private Random random = new Random(); public DragShapesMainPanel() { setLayout(new GridLayout(1, 0)); setBackground(Color.black); rightPanel.setPreferredSize(RIGHT_PANEL_SIZE); leftPanel.setPreferredSize(RIGHT_PANEL_SIZE); rightPanel.setBorder(BorderFactory.createLineBorder(Color.black, 1)); leftPanel.setBorder(BorderFactory.createLineBorder(Color.black, 1)); add(leftPanel); add(rightPanel); MouseAdapter myMouseAdapter = new MyMouseAdapter(); glassPanel.addMouseListener(myMouseAdapter); glassPanel.addMouseMotionListener(myMouseAdapter); glassPanel.setOpaque(false); glassPanel.setVisible(true); for (int i = 0; i < SHAPE_COUNT; i++) { leftPanel.addShape(createRandomShape(i)); } } private Shape createRandomShape(int i) { Dimension size = rightPanel.getPreferredSize(); int x = random.nextInt(size.width - SHAPE_WIDTH); int y = random.nextInt(size.height - SHAPE_HEIGHT); switch (i % 3) { case 0: return new Ellipse2D.Double(x, y, SHAPE_WIDTH, SHAPE_HEIGHT); case 1: return new Rectangle2D.Double(x, y, SHAPE_WIDTH, SHAPE_HEIGHT); case 2: return new RoundRectangle2D.Double(x, y, SHAPE_WIDTH, SHAPE_HEIGHT, 15, 15); default: break; } return null; } public JPanel getGlassPanel() { return glassPanel; } private class MyMouseAdapter extends MouseAdapter { Point initialLocation = null; @Override public void mousePressed(MouseEvent e) { if (e.getButton() != MouseEvent.BUTTON1) { return; } Component componentAt = getComponentAt(e.getPoint()); if (!(componentAt instanceof DragShapesPanel)) { return; } initialLocation = e.getPoint(); DragShapesPanel dsPanel = (DragShapesPanel) getComponentAt(initialLocation); int x = initialLocation.x - dsPanel.getLocation().x; int y = initialLocation.y - dsPanel.getLocation().y; Point p = new Point(x, y); Shape shape = dsPanel.getShapeAtPoint(p); if (shape == null) { initialLocation = null; return; } dsPanel.removeShape(shape); dsPanel.repaint(); int tx = dsPanel.getLocation().x; int ty = dsPanel.getLocation().y; draggedShape = AffineTransform.getTranslateInstance(tx, ty).createTransformedShape(shape); glassPanel.setShape(draggedShape); glassPanel.repaint(); } @Override public void mouseDragged(MouseEvent e) { if (initialLocation == null) { return; } Point currentLocation = e.getPoint(); int x = currentLocation.x - initialLocation.x; int y = currentLocation.y - initialLocation.y; glassPanel.translate(new Point(x, y)); glassPanel.repaint(); } @Override public void mouseReleased(final MouseEvent e) { if (initialLocation == null) { return; } SwingUtilities.invokeLater(new Runnable() { public void run() { Component componentAt = getComponentAt(e.getPoint()); if (!(componentAt instanceof DragShapesPanel)) { return; } DragShapesPanel dsPanel = (DragShapesPanel) getComponentAt(e.getPoint()); Point currentLocation = e.getPoint(); int x = currentLocation.x - initialLocation.x; int y = currentLocation.y - initialLocation.y; Point dspPoint = dsPanel.getLocation(); int tx = x - dspPoint.x; int ty = y - dspPoint.y; draggedShape = AffineTransform.getTranslateInstance(tx, ty).createTransformedShape( draggedShape); dsPanel.addShape(draggedShape); dsPanel.repaint(); initialLocation = null; glassPanel.setShape(null); glassPanel.translate(new Point(0, 0)); } }); } } private static void createAndShowUI() { DragShapesMainPanel dragShapesMain = new DragShapesMainPanel(); JFrame frame = new JFrame("DragShapes"); frame.getContentPane().add(dragShapesMain); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setGlassPane(dragShapesMain.getGlassPanel()); frame.getGlassPane().setVisible(true); frame.setLocationRelativeTo(null); frame.setVisible(true); } public static void main(String[] args) { java.awt.EventQueue.invokeLater(new Runnable() { public void run() { createAndShowUI(); } }); } } @SuppressWarnings("serial") class DragShapesPanel extends JPanel { private static final float STROKE_WIDTH = 3; private static final Stroke SHAPE_STROKE = new BasicStroke(STROKE_WIDTH); private List shapeList = new ArrayList(); private Color shapeFillColor; private Color shapeBorderColor; public DragShapesPanel(Color fillColor, Color borderColor) { this.shapeFillColor = fillColor; this.shapeBorderColor = borderColor; } public void addShape(Shape s) { shapeList.add(s); } public void removeShape(Shape s) { shapeList.remove(s); } public Shape getShapeAtPoint(Point p) { Shape shapeAtPoint = null; for (int i = shapeList.size() - 1; i >= 0; i--) { if (shapeList.get(i).contains(p)) { return shapeList.get(i); } } return shapeAtPoint; } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); for (Shape shape : shapeList) { g2.setColor(shapeFillColor); g2.fill(shape); g2.setStroke(SHAPE_STROKE); g2.setColor(shapeBorderColor); g2.draw(shape); } } } @SuppressWarnings("serial") class DragShapesGlassPanel extends JPanel { private static final float STROKE_WIDTH = 1.5f; private static final Stroke SHAPE_STROKE = new BasicStroke(STROKE_WIDTH); private Shape shape = null; private Color shapeFillColor; private Color shapeBorderColor; private AffineTransform transform = new AffineTransform(); public DragShapesGlassPanel(Color fillColor, Color borderColor) { this.shapeFillColor = fillColor; this.shapeBorderColor = borderColor; } public void setShape(Shape shape) { this.shape = shape; } public void translate(Point p) { transform = AffineTransform.getTranslateInstance(px, py); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); if (shape == null) { return; } Graphics2D g2 = (Graphics2D) g; g2.transform(transform); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setColor(shapeFillColor); g2.fill(shape); g2.setStroke(SHAPE_STROKE); g2.setColor(shapeBorderColor); g2.draw(shape); } }