2

我想创建一个包含一些组件的 JInternalFrame。

我的目标是用 Java 设计一个 bash 控制台。

我的框架由 4 个组件组成:

  • JTextArea 包含在 JScrollPane 中
  • 带有文本“Cmd:”的 JLabel
  • JTextField
  • 带有文本“发送”的 JButton

我有以下代码:

Box box = Box.createHorizontalBox();
box.add(Box.createVerticalStrut(5));
box.add(this.cmd_label);
box.add(Box.createVerticalStrut(5));
box.add(this.cmd_input);
box.add(Box.createVerticalStrut(5));
box.add(this.submit);
box.add(Box.createVerticalStrut(5));

Box mainBox = Box.createVerticalBox();
mainBox.add(Box.createHorizontalStrut(5));
mainBox.add(this.result_scroll);
mainBox.add(Box.createHorizontalStrut(5));
mainBox.add(box);
mainBox.add(Box.createHorizontalStrut(5));
add(mainBox);

所以当frame还没有被最大化的时候,我有一个正确的样子:

非最大化帧

但是当我最大化它时,所有组件的位置都不正确:

最大化框架

所以,这是我的问题:如何为组件设置权重以每次都修复它们的位置,或者,我该如何修复它?

谢谢。

4

3 回答 3

3

我认为使用BorderLayout. 在 BorderLayout 中,指定为中心组件的组件将扩展以填充尽可能多的空间,而其他组件将保持其首选大小。

int hgap = 5;
int vgap = 5;
internalFrame.getContentPane().setLayout(new BorderLayout(hgap, vgap));
internalFrame.getContentPane().add(this.result_scroll, BorderLayout.CENTER);
JPanel bottomPanel = new JPanel();
bottomPanel.add(this.cmd_label);
bottomPanel.add(this.cmd_input);
bottomPanel.add(this.submit);
internalFrame.getContentPane().add(bottomPanel, BorderLayout.SOUTH);
于 2012-04-20T14:30:43.537 回答
2

在这里尝试这段代码,这种行为是否异常:

import java.awt.*;
import javax.swing.*;

public class LayoutExample
{
    private void createAndDisplayGUI()
    {
        JFrame frame = new JFrame("LAYOUT EXAMPLE");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        JPanel centerPanel = new JPanel();
        centerPanel.setLayout(new BorderLayout(5, 5));
        centerPanel.setBorder(
                    BorderFactory.createEmptyBorder(2, 2, 2, 2));
        JTextArea tarea = new JTextArea(10, 10);
        tarea.setBackground(Color.DARK_GRAY.darker());  
        tarea.setForeground(Color.WHITE);
        tarea.setCaretColor(Color.WHITE);
        tarea.setLineWrap(true);

        JScrollPane scrollPane = new JScrollPane(tarea);
        centerPanel.add(scrollPane, BorderLayout.CENTER);

        JPanel footerPanel = new JPanel();
        footerPanel.setLayout(new BorderLayout(5, 5));
        footerPanel.setBorder(
                    BorderFactory.createEmptyBorder(2, 2, 2, 2));       
        JLabel cmdLabel = new JLabel("Cmd : ");         
        JTextField tfield = new JTextField(10);

        JPanel buttonPanel = new JPanel();
        buttonPanel.setBorder(
                    BorderFactory.createEmptyBorder(2, 2, 2, 2));
        JButton sendButton = new JButton("SEND");

        footerPanel.add(cmdLabel, BorderLayout.LINE_START);
        footerPanel.add(tfield, BorderLayout.CENTER);
        buttonPanel.add(sendButton);
        footerPanel.add(buttonPanel, BorderLayout.LINE_END);

        frame.getContentPane().add(centerPanel, BorderLayout.CENTER);
        frame.getContentPane().add(footerPanel, BorderLayout.PAGE_END);

        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String... args)
    {   
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new LayoutExample().createAndDisplayGUI();
            }
        });
    }
}

输出 :

开始

最大化时

于 2012-04-20T15:09:10.007 回答
1

这里的基本问题是我认为 JTextField 的最大布局提示中的一个错误:它在水平垂直维度上都是无界的。后者对于为显示单行文本而设计的组件纯粹是胡说八道。要修复,子类化并让它返回其高度的首选项,例如:

JTextField cmdInput = new JTextField() {

    @Override
    public Dimension getMaximumSize() {
        Dimension max = super.getMaximumSize();
        max.height = getPreferredSize().height;
        return max;
    }

};

由于 BoxLayout 尊重 maxSize,现在多余的高度将仅提供给顶框。

从长远来看,考虑切换到第三方管理器,它允许在多合一面板方法中进行微调。是的,这是我目前最喜欢的:MigLayout。将以下几行与上面的所有嵌套和边框技巧进行比较,玩得开心:-)

MigLayout layout = new MigLayout("wrap 3, debug", 
        "[][grow, fill][]", // 3 columns, middle column filled and allows growing
        "[grow, fill][]"); // two rows, first filled and allows growing

JComponent content = new JPanel(layout);
// the scrollPane in the first row spanning all columns
// and growing in both directions 
content.add(new JScrollPane(new JTextArea(20, 20)), "span, grow");
// auto-wrapped to first column in second row
content.add(new JLabel("Cmd:"));
content.add(new JTextField());
content.add(new JButton("Submit"));
于 2012-06-30T10:24:28.870 回答