.getSize()在JScrollPane中更新,但在JPanel中不更新

时间:2012-07-17 08:04:09

标签: java swing jframe jpanel jscrollpane

原始问题是为什么.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),则调整方块的大小,但会打印出错误的大小。问题是:

  1. 除了调用scrollRectToVisible以更新getSize()之外还有其他方法吗?
  2. 如果没有在jscollpane中添加square,如.getSize() isn't updated中的示例是否有相应的更新函数怎么办?

1 个答案:

答案 0 :(得分:2)

实际上没有问题。问题是你打电话给revalidate()支持延迟布局。请参阅javadoc

  

支持延迟自动布局。

     

调用无效,然后将此组件的validateRoot添加到列表中   需要验证的组件。验证将在以后进行   已分派所有当前待处理事件。 ...

特别是验证将在调度所有当前待处理事件后发生

这意味着在调度所有待处理事件(包括当前鼠标滚轮事件)后,将执行p2的布局(及其大小更改)。

当您调用scrollToVisibleRect时,如果它无效,它会自动执行组件的布局,这就是调用scrollToVisibleRect导致立即调整大小的原因。

如果您确实需要立即调整大小,可以在doLayout()的父容器上使用p2,但我不推荐它,因为它可能更贵。 revalidate()提供了合并repaint()等事件的可能性。