2016-11-24 3 views
0

Ich habe zwei Dinge, die ich zu tun versuchen: eine JPanel auf Mausbewegung markieren und ein blaues Quadrat auf der Maus per Drag bewegen. Die Sache ist, dass ich MouseListeners zu verschiedenen Komponenten hinzufügen muss. Wenn ich dies tue, kann ich nur eine Funktion verwenden - die andere ist blockiert. Was kann ich tun, damit beide Funktionen funktionieren?Wie kann ich mehrere MouseListeners zu einem einzigen JFrame hinzufügen?

HINWEIS: Manchmal zeigt der JFrame nichts - Sie müssen es nur so lange ausführen, bis es funktioniert (normalerweise 2-3 Versuche). Wenn es irgendwelche anderen seltsamen Sachen macht, lass es einfach laufen, bis es funktioniert. Kommentar, wenn es nach> 5 Versuchen immer noch nicht funktioniert.

Was sollte wie folgt aussehen: sucessful start screenshot

Haupt (erstellt die JFrame, den Behälter, und die Kinder, und fügt die MouseListeners)

public class Main extends JFrame{ 
    private static final long serialVersionUID = 7163215339973706671L; 
    private static final Dimension containerSize = new Dimension(640, 477); 
    static JLayeredPane layeredPane; 
    static JPanel container; 

    public Main() { 
     super("Multiple MouseListeners Test"); 
     setSize(640, 477); 
     setLocationRelativeTo(null); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setResizable(false); 
     setVisible(true); 

     layeredPane = new JLayeredPane(); 
     layeredPane.setPreferredSize(containerSize); 
     getContentPane().add(layeredPane); 

     createContainer(); 

     layeredPane.add(container, JLayeredPane.DEFAULT_LAYER); 

     createChildren(4, 4); 

     new MovableObject(); 

     MovableObjectMouseListener moml = new MovableObjectMouseListener(); 
     //comment these two out and the highlighter works 
     layeredPane.addMouseListener(moml); 
     layeredPane.addMouseMotionListener(moml); 
    } 

    private void createChildren(int columns, int rows){ 
     for (int i = 0; i < columns; i++){ 
      for (int j = 0; j < rows; j++){ 
       JPanel child = new JPanel(new BorderLayout()); 
       child.setBackground(Color.LIGHT_GRAY); 
       //comment this out and you can move the MovableObject 
       child.addMouseListener(new HighlightJPanelsMouseListener()); 
       container.add(child); 
      } 
     } 
    } 

    private JPanel createContainer(){ 
     container = new JPanel(); 
     container.setLayout(createLayout(4, 4, 1, 1)); 
     container.setPreferredSize(containerSize); 
     container.setBounds(0, 0, containerSize.width, containerSize.height); 
     return container; 
    } 

    private GridLayout createLayout(int rows, int columns, int hGap, int vGap){ 
     GridLayout layout = new GridLayout(rows, columns); 
     layout.setHgap(hGap); 
     layout.setVgap(vGap); 
     return layout; 
    } 

    public static void main(String[] args) { 
     new Main(); 
    } 
} 

HighlightJPanelsMouseListener (erstellt die MouseListeners, dass wird den Kindern hinzugefügt werden

)
public class HighlightJPanelsMouseListener implements MouseListener{ 
    private Border grayBorder = BorderFactory.createLineBorder(Color.DARK_GRAY); 

    public HighlightJPanelsMouseListener() { 
    } 

    public void mouseEntered(MouseEvent e) { 
     Component comp = (Component) e.getSource(); 
     JPanel parent = (JPanel) comp; 
     parent.setBorder(grayBorder); 
     parent.revalidate(); 
    } 

    public void mouseExited(MouseEvent e) { 
     Component comp = (Component) e.getSource(); 
     JPanel parent = (JPanel) comp; 
     parent.setBorder(null); 
     parent.revalidate(); 
    } 

    public void mousePressed(MouseEvent e){} 
    public void mouseReleased(MouseEvent e){} 
    public void mouseClicked(MouseEvent e) {} 
} 

