代码之家  ›  专栏  ›  技术社区  ›  sergi martinez

SWING禁用或隐藏滚动条,但启用控制盘?

  •  1
  • sergi martinez  · 技术社区  · 7 年前

    我想在JScrollPane中禁用或隐藏滚动条,但让用户用鼠标滚轮上下滚动。 如果我使用verticalScrollBarPolicy(NEVER),它会隐藏滚动条,所以没关系,但不能使用滚轮。

    有什么建议吗? 谢谢

    2 回复  |  直到 7 年前
        1
  •  1
  •   MadProgrammer    7 年前

    Based on this answer from CodeRanch ,当滚动条从未显示时,滚动被禁用。您需要覆盖 JScrollBar s isVisible 属性以“欺骗”滚动。

    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.FontMetrics;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Rectangle;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JScrollBar;
    import javax.swing.JScrollPane;
    import javax.swing.Scrollable;
    
    public class Test {
    
        public static void main(String[] args) {
            new Test();
        }
    
        public Test() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    JFrame frame = new JFrame();
                    JScrollPane scrollPane = new JScrollPane(new TestPane());
                    JScrollBar scrollBar = new JScrollBar(JScrollBar.VERTICAL) {
    
                        @Override
                        public boolean isVisible() {
                            return true;
                        }
                    };
                    // if appropriate, uncomment
                    //scrollBar.putClientProperty("JScrollBar.fastWheelScrolling", Boolean.TRUE);
                    scrollPane.setVerticalScrollBar(scrollBar);
                    scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
                    frame.add(scrollPane);
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel implements Scrollable {
    
            public TestPane() {
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(200, 800);
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g.create();
                FontMetrics fm = g2d.getFontMetrics();
                Integer lineY = null;
                for (int yPos = fm.getAscent(); yPos < getHeight(); yPos += 30) {
                    g2d.drawString(Integer.toString(yPos), 10, yPos + fm.getAscent());
                    if (lineY != null) {
                        g2d.drawLine(15, lineY, 15, yPos);
                    }
                    lineY = yPos + fm.getAscent();
                }
            }
    
            @Override
            public Dimension getPreferredScrollableViewportSize() {
                return new Dimension(200, 200);
            }
    
            @Override
            public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
                return 64;
            }
    
            @Override
            public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
                return 128;
            }
    
            @Override
            public boolean getScrollableTracksViewportWidth() {
                return false;
            }
    
            @Override
            public boolean getScrollableTracksViewportHeight() {
                return false;
            }
    
        }
    
    }
    

    您不需要使用 Scrollable ,此处仅用于演示目的,以检验理论。

    然而,这也会停止调用 getScrollableUnitIncrement ,这可能会影响滚动的总体速度,您需要进一步研究

    哦,还有其他注意事项,如果 JScrollPane 注册到 MouseWheelListener 事件时,它将停止滚动窗格收到通知

        2
  •  1
  •   rodripf    4 年前

    基于@MadProgrammer从CodeRanch引用的相同答案,我得到了一个更简单的解决方案:

    public class OnlyHorizontalJScrollPane extends JScrollPane {
        @Override
        public JScrollBar createVerticalScrollBar() {
            JScrollBar verticalScrollBar = new JScrollPane.ScrollBar(1);
            verticalScrollBar.setPreferredSize(new Dimension(0,0));
            return verticalScrollBar;
        }
    }
    

    我在Windows、java 14上进行了测试。