Reputation: 43
I have a simple Java Swing program defined below:
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);
}
}
The program consists of a simple JScrollPane with multiple buttons inside of it. Only vertical scrolling is enabled. It works fine.
However, the problem is, when I am holding down the 'shift' key, vertical scrolling does not work when I am using the mouse wheel to scroll. Vertical scrolling only works when I drag the scrollbar or let go of the 'shift' key.
Usually, in a JScrollPane, when the 'shift' key is held down, and the mouse wheel is used, it scrolls horizontally instead of vertically. However, I have disabled horizontal scrolling.
How would I go about enabling vertical scrolling using the mouse wheel if the user is holding down 'shift'?
Upvotes: 0
Views: 1369
Reputation: 43
I have figured out a cleaner and simpler answer to my question. Here is the code:
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()));
}
});
}
}
The solution involves disabling JScrollPane from scrolling. It detects when the mousewheel is being rotated, and manually scrolls. This way, it will scroll when the mousewheel is rotated; it does not matter if 'shift' is being held down or not. The only drawback that I can see is that getVerticalScrollBar().setUnitIncrement()
will not change the scrolling speed. The scrolling speed has to be changed manually, perhaps with a constant multiplier.
Upvotes: 0
Reputation: 26
I don't think there is a simple way to do this because normally you would only need the shift scroll when scrolling in more than one direction.
You could try adding a key listener to your JFrame and setting the wheel on your mouse to scroll vertically whenever the shift key is pressed. I tried it with this code and it worked just fine:
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]);
}
}
}
Upvotes: 1