如何使用按钮添加新的JFrame? [英] How to add a new JFrame with buttons?

查看:75
本文介绍了如何使用按钮添加新的JFrame?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

每当我创建一个新的JFrame屏幕时,由于某种原因游戏将无法在计算机上运行,​​我也不知道为什么.我曾尝试解决此问题,但我认为这与按钮或屏幕的位置有关. startStage是我需要帮助的.如果我想念什么,可以告诉我.

Whenever I create a new JFrame screen the game won't run on my computer for some reason and I don't know why. I have tried fixing this issue but I think it has something to do with the buttons or the placement of the screen. The startStage is what I need help on. If I'm missing something can you please tell me.

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) {
}

}

推荐答案

您似乎对容器管理的工作方式有疑问.停下来,退一步,然后重新考虑您的方法.

You seem to have issues with how container management works. Stop, take a step back for a second and re-think your approach.

基本上,您有一个菜单"和一个游戏"面板.这应该是两个单独的面板/类.

You basically have a "menu" and a "game" panel. This should be two separate panels/class.

然后应将这些添加到集线器"面板,该面板管理何时以及如何显示它们.

These should then be added to a "hub" panel, which manages when and how they are displayed.

这是主",集线器"面板.它负责显示菜单和游戏面板.它还负责确定这种情况的如何发生",在本示例中,我仅使用了CardLayout

This is the "main", "hub" panel. It is responsible for displaying both the menu and the game panels. It's also responsible for deciding "how" this happens, in this example, I've simply used a 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

菜单"非常简单.它仅显示可用选项,并提供一种在选择选项时通知感兴趣的参与者的方法

MenuPane

The "menu" is pretty simple. It simply displays the available options and provides a means for interested parties to be notified when an option is selected

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);
    }

}

我对此不做过多介绍,但是您应该看看如何使用按钮,复选框和单选按钮如何编写动作监听器了解更多详情

I'm not going into a lot about this, but you should have a look at How to Use Buttons, Check Boxes, and Radio Buttons and How to Write an Action Listener for more details

我很懒,直接将ActionListener附加到按钮上.相反,您应该分别管理按钮侦听器和面板的侦听器,这样可以防止暴露按钮,并使您可以更好地控制执行特定操作时生成的内容.

I'm been lazy, attaching the ActionListeners directly to the buttons. Instead, you should manage the button listeners and the panel's listeners separately, this will prevent exposing the buttons and allow you better control over what to generate when a specific operation is executed.

最后是游戏"面板.正如我前一天所说的,您应该使用自定义绘画路线如何使用键绑定.他们将共同解决许多其他我们通常不想再被问到的问题

And finally, the "game" panel. As I've been saying for the last day, you should make use a custom painting route and How to Use Key Bindings. Together, they will solve a swagger of other issues we'd generally like not to have to be asked about, again

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);
    }

}

可运行示例...

将它们放在一起...

Runnable Example...

Putting it all together...

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);
        }

    }

}

请记住,您的目标之一应该是关于责任分工",创建可以很好地完成工作的类/组件.这样,您就可以将它们用作设计更复杂解决方案的基础

Remember, one of your goals should be about "separation of responsibility", creating classes/components which do there job and do it well. This way you can use them as building blocks to devise much more complex solutions

这篇关于如何使用按钮添加新的JFrame?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