【问题标题】:JLabel not positioning correctlyJLabel 没有正确定位
【发布时间】:2017-10-25 19:43:06
【问题描述】:

当我遇到一个奇怪的问题时,我只是在拼凑一个快速而肮脏的 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 指出的那样,我的操作顺序已经关闭。翻转我的方法调用,世界上一切都好起来了。感谢第二双眼睛。

【问题讨论】:

  • 订单很重要。在设置框架大小之前不要设置项目的边界。通过先运行 setupFrame 然后运行 ​​setupObjects,可以按预期工作。
  • 两个词 - 布局管理器。当然手动完成它“快速”和“肮脏”,但它需要更长的时间,增加“意外”问题的数量,并且通常只是完全浪费时间。更多地关注信息/交互的流动,然后是“像素完美”布局,不同的平台/PC 将把“像素完美”布局弄得一团糟。简而言之,null 布局永远不是答案,即使您认为它们是,它们也不是

标签: java swing jlabel layout-manager null-layout-manager


【解决方案1】:

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

这是一个示例,展示了使用布局定位字段以及在以后更新规范时更改 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);
    }
}

【讨论】:

  • 虽然您的回答实际上是正确的,但它实际上并没有解决 OP 的问题,即为什么 JLabel 在空布局中忽略其边界。我从未在实际使用中使用过空布局,但这并没有改变我们应该理解为什么这不起作用的事实,即使使用 BorderLayout,因为默认的 add 正在用于最初设置的 JFrame到边框布局。
  • @Compass “OP 的为什么的问题” - OP 真的在某个地方问过这个问题吗?我没看到。
【解决方案2】:

您的操作顺序不正确。

您最初致电setupObjects();

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

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 2011-12-07
    • 1970-01-01
    • 2017-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-19
    相关资源
    最近更新 更多