2012-06-07 1 views
2

안에 JTable이 있습니다. 마우스의 스크롤 휠을 사용하여 JPanel을 위아래로 스크롤 할 수 있지만, 마우스가 JTable 위로 마우스를 가져 가면 스크롤 휠을 사용하여 JPanel 위로 스크롤하려면 테이블 밖으로 이동해야합니다. 마우스가 JTable 위로 마우스를 가져 가면 스크롤 휠을 사용하여 JPanel을 위아래로 스크롤 할 수 있습니까?마우스가 JTable 위로 마우스를 가져 가면 JPanel을 통해 스크롤

+4

방금 ​​설명한 사례를 구현했지만 마우스 포인터가 'JTable'인 경우 'JPanel'이벤트를 스크롤 할 수 있습니다. SSCCE를 게시 할 수 있습니까? – Xeon

+2

하지만 기본적으로 휠 스크롤 이벤트 ('MouseWheelListener')를'JPanel'의'JScrollPane' – Xeon

+1

에 전달할 수 있습니다. 이벤트를 사용하려면 (확장 가능 일 수도 있습니다) :-), 더 나은 도움을 위해 [SSCCE] (http://sscce.org/) – mKorbel

답변

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()); 
    } 

} 
1

코드를 공유해 주셔서 감사합니다. 동일한 줄 (이벤트 전달)을 따라 솔루션을 구현했지만 스크롤 창에 직접 배치했습니다. 다른 사람들에게 유용 할 수 있다고 생각했습니다.

/** 
* 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); 
     } 
    } 
}