JLabel没有正确定位

时间:2017-10-25 19:43:07

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

当我遇到一个奇怪的问题时,我只是把一个快速而脏的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指出的那样,我的操作顺序已经结束。翻转我的方法调用,这一切在世界上再次变好。谢谢第二双眼睛。

2 个答案:

答案 0 :(得分:2)

与原始海报的策略或目前为止的任何答案相反,解决此问题的最佳方法是使用布局

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

enter image description here

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

答案 1 :(得分:0)

您的操作顺序不正确。

您最初致电setupObjects();

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

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

其他add次调用似乎从BorderLayout null管理中释放了上一项,允许边界接管。

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

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

要避免此问题,请在setupFrame();之前致电setupObjects();,然后在setVisible(true)

结束时调用setupObjects();