问题可能不正确,但我不知道如何正确询问。对不起,我很抱歉。
问题在于:
我的JFrame CardLayout
为layout manager
。
我有三个JPanel
&我在它们之间切换。一切都很好,直到我不得不将2 JPanel
加入其中一个。现在我的JPanel
之一应该包含另外两个JPanel
&#39}。我在某处读到它是可行的。因此JPanel
应该有BorderLayout
。它应该如何:
以下是我之前的事情:
我的JFrame
课程:
public class JavaGame2 extends JFrame {
public JavaGame2(){
CardLayout layout = new CardLayout();
setLayout(layout);
GameController controller = new CardLayoutGameController(getContentPane(), layout);
gamePanel = new GamePanel(controller);
menuPanel = new MenuPanel(controller);
lvlPanel = new LvlEndPanel(controller);
add(gamePanel, CardLayoutGameController.GAME_PANEL);
add(menuPanel, CardLayoutGameController.MENU_PANEL);
add(lvlPanel, CardLayoutGameController.LEVEL_PANEL);
controller.showMenu();
}
CardLayoutGameController
的 JPanel
:
public class CardLayoutGameController implements GameController {
public static final String GAME_PANEL = "GamePanel";
public static final String MENU_PANEL = "MenuPanel";
public static final String LEVEL_PANEL = "LvlPanel";
private Container container;
private CardLayout cardLayout;
public CardLayoutGameController(Container parent, CardLayout layout) {
container = parent;
cardLayout = layout;
}
@Override
public void showMenu() {
cardLayout.show(container, MENU_PANEL);
}
@Override
public void showGame() {
cardLayout.show(container, GAME_PANEL);
}
@Override
public void showEndLvl(){
cardLayout.show(container, LEVEL_PANEL);
}
}
然后我添加了两个JPanel
类InterfacePanel
和GameMainPanel
(应该包含此InterfacePanel
和我的旧GamePanel
)
现在的样子:
UPD 可运行的示例:
可运行的课程:
public class Mcve extends JFrame {
private GamePanel gamePanel;
private LvlEndPanel lvlPanel;
private GameMainPanel gameMainPanel;
Mcve(){
CardLayout layout = new CardLayout();
setLayout(layout);
GameController controller = new CardLayoutGameController(getContentPane(), layout);
gamePanel = new GamePanel(controller);
lvlPanel = new LvlEndPanel(controller);
gameMainPanel = new GameMainPanel(controller,this.getContentPane());
add(gamePanel, CardLayoutGameController.GAME_PANEL);
add(lvlPanel, CardLayoutGameController.LEVEL_PANEL);
add(gameMainPanel, CardLayoutGameController.GAME_MAIN_PANEL);
controller.showMenu();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setLocationRelativeTo(null);
setTitle("JavaGame2");
setResizable(false);
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame jgame = new Mcve();
jgame.setVisible(true);
}
});
}
}
GameController
:
public interface GameController {
public void showMenu();
public void showGame();
public void showEndLvl();
}
CardLayoutGameController
:
public class CardLayoutGameController implements GameController {
public static final String MENU_PANEL = "MenuPanel";
public static final String LEVEL_PANEL = "LvlPanel";
public static final String GAME_MAIN_PANEL = "GameMainPanel";
private Container container;
private CardLayout cardLayout;
public CardLayoutGameController(Container parent, CardLayout layout) {
container = parent;
cardLayout = layout;
}
@Override
public void showMenu() {
cardLayout.show(container, MENU_PANEL);
}
@Override
public void showGame() {
cardLayout.show(container, GAME_MAIN_PANEL);
}
@Override
public void showEndLvl(){
cardLayout.show(container, LEVEL_PANEL);
}
}
GameMainPanel
- 包括2 JPanel
' s:
public class GameMainPanel extends JPanel {
private Container container;
private GameController controller;
private BorderLayout layout;
private GamePanel gamePanel;
private InterfacePanel interfacePanel;
GameMainPanel(GameController contrl,Container parent){
controller = contrl;
container = parent;
setFocusable(true);
setBackground(Color.WHITE);
getPreferredSize();
gamePanel = new GamePanel(contrl);
interfacePanel = new InterfacePanel(contrl);
layout = new BorderLayout();
setLayout(layout);
add(gamePanel, BorderLayout.LINE_START);
add(interfacePanel, BorderLayout.LINE_END);
addComponentListener(new ComponentAdapter() {
public void componentShown(ComponentEvent e) {
requestFocusInWindow();
}
});
}
@Override
public void addNotify() {
super.addNotify();
requestFocusInWindow();
}
public void paint(Graphics g) {
super.paint(g);
}
public Dimension getPreferredSize() {
return new Dimension(800, 600);
}
}
GamePanel
:
public class GamePanel extends JPanel {
private GameController controller;
public GamePanel (GameController contrl){
controller = contrl;
addKeyListener(new GameAdapter(contrl));
setFocusable(true);
setBackground(Color.BLACK);
getPreferredSize();
addComponentListener(new ComponentAdapter() {
public void componentShown(ComponentEvent e) {
requestFocusInWindow();
}
});
}
@Override
public void addNotify() {
super.addNotify();
requestFocusInWindow();
}
public Dimension getPreferredSize() {
return new Dimension(650, 600);
}
@Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D)g;
Font small = new Font("Helvetica", Font.BOLD, 24);
FontMetrics metr = this.getFontMetrics(small);
g.setColor(Color.GREEN);
g.setFont(small);
g.drawString("game",300,300);
}
private class GameAdapter extends KeyAdapter{
private GameController controller;
GameAdapter(GameController contrl){
controller = contrl;
}
public void keyPressed(KeyEvent e) {
if ((e.getKeyCode() == KeyEvent.VK_ENTER)) {
controller.showEndLvl();
}
}
}
}
InterfacePanel
public class InterfacePanel extends JPanel {
private GameController controller;
InterfacePanel(GameController contrl){
setFocusable(true);
setBackground(Color.WHITE);
getPreferredSize();
setSize(150,600);
addComponentListener(new ComponentAdapter() {
public void componentShown(ComponentEvent e) {
requestFocusInWindow();
}
});
}
@Override
public void addNotify() {
super.addNotify();
requestFocusInWindow();
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D)g;
Font small = new Font("Helvetica", Font.BOLD, 24);
FontMetrics metr = this.getFontMetrics(small);
g.setColor(Color.GREEN);
g.setFont(small);
g.drawString("interface",10,300);
}
public Dimension getPreferredSize() {
return new Dimension(150, 600);
}
}
LvlEndPanel
:
public class LvlEndPanel extends JPanel{
private GameController controller;
public LvlEndPanel(GameController contrl){
controller = contrl;
setFocusable(true);
setBackground(Color.BLACK);
getPreferredSize();
addComponentListener(new ComponentAdapter() {
public void componentShown(ComponentEvent e) {
requestFocusInWindow();
}
});
addKeyListener(new KeyListener() {
@Override
public void keyPressed(KeyEvent e) {
if ((e.getKeyCode() == KeyEvent.VK_ENTER)) {
controller.showMenu();
}
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
}
});
}
@Override
public void addNotify(){
super.addNotify();
requestFocusInWindow();
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D)g;
Font small = new Font("Helvetica", Font.BOLD, 24);
FontMetrics metr = this.getFontMetrics(small);
g.setColor(Color.GREEN);
g.setFont(small);
g.drawString("Level Panel",300,300);
}
public Dimension getPreferredSize() {
return new Dimension(800, 600);
}
}
MenuPanel
:
public class MenuPanel extends JPanel{
private GameController controller;
public MenuPanel(GameController contrl){
setFocusable(true);
setBackground(Color.WHITE);
getPreferredSize();
controller = contrl;
addComponentListener(new ComponentAdapter() {
public void componentShown(ComponentEvent e) {
requestFocusInWindow();
}
});
addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
if ((e.getKeyCode() == KeyEvent.VK_ENTER)) {
controller.showGame();
}
}
@Override
public void keyReleased(KeyEvent e) {
}
});
}
@Override
public void addNotify() {
super.addNotify();
requestFocusInWindow();
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D)g;
Font small = new Font("Helvetica", Font.BOLD, 24);
FontMetrics metr = this.getFontMetrics(small);
g.setColor(Color.GREEN);
g.setFont(small);
g.drawString("Game Menu", 300,300);
}
public Dimension getPreferredSize() {
return new Dimension(800, 600);
}
}
updend
当我发布这个时,我只有黑框。我怎样才能解决这个问题?我做错了什么?
提前致谢。
感谢您的编辑。
答案 0 :(得分:1)
您是控制器将showMenu
定义为
public void showMenu() {
cardLayout.show(container, MENU_PANEL);
}
但是你永远不会添加名称为MENU_PANEL
add(gamePanel, CardLayoutGameController.GAME_PANEL);
add(lvlPanel, CardLayoutGameController.LEVEL_PANEL);
add(gameMainPanel, CardLayoutGameController.GAME_MAIN_PANEL);
将用于gameMainPanel
的名称更改为MENU_PANEL
或将showMenu
更改为使用GAME_MAIN_PANEL
而不是
根据示例代码更新
您的布局实际上没有任何问题,(主要)问题是您的MenuPanel
paint
方法。在可能的情况下,您应该避免在paint
方法中加载字体,加载字体的过程可能非常耗时,这会阻止您的面板及时绘制。
相反,可以在构造函数中预加载字体,然后在绘制时应用它,例如......
public class MenuPanel extends JPanel {
//...
public MenuPanel(GameController contrl) {
//...
Font small = new Font("Helvetica", Font.BOLD, 24);
setFont(small);
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g.setFont(getFont());
FontMetrics metr = g.getFontMetrics();
g.setColor(Color.GREEN);
g.drawString("Game Menu", 300, 300);
}
}
这适用于LvlEndPanel
,InterfacePanel
和GamePanel
......
旁注
addNotify
将不再按您配置的方式工作,因为组件只添加一次,而您应该依赖ComponentListener
(您是)。更好的解决方案是使用the key bindings API,它可以帮助您克服KeyListener
的焦点限制。paintComponent
而不是paint
。 paint
做了很多很容易被破坏的工作,而其他子组件在重新绘制时会引起问题......