Java 如何从主方法调用中打开一个 Jframe

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18978203/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 13:02:16  来源:igfitidea点击:

how to open one Jframe from main method call

javaswingjframejbutton

提问by Ankush Pruthi

I have downloaded a snake game project in java and try to modify it. Initially the project contains three java files i.e "Engine.java" , "Snake.java", "GameBoard.java". And Engine.javahave the main()method, and when i run this Engine.java class game starts running.

我已经在java中下载了一个蛇游戏项目并尝试修改它。最初该项目包含三个 java 文件,即“ Engine.java”、“ Snake.java”、“ GameBoard.java”。并Engine.javamain()方法,当我运行这个 Engine.java 类游戏时开始运行。

To improve the user iteractivity towards the project i have created two JFrames :"PlayGame.java", Rules.java

为了提高用户对项目的迭代能力,我创建了两个 JFrame:" PlayGame.java",Rules.java

Now this project having five java classes -

现在这个项目有五个 Java 类 -

Engine.java(containing main() method) 
Snake.java
GameBoard.java
PlayGame.java(is a JFrame)
Rules.java(is a JFrame)

PlayGame.java have three buttons

Play - i want when play button get clicked snake game start/run.
Rules - when clicked Rules.java Jframe should be opened 
Exit - exits the application

Now what i want is at first "PlayGame.java" JFrame should appear(and this is appearing as the main output of the game project) and throw this game should start i.e when i click play button from PlayGame JFramegame should start The problem i am facing is when i click playbutton then gamescreenappears on the window but snake is not moving.

现在我想要的是首先“ PlayGame.java” JFrame 应该出现(并且这作为游戏项目的主要输出出现)并抛出这个游戏应该开始,即当我点击游戏中的播放按钮时PlayGame JFrame应该开始我面临的问题是当我单击play按钮然后gamescreen出现在窗口上,但是snake is not moving

Here is the code that i have included in actionPerformed()method of Play button

这是我在actionPerformed()方法中包含的代码Play button

        private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         

            JFrame frame = new JFrame("SnakeGame");
    frame.setVisible(true); 
            frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    frame.setResizable(true);
    Canvas canvas = new Canvas();
    canvas.setBackground(Color.black);
            canvas.setPreferredSize(new Dimension(GameBoard.MAP_SIZE * GameBoard.TILE_SIZE, GameBoard.MAP_SIZE * GameBoard.TILE_SIZE));
            frame.getContentPane().add(canvas); 
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
            new Engine(canvas).startGame();
}           

and also i am showing code of startGame()method which is in Engine.javaclass

而且我还展示startGame()Engine.java课堂上的方法代码

public void startGame() {
    canvas.createBufferStrategy(2);

    Graphics2D g = (Graphics2D)canvas.getBufferStrategy().getDrawGraphics();
    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

    long start = 0L;
    long sleepDuration = 0L;
    while(true) {
        start = System.currentTimeMillis();

        update();
        render(g);

        canvas.getBufferStrategy().show();

        g.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());

        sleepDuration = (1500L / UPDATES_PER_SECOND) - (System.currentTimeMillis() - start);

        if(sleepDuration > 0) {
            try {
                Thread.sleep(sleepDuration);
            } catch(Exception e) {
                e.printStackTrace();
            }
        }
    }
}

Here also i am attaching the Engine.java class and PlayGame.java in my question for better understandig of problem

这里我也在我的问题中附加了 Engine.java 类和 PlayGame.java 以便更好地理解问题

Engine.java

引擎.java

package org.psnbtech;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
import org.psnbtech.GameBoard.TileType;
import org.psnbtech.Snake.Direction;


public class Engine extends KeyAdapter {

    private static final int UPDATES_PER_SECOND = 15;

    private static final Font FONT_SMALL = new Font("Arial", Font.BOLD, 20);

    private static final Font FONT_LARGE = new Font("Arial", Font.BOLD, 40);

    public Canvas canvas;

    public GameBoard board;

    public Snake snake;

    public int score;

