- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
问题可能不正确,但我不知道如何正确提问。对此我感到很抱歉。
问题在这里:
我的 JFrame 将 CardLayout
作为布局管理器
。我有三个 JPanel
,我在它们之间切换。一切都很好,直到我不得不将 2 个 JPanel 添加到其中一个中。现在,我的一个 JPanel
应该包含另外两个 JPanel
。我在某处读到这是可能的。所以这个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
和我的旧游戏面板
)
现在的样子:
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);
}
});
}
}
游戏 Controller
:
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
:
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);
}
}
游戏面板
:
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();
}
}
}
}
界面面板
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);
}
}
菜单面板
:
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);
}
}
向上倾斜
当我启动这个时,我只有黑框。我怎样才能解决这个问题?我做错了什么?
提前致谢。
感谢您的编辑。
最佳答案
您的 Controller 定义 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
做了很多很容易被破坏的工作,并且其他子组件在重新绘制时可能会导致问题......关于java - 如何将 BorderLayout 放入 CardLayout 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23864045/
来自 BorderLayout javadoc: A border layout lays out a container, arranging and resizing its components
我试图在 BorderLayout 的中心添加一个 GridBagLayout,但是当我将它添加到中心时,它没有出现。 尽管如此,如果我将它放在 BorderLayout 中的另一个位置,它会正确显示
我想制作一个带有 BorderLayout 的程序,其中中心和东部在图形上是分开的。我尝试了以下操作,但不幸的是分隔符位于 JFrame 的左侧,而不是在 centerPanel 和 rightPan
我试图将两个 JButton 彼此相邻放置在 JFrame 的中心,当 JFrame 已重新调整大小。 为此,我将两个按钮放在一个带有 FlowLayout 的面板中,然后将其放置在一个带有中心 Bo
我正在尝试设置披萨订单表单的框架,但在使用 orderPanel 和 ButtonPanel 时遇到问题。我可以让其中之一出现,但不能同时出现?在我发布的当前代码中,显示了按钮,但未显示文本框/ord
我正在从事一个计算机科学项目,我遇到了一些边框布局问题:这是我的配置(简化) public class MainPanel extends JPanel{ JSplitPane Pcenter
我决定编写一个小型 Java 程序来试验 BorderLayout,因为我正在开发一个 Java 游戏,我需要同时将 2 个对象放置在一个 JFrame 中,我问的每个人都说我需要 BorderLay
我一直在尝试在这个的死点制作一个 2x2 网格,但我做不到。网格要么会覆盖其余部分,要么会适合,但我只能看到最后一个按钮。 import javax.swing.*; import java.awt.
我正在编写一个程序,该程序旨在使用在窗口的西侧和东侧有两个按钮的 BorderLayout。不知怎的,中心有一个很大的差距。有什么方法可以消除这个间隙并使两个按钮彼此相切吗?下面我附上了我的代码。如有
我正在制作一个标题栏,并将标题放在左侧,将两个按钮放在右侧。但如果我对两个按钮都使用 BorderLayout.EAST,则只会显示最后一个按钮。我可以让两者都可见吗?我尝试使用 JPanel,但它会
我分别在 MouseEnter 和 MouseExit 上添加和删除 JButton。这工作正常,但是当按钮添加到面板时,它出现在右上角,而不是指定的 BorderLayout.SOUTH 位置。 框
我正在尝试创建一个可以在其中绘画的 Canvas ,以及一个将 Canvas 重置为空状态的按钮。然而,使用 BorderLayout 我的按钮会被复制,第二个按钮是第一个按钮的图像副本,但看起来仍然
我很难弄清楚为什么这个边框布局仍然像流布局一样...... 我先尝试了这个: JPanel canvas = new JPanel(new BorderLayout()); add(canvas);
我是 Java GUI 的新手,目前正在致力于创建微波 GUI。我正在尝试将面板放置在面板中,但它并没有真正按照我认为的那样工作。我正在使用 BorderLayout,基本上将一个面板放入 Borde
我尝试做以下事情: 使用 BorderLayout 将组件添加到 JFrame 向 JFrame 添加另一个组件 我希望新组件能够“覆盖”旧组件,因为我使用的是 BorderLayout。如果我在调用
我有如下代码: public static void main(String[] args) { JFrame f = new BorderTest(); JPanel p = new
据我了解,将组件添加到 BorderLayout 时,它们会占据整个隔间的大小。将 panel1 添加到 contentPane 的北部时,似乎是下面的情况。但是,当我随后将 panel2 放在 pa
我在使用 BorderLayout 时遇到问题,但首先,这是我的 GUI 设置: 如您所见,我的 JFrame 中有 3 个不同的组件。添加 JMenu 和 JList 效果很好。但是我的 JPane
我的问题是: 如何将 JPanel 添加到东南部的 BorderLayout? 这是我的按钮组: buttonsPanel = new JPanel(); buttonsPanel.setLayout
我想要一个 JFrame,在左侧和右侧有一个黑色边框,宽度为 withfOfJFrame/10。 现在,我的尝试看起来像这样: JFrame f = new JFrame(); f.setSize(8
我是一名优秀的程序员,十分优秀!