2

フレーム内の要素を移動するために GlassPane を使用しています。ドラッグされた要素がない場合、すべてのマウスイベントは通常の方法で送出されます

public class MainFrame implements MouseListener {
 private JFrame frame;

 public MainFrame()
 {
    frame = new JFrame();

    JPanel testPanel = new JPanel();
    testPanel.addMouseListener(this);

    JLabel testLabel = new JLabel("Test",JLabel.CENTER);
    testPanel.add(testLabel);

    frame.add(testPanel);
    frame.pack();
    frame.setVisible(true);

    GlassPanel glassPanel = new GlassPanel(frame);
    frame.setGlassPane(glassPanel);
    // Without this line the click in the panel is mentioned.
    // otherwise it is ignored.
    frame.getGlassPane().setVisible(true);
 }

 @Override
 public void mouseClicked(MouseEvent e) 
 {
    System.out.print("CLicked");
 }

 @Override
 public void mousePressed(MouseEvent e) {
    // TODO Auto-generated method stub

 }

 @Override
 public void mouseReleased(MouseEvent e) {
    // TODO Auto-generated method stub

 }

 @Override
 public void mouseEntered(MouseEvent e) {
    // TODO Auto-generated method stub

 }

 @Override
 public void mouseExited(MouseEvent e) {
    // TODO Auto-generated method stub

 }

 public class GlassPanel extends JPanel implements MouseMotionListener, MouseListener
 {
    private JFrame frame;

    public GlassPanel(JFrame mainframe)
    {
        frame = mainframe;

        setLayout(null);
        setOpaque(false);

        addMouseMotionListener(this);
        addMouseListener(this);

    }

    @Override
    public void mouseClicked(MouseEvent e) 
    {
        redispatchMouseEvent(e, true);
    }

    @Override
    public void mousePressed(MouseEvent e) 
    {
        redispatchMouseEvent(e, true);
    }

    @Override
    public void mouseReleased(MouseEvent e) 
    {
        redispatchMouseEvent(e, true);
    }

    @Override
    public void mouseEntered(MouseEvent e) 
    {
        redispatchMouseEvent(e, true);
    }

    @Override
    public void mouseExited(MouseEvent e) 
    {
        redispatchMouseEvent(e, true);
    }

    @Override
    public void mouseDragged(MouseEvent e) 
    {
        redispatchMouseEvent(e, true);
    }

    @Override
    public void mouseMoved(MouseEvent e) 
    {
            redispatchMouseEvent(e, true);
    } 

    private void redispatchMouseEvent(MouseEvent e, boolean repaint) 
    {
        System.out.println("Dispatch");
        Point glassPanePoint = e.getPoint();
        Container container = frame.getContentPane();
        Point containerPoint = SwingUtilities.convertPoint(frame.getGlassPane(),
                glassPanePoint, container);

        if (containerPoint.y < 0) { // we're not in the content pane
            // Could have special code to handle mouse events over
            // the menu bar or non-system window decorations, such as
            // the ones provided by the Java look and feel.
        } else {
            // The mouse event is probably over the content pane.
            // Find out exactly which component it's over.
            Component component = SwingUtilities.getDeepestComponentAt(
                    container, containerPoint.x, containerPoint.y);

            if (component != null) {
                // Forward events to component below
                Point componentPoint = SwingUtilities.convertPoint(
                        frame.getGlassPane(), glassPanePoint, component);
                component.dispatchEvent(new MouseEvent(component, e
                        .getID(), e.getWhen(), e.getModifiers(),
                        componentPoint.x, componentPoint.y, e
                                .getClickCount(), e.isPopupTrigger()));
            }
        }
    }
 }
}

しかし、これにより、マウス イベント処理で異常な動作が発生します。例: マウス リスナーを持つ JPanel があります。このパネルをダブルクリックすると、別のフレームが開きます。このパネルにはいくつかのラベルがあります。Glasspane がない場合、このラベルをクリックできます。ラベルはマウス イベントに作用しないため、イベントはパネルに渡され、クリック アクションが実行されます。ディスパッチ ルーチンを使用するとき、マウス イベントをラベルに直接ディスパッチしますが、これはもちろんアクションにつながりません。

では、どうすればこれを修正できますか?もちろん、Panel への参照を使用して独自のラベル クラスを作成し、マウス イベントを再びパネルにディスパッチすることもできますが、これは適切な設計とは言えません。2 つ目は、Glasspane ディスパッチャーで、最も深いパネルがマウス イベントに関心があるかどうかを判断できることです。

何か案は?

4

0 に答える 0