Netzwerk hat Panel mit laufenden Spielen und einem funktionierenden Abbrechen-Button

git-svn-id: svn://sunsvr01.isp.uni-luebeck.de/swproj13/trunk@406 72836036-5685-4462-b002-a69064685172
This commit is contained in:
Ida Massow 2011-06-11 00:02:42 +02:00
parent 9c553786f2
commit cc4797fd8b
11 changed files with 469 additions and 106 deletions

View file

@ -0,0 +1,29 @@
package jrummikub.view;
import jrummikub.util.IEvent;
import jrummikub.util.IEvent1;
import jrummikub.util.MockEvent;
import jrummikub.util.MockEvent1;
/** */
public class MockGameListPanel implements IGameListPanel {
public MockEvent1<GameData> joinEvent = new MockEvent1<GameData>();
public MockEvent openNewGameEvent = new MockEvent();
public MockEvent cancelEvent = new MockEvent();
@Override
public IEvent getOpenNewGameEvent() {
return openNewGameEvent;
}
@Override
public IEvent getCancelEvent() {
return cancelEvent;
}
@Override
public IEvent1<GameData> getJoinEvent() {
return joinEvent;
}
}

View file

@ -27,11 +27,15 @@ public class MockView implements IView {
/** */
public MockLoginPanel loginPanel = new MockLoginPanel();
/** */
public MockGameListPanel gameListPanel = new MockGameListPanel();
/** */
public boolean isSettingsPanelVisible = false;
/** */
public boolean isScorePanelVisible = false;
/** */
public boolean isLoginPanelVisible = false;
/** */
public boolean isGameListPanelVisible = false;
/** */
public Collection<Stone> selectedStones;
@ -127,13 +131,11 @@ public class MockView implements IView {
@Override
public void setCurrentPlayerColor(Color color) {
// TODO Auto-generated method stub
}
@Override
public void setCurrentPlayerHasLaidOut(boolean hasLaidOut) {
// TODO Auto-generated method stub
}
@Override
@ -173,7 +175,6 @@ public class MockView implements IView {
@Override
public void enablePauseMode(boolean enable) {
// TODO Auto-generated method stub
}
@Override
@ -199,6 +200,16 @@ public class MockView implements IView {
@Override
public void showLoginPanel(boolean show) {
isLoginPanelVisible = show;
}
@Override
public void showGameListPanel(boolean show) {
isGameListPanelVisible = show;
}
@Override
public IGameListPanel getGameListPanel() {
return gameListPanel;
}
}

View file

@ -54,10 +54,11 @@ public class ApplicationControl {
new IListener3<GameSettings, GameState, IRoundState>() {
@Override
public void handle(GameSettings settings, GameState gameState,
IRoundState roundState) {
public void handle(GameSettings settings,
GameState gameState, IRoundState roundState) {
abortControls();
gameControl = new GameControl(settings, saveControl, view);
gameControl = new GameControl(settings, saveControl,
view);
addGameControlListeners(gameControl);
gameControl.continueGame(gameState, roundState);
@ -154,10 +155,15 @@ public class ApplicationControl {
}
private void createNetworkControl(LoginData loginData) {
networkControl = new NetworkControl(loginData);
networkControl = new NetworkControl(loginData, view);
// TODO Add listeners
networkControl.getStopNetworkEvent().add(new IListener() {
@Override
public void handle() {
startApplication();
}
});
networkControl.connect();
networkControl.startNetwork();
}
}

View file

@ -0,0 +1,114 @@
package jrummikub.control.network;
import javax.swing.SwingUtilities;
import jrummikub.util.Event;
import jrummikub.util.IEvent;
import jrummikub.util.LoginData;
import org.jivesoftware.smack.Connection;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.XMPPError;
import org.jivesoftware.smack.packet.XMPPError.Type;
import org.jivesoftware.smackx.muc.MultiUserChat;
class ConnectionControl {
private final LoginData loginData;
private volatile Connection connection;
private volatile MultiUserChat muc;
private Event connectedEvent = new Event();
private Event connectionFailedEvent = new Event();
ConnectionControl(LoginData loginData) {
this.loginData = loginData;
}
void connect() {
new Thread(new ConnectRunner()).start();
}
void disconnect() {
connectedEvent = new Event();
connectionFailedEvent = new Event();
new Thread(new DisconnectRunner()).start();
}
IEvent getConnectedEvent() {
return connectedEvent;
}
IEvent getConnectionFailedEvent() {
return connectionFailedEvent;
}
private static void emitLater(final Event event) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
event.emit();
}
});
}
private class ConnectRunner implements Runnable {
@Override
public void run() {
synchronized (ConnectionControl.this) {
connection = new XMPPConnection(loginData.getServerName());
try {
connection.connect();
connection.login(loginData.getUserName(),
loginData.getPassword(), "JRummikub");
muc = new MultiUserChat(connection,
loginData.getChannelName());
String nickname = loginData.getUserName();
// Loop until a unused nickname is found
while (true) {
try {
muc.join(nickname);
break; // Join was successful, break the loop
} catch (XMPPException e) {
XMPPError error = e.getXMPPError();
if (error.getType() == Type.CANCEL
&& error.getCode() == 409) {
// There was a conflict, try again with another
// nickname
nickname += "_";
continue;
} else {
// An unknown error has occurred, cancel connect
throw e;
}
}
}
emitLater(connectedEvent);
} catch (XMPPException e) {
connection.disconnect();
connection = null;
// TODO Auto-generated catch block
e.printStackTrace();
emitLater(connectionFailedEvent);
}
}
}
}
private class DisconnectRunner implements Runnable {
@Override
public void run() {
synchronized (ConnectionControl.this) {
if (connection != null) {
connection.disconnect();
connection = null;
}
}
}
}
}

View file

@ -1,87 +1,87 @@
package jrummikub.control.network;
import javax.swing.SwingUtilities;
import java.util.ArrayList;
import java.util.List;
import jrummikub.util.Connection;
import jrummikub.util.Event;
import jrummikub.util.IEvent;
import jrummikub.util.IListener;
import jrummikub.util.IListener1;
import jrummikub.util.LoginData;
import org.jivesoftware.smack.Connection;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.XMPPError;
import org.jivesoftware.smack.packet.XMPPError.Type;
import org.jivesoftware.smackx.muc.MultiUserChat;
import jrummikub.view.IGameListPanel;
import jrummikub.view.IGameListPanel.GameData;
import jrummikub.view.IView;
public class NetworkControl {
private final LoginData loginData;
private Connection connection;
private MultiUserChat muc;
private Thread networkThread;
private ConnectionControl connectionControl;
private IView view;
private List<Connection> connections = new ArrayList<Connection>();
private Event stopNetworkEvent = new Event();
private Event connectedEvent = new Event();
private Event connectionFailedEvent = new Event();
public NetworkControl(LoginData loginData, final IView view) {
this.view = view;
connectionControl = new ConnectionControl(loginData);
public NetworkControl(LoginData loginData) {
this.loginData = loginData;
connections.add(connectionControl.getConnectedEvent().add(
new IListener() {
@Override
public void handle() {
view.showGameListPanel(true);
}
}));
connections.add(connectionControl.getConnectionFailedEvent().add(
new IListener() {
@Override
public void handle() {
// TODO Auto-generated method stub
}
}));
connections.add(view.getGameListPanel().getJoinEvent()
.add(new IListener1<IGameListPanel.GameData>() {
@Override
public void handle(GameData value) {
// TODO Auto-generated method stub
}
}));
connections.add(view.getGameListPanel().getOpenNewGameEvent()
.add(new IListener() {
@Override
public void handle() {
// TODO Auto-generated method stub
}
}));
connections.add(view.getGameListPanel().getCancelEvent()
.add(new IListener() {
@Override
public void handle() {
abort();
stopNetworkEvent.emit();
}
}));
}
public void connect() {
new Thread(new ConnectRunner()).run();
public void startNetwork() {
connectionControl.connect();
}
public void abort() {
// TODO Implement this
for (Connection c : connections) {
c.remove();
}
connectionControl.disconnect();
view.showGameListPanel(false);
}
private static void emitLater(final Event event) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
event.emit();
}
});
public IEvent getStopNetworkEvent() {
return stopNetworkEvent;
}
private class ConnectRunner implements Runnable {
@Override
public void run() {
connection = new XMPPConnection(loginData.getServerName());
try {
connection.connect();
connection.login(loginData.getUserName(), loginData.getPassword(),
"JRummikub");
muc = new MultiUserChat(connection, loginData.getChannelName());
String nickname = loginData.getUserName();
// Loop until a unused nickname is found
while (true) {
try {
muc.join(nickname);
break; // Join was successful, break the loop
} catch (XMPPException e) {
XMPPError error = e.getXMPPError();
if (error.getType() == Type.CANCEL && error.getCode() == 409) {
// There was a conflict, try again with another nickname
nickname += "_";
continue;
} else {
// An unknown error has occurred, cancel connect
throw e;
}
}
}
emitLater(connectedEvent);
} catch (XMPPException e) {
connection.disconnect();
connection = null;
// TODO Auto-generated catch block
e.printStackTrace();
emitLater(connectionFailedEvent);
}
}
}
}

View file

@ -0,0 +1,54 @@
package jrummikub.view;
import java.util.UUID;
import jrummikub.util.Event;
import jrummikub.util.Event1;
import jrummikub.util.IEvent;
import jrummikub.util.IEvent1;
import jrummikub.view.IGameListPanel.GameData;
public interface IGameListPanel {
public static class GameData {
private UUID gameID;
private String host;
private int currentPlayerCount = 0;
private int maxPlayerCount = 0;
public GameData(UUID gameID, String host) {
this.gameID = gameID;
this.host = host;
}
public void setCurrentPlayerCount(int i) {
currentPlayerCount = i;
}
public int getCurrentPlayerCount() {
return currentPlayerCount;
}
public void setMaxPlayerCount(int i) {
maxPlayerCount = i;
}
public int getMaxPlayerCount() {
return maxPlayerCount;
}
public String getHost() {
return host;
}
public UUID getGameID() {
return gameID;
}
}
public IEvent getOpenNewGameEvent();
public IEvent getCancelEvent();
public IEvent1<GameData> getJoinEvent();
}

View file

@ -4,8 +4,17 @@ import jrummikub.util.IEvent;
import jrummikub.util.IEvent1;
import jrummikub.util.LoginData;
/**
* LoginPanel for network game
*
*/
public interface ILoginPanel {
/**
* Player has offered all information and wants to connect
*
* @return LoginData username, server, password, channel
*/
public IEvent1<LoginData> getLoginEvent();
public IEvent getCancelEvent();

View file

@ -172,10 +172,14 @@ public interface IView {
public ILoginPanel getLoginPanel();
public IGameListPanel getGameListPanel();
public void showLoginPanel(boolean show);
public void enablePauseMode(boolean enable);
public void showGameListPanel(boolean show);
/**
* Different types of bottom panels
*/

View file

@ -0,0 +1,111 @@
package jrummikub.view.impl;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import jrummikub.util.Event;
import jrummikub.util.Event1;
import jrummikub.util.IEvent;
import jrummikub.util.IEvent1;
import jrummikub.view.IGameListPanel;
class GameListPanel extends JPanel implements IGameListPanel {
private JLabel title;
private JList gameList;
private JButton joinButton;
private JButton openNewGameButton;
private JButton cancelButton;
private Event1<GameData> joinEvent = new Event1<GameData>();
private Event openNewGameEvent = new Event();
private Event cancelEvent = new Event();
GameListPanel() {
setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.gridwidth = GridBagConstraints.REMAINDER;
c.weightx = 1;
c.weighty = 0;
title = new JLabel();
add(title, c);
gameList = new JList();
c.weighty = 1;
add(new JScrollPane(gameList, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER), c);
joinButton = new JButton("Beitreten");
c.weighty = 0;
c.gridwidth = 1;
add(joinButton, c);
joinButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
// joinEvent.emit();
}
});
c.weightx = 0;
add(Box.createHorizontalStrut(10), c);
openNewGameButton = new JButton("Neues Spiel");
c.weightx = 1;
add(openNewGameButton, c);
openNewGameButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
openNewGameEvent.emit();
}
});
c.weightx = 0;
add(Box.createHorizontalStrut(10), c);
cancelButton = new JButton("Abbrechen");
c.weightx = 1;
c.weighty = 0;
c.gridwidth = GridBagConstraints.REMAINDER;
add(cancelButton, c);
cancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
cancelEvent.emit();
}
});
setBorder(new CompoundBorder(new LineBorder(Color.BLACK),
new EmptyBorder(10, 10, 10, 10)));
}
@Override
public IEvent getOpenNewGameEvent() {
return openNewGameEvent;
}
@Override
public IEvent1<GameData> getJoinEvent() {
return joinEvent;
}
@Override
public IEvent getCancelEvent() {
return cancelEvent;
}
}

