ホームページ  >  記事  >  Java  >  Java Swing でネストされたコンポーネントを含む JScrollPane にマウス ドラッグ スクロールを実装するにはどうすればよいですか?

Java Swing でネストされたコンポーネントを含む JScrollPane にマウス ドラッグ スクロールを実装するにはどうすればよいですか?

Patricia Arquette
Patricia Arquetteオリジナル
2024-10-26 11:19:29897ブラウズ

How to Implement Mouse Drag Scrolling for a JScrollPane with Nested Components in Java Swing?

Java Swing の MouseMotionEvent: ネストされたコンポーネントと対話する方法

コンポーネント階層の課題

Swing ベースの GUI を設計する場合、開発者はよく遭遇する問題に直面します。ネストされたコンポーネント内でマウス イベントを処理する際の課題。デフォルトでは、マウス イベントはコンポーネント階層を上に伝播し、最上位のコンテナで終了します。これにより、ネストされた構造内の特定のコンポーネントのイベント処理が妨げられる可能性があります。

問題: マウス イベントが内部コンポーネントに到達しない

そのようなシナリオの 1 つが、提起された質問で例示されています。目標は、マウスのドラッグに応答する JScrollPane を使用してスクロール可能なビューを実装することです。ただし、追加コンポーネントを JScrollPane に追加すると、マウス モーション イベントがスクロール ペインに到達することがブロックされます。

マウス イベントを手動で伝播する: 非効率的なアプローチ

開発者は当初、マウス イベントを手動で伝播することを検討しました。ネストされたすべてのコンポーネントにリスナーを追加し、イベントを親に転送します。ただし、このアプローチでは非現実的な時間の投資が発生します。

代替ソリューション: JScrollPane アクションを活用する

手動で伝播する代わりに、より効率的なソリューションは、JScrollPane に関連付けられた既存のアクションを活用することです。これらのアクションは通常、キー バインディングに使用されます。

ソリューションの実装:

  1. スクロール アクションを模倣するカスタム キー バインディング アクションを作成します。
  2. これらのアクションをJScrollPane インスタンス。
  3. タイマーを使用して、ビューポート内でのマウスの動きに基づいて、左、右、上、下などの目的のスクロール アクションを継続的にトリガーします。

Java コード:

<code class="java">import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.Action;
import javax.swing.JViewport;
import javax.swing.JScrollPane;
import javax.swing.Timer;

class ScrollTimer implements ActionListener {

    private Timer timer;
    private Action action;
    private JScrollPane scrollPane;
    private int count;

    public ScrollTimer(JScrollPane scrollPane, String action) {
        this.action = scrollPane.getActionMap().get(action);
        this.scrollPane = scrollPane;
        timer = new Timer(100, this);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (count++ < 10) {
            action.actionPerformed(new ActionEvent(scrollPane, 0, action.getValue(Action.NAME)));
        } else {
            timer.stop();
        }
    }

    public void start() {
        count = 0;
        timer.start();
    }

    public void stop() {
        timer.stop();
        count = 0;
    }
}

class MouseEventHandler extends MouseAdapter {

    private ScrollTimer left, right, up, down;

    public MouseEventHandler(JScrollPane scrollPane) {
        left = new ScrollTimer(scrollPane, "scrollLeft");
        right = new ScrollTimer(scrollPane, "scrollRight");
        up = new ScrollTimer(scrollPane, "scrollUp");
        down = new ScrollTimer(scrollPane, "scrollDown");
        JViewport viewPort = scrollPane.getViewport();
        viewPort.addMouseMotionListener(this);
    }

    @Override
    public void mouseMoved(MouseEvent e) {
        left.stop();
        if (e.getX() < 16) {
            left.start();
        }
        right.stop();
        if (e.getX() > viewPort.getWidth() - 16) {
            right.start();
        }
        up.stop();
        if (e.getY() < 16) {
            up.start();
        }
        down.stop();
        if (e.getY() > viewPort.getHeight() - 16) {
            down.start();
        }
    }
}

// ... (rest of the code)</code>

結論

この代替アプローチは、元の質問が直面した問題を効果的に解決します。 JScrollPane の組み込みスクロール アクションを利用することで、開発者はマウス モーション イベントをスクロール ペインに伝播でき、ネストされたコンポーネント構造内でもスムーズで応答性の高いスクロールが可能になります。

以上がJava Swing でネストされたコンポーネントを含む JScrollPane にマウス ドラッグ スクロールを実装するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。