从另一个类访问静态变量

我在同一个包中有两个类。 我在一个类中声明了一个static variable ,并希望在另一个类中访问该变量。

这是我已经声明了静态变量的代码

 public class wampusGUI extends javax.swing.JFrame { static String userCommand; public wampusGUI() { initComponents(); } public void setTextArea(String text) { displayTextArea.append(text); } private void enterButtonActionPerformed(java.awt.event.ActionEvent evt) { userCommand = commandText.getText(); } public static void main(String args[]) { /* Create and display the form */ java.awt.EventQueue.invokeLater(new Runnable() { public void run() { wampusGUI w = new wampusGUI(); w.setVisible(true); Game g = new Game(w); g.play(); } }); } } 

这是我想要访问变量的代码

 public class Game { private wampusGUI gui; public Game(wampusGUI w) { world = new World(); world.start(); gui = w; } public void play() { gui.setTextArea(welcome()); gui.setTextArea(describe()); for (;;) { String s = userCommand; // here value should come should System.out.println(userCommand); Command c = Command.create(s); String r = c.perform(world); // is game over? if (r == null) { break; } System.out.println(r); } System.out.println("Game over"); } } 

但是,我可以将第一类中的变量作为参数传递。 但问题是,当我将运行程序时,值第一次为空,我不想要。 我希望当我在textfield输入值时,它应该转到另一个类。

谢谢。

我建议你使用一种或另一种的监听器来允许Game对象监听并响应GUI对象状态的变化。 有几种方法可以做到这一点,但我发现最优雅和最有用的方法之一是使用Swing自己的固有PropertyChangeSupport来允许你使用PropertyChangeListeners。 所有Swing组件都允许您向其添加PropertyChangeListener。 所以我建议你这样做,你有游戏添加一个到你的WampusGUI类(应该大写)对象,如下所示:

 public Game(WampusGUI w) { gui = w; gui.addPropertyChangeListener(new PropertyChangeListener() { // .... } 

这将允许Game监听gui状态的变化。

然后,您将要使gui的userCommand String成为“绑定属性”,这意味着为其提供一个setter方法,该方法将触发属性更改支持,通知所有侦听器发生更改。 我会这样做:

 public class WampusGUI extends JFrame { public static final String USER_COMMAND = "user command"; // .... private void setUserCommand(String userCommand) { String oldValue = this.userCommand; String newValue = userCommand; this.userCommand = userCommand; firePropertyChange(USER_COMMAND, oldValue, newValue); } 

然后你只能通过这个setter方法改变这个String的值:

 private void enterButtonActionPerformed(java.awt.event.ActionEvent evt) { setUserCommand(commandText.getText()); } 

游戏的属性更改侦听器会响应如下:

  gui.addPropertyChangeListener(new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent pcEvt) { // is the property being changed the one we're interested in? if (WampusGUI.USER_COMMAND.equals(pcEvt.getPropertyName())) { // get user command: String userCommand = pcEvt.getNewValue().toString(); // then we can do with it what we want play(userCommand); } } }); 

这种技术的优点之一是观察到的类GUI不必具有关于观察者类(游戏)的任何知识。 一个小的可运行的例子是这样的:

 import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.*; public class WampusGUI extends JFrame { public static final String USER_COMMAND = "user command"; private String userCommand; private JTextArea displayTextArea = new JTextArea(10, 30); private JTextField commandText = new JTextField(10); public WampusGUI() { initComponents(); } private void setUserCommand(String userCommand) { String oldValue = this.userCommand; String newValue = userCommand; this.userCommand = userCommand; firePropertyChange(USER_COMMAND, oldValue, newValue); } private void initComponents() { displayTextArea.setEditable(false); displayTextArea.setFocusable(false); JButton enterButton = new JButton("Enter Command"); enterButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { enterButtonActionPerformed(evt); } }); JPanel commandPanel = new JPanel(); commandPanel.add(commandText); commandPanel.add(Box.createHorizontalStrut(15)); commandPanel.add(enterButton); JPanel mainPanel = new JPanel(); mainPanel.setLayout(new BorderLayout()); mainPanel.add(new JScrollPane(displayTextArea)); mainPanel.add(commandPanel, BorderLayout.SOUTH); add(mainPanel); } public void setTextArea(String text) { displayTextArea.append(text); } private void enterButtonActionPerformed(java.awt.event.ActionEvent evt) { setUserCommand(commandText.getText()); } public static void main(String args[]) { java.awt.EventQueue.invokeLater(new Runnable() { public void run() { WampusGUI w = new WampusGUI(); w.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); w.pack(); w.setLocationRelativeTo(null); w.setVisible(true); Game g = new Game(w); g.play(); } }); } } class Game { private WampusGUI gui; public Game(WampusGUI w) { gui = w; gui.addPropertyChangeListener(new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent pcEvt) { // is the property being changed the one we're interested in? if (WampusGUI.USER_COMMAND.equals(pcEvt.getPropertyName())) { // get user command: String userCommand = pcEvt.getNewValue().toString(); // then we can do with it what we want play(userCommand); } } }); } public void play() { gui.setTextArea("Welcome!\n"); gui.setTextArea("Please enjoy the game!\n"); } public void play(String userCommand) { // here we can do what we want with the String. For instance we can display it in the gui: gui.setTextArea("User entered: " + userCommand + "\n"); } } 

查看代码,您似乎希望使用特定文本向用户显示对话框

 gui.setTextArea(welcome()); gui.setTextArea(describe()); 

有时,该对话框应捕获之后处理的用户输入。

  1. 那些setTextArea调用不是你想要使用的。 用户永远不会看到欢迎消息,因为它将立即被描述消息替换。
  2. 确保不阻止事件调度线程(EDT)或根本不显示任何内容。 我不知道你的Command类会做什么,但我在Event Dispatch Thread上看到一个无限循环,这绝不是一件好事。 有关更多信息,请查看Swurrency中的Concurrency教程
  3. 由于for循环,用户将无法输入任何命令,因为EDT忙于处理循环。 您需要的是一个阻止调用,允许用户提供输入(不阻止EDT,但只是阻止代码的执行)。 JOptionPane类中的静态方法非常适合这种方法(例如JOptionPane#showInputDialog )。 这些方法还有一种机制,可以将用户输入传递回调用代码,而无需任何静态变量,从而解决了您的问题。

我同意Jon Skeet认为这不是一个好的解决方案……

但是如果你想要一个肮脏的解决方案你的问题,那么你可以试试这个:

 public class wampusGUI extends javax.swing.JFrame { private static wampusGUI myInstance; public wampusGUI( ) { myInstance = this; initComponents(); } public static void getUserCommand() { if(myInstance!=null) { return myInstance.commandText.getText(); } else { return null; } } ...... ...... } 

在其他课程中使用:

 public void play() { ..... //String s = userCommand; // here value should come should String s = wampusGUI.getUserCommand(); ..... } 

这些代码存在于我们的一些遗留项目中……我讨厌这个。