如何将全局JPanel添加到JFrame

时间:2014-04-24 00:19:56

标签: java swing jframe jpanel

我目前正在读高中的编程课程,我们专注于Java,其中一个需要建立的程序是Rock Paper Scissors游戏。我很容易做到这一点并且它有效,但我决定尝试弄清楚如何使它在自己的窗口中工作。这导致我研究JFrames以及如何使用它们。我已经找了很多教程来介绍它,我从oracle网站上保存了5个不同的例子供参考,但我无法弄清楚为什么这个程序不起作用。

package rps;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
/**
 * Name: Steven Biro
 * Course Code: ICS3U
 * Teacher: Mr.Carron
 * Date: 23-Apr-2014
 * Program Description: 
 */
public class RPS 
                implements ActionListener {
    static JPanel text,buttons;

    /**
     * @param args the command line arguments
     */
    public void RPS() {
        JButton Rock,Paper,Scissors;
        buttons = new JPanel();
        Rock = new JButton("Rock");
        Paper = new JButton("Paper");
        Scissors = new JButton("Scissors");
        Rock.setMnemonic(KeyEvent.VK_D);
        Paper.setMnemonic(KeyEvent.VK_M);
        Scissors.setMnemonic(KeyEvent.VK_E);
        Rock.setActionCommand("Rock");
        Paper.setActionCommand("Paper");
        Scissors.setActionCommand("Scissors");
        Rock.addActionListener(this);
        Paper.addActionListener(this);
        Scissors.addActionListener(this);
        buttons.add(Rock);
        buttons.add(Paper);
        buttons.add(Scissors);

    }

    public void actionPerformed(ActionEvent e) {
        String PC,Player;
        int outcome;
    PC="";
    Player=(e.getActionCommand());
    int computer = (int)(Math.random()*3+1);
    if (computer==1) {
        PC="Rock";
    } else if (computer==2) {
        PC="Paper";
    } else {
        PC="Scissors";
    } if (Player.equals(PC)) {
        outcome=0; //tied
    } else {
        if ("Rock".equals(PC)) {
            if ("Paper".equals(Player)) {
                outcome=1; //win
            } else { 
                outcome=2; //lose
            }
        } else if ("Paper".equals(PC)) {
            if ("Scissors".equals(Player)) {
                outcome=1; //win
            } else {
                outcome=2; //lose
            }
        } else {
            if ("Rock".equals(Player)) {
                outcome=1; //win
            } else {
                outcome=2; //lose
                }
            }
        }
    JLabel r;
        if (outcome==0) {
            r = new JLabel ("You Tied.");
        } else if (outcome==1) {
            r = new JLabel ("You Win.");
        } else if (outcome==2) {
            r = new JLabel ("You Lose.");
        } else {
            System.exit(2);
            r = new JLabel ("wont ever execute");
        }
        text = new JPanel();
        text.add(r);
    }

 public static void GUI() {
                       //Create and set up the window.
        JFrame frame = new JFrame("RockPaperScissors");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Create and set up the content pane.
        frame.add(buttons);
        frame.add(text);

        //Display the window.
        frame.pack();
        frame.setVisible(true);
        frame.setSize(250,150);
    }


    public static void main(String[] args) {

        GUI();

    }

}

如果你能帮我弄清楚为什么JPanels称为“按钮”和“文字”不会添加我会非常感激。

如果我删除

        //Create and set up the content pane.
    frame.add(buttons);
    frame.add(text);

来自我的程序,然后它运行没有问题,只是一个空白的窗口,如预期的那样,所以我不知道该怎么做。

编辑: 我在纠正从void

中删除public void RPS() {后得到的错误

Exception in thread "main" java.lang.NullPointerException at java.awt.Container.addImpl(Container.java:1091) at java.awt.Container.add(Container.java:1003) at javax.swing.JFrame.addImpl(JFrame.java:564) at java.awt.Container.add(Container.java:415) at rps.RPS.GUI(RPS.java:102) at rps.RPS.main(RPS.java:114) Picked up _JAVA_OPTIONS: -Djava.net.preferIPv4Stack=true Java Result: 1

如果我从static删除static JPanel text,buttons;,那么netbeans会“纠正”每个方法,因此它永远不会对其中的任何一个说static,包括Main,所以它说它无法找到main。

抱歉,如果我遇到愚蠢,但如果有人能帮我解决这个问题,我将非常感激。

2 个答案:

答案 0 :(得分:3)

  • 您永远不会通过new RPS()在任何地方创建RPS实例。
  • 你有一个"伪构造函数"在您的RPS课程中。即,public void RPS() {不是构造函数。摆脱void返回类型,因为构造函数应该没有返回类型:public RPS() {
  • 您的Swing组件字段绝对不应该是静态的。
  • 您将组件添加到JFrame,而不考虑其布局管理器BorderLayout。您当前的代码是添加空组件,但如果它们不为空,则它们都会添加BorderLayout.CENTER,最后一个覆盖前一个。
  • 在RPS类中创建一个主JPanel,然后通过非静态方法将其添加到main方法中的JFrame。

例如,RPS可能会扩展JPanel,如果是这种情况,那么您可以将它添加到JFrame中,如下所示:

JFrame frame = new JFrame("RPS");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(new RPS());

其他建议:

  • 查看枚举,因为Rock Paper Scissors非常适合这一点,包括给出枚举方法来测试胜利
  • 通过使用枚举,稍后修改代码以允许其他状态(如Lizard和Spock)会更容易。
  • 尝试将程序的逻辑部分与视图分开 - GUI部分。
  • 避免让您的GUI类实现您的侦听器接口,因为这会导致创建" switch-board"听众,有点像你正在写作 - 一只熊来调试或增强。而是在这里尝试使用匿名内部类或私有内部类。

答案 1 :(得分:2)

这可能是因为

public void RPS() {

不是构造函数,而是一个方法(因为它有返回类型),因此永远不会被调用。

删除void,你应该很好。