java - 为什么我的内容 Pane 不会显示在 JFrame 上?

标签 java swing jframe jpanel

这是我的图形类,但是当我创建 JPanel 并将其添加为内容 Pane 时,什么也没有显示。我已经做了很多测试来查看我的内容 Pane 是否可见,但它仍然不会显示。

import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;


public class GraphicsMain extends JFrame{
    public static final long serialVersionUID = 7610350056926018727L;
    static GraphicsMain frame = new GraphicsMain();
    static final int WIDTH = 1024, HEIGHT = 768;
    static Listener listener = new Listener();

    public static void init() {
        createGUI();
    }

    public static void createGUI() {
        frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        frame.setFocusable(true);
        frame.setLayout(null);
        frame.setResizable(false);
        frame.setSize(WIDTH, HEIGHT);
        frame.setTitle("Game of Life");
        frame.setContentPane(frame.createMainPanel());
        frame.setVisible(true);
    }

    public JPanel createMainPanel() {
        JPanel totalGUI = new JPanel();
        totalGUI.setSize(HEIGHT, WIDTH);
        totalGUI.setBackground(Color.red);
        totalGUI.setLayout(null);

        JPanel buttonPanel = createButtonPanel();

        totalGUI.add(buttonPanel);
        totalGUI.setVisible(true);
        System.out.println("Is returning!");
        return totalGUI;
    }

    public JPanel createButtonPanel() {
        JPanel buttonPanel = new JPanel();
        buttonPanel.setSize(WIDTH, HEIGHT);
        buttonPanel.setLocation(0, 0);

        Font buttonFont = new Font("Button Font", Font.PLAIN, 12);
        JButton goButton = createButton("Go", WIDTH/16, HEIGHT/12, 10, 10, listener, buttonFont, Color.black);
        buttonPanel.add(goButton);
        JButton clearButton = createButton("Clear", WIDTH/16, HEIGHT/12, 10 + HEIGHT/12, 10, listener, buttonFont, Color.black);
        buttonPanel.add(clearButton);
        JButton exitButton = createButton("Exit", WIDTH/16, HEIGHT/12, 10 + 2*HEIGHT/12, 10, listener, buttonFont, Color.black);
        buttonPanel.add(exitButton);
        return buttonPanel;
    }

    public JButton createButton(String text, int width, int height, int x, int y, ActionListener listener, Font font, Color color) {
        JButton button = new JButton(text);
        button.setSize(width, height);
        button.setLocation(x, y);
        button.addActionListener(listener);
        button.setFont(font);
        button.setForeground(Color.red);
        return button;
    }

}

这个类被调用

import javax.swing.SwingUtilities;


public class GameOfLifeMain {
    static boolean running = true;
    static int UPS = 60;
    static GameOfLifeMain main = new GameOfLifeMain();

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                main.init();
                long startTime = System.nanoTime();
                double ns = 1000000000.0 / UPS;
                double delta = 0;

                long secondTimer = System.nanoTime();
                while(running) {
                    long now = System.nanoTime();
                    delta += (now - startTime) / ns;
                    startTime = now;
                    while(delta >= 1) {
                    main.update();
                        delta--;
                    }
                    main.render();

                    if(System.nanoTime() - secondTimer > 1000000000) {
                        secondTimer += 1000000000;
                    }
                }
            }
        });
    }

    public void init() {
        GraphicsMain.init();
    }

    public void update() {
    }

    public void render() {
        //GraphicsMain.render();
    }

}

最佳答案

你的问题(至少)有两个:

  • 正如@Radiodef 敏锐地指出的那样,您正在 Swing 事件线程上调用长时间运行的循环。由于该线程完全负责 GUI 的渲染以及与用户的交互,因此您的 GUI 会完全卡住。
  • 您正在使用空布局,这使您完全负责使用组件添加到空布局的所有组件的位置和大小。

我建议:

  • 正如 @Radiodef 建议的那样,在后台线程(例如 SwingWorker)中执行长时间运行的循环。这将使 GUI 和后台进程之间的交互更加容易。他的链接很好:Concurrency in Swing .
  • 使用嵌套的 JPanel,每个 JPanel 都使用自己的布局来实现所需的布局,该布局可以在任何平台和任何视频卡设置上良好运行。
  • 最好重写您的绘图 JPanels getPreferredSize(...) 方法以使其尺寸正确。
  • 通过 setOpaque(true) 将 JPanel 设置为不透明不会有帮助,因为默认情况下 JPanel 已经是不透明的。
<小时/>

编辑
我纠正了 Jan Bodnar 的最后一点:

"However, the default value for this property on most standard JComponent subclasses (such as JButton and JTree) is look-and-feel dependent." For example, the JPanel of the GTK look and feel is not opaque by default.

谢谢,简

关于java - 为什么我的内容 Pane 不会显示在 JFrame 上?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20671736/

相关文章:

java - 合并过程数组越界

java - 可以在构造函数方法参数中设置类变量吗?

java - 我已经重写了paintComponent(),那么为什么我的形状没有出现呢?

java - 有没有办法在不重新打开的情况下去除框架装饰?

java - 如何为 @MappedSuperclass 实现 Spring Data 存储库

java - 远程 JMS 队列的客户端

java - 在继续代码中的下一项之前,有没有一种方法可以解决自身问题

java - JTable 中 JEditorPane 中的超链接

java - JFrame 的 setIconImages() 方法使用哪些图标大小?

java - 只有一个 Activity 的新 jframe