View file

@ -41,9 +41,12 @@ class LoginPanel extends JPanel implements ILoginPanel {
c.weighty = 1;
userNameField = addInputRow("Benutzername:", new JTextField());
userNameField.setText("test1");
serverNameField = addInputRow("Server:", new JTextField());
serverNameField.setText("universe-factory.net");
passwordField = addInputRow("Passwort:", new JPasswordField());
channelNameField = addInputRow("Channel:", new JTextField());
channelNameField.setText("jrummikub@muc.universe-factory.net");
add(Box.createVerticalGlue(), c);
c.gridwidth = 1;

View file

@ -31,6 +31,7 @@ import jrummikub.util.IEvent;
import jrummikub.util.IEvent1;
import jrummikub.util.IListener;
import jrummikub.util.Pair;
import jrummikub.view.IGameListPanel;
import jrummikub.view.IHandPanel;
import jrummikub.view.ILoginPanel;
import jrummikub.view.IPlayerPanel;
@ -60,6 +61,7 @@ public class View extends JFrame implements IView {
private SettingsPanel settingsPanel;
private LoginPanel loginPanel;
private ScorePanel scorePanel;
private GameListPanel gameListPanel;
private BottomPanelType bottomPanelType;
@ -106,6 +108,11 @@ public class View extends JFrame implements IView {
return playerPanel;
}
@Override
public IGameListPanel getGameListPanel() {
return gameListPanel;
}
@Override
public IEvent getMenuNewGameEvent() {
return menuNewGameEvent;
@ -146,7 +153,9 @@ public class View extends JFrame implements IView {
showScorePanel(false);
showSettingsPanel(false);
showLoginPanel(false);
getHandPanel().setStones(Collections.<Pair<Stone, Position>> emptyList());
showGameListPanel(false);
getHandPanel().setStones(
Collections.<Pair<Stone, Position>> emptyList());
getTablePanel().setStoneSets(
Collections.<Pair<StoneSet, Position>> emptyList());
setSelectedStones(Collections.<Stone> emptyList());
@ -249,6 +258,12 @@ public class View extends JFrame implements IView {
layeredPane.setLayer(loginPanel, JLayeredPane.POPUP_LAYER);
layeredPane.add(loginPanel);
gameListPanel = new GameListPanel();
gameListPanel.setVisible(false);
layeredPane.setLayer(gameListPanel, JLayeredPane.POPUP_LAYER);
layeredPane.add(gameListPanel);
scorePanel = new ScorePanel();
scorePanel.setVisible(false);
layeredPane.setLayer(scorePanel, JLayeredPane.POPUP_LAYER);
@ -291,8 +306,8 @@ public class View extends JFrame implements IView {
mainLayer.add(table);
playerPanel = new PlayerPanel();
playerPanel.setBorder(new MatteBorder(PLAYER_PANEL_BORDER_WIDTH, 0, 0, 0,
Color.BLACK));
playerPanel.setBorder(new MatteBorder(PLAYER_PANEL_BORDER_WIDTH, 0, 0,
0, Color.BLACK));
mainLayer.add(playerPanel);
startTurnPanel = new StartTurnPanel();
@ -340,6 +355,7 @@ public class View extends JFrame implements IView {
settingsPanel.setBounds(width / 4, height / 4, width / 2, height / 2);
scorePanel.setBounds(width / 8, height / 4, width * 3 / 4, height / 2);
loginPanel.setBounds(width / 3, height / 3, width / 3, height / 3);
gameListPanel.setBounds(width / 4, height / 4, width / 2, height / 2);
}
@Override
@ -362,6 +378,11 @@ public class View extends JFrame implements IView {
loginPanel.setVisible(show);
}
@Override
public void showGameListPanel(boolean show) {
gameListPanel.setVisible(show);
}
@Override
public void showScorePanel(boolean show) {
scorePanel.setVisible(show);
@ -406,24 +427,24 @@ public class View extends JFrame implements IView {
@SuppressWarnings("unchecked")
private List<Pair<Stone, Position>> createDecorationStones() {
Pair<Stone, Position> stoneJ = new Pair<Stone, Position>(new Stone(-'J',
StoneColor.BLACK), new Position(2.5f, 0));
Pair<Stone, Position> stoneR = new Pair<Stone, Position>(new Stone(-'R',
StoneColor.ORANGE), new Position(3.5f, 0));
Pair<Stone, Position> stoneu1 = new Pair<Stone, Position>(new Stone(-'u',
StoneColor.BLUE), new Position(4.5f, 0));
Pair<Stone, Position> stonem1 = new Pair<Stone, Position>(new Stone(-'m',
StoneColor.RED), new Position(5.5f, 0));
Pair<Stone, Position> stonem2 = new Pair<Stone, Position>(new Stone(-'m',
StoneColor.GREEN), new Position(6.5f, 0));
Pair<Stone, Position> stonei = new Pair<Stone, Position>(new Stone(-'i',
StoneColor.VIOLET), new Position(7.5f, 0));
Pair<Stone, Position> stonek = new Pair<Stone, Position>(new Stone(-'k',
StoneColor.AQUA), new Position(8.5f, 0));
Pair<Stone, Position> stoneu2 = new Pair<Stone, Position>(new Stone(-'u',
StoneColor.GRAY), new Position(9.5f, 0));
Pair<Stone, Position> stoneb = new Pair<Stone, Position>(new Stone(-'b',
StoneColor.BLACK), new Position(10.5f, 0));
Pair<Stone, Position> stoneJ = new Pair<Stone, Position>(new Stone(
-'J', StoneColor.BLACK), new Position(2.5f, 0));
Pair<Stone, Position> stoneR = new Pair<Stone, Position>(new Stone(
-'R', StoneColor.ORANGE), new Position(3.5f, 0));
Pair<Stone, Position> stoneu1 = new Pair<Stone, Position>(new Stone(
-'u', StoneColor.BLUE), new Position(4.5f, 0));
Pair<Stone, Position> stonem1 = new Pair<Stone, Position>(new Stone(
-'m', StoneColor.RED), new Position(5.5f, 0));
Pair<Stone, Position> stonem2 = new Pair<Stone, Position>(new Stone(
-'m', StoneColor.GREEN), new Position(6.5f, 0));
Pair<Stone, Position> stonei = new Pair<Stone, Position>(new Stone(
-'i', StoneColor.VIOLET), new Position(7.5f, 0));
Pair<Stone, Position> stonek = new Pair<Stone, Position>(new Stone(
-'k', StoneColor.AQUA), new Position(8.5f, 0));
Pair<Stone, Position> stoneu2 = new Pair<Stone, Position>(new Stone(
-'u', StoneColor.GRAY), new Position(9.5f, 0));
Pair<Stone, Position> stoneb = new Pair<Stone, Position>(new Stone(
-'b', StoneColor.BLACK), new Position(10.5f, 0));
Pair<Stone, Position> stone1 = new Pair<Stone, Position>(new Stone(
StoneColor.RED), new Position(2, 1));
@ -438,9 +459,9 @@ public class View extends JFrame implements IView {
Pair<Stone, Position> stone6 = new Pair<Stone, Position>(new Stone(
StoneColor.BLACK), new Position(11, 1));
return Arrays
.asList(stoneJ, stoneR, stoneu1, stonem1, stonem2, stonei, stonek,
stoneu2, stoneb, stone1, stone2, stone3, stone4, stone5, stone6);
return Arrays.asList(stoneJ, stoneR, stoneu1, stonem1, stonem2, stonei,
stonek, stoneu2, stoneb, stone1, stone2, stone3, stone4,
stone5, stone6);
}
@Override
@ -457,7 +478,8 @@ public class View extends JFrame implements IView {
&& type != BottomPanelType.WIN_PANEL && type != null);
if (type == BottomPanelType.START_GAME_PANEL) {
table.setStoneSets(Collections.<Pair<StoneSet, Position>> emptyList());
table.setStoneSets(Collections
.<Pair<StoneSet, Position>> emptyList());
playerPanel.getHandPanel().setStones(createDecorationStones());
}