【问题标题】:Why JTextfield's text value is not changing visually by using a variable?为什么 JTextfield 的文本值没有通过使用变量在视觉上发生变化?
【发布时间】:2015-10-02 18:44:11
【问题描述】:

我正在做一个使用 JAVA 制作棋盘游戏的项目。现在我希望当玩家获胜时,分数将显示在 Jtextfield 中。所以首先我使用了一种方法从 GamePlan 类中的 Declarewin 方法()中的 Player1Graphics 类中获取 JTextfield。但是这个向我展示了一个 NullPointerException。

所以我想到了另一种方法。因为我不能将 GameGui 类的对象设置为任何其他类,因为它会创建无限循环。所以我使用了另一个名为 Player 类的类并创建了一个变量“SName”,它将从 decarewin() 方法中的“score”变量中获取值。然后我在 Player1Graphics 类中使用了一个 updatetextfied() 方法,它是一个GameGui 类的内部类并在其上设置“SName”变量。现在在运行时所有变量都运行良好,它们按预期传递值,JTextfield 文本值也在更新,但 JTextfield 的视觉没有更新。它没有改变从 0 到 1 或 1 到 2。

我给出下面的代码......

这是来自 GameGui 类的代码............

public class GameGui extends JFrame{


    GameGui(){

    super("Board");
    this.setVisible(true);
    this.setSize(700,800);
    this.setLocationRelativeTo(null);
    this.setResizable(false);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    this.setContentPane(main_panel);
    main_panel.setLayout(new BorderLayout());
    main_panel.setBackground(Color.WHITE);

    resourcer();

}


resourcer(){


//players
    JPanel playersroom = new JPanel();

    //playersroom.setBorder(BorderFactory.createLineBorder(Color.black, 1));
    playersroom.setBackground(Color.white);
    playersroom.setLayout(new BorderLayout());

    JPanel player1room = new JPanel();
    player1room.setLayout(new BorderLayout());
    //player1room.setBorder(BorderFactory.createMatteBorder(0, 0, 0, 1, Color.BLACK));
    player1room.setPreferredSize(new Dimension(350,300));
    player1room.add(new Player1graphics(),BorderLayout.CENTER);
    playersroom.add(player1room,BorderLayout.WEST);


    arena.add(playersroom,BorderLayout.CENTER);




    main_panel.add(arena,BorderLayout.SOUTH);






}

这是保存 JTextfield 的 player1Graphics 类,它是 GameGui 类的内部类。

public class Player1graphics extends JPanel{
    private String newname;
     JLabel name = new JLabel("PLAYER 1",SwingConstants.CENTER);
    JButton setname = new JButton("CN");
    GamePlan g = new GamePlan();
    JButton token = new JButton("POISON");

    JTextField showscore = new JTextField(20); //this is the JTextfield


    Player1graphics(){
        //repaint();
        this.setLayout(null);
        this.setBackground(new Color(255,220,154));


        //setname code & name code
        //JButton setname = new JButton("CN");

        setname.setBounds(160, 40, 30, 20);
        setname.setBorder( BorderFactory.createLineBorder(Color.black, 1, true));
        setname.setToolTipText("Change the name");




        name.setBounds(132, 70, 80, 30);
        name.setOpaque(true);
        name.setBackground(new Color(102,140,185));
        name.setForeground(new Color(202,208,215));
        name.setBorder(BorderFactory.createLineBorder(Color.black, 1));




    setname.addActionListener(new ActionListener() {

            @Override
            public  void  actionPerformed(ActionEvent e) {


                 newname = JOptionPane.showInputDialog(null,"ENTER YOUR NAME");
                if (newname==null){
                name.setText("PLAYER 1");
                }else{
                    t1=1;
                name.setText(newname);

                getfirstplayername(newname);
                }

            }
        });


        //token button code
        //JButton token = new JButton("POISON");
        token.setBackground(new Color(233,249,254));


        token.setBounds(132, 110, 80, 30);
        token.setToolTipText("token can be used only one time");
        ActionClass ac = new ActionClass();
        ac.getfirstplayerpoisonbutton(token);
        token.addActionListener(ac);


        //won and showin textfieldcode
        JLabel won = new JLabel("Won",SwingConstants.CENTER);
        won.setBorder( BorderFactory.createLineBorder(new Color(102,140,185), 2, true));
        won.setBounds(132, 150, 50, 30);
        won.setBackground(new Color(102,140,185));
        won.setForeground(Color.WHITE);

//JTextfield codes
        //JTextField showwin = new JTextField();
        //GamePlan gm = new GamePlan();

        Player player = new Player();
        showscore.setBounds(185, 150, 30, 30);

        showscore.setEditable(false);

        //showwin.setOpaque(true);
        //showwin.setBackground(Color.WHITE);
        //showwin.setText(player.sname);
        updatetextfield(player.sname);

        this.add(name);
        this.add(setname);
        this.add(token);
        this.add(won);
        this.add(showscore);
        repaint();

    }

