Swing 组件在自定义布局管理器中不可见
Swing components are not visible in custom layout manager
我制作了以下布局管理器class:
public class MainFrameLayout extends BorderLayout
{
private final JPanel north, center, south;
/**
* Constructor for this layout.
*/
public MainFrameLayout()
{
super();
north = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 0));
center = new JPanel();
center.setLayout(new BoxLayout(center, BoxLayout.Y_AXIS));
south = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 0));
north.setVisible(true);
center.setVisible(true);
south.setVisible(true);
super.addLayoutComponent(north, NORTH);
super.addLayoutComponent(center, CENTER);
super.addLayoutComponent(south, SOUTH);
}
@Override
public void addLayoutComponent(Component comp, Object constraints)
{
if (!(constraints instanceof MainFrameLayoutConstraints))
throw new IllegalArgumentException("Invalid constraints");
switch ((MainFrameLayoutConstraints) constraints)
{
case NORTH:
north.add(comp);
break;
case CENTER:
center.add(comp);
break;
case SOUTH:
south.add(comp);
break;
}
}
}
MainFrameLayoutConstraints
是通用的 enum
class,只有 NORTH
、CENTER
和 SOUTH
变体。
我试图在以下应用程序中使用此布局:
public class MyApplication extends JFrame
{
private final JFormattedTextField caseNumberBox;
public MyApplication()
{
super("A Title Thingy");
this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
NumberFormat caseNumberFormat = NumberFormat.getIntegerInstance();
caseNumberBox = new JFormattedTextField(caseNumberFormat);
caseNumberBox.setColumns(20);
this.setLayout(new MainFrameLayout());
this.add(new JLabel("Major Release Case: "), MainFrameLayoutConstraints.NORTH);
this.add(caseNumberBox, MainFrameLayoutConstraints.NORTH);
this.pack();
this.setVisible(true);
}
/**
* @param args the command line arguments
*/
public static void main(String[] args)
{
MyApplication app = new MyApplication();
}
}
为什么,当我 运行 这个应用程序时,我的组件(标签和文本字段)是不可见的,即使对 pack()
的调用适当地调整了 window 的大小以适合这些字段?
这就是评论员所说的..您的自定义布局并不是真正必要的。您可以直接在 MyApplication
class.
中添加组件
public MyApplication() {
...
setLayout(new BorderLayout(2, 1));
...
add(new JLabel("Major Release Case: "), BorderLayout.NORTH);
add(caseNumberBox, BorderLayout.CENTER);
...
}
该行为的原因是试图在布局管理器中创建组件。虽然 MainFrameLayout
为其创建的组件调用 super.addLayoutComponent()
,但这些 未 添加到父组件本身。因此,您添加到框架的组件计数用于框架的首选大小计算,因为它被委托给 BorderLayout
,它假设内容窗格包含您在 MainFrameLayout
构造函数中创建的面板,但它们永远不会被绘制为这些面板实际上并未添加到内容面板。
自定义布局管理器不是您想要实现的目标的错误工具。只需使用嵌套布局。
我制作了以下布局管理器class:
public class MainFrameLayout extends BorderLayout
{
private final JPanel north, center, south;
/**
* Constructor for this layout.
*/
public MainFrameLayout()
{
super();
north = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 0));
center = new JPanel();
center.setLayout(new BoxLayout(center, BoxLayout.Y_AXIS));
south = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 0));
north.setVisible(true);
center.setVisible(true);
south.setVisible(true);
super.addLayoutComponent(north, NORTH);
super.addLayoutComponent(center, CENTER);
super.addLayoutComponent(south, SOUTH);
}
@Override
public void addLayoutComponent(Component comp, Object constraints)
{
if (!(constraints instanceof MainFrameLayoutConstraints))
throw new IllegalArgumentException("Invalid constraints");
switch ((MainFrameLayoutConstraints) constraints)
{
case NORTH:
north.add(comp);
break;
case CENTER:
center.add(comp);
break;
case SOUTH:
south.add(comp);
break;
}
}
}
MainFrameLayoutConstraints
是通用的 enum
class,只有 NORTH
、CENTER
和 SOUTH
变体。
我试图在以下应用程序中使用此布局:
public class MyApplication extends JFrame
{
private final JFormattedTextField caseNumberBox;
public MyApplication()
{
super("A Title Thingy");
this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
NumberFormat caseNumberFormat = NumberFormat.getIntegerInstance();
caseNumberBox = new JFormattedTextField(caseNumberFormat);
caseNumberBox.setColumns(20);
this.setLayout(new MainFrameLayout());
this.add(new JLabel("Major Release Case: "), MainFrameLayoutConstraints.NORTH);
this.add(caseNumberBox, MainFrameLayoutConstraints.NORTH);
this.pack();
this.setVisible(true);
}
/**
* @param args the command line arguments
*/
public static void main(String[] args)
{
MyApplication app = new MyApplication();
}
}
为什么,当我 运行 这个应用程序时,我的组件(标签和文本字段)是不可见的,即使对 pack()
的调用适当地调整了 window 的大小以适合这些字段?
这就是评论员所说的..您的自定义布局并不是真正必要的。您可以直接在 MyApplication
class.
public MyApplication() {
...
setLayout(new BorderLayout(2, 1));
...
add(new JLabel("Major Release Case: "), BorderLayout.NORTH);
add(caseNumberBox, BorderLayout.CENTER);
...
}
该行为的原因是试图在布局管理器中创建组件。虽然 MainFrameLayout
为其创建的组件调用 super.addLayoutComponent()
,但这些 未 添加到父组件本身。因此,您添加到框架的组件计数用于框架的首选大小计算,因为它被委托给 BorderLayout
,它假设内容窗格包含您在 MainFrameLayout
构造函数中创建的面板,但它们永远不会被绘制为这些面板实际上并未添加到内容面板。
自定义布局管理器不是您想要实现的目标的错误工具。只需使用嵌套布局。