繁体   English   中英

如何使用按钮添加新的JFrame?

[英]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.

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