按住鼠标按钮时更改mouseListener

问题描述:

我正在使用Java进行游戏并遇到以下挑战。按住鼠标按钮时更改mouseListener

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

现在问题来了,这个解决方法只适用于windows,而不是osx上的osx上,只要鼠标按钮被按下,鼠标一直跟JPanels mouseAdapter对话。那么是否有人知道如何以正确的方式将mousePressed状态从一个mouseAdapter转移到另一个状态,同时按下鼠标按钮? (释放按钮并再次按下不是一个选项,因为这会拖拽拖拽的目的。)

+1

它似乎是你试图重新实现Java的拖放机制。你尝试过使用它吗? – MeBigFatGuy 2011-04-08 21:42:33

+0

@MeBigFatGuy那么,形状不支持开箱即用,所以我需要实现它,这将是很多工作。 (特别是因为我不知道该怎么做)而且我已经投入了相当多的时间在这种拖动方法中,所以我不愿放弃它... – Jesse 2011-04-08 21:54:39

+0

了解。但我猜测把你的形状变成组件会比较容易,然后试着跳过你试图做的事情。祝你好运! – MeBigFatGuy 2011-04-08 22:08:56

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

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

编辑:或去与MeBigFatGuy的优秀建议。

编辑2:在深夜尝试一个半简化的概念程序,这是一个通过向Glass面板添加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<Shape> shapeList = new ArrayList<Shape>(); 
    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(p.x, p.y); 
    } 

    @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); 
    } 
} 
+0

这是你有的一个有趣的想法,我会尝试一下。日Thnx。 – Jesse 2011-04-08 22:17:41

+0

你不能添加mouseListeners到Shape对象,有什么建议吗? – Jesse 2011-04-08 23:56:37

+0

@Jesse:创建并发布[SSCCE](http://sscce.org),让您获得快速获得体面的帮助的最佳机会(查看链接)。 – 2011-04-09 02:40:44