JTextPane prevents scrolling in the parent JScrollPane

前端 未结 4 485
温柔的废话
温柔的废话 2021-01-06 00:49

I have the following \"tree\" of objects:

JPanel
    JScrollPane
        JPanel
            JPanel
                JScrollPane
                    JTextPane
         


        
4条回答
  •  走了就别回头了
    2021-01-06 01:18

    I have run into this annoying problem also, and Sbodd's solution was not acceptable for me because I needed to be able to scroll inside tables and JTextAreas. I wanted the behavior to be the same as a browser, where the mouse over a scrollable control will scroll that control until the control bottoms out, then continue to scroll the parent scrollpane, usually the scrollpane for the whole page.

    This class will do just that. Just use it in place of a regular JScrollPane. I hope it helps you.

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

提交回复
热议问题