启用另一个 JBUtton 时禁用一个 JButton
Disable one JButton when another JBUtton is enabled
我正在尝试为我的作业构建一个简单的掷骰子游戏。将有2名球员。在我的代码中,我尝试使用方法 getSource()
以便当玩家 roll
JButton 启用时,其他玩家的按钮将被禁用,但是当我 运行 游戏时,两个玩家的按钮仍然启用.这是我的代码:
Die.java
import java.util.*;
public class Die
{
private final int MAX = 6;
private int die1;
Random rand = new Random();
//Constructor
public Die()
{
die1 = 1;
}// end Constructor
public int Roll()
{
die1 = rand.nextInt(MAX)+1;
return die1;
}
}
DisplaySixNumbersPanel.java
import java.awt.*;
import javax.swing.*;
public class DisplaySixNumbersPanel
{
public static void main(String[ ] args)
{
JFrame w1 = new JFrame("Six Numbers Game");
w1.setLayout(new GridLayout(1,2));
SixNumbersPanel2 player1 =new SixNumbersPanel2();
SixNumbersPanel2 player2 =new SixNumbersPanel2();
w1.add(player1);
w1.add(player2);
w1.setSize(540, 350);
w1.setVisible(true);
w1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
} //end main
} //end class
SixNumbersPanel2.java
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.*;
public class SixNumbersPanel2 extends JPanel implements ActionListener
{
private JTextField text1;
private boolean flag = false;
private boolean checkflag[] = {false,false,false,false,false,false,false};
private JLabel label;
private JLabel label1;
public JButton roll;
private JButton restartButton;
private JTextArea display;
private JTextField[] fields = new JTextField[7];
private Die dice = new Die();
private int key;
private int count;
private int count1;
private Player player1 = new Player();
private Player player2 = new Player();
private int check;
private int[] list = new int [7];
//private SixNumbersPanel2 player2panel;
public SixNumbersPanel2()
{
label= new JLabel ("A number between 1 to 6 wil appear");
label1 = new JLabel("once in each of the following textfields");
roll = new JButton("Roll dice");
restartButton = new JButton("Restart Game");
text1 = new JTextField(3);
display = new JTextArea(10,15);
add(label);
add(label1);
for(int i=1;i<7;i++)
{
fields[i] = new JTextField(3);
add(fields[i]);
}
add(roll);
add(text1);
add(display);
display.setEditable(false);
restartButton.setVisible(false);
add(restartButton);
restartButton.addActionListener(this);
roll.addActionListener(this);
}
public void restart()
{
display.setText("");
text1.setText("");
for(int i=1; i<7; i++)
{
fields[i].setText("");
}
count=0;
count1=0;
Arrays.fill(checkflag,false);
Arrays.fill(list,0);
flag = false;
restartButton.setVisible(false);
rollenable();
}
public void actionPerformed(ActionEvent event)
{
if(event.getSource() == roll)
{
player2.rolldisable();
}
key=dice.Roll();
count++;
String toScreen= "Number of rolls: "+count;
display.setText(toScreen);
text1.setText(""+key);
check = player1.Check(list,key);
if(check < 0)
{
count1++;
for(int i=1;i<7;i++)
{
if(key == i)
{
list[i] = key;
checkflag[i]=true;
fields[i].setText(""+key);
if(checkflag[i] == true)
{
flag = true;
for(int a=1; a<7; a++)
{
if(checkflag[a]==false)
{
flag=false;
}
}
}
}
if(flag == true)
{
display.setText("Congratulation, you have \ntaken "+count+" rolls to get one of \neach number between 1 and 6");
rolldisable();
restartButton.setVisible(true);
}
}
}
if(event.getSource() == restartButton)
{
restart();
}
}
public void rollenable()
{
roll.setEnabled(true);
}
public void rolldisable()
{
roll.setEnabled(false);
}
public JButton getSubButton()
{
return this.roll;
}
}
Player.java
import java.util.*;
import javax.swing.*;
public class Player
{
private final int MAX = 100;
private Die play = new Die();
private boolean[] results = {false,false,false,false,false,false,false};
private int count;
private int key;
private boolean check = false;
//private JButton roll;
public Player()
{
count=0;
key=0;
}
public void Play()
{
for(int i=0;i<MAX;i++)
{
key=play.Roll();
System.out.print("\nNumber rolled: "+key);
count++;
for(int a=1;a<7;a++)
{
if(a==key)
{
results[a]=true;
System.out.print("\nSo far, you have rolled ");
if(results[a]==true)
{
check=true;
for(int k=1;k<7;k++)
{
if(results[k] ==true)
{
System.out.print(" "+k+" ");
}
if(results[k] == false)
check=false;
}
}
}
}
if(check==true)
{
System.out.print("\nCongratulations, you have taken "+count+" rolls to get one of each number between 1 and 6");
break;
}
}
}
public int Check(int []check,int key)
{
int check1= Arrays.binarySearch(check,key);
return check1;
}
//public JButton getButton()
//{
// JButton button = null;
//SixNumbersPanel2 roll = new SixNumbersPanel2();
//return roll.roll = button;
//}
public void rolldisable()
{
SixNumbersPanel2 dis = new SixNumbersPanel2();
dis.getSubButton().setEnabled(false);
}
}
还有 restartButton
JButton,它不会重新启动整个游戏,只会为点击它的玩家重新启动。关于如何让它重新启动整个 GUI 的任何建议都很棒。
我们将不胜感激。
这个...
public void rolldisable()
{
SixNumbersPanel2 dis = new SixNumbersPanel2();
dis.getSubButton().setEnabled(false);
}
是错误的,基本上你正在创建 SixNumbersPanel2
的新实例并试图改变它的状态,但它实际上并没有显示在屏幕上,也与屏幕上显示的内容没有任何关系屏幕。
这个解决方案并不简单。您需要的是某种 model/controller,它可以在 SixNumbersPanel2
的两个实例之间共享,并生成它们可以响应的适当状态事件。
您需要设计一些方法来识别哪个玩家是哪个玩家,这样每个 SixNumbersPanel2
都知道它代表哪个玩家以及哪个玩家当前处于活动状态
已更新...
为了实现所需的功能更改,您需要某种 "central" 集线器,它管理核心功能并且可以在状态以某种有意义的方式更改时生成 notification/events(就像下一个玩家回合一样)
从广义上讲,这些包括:
首先,我们需要从某种令牌入手,区分玩家...
enum Player {
ONE, TWO;
}
接下来,我们需要某种"model",用于管理数据和核心功能
public interface SixNumbersModel {
public Player getCurrentTurn();
public Player nextTurn();
public int roll();
public boolean hasWon(Player player);
public Set<Integer> getPlayerResults(Player player);
public int getTurnsCount(Player player);
public void addChangeListener(ChangeListener listener);
public void removeChangeListener(ChangeListener listener);
}
nb:你实际上可以有一个 "player model" 来管理结果,但我很懒惰
我从 interface
开始的原因是模型的用户不应该关心模型是如何实现的(实现可能会将每个玩家结果的管理分离到单独的模型中,但是模型的用户SixNumbersModel
不在乎)
public class DefaultSizeNumbersModel implements SixNumbersModel {
private List<ChangeListener> changeListeners;
private Die die = new Die();
private Player turn;
private Map<Player, Set<Integer>> results;
private Map<Player, Integer> turns;
public DefaultSizeNumbersModel() {
changeListeners = new ArrayList<>(2);
results = new HashMap<>();
results.put(Player.ONE, new HashSet<>(6));
results.put(Player.TWO, new HashSet<>(6));
turns = new HashMap<>(2);
turns.put(Player.ONE, 0);
turns.put(Player.TWO, 0);
setCurrentTurn(Player.ONE);
}
@Override
public Player getCurrentTurn() {
return turn;
}
protected void setCurrentTurn(Player player) {
turn = player;
}
@Override
public Player nextTurn() {
switch (getCurrentTurn()) {
case ONE:
setCurrentTurn(Player.TWO);
break;
case TWO:
setCurrentTurn(Player.ONE);
break;
default:
setCurrentTurn(Player.ONE);
break;
}
fireStateChanged();
return getCurrentTurn();
}
@Override
public int roll() {
incrementTurnCount(getCurrentTurn());
int result = die.Roll();
Set<Integer> playerResults = results.get(getCurrentTurn());
playerResults.add(result);
return result;
}
@Override
public boolean hasWon(Player player) {
Set<Integer> playerResults = results.get(getCurrentTurn());
return playerResults.size() == 5; // 0...5
}
@Override
public Set<Integer> getPlayerResults(Player player) {
Set<Integer> actualResults = results.get(player);
Set<Integer> copy = new HashSet<>(actualResults);
return copy;
}
@Override
public int getTurnsCount(Player player) {
return turns.get(player);
}
protected void setTurnsCount(Player player, int count) {
turns.put(player, count);
}
protected void incrementTurnCount(Player player) {
int count = getTurnsCount(player);
count++;
setTurnsCount(player, count);
}
@Override
public void addChangeListener(ChangeListener listener) {
changeListeners.add(listener);
}
@Override
public void removeChangeListener(ChangeListener listener) {
changeListeners.remove(listener);
}
protected void fireStateChanged() {
ChangeEvent evt = new ChangeEvent(this);
for (ChangeListener listener : changeListeners) {
listener.stateChanged(evt);
}
}
}
然后我们需要某种 "view"...
public class SixNumbersPanel extends JPanel {
private Player player;
private SixNumbersModel model;
private JButton roll;
private JTextArea ta;
public SixNumbersPanel(Player player, SixNumbersModel model) {
this.player = player;
this.model = model;
model.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
roll.setEnabled(player == model.getCurrentTurn());
}
});
roll = new JButton("Roll");
ta = new JTextArea(5, 10);
roll.setEnabled(player == model.getCurrentTurn());
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(new JLabel(player.name()), gbc);
add(roll, gbc);
gbc.weightx = 1;
gbc.weighty = 1;
gbc.fill = GridBagConstraints.BOTH;
add(new JScrollPane(ta), gbc);
roll.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int result = model.roll();
ta.append(Integer.toString(result) + "\n");
if (model.hasWon(player)) {
JOptionPane.showMessageDialog(SixNumbersPanel.this, player + " has won");
}
model.nextTurn();
}
});
}
}
好的,非常基础,但是,它只有一个按钮和一个文本区域。它向模型注册兴趣,以便在状态更改时收到通知,并确保仅当它代表的玩家是当前玩家时才启用该按钮。
可运行示例...
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class Test {
public static void main(String[] args) {
new Test();
}
enum Player {
ONE, TWO;
}
public interface SixNumbersModel {
public Player getCurrentTurn();
public Player nextTurn();
public int roll();
public boolean hasWon(Player player);
public Set<Integer> getPlayerResults(Player player);
public int getTurnsCount(Player player);
public void addChangeListener(ChangeListener listener);
public void removeChangeListener(ChangeListener listener);
}
public class DefaultSizeNumbersModel implements SixNumbersModel {
private List<ChangeListener> changeListeners;
private Die die = new Die();
private Player turn;
private Map<Player, Set<Integer>> results;
private Map<Player, Integer> turns;
public DefaultSizeNumbersModel() {
changeListeners = new ArrayList<>(2);
results = new HashMap<>();
results.put(Player.ONE, new HashSet<>(6));
results.put(Player.TWO, new HashSet<>(6));
turns = new HashMap<>(2);
turns.put(Player.ONE, 0);
turns.put(Player.TWO, 0);
setCurrentTurn(Player.ONE);
}
@Override
public Player getCurrentTurn() {
return turn;
}
protected void setCurrentTurn(Player player) {
turn = player;
}
@Override
public Player nextTurn() {
switch (getCurrentTurn()) {
case ONE:
setCurrentTurn(Player.TWO);
break;
case TWO:
setCurrentTurn(Player.ONE);
break;
default:
setCurrentTurn(Player.ONE);
break;
}
fireStateChanged();
return getCurrentTurn();
}
@Override
public int roll() {
incrementTurnCount(getCurrentTurn());
int result = die.Roll();
Set<Integer> playerResults = results.get(getCurrentTurn());
playerResults.add(result);
return result;
}
@Override
public boolean hasWon(Player player) {
Set<Integer> playerResults = results.get(getCurrentTurn());
return playerResults.size() == 5; // 0...5
}
@Override
public Set<Integer> getPlayerResults(Player player) {
Set<Integer> actualResults = results.get(player);
Set<Integer> copy = new HashSet<>(actualResults);
return copy;
}
@Override
public int getTurnsCount(Player player) {
return turns.get(player);
}
protected void setTurnsCount(Player player, int count) {
turns.put(player, count);
}
protected void incrementTurnCount(Player player) {
int count = getTurnsCount(player);
count++;
setTurnsCount(player, count);
}
@Override
public void addChangeListener(ChangeListener listener) {
changeListeners.add(listener);
}
@Override
public void removeChangeListener(ChangeListener listener) {
changeListeners.remove(listener);
}
protected void fireStateChanged() {
ChangeEvent evt = new ChangeEvent(this);
for (ChangeListener listener : changeListeners) {
listener.stateChanged(evt);
}
}
}
public class Die {
private final int MAX = 6;
private int die1;
Random rand = new Random();
//Constructor
public Die() {
die1 = 1;
}// end Constructor
public int Roll() {
die1 = rand.nextInt(MAX) + 1;
return die1;
}
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame("Roll Six");
frame.setLayout(new GridLayout(2, 0));
SixNumbersModel model = new DefaultSizeNumbersModel();
SixNumbersPanel onePane = new SixNumbersPanel(Player.ONE, model);
SixNumbersPanel twoPane = new SixNumbersPanel(Player.TWO, model);
frame.add(onePane);
frame.add(twoPane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class SixNumbersPanel extends JPanel {
private Player player;
private SixNumbersModel model;
private JButton roll;
private JTextArea ta;
public SixNumbersPanel(Player player, SixNumbersModel model) {
this.player = player;
this.model = model;
model.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
roll.setEnabled(player == model.getCurrentTurn());
}
});
roll = new JButton("Roll");
ta = new JTextArea(5, 10);
roll.setEnabled(player == model.getCurrentTurn());
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(new JLabel(player.name()), gbc);
add(roll, gbc);
gbc.weightx = 1;
gbc.weighty = 1;
gbc.fill = GridBagConstraints.BOTH;
add(new JScrollPane(ta), gbc);
roll.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int result = model.roll();
ta.append(Integer.toString(result) + "\n");
if (model.hasWon(player)) {
JOptionPane.showMessageDialog(SixNumbersPanel.this, player + " has won");
}
model.nextTurn();
}
});
}
}
}
我正在尝试为我的作业构建一个简单的掷骰子游戏。将有2名球员。在我的代码中,我尝试使用方法 getSource()
以便当玩家 roll
JButton 启用时,其他玩家的按钮将被禁用,但是当我 运行 游戏时,两个玩家的按钮仍然启用.这是我的代码:
Die.java
import java.util.*;
public class Die
{
private final int MAX = 6;
private int die1;
Random rand = new Random();
//Constructor
public Die()
{
die1 = 1;
}// end Constructor
public int Roll()
{
die1 = rand.nextInt(MAX)+1;
return die1;
}
}
DisplaySixNumbersPanel.java
import java.awt.*;
import javax.swing.*;
public class DisplaySixNumbersPanel
{
public static void main(String[ ] args)
{
JFrame w1 = new JFrame("Six Numbers Game");
w1.setLayout(new GridLayout(1,2));
SixNumbersPanel2 player1 =new SixNumbersPanel2();
SixNumbersPanel2 player2 =new SixNumbersPanel2();
w1.add(player1);
w1.add(player2);
w1.setSize(540, 350);
w1.setVisible(true);
w1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
} //end main
} //end class
SixNumbersPanel2.java
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.*;
public class SixNumbersPanel2 extends JPanel implements ActionListener
{
private JTextField text1;
private boolean flag = false;
private boolean checkflag[] = {false,false,false,false,false,false,false};
private JLabel label;
private JLabel label1;
public JButton roll;
private JButton restartButton;
private JTextArea display;
private JTextField[] fields = new JTextField[7];
private Die dice = new Die();
private int key;
private int count;
private int count1;
private Player player1 = new Player();
private Player player2 = new Player();
private int check;
private int[] list = new int [7];
//private SixNumbersPanel2 player2panel;
public SixNumbersPanel2()
{
label= new JLabel ("A number between 1 to 6 wil appear");
label1 = new JLabel("once in each of the following textfields");
roll = new JButton("Roll dice");
restartButton = new JButton("Restart Game");
text1 = new JTextField(3);
display = new JTextArea(10,15);
add(label);
add(label1);
for(int i=1;i<7;i++)
{
fields[i] = new JTextField(3);
add(fields[i]);
}
add(roll);
add(text1);
add(display);
display.setEditable(false);
restartButton.setVisible(false);
add(restartButton);
restartButton.addActionListener(this);
roll.addActionListener(this);
}
public void restart()
{
display.setText("");
text1.setText("");
for(int i=1; i<7; i++)
{
fields[i].setText("");
}
count=0;
count1=0;
Arrays.fill(checkflag,false);
Arrays.fill(list,0);
flag = false;
restartButton.setVisible(false);
rollenable();
}
public void actionPerformed(ActionEvent event)
{
if(event.getSource() == roll)
{
player2.rolldisable();
}
key=dice.Roll();
count++;
String toScreen= "Number of rolls: "+count;
display.setText(toScreen);
text1.setText(""+key);
check = player1.Check(list,key);
if(check < 0)
{
count1++;
for(int i=1;i<7;i++)
{
if(key == i)
{
list[i] = key;
checkflag[i]=true;
fields[i].setText(""+key);
if(checkflag[i] == true)
{
flag = true;
for(int a=1; a<7; a++)
{
if(checkflag[a]==false)
{
flag=false;
}
}
}
}
if(flag == true)
{
display.setText("Congratulation, you have \ntaken "+count+" rolls to get one of \neach number between 1 and 6");
rolldisable();
restartButton.setVisible(true);
}
}
}
if(event.getSource() == restartButton)
{
restart();
}
}
public void rollenable()
{
roll.setEnabled(true);
}
public void rolldisable()
{
roll.setEnabled(false);
}
public JButton getSubButton()
{
return this.roll;
}
}
Player.java
import java.util.*;
import javax.swing.*;
public class Player
{
private final int MAX = 100;
private Die play = new Die();
private boolean[] results = {false,false,false,false,false,false,false};
private int count;
private int key;
private boolean check = false;
//private JButton roll;
public Player()
{
count=0;
key=0;
}
public void Play()
{
for(int i=0;i<MAX;i++)
{
key=play.Roll();
System.out.print("\nNumber rolled: "+key);
count++;
for(int a=1;a<7;a++)
{
if(a==key)
{
results[a]=true;
System.out.print("\nSo far, you have rolled ");
if(results[a]==true)
{
check=true;
for(int k=1;k<7;k++)
{
if(results[k] ==true)
{
System.out.print(" "+k+" ");
}
if(results[k] == false)
check=false;
}
}
}
}
if(check==true)
{
System.out.print("\nCongratulations, you have taken "+count+" rolls to get one of each number between 1 and 6");
break;
}
}
}
public int Check(int []check,int key)
{
int check1= Arrays.binarySearch(check,key);
return check1;
}
//public JButton getButton()
//{
// JButton button = null;
//SixNumbersPanel2 roll = new SixNumbersPanel2();
//return roll.roll = button;
//}
public void rolldisable()
{
SixNumbersPanel2 dis = new SixNumbersPanel2();
dis.getSubButton().setEnabled(false);
}
}
还有 restartButton
JButton,它不会重新启动整个游戏,只会为点击它的玩家重新启动。关于如何让它重新启动整个 GUI 的任何建议都很棒。
我们将不胜感激。
这个...
public void rolldisable()
{
SixNumbersPanel2 dis = new SixNumbersPanel2();
dis.getSubButton().setEnabled(false);
}
是错误的,基本上你正在创建 SixNumbersPanel2
的新实例并试图改变它的状态,但它实际上并没有显示在屏幕上,也与屏幕上显示的内容没有任何关系屏幕。
这个解决方案并不简单。您需要的是某种 model/controller,它可以在 SixNumbersPanel2
的两个实例之间共享,并生成它们可以响应的适当状态事件。
您需要设计一些方法来识别哪个玩家是哪个玩家,这样每个 SixNumbersPanel2
都知道它代表哪个玩家以及哪个玩家当前处于活动状态
已更新...
为了实现所需的功能更改,您需要某种 "central" 集线器,它管理核心功能并且可以在状态以某种有意义的方式更改时生成 notification/events(就像下一个玩家回合一样)
从广义上讲,这些包括:
首先,我们需要从某种令牌入手,区分玩家...
enum Player {
ONE, TWO;
}
接下来,我们需要某种"model",用于管理数据和核心功能
public interface SixNumbersModel {
public Player getCurrentTurn();
public Player nextTurn();
public int roll();
public boolean hasWon(Player player);
public Set<Integer> getPlayerResults(Player player);
public int getTurnsCount(Player player);
public void addChangeListener(ChangeListener listener);
public void removeChangeListener(ChangeListener listener);
}
nb:你实际上可以有一个 "player model" 来管理结果,但我很懒惰
我从 interface
开始的原因是模型的用户不应该关心模型是如何实现的(实现可能会将每个玩家结果的管理分离到单独的模型中,但是模型的用户SixNumbersModel
不在乎)
public class DefaultSizeNumbersModel implements SixNumbersModel {
private List<ChangeListener> changeListeners;
private Die die = new Die();
private Player turn;
private Map<Player, Set<Integer>> results;
private Map<Player, Integer> turns;
public DefaultSizeNumbersModel() {
changeListeners = new ArrayList<>(2);
results = new HashMap<>();
results.put(Player.ONE, new HashSet<>(6));
results.put(Player.TWO, new HashSet<>(6));
turns = new HashMap<>(2);
turns.put(Player.ONE, 0);
turns.put(Player.TWO, 0);
setCurrentTurn(Player.ONE);
}
@Override
public Player getCurrentTurn() {
return turn;
}
protected void setCurrentTurn(Player player) {
turn = player;
}
@Override
public Player nextTurn() {
switch (getCurrentTurn()) {
case ONE:
setCurrentTurn(Player.TWO);
break;
case TWO:
setCurrentTurn(Player.ONE);
break;
default:
setCurrentTurn(Player.ONE);
break;
}
fireStateChanged();
return getCurrentTurn();
}
@Override
public int roll() {
incrementTurnCount(getCurrentTurn());
int result = die.Roll();
Set<Integer> playerResults = results.get(getCurrentTurn());
playerResults.add(result);
return result;
}
@Override
public boolean hasWon(Player player) {
Set<Integer> playerResults = results.get(getCurrentTurn());
return playerResults.size() == 5; // 0...5
}
@Override
public Set<Integer> getPlayerResults(Player player) {
Set<Integer> actualResults = results.get(player);
Set<Integer> copy = new HashSet<>(actualResults);
return copy;
}
@Override
public int getTurnsCount(Player player) {
return turns.get(player);
}
protected void setTurnsCount(Player player, int count) {
turns.put(player, count);
}
protected void incrementTurnCount(Player player) {
int count = getTurnsCount(player);
count++;
setTurnsCount(player, count);
}
@Override
public void addChangeListener(ChangeListener listener) {
changeListeners.add(listener);
}
@Override
public void removeChangeListener(ChangeListener listener) {
changeListeners.remove(listener);
}
protected void fireStateChanged() {
ChangeEvent evt = new ChangeEvent(this);
for (ChangeListener listener : changeListeners) {
listener.stateChanged(evt);
}
}
}
然后我们需要某种 "view"...
public class SixNumbersPanel extends JPanel {
private Player player;
private SixNumbersModel model;
private JButton roll;
private JTextArea ta;
public SixNumbersPanel(Player player, SixNumbersModel model) {
this.player = player;
this.model = model;
model.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
roll.setEnabled(player == model.getCurrentTurn());
}
});
roll = new JButton("Roll");
ta = new JTextArea(5, 10);
roll.setEnabled(player == model.getCurrentTurn());
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(new JLabel(player.name()), gbc);
add(roll, gbc);
gbc.weightx = 1;
gbc.weighty = 1;
gbc.fill = GridBagConstraints.BOTH;
add(new JScrollPane(ta), gbc);
roll.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int result = model.roll();
ta.append(Integer.toString(result) + "\n");
if (model.hasWon(player)) {
JOptionPane.showMessageDialog(SixNumbersPanel.this, player + " has won");
}
model.nextTurn();
}
});
}
}
好的,非常基础,但是,它只有一个按钮和一个文本区域。它向模型注册兴趣,以便在状态更改时收到通知,并确保仅当它代表的玩家是当前玩家时才启用该按钮。
可运行示例...
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class Test {
public static void main(String[] args) {
new Test();
}
enum Player {
ONE, TWO;
}
public interface SixNumbersModel {
public Player getCurrentTurn();
public Player nextTurn();
public int roll();
public boolean hasWon(Player player);
public Set<Integer> getPlayerResults(Player player);
public int getTurnsCount(Player player);
public void addChangeListener(ChangeListener listener);
public void removeChangeListener(ChangeListener listener);
}
public class DefaultSizeNumbersModel implements SixNumbersModel {
private List<ChangeListener> changeListeners;
private Die die = new Die();
private Player turn;
private Map<Player, Set<Integer>> results;
private Map<Player, Integer> turns;
public DefaultSizeNumbersModel() {
changeListeners = new ArrayList<>(2);
results = new HashMap<>();
results.put(Player.ONE, new HashSet<>(6));
results.put(Player.TWO, new HashSet<>(6));
turns = new HashMap<>(2);
turns.put(Player.ONE, 0);
turns.put(Player.TWO, 0);
setCurrentTurn(Player.ONE);
}
@Override
public Player getCurrentTurn() {
return turn;
}
protected void setCurrentTurn(Player player) {
turn = player;
}
@Override
public Player nextTurn() {
switch (getCurrentTurn()) {
case ONE:
setCurrentTurn(Player.TWO);
break;
case TWO:
setCurrentTurn(Player.ONE);
break;
default:
setCurrentTurn(Player.ONE);
break;
}
fireStateChanged();
return getCurrentTurn();
}
@Override
public int roll() {
incrementTurnCount(getCurrentTurn());
int result = die.Roll();
Set<Integer> playerResults = results.get(getCurrentTurn());
playerResults.add(result);
return result;
}
@Override
public boolean hasWon(Player player) {
Set<Integer> playerResults = results.get(getCurrentTurn());
return playerResults.size() == 5; // 0...5
}
@Override
public Set<Integer> getPlayerResults(Player player) {
Set<Integer> actualResults = results.get(player);
Set<Integer> copy = new HashSet<>(actualResults);
return copy;
}
@Override
public int getTurnsCount(Player player) {
return turns.get(player);
}
protected void setTurnsCount(Player player, int count) {
turns.put(player, count);
}
protected void incrementTurnCount(Player player) {
int count = getTurnsCount(player);
count++;
setTurnsCount(player, count);
}
@Override
public void addChangeListener(ChangeListener listener) {
changeListeners.add(listener);
}
@Override
public void removeChangeListener(ChangeListener listener) {
changeListeners.remove(listener);
}
protected void fireStateChanged() {
ChangeEvent evt = new ChangeEvent(this);
for (ChangeListener listener : changeListeners) {
listener.stateChanged(evt);
}
}
}
public class Die {
private final int MAX = 6;
private int die1;
Random rand = new Random();
//Constructor
public Die() {
die1 = 1;
}// end Constructor
public int Roll() {
die1 = rand.nextInt(MAX) + 1;
return die1;
}
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame("Roll Six");
frame.setLayout(new GridLayout(2, 0));
SixNumbersModel model = new DefaultSizeNumbersModel();
SixNumbersPanel onePane = new SixNumbersPanel(Player.ONE, model);
SixNumbersPanel twoPane = new SixNumbersPanel(Player.TWO, model);
frame.add(onePane);
frame.add(twoPane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class SixNumbersPanel extends JPanel {
private Player player;
private SixNumbersModel model;
private JButton roll;
private JTextArea ta;
public SixNumbersPanel(Player player, SixNumbersModel model) {
this.player = player;
this.model = model;
model.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
roll.setEnabled(player == model.getCurrentTurn());
}
});
roll = new JButton("Roll");
ta = new JTextArea(5, 10);
roll.setEnabled(player == model.getCurrentTurn());
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(new JLabel(player.name()), gbc);
add(roll, gbc);
gbc.weightx = 1;
gbc.weighty = 1;
gbc.fill = GridBagConstraints.BOTH;
add(new JScrollPane(ta), gbc);
roll.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int result = model.roll();
ta.append(Integer.toString(result) + "\n");
if (model.hasWon(player)) {
JOptionPane.showMessageDialog(SixNumbersPanel.this, player + " has won");
}
model.nextTurn();
}
});
}
}
}