【问题标题】:Empty Java JFrame [duplicate]空 Java JFrame [重复]
【发布时间】:2024-01-08 02:14:01
【问题描述】:

感谢您提供有关 Frame 未显示原因的建议。我现在使用以下代码显示内容(在 main 方法的子类中,没有扩展任何内容,尽管具有 main 方法的类正在扩展 JPanel),但不正确:

case start:
    JPanel mapFrame = new JPanel();
    mapFrame.setPreferredSize(new Dimension(950, 950));
    mapFrame.setBackground(Color.CYAN);
    mapFrame.setVisible(true);
    mapFrame.add(new Main());

    JPanel statBar = new JPanel();
    statBar.setBackground(Color.BLACK);
    statBar.setPreferredSize(new Dimension(400, 950));

    JFrame fullBox = new JFrame();
    fullBox.getContentPane().setLayout(new BorderLayout());
    fullBox.setPreferredSize(new Dimension(1350, 950));

    fullBox.getContentPane().add(statBar, BorderLayout.EAST);
    fullBox.getContentPane().add(mapFrame, BorderLayout.WEST);
    fullBox.setResizable(true);
    fullBox.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    fullBox.setVisible(true);
    fullBox.pack();

以前,我有以下代码,而不是上面包含的代码(在 main 方法的子类中),它在显示背景图像和播放器时完美地工作,其位置随着按键输入而更新:

case start:
    JFrame mapFrame = new JFrame();
    mapFrame.pack();
    mapFrame.setSize(1350, 1000);
    mapFrame.setResizable(false);
    mapFrame.setLocationRelativeTo(null);
    mapFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);       
    mapFrame.add(new Main());
    mapFrame.setVisible(true);

我的背景和播放器的绘制方法如下(在扩展JPanel的类中):

public void paint(Graphics g){
    super.paint(g);
    Graphics2D g2d = (Graphics2D) g;
    g2d.drawImage(getBackgroundImage(), 0, 0, this);
    ((Penguin)player).draw(g2d);

public BufferedImage getBackgroundImage(){
    ImageIcon i = new ImageIcon(getClass().getResource(background));
    Image image = i.getImage();
    BufferedImage scaledImage = new BufferedImage(950, 950, BufferedImage.TYPE_INT_ARGB);
    Graphics2D g2 = scaledImage.createGraphics();
    g2.drawImage(image, 0, 0, 950, 950, null);
    g2.dispose();
    return scaledImage;
}

fullBox Frame 需要不断地重新绘制,因为 mapFrame 包含玩家角色和要收集的点数,而 statBar 稍后将包含也会更新时间和点数的文本。我尝试删除 mapFrame 的背景颜色,它只是 JPanel 的默认颜色。当我包含颜色时,有一个小白框固定在青色上方的位置 - 有点奇怪。

screenshot of execution of current code

【问题讨论】:

  • 在将所有组件添加到框架后,最后调用 setVisible 开始
  • 另外,不需要扩展JFrame,因为您没有在任何地方使用JFrame(至少在显示的代码中)。另请参阅The use of multiple JFrames, Good / Bad practice? 普遍共识说这很糟糕。为了尽快获得更好的帮助,请发布有效的minimal reproducible example
  • 在 JFrames 上,当您向它们添加可见组件时,您应该通过内容窗格来完成,例如fullBox.getContentPane().add(mapFrame, BorderLayout.WEST);
  • @Brianbcr666Ray 自 Java 以来不是“必需的”,是 5 还是 6? JFrame#add 自动将呼叫转发到内容窗格,这两种方式都不会产生太大影响,但我很懒,我需要做的打字越少越好:P
  • 根据我对您的代码的了解,我建议您也阅读一下How to Use CardLayout,它将消除对多帧的需求,并有助于使更新变得更容易

标签: java swing jframe jpanel


【解决方案1】:
class MenuActionListener implements ActionListener {
    @Override
    public void actionPerformed(ActionEvent e) {

        switch (e.getActionCommand()) {
            case startGame:
                JFrame fullBox = new JFrame();
                fullBox.getContentPane().setLayout(new BorderLayout());
                JPanel mapFrame = new JPanel();
                mapFrame.setSize(950, 950);
                mapFrame.setVisible(true);
                mapFrame.add(new Main());
                fullBox.getContentPane().add(mapFrame, BorderLayout.WEST);
                JPanel statBar = new JPanel();
                statBar.setSize(400, 950);

                fullBox.getContentPane().add(statBar, BorderLayout.EAST);

                fullBox.setResizable(false);
                fullBox.setLocationRelativeTo(null);
                fullBox.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                fullBox.pack();
                fullBox.setVisible(true);

                break;
            case loadLog:
                System.out.println("load game");
                break;
            case aboutGame:
                System.out.println("about game");
                break;
            case exitGame:
                System.out.println("exit game");
                System.exit(0);

【讨论】:

  • 谢谢!它现在显示两个面板,但它们没有被正确绘制..