2016-11-24 12 views
0

私はしようとしていることが2つあります:マウスのホバー上のJPanelを強調表示し、マウスドラッグで青い四角を移動します。つまり、別のコンポーネントにMouseListenersを追加する必要があります。これを行うと、私は1つの機能しか使用できません - もう1つはブロックされています。両方の機能が動作するように私は何ができますか?複数のMouseListenersを1つのJFrameに追加するにはどうすればよいですか?

注:場合によってはJFrameに何も表示されない場合があります(通常は2-3回の試行が必要です)。他の奇妙なものがあれば、それが動作するまでそれを続けてください。 > 5回の試行の直後にまだ動作していない場合はコメントしてください。それがどのように見えるか

sucessful start screenshot

メイン(JFrameの、コンテナ、および子供を作成し、のMouseListenerを追加)

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は(そののMouseListenerを作成します子供に追加されます)

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(MovableObjectを作成)

download blueSquare.png、又は別の画像を使用します。下の画像の名前をあなたのものに変更してください。

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(MovableObjectに使用するのMouseListenerを作成します)

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

'時にはJFrameに何も表示されません。フレームが表示される前にすべてのコンポーネントをフレームに追加する必要があります。 – camickr

答えて

2

は詳細にあなたのコードを見ていませんでしたが、私はあなたにドラッグするMouseListenerを追加する必要があることを示唆していますパネルではなく移動可能なオブジェクト(つまりJLabel)です。ラベルがドラッグイベントを取得し、パネルはmouseEntered/Exitedイベントを取得します。

これにより、ラベルの上を移動したときにmouseExitedイベントが生成されるという追加の問題が発生します(発生したくないイベント)。この問題を解決するには、how to avoid mouseExited to fire while on any nested componentをご覧ください。

関連する問題