如何使对象的实例可供多个swing窗体访问?JAVA
我正在制作一个基于文本的RPG来帮助我学习Java。所以我现在有一堆不同的类来制作swing表单,每一个都会相互联系。然而,在一种形式中,我实际上创建了名为Player的对象的实例,我将根据用户的选择设置统计数据(强度、敏捷性、级别等) 但是,我只能在该类/窗口中访问该对象,并且不能在应用程序中的任何其他位置调用它来操作该对象 如何使其全球可访问 编辑如何使对象的实例可供多个swing窗体访问?JAVA,java,Java,我正在制作一个基于文本的RPG来帮助我学习Java。所以我现在有一堆不同的类来制作swing表单,每一个都会相互联系。然而,在一种形式中,我实际上创建了名为Player的对象的实例,我将根据用户的选择设置统计数据(强度、敏捷性、级别等) 但是,我只能在该类/窗口中访问该对象,并且不能在应用程序中的任何其他位置调用它来操作该对象 如何使其全球可访问 编辑 我应该用更恰当的措辞。假设我有一个名为PlayerCreation的类,在PlayerCreation中,我通过调用Player类Player
我应该用更恰当的措辞。假设我有一个名为PlayerCreation的类,在PlayerCreation中,我通过调用Player类Player p1=new Player()来创建一个对象;现在我完全离开了这个类,转到另一个叫做PlayerStats的表单,我想调用p1.getStrength();但是由于p1是在PlayerCreation类中,我无法获得它。我现在正在学习一个Java类,我认为我书中的这个示例将对您有所帮助。在本例中,他们采用了一个可公开访问的“rooms”类 使用单例模式。 如果你给你的班级一个字段,比如:
private static final int agility
或者任何你喜欢的变量,以及像这样的getter:
public static int getAgility() {
return agility;
}
new ClassNameYouChoose();
您可以在启动时按如下方式实例化该类:
public static int getAgility() {
return agility;
}
new ClassNameYouChoose();
您可以从任何地方访问getter:
int agility = ClassNameYouChoose();
注意,你不应该“滥用”这个;如果您决定在以后的游戏开发中更改某些内容,那么找出您在何处使用该类内容可能会非常具有挑战性。以下是我所说的示例。我稍后会添加一些文本,但如果您编译并运行此代码,您将看到它是如何工作的:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
public class DependInjectEg {
private static void createAndShowGui() {
Player[] players = {
new Player("John Smith", 10, 5),
new Player("Donald Duck", 8, 3),
new Player("Doris Day", 5, 2),
new Player("Bill Jones", 4, 6),
new Player("Frank Stein", 1, 1),
};
PlayerStats mainPanel = new PlayerStats();
for (Player player : players) {
mainPanel.addPlayer(player);
}
JFrame frame = new JFrame("Dependency Injection Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class Player {
private String name;
private int speed;
private int strength;
// default constructor
public Player() {
}
public Player(String name, int speed, int strength) {
this.name = name;
this.speed = speed;
this.strength = strength;
}
public int getStrength() {
return strength;
}
public void setStrength(int strength) {
this.strength = strength;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getSpeed() {
return speed;
}
public void setSpeed(int speed) {
this.speed = speed;
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("Name: " + name + ", ");
sb.append("Speed: " + speed + ", ");
sb.append("Strength: " + strength);
return sb.toString();
}
}
@SuppressWarnings("serial")
class PlayerStats extends JPanel {
private DefaultListModel playerListModel = new DefaultListModel();
private JList playerList = new JList(playerListModel);
public PlayerStats() {
JPanel btnPanel = new JPanel(new GridLayout(1, 0, 5, 0));
btnPanel.add(new JButton(new NewPlayerAction()));
btnPanel.add(new JButton(new EditPlayerAction()));
btnPanel.add(new JButton(new ExitAction()));
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder("Player Stats"),
BorderFactory.createEmptyBorder(5, 5, 5, 5)));
add(new JScrollPane(playerList));
add(Box.createVerticalStrut(5));
add(btnPanel);
}
public void addPlayer(Player player) {
playerListModel.addElement(player);
}
private class NewPlayerAction extends AbstractAction {
public NewPlayerAction() {
super("New Player");
putValue(MNEMONIC_KEY, KeyEvent.VK_N);
}
public void actionPerformed(ActionEvent evt) {
PlayerEditorPanel editorPanel = new PlayerEditorPanel();
int result = JOptionPane.showConfirmDialog(PlayerStats.this,
editorPanel, "Create Player", JOptionPane.OK_CANCEL_OPTION,
JOptionPane.PLAIN_MESSAGE);
if (result == JOptionPane.OK_OPTION) {
Player player = editorPanel.getNewPlayer();
playerListModel.addElement(player);
}
};
}
private class EditPlayerAction extends AbstractAction {
public EditPlayerAction() {
super("Edit Player");
putValue(MNEMONIC_KEY, KeyEvent.VK_E);
}
public void actionPerformed(ActionEvent evt) {
Player player = (Player) playerList.getSelectedValue();
if (player == null) {
return; // do nothing if no player selected
}
PlayerEditorPanel editorPanel = new PlayerEditorPanel();
editorPanel.setPlayer(player);
int result = JOptionPane.showConfirmDialog(PlayerStats.this,
editorPanel, "Edit Player", JOptionPane.OK_CANCEL_OPTION,
JOptionPane.PLAIN_MESSAGE);
if (result == JOptionPane.OK_OPTION) {
editorPanel.upDatePlayerAttributes();
playerList.repaint();
}
}
}
private class ExitAction extends AbstractAction {
public ExitAction() {
super("Exit");
putValue(MNEMONIC_KEY, KeyEvent.VK_X);
}
public void actionPerformed(ActionEvent e) {
Window win = SwingUtilities.getWindowAncestor(PlayerStats.this);
win.dispose();
}
}
}
@SuppressWarnings("serial")
class PlayerEditorPanel extends JPanel {
public static final String[] FIELD_TITLES = { "Name", "Speed", "Strength" };
private static final Insets WEST_INSETS = new Insets(5, 0, 5, 5);
private static final Insets EAST_INSETS = new Insets(5, 5, 5, 0);
private JTextField nameField = new JTextField(10);
private JTextField speedField = new JTextField(10);
private JTextField strengthField = new JTextField(10);
private JTextField[] fields = { nameField, speedField, strengthField };
private Player player;
public PlayerEditorPanel() {
setLayout(new GridBagLayout());
setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder("Player Editor"),
BorderFactory.createEmptyBorder(5, 5, 5, 5)));
GridBagConstraints gbc;
for (int i = 0; i < FIELD_TITLES.length; i++) {
gbc = createGbc(0, i);
add(new JLabel(FIELD_TITLES[i] + ":", JLabel.LEFT), gbc);
gbc = createGbc(1, i);
add(fields[i], gbc);
}
}
@SuppressWarnings("static-access")
private GridBagConstraints createGbc(int x, int y) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.gridwidth = 1;
gbc.gridheight = 1;
// bad coding habit using variable name to access static constants
// done for sake of brevity and clarity
gbc.anchor = (x == 0) ? gbc.WEST : gbc.EAST;
gbc.fill = (x == 0) ? gbc.BOTH : gbc.HORIZONTAL;
gbc.insets = (x == 0) ? WEST_INSETS : EAST_INSETS;
gbc.weightx = (x == 0) ? 0.1 : 1.0;
gbc.weighty = 1.0;
return gbc;
}
public void setPlayer(Player player) {
this.player = player;
nameField.setText(player.getName());
speedField.setText(String.valueOf(player.getSpeed()));
strengthField.setText(String.valueOf(player.getStrength()));
}
public Player getNewPlayer() {
String name = nameField.getText();
int strength = 0;
try {
strength = Integer.parseInt(strengthField.getText());
} catch (NumberFormatException e) {
// TODO: notify user that field was empty
}
int speed = 0;
try {
speed = Integer.parseInt(speedField.getText());
} catch (NumberFormatException e) {
// TODO: notify user that field was empty
}
Player p = new Player();
p.setName(name);
p.setSpeed(speed);
p.setStrength(strength);
return p;
}
public void upDatePlayerAttributes() {
String name = nameField.getText();
int strength = 0;
try {
strength = Integer.parseInt(strengthField.getText());
} catch (NumberFormatException e) {
// TODO: notify user that field was empty
}
int speed = 0;
try {
speed = Integer.parseInt(speedField.getText());
} catch (NumberFormatException e) {
// TODO: notify user that field was empty
}
player.setName(name);
player.setSpeed(speed);
player.setStrength(strength);
}
}
这将在JTextField中显示播放器的属性,并将设置一个内部私有变量Player来引用这个注入的播放器对象。这在PlayerStats类中调用,如下所示:
public void actionPerformed(ActionEvent evt) {
// *** first get the selected Player from the JList
Player player = (Player) playerList.getSelectedValue();
if (player == null) {
return; // do nothing if no player selected
}
// then create a PlayerEditorPanel object
PlayerEditorPanel editorPanel = new PlayerEditorPanel();
// and then "inject" the selected Player into the editor panel.
editorPanel.setPlayer(player);
// and display it in a JOptionPane
int result = JOptionPane.showConfirmDialog(PlayerStats.this,
editorPanel, "Edit Player", JOptionPane.OK_CANCEL_OPTION,
JOptionPane.PLAIN_MESSAGE);
if (result == JOptionPane.OK_OPTION) {
editorPanel.upDatePlayerAttributes();
playerList.repaint();
}
}
然后,如果您决定接受更改后的属性,则可以调用upDatePlayerAttributes()
方法,将这些属性赋予Player变量所持有的Player对象:
public void upDatePlayerAttributes() {
String name = nameField.getText();
int strength = 0;
try {
strength = Integer.parseInt(strengthField.getText());
} catch (NumberFormatException e) {
// TODO: notify user that field was empty
}
int speed = 0;
try {
speed = Integer.parseInt(speedField.getText());
} catch (NumberFormatException e) {
// TODO: notify user that field was empty
}
player.setName(name);
player.setSpeed(speed);
player.setStrength(strength);
}
有意义吗?可能重复-注意各种答案;依赖项注入通常是一种很好的方法。@Ben Allen:您将类公开了吗?@Brian的建议是:使用依赖项注入传递引用,就像对非GUI Java类传递引用一样。并继续遵循良好的面向对象指导原则,避免使用静态变量之类的东西。我应该更好地表达这一点。假设我有一个名为PlayerCreation的类,在PlayerCreation中,我通过调用Player类Player p1=new Player()来创建一个对象;现在我完全离开了这个类,转到另一个叫做PlayerStats的表单,我想调用p1.getStrength();但由于p1在PlayerCreation类中,我无法理解它。@HovercraftFullOfEels您对依赖注入有更好的解释吗?我很困惑:(他希望能够对修改类和游戏类中可访问的玩家对象进行更改。单例模式绝对不是解决这个问题的方法。同样,解决方案是通过依赖项注入。-1非常好,是的,这很有意义!非常感谢!