    public void paintComponent(Graphics g){
        super.paintComponent(g);
        Graphics2D myg = (Graphics2D) g;
        myg.setStroke(new BasicStroke(1));
        myg.setColor(new Color(163,193,231));
        myg.fillOval(25, 10, 300, 200);


    }


    public void updatetextfield(String s){



        showscore.setText(s);
        showscore.repaint();

        //JOptionPane.showMessageDialog(null, showwin.getText());
    }



}

这是 JTextfield 代码........

    JTextField showscore = new JTextField(20);
    Player player = new Player();

        showscore.setBounds(185, 150, 30, 30);

        showscore.setEditable(false);
        updatetextfield(player.sname);

这是updatetextfield方法代码............

public void updatetextfield(String s){



        showscore.setText(s);
        showscore.repaint();

        //JOptionPane.showMessageDialog(null, showscore.getText());
    }

这是我在播放器类中创建的变量............

public class Player{

 String sname =  Integer.toString(GamePlan.score);


}

这是 score 变量更新的 declarewin 方法,它位于另一个名为 GamePlan Class 的类中。

public class GamePlan{

static int score=0;  


public void declarewin(){

    score++;  //score variable updating

    for(int i=0;i<20;i++){
        for(int j=0;j<20;j++){
            bbutton[i][j].setEnabled(false);
        }
    }

    JOptionPane.showMessageDialog(null, score);
    Player pl = new Player();
    JOptionPane.showMessageDialog(null, pl.sname);

    JOptionPane.showMessageDialog(null, "YOU have won the   game");
}

我使用了很多 JOption 来查看变量是否正在传递值,并且我使用 gettext() 方法查看 JTextfield 的值是否正在改变。是的,所有的值都在改变,但是只有 Textfield 的视觉没有改变。虽然在 JTextfield 内部的文本值为 1 或 2,但它在 GUI 中显示为 0。IT 永远不会改变......

我已经花了几个小时来解决这个问题,但我无法解决。这让我很生气。

请有人帮我摆脱这个混乱...... :| :|

【问题讨论】:

  • 您是否在主窗口中添加了 Player1graphics 面板?,输入主框架代码
  • 你有没有在初始化代码之外调用过updatetextfield方法?
  • 我已经添加了主框架代码............@Michele Lacorte
  • 我正在调用 Player1GraphicsClass 构造函数中的 updatetextfield() 方法......@Subler
  • 如果只在构造函数中调用,启动游戏后永远不会更新,为什么一直为0?

标签: java variables methods parameter-passing jtextfield


【解决方案1】:

每次更新 player.sname 变量的值时,都需要更新文本字段。

现在您创建乐谱的副本并将其保存在文本字段中。 您需要使用新值再次调用 updatetextfield 函数。

看这个例子:

public class GamePlan{

    static int score=0;  

    //First new line
    GameGui referenceToGui //Get this reference somethere

    public void declarewin(){

        score++;  //score variable updating
        //Second new line
        referenceToGui.updateTextField(""+score); 

        for(int i=0;i<20;i++){
            for(int j=0;j<20;j++){
                bbutton[i][j].setEnabled(false);
            }
        }

        JOptionPane.showMessageDialog(null, score);
        Player pl = new Player();
        JOptionPane.showMessageDialog(null, pl.sname);

        JOptionPane.showMessageDialog(null, "YOU have won the   game");
    }

【讨论】:

  • 我已经按照你展示的那样做了......但是因为 updatetextfield() 方法在 player1graphics 类中,这是 GameGUIi 类的内部类。所以我无法使用updatetextfield() 方法直接使用 GameGUI 引用。所以我使用了这样的链命令 // code 'GameGui reference; reference.pl1.updatetextfield("" + score); //pl1 是 player1graphics 类的对象 ' 但是编译器显示空指针异常.......@Denis.......:/
猜你喜欢
  • 1970-01-01
  • 2020-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-15
  • 2012-11-18
  • 1970-01-01
相关资源
最近更新 更多