Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/349.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 类变量在方法调用后未更新_Java_Swing_Interface_Radio Button - Fatal编程技术网

Java 类变量在方法调用后未更新

Java 类变量在方法调用后未更新,java,swing,interface,radio-button,Java,Swing,Interface,Radio Button,我对Java非常陌生,只是在研究、谷歌搜索和阅读了许多答案之后,我才发布这篇文章。我有点迷路了。一点指导会有很大帮助。下面是来自实现“ActionListener”接口的类的方法。我想做的是:有一个按钮,点击它会打开一个新窗口,其中有两个选项,以两个单选按钮的形式出现。我需要知道在我的代码中选择的用于进一步使用的单选按钮。我将“scoreOption”变量声明为类变量和静态变量,然后尝试在“actionPerformed”抽象方法中更新它。但是当我引用它时(在方法调用之后),该值保持不变-nul

我对Java非常陌生,只是在研究、谷歌搜索和阅读了许多答案之后,我才发布这篇文章。我有点迷路了。一点指导会有很大帮助。下面是来自实现“ActionListener”接口的类的方法。我想做的是:有一个按钮,点击它会打开一个新窗口,其中有两个选项,以两个单选按钮的形式出现。我需要知道在我的代码中选择的用于进一步使用的单选按钮。我将“scoreOption”变量声明为类变量和静态变量,然后尝试在“actionPerformed”抽象方法中更新它。但是当我引用它时(在方法调用之后),该值保持不变-null,或者我最初设置它的值。代码如下:

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Scanner;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextArea;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class StartEvents implements ActionListener {
    StartPanel startingPanel;
    static String scoreOption;
    
    public StartEvents(StartPanel startPanel) {
        startingPanel = startPanel;
    }
    // Scoring System Window - 1
    public void scoringSystem() {
        startingPanel.scoringSystem.addActionListener(new ActionListener () {
            @Override
            public void actionPerformed(ActionEvent e) {
                Panel scoringSystemPanel = new Panel();
                JFrame scoreSystemFrame  = scoringSystemPanel.frame(150, 250, "Scoring System", 2, true);
                JPanel scoreSystemPanel = scoringSystemPanel.panel(Color.lightGray);
                JButton confirmSelection = scoringSystemPanel.button(40, 20, "Confirm");
                JRadioButton scoreSystem1 = scoringSystemPanel.radioButton("Option 1: Same Points Per Hit");    
                scoreSystem1.setActionCommand("Option 1");
                JRadioButton scoreSystem2 = scoringSystemPanel.radioButton("Option 2: Unique Points Per Hit");
                scoreSystem2.setActionCommand("Option 2");
                ButtonGroup scoreSys = new ButtonGroup();
                scoreSys.add(scoreSystem1);
                scoreSys.add(scoreSystem2);
                scoreSystemFrame.getContentPane().add(scoreSystemPanel);
                scoreSystemPanel.add(scoreSystem1);
                scoreSystemPanel.add(scoreSystem2);
                scoreSystemPanel.add(confirmSelection);
                
                // Get Selection Event
                // Option 1
                scoreSystem1.addActionListener(new ActionListener () {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        if (scoreSystem1.isSelected()) {
                            scoreOption = scoreSystem1.getActionCommand();
                        }
                    }
                });
                // Option 2
                scoreSystem2.addActionListener(new ActionListener () {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        if (scoreSystem2.isSelected()) {
                            scoreOption = scoreSystem2.getActionCommand();
                        }
                    }
                });
                // Confirm Event 
                confirmSelection.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        scoreSystemFrame.dispose();
                    }
                });
            }
        });
    }
调用scoringsystem方法的主游戏类

import java.util.ArrayList;

public class Game {

