Swing 内でタッチ ユーザー インターフェイスを開発する場合、ネストされたコンポーネントが邪魔をする場合に MouseMotionListener インターフェイスを効果的に使用するという課題に遭遇する可能性があります。イベントの伝播。
MouseMovedEvent と MouseDraggedEvent は GUI 階層を上に伝播することを目的としていますが、コンテナ内のコンポーネントによってブロックされる可能性があります。たとえば、JButton を JScrollPane に追加すると、イベントが JScrollPane の MouseMotionListener を再度トリガーしない可能性があります。
この問題を克服するために、JScrollPane の組み込みを利用する アドホック アプローチを紹介します。アクション。通常はキー バインドに使用されます。このソリューションでは、実装に合わせて N 変数を調整することで、大規模な手動イベント転送を必要とせずにイベントの伝播が可能になります。
実際の例を次に示します:
<code class="java">import java.awt.Color; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; 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.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JViewport; import javax.swing.Timer; public class ScrollAction extends JFrame { private static final int TILE = 64; private static final int DELTA = 16; public ScrollAction() { setupAndDisplay(); } private void setupAndDisplay() { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel panel = new JPanel() { @Override protected void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(Color.lightGray); int w = this.getWidth() / TILE + 1; int h = this.getHeight() / TILE + 1; for (int row = 0; row < h; row++) { for (int col = 0; col < w; col++) { if ((row + col) % 2 == 0) { g.fillRect(col * TILE, row * TILE, TILE, TILE); } } } } }; panel.setOpaque(false); panel.setFocusable(true); panel.setPreferredSize(new Dimension(50 * TILE, 50 * TILE)); final JScrollPane scrollPane = new JScrollPane(panel); final JViewport viewport = scrollPane.getViewport(); viewport.addMouseMotionListener(new MouseAdapter() { @Override public void mouseMoved(MouseEvent e) { handleMouseMovement(scrollPane, e); } }); add(scrollPane); } private static final class ScrollTimer implements ActionListener { private static int N = 10; private static int DELAY = 100; private String cmd; private Timer timer; private Action action; private JScrollPane scrollPane; private int count; public ScrollTimer(JScrollPane scrollPane, String action) { this.cmd = action; this.timer = new Timer(DELAY, this); this.action = scrollPane.getActionMap().get(action); this.scrollPane = scrollPane; } @Override public void actionPerformed(ActionEvent e) { if (count++ < N) { action.actionPerformed(new ActionEvent(scrollPane, 0, cmd)); } else { timer.stop(); } } public void start() { count = 0; timer.start(); } public void stop() { timer.stop(); count = 0; } } private void handleMouseMovement(JScrollPane scrollPane, MouseEvent e) { final ScrollTimer left = new ScrollTimer(scrollPane, "scrollLeft"); final ScrollTimer right = new ScrollTimer(scrollPane, "scrollRight"); final ScrollTimer up = new ScrollTimer(scrollPane, "scrollUp"); final ScrollTimer down = new ScrollTimer(scrollPane, "scrollDown"); left.stop(); if (e.getX() < DELTA) { left.start(); } right.stop(); if (e.getX() > viewport.getWidth() - DELTA) { right.start(); } up.stop(); if (e.getY() < DELTA) { up.start(); } down.stop(); if (e.getY() > viewport.getHeight() - DELTA) { down.start(); } } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { new ScrollAction().setVisible(true); pack(); } }); } }</code>
以上がネストされたコンポーネントを含む Java Swing で MouseMotionListener を効果的に使用する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。