0

元の質問は、コンポーネントのサイズが変更された後に .getSize() が JCompnent の実際のサイズを返さない理由でした: .getSize() は更新されません

代わりに、この場合は JPanel を JScrollPane 内に追加し、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());
    }
}

マウスホイールを 1 回クリックすると、緑色の四角形のサイズが変更されます。プログラムは正しいサイズも印刷します。ただし、 scrollRectToVisible(1,1,1,1) を削除すると、正方形のサイズが変更されますが、間違ったサイズが出力されます。質問は次のとおりです。

  1. getSize() を更新するために scrollRectToVisible を呼び出す以外の方法はありますか?
  2. .getSize()の例が更新されていないように、jscollpane 内に正方形が追加されていない場合はどうなり ますか?対応する更新関数はありますか?
4

1 に答える 1

2

実際には問題ありません。重要なのは、遅延レイアウトrevalidate() をサポートする呼び出しです。javadocを参照してください:

遅延自動レイアウトをサポートします。

呼び出しはinvalidateを呼び出してから、このコンポーネントのvalidateRootを検証が必要なコンポーネントのリストに追加します。検証は、現在保留中のすべてのイベントがディスパッチされた後に行われます。..。

特に、検証は、現在保留中のすべてのイベントがディスパッチされた後に行われます。

これは、現在のマウスホイールイベントを含むすべての保留中のイベントがディスパッチされた後に、p2のレイアウト(したがってそのサイズ変更)が実行されることを意味します。

を呼び出すとscrollToVisibleRect、コンポーネントが有効でない場合はコンポーネントのレイアウトが自動的に実行されます。これが、scrollToVisibleRectを呼び出すとすぐにサイズ変更が行われる理由です。

すぐにサイズ変更が必要な場合はdoLayout()、の親コンテナで使用できp2ますが、コストが高くなる可能性があるため、お勧めしません。revalidate()のようにイベントを合体させる可能性を提供しますrepaint()

于 2012-07-17T08:31:40.707 に答える