    public static void main(String[] args) {
        StartPanel startingPanel = new StartPanel();
        startingPanel.makeStartPanel();
        StartEvents starter = new StartEvents(startingPanel);
        starter.rulesButton();
        starter.exitButton();
        starter.highScoresButton();
        ArrayList<Integer> dimensions = starter.boardSizeSelector();
        
        // Problem Zone
        System.out.println(StartEvents.scoreOption);
        starter.scoringSystem();
        System.out.println(StartEvents.scoreOption);
        // The two values of scoreOption should be different
        
        String[] playPanelDetails = {"970", "Player 1", "450"};
        
        // Final Start of the Game
        starter.startGameButton(playPanelDetails, dimensions);
        
    }

}
import java.util.ArrayList;
公开课游戏{
公共静态void main(字符串[]args){
StartPanel startingPanel=新的StartPanel();
startingPanel.makeStartPanel();
StartEvents启动器=新的StartEvents(启动面板);
starter.rulesButton();
starter.exitButton();
starter.highScoresButton();
ArrayList维度=starter.boardSizeSelector();
//问题区
System.out.println(StartEvents.scoreOption);
starter.scoringSystem();
System.out.println(StartEvents.scoreOption);
//scoreOption的两个值应该不同
String[]playPanelDetails={“970”、“播放器1”、“450”};
//比赛的最后开始
启动机。启动按钮(播放面板详情、尺寸);
}
}
此外,关于以下问题,请告知我:

  • 建议在另一个“ActionListener”中实现“ActionListener”?良好做法
  • “actionPerformed”方法只能有一个声明,还是可以重载
  • 是否可以从“actionPerformed”方法获取返回值
  • 如果能提供一些提示,我将不胜感激。我真的试了很多,然后才把它贴在这里。事先非常感谢

    小编辑:当我在“System.out.println”中输入“actioncommand”时,它会在控制台中完美地工作。但当我尝试更新类变量,然后在方法调用后尝试打印它时,情况并非如此。不知道这是否有帮助。

    JFrames不是模态的——您创建一个并显示它,它不会阻止代码流,因此您在JFrames显示时提取scoreOption的值,在用户有机会更改它之前。您需要使用模态对话框,例如作为模态对话框创建的JDialog,或者使用JOptionPane(实际上只是引擎盖下的模态JDialog)。这将阻止代码流,以便您仅在用户更改数据后提取数据

    一个例子证明了这一点:

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    
    public class FooGui01 extends JPanel {
        private String frameTest = "";
        private String dialogTest = "";
        private JFrame mainFrame = new JFrame("Main GUI");
        
        private JFrame subFrame;
        private JDialog dialog;
    
        
        public FooGui01() {
            JButton showFrameBtn = new JButton("Show JFrame");
            showFrameBtn.addActionListener(e -> {
                changeTest1WithJFrame();
                System.out.println("frameTest: " + frameTest);
            });
            
            JButton showDialogBtn = new JButton("Show JDialog");
            showDialogBtn.addActionListener(e -> {
                changeTest2WithModalDialog();
                System.out.println("dialogTest: " + dialogTest);
            });
            
            JPanel panel = new JPanel();
            panel.add(showDialogBtn);
            panel.add(showFrameBtn);
            
            mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            mainFrame.add(panel);
            mainFrame.pack();
            mainFrame.setLocationByPlatform(true);
            mainFrame.setVisible(true);
            
        }
        
        public void changeTest1WithJFrame() {
    
            if (subFrame == null) {
                subFrame = new JFrame("Frame");
                JButton button = new JButton("Press me");
                button.addActionListener(e -> {
                    frameTest = "Hello World and frameTest";
                    subFrame.setVisible(false);
                });
    
                JPanel panel = new JPanel();
                panel.add(button);
                
                subFrame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
                subFrame.add(panel);
                subFrame.pack();
                subFrame.setLocationByPlatform(true);
            }
            subFrame.setVisible(true);
        }
        
        public void changeTest2WithModalDialog() {
            
            if (dialog == null) {       
                dialog = new JDialog(mainFrame, "Dialog", Dialog.ModalityType.APPLICATION_MODAL);
                JButton button = new JButton("Press me");
                button.addActionListener(e -> {
                    dialogTest = "Hello World and dialogTest";
                    dialog.setVisible(false);
                });
    
                JPanel panel = new JPanel();
                panel.add(button);
                
                dialog.add(panel);
                dialog.pack();
                dialog.setLocationByPlatform(true);
            }
            dialog.setVisible(true);
        }
            
        public static void main(String[] args) {
            SwingUtilities.invokeLater(() -> new FooGui01());
        }
    }
    
    如果您运行代码,当您显示子JFrame时,在处理对话框之前,测试文本将立即显示在控制台中。如果按下按钮以显示对话框,则测试文本显示将延迟到按下按钮后,从而更改文本


    按两次frame按钮将最终显示正确的文本,因为文本是在第一次显示时设置的。

    JDialig就像JFrame一样。也就是说,您可以像添加任何帧一样向其添加组件

    不同之处在于,您可以创建JDialog模式。这意味着当您使用:

    dialog.setVisible(true);
    System.out.println("here");
    
    在对话框关闭之前,setVisible(…)语句后面的代码不会执行。这也意味着在对话框关闭之前,您不能单击父JFrame

    创建
    模态JDialog
    的一种简单方法是使用
    JOptionPane
    。它有一些预定义的方法,可以方便地提示用户输入

    例如,在您的情况下,您可以执行以下操作:

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    
    public class SSCCE extends JPanel
    {
        private int scoringOption = -1;
    
        public SSCCE()
        {
            JButton button = new JButton("Change Points Option");
            add(button);
    
            button.addActionListener((e) -> displayOptionDialog());
        }
    
        private void displayOptionDialog()
        {
            Window window = SwingUtilities.windowForComponent( this );
    
            // Custom button text
    
            Object[] options = {"Option 1: Same Points Per Hit", "Option 2: Unique Points Per Hit"};
    
            scoringOption = JOptionPane.showOptionDialog(
                window,
                "Select your scoring option:",
                "Scoring Option",
                JOptionPane.YES_NO_CANCEL_OPTION,
                JOptionPane.QUESTION_MESSAGE,
                null,
                options,
                null);
    
            System.out.println( scoringOption );
        }
    
        private static void createAndShowGUI()
        {
            JFrame frame = new JFrame("SSCCE");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(new SSCCE());
            frame.pack();
            frame.setLocationByPlatform( true );
            frame.setVisible( true );
        }
    
        public static void main(String[] args) throws Exception
        {
            java.awt.EventQueue.invokeLater( () -> createAndShowGUI() );
        }
    }
    
    以上也是“MRE”的一个示例。代码很简单,包含在一个类中,您可以复制/粘贴/编译和测试

    阅读上Swing教程中的部分,了解更多使用
    JOptionPane
    的示例

    如果确实要使用单选按钮,则可以使用
    showConfirmDialog(…)
    方法创建包含单选按钮的面板,并将其显示在选项窗格中。当对话框关闭时,您需要从
    ButtonGroup
    ButtonModel
    获取操作命令


    请参阅:有关此方法的基本示例,以帮助您入门。

    请查看该链接,因为这是让其他人了解当前代码为何无法按预期工作的最佳方法。该链接将解释这是什么,如何创建一个,以及为什么它可以帮助您和我们。请注意,这不是对您的整个程序或无法运行的代码段的请求(如您现在提供的),而是一个我们可以运行的新的小演示程序,它向我们展示了问题所在。在我看来,我们无法从上面的代码中看出为什么scoreOption保持null,而JFrame不是模式窗口,您当然不希望在应用程序中显示多个jframe。也许您需要一个模态对话框窗口,比如模态JDialog,而不是JFrame。变量为null还有其他原因,例如变量阴影,但这是否发生是任何人的猜测。您能否至少向我们展示
    scoreOption
    的声明?关于ActionListener中的ActionListener,一般来说,这是可以的,但实际上这段代码应该被重新分解到不同的类中,更不用说不同的方法了。@DawoodibnKareem我添加了完整的类。这就是你想要的吗?请你用一种更具描述性的方式解释一下这个上下文中的“模态”。我相信我可以看出我哪里出了问题,但你是专业的,可以给我一点机会