2017-07-30 5 views
0
私はこの次のコードそれ奇妙であると考えられて何かに気づい

:私は、コードを実行すると、JLabelのが表示されないたoccuringたSwingクラス、異例のJLabelのappearence

public class QuestionFour extends JFrame { 
    private JTextArea txta1; 
    private JTextField txt1; 
    private JButton btnSort; 
    private JButton btnShuffle; 
    private JButton btnReverse; 
    private JPanel pnl1; 
    private JLabel lbl1; 
    private LinkedList linkedList; 

    public QuestionFour() { 
     super(); 
     this.setLocationRelativeTo(null); 
     this.setSize(500, 200); 
     this.setVisible(true); 
     this.setLayout(new FlowLayout()); 
     txt1 = new JTextField(); // 1 
     lbl1 = new JLabel("Enter a number: "); // 2 
     this.add(lbl1); 
    } 

    public static void main(String args[]) { 
     QuestionFour ob = new QuestionFour(); 
    } 
} 

問題は、私の場合1行目をコメントとしてコメントするとJLabelが表示されますが、TextFieldをインスタンス化するだけでJFrameには追加しないので、私は奇妙に思っています。

誰かが私にこれを説明できますか?

答えて

0

UIスレッド外でsetVisible(true)という呼び出しが原因で発生する可能性があります。この方法を試してください。

public QuestionFour() 
{ 
    setLocationRelativeTo(null); 
    this.setSize(500, 200); 
    setLayout(new FlowLayout()); 
    this.txt1 = new JTextField(); // 1 
    this.lbl1 = new JLabel("Enter a number: "); // 2 
    this.add(this.lbl1); 

    javax.swing.SwingUtilities.invokeLater(() -> setVisible(true)); 
} 

お知らせ:任意のUIコンポーネント(などJTextFieldなど)への読み取り/書き込みアクセスユーザーインターフェイススレッド(UIスレッド)内で行われなければならないが。 SwingUtilitiesは便利な方法を提供します。 EDT内でsetVisible()も呼び出す必要があります。

もう1つの問題は、最初にsetVisible(true)を呼び出し、後でUIコンポーネントを追加することでした。これはUIコンポーネントへの「書き込みアクセス」を表します(「あなたはメインパネルに何かを追加しています」)。あなたのクラスコンストラクタはEDT内で実行されないので、この場合はSwingUtilitiesのメソッドにthis.add(this.lbl1)をカプセル化しなければなりませんでした。しかし、UI全体を最初に構築してから、それを最終的に見えるように設定する方が良いでしょう。

スイングライブラリとスレッドセーフの詳細については、次を参照してください。https://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html

関連する問題