Java 当按住 shift 并使用鼠标滚轮时,Swing JScrollPane 不滚动
Java Swing JScrollPane not scrolling when shift held down and using mouse wheel
我有一个简单的 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',我将如何使用鼠标滚轮启用垂直滚动?
我不认为有一种简单的方法可以做到这一点,因为通常你只需要在多个方向滚动时使用 shift 滚动条。
您可以尝试向 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]);
}
}
}
我找到了一个更清晰、更简单的问题答案。这是代码:
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()
不会改变滚动速度。滚动速度必须手动更改,也许使用常数乘数。
我有一个简单的 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',我将如何使用鼠标滚轮启用垂直滚动?
我不认为有一种简单的方法可以做到这一点,因为通常你只需要在多个方向滚动时使用 shift 滚动条。
您可以尝试向 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]);
}
}
}
我找到了一个更清晰、更简单的问题答案。这是代码:
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()
不会改变滚动速度。滚动速度必须手动更改,也许使用常数乘数。