Lors de la conception d'interfaces graphiques basées sur Swing, les développeurs sont souvent confrontés défis lors de la gestion des événements de souris dans des composants imbriqués. Par défaut, les événements de souris sont propagés dans la hiérarchie des composants, se terminant au conteneur de niveau supérieur. Cela peut interférer avec la gestion des événements pour des composants spécifiques au sein de structures imbriquées.
Un de ces scénarios est illustré dans la question posée. L'objectif est d'implémenter une vue déroulante à l'aide de JScrollPane qui répond aux glissements de la souris. Cependant, lors de l'ajout de composants supplémentaires au JScrollPane, les événements de mouvement de la souris ne peuvent pas atteindre le volet de défilement.
Le développeur a initialement envisagé de propager manuellement les événements de souris en ajouter des écouteurs à chaque composant imbriqué et transmettre les événements au parent. Cependant, cette approche pose un investissement de temps peu pratique.
Au lieu de la propagation manuelle, une solution plus efficace consiste à exploiter les actions existantes associées à JScrollPane. Ces actions sont généralement utilisées pour les raccourcis clavier.
<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>
Cette approche alternative résout efficacement le problème rencontré par la question initiale. En exploitant les actions de défilement intégrées de JScrollPane, les développeurs peuvent propager les événements de mouvement de la souris au volet de défilement, permettant un défilement fluide et réactif même au sein de structures de composants imbriquées.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!