11

拡張する単純なオブジェクトがあります。このオブジェクトJPanelupdate()メソッドが呼び出されると、パネルにいくつかのラベルを追加してから再描画することを意味しました。ただし、更新メソッドが呼び出された後、ラベルは表示されません。以下は更新のコードです。

public void update(){
        GridBagConstraints constraints = new GridBagConstraints();

        if(cardsHidden){
            for(int i = 0; i < 2; i++){
                constraints.gridx = i;
                constraints.gridy = 0;
                JLabel card = new JLabel(PlayingCards.cardImages[PlayingCards.CARD_BACK_INDEX]);
                add(card, constraints);
            }
        }
        else{
            Card[] holeCards = player.getHoleCards();
            for(int i = 0; i < holeCards.length; i++){
                constraints.gridx = i;
                constraints.gridy = 0;
                JLabel card = new JLabel(holeCards[i].getImageIcon());
                add(card, constraints); 
            }
        }

        validate();
        repaint();
    }

何か案は?

ありがとう

編集

解決済み:

HoleCardsPanelが親フレームに適切に追加されていないことが判明しました。JLabelそれが修正されると、新しいs の追加は正常に機能します。私も:

  • を使用して、メソッドへの呼び出しをupdate()イベントディスパッチスレッドに追加しましたSwingUtillities.invokeLater
  • Devon_C_Millerが回答で示唆しているようにvalidate()、最上位のコンポーネント (この場合は) から呼び出す必要がありました。JFrame
4

6 に答える 6

25

何をしたいのか、どのレイアウト マネージャーを使用しているかによって異なりますが、基本的なルールは次のとおりです。

  1. updateが EDT で呼び出されていることを確認します。そうでない場合 ( false を返す) 、EDT で更新をスケジュールするSwingUtilities.isEventDispatchThread()ために を使用する必要があります。SwingUtilities.invokeLater例えば:

    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            update();
        }});
    
  2. コールしinvalidate()ます。コンポーネントを変更するほとんどのことは、これを行います。したがって、以下が単独では機能しない場合にのみ、これを呼び出す必要があります。

  3. 最も影響を受けるコンポーネントをvalidate()呼び出します。これはおそらく、Java のレンダリング サイクルの最も複雑な部分です。の呼び出しは、コンポーネントとそのすべての祖先をレイアウトが必要であるとマークします。の呼び出しにより、コンポーネントとそのすべての子孫のレイアウトが実行されます。1 つは「上」で動作し、もう 1 つは「下」で動作します。変更の影響を受けるツリーの最上位のコンポーネントを呼び出す必要があります。invalidatevalidatevalidate

    また、最上位コンポーネント (JWindow、JDialog、JFrame) で検証を呼び出しても、必ずしもそのコンポーネントのサイズが変更されるとは限りません。pack()そのためには、またはに電話する必要がありますsetSize()

  4. 変更によってコンテナーのサイズまたは位置が変更された場合、サイズ変更されたコンテナーは再描画されますが、使用されていたスペースは消去されません。コンテナの親を呼び出すrepaint()と、背景が再描画され、損傷が修正されます。

于 2010-01-28T20:36:15.573 に答える
17

revalidate();を呼び出してみてください。再塗装はあなたが望むものではありません。

によると:

APIドキュメント

注:表示されたコンテナーにコンポーネントが追加されている場合、新しいコンポーネントを表示するには、そのコンテナーでvalidateを呼び出す必要があります。複数のコンポーネントを追加する場合は、すべてのコンポーネントを追加した後で、validateを1回だけ呼び出すことで、効率を向上させることができます。

revalidate()は基本的にinvalidate()とそれに続くvalidate()です。

この質問を参照してください.....

于 2010-01-28T15:11:36.183 に答える
5

への呼び出しは機能するvalidate()はずrevalidate()ですが、十分かもしれません。repaint()必須ではありません。あなたがやっていることを、dynamic を行うこのGridBagLayoutと比較するかもしれません。

于 2010-01-28T19:18:47.890 に答える
2

メソッドを呼び出してみてくださいupdateUI()

于 2010-01-28T19:50:29.110 に答える
0

ラベルで SetVisible() を試しましたか?

更新せずに初期化時にオブジェクトを追加しようとしましたか? 彼らがそこに現れなければ、彼らは決して現れることはありません。

于 2010-01-28T15:05:56.630 に答える
0

HoleCardsPanel親フレームに適切に追加されていないことが判明しました。これが修正されると、新しいJLabels作品の追加が正常に機能します。update()メソッドの呼び出しをevent dispatch thread使用するように追加しました。さらに、最上位のコンポーネント (この場合は)SwingUtillities.invokeLaterから呼び出す必要がありました。validate()JFrame

于 2010-01-29T12:39:13.403 に答える