BorderLayout javadoc から:
ボーダー レイアウトはコンテナーをレイアウトし、そのコンポーネントを配置してサイズを変更し、北、南、東、西、中央の 5 つの領域に収まるようにします。各領域には、複数のコンポーネントを含めることはできず、NORTH、SOUTH、EAST、WEST、および CENTER の対応する定数によって識別されます。
別の SO questionに基づいて、BorderLayout センターにボタンを含む JFrame UI を作成し、5 秒待ってから、別のボタンを同じ位置に配置するプログラムがあります。ステートメント (各領域には複数のコンポーネントが含まれていない可能性があります) があるため、2 番目のボタンが最初のボタンに置き換わると予想されます。ただし、元のボタンは「ぶら下がっている」ままです。コードは次のとおりです。
import java.awt.BorderLayout;
import java.awt.Component;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class ReplaceBorderLayoutComponent extends JFrame
{
private static final long serialVersionUID = 1L;
public static void say(String msg) { System.out.println(msg); }
public void createUI()
{
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
try
{
SwingUtilities.invokeAndWait
(
new Runnable()
{
public void run()
{
// setLayout(new BorderLayout());
JButton longText = new JButton("Quite a long text");
/*getContentPane().*/add(longText, BorderLayout.CENTER);
pack();
setVisible(true);
say("longText = " + longText.toString());
}
}
);
}
catch (Exception e) {}
}
public void replaceComponent()
{
try
{
SwingUtilities.invokeAndWait
(
new Runnable()
{
public void run()
{
JButton anotherText = new JButton("Another text");
/*getContentPane().*/add(anotherText, BorderLayout.CENTER);
pack();
validate();
repaint();
say("anotherText = " + anotherText.toString());
}
}
);
}
catch (Exception e) { }
say("replaced");
}
public Component getComponent(String constraint)
{
BorderLayout bl = (BorderLayout)getContentPane().getLayout();
return bl.getLayoutComponent(constraint);
}
public static void main(String ... args)
{
ReplaceBorderLayoutComponent st = new ReplaceBorderLayoutComponent();
st.createUI();
try { Thread.sleep(5000); } catch (InterruptedException ie) {}
st.replaceComponent();
Component c = st.getComponent(BorderLayout.CENTER);
say("Center component = " + c.toString());
String otherPlaces[] = { "North", "South", "East", "West", "First", "Last", "Before", "After" };
for (String s : otherPlaces)
{
Component c2 = st.getComponent(s);
if (c2 != null) { say("found additional component at " + s + ", " + c2.toString()); }
}
}
}
実行すると、最初のボタンがフレームのすべてのスペースを適切に占有します。サイズを変更すると、期待どおりに拡張されます。遅延コードを実行すると、2 番目のボタンがフレームに配置されますが、フレームを拡大すると両方のボタンが表示されます。2 番目のボタンは、中央コンポーネントの通常どおりに展開されます。最初のボタンは、2 番目のボタンが追加されたときのサイズのままです (たとえば、追加する前にフレームを拡張すると、拡張されます)。
追加後、2 番目のボタンにカーソルを合わせると、最初のボタンが非表示になります。フレームのサイズを変更すると、最初のフレームが 2 番目のフレームの上に再表示されます。最初のボタンが表示されていない場合、その位置にカーソルを合わせると、少なくとも時々表示されます。
最初のボタンはまだフレーム レイアウトのどこかにあると結論付けなければなりません (たとえば、クリックするとデフォルトのアニメーションが表示されます) が、どこにあるのかわかりません。他の BorderLayout コンポーネントのいずれにも含まれていないこと、および中央のコンポーネントが実際に 2 番目のボタンであることを確認するコードがあります。
pack() の 1 つと両方の呼び出しを削除しました - 2 つのボタンに関して同じ動作です。
元の質問の投稿者は、最初のコンポーネントを削除してから 2 番目のコンポーネントを追加することで問題を回避しましたが、このプログラムで最初のボタンがまだ参照されている場所を理解したいと思います。誰でも助けることができますか?