SWING 禁用或隐藏滚动条,但启用滚轮?
SWING disable or hide scroll bar, but enable wheel?
我想禁用或隐藏 JScrollPane 中的滚动条,但让用户使用鼠标滚轮上下滚动。
如果我使用 verticalScrollBarPolicy(NEVER) 它会隐藏滚动条,所以没问题,但不能使用滚轮。
有什么建议吗?
谢谢!
Based on this answer from CodeRanch,当滚动条从不显示时,滚动被禁用。您需要覆盖 JScrollBar
s isVisible
属性 到 "trick" 进入滚动。
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.Scrollable;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
JScrollPane scrollPane = new JScrollPane(new TestPane());
JScrollBar scrollBar = new JScrollBar(JScrollBar.VERTICAL) {
@Override
public boolean isVisible() {
return true;
}
};
// if appropriate, uncomment
//scrollBar.putClientProperty("JScrollBar.fastWheelScrolling", Boolean.TRUE);
scrollPane.setVerticalScrollBar(scrollBar);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
frame.add(scrollPane);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel implements Scrollable {
public TestPane() {
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 800);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
FontMetrics fm = g2d.getFontMetrics();
Integer lineY = null;
for (int yPos = fm.getAscent(); yPos < getHeight(); yPos += 30) {
g2d.drawString(Integer.toString(yPos), 10, yPos + fm.getAscent());
if (lineY != null) {
g2d.drawLine(15, lineY, 15, yPos);
}
lineY = yPos + fm.getAscent();
}
}
@Override
public Dimension getPreferredScrollableViewportSize() {
return new Dimension(200, 200);
}
@Override
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
return 64;
}
@Override
public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
return 128;
}
@Override
public boolean getScrollableTracksViewportWidth() {
return false;
}
@Override
public boolean getScrollableTracksViewportHeight() {
return false;
}
}
}
您不需要使用Scrollable
,这里使用它纯粹是为了演示目的来验证理论。
然而,这也会停止调用 getScrollableUnitIncrement
,这可能会影响滚动的整体速度,您需要进一步调查
哦,还有其他注意事项,如果JScrollPane
中包含的一个或多个组件注册到MouseWheelListener
事件,它将停止通知滚动窗格
基于@MadProgrammer 从 CodeRanch 引用的相同答案,我得到了一个更简单的解决方案:
public class OnlyHorizontalJScrollPane extends JScrollPane {
@Override
public JScrollBar createVerticalScrollBar() {
JScrollBar verticalScrollBar = new JScrollPane.ScrollBar(1);
verticalScrollBar.setPreferredSize(new Dimension(0,0));
return verticalScrollBar;
}
}
我在 Windows、java 14.
上进行了测试
我想禁用或隐藏 JScrollPane 中的滚动条,但让用户使用鼠标滚轮上下滚动。 如果我使用 verticalScrollBarPolicy(NEVER) 它会隐藏滚动条,所以没问题,但不能使用滚轮。
有什么建议吗? 谢谢!
Based on this answer from CodeRanch,当滚动条从不显示时,滚动被禁用。您需要覆盖 JScrollBar
s isVisible
属性 到 "trick" 进入滚动。
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.Scrollable;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
JScrollPane scrollPane = new JScrollPane(new TestPane());
JScrollBar scrollBar = new JScrollBar(JScrollBar.VERTICAL) {
@Override
public boolean isVisible() {
return true;
}
};
// if appropriate, uncomment
//scrollBar.putClientProperty("JScrollBar.fastWheelScrolling", Boolean.TRUE);
scrollPane.setVerticalScrollBar(scrollBar);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
frame.add(scrollPane);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel implements Scrollable {
public TestPane() {
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 800);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
FontMetrics fm = g2d.getFontMetrics();
Integer lineY = null;
for (int yPos = fm.getAscent(); yPos < getHeight(); yPos += 30) {
g2d.drawString(Integer.toString(yPos), 10, yPos + fm.getAscent());
if (lineY != null) {
g2d.drawLine(15, lineY, 15, yPos);
}
lineY = yPos + fm.getAscent();
}
}
@Override
public Dimension getPreferredScrollableViewportSize() {
return new Dimension(200, 200);
}
@Override
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
return 64;
}
@Override
public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
return 128;
}
@Override
public boolean getScrollableTracksViewportWidth() {
return false;
}
@Override
public boolean getScrollableTracksViewportHeight() {
return false;
}
}
}
您不需要使用Scrollable
,这里使用它纯粹是为了演示目的来验证理论。
然而,这也会停止调用 getScrollableUnitIncrement
,这可能会影响滚动的整体速度,您需要进一步调查
哦,还有其他注意事项,如果JScrollPane
中包含的一个或多个组件注册到MouseWheelListener
事件,它将停止通知滚动窗格
基于@MadProgrammer 从 CodeRanch 引用的相同答案,我得到了一个更简单的解决方案:
public class OnlyHorizontalJScrollPane extends JScrollPane {
@Override
public JScrollBar createVerticalScrollBar() {
JScrollBar verticalScrollBar = new JScrollPane.ScrollBar(1);
verticalScrollBar.setPreferredSize(new Dimension(0,0));
return verticalScrollBar;
}
}
我在 Windows、java 14.
上进行了测试