    public boolean gameOver;


    public Engine(Canvas canvas) {
                this.canvas = canvas;
            this.board = new GameBoard();
        this.snake = new Snake(board);

        resetGame();

        canvas.addKeyListener(this);
                //new Engine(canvas).startGame();
    }


    public void startGame() {
        canvas.createBufferStrategy(2);

        Graphics2D g = (Graphics2D)canvas.getBufferStrategy().getDrawGraphics();
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        long start = 0L;
        long sleepDuration = 0L;
        while(true) {
            start = System.currentTimeMillis();

            update();
            render(g);

            canvas.getBufferStrategy().show();

            g.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());

            sleepDuration = (1500L / UPDATES_PER_SECOND) - (System.currentTimeMillis() - start);

            if(sleepDuration > 0) {
                try {
                    Thread.sleep(sleepDuration);
                } catch(Exception e) {
                                    e.printStackTrace();
                }
            }
        }
    }

    public void update() {
        if(gameOver || !canvas.isFocusOwner()) {
            return;
        }
        TileType snakeTile = snake.updateSnake();
        if(snakeTile == null || snakeTile.equals(TileType.SNAKE)) {
            gameOver = true;
        } else if(snakeTile.equals(TileType.FRUIT)) {
            score += 10;
            spawnFruit();
        }
    }

    public void render(Graphics2D g) {
        board.draw(g);

        g.setColor(Color.WHITE);

        if(gameOver) {
            g.setFont(FONT_LARGE);
            String message = new String("Your Score: " + score);
            g.drawString(message, canvas.getWidth() / 2 - (g.getFontMetrics().stringWidth(message) / 2), 250);

            g.setFont(FONT_SMALL);
            message = new String("Press Enter to Restart the Game");
            g.drawString(message, canvas.getWidth() / 2 - (g.getFontMetrics().stringWidth(message) / 2), 350);
        } else {
            g.setFont(FONT_SMALL);
            g.drawString("Score:" + score, 10, 20);
        }
    }

    public void resetGame() {
        board.resetBoard();
        snake.resetSnake();
        score = 0;
        gameOver = false;
        spawnFruit();
    }

    public void spawnFruit() {
        int random = (int)(Math.random() * ((GameBoard.MAP_SIZE * GameBoard.MAP_SIZE) - snake.getSnakeLength())); // if '*' replace by '/' then only one fruit is there for snake

        int emptyFound = 0;
        int index = 0;
        while(emptyFound < random) {
            index++;
            if(board.getTile(index % GameBoard.MAP_SIZE, index / GameBoard.MAP_SIZE).equals(TileType.EMPTY)) { // if '/' replaced by '*' then nothing displays on the board 
                emptyFound++;
            }
        }
        board.setTile(index % GameBoard.MAP_SIZE, index / GameBoard.MAP_SIZE, TileType.FRUIT); // it also show nothing when replacing '/' by '/' 
    }

    @Override
    public void keyPressed(KeyEvent e) {
        if((e.getKeyCode() == KeyEvent.VK_UP)||(e.getKeyCode() == KeyEvent.VK_W)) {
            snake.setDirection(Direction.UP);
        }
        if((e.getKeyCode() == KeyEvent.VK_DOWN)||(e.getKeyCode() == KeyEvent.VK_S)) {
            snake.setDirection(Direction.DOWN);
        }
        if((e.getKeyCode() == KeyEvent.VK_LEFT)||(e.getKeyCode() == KeyEvent.VK_A)) {
            snake.setDirection(Direction.LEFT);
        }
        if((e.getKeyCode() == KeyEvent.VK_RIGHT)||(e.getKeyCode() == KeyEvent.VK_D)) {
            snake.setDirection(Direction.RIGHT);
        }
        if(e.getKeyCode() == KeyEvent.VK_ENTER && gameOver) {
            resetGame();
        }
    }

         public static void main(String[] args)  {
        new PlayGame().setVisible(true);

        /**JFrame frame = new JFrame("SnakeGame");
        frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
        frame.setResizable(false);

        Canvas canvas = new Canvas();
        canvas.setBackground(Color.black);
        canvas.setPreferredSize(new Dimension(GameBoard.MAP_SIZE * GameBoard.TILE_SIZE, GameBoard.MAP_SIZE * GameBoard.TILE_SIZE));

        frame.getContentPane().add(canvas);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true); 

        new Engine(canvas).startGame();*/


             }        
}

