2009-09-04 2 views
2

스크롤 방지 할 수 있습니다. 마우스 커서가 내부의 JScrollPane를 터치하자마자, 스크롤 이벤트가 그 JScrollPane에 건네 져 최초의 이벤트에 의해 처리되지 않게되는 것 같습니다. 즉, 「부모」JScrollPane의 스크롤이 정지하는 것을 의미합니다.JTextPane가 내가 개체의 "나무"다음 한 부모에 JScrollPane의

비활성화 할 수 있습니까 내부 JScrollPane의 마우스 휠만 사용 하시겠습니까? 또는 더 좋게 스크롤 할 수 없으면 스크롤을 사용하지 않도록 설정하고 (대부분 텍스트 팬에는 1-3 줄만 포함), 을 사용하면 콘텐츠가 더 많습니까??

답변

9

나는 테이블과 JTextAreas를 스크롤 할 수 있어야하기 때문에이 성가신 문제도 발생했으며 Sbodd의 해결책은 받아 들일 수 없었다. 이 동작을 브라우저와 동일하게하고 싶었습니다. 스크롤 할 수있는 컨트롤 위에 마우스를 놓으면 컨트롤이 닫힐 때까지 컨트롤을 스크롤 한 다음 부모 스크롤 패널을 계속 스크롤합니다. 일반적으로 전체 페이지의 스크롤 패널입니다.

이 수업은 그렇게 할 것입니다. 보통의 JScrollPane 대신에 사용하십시오. 나는 그것이 당신을 돕기를 바랍니다.

/** 
* A JScrollPane that will bubble a mouse wheel scroll event to the parent 
* JScrollPane if one exists when this scrollpane either tops out or bottoms out. 
*/ 
public class PDControlScrollPane extends JScrollPane { 

public PDControlScrollPane() { 
    super(); 

    addMouseWheelListener(new PDMouseWheelListener()); 
} 

class PDMouseWheelListener implements MouseWheelListener { 

    private JScrollBar bar; 
    private int previousValue = 0; 
    private JScrollPane parentScrollPane; 

    private JScrollPane getParentScrollPane() { 
     if (parentScrollPane == null) { 
      Component parent = getParent(); 
      while (!(parent instanceof JScrollPane) && parent != null) { 
       parent = parent.getParent(); 
      } 
      parentScrollPane = (JScrollPane)parent; 
     } 
     return parentScrollPane; 
    } 

    public PDMouseWheelListener() { 
     bar = PDControlScrollPane.this.getVerticalScrollBar(); 
    } 
    public void mouseWheelMoved(MouseWheelEvent e) { 
     JScrollPane parent = getParentScrollPane(); 
     if (parent != null) { 
      /* 
      * Only dispatch if we have reached top/bottom on previous scroll 
      */ 
      if (e.getWheelRotation() < 0) { 
       if (bar.getValue() == 0 && previousValue == 0) { 
        parent.dispatchEvent(cloneEvent(e)); 
       } 
      } else { 
       if (bar.getValue() == getMax() && previousValue == getMax()) { 
        parent.dispatchEvent(cloneEvent(e)); 
       } 
      } 
      previousValue = bar.getValue(); 
     } 
     /* 
     * If parent scrollpane doesn't exist, remove this as a listener. 
     * We have to defer this till now (vs doing it in constructor) 
     * because in the constructor this item has no parent yet. 
     */ 
     else { 
      PDControlScrollPane.this.removeMouseWheelListener(this); 
     } 
    } 
    private int getMax() { 
     return bar.getMaximum() - bar.getVisibleAmount(); 
    } 
    private MouseWheelEvent cloneEvent(MouseWheelEvent e) { 
     return new MouseWheelEvent(getParentScrollPane(), e.getID(), e 
       .getWhen(), e.getModifiers(), 1, 1, e 
       .getClickCount(), false, e.getScrollType(), e 
       .getScrollAmount(), e.getWheelRotation()); 
    } 
} 
} 
+0

감사합니다, 이것은 내가 그것을 원하는 정확히 방식으로 동작합니다. – exhuma

+0

감사합니다, 잔뜩 챔피언처럼 작동! – Satish

0

슬프게도, 명백한 솔루션 (JScrollPane.setWheelScrollingEnabled (false))은 실제로 MouseWheelEvents에 대한 등록 취소가 없으므로 원하는 효과를 얻지 못합니다. 여기

는 MouseWheelEvents에이 외부가 JScrollPane에 도달 할 것 모두 스크롤 해제의 원유-해커 방법 : 당신이 당신의 내부가 JScrollPane에 이렇게 할 경우

for (MouseWheelListener mwl : scrollPane.getMouseWheelListeners()) { 
    scrollPane.removeMouseWheelListener(mwl); 
} 

것은, 그것은 휠 이벤트를 스크롤 응답하지 않을거야을; 외부 JScrollPane가 그것들을 모두 가져옵니다.

"깨끗하게"하려면 자체 ScrollPaneUI를 구현하고 setUI()를 사용하여 JScrollPane의 UI로 설정해야합니다. 불행하게도, 관련 멤버 변수는 private이고 ScrollPaneUI의 MouseWheelListener 설치시 깃발이나 가드가 없으므로 BasicScrollPaneUI를 확장하고 마우스 휠 리스너를 비활성화 할 수 없습니다.

"더 나은"솔루션을 얻으려면 ScrollPaneUI에 들어가는 시간보다 더 깊이 파고들 필요가 있습니다. 스크롤 막대가 표시/숨김 상태가되는 후크를 찾고 해당 지점에서 MouseWheelListener를 추가/제거해야합니다.

희망 하시겠습니까?

1

@ 네미는 이미 좋은 해결책이 있습니다.

가 내 라이브러리에 follwing을 방법을 넣어, 조금 더를 내려 삶은 :

static public void passMouseWheelEventsToParent(final Component pComponent, final Component pParent) { 
     pComponent.addMouseWheelListener((final MouseWheelEvent pE) -> { 
      pParent.dispatchEvent(new MouseWheelEvent(pParent, pE.getID(), pE.getWhen(), pE.getModifiers(), 1, 1, pE.getClickCount(), false, pE.getScrollType(), pE.getScrollAmount(), pE.getWheelRotation())); 
     }); 
} 
관련 문제