/**
* This file is part of JSkat.
*
* JSkat is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* JSkat is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with JSkat. If not, see <http://www.gnu.org/licenses/>.
*/
package org.jskat.gui.swing;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Desktop;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.swing.ActionMap;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.jskat.control.JSkatEventBus;
import org.jskat.control.JSkatMaster;
import org.jskat.control.command.general.HideToolbarCommand;
import org.jskat.control.command.general.ShowAboutInformationCommand;
import org.jskat.control.command.general.ShowHelpCommand;
import org.jskat.control.command.general.ShowLicenseCommand;
import org.jskat.control.command.general.ShowPreferencesCommand;
import org.jskat.control.command.general.ShowToolbarCommand;
import org.jskat.control.command.general.ShowTrainingOverviewCommand;
import org.jskat.control.command.iss.IssDisconnectCommand;
import org.jskat.control.command.skatseries.CreateSkatSeriesCommand;
import org.jskat.control.command.table.ShowCardsCommand;
import org.jskat.control.event.iss.IssConnectedEvent;
import org.jskat.control.event.nntraining.TrainingResultEvent;
import org.jskat.control.event.skatgame.BidEvent;
import org.jskat.control.event.skatgame.CardDealEvent;
import org.jskat.control.event.skatgame.GameAnnouncementEvent;
import org.jskat.control.event.skatgame.GameStartEvent;
import org.jskat.control.event.skatgame.HoldBidEvent;
import org.jskat.control.event.skatgame.InvalidNumberOfCardsInDiscardedSkatEvent;
import org.jskat.control.event.skatgame.PassBidEvent;
import org.jskat.control.event.skatgame.TrickCardPlayedEvent;
import org.jskat.control.event.table.DuplicateTableNameInputEvent;
import org.jskat.control.event.table.EmptyTableNameInputEvent;
import org.jskat.control.event.table.TableCreatedEvent;
import org.jskat.control.event.table.TableGameMoveEvent;
import org.jskat.control.event.table.TableRemovedEvent;
import org.jskat.control.event.table.TrickCompletedEvent;
import org.jskat.control.iss.ChatMessageType;
import org.jskat.data.JSkatOptions;
import org.jskat.data.JSkatViewType;
import org.jskat.data.SkatGameData;
import org.jskat.data.SkatGameData.GameState;
import org.jskat.data.SkatSeriesData.SeriesState;
import org.jskat.data.Trick;
import org.jskat.data.iss.ChatMessage;
import org.jskat.data.iss.GameStartInformation;
import org.jskat.data.iss.MoveInformation;
import org.jskat.data.iss.MovePlayer;
import org.jskat.data.iss.TablePanelStatus;
import org.jskat.gui.JSkatView;
import org.jskat.gui.action.JSkatAction;
import org.jskat.gui.action.human.CallContraAction;
import org.jskat.gui.action.human.CallReAction;
import org.jskat.gui.action.human.DiscardAction;
import org.jskat.gui.action.human.GameAnnounceAction;
import org.jskat.gui.action.human.HoldBidAction;
import org.jskat.gui.action.human.MakeBidAction;
import org.jskat.gui.action.human.PassBidAction;
import org.jskat.gui.action.human.PickUpSkatAction;
import org.jskat.gui.action.human.PlayCardAction;
import org.jskat.gui.action.human.PlayGrandHandAction;
import org.jskat.gui.action.human.PlayHandGameAction;
import org.jskat.gui.action.human.PlaySchiebeRamschAction;
import org.jskat.gui.action.human.SchiebenAction;
import org.jskat.gui.action.iss.ChangeTableSeatsAction;
import org.jskat.gui.action.iss.ConnectAction;
import org.jskat.gui.action.iss.CreateIssTableAction;
import org.jskat.gui.action.iss.InvitePlayerAction;
import org.jskat.gui.action.iss.JoinIssTableAction;
import org.jskat.gui.action.iss.LeaveIssTableAction;
import org.jskat.gui.action.iss.LogoutAction;
import org.jskat.gui.action.iss.ObserveTableAction;
import org.jskat.gui.action.iss.OpenHomepageAction;
import org.jskat.gui.action.iss.ReadyAction;
import org.jskat.gui.action.iss.RegisterAction;
import org.jskat.gui.action.iss.ResignAction;
import org.jskat.gui.action.iss.SendChatMessageAction;
import org.jskat.gui.action.iss.ShowCardsAction;
import org.jskat.gui.action.iss.ShowLoginPanelAction;
import org.jskat.gui.action.iss.TalkEnableAction;
import org.jskat.gui.action.main.AboutAction;
import org.jskat.gui.action.main.ChangeActiveTableAction;
import org.jskat.gui.action.main.ContinueSkatSeriesAction;
import org.jskat.gui.action.main.CreateTableAction;
import org.jskat.gui.action.main.ExitAction;
import org.jskat.gui.action.main.HelpAction;
import org.jskat.gui.action.main.LicenseAction;
import org.jskat.gui.action.main.LoadNeuralNetworksAction;
import org.jskat.gui.action.main.LoadSeriesAction;
import org.jskat.gui.action.main.NextReplayMoveAction;
import org.jskat.gui.action.main.PreferencesAction;
import org.jskat.gui.action.main.PutCardIntoSkatAction;
import org.jskat.gui.action.main.ReplayGameAction;
import org.jskat.gui.action.main.ResetNeuralNetworksAction;
import org.jskat.gui.action.main.SaveNeuralNetworksAction;
import org.jskat.gui.action.main.SaveSeriesAction;
import org.jskat.gui.action.main.SaveSeriesAsAction;
import org.jskat.gui.action.main.StartSkatSeriesAction;
import org.jskat.gui.action.main.StopTrainNeuralNetworksAction;
import org.jskat.gui.action.main.TakeCardFromSkatAction;
import org.jskat.gui.action.main.TrainNeuralNetworksAction;
import org.jskat.gui.human.AbstractHumanJSkatPlayer;
import org.jskat.gui.human.SwingHumanPlayer;
import org.jskat.gui.img.JSkatGraphicRepository;
import org.jskat.gui.swing.help.JSkatHelpDialog;
import org.jskat.gui.swing.iss.ISSTablePanel;
import org.jskat.gui.swing.iss.LobbyPanel;
import org.jskat.gui.swing.iss.LoginPanel;
import org.jskat.gui.swing.iss.PlayerInvitationPanel;
import org.jskat.gui.swing.nn.NeuralNetworkTrainingOverview;
import org.jskat.gui.swing.table.SkatSeriesStartDialog;
import org.jskat.gui.swing.table.SkatTablePanel;
import org.jskat.util.Card;
import org.jskat.util.CardList;
import org.jskat.util.GameVariant;
import org.jskat.util.JSkatResourceBundle;
import org.jskat.util.Player;
import org.jskat.util.SkatConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.eventbus.Subscribe;
import javafx.collections.ObservableList;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.stage.Screen;
public class JSkatViewImpl implements JSkatView {
private static Logger LOG = LoggerFactory.getLogger(JSkatViewImpl.class);
public final JPanel mainPanel = new JPanel();
private JPanel toolbar;
private final SkatSeriesStartDialog skatSeriesStartDialog;
private final JSkatOptionsDialog preferencesDialog;
private final NeuralNetworkTrainingOverview trainingOverview;
private JTabbedPane tabs;
private String activeView;
@Deprecated
private final Map<String, SkatTablePanel> tables = new HashMap<>();
private final JSkatGraphicRepository bitmaps = JSkatGraphicRepository.INSTANCE;
private final JSkatResourceBundle strings = JSkatResourceBundle.INSTANCE;
private final JSkatOptions options = JSkatOptions.instance();
static ActionMap actions;
private LobbyPanel issLobby;
private static String VERSION;
/**
* Constructor
*
* @param targetScreen
* Target screen for main window
* @param menu
* Menu bar
* @param version
* JSkat version
*/
public JSkatViewImpl(final Screen targetScreen, final MenuBar menu, final String version) {
JSkatViewImpl.VERSION = version;
JSkatEventBus.INSTANCE.register(this);
this.skatSeriesStartDialog = new SkatSeriesStartDialog(mainPanel);
this.preferencesDialog = new JSkatOptionsDialog(mainPanel);
this.trainingOverview = new NeuralNetworkTrainingOverview(mainPanel);
initActionMap(menu);
initGUI(targetScreen);
}
private void initActionMap(final MenuBar menu) {
actions = new ActionMap();
// common actions
final ObservableList<Menu> menus = menu.getMenus();
final LoadSeriesAction loadSeriesAction = new LoadSeriesAction();
loadSeriesAction.setMenuItem(menus.get(0).getItems().get(0));
actions.put(JSkatAction.LOAD_SERIES, loadSeriesAction);
final SaveSeriesAction saveSeriesAction = new SaveSeriesAction();
saveSeriesAction.setMenuItem(menus.get(0).getItems().get(1));
actions.put(JSkatAction.SAVE_SERIES, saveSeriesAction);
final SaveSeriesAsAction saveSeriesAsAction = new SaveSeriesAsAction();
saveSeriesAsAction.setMenuItem(menus.get(0).getItems().get(2));
actions.put(JSkatAction.SAVE_SERIES_AS, saveSeriesAsAction);
actions.put(JSkatAction.HELP, new HelpAction());
actions.put(JSkatAction.LICENSE, new LicenseAction());
actions.put(JSkatAction.EXIT_JSKAT, new ExitAction());
actions.put(JSkatAction.PREFERENCES, new PreferencesAction());
actions.put(JSkatAction.ABOUT_JSKAT, new AboutAction());
actions.put(JSkatAction.CHANGE_ACTIVE_TABLE, new ChangeActiveTableAction());
// skat table actions
actions.put(JSkatAction.CREATE_LOCAL_TABLE, new CreateTableAction());
actions.put(JSkatAction.START_LOCAL_SERIES, new StartSkatSeriesAction());
actions.put(JSkatAction.CONTINUE_LOCAL_SERIES, new ContinueSkatSeriesAction());
actions.put(JSkatAction.REPLAY_GAME, new ReplayGameAction());
actions.put(JSkatAction.NEXT_REPLAY_STEP, new NextReplayMoveAction());
// ISS actions
actions.put(JSkatAction.REGISTER_ON_ISS, new RegisterAction());
actions.put(JSkatAction.OPEN_ISS_HOMEPAGE, new OpenHomepageAction());
actions.put(JSkatAction.SHOW_ISS_LOGIN, new ShowLoginPanelAction());
actions.put(JSkatAction.CONNECT_TO_ISS, new ConnectAction());
actions.put(JSkatAction.DISCONNECT_FROM_ISS, new LogoutAction());
actions.put(JSkatAction.SEND_CHAT_MESSAGE, new SendChatMessageAction());
actions.put(JSkatAction.CREATE_ISS_TABLE, new CreateIssTableAction());
actions.put(JSkatAction.JOIN_ISS_TABLE, new JoinIssTableAction());
actions.put(JSkatAction.LEAVE_ISS_TABLE, new LeaveIssTableAction());
actions.put(JSkatAction.OBSERVE_ISS_TABLE, new ObserveTableAction());
actions.put(JSkatAction.READY_TO_PLAY, new ReadyAction());
actions.put(JSkatAction.TALK_ENABLED, new TalkEnableAction());
actions.put(JSkatAction.CHANGE_TABLE_SEATS, new ChangeTableSeatsAction());
actions.put(JSkatAction.INVITE_ISS_PLAYER, new InvitePlayerAction());
actions.put(JSkatAction.RESIGN, new ResignAction());
actions.put(JSkatAction.SHOW_CARDS, new ShowCardsAction());
// Neural network actions
actions.put(JSkatAction.TRAIN_NEURAL_NETWORKS, new TrainNeuralNetworksAction());
actions.put(JSkatAction.STOP_TRAIN_NEURAL_NETWORKS, new StopTrainNeuralNetworksAction());
actions.put(JSkatAction.LOAD_NEURAL_NETWORKS, new LoadNeuralNetworksAction());
actions.put(JSkatAction.SAVE_NEURAL_NETWORKS, new SaveNeuralNetworksAction());
actions.put(JSkatAction.RESET_NEURAL_NETWORKS, new ResetNeuralNetworksAction());
// Human player actions
actions.put(JSkatAction.MAKE_BID, new MakeBidAction());
actions.put(JSkatAction.HOLD_BID, new HoldBidAction());
actions.put(JSkatAction.PASS_BID, new PassBidAction());
actions.put(JSkatAction.PICK_UP_SKAT, new PickUpSkatAction());
actions.put(JSkatAction.PLAY_GRAND_HAND, new PlayGrandHandAction());
actions.put(JSkatAction.CALL_CONTRA, new CallContraAction());
actions.put(JSkatAction.CALL_RE, new CallReAction());
actions.put(JSkatAction.PLAY_SCHIEBERAMSCH, new PlaySchiebeRamschAction());
actions.put(JSkatAction.SCHIEBEN, new SchiebenAction());
actions.put(JSkatAction.PLAY_HAND_GAME, new PlayHandGameAction());
actions.put(JSkatAction.ANNOUNCE_GAME, new GameAnnounceAction());
actions.put(JSkatAction.PUT_CARD_INTO_SKAT, new PutCardIntoSkatAction());
actions.put(JSkatAction.TAKE_CARD_FROM_SKAT, new TakeCardFromSkatAction());
actions.put(JSkatAction.DISCARD_CARDS, new DiscardAction());
actions.put(JSkatAction.PLAY_CARD, new PlayCardAction());
// disable some actions
actions.get(JSkatAction.LOAD_SERIES).setEnabled(false);
actions.get(JSkatAction.SAVE_SERIES).setEnabled(false);
actions.get(JSkatAction.SAVE_SERIES_AS).setEnabled(false);
actions.get(JSkatAction.START_LOCAL_SERIES).setEnabled(false);
actions.get(JSkatAction.CREATE_ISS_TABLE).setEnabled(false);
actions.get(JSkatAction.INVITE_ISS_PLAYER).setEnabled(false);
actions.get(JSkatAction.REPLAY_GAME).setEnabled(false);
actions.get(JSkatAction.NEXT_REPLAY_STEP).setEnabled(false);
}
private void initGUI(final Screen targetScreen) {
mainPanel.setLayout(new BorderLayout());
createToolbar();
if (ScreenResolution.isBigScreen(targetScreen) && !options.isHideToolbar()) {
addToolbar();
}
// main area
addTabbedPane();
addTabPanel(new WelcomePanel(this.strings.getString("welcome"), actions), //$NON-NLS-1$
this.strings.getString("welcome")); //$NON-NLS-1$
LOG.debug("GUI initialization finished.");
}
@Subscribe
public void hideToolbarOn(final HideToolbarCommand command) {
mainPanel.remove(toolbar);
mainPanel.validate();
}
@Subscribe
public void addToolbar(final ShowToolbarCommand command) {
addToolbar();
}
private void addToolbar() {
mainPanel.add(toolbar, BorderLayout.NORTH);
mainPanel.validate();
}
private void addTabbedPane() {
this.tabs = new JTabbedPane();
this.tabs.setAutoscrolls(true);
this.tabs.addChangeListener(new ChangeListener() {
/**
* @see ChangeListener#stateChanged(ChangeEvent)
*/
@Override
public void stateChanged(final ChangeEvent e) {
if (e.getSource() instanceof JTabbedPane) {
final JTabbedPane changedTabs = (JTabbedPane) e.getSource();
final Component tab = changedTabs.getSelectedComponent();
if (tab instanceof AbstractTabPanel) {
final AbstractTabPanel panel = (AbstractTabPanel) tab;
final String tableName = panel.getName();
LOG.debug("showing table panel of table " + tableName); //$NON-NLS-1$
panel.setFocus();
JSkatMaster.INSTANCE.setActiveTable(tableName);
}
}
}
});
mainPanel.add(this.tabs, BorderLayout.CENTER);
}
private void createToolbar() {
toolbar = new JPanel(LayoutFactory.getMigLayout());
toolbar.add(new ToolbarButton(actions.get(JSkatAction.CREATE_LOCAL_TABLE)));
toolbar.add(new ToolbarButton(actions.get(JSkatAction.START_LOCAL_SERIES)));
toolbar.add(new ToolbarButton(actions.get(JSkatAction.SHOW_ISS_LOGIN)));
toolbar.add(new ToolbarButton(actions.get(JSkatAction.REPLAY_GAME)));
toolbar.add(new ToolbarButton(actions.get(JSkatAction.NEXT_REPLAY_STEP)));
toolbar.add(new ToolbarButton(actions.get(JSkatAction.HELP)));
}
/**
* {@inheritDoc}
*/
@Override
public void startGame(final String tableName) {
this.tables.get(tableName).startGame();
}
@Subscribe
public void createSkatTablePanelOn(final TableCreatedEvent event) {
if (JSkatViewType.TRAINING_TABLE.equals(event.tableType)) {
return;
}
final String tableName = event.tableName;
String tabTitle = null;
SkatTablePanel panel = null;
if (JSkatViewType.LOCAL_TABLE.equals(event.tableType)) {
panel = new SkatTablePanel(tableName, actions);
tabTitle = tableName;
} else if (JSkatViewType.ISS_TABLE.equals(event.tableType)) {
panel = new ISSTablePanel(tableName, actions);
tabTitle = strings.getString("iss_table") + ": " + tableName;
}
tables.put(tableName, panel);
addTabPanel(panel, tabTitle);
actions.get(JSkatAction.START_LOCAL_SERIES).setEnabled(true);
}
@Subscribe
public void showAboutInformationDialogOn(final ShowAboutInformationCommand command) {
JOptionPane.showMessageDialog(null,
"JSkat " //$NON-NLS-1$
+ this.strings.getString("version") //$NON-NLS-1$
+ " " //$NON-NLS-1$
+ VERSION + "\n\n" //$NON-NLS-1$
+ "http://www.jskat.org\n" //$NON-NLS-1$
+ "http://sourceforge.net/projects/jskat" //$NON-NLS-1$
+ "\n\n" //$NON-NLS-1$
+ this.strings.getString(
"authors") //$NON-NLS-1$
+ ":\nJan Schäfer (jansch@users.sourceforge.net)\nMarkus J. Luzius (jskat@luzius.de)\nDaniel Loreck (daniel.loreck@gmail.com)\nSascha Laurien\nSlovasim\nMartin Rothe\n\n" //$NON-NLS-1$
+ this.strings.getString("cards") //$NON-NLS-1$
+ ": International Skat Server, KDE project, OpenClipart.org\n\n" //$NON-NLS-1$
+ this.strings.getString("icons") //$NON-NLS-1$
+ ": Gnome Desktop Icons, Tango project, Elementary icons,\n" //$NON-NLS-1$
+ "Silvestre Herrera, Alex Roberts and Icojoy\n\n" //$NON-NLS-1$
+ this.strings.getString("background_image") + ": webtreats\n\n"
+ "This program comes with ABSOLUTELY NO WARRANTY;\n" //$NON-NLS-1$
+ "for details see licence dialog\n" //$NON-NLS-1$
+ "This is free software, and you are welcome to redistribute it\n" //$NON-NLS-1$
+ "under certain conditions; see licence dialog for details.", //$NON-NLS-1$
this.strings.getString("about"), //$NON-NLS-1$
JOptionPane.INFORMATION_MESSAGE, new ImageIcon(this.bitmaps.getJSkatLogoImage()));
}
/**
* {@inheritDoc}
*/
@Override
public void showMessage(final String title, final String message) {
JOptionPane.showMessageDialog(null, message, title, JOptionPane.INFORMATION_MESSAGE);
}
@Override
public void showAIPlayedSchwarzMessageDiscarding(final String playerName, final CardList discardedCards) {
String cardString = "";
if (discardedCards != null) {
for (final Card card : discardedCards) {
cardString += " " + this.strings.getCardStringForCardFace(card);
}
} else {
cardString = this.strings.getString("unknown_cards");
}
showMessage(this.strings.getString("player_played_schwarz_title"),
this.strings.getString("player_played_schwarz_discarding", playerName, cardString));
}
@Override
public void showAIPlayedSchwarzMessageCardPlay(final String playerName, final Card card) {
String cardString = null;
if (card != null) {
cardString = this.strings.getCardStringForCardFace(card);
} else {
cardString = this.strings.getString("unknown_card");
}
showMessage(this.strings.getString("player_played_schwarz_title"),
this.strings.getString("player_played_schwarz_card_play", playerName, cardString));
}
/**
* {@inheritDoc}
*/
@Override
public void showErrorMessage(final String title, final String message) {
JOptionPane.showMessageDialog(null, message, title, JOptionPane.ERROR_MESSAGE);
}
/**
* {@inheritDoc}
*/
@Override
public void setGameState(final String tableName, final GameState state) {
this.tables.get(tableName).setGameState(state);
if (this.activeView.equals(tableName)) {
setActions(state);
}
}
private void setActions(final GameState state) {
switch (state) {
case GAME_START:
actions.get(JSkatAction.START_LOCAL_SERIES).setEnabled(true);
actions.get(JSkatAction.REPLAY_GAME).setEnabled(false);
actions.get(JSkatAction.NEXT_REPLAY_STEP).setEnabled(false);
break;
case BIDDING:
actions.get(JSkatAction.ANNOUNCE_GAME).setEnabled(false);
actions.get(JSkatAction.MAKE_BID).setEnabled(true);
actions.get(JSkatAction.HOLD_BID).setEnabled(true);
actions.get(JSkatAction.PASS_BID).setEnabled(true);
break;
case DISCARDING:
actions.get(JSkatAction.ANNOUNCE_GAME).setEnabled(true);
break;
case RAMSCH_GRAND_HAND_ANNOUNCING:
actions.get(JSkatAction.PLAY_GRAND_HAND).setEnabled(true);
actions.get(JSkatAction.PLAY_SCHIEBERAMSCH).setEnabled(true);
actions.get(JSkatAction.SCHIEBEN).setEnabled(false);
actions.get(JSkatAction.PICK_UP_SKAT).setEnabled(false);
break;
case SCHIEBERAMSCH:
actions.get(JSkatAction.PLAY_GRAND_HAND).setEnabled(false);
actions.get(JSkatAction.PLAY_SCHIEBERAMSCH).setEnabled(false);
actions.get(JSkatAction.SCHIEBEN).setEnabled(true);
actions.get(JSkatAction.PICK_UP_SKAT).setEnabled(true);
break;
case PICKING_UP_SKAT:
// FIXME jan 23.02.2013: use a different context panel when an
// opponent discards
actions.get(JSkatAction.MAKE_BID).setEnabled(false);
actions.get(JSkatAction.HOLD_BID).setEnabled(false);
actions.get(JSkatAction.PASS_BID).setEnabled(false);
actions.get(JSkatAction.PICK_UP_SKAT).setEnabled(true);
actions.get(JSkatAction.ANNOUNCE_GAME).setEnabled(true);
break;
case TRICK_PLAYING:
if (this.options.isPlayContra()) {
actions.get(JSkatAction.CALL_CONTRA).setEnabled(true);
} else {
actions.get(JSkatAction.CALL_CONTRA).setEnabled(false);
}
break;
case GAME_OVER:
actions.get(JSkatAction.CONTINUE_LOCAL_SERIES).setEnabled(true);
actions.get(JSkatAction.REPLAY_GAME).setEnabled(true);
actions.get(JSkatAction.NEXT_REPLAY_STEP).setEnabled(true);
break;
default:
break;
}
}
@Subscribe
public void showHelpDialogOn(final ShowHelpCommand command) {
new JSkatHelpDialog(null, this.strings.getString("help"), //$NON-NLS-1$
"org/jskat/gui/help/" + JSkatOptions.instance().getI18NCode() //$NON-NLS-1$
+ "/contents.html") //$NON-NLS-1$
.setVisible(true);
}
@Subscribe
public void showLicenceDialogOn(final ShowLicenseCommand command) {
new JSkatHelpDialog(null, this.strings.getString("license"), //$NON-NLS-1$
"org/jskat/gui/help/gpl3.html").setVisible(true); //$NON-NLS-1$
}
/**
* {@inheritDoc}
*/
@Override
public void setBidValueToMake(final String tableName, final int bidValue) {
this.tables.get(tableName).setBidValueToMake(bidValue);
}
/**
* {@inheritDoc}
*/
@Override
public void setBidValueToHold(final String tableName, final int bidValue) {
this.tables.get(tableName).setBidValueToHold(bidValue);
}
@Subscribe
public void showSkatSeriesStartDialogOn(final CreateSkatSeriesCommand command) {
this.skatSeriesStartDialog.setVisible(true);
}
/**
* {@inheritDoc}
*/
@Override
public void showISSLogin() {
final LoginPanel loginPanel = new LoginPanel("ISS login", actions);
addTabPanel(loginPanel, "ISS login");
}
/**
* {@inheritDoc}
*/
@Override
public void updateISSLobbyPlayerList(final String playerName, final String language, final long gamesPlayed,
final double strength) {
this.issLobby.updatePlayer(playerName, language, gamesPlayed, strength);
}
/**
* {@inheritDoc}
*/
@Override
public void removeFromISSLobbyPlayerList(final String playerName) {
this.issLobby.removePlayer(playerName);
}
@Subscribe
public void showIssLobbyOn(final IssConnectedEvent event) {
// show ISS lobby if connection was successfull
// FIXME (jan 07.12.2010) use constant instead of title
closeTabPanel("ISS login"); //$NON-NLS-1$
this.issLobby = new LobbyPanel("ISS lobby", actions);
addTabPanel(this.issLobby, this.strings.getString("iss_lobby"));
}
/**
* {@inheritDoc}
*/
@Override
public void updateISSLobbyTableList(final String tableName, final int maxPlayers, final long gamesPlayed,
final String player1, final String player2, final String player3) {
this.issLobby.updateTable(tableName, maxPlayers, gamesPlayed, player1, player2, player3);
}
/**
* {@inheritDoc}
*/
@Override
public void removeFromISSLobbyTableList(final String tableName) {
this.issLobby.removeTable(tableName);
}
/**
* {@inheritDoc}
*/
@Override
public void appendISSChatMessage(final ChatMessageType messageType, final ChatMessage message) {
LOG.debug("appendISSChatMessage"); //$NON-NLS-1$
this.issLobby.appendChatMessage(message);
for (final SkatTablePanel table : this.tables.values()) {
if (table instanceof ISSTablePanel) {
final ISSTablePanel issTable = (ISSTablePanel) table;
final String chatname = message.getChatName();
if ("Lobby".equals(chatname) || issTable.getName().equals(chatname)) {
issTable.appendChatMessage(message);
}
}
}
}
/**
* {@inheritDoc}
*/
@Override
public void updateISSTable(final String tableName, final TablePanelStatus tableStatus) {
// FIXME (jan 08.11.2010) seems very complicated
final SkatTablePanel panel = this.tables.get(tableName);
if (panel instanceof ISSTablePanel) {
((ISSTablePanel) panel).setTableStatus(tableStatus);
}
}
/**
* {@inheritDoc}
*/
@Override
public void updateISSTable(final String tableName, final String issLogin, final GameStartInformation status) {
if (issLogin.equals(status.getPlayerName(Player.FOREHAND))) {
updateISSTable(tableName, Player.MIDDLEHAND, Player.REARHAND, Player.FOREHAND, status);
} else if (issLogin.equals(status.getPlayerName(Player.MIDDLEHAND))) {
updateISSTable(tableName, Player.REARHAND, Player.FOREHAND, Player.MIDDLEHAND, status);
} else if (issLogin.equals(status.getPlayerName(Player.REARHAND))) {
updateISSTable(tableName, Player.FOREHAND, Player.MIDDLEHAND, Player.REARHAND, status);
}
}
private void updateISSTable(final String tableName, final Player leftOpponent, final Player rightOpponent,
final Player player, final GameStartInformation status) {
LOG.debug("Updating ISS table: " + tableName + " " + leftOpponent + " " //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ rightOpponent + " " + player); //$NON-NLS-1$
JSkatEventBus.TABLE_EVENT_BUSSES.get(tableName).post(
new GameStartEvent(status.getGameNo(), GameVariant.STANDARD, leftOpponent, rightOpponent, player));
// FIXME (jansch 09.11.2010) this is only done for ISS games
final SkatTablePanel table = this.tables.get(tableName);
table.setGameState(GameState.GAME_START);
table.setPlayerName(leftOpponent, status.getPlayerName(leftOpponent));
table.setPlayerTime(leftOpponent, status.getPlayerTime(leftOpponent));
table.setPlayerName(rightOpponent, status.getPlayerName(rightOpponent));
table.setPlayerTime(rightOpponent, status.getPlayerTime(rightOpponent));
table.setPlayerName(player, status.getPlayerName(player));
table.setPlayerTime(player, status.getPlayerTime(player));
table.setPlayerNames(status.getPlayerName(leftOpponent), false, status.getPlayerName(rightOpponent), false,
status.getPlayerName(player), false);
}
/**
* {@inheritDoc}
*/
@Override
public String getNewTableName(final int localTablesCreated) {
// get table name
String tableName = JOptionPane.showInputDialog(null, this.strings.getString("new_table_dialog_message"), //$NON-NLS-1$
this.strings.getString("local_table") + " " //$NON-NLS-1$ //$NON-NLS-2$
+ (localTablesCreated + 1));
// truncate table name
if (tableName != null && tableName.length() > 100) {
tableName = tableName.substring(0, 100);
}
return tableName;
}
/**
* {@inheritDoc}
*/
@Override
public void updateISSMove(final String tableName, final SkatGameData gameData,
final MoveInformation moveInformation) {
final Player movePlayer = moveInformation.getPlayer();
switch (moveInformation.getType()) {
// TODO add other types too
case DEAL:
setGameState(tableName, GameState.DEALING);
final SkatTablePanel table = this.tables.get(tableName);
table.hideCards(Player.FOREHAND);
table.hideCards(Player.MIDDLEHAND);
table.hideCards(Player.REARHAND);
final Map<Player, CardList> dealtCards = new HashMap<>();
dealtCards.put(Player.FOREHAND, moveInformation.getCards(Player.FOREHAND));
dealtCards.put(Player.MIDDLEHAND, moveInformation.getCards(Player.MIDDLEHAND));
dealtCards.put(Player.REARHAND, moveInformation.getCards(Player.REARHAND));
JSkatEventBus.TABLE_EVENT_BUSSES.get(tableName).post(new CardDealEvent(dealtCards, new CardList()));
setGameState(tableName, GameState.BIDDING);
break;
case BID:
setGameState(tableName, GameState.BIDDING);
JSkatEventBus.TABLE_EVENT_BUSSES.get(tableName)
.post(new BidEvent(movePlayer, moveInformation.getBidValue()));
setBidValueToHold(tableName, moveInformation.getBidValue());
break;
case HOLD_BID:
setGameState(tableName, GameState.BIDDING);
JSkatEventBus.TABLE_EVENT_BUSSES.get(tableName)
.post(new HoldBidEvent(movePlayer, gameData.getMaxBidValue()));
setBidValueToMake(tableName, SkatConstants.getNextBidValue(gameData.getMaxBidValue()));
break;
case PASS:
setGameState(tableName, GameState.BIDDING);
JSkatEventBus.TABLE_EVENT_BUSSES.get(tableName).post(new PassBidEvent(movePlayer));
setBidValueToMake(tableName, SkatConstants.getNextBidValue(gameData.getMaxBidValue()));
break;
case SKAT_REQUEST:
setGameState(tableName, GameState.PICKING_UP_SKAT);
break;
case PICK_UP_SKAT:
setGameState(tableName, GameState.DISCARDING);
if (moveInformation.getSkat().size() == 2) {
setSkat(tableName, moveInformation.getSkat());
}
break;
case GAME_ANNOUNCEMENT:
setGameState(tableName, GameState.DECLARING);
JSkatEventBus.INSTANCE.post(new TableGameMoveEvent(tableName,
new GameAnnouncementEvent(movePlayer, moveInformation.getGameAnnouncement())));
if (moveInformation.getGameAnnouncement().isOuvert()) {
showCardsForPlayer(tableName, movePlayer, moveInformation.getOuvertCards());
}
setGameState(tableName, GameState.TRICK_PLAYING);
break;
case CARD_PLAY:
setGameState(tableName, GameState.TRICK_PLAYING);
if (gameData.getTricks().size() > 1) {
final Trick currentTrick = gameData.getCurrentTrick();
final Trick lastTrick = gameData.getLastCompletedTrick();
if (currentTrick.getFirstCard() != null && currentTrick.getSecondCard() == null
&& currentTrick.getThirdCard() == null) {
// first card in new trick
JSkatEventBus.TABLE_EVENT_BUSSES.get(tableName).post(new TrickCompletedEvent(lastTrick));
}
}
JSkatEventBus.INSTANCE.post(
new TableGameMoveEvent(tableName, new TrickCardPlayedEvent(movePlayer, moveInformation.getCard())));
break;
case SHOW_CARDS:
showCardsForPlayer(tableName, movePlayer, moveInformation.getOuvertCards());
break;
case RESIGN:
setResign(tableName, movePlayer);
break;
case TIME_OUT:
// TODO show message box
break;
}
// adjust player times
if (moveInformation.getMovePlayer() != MovePlayer.WORLD) {
// FIXME dirty hack
final SkatTablePanel table = this.tables.get(tableName);
table.setPlayerTime(Player.FOREHAND, moveInformation.getPlayerTime(Player.FOREHAND));
table.setPlayerTime(Player.MIDDLEHAND, moveInformation.getPlayerTime(Player.MIDDLEHAND));
table.setPlayerTime(Player.REARHAND, moveInformation.getPlayerTime(Player.REARHAND));
}
}
private void showCardsForPlayer(final String tableName, final Player player, final CardList cards) {
final Map<Player, CardList> ouvertCards = new HashMap<>();
ouvertCards.put(player, cards);
JSkatEventBus.INSTANCE.post(new ShowCardsCommand(tableName, ouvertCards));
}
@Subscribe
public void showPreferencesDialogOn(final ShowPreferencesCommand command) {
this.preferencesDialog.validate();
this.preferencesDialog.setVisible(true);
}
@Subscribe
public void showTrainingOverviewDialogOn(final ShowTrainingOverviewCommand command) {
this.trainingOverview.setVisible(true);
}
@Subscribe
public void closeTableOn(final TableRemovedEvent event) {
closeTabPanel(event.tableName);
}
/**
* {@inheritDoc}
*/
private void closeTabPanel(final String tabName) {
AbstractTabPanel panel = (AbstractTabPanel) this.tabs.getSelectedComponent();
if (!tabName.equals(panel.getName())) {
for (final Component currPanel : this.tabs.getComponents()) {
if (tabName.equals(currPanel.getName())) {
panel = (AbstractTabPanel) currPanel;
}
}
}
if (panel instanceof SkatTablePanel || panel instanceof ISSTablePanel) {
// remove from table list
this.tables.remove(panel.getName());
}
this.tabs.remove(panel);
}
/**
* {@inheritDoc}
*/
@Override
public List<String> getPlayerForInvitation(final Set<String> playerNames) {
final List<String> result = new ArrayList<>();
final PlayerInvitationPanel invitationPanel = new PlayerInvitationPanel(playerNames);
final int dialogResult = JOptionPane.showConfirmDialog(null, invitationPanel,
this.strings.getString("invite_players"), //$NON-NLS-1$
JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
if (dialogResult == JOptionPane.OK_OPTION) {
result.addAll(invitationPanel.getPlayer());
}
LOG.debug("Players to invite: " + result); //$NON-NLS-1$
return result;
}
private void addTabPanel(final AbstractTabPanel newPanel, final String title) {
this.tabs.addTab(title, newPanel);
this.tabs.setTabComponentAt(this.tabs.indexOfComponent(newPanel),
new JSkatTabComponent(this.tabs, this.bitmaps));
this.tabs.setSelectedComponent(newPanel);
newPanel.setFocus();
}
/**
* {@inheritDoc}
*/
@Override
public void setSeriesState(final String tableName, final SeriesState state) {
this.tables.get(tableName).setSeriesState(state);
}
/**
* {@inheritDoc}
*/
@Override
public void setSkat(final String tableName, final CardList skat) {
this.tables.get(tableName).setSkat(skat);
}
/**
* {@inheritDoc}
*/
@Override
public boolean showISSTableInvitation(final String invitor, final String tableName) {
boolean result = false;
final String question = this.strings.getString("iss_table_invitation", //$NON-NLS-1$
invitor, tableName);
final int answer = JOptionPane.showConfirmDialog(null, question,
this.strings.getString("iss_table_invitation_title"), //$NON-NLS-1$
JOptionPane.YES_NO_OPTION);
if (answer == JOptionPane.YES_OPTION) {
result = true;
}
return result;
}
/**
* {@inheritDoc}
*/
@Override
public void showCardNotAllowedMessage(final Card card) {
final String title = this.strings.getString("card_not_allowed_title"); //$NON-NLS-1$
final String message = this.strings.getString("card_not_allowed_message", //$NON-NLS-1$
card != null ? this.strings.getSuitStringForCardFace(card.getSuit()) : "--", //$NON-NLS-1$
card != null ? this.strings.getRankStringForCardFace(card.getRank()) : "--"); //$NON-NLS-1$
showErrorMessage(title, message);
}
@Subscribe
public void addTrainingResultOn(final TrainingResultEvent event) {
this.trainingOverview.addTrainingResult(event.gameType, event.episodes, event.totalGamesWon,
event.avgNetworkErrorDeclarer, event.avgNetworkErrorOpponents);
}
/**
* {@inheritDoc}
*/
@Override
public void setPlayerNames(String tableName, String upperLeftPlayerName, boolean isUpperLeftPlayerAIPlayer,
String upperRightPlayerName, boolean isUpperRightPlayerAIPlayer, String lowerPlayerName,
boolean isLowerPlayerAIPlayer) {
this.tables.get(tableName).setPlayerNames(upperLeftPlayerName, isUpperLeftPlayerAIPlayer, upperRightPlayerName,
isUpperRightPlayerAIPlayer, lowerPlayerName, isLowerPlayerAIPlayer);
}
/**
* {@inheritDoc}
*/
@Override
public void setDeclarer(final String tableName, final Player declarer) {
this.tables.get(tableName).setDeclarer(declarer);
}
@Subscribe
public void closeAllIssTabsOn(final IssDisconnectCommand event) {
for (final Component currPanel : this.tabs.getComponents()) {
if (currPanel instanceof LobbyPanel || currPanel instanceof ISSTablePanel) {
closeTabPanel(currPanel.getName());
}
}
}
@Subscribe
public void showErrorMessageOn(final InvalidNumberOfCardsInDiscardedSkatEvent event) {
showErrorMessage(this.strings.getString("invalid_number_of_cards_in_skat_title"), //$NON-NLS-1$
this.strings.getString("invalid_number_of_cards_in_skat_message"));
}
@Subscribe
public void showErrorMessageOn(final DuplicateTableNameInputEvent event) {
final String message = this.strings.getString("duplicate_table_name_message", //$NON-NLS-1$
event.tableName);
showErrorMessage(this.strings.getString("duplicate_table_name_title"), //$NON-NLS-1$
message);
}
@Subscribe
public void showErrorMessageOn(final EmptyTableNameInputEvent event) {
showErrorMessage(this.strings.getString("invalid_name_input_null_title"), //$NON-NLS-1$
this.strings.getString("invalid_name_input_null_message"));
}
/**
* {@inheritDoc}
*/
@Override
public void setResign(final String tableName, final Player player) {
this.tables.get(tableName).setResign(player);
}
/**
* {@inheritDoc}
*/
@Override
public void setGeschoben(final String tableName, final Player player) {
this.tables.get(tableName).setGeschoben(player);
}
/**
* {@inheritDoc}
*/
@Override
public void setDiscardedSkat(final String tableName, final Player player, final CardList skatBefore,
final CardList discardedSkat) {
this.tables.get(tableName).setDiscardedSkat(player, skatBefore, discardedSkat);
}
/**
* {@inheritDoc}
*/
@Override
public void takeCardFromSkat(final String tableName, final Card card) {
this.tables.get(tableName).takeCardFromSkat(card);
}
/**
* {@inheritDoc}
*/
@Override
public void putCardIntoSkat(final String tableName, final Card card) {
this.tables.get(tableName).putCardIntoSkat(card);
}
/**
* {@inheritDoc}
*/
@Override
public void openWebPage(final String link) {
try {
final Desktop desktop = java.awt.Desktop.getDesktop();
final URI uri = new URI(link);
desktop.browse(uri);
} catch (final URISyntaxException except) {
LOG.error(except.toString());
} catch (final IOException except) {
LOG.error(except.toString());
}
}
@Override
public AbstractHumanJSkatPlayer getHumanPlayerForGUI() {
return new SwingHumanPlayer();
}
@Override
public void setActiveView(final String viewName) {
this.activeView = viewName;
}
}