JLabel 定位不正确

JLabel not positioning correctly

当我 运行 遇到一个奇怪的问题时,我只是拼凑了一个快速而肮脏的 GUI 来显示一些数据。我添加到 JFrame 的最后一个标签不想定位或显示我放在它上面的边框,所以它看起来像这样:

这是我的代码:

public DisplayData (Connection tConn)
{
    ID = tID;
    conn = tConn;

    setupObjects();
    setupFrame();
}

private void setupObjects()
{
    JLabel caseLabel = new JLabel ("Case #:");
    JLabel dateLabel = new JLabel ("Date:");
    JLabel reportLabel = new JLabel ("Report:");
    JLabel offenceLabel = new JLabel ("Offence:");
    JLabel descriptionLabel = new JLabel ("Description:");

    this.add(caseLabel);
    this.add(dateLabel);
    this.add(reportLabel);
    this.add(offenceLabel);
    this.add(descriptionLabel);

    caseLabel.setBounds(50, 50, 130, 25); //x, y, width, height
    dateLabel.setBounds(50, 100, 130, 25);
    reportLabel.setBounds(50, 150, 130, 25);
    offenceLabel.setBounds(50, 200, 130, 25);
    descriptionLabel.setBounds(100, 50, 130, 25);

    caseLabel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
    dateLabel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
    reportLabel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
    offenceLabel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
    descriptionLabel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
}

private void setupFrame()
{
    this.setTitle("Data Display");
    this.setSize (650, 700); //Width, Height
    this.setLocation(300, 10);
    this.setResizable(false);
    this.setVisible(true);
    this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    this.setLayout(null);
}

是的,我知道我应该使用合适的布局管理器,但就像我说的,我只是想要一些快速而肮脏的东西。另外,我不会被这么简单的事情打败。任何想法将不胜感激。

编辑: 正如 Compass 和 Neophyte 所指出的那样,我的操作命令已关闭。翻转我的方法调用,世界上一切都好起来了。感谢第二双眼睛

您的操作顺序不正确。

您最初调用 setupObjects();

这会将您的对象播放到 JFrame 上,该 JFrame 的默认 LayoutManager 为 BorderLayout

通过使用默认的 add(Component comp) 方法和 BorderLayout,您最终会将组件放入 BorderLayout 的 null,这不应该是正常的。此外,您看不到该对象边框的原因是边框实际上是框架的大小。如果您明确为 BorderLayout 设置一个区域,那么您会看到它有效,但设置为无区域似乎只会破坏 BorderLayout。

额外的 add 调用似乎是为了从 BorderLayout 空管理中释放前一个项目,允许边界接管。

之后,您调用 setupFrame(); 删除布局管理器,但不会刷新当前呈现的内容

这会将布局设置为 null,这对框架的显示方式没有任何影响,只是删除了布局。

为避免此问题,请在 setupObjects(); 之前调用 setupFrame();,然后可以在 setupObjects();

结束时调用 setVisible(true)

与原始发布者的策略或迄今为止的任何答案相反,解决此问题的最佳方法是使用布局

这是一个示例,展示了使用布局定位字段以及在以后更新规范时更改 GUI 是多么容易。

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

public class CourtDetailsGUI {

    private JComponent ui = null;
    static final String[] FIELD_NAMES = {
        "Case #:",
        "Date:",
        "Report:",
        "Offence:",
        "Plaintiff:",
        "Defendant:"
    };

    CourtDetailsGUI(int num) {
        initUI(num);
    }

    public void initUI(int num) {
        if (ui != null) {
            return;
        }

        ui = new JPanel(new BorderLayout(4, 4));
        ui.setBorder(new EmptyBorder(4, 4, 4, 4));

        ui.add(getFieldsPanel(num), BorderLayout.PAGE_START);

        JTextArea ta = new JTextArea(5, 40);
        JScrollPane sp = new JScrollPane(ta);
        JPanel p = new JPanel(new GridLayout());
        p.add(sp);
        p.setBorder(new TitledBorder("Details"));
        ui.add(p);
    }

    private JPanel getFieldsPanel(int num) {
        JPanel outerPanel = new JPanel(new FlowLayout());
        JPanel innerPanel = new JPanel(new GridLayout(0, 1, 15, 15));
        outerPanel.add(innerPanel);
        for (int ii=1; ii<num; ii++) {
            JLabel l = new JLabel(FIELD_NAMES[ii]);
            l.setBorder(new LineBorder(Color.BLACK));
            innerPanel.add(l);
        }

        return outerPanel;
    }

    public JComponent getUI() {
        return ui;
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception useDefault) {
                }
                for (int ii=0; ii<FIELD_NAMES.length; ii++) {
                    CourtDetailsGUI o = new CourtDetailsGUI(ii+1);

                    JFrame f = new JFrame("Data " + (ii+1));
                    f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                    f.setLocationByPlatform(true);

                    f.setContentPane(o.getUI());
                    f.pack();
                    f.setMinimumSize(f.getSize());

                    f.setVisible(true);
                }
            }
        };
        SwingUtilities.invokeLater(r);
    }
}