[英]How to add a new JFrame with buttons?
每当我创建新的JFrame
屏幕时,由于某种原因游戏将无法在计算机上运行,我也不知道为什么。 我曾尝试解决此问题,但我认为这与按钮或屏幕的位置有关。 我需要startStage
帮助。 如果我想念什么,可以告诉我。
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.HashSet;
import java.util.Set;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
/**
* This class demonstrates basic animation using a timer, an action listener,
* and a key listener
*
*
*
*/
public class GameWindow extends JPanel implements ActionListener, KeyListener {
private static final long serialVersionUID = 1L;
JLabel player = new JLabel();
int playerSpeed = 1;
int FPS = 30;
// The keys set holds the keys being pressed
private final Set<Integer> keys = new HashSet<>();
public static void main(String[] args) {
// Open the GUI window
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
// Create a new object and
// run its go() method
new GameWindow().go();
}
});
}
public GameWindow() {
// Run the parent class constructor
super();
// Allow the panel to get focus
setFocusable(true);
// Don't let keys change the focus
setFocusTraversalKeysEnabled(false);
//Make a new screen with a button and put it in the window
JPanel startStage = new JPanel(); // Create a new JPanel and add it to the card layout
startStage.setSize(getWidth(), getHeight()); // make the new JPanel fit the window
startStage.setBackground(Color.BLUE); // set the JPanel background to blue
startStage.setVisible(true); // show the JPanel
JButton playButton = new JButton("Play"); // Add a button to the panel
playButton.addMouseListener(new MouseAdapter() { // Set the button to switch to the game stage
@Override
public void mouseClicked(MouseEvent arg0) {
((CardLayout) getContentPane().getLayout()).show(
getContentPane(), "game");
}
});
startStage.add(playButton); // add the button to the stage
add(startStage, "start"); // add the stage to the window
}
protected void go() {
// Setup the window
JFrame jf = new JFrame();
// Add this panel to the window
jf.setContentPane(this);
// Set the window properties
jf.setTitle("Animation Demo");
jf.setSize(300, 200);
jf.setLocationRelativeTo(null);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setVisible(true);
// Setup the movable box
player.setBounds(10, 10, 10, 10);
player.setVisible(true);
player.setBackground(Color.BLUE);
// Opaque makes the background visible
player.setOpaque(true);
// Setup the key listener
addKeyListener(this);
// Null layout allows moving objects!!!
setLayout(null);
add(player);
// Set the timer
Timer tm = new Timer(1000 / FPS, this);
tm.start();
}
@Override
public void actionPerformed(ActionEvent arg0) {
// Move up if W is pressed
if (keys.contains(KeyEvent.VK_W)) {
player.setLocation(player.getX(), player.getY() - playerSpeed);
}
// Move right if D is pressed
if (keys.contains(KeyEvent.VK_D)) {
player.setLocation(player.getX() + playerSpeed, player.getY());
}
// Move down if S is pressed
if (keys.contains(KeyEvent.VK_S)) {
player.setLocation(player.getX(), player.getY() + playerSpeed);
}
// Move left if A is pressed
if (keys.contains(KeyEvent.VK_A)) {
player.setLocation(player.getX() - playerSpeed, player.getY());
}
}
@Override
public void keyPressed(KeyEvent e) {
// Add the key to the list
// of pressed keys
if (!keys.contains(e.getKeyCode())) {
keys.add(e.getKeyCode());
}
}
@Override
public void keyReleased(KeyEvent e) {
// Remove the key from the
// list of pressed keys
keys.remove((Integer) e.getKeyCode());
}
@Override
public void keyTyped(KeyEvent e) {
}
}
您似乎对容器管理的工作方式有疑问。 停下来,退一步,然后重新考虑您的方法。
您基本上有一个“菜单”和一个“游戏”面板。 这应该是两个单独的面板/类。
然后应将它们添加到“集线器”面板,该面板管理何时以及如何显示它们。
MainPane
这是“主”,“集线器”面板。 它负责显示菜单和游戏面板。 它还负责确定这种情况的“如何发生”,在此示例中,我仅使用了CardLayout
public class MainPane extends JPanel {
public MainPane() {
setLayout(new CardLayout());
MenuPane menu = new MenuPane();
menu.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (getLayout() instanceof CardLayout) {
CardLayout layout = (CardLayout) getLayout();
layout.show(MainPane.this, "game");
}
}
});
GamePane game = new GamePane();
add(menu, "menu");
add(game, "game");
((CardLayout) getLayout()).show(this, "menu");
}
}
MenuPane
“菜单”非常简单。 它仅显示可用选项,并为选择相关选项时有兴趣的各方提供通知
public class MenuPane extends JPanel {
private JButton btn;
public MenuPane() {
setLayout(new GridBagLayout());
setBackground(Color.BLUE);
btn = new JButton("Start");
add(btn);
}
public void addActionListener(ActionListener listener) {
btn.addActionListener(listener);
}
public void removeActionListener(ActionListener listener) {
btn.removeActionListener(listener);
}
}
我不会对此进行过多讨论,但是您应该了解如何使用按钮,复选框和单选按钮以及如何编写动作监听器的更多信息。
我很懒,直接将ActionListener
附加到按钮上。 相反,您应该分别管理按钮侦听器和面板的侦听器,这将防止暴露按钮,并使您可以更好地控制执行特定操作时生成的内容。
GamePane
最后是“游戏”面板。 正如我在最后一天所说的那样,您应该使用自定义的绘画路线和“ 如何使用键绑定” 。 他们将共同解决许多其他我们通常不想再被问到的问题
public interface Movable {
public void changeLocation(int xDelta, int yDelta);
}
public class GamePane extends JPanel implements Movable {
private Rectangle player;
public GamePane() {
String text = "X";
FontMetrics fm = getFontMetrics(getFont());
int width = fm.stringWidth(text);
int height = fm.getHeight();
player = new Rectangle(0, 0, width, height);
setupKeyBindings();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
protected void setupKeyBindings() {
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap am = getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0), "up");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0), "down");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0), "left");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0), "right");
int xDelta = player.width;
int yDelta = player.height;
am.put("up", new MoveAction(this, 0, -yDelta));
am.put("down", new MoveAction(this, 0, yDelta));
am.put("left", new MoveAction(this, -xDelta, 0));
am.put("right", new MoveAction(this, xDelta, 0));
}
@Override
public void changeLocation(int xDelta, int yDelta) {
int xPos = player.x + xDelta;
int yPos = player.y + yDelta;
if (xPos + player.width > getWidth()) {
xPos = getWidth() - player.width;
} else if (xPos < 0) {
xPos = 0;
}
if (yPos + player.height > getHeight()) {
yPos = getHeight() - player.height;
} else if (xPos < 0) {
yPos = 0;
}
player.setLocation(xPos, yPos);
repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.RED);
g2d.draw(player);
FontMetrics fm = g2d.getFontMetrics();
g2d.drawString("X", player.x, player.y + fm.getAscent());
g2d.dispose();
}
}
public class MoveAction extends AbstractAction {
private Movable movable;
private int xDelta;
private int yDelta;
public MoveAction(Movable movable, int xDelta, int yDelta) {
this.movable = movable;
this.xDelta = xDelta;
this.yDelta = yDelta;
}
@Override
public void actionPerformed(ActionEvent e) {
movable.changeLocation(xDelta, yDelta);
}
}
全部放在一起...
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Game {
public static void main(String[] args) {
new Game();
}
public Game() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new MainPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class MainPane extends JPanel {
public MainPane() {
setLayout(new CardLayout());
MenuPane menu = new MenuPane();
menu.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (getLayout() instanceof CardLayout) {
CardLayout layout = (CardLayout) getLayout();
layout.show(MainPane.this, "game");
}
}
});
GamePane game = new GamePane();
add(menu, "menu");
add(game, "game");
((CardLayout) getLayout()).show(this, "menu");
}
}
public class MenuPane extends JPanel {
private JButton btn;
public MenuPane() {
setLayout(new GridBagLayout());
setBackground(Color.BLUE);
btn = new JButton("Start");
add(btn);
}
public void addActionListener(ActionListener listener) {
btn.addActionListener(listener);
}
public void removeActionListener(ActionListener listener) {
btn.removeActionListener(listener);
}
}
public interface Movable {
public void changeLocation(int xDelta, int yDelta);
}
public class GamePane extends JPanel implements Movable {
private Rectangle player;
public GamePane() {
String text = "X";
FontMetrics fm = getFontMetrics(getFont());
int width = fm.stringWidth(text);
int height = fm.getHeight();
player = new Rectangle(0, 0, width, height);
setupKeyBindings();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
protected void setupKeyBindings() {
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap am = getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0), "up");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0), "down");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0), "left");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0), "right");
int xDelta = player.width;
int yDelta = player.height;
am.put("up", new MoveAction(this, 0, -yDelta));
am.put("down", new MoveAction(this, 0, yDelta));
am.put("left", new MoveAction(this, -xDelta, 0));
am.put("right", new MoveAction(this, xDelta, 0));
}
@Override
public void changeLocation(int xDelta, int yDelta) {
int xPos = player.x + xDelta;
int yPos = player.y + yDelta;
if (xPos + player.width > getWidth()) {
xPos = getWidth() - player.width;
} else if (xPos < 0) {
xPos = 0;
}
if (yPos + player.height > getHeight()) {
yPos = getHeight() - player.height;
} else if (xPos < 0) {
yPos = 0;
}
player.setLocation(xPos, yPos);
repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.RED);
g2d.draw(player);
FontMetrics fm = g2d.getFontMetrics();
g2d.drawString("X", player.x, player.y + fm.getAscent());
g2d.dispose();
}
}
public class MoveAction extends AbstractAction {
private Movable movable;
private int xDelta;
private int yDelta;
public MoveAction(Movable movable, int xDelta, int yDelta) {
this.movable = movable;
this.xDelta = xDelta;
this.yDelta = yDelta;
}
@Override
public void actionPerformed(ActionEvent e) {
movable.changeLocation(xDelta, yDelta);
}
}
}
请记住,您的目标之一应该是关于“职责分离”,创建可以很好地完成工作并很好地完成工作的类/组件。 这样,您可以将它们用作构建更复杂的解决方案的基础
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.