java-动态 JLabel 未显示

标签 java swing user-interface

我正在尝试创建一个程序,使学校项目的平面图创建变得容易。用户可以输入建筑物的尺寸,然后将其描绘为标签网格,通过单击标签可以将其变成墙壁、 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/

相关文章:

java - 非法参数异常 : Unsupported ciphersuite

java - Graphics2D 不会从类变量中提取值

iphone - 操作表的最后一个按钮没有被点击

android - 以编程方式更改 TextInputLayout 提示颜色

java - 如何除以两个 float 并得到一个整数

java - 将不同数据集概括为坐标系以显示为图形的算法

java - 解码Android的反编译源代码

Java swing JTable 在使用 JScrollPane 时不显示滚动条

Java:如何从文件中获取缩略图

java - 如何从具有 GridBagLayout 布局的 JPanel 中获取位于特定 gridx、gridy 中的组件?