Java jframe 添加 canvas 和 jpanel

Java jframe adding canvas and jpanel to it

下面的 class 创建一个 window/frame.

public class Window {

private int width, height;
private JFrame frame;
private Canvas canvas;
private String title;
private JButton button;
private JPanel panel;

public Window(String title){

    System.out.println("Initialization Window...");

    this.title = title;

    width = Reference.width;
    height = Reference.height;

    button = new JButton("cool button");

    CreateWindow();
}

private void CreateWindow(){

    frame = new JFrame(title);
    frame.setSize(width, height);
    frame.setResizable(false);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);

    panel = new JPanel();
    panel.add(button);

    canvas = new Canvas();
    canvas.setPreferredSize(new Dimension(width, height));
    canvas.setMaximumSize(new Dimension(width, height));
    canvas.setMinimumSize(new Dimension(width, height));
    canvas.setFocusable(false);

    frame.add(canvas);
    frame.add(panel);//my problem is in this line
    frame.pack();
}

我在 运行 时添加到框架 canvas 和 jpanel 中。框架的大小设置为非常小,我制作的按钮大小。但删除 "frame.add(panel) 会使它恢复正常大小。我错过了什么吗?

以防我使用 jpanel 和 canvas。好吧,我正在使用 canvas,因为我使用 bufferstategy 来绘制图形,我还需要 jpanel 来添加按钮和其他东西。

  1. 当您以默认方式将两个组件添加到任何使用 BorderLayout 的容器(例如 JFrame 的容器)时,默认情况下都会将两个组件添加到 BorderLayout.CENTER 位置并且第二个组件覆盖第一个组件,所以这里JPanel 覆盖 Canvas,由于 Canvas 未显示,因此忽略其首选大小。
  2. 相反,您需要弄清楚组件之间的相对位置,特别是 JPanel、Canvas 以及它们在 JFrame 中的放置方式,然后使用布局管理器来确定它们的位置优势,而不是像您的代码当前那样与布局管理器作斗争。
  3. 无论你做什么,都要避免像瘟疫一样的 null 布局。
  4. 混合使用 AWT 和 Swing 组件通常不是一个好主意。您绝对肯定需要使用Canvas吗?默认情况下,JPanels 是双缓冲的,如果这是您的目标,通常可以平滑任何动画。

我必须说,如果您只是扩展 JFrame 会更简单,除非您想扩展其他内容。 您需要了解,为了代码的可读性和可重用性,您需要遵循常规 Java 规则和最佳实践。

@Hovercraft Full Of Eels 上面已经解释了你需要的一切。我在这里所做的只是以身作则,让您纠正错误,因此无需重复他所说的话。 FlowLayout 可能是 Java 中最简单和最简单的布局管理器,但与 GridLayoutGrdiBagLayout 相比,它并不是那么强大。 这是代码:

public class Window extends JFrame {

    private int width, height;
    private Canvas canvas;
    private String title;
    private JButton button;
    private JPanel panel;

    public Window(String title){
        super( title );
        System.out.println("Initialization Window...");

        this.title = title;
        setLayout( new FlowLayout() );

        //width = Reference.width;
        //height = Reference.height;

        button = new JButton("cool button");

        createWindow();
    }

    private void createWindow(){


        setSize(width, height);
        setResizable(false);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        setVisible(true);

        panel = new JPanel();
        panel.add(button);

        canvas = new Canvas();
        canvas.setPreferredSize(new Dimension(200, 200));
        canvas.setMaximumSize(new Dimension(400, 400));
        canvas.setMinimumSize(new Dimension(200, 200));
        canvas.setFocusable(false);

        add(canvas);
        add(panel);//my problem is in this line
        pack();
    }

}