MovableObject (schafft die MovableObject)

download blueSquare.png oder ein anderes Bild verwendet werden. Denken Sie daran, den Namen des Bildes unten zu ändern, was auch immer Ihr ist.

public class MovableObject { 
    public MovableObject() { 
     JPanel parent = (JPanel) Main.container.findComponentAt(10, 10); 
     ImageIcon icon = null; 
     //use any image you might have laying around your workspace - or download the one above 
     URL imgURL = MovableObject.class.getResource("/blueSquare.png"); 

     if (imgURL != null){ 
      icon = new ImageIcon(imgURL); 
     }else{ 
      System.err.println("Couldn't find file"); 
     } 

     JLabel movableObject = new JLabel(icon); 
     parent.add(movableObject); 
     parent.revalidate(); 
    } 
} 

MovableObjectMouseListener verwendet (die Mouselistener für MovableObject verwendet werden)

public class MovableObjectMouseListener implements MouseListener, MouseMotionListener{ 
    private JLabel replacement; 
    private int xAdjustment, yAdjustment; 

    public void mousePressed(MouseEvent e){ 
     replacement = null; 
     Component c = Main.container.findComponentAt(e.getX(), e.getY()); 

     if (!(c instanceof JLabel)){ 
      return; 
     } 

     Point parentLocation = c.getParent().getLocation(); 
     xAdjustment = parentLocation.x - e.getX(); 
     yAdjustment = parentLocation.y - e.getY(); 
     replacement = (JLabel)c; 
     replacement.setLocation(e.getX() + xAdjustment, e.getY() + yAdjustment); 

     Main.layeredPane.add(replacement, JLayeredPane.DRAG_LAYER); 
     Main.layeredPane.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); 
    } 

    public void mouseDragged(MouseEvent me){ 
     if (replacement == null){ 
      return; 
     } 

     int x = me.getX() + xAdjustment; 
     int xMax = Main.layeredPane.getWidth() - replacement.getWidth(); 
     x = Math.min(x, xMax); 
     x = Math.max(x, 0); 

     int y = me.getY() + yAdjustment; 
     int yMax = Main.layeredPane.getHeight() - replacement.getHeight(); 
     y = Math.min(y, yMax); 
     y = Math.max(y, 0); 

     replacement.setLocation(x, y); 
    } 


    public void mouseReleased(MouseEvent e){ 
     Main.layeredPane.setCursor(null); 

     if (replacement == null){ 
      return; 
     } 

     int xMax = Main.layeredPane.getWidth() - replacement.getWidth(); 
     int x = Math.min(e.getX(), xMax); 
     x = Math.max(x, 0); 

     int yMax = Main.layeredPane.getHeight() - replacement.getHeight(); 
     int y = Math.min(e.getY(), yMax); 
     y = Math.max(y, 0); 


     Component c = Main.container.findComponentAt(x, y); 
     Container parent = (Container) c; 
     parent.add(replacement); 
     parent.validate(); 
    } 

    public void mouseClicked(MouseEvent e) {} 
    public void mouseMoved(MouseEvent e) {} 
    public void mouseEntered(MouseEvent e) {} 
    public void mouseExited(MouseEvent e) {} 
} 
+0

'Manchmal ist die JFrame nicht anything' zeigen - alle Komponenten mit dem Rahmen hinzugefügt werden sollten, bevor der Rahmen sichtbar gemacht wird. – camickr

Antwort

2

Haben Sie nicht auf den Code im Detail aussehen, aber ich würde vorschlagen, dass Sie die Drag Mouselistener auf die hinzugefügt werden muss bewegliches Objekt (dh die JLabel) und nicht das Panel. Dann erhält das Label die Ziehereignisse und das Panel erhält die mouseEntered/Exited Events.

Diese auf ein zusätzliches Problem bei dem mouseExited Ereignisse führen wird nun erzeugt wird, wenn Sie auf das Etikett zu bewegen (die Sie nicht passieren wollen). Check out: how to avoid mouseExited to fire while on any nested component für eine Lösung für dieses Problem.

Verwandte Themen