简体   繁体   English

从另一个类访问静态变量

[英]Access static variable from another class

I have two classes in same package. 我在同一个包中有两个类。 i have declared a static variable in one class and want to access that variable in another class. 我在一个类中声明了一个static variable ,并希望在另一个类中访问该变量。

Here is my code in which i have declared the 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();
            }
        });
    }
}

Here is the code in which i want to access variable 这是我想要访问变量的代码

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");
    }
}

However, i can pass the variable from first class as a argument. 但是,我可以将第一类中的变量作为参数传递。 but the problem is that, when i will run program the value is going null first time, which i dont want. 但问题是,当我将运行程序时,值第一次为空,我不想要。 i want when i enter value in textfield then it should go to another class. 我希望当我在textfield输入值时,它应该转到另一个类。

Thank you. 谢谢。

Looking at your code, it seems you want to show dialogs to your user with a certain text 查看代码,您似乎希望使用特定文本向用户显示对话框

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

and sometimes, that dialog should capture user input which is handled afterwards. 有时,该对话框应该捕获之后处理的用户输入。

  1. Those setTextArea calls are not what you want to use. 那些setTextArea调用不是你想要使用的。 The user will never see the welcome message as it will immediately be replaced by the describe message. 用户永远不会看到欢迎消息,因为它将立即被描述消息替换。
  2. Make sure you do not block the Event Dispatch Thread (EDT) or nothing will be shown at all. 确保不阻止事件调度线程(EDT)或根本不显示任何内容。 I do not know what your Command class will do, but I see an infinite loop on the Event Dispatch Thread which is never a good thing. 我不知道你的Command类会做什么,但我看到Event Dispatch Thread上有一个无限循环,这绝不是一件好事。 Take a look at the Concurrency in Swing tutorial for more information 有关更多信息,请查看Swurrency中Concurrency教程
  3. Thanks to that for loop, the user will simply not be capable to input any command as the EDT is busy handling your loop. 由于for循环,用户将无法输入任何命令,因为EDT忙于处理循环。 What you need is a blocking call allowing the user to provide input (not blocking the EDT, but just blocking the execution of your code). 您需要的是一个阻止调用,允许用户提供输入(不阻止EDT,但只是阻止代码的执行)。 The static methods in the JOptionPane class are perfectly suited for this (eg the JOptionPane#showInputDialog ). JOptionPane类中的静态方法非常适合这种方法(例如JOptionPane#showInputDialog )。 These methods also have a mechanism to pass the user input back to the calling code without any static variables, which solves your problem. 这些方法还有一种机制,可以将用户输入传递回调用代码而不需要任何静态变量,从而解决了您的问题。

I suggest that you use a listener of one sort or another to allow the Game object to listen for and respond to changes in the state of the GUI object. 我建议你使用一种或另一种的监听器来允许Game对象监听并响应GUI对象状态的变化。 There are several ways to do this, but one of the most elegant and useful I've found is to use Swing's own innate PropertyChangeSupport to allow you to use PropertyChangeListeners. 有几种方法可以做到这一点,但我发现最优雅和最有用的方法之一是使用Swing自己的固有PropertyChangeSupport来允许你使用PropertyChangeListeners。 All Swing components will allow you to add a PropertyChangeListener to it. 所有Swing组件都允许您向其添加PropertyChangeListener。 And so I suggest that you do this, that you have Game add one to your WampusGUI class (which should be capitalized) object like so: 所以我建议你这样做,你有游戏添加一个到你的WampusGUI类(应该大写)对象,如下所示:

public Game(WampusGUI w) {
  gui = w;

  gui.addPropertyChangeListener(new PropertyChangeListener() {
     // ....
  }

This will allow Game to listen for changes in the gui's state. 这将允许游戏监听gui状态的变化。

You'll then want to make the gui's userCommand String a "bound property" which means giving it a setter method that will fire the property change support notifying all listeners of change. 然后,您将要使gui的userCommand String成为“绑定属性”,这意味着为其提供一个setter方法,该方法将触发属性更改支持,通知所有侦听器更改。 I would do this like so: 我会这样做:

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);
   } 

Then you would only change this String's value via this setter method: 然后你只能通过这个setter方法改变这个String的值:

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

The Game's property change listener would then respond like so: 游戏的属性更改侦听器会响应如下:

  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);

        }

     }
  });

One of the beauties of this technique is that the observed class, the GUI, doesn't have to have any knowledge about the observer class (the Game). 这种技术的优点之一是观察到的类GUI不必具有关于观察者类(游戏)的任何知识。 A small runnable example of this is like so: 一个小的可运行的例子是这样的:

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");
   }

}

I agree with Jon Skeet that this is not a good solution... 我同意Jon Skeet认为这不是一个好的解决方案......

But in case u want an dirty solution to ur problem then u can try this: 但是如果你想要一个解决问题的脏问题,那么你可以试试这个:

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;
        }
    }
    ......
    ......
}

in the other class use: 在其他课程中使用:

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

This kind of code is there in some of our legacy projects... and I hate this. 这些代码存在于我们的一些遗留项目中......我讨厌这个。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM