在模式中动态添加JLabel但最后一个不能正常工作

时间:2015-06-26 12:27:01

标签: java swing jframe jlabel

我正在尝试以模式创建40个动态 JLabel ,这工作得非常好,但最后 JLabel 没有根据到模式。谁能告诉我我做错了什么?

这是我到目前为止所做的:

public class Booking2 {

    public static void main(String[] args) {
        JFrame jf = new JFrame();
        jf.setVisible(true);
        jf.setDefaultCloseOperation(jf.EXIT_ON_CLOSE);

        jf.setSize(700, 400);
        jf.setLocationRelativeTo(null);
        int c1 = 40;
        int count = 0, count2 = 0, count3 = 0, count4 = 0, x;
        JLabel[] jl = new JLabel[c1];

        for (int i = 0; i <= c1 - 1; i++) {
            jl[i] = new JLabel();

            if (i <= 9) {
                x = 25 * count;
                jl[i].setBounds(x, 50, 20, 30);
                count++;
            }
            if (i >= 10 && i <= 19) {
                x = 25 * count2;
                jl[i].setBounds(x, 80, 20, 20);
                count2++;
            }
            if (i >= 20 && i <= 29) {
                x = 25 * count3;
                jl[i].setBounds(x, 110, 20, 20);
                count3++;
            }
            if (i >= 30 && i <= 39) {
                x = 25 * count4;
                jl[i].setBounds(x, 130, 20, 20);
                count4++;
            }
            // jl[i].setIcon(new
            // ImageIcon(Booking2.class.getResource("booked.png")));
            jl[i].setText("O");
            jf.add(jl[i]);
        }
    }
}

enter image description here

2 个答案:

答案 0 :(得分:5)

您使用的是绝对定位/空布局,但尚未将布局设置为null。默认的jframe布局是边框布局。

添加此行

jf.setLayout(null);

并在添加所有组件后调用jframe的revalidate()repaint()方法。

例如

public class Booking2 {

    public static void main(String[] args) {
        JFrame jf = new JFrame();
        jf.setVisible(true);
        jf.setDefaultCloseOperation(jf.EXIT_ON_CLOSE);

        jf.setLayout(null); // this is important 

        jf.setSize(700, 400);

        int c1 = 40;
        int count = 0, count2 = 0, count3 = 0, count4 = 0, x;
        JLabel[] jl = new JLabel[c1];

        for (int i = 0; i <= c1 - 1; i++) {
            jl[i] = new JLabel();

            if (i <= 9) {
                x = 25 * count;
                jl[i].setBounds(x, 50, 20, 20);
                count++;
            }
            if (i >= 10 && i <= 19) {
                x = 25 * count2;
                jl[i].setBounds(x, 80, 20, 20);
                count2++;
            }
            if (i >= 20 && i <= 29) {
                x = 25 * count3;
                jl[i].setBounds(x, 110, 20, 20);
                count3++;
            }
            if (i >= 30 && i <= 39) {
                x = 25 * count4;
                jl[i].setBounds(x, 130, 20, 20);
                count4++;
            }
            //jl[i].setIcon(new ImageIcon(Booking2.class.getResource("booked.png")));
            jl[i].setText("O");
            jf.add(jl[i]);
        }
         jf.revalidate();
        jf.setVisible(true);
    }

}

输出

enter image description here

注意

1)你应该避免使用null布局。使用布局GRID布局似乎对你的情况有好处。如果这是一种游戏/动画你应该看看这些例子https://www3.ntu.edu.sg/home/ehchua/programming/java/J8a_GameIntro-BouncingBalls.html。您可以使用paintComponent()方法在jpanel中绘制此网格,这是有效的,您可以绘制任何类型的模式。如果您创建一个大网格,例如100 * 100使用jlables它不是很好

2)最好将组件添加到jpanel而不是直接添加到jframe。你可以使用setContentPane()方法

答案 1 :(得分:4)

使用布局会更好,例如GridLayout

import javax.swing.*;
import java.awt.*;

public class Booking2 {

    public static void main(String[] args) {
        JFrame jf = new JFrame();
        jf.setVisible(true);
        jf.setDefaultCloseOperation(jf.EXIT_ON_CLOSE);
        jf.setLayout(new GridLayout(4,10));
        jf.setSize(700, 400);
        jf.setLocationRelativeTo(null);
        int c1=40;
        JLabel[] jl = new JLabel[c1];

        for(int i=c1-1; i>=0; i--){
            jl[i]=new JLabel();
            jl[i].setText("O");
            jf.add(jl[i]);
        }
    }
}

这是更优雅的方式。但是,如果您决定使用setBound(),则应将JFrame(或其他具有JLabels}布局的容器设置为null:

jf.setLayout(null);

这将允许在容器内进行绝对定位。似乎默认JFrames BorderLoyout会扭曲您的setBounds()设置。

然而,通常不建议使用null布局,并且它被认为是一种糟糕的编程习惯。最好使用LayoutMenagers!