Пролистав jpanel по Когда мышь находится над jtable, выполните следующие действия
У меня есть JTable
внутри JPanel
. Я могу прокручивать вверх и вниз JPanel
с помощью колесика прокрутки мыши, но когда моя мышь зависает над JTable
, я должен переместить ее из таблицы, чтобы прокрутить назад JPanel
с помощью колеса прокрутки. Есть ли способ прокручивать вверх и вниз JPanel
с помощью колеса прокрутки, если мышь находится над JTable
?
2 ответа:
Я воспользовался советом Xeon в комментарии выше и реализовал прослушиватель колеса мыши, который перенаправляет события колеса мыши в родительский компонент. Смотрите код ниже.
public class CustomMouseWheelListener implements MouseWheelListener { private JScrollBar bar; private int previousValue = 0; private JScrollPane parentScrollPane; private JScrollPane customScrollPane; /** @return The parent scroll pane, or null if there is no parent. */ private JScrollPane getParentScrollPane() { if (this.parentScrollPane == null) { Component parent = this.customScrollPane.getParent(); while (!(parent instanceof JScrollPane) && parent != null) { parent = parent.getParent(); } this.parentScrollPane = (JScrollPane) parent; } return this.parentScrollPane; } /** * Creates a new CustomMouseWheelListener. * @param customScrollPane The scroll pane to which this listener belongs. */ public CustomMouseWheelListener(JScrollPane customScrollPane) { ValidationUtils.checkNull(customScrollPane); this.customScrollPane = customScrollPane; this.bar = this.customScrollPane.getVerticalScrollBar(); } /** {@inheritDoc} */ @Override public void mouseWheelMoved(MouseWheelEvent event) { JScrollPane parent = getParentScrollPane(); if (parent != null) { if (event.getWheelRotation() < 0) { if (this.bar.getValue() == 0 && this.previousValue == 0) { parent.dispatchEvent(cloneEvent(event)); } } else { if (this.bar.getValue() == getMax() && this.previousValue == getMax()) { parent.dispatchEvent(cloneEvent(event)); } } this.previousValue = this.bar.getValue(); } else { this.customScrollPane.removeMouseWheelListener(this); } } /** @return The maximum value of the scrollbar. */ private int getMax() { return this.bar.getMaximum() - this.bar.getVisibleAmount(); } /** * Copies the given MouseWheelEvent. * * @param event The MouseWheelEvent to copy. * @return A copy of the mouse wheel event. */ private MouseWheelEvent cloneEvent(MouseWheelEvent event) { return new MouseWheelEvent(getParentScrollPane(), event.getID(), event.getWhen(), event.getModifiers(), 1, 1, event.getClickCount(), false, event.getScrollType(), event.getScrollAmount(), event.getWheelRotation()); } }
Спасибо denshaotoko за то, что поделилась своим кодом. Я реализовал решение в том же духе (переадресация событий), но поместил его непосредственно в область прокрутки. Подумал, что это может пригодиться другим.
/** * Scroll pane that only scrolls when it owns focus. When not owning focus (i.e. mouse * hover), propagates mouse wheel events to its container. * <p> * This is a solution for <i>"I have a JTable inside a JPanel. When my mouse is hovering * over the JTable, I have to move it out of the table to scroll the JPanel."</i> */ public class ScrollWhenFocusedPane extends JScrollPane { // Note: don't leave users with "scroll on focus" behaviour // on widgets that they cannot focus. These will be okay. public ScrollWhenFocusedPane (JTree view) {super (view);} public ScrollWhenFocusedPane (JList view) {super (view);} public ScrollWhenFocusedPane (JTable view) {super (view);} public ScrollWhenFocusedPane (JTextArea view) {super (view);} @Override protected void processMouseWheelEvent (MouseWheelEvent evt) { Component outerWidget = SwingUtilities.getAncestorOfClass (Component.class, this); // Case 1: we don't have focus, so we don't scroll Component innerWidget = getViewport().getView(); if (!innerWidget.hasFocus()) outerWidget.dispatchEvent(evt); // Case 2: we have focus else { JScrollBar innerBar = getVerticalScrollBar(); if (!innerBar.isShowing()) // Deal with horizontally scrolling widgets innerBar = getHorizontalScrollBar(); boolean wheelUp = evt.getWheelRotation() < 0; boolean atTop = (innerBar.getValue() == 0); boolean atBottom = (innerBar.getValue() == (innerBar.getMaximum() - innerBar.getVisibleAmount())); // Case 2.1: we've already scrolled as much as we could if ((wheelUp & atTop) || (!wheelUp & atBottom)) outerWidget.dispatchEvent(evt); // Case 2.2: we'll scroll else super.processMouseWheelEvent (evt); } } }