gpt4 book ai didi

java - BorderLayout -- 替换 BorderLayout 组件

转载 作者:太空宇宙 更新时间:2023-11-04 07:25:00 25 4
gpt4 key购买 nike

来自 BorderLayout javadoc:

A border layout lays out a container, arranging and resizing its components to fit in five regions: north, south, east, west, and center. Each region may contain no more than one component, and is identified by a corresponding constant: NORTH, SOUTH, EAST, WEST, and CENTER.

我有一个程序,基于 another SO question ,它会创建一个在 BorderLayout 中心包含一个按钮的 JFrame UI,等待 5 秒,然后将另一个按钮放在同一位置。由于声明(每个区域可能包含不超过一个组件),我希望第二个按钮取代第一个按钮。但是,原始按钮仍然“卡在周围”。代码如下:

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()); }
}
}
}

当我运行它时,第一个按钮适本地占据了框架的所有空间。如果我调整它的大小,它会按预期扩展。当延迟代码运行时,它将第二个按钮放入框架中,但如果我展开框架,我可以看到两个按钮。第二个按钮按照中心组件的正常情况展开;第一个按钮保持添加第二个按钮时的大小(例如,如果我在添加之前扩展框架,则会扩展)。

添加后,将鼠标悬停在第二个按钮上会隐藏第一个按钮;调整框架大小会在第二个框架的顶部重新显示第一个框架。如果第一个按钮不可见,则将鼠标悬停在其位置上会显示它,至少有时是这样。

我必须得出结论,第一个按钮仍然是框架布局中某处的一部分(例如,它在单击时显示默认动画),但我不知道在哪里。我有代码确保它不在任何其他 BorderLayout 组件中,并且中心组件确实是第二个按钮。

我删除了一个和两个对 pack() 的调用 - 这两个按钮的行为相同。

原始问题的发布者通过在添加第二个组件之前删除第一个组件解决了他的问题,但我想了解该程序中仍在引用第一个按钮的位置。有人可以帮忙吗?

最佳答案

我将尝试回答我自己的问题,主要基于 kleopatra 和 AndrewThompson 的有用评论。

BorderLayout 文档说“每个区域只能包含一个组件”;显然没有代码可以强制执行此操作,这取决于用户是否这样做。

我对程序行为的最佳猜测:当第二个组件被添加到容器中时,它被适本地放置在 borderlayout 的“中心”区域(它有自己的组件引用)。第一个组件仍在容器中,但不在布局中,因此它仍然可以渲染,并且可能出现在其他项目的顶部或底部;行为并未真正定义,因为它不再由布局容器管理。

我认为这是相当不幸的;这是我遇到的第一个组件可以位于容器中但不能位于布局管理器中的情况,事实上这是我第一次考虑这样的事情。我将它们视为两个密切互动的对象,而不是我需要帮助管理其协调的一对。

如果我知道向谁建议的话,我建议加强 BorderLayout javadoc,并提及用户有责任不要将两个组件放入一个区域。

关于java - BorderLayout -- 替换 BorderLayout 组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18673401/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com