单击后重命名按钮 - Java JButton

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15285977/
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-10-31 19:05:41  来源:igfitidea点击:

Renaming a button after clicking - Java JButton

javaswingjframejbuttonactionlistener

提问by user1692517

I'm trying to change my button from saying "Start" to "Stop" when I click on it. My attempt at doing this is below, I looked it up and tried to copy the guides but I don't see what I'm doing wrong. I might be missing some "}" because I left out a lot of the code that's irrelevant. Can someone see what I'm doing wrong?

当我点击它时,我试图将我的按钮从“开始”更改为“停止”。我尝试这样做的尝试如下,我查了一下并尝试复制指南,但我看不出我做错了什么。我可能会遗漏一些“}”,因为我遗漏了很多不相关的代码。有人能看到我做错了什么吗?

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

public class PipeGameApp extends JFrame implements ActionListener {

    private static int BOARD_SIZE = 11;
    private PipeGame game;      // The model
    private PipeGameView view;      // The view

    // This constructor builds the window
    public PipeGameApp(String title) {
        super(title);

        game = new PipeGame(BOARD_SIZE);
        view = new PipeGameView(game);

        //THE TOP BAR
        JPanel topBar = new JPanel();
        JButton startButton = new JButton("Start");
        startButton.addActionListener(this);



        ButtonGroup bg1 = new ButtonGroup();
        JRadioButton rb1 = new JRadioButton("2 minutes", true);
        rb1.addActionListener(this);


        JRadioButton rb2 = new JRadioButton("10 minutes", false);
        JRadioButton rb3 = new JRadioButton("No Time Limit", false);
        bg1.add(rb1);
        bg1.add(rb2);
        bg1.add(rb3);





        topBar.add(startButton);
        topBar.add(rb1);
        topBar.add(rb2);
        topBar.add(rb3);
        //END OF TOP BAR

        //THE BOTTOM BAR
        JPanel bottomBar = new JPanel();
        JLabel timeLeft = new JLabel("Time Left: ");
        JProgressBar bar = new JProgressBar();
        bottomBar.add(timeLeft);
        bottomBar.add(bar);
        bottomBar.setVisible(false);
        //end of bottom

        /*
         //bottom 2
         int fscore=10;
         JPanel bottomBar2 = new JPanel();
         JLabel score = new JLabel("Final score:" + fscore);
         bottomBar2.add(score);
         bottomBar2.setVisible(false);
         */


        getContentPane().add(view); //CHANGE LOCATION OF BOARD GAME HERE BorderLayout.SOUTH

        getContentPane().add(topBar, BorderLayout.NORTH);
        getContentPane().add(bottomBar, BorderLayout.SOUTH);

        //getContentPane().add(bottomBar2, BorderLayout.SOUTH);



        // Add the listeners to the view's buttons
        for (int r = 0; r < BOARD_SIZE; r++) {
            for (int c = 0; c < BOARD_SIZE; c++) {
                view.getButton(r, c).addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        handleTileSelection(e);
                    }
                });
            }
        }

        setDefaultCloseOperation(EXIT_ON_CLOSE);
        //setSize(446,466);
        setSize(446, 530);
        setResizable(false);
    }

    // Handle a Tile Selection.   Just change the model and update the view.
    private void handleTileSelection(ActionEvent e) {
        // Find the row and column of the pressed button, then make the change
        int r = 0, c = 0;
        for (int i = 0; i < BOARD_SIZE; i++) {
            for (int j = 0; j < BOARD_SIZE; j++) {
                if (e.getSource() == view.getButton(i, j)) {
                    if (game.placePipe(i, j)) {
                        view.update();
                    }
                    return;
                }
            }
        }
    }

    // This is where it all begins
    public static void main(String[] args) {
        new PipeGameApp("The Frantic Pipe Layer").setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent ae) {
        startButton.setText("asdf");
    }
}

采纳答案by Hovercraft Full Of Eels

Your problem is one of limited variable scope. Your startButton variable is being declared in the constructor and thus is only visible in the constructor. You need to declare it in the class not re-declare it in the constructor allowing the rest of the class to be able to "see" the variable and use it.

您的问题是可变范围有限的问题之一。您的 startButton 变量是在构造函数中声明的,因此仅在构造函数中可见。您需要在类中声明它而不是在构造函数中重新声明它,以便类的其余部分能够“看到”变量并使用它。

i.e., change this:

即,改变这个:

public class PipeGameApp extends JFrame implements ActionListener {

    private static int BOARD_SIZE = 11;
    private PipeGame game;      // The model
    private PipeGameView view;      // The view

    public PipeGameApp(String title) {

        JButton startButton = new JButton("Start");
        startButton.addActionListener(this);
        // etc...

to this:

对此:

public class PipeGameApp extends JFrame implements ActionListener {

    private static int BOARD_SIZE = 11;
    private PipeGame game;      // The model
    private PipeGameView view;      // The view
    private JButton startButton; // *** note change ***

    public PipeGameApp(String title) {

        startButton = new JButton("Start"); // *** note change ***
        startButton.addActionListener(this);
        // etc...

Alternatively:

或者:

  • use A JToggleButton
  • Or use the object returned by the ActionEvent's getSource()method, and set it's new state based on its currentstate.
  • 使用 JToggleButton
  • 或者使用 ActionEvent 的getSource()方法返回的对象,并根据其当前状态设置它的新状态。

For example,

例如,

@Override
public void actionPerformed(ActionEvent ae) {
    Object source = ae.getSource();
    if (source instanceof JButton) {
       if (ae.getText().equals("Start")) {
          ae.setText("Stop");
          // do other stuff
       } else if (ae.getText().equals("Stop")) {
          ae.setText("Start");
          // do more stuff
       }
    }
}

Regarding "I might be missing some "}" because I left out a lot of the code that's irrelevant."Please put in the effort so that this doesn't happen. That missing "}" shouldn't be missing and makes it harder for us to understand your code and to help you. If you're asking others to put in the effort to help you on their free time, it's not asking you too much to not post junk code.

关于"I might be missing some "}" because I left out a lot of the code that's irrelevant."请努力避免这种情况发生。丢失的“}”不应该丢失,这会使我们更难理解您的代码并为您提供帮助。如果您要求其他人在空闲时间努力帮助您,那并不是要求您不要发布垃圾代码。

回答by Ravindra Gullapalli

You kept the constructor's end brace after mainmethod. Here is the corrected code.

您在main方法之后保留了构造函数的结束大括号。这是更正后的代码。

public PipeGameApp(String title) {
    super(title);

    JPanel topBar = new JPanel();
    JButton startButton = new JButton("Start");
    startButton.addActionListener(this);
}

public static void main(String[] args) {
    new PipeGameApp("The Frantic Pipe Layer").setVisible(true);
}

@Override
public void actionPerformed(ActionEvent ae) {
    startButton.setText("asdf");
}