仅在鼠标悬停时显示滚动条
Show scrollbars only when mouse is over
我只想在鼠标悬停在 JScrollPane 上时才显示滚动条。我尝试使用下面显示的方法将 MouseAdapter 作为 MouseListener 添加到 JScrollbar,但效果不佳。当鼠标在滚动条上方移动时,滚动条会闪烁。
有什么建议吗?
@Override
public void mouseEntered(java.awt.event.MouseEvent evt) {
Runnable runner = new Runnable()
{
public void run() {
JScrollPane sp = (JScrollPane) evt.getSource();
sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
sp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
}
};
Thread t = new Thread(runner, "Enter Thread");
t.start();
}
@Override
public void mouseExited(java.awt.event.MouseEvent evt) {
Runnable runner = new Runnable()
{
public void run() {
JScrollPane sp = (JScrollPane) evt.getSource();
sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
sp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
}
};
Thread t = new Thread(runner, "Exit Thread");
t.start();}
我已经编辑了我的答案以包含下面的评论。
JScrollPane scrollPane = new JScrollPane();
scrollPane.setPreferredSize(new Dimension(600, 600));
scrollPane.addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(final java.awt.event.MouseEvent evt) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JScrollPane sp = (JScrollPane) evt.getSource();
sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
sp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
}
});
}
@Override
public void mouseExited(final java.awt.event.MouseEvent evt) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JScrollPane sp = (JScrollPane) evt.getSource();
sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
sp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
}
});
}
});
JPanel panel = new JPanel(new BorderLayout());
add(panel);
JTextArea ta = new JTextArea();
ta.setPreferredSize(new Dimension(500, 500));
scrollPane.add(ta);
panel.add(scrollPane);
- 在这种情况下,使用
MouseListener
的方式比较麻烦,所以不推荐。
- 例如,鼠标光标在
JScrollBar
上闪烁。
- 您或许可以使用
JLayer
:
import java.awt.*;
import java.awt.event.*;
import java.util.Collections;
import javax.swing.*;
import javax.swing.plaf.LayerUI;
public class ScrollPaneMouseOverTest {
public JComponent makeUI() {
String text = String.join("\n", Collections.nCopies(100, "aaaaa"));
JTextArea ta = new JTextArea(
"Mouse cursor flickers over the JScrollBar.\n" + text);
ta.addMouseListener(new MouseAdapter() {
@Override public void mouseEntered(MouseEvent e) {
JScrollPane sp = (JScrollPane) SwingUtilities.getAncestorOfClass(
JScrollPane.class, (Component) e.getSource());
sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
}
@Override public void mouseExited(MouseEvent e) {
JScrollPane sp = (JScrollPane) SwingUtilities.getAncestorOfClass(
JScrollPane.class, (Component) e.getSource());
sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
}
});
JScrollPane scroll = new JScrollPane(new JTextArea(text));
scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
JPanel p = new JPanel(new GridLayout(2, 1));
p.add(new JScrollPane(ta));
p.add(new JLayer<>(scroll, new LayerUI<JScrollPane>() {
@Override public void installUI(JComponent c) {
super.installUI(c);
if (c instanceof JLayer) {
((JLayer) c).setLayerEventMask(AWTEvent.MOUSE_EVENT_MASK);
}
}
@Override public void uninstallUI(JComponent c) {
if (c instanceof JLayer) {
((JLayer) c).setLayerEventMask(0);
}
super.uninstallUI(c);
}
@Override protected void processMouseEvent(
MouseEvent e, JLayer<? extends JScrollPane> l) {
JScrollPane sp = l.getView();
switch (e.getID()) {
case MouseEvent.MOUSE_ENTERED:
sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
break;
case MouseEvent.MOUSE_EXITED:
sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
break;
default:
break;
}
//super.processMouseEvent(e, l);
}
}));
return p;
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new ScrollPaneMouseOverTest().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
});
}
}
我只想在鼠标悬停在 JScrollPane 上时才显示滚动条。我尝试使用下面显示的方法将 MouseAdapter 作为 MouseListener 添加到 JScrollbar,但效果不佳。当鼠标在滚动条上方移动时,滚动条会闪烁。
有什么建议吗?
@Override
public void mouseEntered(java.awt.event.MouseEvent evt) {
Runnable runner = new Runnable()
{
public void run() {
JScrollPane sp = (JScrollPane) evt.getSource();
sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
sp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
}
};
Thread t = new Thread(runner, "Enter Thread");
t.start();
}
@Override
public void mouseExited(java.awt.event.MouseEvent evt) {
Runnable runner = new Runnable()
{
public void run() {
JScrollPane sp = (JScrollPane) evt.getSource();
sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
sp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
}
};
Thread t = new Thread(runner, "Exit Thread");
t.start();}
我已经编辑了我的答案以包含下面的评论。
JScrollPane scrollPane = new JScrollPane();
scrollPane.setPreferredSize(new Dimension(600, 600));
scrollPane.addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(final java.awt.event.MouseEvent evt) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JScrollPane sp = (JScrollPane) evt.getSource();
sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
sp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
}
});
}
@Override
public void mouseExited(final java.awt.event.MouseEvent evt) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JScrollPane sp = (JScrollPane) evt.getSource();
sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
sp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
}
});
}
});
JPanel panel = new JPanel(new BorderLayout());
add(panel);
JTextArea ta = new JTextArea();
ta.setPreferredSize(new Dimension(500, 500));
scrollPane.add(ta);
panel.add(scrollPane);
- 在这种情况下,使用
MouseListener
的方式比较麻烦,所以不推荐。- 例如,鼠标光标在
JScrollBar
上闪烁。
- 例如,鼠标光标在
- 您或许可以使用
JLayer
:
import java.awt.*;
import java.awt.event.*;
import java.util.Collections;
import javax.swing.*;
import javax.swing.plaf.LayerUI;
public class ScrollPaneMouseOverTest {
public JComponent makeUI() {
String text = String.join("\n", Collections.nCopies(100, "aaaaa"));
JTextArea ta = new JTextArea(
"Mouse cursor flickers over the JScrollBar.\n" + text);
ta.addMouseListener(new MouseAdapter() {
@Override public void mouseEntered(MouseEvent e) {
JScrollPane sp = (JScrollPane) SwingUtilities.getAncestorOfClass(
JScrollPane.class, (Component) e.getSource());
sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
}
@Override public void mouseExited(MouseEvent e) {
JScrollPane sp = (JScrollPane) SwingUtilities.getAncestorOfClass(
JScrollPane.class, (Component) e.getSource());
sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
}
});
JScrollPane scroll = new JScrollPane(new JTextArea(text));
scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
JPanel p = new JPanel(new GridLayout(2, 1));
p.add(new JScrollPane(ta));
p.add(new JLayer<>(scroll, new LayerUI<JScrollPane>() {
@Override public void installUI(JComponent c) {
super.installUI(c);
if (c instanceof JLayer) {
((JLayer) c).setLayerEventMask(AWTEvent.MOUSE_EVENT_MASK);
}
}
@Override public void uninstallUI(JComponent c) {
if (c instanceof JLayer) {
((JLayer) c).setLayerEventMask(0);
}
super.uninstallUI(c);
}
@Override protected void processMouseEvent(
MouseEvent e, JLayer<? extends JScrollPane> l) {
JScrollPane sp = l.getView();
switch (e.getID()) {
case MouseEvent.MOUSE_ENTERED:
sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
break;
case MouseEvent.MOUSE_EXITED:
sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
break;
default:
break;
}
//super.processMouseEvent(e, l);
}
}));
return p;
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new ScrollPaneMouseOverTest().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
});
}
}