0

最初的问题是为什么 .getSize() 在组件调整大小后不返回 JCompnent 的实际大小:.getSize() 没有更新

相反,我在 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)正方形的大小会被调整,但它会打印出错误的 size。问题是:

  1. 除了调用 scrollRectToVisible 来更新 getSize() 之外,还有其他方法吗?
  2. 如果正方形没有添加到 jscollpane 中,例如 .getSize() 中的示例没有更新,是否有相应的更新函数?
4

1 回答 1

2

实际上没有问题。问题是你调用revalidate() 它支持延迟布局。请参阅javadoc

支持延迟自动布局。

调用 invalidate 然后将此组件的 validateRoot 添加到需要验证的组件列表中。验证将在所有当前挂起的事件都已调度后进行。...

特别是验证将在所有当前未决事件已被调度后发生

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

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

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

于 2012-07-17T08:31:40.707 回答