0

「ユーザー」のラベル、ユーザー名のテキストフィールド、および「サインイン」ボタンを持つボックスをSwingで作成しようとしています。これは私のコードです

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.util.*;

public class Engine
{
    JFrame frame;
    public void go()
    {
        setUpGui();
        userNameScreen();
    }
    public void setUpGui()
    {
        frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
    public void userNameScreen()
    {
        JPanel background = new JPanel();
            frame.getContentPane().add(background);
        JLabel labelUserName = new JLabel("User:");
            background.add(labelUserName);
            System.out.println(labelUserName.getHeight()); // 0
        JTextField textFieldUserName = new JTextField();
            System.out.println(labelUserName.getHeight()); // 16
            textFieldUserName.setPreferredSize(new Dimension(110,labelUserName.getHeight()));
            background.add(textFieldUserName);
        JButton buttonSignIn = new JButton("Sign In");
            background.add(buttonSignIn);
        /*
        background.add(labelUserName);
        background.add(textFieldUserName);
        background.add(buttonSignIn);
        frame.getContentPane().add(background);
        */
        frame.pack();
    }
}

私のドライバー クラスは、engine のインスタンスを作成し、go() メソッドを実行するだけです。
Swing コンポーネントは、追加されるまで高さ/幅の属性を持たないことを読みました (これは、レイアウト マネージャーがどれだけのスペースを確保できるかを決定するためです)。最後に* (ここでコメントアウト) は、textFieldUserName 変数に高さを持たないようにします。
ただし、同じメソッド userNameScreen() で確認できます。

System.out.println(labelUserName.getHeight());

二回。1 回目は 0 です。2 回目は 16 です。なぜ 1 回目は 0 として登録されるのかわかりません。パネルには既に追加されています (前の行で)。最初の println() と次の println() の間で高さが変わるようなものではないようです。では、なぜ最初の値が 0 であり、その直後に 16 に変わるのはなぜでしょうか?

*最後にコメントアウトされたすべてのものを追加すると言うとき、コードの他の場所で実行されたすべての同じコマンドを削除/コメントアウトすることも含まれることに注意してください。

4

2 に答える 2

2

これは、EDT で Swing コンポーネントを作成/変更しないことによる副作用です。別のスレッドでコンポーネントを追加している間、EDT はレイアウトを行うためにビジー状態になります。

メイン メソッドは次のようになります。

public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            new Engine().go();
        }
    });
}
于 2012-06-27T10:29:23.987 に答える
1

なぜこれが起こっているのかわかりませんが、コンポーネントの追加がおそらくバックグラウンドスレッドにあり、次のステートメントが呼び出されるまで更新されず、数ミリ秒後に更新され、2回目に呼び出したときに表示される可能性があります.

于 2012-06-27T08:31:21.777 に答える