我對Java併發性比較陌生,這是我的這種性質的第一個應用程序之一。如何使用按鈕單擊刪除並替換JPanel?
我一直在試圖添加一個名爲Panel of Dice的自定義JPanel,當單擊一個按鈕「Throw」時,它顯示隨機生成的5個骰子面。我使用了兩個SwingWorker Threads HumanPlayer和SystemPlayer,它們更新了它們自己的throws,並使用上面的面板在JFrame上顯示結果。
但預期的面板替換不能按預期工作。以下是不完整的Throw按鈕ActionListener實現。有人可以指出我的代碼問題嗎?
this.throwButton = new JButton("Throw");
this.throwButton.addActionListener(
new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
int throwNumber = throwCount % 3;
if(throwNumber == 1 || throwNumber == 2) {
int response = JOptionPane.showConfirmDialog(null, "Do you want to reroll?");
if(response == 0) {
int number = Integer.parseInt(JOptionPane.showInputDialog("How many dice do you want throw?"));
if(number > 0 && number < 6) {
container.remove(panel);
container.remove(systemPanel);
HumanPlayerCalculator human = new HumanPlayerCalculator(container, humanPlayer, game, currentScore, throwNumber, number, scoreButton);
human.execute();
throwCount++;
}
else {
JOptionPane.showMessageDialog(null, "Invalid number entry.", "Input Error", JOptionPane.ERROR_MESSAGE);
}
}
else if(response == 1) {
if(throwNumber == 1) {
humanPlayer.addScore(currentScore.getMandatoryThrow());
throwCount += 2;
}
else if(throwNumber == 2) {
humanPlayer.addScore(currentScore.getRerolls()[0]);
throwCount += 1;
}
scoreButton.setEnabled(false);
newGameButton.setEnabled(true);
}
else {
//Do nothing
}
}
else {
container.remove(panel);
container.remove(systemPanel);
currentScore = new Score();
HumanPlayerCalculator human = new HumanPlayerCalculator(container, humanPlayer, game, currentScore, throwNumber, 5, scoreButton);
human.execute();
scoreButton.setEnabled(true);
systemScore = new Score();
SystemPlayerCalculator systemCalculator = new SystemPlayerCalculator(container, game.getSystemPlayer(), game, systemScore, throwNumber, 5);
systemCalculator.execute();
throwCount++;
}
}
}
);
PlayerCalculator.java
package ac.lk.iit.coursework2;
import java.awt.Container;
import java.io.Serializable;
import javax.swing.SwingWorker;
public abstract class PlayerCalculator extends SwingWorker<Throw, Object> implements Serializable {
private Player player;
private Game game;
private Container container;
private Score score;
private int throwCount;
private int diceCount;
public PlayerCalculator() {
}
public PlayerCalculator(Player player, Game game, Container container, Score score, int count, int diceCount) {
this.setPlayer(player);
this.setGame(game);
this.setContainer(container);
this.setScore(score);
this.setThrowCount(count);
this.setDiceCount(diceCount);
}
public Player getPlayer() {
return player;
}
public void setPlayer(Player player) {
this.player = player;
}
public Game getGame() {
return game;
}
public void setGame(Game game) {
this.game = game;
}
public Container getContainer() {
return container;
}
public void setContainer(Container container) {
this.container = container;
}
public Score getScore() {
return score;
}
public void setScore(Score score) {
this.score = score;
}
public int getThrowCount() {
return throwCount;
}
public void setThrowCount(int throwCount) {
this.throwCount = throwCount;
}
public int getDiceCount() {
return diceCount;
}
public void setDiceCount(int diceCount) {
this.diceCount = diceCount;
}
}
的HumanPlayerCalculator.java類
package ac.lk.iit.coursework2;
import java.awt.BorderLayout;
import java.awt.Container;
import java.util.ArrayList;
import java.util.concurrent.ExecutionException;
import javax.swing.JButton;
import javax.swing.JOptionPane;
public class HumanPlayerCalculator extends PlayerCalculator {
private JButton button;
public HumanPlayerCalculator() {
super();
}
public HumanPlayerCalculator(Container container, HumanPlayer player, Game game, Score score, int throwCount, int count, JButton button) {
super(player, game, container, score, throwCount, count);
this.setDiceCount(count);
this.setThrowButton(button);
}
public JButton getThrowButton() {
return button;
}
public void setThrowButton(JButton throwButton) {
this.button = throwButton;
}
@Override
protected Throw doInBackground() throws Exception {
Throw aThrow = new Throw(this.getDiceCount());
ArrayList<Die> faces = aThrow.getFaces();
//Testing
System.out.println("You:");
for(int i = 0 ; i < faces.size() ; i++) {
System.out.print(faces.get(i).getValue() + " ");
}
System.out.println();
System.out.println("Faces = " + faces.size());
//Testing
getContainer().add(new PanelOfDice("You", faces, "Current total = " + this.getPlayer().getScore()), BorderLayout.CENTER);
this.getContainer().validate();
this.getContainer().getComponent(0).repaint();
return aThrow;
}
protected void done() {
try {
if(this.getThrowCount() == 0) {
this.getScore().setMandatoryThrow(get());
}
else if(this.getThrowCount() == 1) {
this.getScore().setRerolls(get(), 1);
}
else {
this.getPlayer().addScore(get());
this.getThrowButton().setEnabled(false);
}
}
catch(ExecutionException executionException) {
executionException.printStackTrace();
JOptionPane.showMessageDialog(null, "Error in system. Please try again.", "System Error", JOptionPane.ERROR_MESSAGE);
}
catch(InterruptedException interruptedException) {
interruptedException.printStackTrace();
JOptionPane.showMessageDialog(null, "Error in system. Please try again.", "System Error", JOptionPane.ERROR_MESSAGE);
}
}
}
的SystemPlayerCalculator.java
package ac.lk.iit.coursework2;
import java.awt.BorderLayout;
import java.awt.Container;
import java.util.ArrayList;
import java.util.concurrent.ExecutionException;
import javax.swing.JOptionPane;
public class SystemPlayerCalculator extends PlayerCalculator {
public SystemPlayerCalculator(Container container, SystemPlayer player, Game game, Score score, int throwCount, int count) {
super(player, game, container, score, throwCount, count);
}
@Override
protected Throw doInBackground() throws Exception {
Throw aThrow = new Throw(this.getDiceCount());
ArrayList<Die> faces = aThrow.getFaces();
Thread.sleep(5000);
//Testing
System.out.println("Computer:");
for(int i = 0 ; i < faces.size() ; i++) {
System.out.print(faces.get(i).getValue() + " ");
}
System.out.println();
System.out.println("Faces = " + faces.size());
//Testing
getContainer().add(new PanelOfDice("Computer", faces, "Current total = " + this.getPlayer().getScore()), BorderLayout.SOUTH);
this.getContainer().validate();
this.getContainer().getComponent(1).repaint();
return aThrow;
}
protected void done() {
try {
if(this.getThrowCount() == 0) {
this.getScore().setMandatoryThrow(get());
}
else if(this.getThrowCount() == 1) {
this.getScore().setRerolls(get(), 1);
}
else {
this.getPlayer().addScore(get());
}
}
catch(ExecutionException executionException) {
JOptionPane.showMessageDialog(null, "Error in system. Please try again.", "System Error", JOptionPane.ERROR_MESSAGE);
}
catch(InterruptedException interruptedException) {
JOptionPane.showMessageDialog(null, "Error in system. Please try again.", "System Error", JOptionPane.ERROR_MESSAGE);
}
}
}
在這個關頭SystemPlayer之遙,將REPL在線程定時等待之後調用HumanPlayer的throw顯示,雖然它們被放置在基於BorderLayout的不同位置。我無法弄清楚爲什麼會發生這種情況。
有人可以幫助我在這種情況下?
沒有答案,但我會大大簡化所有這一切**不**使用SwingWorker或線程直接,而是通過使用Swing Timer和CardLayout。 –
...或甚至比CardLayout更好 - 使用JLabel來顯示骰子的面部,只需換出ImageIcons以顯示不同的面部。 –
最後考慮創建併發布[最小,完整和可驗證示例程序](http://stackoverflow.com/help/mcve)。我們不想看到你的整個程序,而是你應該將你的代碼壓縮到仍然編譯的最小位,沒有額外的代碼與你的問題無關,但仍然表明你的問題。 –