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);
}
}
当我 运行 遇到一个奇怪的问题时,我只是拼凑了一个快速而肮脏的 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);
}
}