原始问题是为什么.getSize()在调整组件大小后不返回JCompnent的实际大小:.getSize() isn't updated
相反,我在JScrollPane中添加了一个JPanel,并使用了scrollRectToVisible()来更新getSize()。考虑这个小例子:
import java.awt.*;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import javax.swing.*;
public class Test extends JFrame implements MouseWheelListener{
JPanel p,p2;
JScrollPane js;
Test(){
setLayout(new FlowLayout());
setPreferredSize(new Dimension(1000,1000));
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
p = new JPanel();
p.setPreferredSize(new Dimension(200,200));
p2=new JPanel();
p2.setPreferredSize(new Dimension(20,20));
p2.setBackground(Color.green);
p.add(p2);
js = new JScrollPane(p);
add(js);
addMouseWheelListener(this);
pack();
}
public static void main(String args[]){
new Test();
}
public void mouseWheelMoved(MouseWheelEvent e) {
System.out.println(p2.getSize());
p2.setPreferredSize(new Dimension(100,100));
p2.revalidate();
p2.scrollRectToVisible(new Rectangle(1,1,1,1));
System.out.println(p2.getSize());
}
}
滚动鼠标滚轮后,单击绿色方块的大小。该程序还打印出正确的大小。但是,如果我删除了scrollRectToVisible(1,1,1,1),则调整方块的大小,但会打印出错误的大小。问题是:
答案 0 :(得分:2)
实际上没有问题。问题是你打电话给revalidate()
支持延迟布局。请参阅javadoc:
支持延迟自动布局。
调用无效,然后将此组件的validateRoot添加到列表中 需要验证的组件。验证将在以后进行 已分派所有当前待处理事件。 ...
特别是验证将在调度所有当前待处理事件后发生
这意味着在调度所有待处理事件(包括当前鼠标滚轮事件)后,将执行p2的布局(及其大小更改)。
当您调用scrollToVisibleRect
时,如果它无效,它会自动执行组件的布局,这就是调用scrollToVisibleRect导致立即调整大小的原因。
如果您确实需要立即调整大小,可以在doLayout()
的父容器上使用p2
,但我不推荐它,因为它可能更贵。 revalidate()
提供了合并repaint()
等事件的可能性。