当前位置: 首页 > 知识库问答 >
问题:

Java Swing JScrollPane在按下shift并使用鼠标滚轮时不滚动

韩嘉祯
2023-03-14

我有一个简单的Java Swing程序定义如下:

import javax.swing.*;
import java.awt.*;

public class Test implements Runnable {

    public static void main(String[] args) {
        Test main = new Test();
        SwingUtilities.invokeLater(main);
    }

    @Override
    public void run() {

        // Application window.
        JFrame mainFrame = new JFrame();

        // Set up window.
        mainFrame.setPreferredSize(new Dimension(600,700));
        mainFrame.setFocusable(true);
        mainFrame.requestFocus();

        JScrollPane scrollPane = new JScrollPane();
        scrollPane.setPreferredSize(new Dimension(600,700));

        JPanel scrollPanel = new JPanel();
        scrollPanel.setLayout(new GridLayout(0,1));

        // Add buttons.
        for (int i = 0; i < 40; i ++) {
            JButton button = new JButton("Button " + i);
            button.setPreferredSize(new Dimension(600,100));
            scrollPanel.add(button);
        }

        scrollPane.setViewportView(scrollPanel);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

        JPanel mainPanel = new JPanel();
        mainPanel.add(scrollPane);

        // Fill up window.
        mainFrame.getContentPane().setLayout(new BorderLayout());
        mainFrame.getContentPane().add(mainPanel, BorderLayout.CENTER);
        SwingUtilities.updateComponentTreeUI(mainFrame);

        mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainFrame.pack();
        mainFrame.setVisible(true);

    }
}

这个程序由一个简单的JScrollPane组成,里面有多个按钮。仅启用垂直滚动。工作很好。但问题是,当我按住'shift'键时,当我使用鼠标滚轮滚动时,垂直滚动不起作用。垂直滚动只有在我拖动滚动条或放开“Shift”键时才起作用。通常,在JScrollPane中,当按住“Shift”键,使用鼠标滚轮时,它会水平滚动而不是垂直滚动。但是,我已经禁用了水平滚动。如果用户按住“shift”,我将如何使用鼠标滚轮实现垂直滚动?先谢谢你。

共有2个答案

上官德寿
2023-03-14

对于我的问题,我已经想出了一个更干净、更简单的答案。代码如下:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class CustomScrollPane extends JScrollPane {

    public CustomScrollPane(Component component) {
        super(component);
        initialize();
    }

    private void initialize() {

        // Set up the scroll bar.
        setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

        // Disable scrolling so we can do it manually.
        setWheelScrollingEnabled(false);

        addMouseWheelListener(new MouseWheelListener() {
            @Override
            public void mouseWheelMoved(MouseWheelEvent e) {
                // Manually scroll.
                getVerticalScrollBar().setValue(getVerticalScrollBar().getValue() + (e.getWheelRotation()));
            }
        });
    }
}

解决方案涉及禁用JScrollPane滚动。它检测鼠标轮何时旋转,并手动滚动。这样,当鼠标轮旋转时,它将滚动;“shift”是否被按住并不重要。我能看到的唯一缺点是getVerticalScrollBar().setUnitIncrement()不会改变滚动速度。滚动速度必须手动改变,也许用一个恒定的乘法器。

晋坚
2023-03-14

我不认为有一个简单的方法来做到这一点,因为通常情况下,当滚动多个方向时,只需要移动滚动。

您可以尝试在JFrame中添加一个键侦听器,并将鼠标上的滚轮设置为每当按下shift键时垂直滚动。我用这段代码试了一下,它工作得很好:

frame.addKeyListener(new KeyListener() {

        @Override
        public void keyPressed(KeyEvent arg0) {
            // TODO Auto-generated method stub
            if(arg0.isShiftDown()) {
                frame.addMouseWheelListener(new MouseWheelListener() {

                    @Override
                    public void mouseWheelMoved(MouseWheelEvent arg0) {
                        // TODO Auto-generated method stub
                        pane.getVerticalScrollBar().setValue(pane.getVerticalScrollBar().getValue()+arg0.getWheelRotation());
                    }

                });
            }
            if(!arg0.isShiftDown()) {
                frame.removeMouseWheelListener(frame.getMouseWheelListeners()[0]);
            }
        }
}
 类似资料:
  • 问题内容: 在鼠标滚轮上滚动它执行水平滚动。 已编辑 好吧,firebug说他在用 问题答案: 看来他只是将mousewheel事件映射到滚动区域。在IE中,仅通过使用方法就非常容易-滚动水平条的量为垂直条通常滚动的量。其他浏览器不支持该方法,因此您必须随心所欲地滚动任意数量:

  • 问题内容: 我的意思是滚动时会轻松。 问题答案: var $pages = $(“.page”), PS: 使用,如果你的s为像一个滚动的DIV内(而不是) 注意: 对于 移动设备, 您可能希望针对浏览器的标签栏高度调整值(最好还是完全避免这种情况)。你有主意

  • 问题内容: 我看到了启用或禁用鼠标滚轮滚动的方法。但是,有什么方法可以调整滚动速度?我认为这太慢了。不管我使窗口多大,每次单击滚动大约三个像素。我希望它远不止于此。 有任何想法吗? 问题答案: 您可以尝试以下方法:

  • 我有一个子类JPanel的PointPanel,我想在其中实现以下行为:如果鼠标悬停在实例上,按下shift键,鼠标光标变为手光标;如果松开shift键,鼠标光标将变回默认光标。 为了实现这一点,我尝试在构造函数中添加一个: 这种方法不起作用。 包含此面板的窗口应该具有焦点,因为它是应用程序的唯一可见窗口。 我错过了什么?

  • 我的问题是: 我的解决方案是使用mousewheel/scroll事件处理程序来知道用户是否在移动,然后计算我是否在页面底部并隐藏或显示元素。。。 一切正常,但我有点担心 由于主线程正忙,“mousewheel”输入事件的处理延迟了123毫秒。将事件处理程序标记为“被动”以使页面更加响应。 这(我猜)是因为这个代码 跑太多次了。 那么,我怎样才能使这段代码更有效率呢 是否有办法在滚动后运行事件?

  • 鼠标事件是Web 开发中最常用的一类事件,毕竟鼠标还是最主要的定位设备。DOM3 级事件中定义了9 个鼠标事件,简介如下。 click:在用户单击主鼠标按钮(一般是左边的按钮)或者按下回车键时触发。这一点对确保易访问性很重要,意味着onclick 事件处理程序既可以通过键盘也可以通过鼠标执行。 dblclick:在用户双击主鼠标按钮(一般是左边的按钮)时触发。从技术上说,这个事件并不是DOM2 级