简体   繁体   English

在单个JFrame中使用多个JPanel

[英]Using multiple JPanels in a single JFrame

I've basically been trying to make a menu for a game by using a JFrame and switching out 2 JPanels (one for the menu and one for the actual game). 我基本上一直在尝试通过使用JFrame并切换出2个JPanels(一个用于菜单,一个用于实际游戏)来制作游戏菜单。 I'm trying to implement the most basic format I can think of but can't seem to get it to work. 我正在尝试实现我能想到的最基本的格式,但似乎无法使其正常工作。 If anybody could explain what's wrong with the code I would appreciate it. 如果有人可以解释代码有什么问题,我将不胜感激。

Here's my JFrame, menu panel, and ActionListener 这是我的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();
}
}

The actionPerformed calls the panel created in this class 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;       
}

}

Again, if anybody could explain to me what's wrong with this code I would appreciate it. 同样,如果有人可以向我解释这段代码有什么问题,我将不胜感激。 Thanks 谢谢

When adding/removing components, you will need to revalidate the parent container to force it to relay itself out... 添加/删除组件时,您将需要revalidate父容器以强制其自身中继出去...

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

A better solution would be to use something like a CardLayout 更好的解决方案是使用CardLayout类的东西

Take a look at How to use CardLayout for more details 看看如何使用CardLayout了解更多详细信息

ps- I should add. ps-我应该补充。 You should avoid extending directly from JFrame , instead create your application entire on a base component, like a JPanel . 您应该避免直接从JFrame扩展,而应在整个基础组件(如JPanel上创建应用程序。 When you need to display it, create an instance of JFrame and add the application component to it. 当需要显示它时,创建一个JFrame实例并将应用程序组件添加到其中。 This way your application becomes more flexible in terms of deployment and re-use 这样,您的应用程序在部署和重用方面变得更加灵活

Use validate() method to see the changes. 使用validate()方法查看更改。

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

What's wrong with my code may be kind of a vague question, but I'll sort some points: 我的代码有什么问题,可能是一个模糊的问题,但我会说明一些要点:

  • extends JFrame : You're not really extending JFrame , you're just using one, as part of your GUI. extends JFrame :您并不是真正地扩展 JFrame ,您只是在使用它作为GUI的一部分。
  • As other answers mention, you should revalidate() after adding/removing components. 如其他答案所述,您应该在添加/删除组件后revalidate()
  • menu.setVisible(true) , usually this isn't needed. menu.setVisible(true) ,通常不需要。
  • Maybe not wrong , but I usually build all my interface first ( ie , creating and adding the initial components), and only then set the dimensions and visibility of the frame. 也许没有 ,但是我通常会首先构建所有接口( 创建和添加初始组件),然后才设置框架的尺寸和可见性。
  • You're running all that code in the main thread; 您正在main线程中运行所有这些代码。 Swing components aren't thread-safe. Swing组件不是线程安全的。 See Concurrency in Swing for more information on that. 有关更多信息,请参见Swing中的并发
  • I know this is for a game, but is absolute positioning in your panels really needed? 我知道这是针对游戏的,但是否确实需要在面板中绝对定位? Use Layout managers if possible (with an exception for your game panel, which will probably do only custom painting). 如果可能,请使用布局管理器(游戏面板例外,该面板可能仅会进行自定义绘制)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM