我正在使用滚动窗格设置来使用自定义滚动条,除此之外,我还想在滚动条的拇指上安装一个侦听器,这样每当鼠标进入拇指区域时,它就可以改变颜色或边框。我搜索了 BasicScrollBarUI(由我的自定义滚动条 UI 扩展)并找到了 installListeners() 方法,因此我覆盖了它并让它为拇指区域再调用一个侦听器。
SSCCE:
public class TestScrollBar extends JFrame {
public TestScrollBar() {
JPanel innerPanel = new JPanel();
innerPanel.setLayout(new BoxLayout(innerPanel, BoxLayout.Y_AXIS));
for (int i=1; i<=10; i++) {
innerPanel.add(new JLabel("Label "+i));
innerPanel.add(Box.createRigidArea(new Dimension(0, 20)));
}
JScrollPane scrollPane = new JScrollPane(innerPanel);
scrollPane.setPreferredSize(new Dimension(innerPanel.getPreferredSize().width, innerPanel.getPreferredSize().height/2));
scrollPane.getVerticalScrollBar().setUI(new CustomScrollBarUI());
this.setLayout(new BorderLayout());
this.add(Box.createRigidArea(new Dimension(0, 20)), BorderLayout.NORTH);
this.add(Box.createRigidArea(new Dimension(0, 20)), BorderLayout.SOUTH);
this.add(Box.createRigidArea(new Dimension(20, 0)), BorderLayout.EAST);
this.add(Box.createRigidArea(new Dimension(20, 0)), BorderLayout.WEST);
this.add(scrollPane, BorderLayout.CENTER);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
TestScrollBar frame = new TestScrollBar();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
还有一个简单的滚动条自定义 UI:
public class CustomScrollBarUI extends BasicScrollBarUI {
@Override
protected void installListeners() {
super.installListeners();
scrollbar.addMouseListener(new CustomListener());
}
protected class CustomListener extends MouseAdapter {
public void mouseEntered(MouseEvent e) {
if (getThumbBounds().contains(e.getX(), e.getY())) {
System.out.println("THUMB");
}
}
}
}
当鼠标从右侧或左侧进入拇指区域时,侦听器工作正常,但它并不总是适用于顶部或底部。对于这些侧面,它仅在拇指触摸其中一个按钮时才起作用。例如,当滚动条位于最顶部时,侦听器仅在鼠标从顶部按钮而不是从下方进入拇指区域时才起作用(左右侧除外)。当滚动条触摸减少按钮时,会发生相反的情况(仅适用于右侧/左侧/底部,但不适用于顶部)。当拇指介于两者之间而不接触任何按钮时,则只有左右两侧起作用。如果您运行代码,您可以看到所有这些。
我还尝试使用现有的侦听器之一(而不是创建自己的侦听器)BasicScrollBarUI.TrackListener,我在其中添加了一个仅侦听拇指区域的方法,但结果完全相同:
public class CustomScrollBarUI extends BasicScrollBarUI {
@Override
protected TrackListener createTrackListener(){
return new TrackListener();
}
protected class TrackListener extends BasicScrollBarUI.TrackListener {
public void mouseEntered(MouseEvent e) {
currentMouseX = e.getX();
currentMouseY = e.getY();
if (getThumbBounds().contains(currentMouseX, currentMouseY)) {
System.out.println("THUMB");
}
}
}
}