class 方法调用后变量未更新
class variable not updating after method call
我对 Java 很陌生,只有在研究、谷歌搜索和阅读许多答案之后,我才发布这个。我有点迷路了。一点指导会有很大帮助。以下是 class 中实现“ActionListener”接口的方法。我想要做的是:有一个按钮,单击该按钮应该打开一个新的 window,其中包含两个单选按钮形式的两个选项。我需要知道为在我的代码中进一步使用而选择的单选按钮。我将“scoreOption”变量声明为 class 变量和静态变量,然后尝试在“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();
}
});
}
});
}
主游戏 Class 调用方法计分系统。
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);
}
}
此外,您能否就以下问题告诉我:
- 建议在另一个“ActionListener”中实现“ActionListener”?好的做法?
- “actionPerformed”方法只能声明一个还是也可以重载?
- 是否可以从“actionPerformed”方法中获取 return 值?
如果能提供一些提示,我将不胜感激。我真的尝试了很多,然后才把它贴在这里。非常感谢您。
小编辑:当我“System.out.println”那里的“actioncommand”时,它确实工作得很好,在控制台中打印。但是当我尝试更新 class 变量然后尝试在方法调用后打印它时,情况并非如此。不知道这是否有帮助。
JFrame 不是模态的——您创建一个并显示它,它不会阻塞代码流,因此您在显示 JFrame 时正确提取 scoreOption 的值 before 用户有机会更改它。您需要使用模态对话框,例如作为模态对话框创建的 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 时,测试文本会立即显示在控制台中 在 对话框处理之前。如果您按下按钮显示对话框,测试文本显示将延迟到按下按钮后,更改文本。
按两次框架按钮将最终显示正确的文本,因为文本是在第一次显示时设置的。
JDialig 就像 JFrame。那就是你像添加任何框架一样向它添加组件。
不同之处在于您可以制作 JDialog 模式。这意味着当您使用:
dialog.setVisible(true);
System.out.println("here");
setVisible(...) 语句之后的代码将在对话框关闭后才会执行。这也意味着您不能在对话框关闭之前单击父 JFrame。
创建 modal 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”的例子。代码很简单,包含在一个 class 中,您可以 copy/paste/compile 和测试。
阅读有关 How to Use Dialogs 的 Swing 教程部分,了解更多使用 JOptionPane
的示例。
如果你真的想使用单选按钮,那么你可以创建一个带有单选按钮的面板,并使用showConfirmDialog(...)
方法将它们显示在选项面板上。当对话框关闭时,您需要从 ButtonGroup
.
的 ButtonModel
获取操作命令
请参阅:how to set & manage the layout of JOptionPane 了解此方法的基本示例以帮助您入门。
我对 Java 很陌生,只有在研究、谷歌搜索和阅读许多答案之后,我才发布这个。我有点迷路了。一点指导会有很大帮助。以下是 class 中实现“ActionListener”接口的方法。我想要做的是:有一个按钮,单击该按钮应该打开一个新的 window,其中包含两个单选按钮形式的两个选项。我需要知道为在我的代码中进一步使用而选择的单选按钮。我将“scoreOption”变量声明为 class 变量和静态变量,然后尝试在“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();
}
});
}
});
}
主游戏 Class 调用方法计分系统。
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);
}
}
此外,您能否就以下问题告诉我:
- 建议在另一个“ActionListener”中实现“ActionListener”?好的做法?
- “actionPerformed”方法只能声明一个还是也可以重载?
- 是否可以从“actionPerformed”方法中获取 return 值?
如果能提供一些提示,我将不胜感激。我真的尝试了很多,然后才把它贴在这里。非常感谢您。
小编辑:当我“System.out.println”那里的“actioncommand”时,它确实工作得很好,在控制台中打印。但是当我尝试更新 class 变量然后尝试在方法调用后打印它时,情况并非如此。不知道这是否有帮助。
JFrame 不是模态的——您创建一个并显示它,它不会阻塞代码流,因此您在显示 JFrame 时正确提取 scoreOption 的值 before 用户有机会更改它。您需要使用模态对话框,例如作为模态对话框创建的 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 时,测试文本会立即显示在控制台中 在 对话框处理之前。如果您按下按钮显示对话框,测试文本显示将延迟到按下按钮后,更改文本。
按两次框架按钮将最终显示正确的文本,因为文本是在第一次显示时设置的。
JDialig 就像 JFrame。那就是你像添加任何框架一样向它添加组件。
不同之处在于您可以制作 JDialog 模式。这意味着当您使用:
dialog.setVisible(true);
System.out.println("here");
setVisible(...) 语句之后的代码将在对话框关闭后才会执行。这也意味着您不能在对话框关闭之前单击父 JFrame。
创建 modal 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”的例子。代码很简单,包含在一个 class 中,您可以 copy/paste/compile 和测试。
阅读有关 How to Use Dialogs 的 Swing 教程部分,了解更多使用 JOptionPane
的示例。
如果你真的想使用单选按钮,那么你可以创建一个带有单选按钮的面板,并使用showConfirmDialog(...)
方法将它们显示在选项面板上。当对话框关闭时,您需要从 ButtonGroup
.
ButtonModel
获取操作命令
请参阅:how to set & manage the layout of JOptionPane 了解此方法的基本示例以帮助您入门。