前言

由于某些需要,需要进行 Java Swing 编程。但是在进行编程中,发现了一个很让人火大的事情,那就是给 JFrame 添加组件后,没有立即显示。你以为你程序有问题,各种查资料,发现没问题,都是这样的,然后在你骂娘的时候,你突然对窗体进行拉伸,你就发现组件又显示出来了。此时就各种冒火。那么这到底是什么鬼呢?其实就是程序语句顺序的问题,即:对 JFrame 主窗体的初始化等设置一定要放在程序最后面。

模拟场景

Main.java: [没问题的版本,仅有 3 个 JLabel]

/**
 - 程序入口
 - @author johnnie
 *
 */
public class Main{

    private static final int FRAME_WIDTH = 600;         
    private static final int FRAME_HEIGHT = 600;        

    private String title = "主界面";                       // 窗体标题

    private JPanel contentPanel;

    /**
     - 初始化控件
     */
    public void initViews () {

        contentPanel = new JPanel();                        // 创建一个中间容器对象
        contentPanel.setLayout(null);

        // 得到屏幕尺寸
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();     
        int screenWidth = screenSize.width;
        int screenHeight = screenSize.height;
        int width = (screenWidth - FRAME_WIDTH) / 2;        // x 轴位移
        int height = (screenHeight - FRAME_HEIGHT) / 2; // y 轴位移

        JFrame jf_main = new JFrame(this.title);
        jf_main.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        jf_main.setBounds(width, height, FRAME_WIDTH, FRAME_HEIGHT);
        jf_main.setResizable(false);                        // 去掉窗体最大化
        jf_main.setVisible(true);
        jf_main.setContentPane(contentPanel);               // 设置 JFrame 的内容面板

        JLabel jl_in = new JLabel("请选择pcap文件:");
        jl_in.setBounds(10, 10, 120, 35);
        JLabel jl_out = new JLabel("请选择输出目录:");
        jl_out.setBounds(10, 70, 120, 35);
        JLabel jl_status = new JLabel("程序运行状态:");
        jl_status.setBounds(10, 130, 120, 35);

        contentPanel.add(jl_in);
        contentPanel.add(jl_out);
        contentPanel.add(jl_status);

    }

    public Main(String title) {
        this.title = title;
    }

    public static void main(String[] args) {
        new Main("PcapAnalyzer").initViews();;
    }

}

[运行结果]

java不显示控件 javaswing组件不显示_java不显示控件

有问题的版本:[添加一个 JTextField 后,就开始傻逼了]

public void initViews () {

    // ... (略,和上面一样)

    JLabel jl_in = new JLabel("请选择pcap文件:");
    jl_in.setBounds(10, 10, 120, 35);
    JLabel jl_out = new JLabel("请选择输出目录:");
    jl_out.setBounds(10, 70, 120, 35);
    JLabel jl_status = new JLabel("程序运行状态:");
    jl_status.setBounds(10, 130, 120, 35);

    JTextField jtf = new JTextField();
    jtf.setBounds(10, 10, 100, 50);

    contentPanel.add(jl_in);
    contentPanel.add(jl_out);
    contentPanel.add(jl_status);
    contentPanel.add(jtf);

}

[运行结果]

java不显示控件 javaswing组件不显示_初始化_02


[去掉关闭窗口最大化后,拉伸窗体]

java不显示控件 javaswing组件不显示_java_03

看到这样,真是内心很郁闷,什么鬼?为毛会这样!!!为毛加了个 JTextField 后就没有立即显示了?那试试只有一个 JTextField 呢?如下

只有一个 JTextField 的测试

public class Test {

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        JPanel panel = new JPanel();
        panel.setLayout(null);
        frame.setContentPane(panel);
        frame.setBounds(100, 100, 200, 200);
        frame.setVisible(true);

        JTextField field = new JTextField();
        field.setSize(100, 10);
        panel.add(field);

    }

}

[运行结果]

java不显示控件 javaswing组件不显示_swing_04


[拉伸窗体]

java不显示控件 javaswing组件不显示_java不显示控件_05

还是一样的没有立即显示!真是日了,什么鬼?JFrame 添加的组件不能立即显示,还得拉伸窗体才会显示是为毛?忍着恶心烦躁,本着程序猿的干掉 bug 的态度,查资料。最后发现,窗体 JFrame 的语句,必须得放在最后面执行,只有这样才能不出现这种神经病的问题。

修改版 Main.java

public class Main{

    private static final int FRAME_WIDTH = 600;         
    private static final int FRAME_HEIGHT = 600;        

    private String title = "主界面";                       // 窗体标题

    private JPanel contentPanel;

    /**
     - 初始化控件
     */
    public void initViews () {

        contentPanel = new JPanel();                        // 创建一个中间容器对象
        contentPanel.setLayout(null);

        JLabel jl_in = new JLabel("请选择pcap文件:");
        jl_in.setBounds(10, 10, 120, 35);
        JLabel jl_out = new JLabel("请选择输出目录:");
        jl_out.setBounds(10, 70, 120, 35);
        JLabel jl_status = new JLabel("程序运行状态:");
        jl_status.setBounds(10, 130, 120, 35);

        JTextField jtf = new JTextField();
        jtf.setBounds(10, 10, 100, 50);


        contentPanel.add(jl_in);
        contentPanel.add(jl_out);
        contentPanel.add(jl_status);
        contentPanel.add(jtf);

        // 得到屏幕尺寸
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();     
        int screenWidth = screenSize.width;
        int screenHeight = screenSize.height;
        int width = (screenWidth - FRAME_WIDTH) / 2;        // x 轴位移
        int height = (screenHeight - FRAME_HEIGHT) / 2; // y 轴位移

        JFrame jf_main = new JFrame(this.title);
        jf_main.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        jf_main.setBounds(width, height, FRAME_WIDTH, FRAME_HEIGHT);
        jf_main.setResizable(false);                        // 去掉窗体最大化
        jf_main.pack();
        jf_main.setVisible(true);
        jf_main.setContentPane(contentPanel);               // 设置 JFrame 的内容面板

    }

    public Main(String title) {
        this.title = title;
    }

    public static void main(String[] args) {
        new Main("PcapAnalyzer").initViews();;
    }

}

[运行结果]

java不显示控件 javaswing组件不显示_swing_06


终于解决了,就这鸡毛的问题,恶心了我2个多小时,太心酸了!给自己鼓掌!!!