【问题标题】:Using multiple JPanels in a single JFrame在单个 JFrame 中使用多个 JPanel
【发布时间】:2013-07-17 23:13:05
【问题描述】:

我基本上一直在尝试通过使用 JFrame 并切换出 2 个 JPanel(一个用于菜单,一个用于实际游戏)来为游戏制作菜单。我正在尝试实现我能想到的最基本的格式,但似乎无法让它发挥作用。如果有人能解释代码有什么问题,我将不胜感激。

这是我的 JFrame、菜单面板和 ActionListener

package buttonMenu;

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

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

public class Skeleton extends JFrame implements ActionListener{

JPanel menu;
JButton button;

public Skeleton(){

setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(400, 400);
setVisible(true);

menu = new JPanel();
button = new JButton("button");

menu.setSize(400, 400);
menu.setBackground(Color.BLACK);
menu.setVisible(true);
menu.add(button);

button.setLocation(200, 200);
button.addActionListener(this);

add(menu, BorderLayout.CENTER);

}

public void actionPerformed(ActionEvent a){
    JPanel panel = Game.Game();
    this.remove(menu);
    this.add(panel);   
}

public static void main(String args[]){
    new Skeleton();
}
}

actionPerformed 调用在此类中创建的面板

package buttonMenu;
import java.awt.Color;
import javax.swing.JPanel;
public class Game{

public static JPanel Game(){
    JPanel panel = new JPanel();
    panel.setSize(400, 400);
    panel.setBackground(Color.WHITE);
    return panel;       
}

}

再次,如果有人能向我解释这段代码有什么问题,我将不胜感激。谢谢

【问题讨论】:

    标签: java swing jframe jpanel jbutton


    【解决方案1】:

    当添加/移除组件时,你需要revalidate父容器来强制它自己中继出来...

    public void actionPerformed(ActionEvent a){
        JPanel panel = Game.Game();
        this.remove(menu);
        this.add(panel);   
        this.revalidate();
    }
    

    更好的解决方案是使用 CardLayout 之类的东西

    查看How to use CardLayout了解更多详情

    ps- 我应该补充一下。您应该避免直接从JFrame 扩展,而是在基础组件上创建整个应用程序,例如JPanel。当您需要显示它时,创建一个 JFrame 实例并将应用程序组件添加到其中。这样,您的应用程序在部署和重用方面变得更加灵活

    【讨论】:

    • 感谢您的建议,我从未使用过重新验证,但它现在可以工作了。另外,感谢您的链接,看起来卡片布局是要走的路。
    【解决方案2】:

    使用 validate() 方法查看更改。

    public void actionPerformed(ActionEvent a){
        JPanel panel = Game.Game();
        this.remove(menu);
        this.add(panel);   
        this.validate();
    }
    

    【讨论】:

      【解决方案3】:

      我的代码有什么问题可能是一个模糊的问题,但我会整理一些要点:

      • extends JFrame:你并没有真正扩展 JFrame,你只是在使用一个,作为你的GUI的一部分。
      • 正如其他答案所提到的,您应该在添加/删除组件后revalidate()
      • menu.setVisible(true),通常不需要。
      • 也许没有,但我通常先构建我的所有界面(ie,创建和添加初始组件),然后才设置尺寸和可见性框架。
      • 您正在main 线程中运行所有代码; Swing 组件不是线程安全的。有关详细信息,请参阅 Concurrency in Swing
      • 我知道这是为了游戏,但你的面板中真的需要绝对定位吗?如果可能,请使用布局管理器(您的游戏面板除外,它可能只进行自定义绘制)。

      【讨论】:

      • 啊,很抱歉,我刚刚意识到我忘了指定我的代码在做什么。不过感谢您的建议,它现在正在工作。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-05-03
      • 1970-01-01
      • 2014-04-27
      • 1970-01-01
      • 2012-05-02
      • 2011-09-13
      • 2013-12-12
      相关资源
      最近更新 更多