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

时间:2017-08-25 20:57:14

标签: java swing jscrollpane mousewheel

我有一个简单的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 个答案:

答案 0 :(得分:0)

我不认为有一种简单的方法可以做到这一点,因为通常在向多个方向滚动时只需要移位滚动。

您可以尝试向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]);
            }
        }
}

答案 1 :(得分:0)

我已经找到了一个更清晰,更简单的问题答案。这是代码:

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。它会检测鼠标滚轮何时旋转,并手动滚动。这样,它会在鼠标滚轮旋转时滚动;如果&#39;转移&#39;无关紧要。是否被压制。我能看到的唯一缺点是getVerticalScrollBar().setUnitIncrement()不会改变滚动速度。滚动速度必须手动更改,可能使用常数乘数。