3

MouseEventで迷子になる、つまり親に配信されないことがわかっているようJScrollPaneに、これはまだ修正されていない古いバグです: https://forums.oracle.com/forums/thread.jspa?threadID=1362237

JScrollPaneそのため、一時的なリスナーでイベントをキャッチし、実際のリスナーで処理される親であるイベントにディスパッチすることで回避策を使用していました。

    private class DispatchListener extends MouseAdapter {
    @Override
    public void mousePressed (MouseEvent me) {
        System.out.println("dispatch.mousePressed: " + me.getButton());
        preDispatchEvent(me);
    }

    @Override
    public void mouseReleased (MouseEvent me) {
        preDispatchEvent(me);
    }

    @Override
    public void mouseDragged (MouseEvent me) {
        System.out.println("dispatch.mouseDragged");
        preDispatchEvent(me);
    }

    private void preDispatchEvent (MouseEvent me) {
        JScrollPane pane = (JScrollPane)me.getSource();
        MouseEvent newMe = SwingUtilities.convertMouseEvent(pane.getViewport(), me, tablePanel);
        dispatchEvent(newMe);
    }
}

問題なく動作しましたが、Java 7 を使用している人々は、マウス クリックがアプリケーションで反応しないと不満を言い始めました。Java 6 にダウングレードした後、問題は解決しましたが、現在はテスト中Appletであり、Chromeプラグインをバージョン 7 にアップグレードする必要がありました。

デバッグ後、渡されたボタンから独立してconvertMouseEventボタンを設定することがわかりましたMouseEvent.NOBUTTON

MouseEvent newMe = SwingUtilities.convertMouseEvent(pane.getViewport(), me, tablePanel);

Eclipse のソース コードから

else {
        newEvent = new MouseEvent(newSource,
                                  sourceEvent.getID(),
                                  sourceEvent.getWhen(),
                                  sourceEvent.getModifiers(),
                                  p.x,p.y,
                                  sourceEvent.getXOnScreen(),
                                  sourceEvent.getYOnScreen(),
                                  sourceEvent.getClickCount(),
                                  sourceEvent.isPopupTrigger(),
                                  MouseEvent.NOBUTTON ); //!!!
    }
    return newEvent;

なぜそのように実装されているのかわかりませんか?それは別のバグまたは機能ですか?

SwingUtilities.convertMouseEventsourceEvent からボタンを呼び出して設定せずに、独自のオブジェクトを作成する必要があるようです。

4

2 に答える 2

3

これは興味深い問題です。MouseEvent.NOBUTTONin SwingUtilities.convertMouseEventsureの使用は非常に奇妙に見えます。ただし、Java 7 では問題を再現できません。私にとってbutton、変換されたマウス イベントのフィールドは Java 7 および 6 で正しいです (Windows 7 ラップトップで 1.7.0-b147 64 ビットおよび 1.6.0_21-b07 64 ビットを使用)。

MouseEventコンストラクターを介してデバッグすると、buttonフィールドが最初にゼロに設定されている間setNewModifiers、コンストラクターの最後の呼び出しがフィールドbuttonに基づいて変化することがわかりました (変換されたマウス イベントが で構築されたときにmodifiers値を受け取ります)。sourceEvent.getModifiersSwingUtilities.convertMouseEvent

シングル クリックから変換されたマウス イベントは次のようになります (Java 7 の場合)。

java.awt.event.MouseEvent[MOUSE_PRESSED,(185,175),absolute(593,305),button=1,modifiers=Button1,extModifiers=Button1,clickCount=1] on javax.swing.JPanel[,0,0,381x259,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=]
java.awt.event.MouseEvent[MOUSE_RELEASED,(185,175),absolute(593,305),button=1,modifiers=Button1,clickCount=1] on javax.swing.JPanel[,0,0,381x259,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=]

あなたの質問に答えて:フィールドの値はとにかくフィールドの値によって決定されるため、コンストラクターMouseEvent.NOBUTTONに渡されると思います。私のラップトップでは、Java 7 と 6 の両方で期待どおりに動作するため、バグのようには見えません。アプリケーションはブラウザーで実行されていますか?それによってマウス イベントの変換方法に違いはありますか? 問題を解決するための回避策を既に作成しましたか、それともアプレット コードの一部を共有していただけますか?MouseEventbuttonmodifiers


その他のイベントの種類createまたはオブジェクト
によって処理される最初の 2 つのケース。どちらのコンストラクターも (最終的に)パラメーターを指定してコンストラクターを呼び出します。(私のラップトップでこれらのイベントを(変換なしで)見ると、a のフィールドは常にゼロです(私のマウスにはホイールが1つしかありません)。オブジェクトの場合、イベントの場合は1に等しく、それ以外の場合はゼロですが、フィールドは常にに等しくなります.) したがって、コンストラクターへのパラメーターとして非常に人気があるようです。SwingUtilities.convertMouseEventMouseWheelEventMenuDragMouseEventMouseEventMouseEvent.NOBUTTONbuttonMouseWheelEventMenuDragMouseEventbuttonmenuDragMouseReleasedmodifiersBUTTON1_MASKMouseEvent.NOBUTTONMouseEvent

于 2013-01-26T23:44:39.807 に答える
0

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7181403を参照してください - convertMouseEvent() は最近変更されていないようです。そのため、他のコード変更が Java 7 で見られる変更の原因である必要があります (ここでも 1.7.0_21 で問題を再現します)。

いずれにせよ、問題は Java 8 で解決されたようです。

于 2013-06-07T10:39:32.150 に答える