[英]JButton doesn't show up in JFrame
I'm currently working on a schoolproject, where I have to code the game snake. 我目前正在做一个学校项目,必须在其中编写游戏蛇的代码。 Now I`m finished with the biggest part and tryed to make the game menue.
现在,我完成了最大的部分,并尝试制作游戏菜单。 I tryed to place a JButton for starting the game (startPlay).
我试图放置一个JButton来启动游戏(startPlay)。 However, the button won't show up and I can't figure out why.
但是,该按钮不会显示,我也不知道为什么。 Can someone help?
有人可以帮忙吗? Thanks in advance!!
提前致谢!!
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.*;
public class Main extends JPanel implements ActionListener, KeyListener{
public static int field[][];
public static GenerateField genField;
public static Snake snake;
public static GenerateFood food;
public static GenerateBarrier barrier;
public int difficultness;
public static int widthField;
public static int heightField;
public static TimerTask move, genBarriers;
public static Timer snakeTimer, barrierTimer;
public JButton startPlay;
public static boolean gameStarted;
public Main ()
{
startPlay = new JButton("Starte Spiel");
startPlay.setBounds(0,0,300,200);
startPlay.addActionListener(this);
add(startPlay);
difficultness = 15;
gameStarted = false;
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
widthField = 150;
heightField = 95;
genField = new GenerateField();
snake = new Snake();
food = new GenerateFood();
barrier = new GenerateBarrier();
barrierTimer = new Timer("Timer");
snakeTimer = new Timer("Timer");
genBarriers = new TimerTask() {
@Override
public void run() {
barrier.clearBarrier();
barrier.multiSpawnBarrier(difficultness);
}
};
move = new TimerTask()
{
public void run()
{
if(GenerateField.inGame)
{
snake.moveSnake();
repaint();
}
}
};
}
private static void startGame()
{
genField.generateField();
field = genField.getField();
snake.generateSnake(40, 75);
food.spawnFood();
snakeTimer.schedule(move,0,50);
barrierTimer.schedule(genBarriers, 0, 25000);
}
public static void main(String[] args)
{
JFrame frame = new JFrame();
frame.setSize(1520,1000);
frame.getContentPane().add(new Main());
frame.setLocationRelativeTo(null);
frame.setBackground(Color.LIGHT_GRAY);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
@Override
public void paint(Graphics g)
{
if(gameStarted) {
for (int iy = 0; iy < heightField; iy++) {
for (int ix = 0; ix < widthField; ix++) {
//Zeichnet schwarzen Hintergrund
if (genField.field[iy][ix] == 0) {
g.setColor(Color.BLACK);
g.fillRect(ix * 10, iy * 10, 10, 10);
}
//Zeichnet die Grenze an den Rändern
if (genField.field[iy][ix] == 1) {
g.setColor(Color.red);
g.fillRect(ix * 10, iy * 10, 10, 10);
}
//Zeichnet die Schlange
if (genField.field[iy][ix] == 2) {
g.setColor(Color.green);
g.fillRect(ix * 10, iy * 10, 10, 10);
}
//Zeichnet das "Futter"
if (genField.field[iy][ix] == 3) {
g.setColor(Color.orange);
g.fillRect(ix * 10, iy * 10, 10, 10);
}
//Zeichte die Hindernisse
if (genField.field[iy][ix] == 4) {
g.setColor(Color.blue);
g.fillRect(ix * 10, iy * 10, 10, 10);
}
}
}
}
}
@Override
public void actionPerformed(ActionEvent e)
{
startPlay.setVisible(false);
startGame();
gameStarted = true;
}
@Override
public void keyPressed (KeyEvent e)
{
int code = e.getKeyCode();
if ( code == KeyEvent.VK_LEFT)
{
if (snake.mRight == false)
{
snake.mLeft = true;
snake.mRight = false;
snake.mUp = false;
snake.mDown = false;
}
}
if ( code == KeyEvent.VK_RIGHT)
{
if (snake.mLeft == false)
{
snake.mLeft = false;
snake.mRight = true;
snake.mUp = false;
snake.mDown = false;
}
}
if ( code == KeyEvent.VK_UP)
{
if (snake.mDown == false)
{
snake.mLeft = false;
snake.mRight = false;
snake.mUp = true;
snake.mDown = false;
}
}
if ( code == KeyEvent.VK_DOWN)
{
if (snake.mUp == false)
{
snake.mLeft = false;
snake.mRight = false;
snake.mUp = false;
snake.mDown = true;
}
}
}
@Override
public void keyReleased(KeyEvent e)
{
}
@Override
public void keyTyped(KeyEvent e)
{
}
}
The over use of static
highlights issues with your design. 过度使用
static
突出设计的问题。 static
is not your friend, you should use it sparingly and wisely. static
不是您的朋友,您应该谨慎而明智地使用它。
You're trying to put all your eggs in single basket. 您正在尝试将所有鸡蛋放在一个篮子里。 This is just going to make the state management harder to handle.
这只会使状态管理更难处理。
Instead, start by separating your menu and game into separate classes and managing them independently of each other. 取而代之的是,首先将菜单和游戏分成不同的类,然后彼此独立地进行管理。
This then allows you to use a CardLayout
to manage the navigation between the different views. 然后,您可以使用
CardLayout
来管理不同视图之间的导航。
The following is simple example to demonstrate how you might use CardLayout
to perform decoupled navigation 下面是一个简单的示例,以演示如何使用
CardLayout
执行解耦导航
import java.awt.CardLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
CardLayout cardLayout = new CardLayout();
JPanel base = new JPanel(cardLayout);
NavigationController controller = new NavigationController() {
@Override
public void show(Screen screen) {
cardLayout.show(base, screen.name());
}
};
base.add(new MainMenuPane(controller), Screen.MENU.name());
base.add(new GamePane(controller), Screen.GAME.name());
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(base);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public enum Screen {
MENU, GAME;
}
public interface NavigationController {
public void show(Screen scren);
}
public class MainMenuPane extends JPanel {
public MainMenuPane(NavigationController controller) {
setLayout(new GridBagLayout());
JButton start = new JButton("Start");
add(start);
start.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
controller.show(Screen.GAME);
}
});
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
public class GamePane extends JPanel {
private NavigationController controller;
public GamePane(NavigationController controller) {
this.controller = controller;
setLayout(new GridBagLayout());
add(new JLabel("Ready Player One"));
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}
KeyListener
, use Key bindings instead , they will fix the focus related issues in a more reliable way KeyListener
, 而是使用Key绑定 ,它们将以更可靠的方式解决与焦点相关的问题 paint
chain, which is part of your immediate problem - See Performing Custom Painting and Painting in Swing for more details about how painting works and how you should work with it paint
链的要求,这是您当前的问题之一-有关绘画的工作方式以及如何使用它的详细信息,请参见在Swing中 执行自定义绘画和绘画。 java.util.Timer
is running the risk of dirty read/writes which could lead to any number of weird and near impossible to diagnose issues. java.util.Timer
冒着读/写脏的风险,这可能导致任何数量的怪异且几乎无法诊断问题。 Instead, you should be using Swing Timer instead, which will ensure that any updates you make are made within the context of the Event Dispatching Thread. Timer
and scheduling everything in a simple update pass - this will generally improve performance Timer
并通过简单的更新过程安排所有时间-这通常会提高性能
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.