PlayGame.java

玩游戏

package org.psnbtech;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;


import javax.swing.JFrame;


public class PlayGame extends javax.swing.JFrame  {



   public PlayGame() {

        initComponents();      
    }


    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        jButton2 = new javax.swing.JButton();
        jButton3 = new javax.swing.JButton();
        jButton1 = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jButton2.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/psnbtech/GUID-4ED364DF-2D44-40F5-9F05-31D451F15EF1-low.png"))); // NOI18N
        jButton2.setText("Rules");
        jButton2.setMaximumSize(new java.awt.Dimension(89, 39));
        jButton2.setMinimumSize(new java.awt.Dimension(89, 39));
        jButton2.setPreferredSize(new java.awt.Dimension(89, 41));
        jButton2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton2ActionPerformed(evt);
            }
        });

        jButton3.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/psnbtech/exit (1).png"))); // NOI18N
        jButton3.setText("Exit");
        jButton3.setPreferredSize(new java.awt.Dimension(89, 41));
        jButton3.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton3ActionPerformed(evt);
            }
        });

        jButton1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/psnbtech/play.png"))); // NOI18N
        jButton1.setText("Play");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                .addContainerGap(277, Short.MAX_VALUE)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addComponent(jButton3, javax.swing.GroupLayout.PREFERRED_SIZE, 111, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addContainerGap())
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(jButton2, javax.swing.GroupLayout.PREFERRED_SIZE, 109, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 109, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGap(27, 27, 27))))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                .addGap(40, 40, 40)
                .addComponent(jButton1)
                .addGap(35, 35, 35)
                .addComponent(jButton2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(27, 27, 27)
                .addComponent(jButton3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(75, Short.MAX_VALUE))
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );

        pack();
    }// </editor-fold>                        

    private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        System.exit(0);        
    }                                        

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                         

        this.dispose();
        new Rules().setVisible(true);

    }                                        



    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         

                JFrame frame = new JFrame("SnakeGame");
        frame.setVisible(true); 
                frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.setResizable(true);
        Canvas canvas = new Canvas();
        canvas.setBackground(Color.black);
                canvas.setPreferredSize(new Dimension(GameBoard.MAP_SIZE * GameBoard.TILE_SIZE, GameBoard.MAP_SIZE * GameBoard.TILE_SIZE));
                //canvas.addKeyListener((KeyListener) this);
                frame.getContentPane().add(canvas); 
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
                new Engine(canvas).startGame();
    }                                        


    // Variables declaration - do not modify                     
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JButton jButton3;
    private javax.swing.JPanel jPanel1;
    // End of variables declaration                   
}

采纳答案by StanislavL

Taht happens because you call

Taht 发生是因为你打电话

new PlayGame().setVisible(true);

and

frame.setVisible(true); 

Show just the first frame and on button click the second.

仅显示第一帧,然后在按钮上单击第二帧。

The recommended approach is to use just one frame always but multiple panels 1. where game is rendered and 2. options pane. Swap them e.g. by using CardLayout.

推荐的方法是始终只使用一帧,但使用多个面板 1. 渲染游戏的位置和 2. 选项面板。交换它们,例如使用CardLayout.

Also don't use Canvasuse JPanelinstead overriding paintComponent()method.

也不要使用CanvasuseJPanel代替覆盖paintComponent()方法。

回答by Piseth Sok

Try the follwing:

尝试以下:

JFrameAdd ja = new JFrameAdd();
ja.setVisible(true);
ja.setLocationRelativeTo(null);

Hope it will help!

希望它会有所帮助!