我在同一个封装中的两个班。 我已经声明了一个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
,那么它应该去到另一个阶级。
谢谢。
我建议你使用一种或另一种的听众,让游戏对象侦听和在GUI对象的状态的变化。 有几种方法可以做到这一点,但我已经找到了最优雅,最有效的方法之一是使用Swing的自己天生的PropertyChangeSupport,让您使用的PropertyChangeListeners。 所有Swing组件将允许你一个PropertyChangeListener添加到它。 所以,我建议你这样做,你有游戏添加一个到您的WampusGUI类(这应该是大写)对象,像这样:
public Game(WampusGUI w) {
gui = w;
gui.addPropertyChangeListener(new PropertyChangeListener() {
// ....
}
这将允许游戏监听在GUI中的状态变化。
然后,您会希望在GUI的userCommand字符串一个“绑定属性”,这意味着给它一个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);
}
然后,你就只能通过这种设置方法改变这个字符串的值:
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);
}
}
});
一个这种技术的美的是,观察到的类,图形用户界面,不必有关于观察者类(游戏)的任何知识。 这方面的一个可运行的小的例子是如下所示:
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());
有时,该对话框应该捕获它之后处理用户输入。
- 这些
setTextArea
电话是不是你想用什么。 用户将不会看到欢迎消息,因为它会立即被描述的消息所取代。 - 请确保您没有阻止事件分派线程(EDT),否则将无法在所有的显示。 我不知道你是什么
Command
类会做,但我看到在一个无限循环Event Dispatch Thread
这是从来没有一件好事。 看看的并发在Swing教程以获取更多信息 - 多亏了
for
循环,用户只需不能够输入任何命令作为EDT正忙于处理你的循环。 你需要的是一个阻塞调用允许用户提供输入(不堵EDT,但正好挡住你的代码的执行)。 在静态方法JOptionPane
类是完全适合这种(例如JOptionPane#showInputDialog
)。 这些方法也有一个机制,通过用户输入回没有任何静态变量调用代码,从而解决您的问题。
我乔恩斯基特同意,这是不是一个很好的解决方案...
但如果ü想的肮脏的解决方案,以乌尔问题,那么U可以试试这个:
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();
.....
}
这种代码是有一些我们的传统项目的...我讨厌这一点。