当JScrollPane中的View包含一个JLabel,如果这个JLabel很长,那么在一开始,水平滚动条是隐藏的。这时候,如果我们慢慢拖动窗口使JScrollPane变宽,那么View也变宽了(因为JLabel很长)。但是如果这时候拖动窗口使JScrollPane变窄,View的宽度没有变窄!水平滚动条出现了!
我们期望的结果是,JScrollPane变窄的时候,JLabel也变窄。
但是我们发现JTextArea在JScrollPane中的时候,JScrollPane变窄,JTextArea也会变窄。这是为啥呢?
其实是因为JTextArea实现了Scrollable接口,JScrollPane会因为View是否实现Scrollable接口而有不同的表现。
参考JTextArea中Scrollable的实现(JTextComponent的实现),相应的,我们可以让View按照如下的方法实现Scrollable。此处为MyFixedWidthPanel。
public class MyFixWidthPanel extends JPanel implements Scrollable {
public MyFixWidthPanel() {
super();
}
public MyFixWidthPanel(LayoutManager layout) {
super(layout);
}
@Override
public Dimension getPreferredScrollableViewportSize() {
return getPreferredSize();
}
@Override
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
switch (orientation) {
case SwingConstants.VERTICAL:
return visibleRect.height / 10;
case SwingConstants.HORIZONTAL:
return visibleRect.width / 10;
default:
throw new IllegalArgumentException("Invalid orientation: " + orientation);
}
}
@Override
public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
switch (orientation) {
case SwingConstants.VERTICAL:
return visibleRect.height;
case SwingConstants.HORIZONTAL:
return visibleRect.width;
default:
throw new IllegalArgumentException("Invalid orientation: " + orientation);
}
}
@Override
public boolean getScrollableTracksViewportWidth() {
return true;
}
@Override
public boolean getScrollableTracksViewportHeight() {
return false;
}
}