我正在尝试创建一个程序,使学校项目的平面图创建变得容易。用户可以输入建筑物的尺寸,然后将其描绘为标签网格,通过单击标签可以将其变成墙壁、 window 或门。由于墙壁、 window 和门具有不同的外观、 Material 等,因此我为每个创建了单独的类,所有这些都扩展了buildingObject。为了让它首先工作,我只专注于在表单上获取buildingObjects。
package building.pkg3d.printer;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class buildingObject {
private int x;
private int y;
private int rotation;
private javax.swing.JLabel jLabel = new javax.swing.JLabel("wohnvipowa");
private static final int WIDTH = 10;
private static final int HEIGHT = 100;
public buildingObject(int x, int y, int rotation, JPanel p) {
this.x = x;
this.y = y;
this.rotation = rotation;
initLabel(p);
}
public void initLabel(JPanel p)
{
jLabel.setLocation(x, y);
if (rotation == 1)
jLabel.setPreferredSize(new Dimension(WIDTH, HEIGHT));
else
jLabel.setPreferredSize(new Dimension(HEIGHT, WIDTH));
jLabel.setBackground(Color.BLACK);
jLabel.setOpaque(true);
p.add(jLabel);
p.validate();
System.out.println("jLabel added to panel");
System.out.println("jLabel at: " + jLabel.getX() + ", " + jLabel.getY());
System.out.println("");
jLabel.setVisible(true);
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public int getRotation() {
return rotation;
}
public JLabel getjLabel() {
return jLabel;
}
@Override
public String toString() {
return "buildingObject{" + "x=" + x + ", y=" + y + ", rotation=" + rotation + ", jLabel=" + jLabel + '}';
}
}
我正在空表单上快速测试它
package building.pkg3d.printer;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import javax.swing.JPanel;
public class labelTester extends javax.swing.JFrame {
private buildingObject[][] matrix;
/**
* Creates new form labelTester
*/
public labelTester() {
initComponents();
initLayout(1500,1500);
System.out.println(this.getContentPane().getComponentAt(0, 0).toString());
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 514, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 426, Short.MAX_VALUE)
);
pack();
}// </editor-fold>
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(labelTester.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(labelTester.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(labelTester.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(labelTester.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new labelTester();
}
});
}
private void initLayout(int w, int l)
{
int numRows = l / 100;
int numCol = w / 100;
matrix = new buildingObject[numRows][numCol];
JPanel p = new JPanel();
for(int i = 0; i < matrix.length; i++)
{
for(int j = 0; j < matrix[i].length; j++)
{
matrix[i][j] = new buildingObject(i * 100, j * 100, 1, p);
}
}
this.add(p, BorderLayout.NORTH);
this.pack();
this.setVisible(true);
}
// Variables declaration - do not modify
// End of variables declaration
}
但是每当我运行该程序时,标签都存在但不显示。我需要能够将标签放置在特定的 x 和 y 值处,所以我不相信我可以使用布局。我该怎么做才能显示我的标签?还是有我不知道的更好的方法来做到这一点?
最佳答案
I need to be able to place the labels at specific x and y values so I don't believe I can use a layout.
正确。
但是,您的代码存在问题,因为您不了解使用布局管理器的基础知识,并且您正在使用 IDE 生成代码。
在 initComponents()
方法中,您的 IDE 会生成代码:
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
所以这意味着您正在使用GroupLayout
。
在您使用的 initLayout()
方法中:
this.add(p, BorderLayout.NORTH);
因此,您假设布局管理器是一个 BorderLayout
,但事实并非如此。如果要将面板添加到框架中,则需要使用 GroupLayout
所需的所有约束。由于您没有使用正确的约束,因此面板永远不会显示,并且您将看不到添加到面板中的组件。
最后,默认情况下 JPanel 使用 FlowLayout,因此当您将 BuildObject 添加到面板时,它们将根据布局管理器的规则进行定位。
所以你真正需要做的是重新开始。我建议不要使用 IDE 生成 GUI 代码,而是手动创建 GUI,以便您可以在需要时控制布局管理器。
然后,对于保存 BuildObjects 的面板,您将需要使用空布局。然后,您将负责设置添加到面板的组件的大小
和位置
。
现在使用空布局通常不是一个好主意,因为 Swing 被设计为与布局管理器一起使用,因此 pack() 方法可以确定面板的首选大小并且滚动将正常工作。
因此,为了让生活更轻松,您可以使用Drag Layout 。它允许随机定位组件,但它将实现布局管理器的其他功能。
关于java-动态 JLabel 未显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47239481/