/**
* Copyright 1999-2009 The Pegadi Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Tetris to the people!
*
* @author H?vard Wigtil
* @version $Revision$, $Date$
*/
package org.pegadi.games.tetris;
import org.pegadi.games.Score;
import org.pegadi.games.tetris.actions.NewGameAction;
import org.pegadi.model.LoginContext;
import org.pegadi.util.GridBagConstraints2;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;
import java.awt.*;
import java.awt.event.*;
import java.net.URL;
import java.util.Enumeration;
import java.util.Properties;
import java.util.ResourceBundle;
public class Tetris extends JFrame {
protected BorderLayout borderLayout1 = new BorderLayout();
protected NewGameAction newGameAction;
protected JComboBox levelCombo = new JComboBox();
protected JLabel levelLabel = new JLabel();
protected JPanel gamePanel = new JPanel();
protected GridBagLayout gameLayout = new GridBagLayout();
protected JPanel gameInfoPanel = new JPanel();
protected JLabel gameScoreText = new JLabel();
protected JLabel gameLevelLabel = new JLabel();
protected JLabel gameScoreLabel = new JLabel();
protected GridBagLayout gameInfoLayout = new GridBagLayout();
protected JLabel gameLevelText = new JLabel();
protected JLabel gameLinesLabel = new JLabel();
protected JLabel gameLinesText = new JLabel();
protected Border border1;
protected TitledBorder titledBorder1;
protected Border border2;
protected JLabel gameNextlabel = new JLabel();
protected JToolBar toolBar = new JToolBar();
protected ScorePanel scores = new ScorePanel();
protected TetrisWindow tetrisWnd = new TetrisWindow();
protected PreviewWindow gameNextWindow = new PreviewWindow();
protected TetrisGame mActiveGame;
protected Thread mActiveTimer;
/** The score of the currently running game. */
protected TetrisScore score;
/** Translatable strings. */
protected ResourceBundle strings;
/** Shared UI definitions. */
protected ResourceBundle uiShared;
/** List of application preferences. */
Properties prefs;
static final String PREFS_ROTATELEFT = "Rotate_left";
static final String PREFS_DOMAIN = "Tetris";
static final String PREFS_PREVIEW= "Preview";
static final String PREFS_SCORES = "Scorelist";
static final String PREFS_ACTIVE_ONLY = "active_only";
static final String PREFS_HIGH = "Hiscores";
static final String PREFS_TODAY = "Todays_best";
static final String PREFS_PERS = "Personal_best";
static final String PREFS_START = "Start_level";
/** A count of completed lines, used to detect if score updates should be
sendt to the server. */
protected int lineCount;
protected JButton gameStatusButton = new JButton();
protected JMenuBar menuBar = new JMenuBar();
protected JMenu gameMenu = new JMenu();
protected JMenu helpMenu = new JMenu();
protected JMenuItem aboutItem = new JMenuItem();
protected JMenuItem exitItem = new JMenuItem();
protected JCheckBoxMenuItem pauseItem = new JCheckBoxMenuItem();
protected JMenu editMenu = new JMenu();
protected JMenuItem preferencesItem = new JMenuItem();
/** rotateLeft check*/
private boolean rotateLeft;
private final Logger log = LoggerFactory.getLogger(getClass());
public Tetris() {
super();
newGameAction = new NewGameAction(this);
this.prefs = new Properties();
try {
jbInit();
}
catch(Exception e) {
log.error("Exception creating the interface.", e);
}
for (int i = 1; i < 10; i++) {
levelCombo.addItem(i);
}
loadPrefs();
// Add this after populating to avoid recieving an event for population.
levelCombo.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
levelCombo_itemStateChanged(e);
}
});
URL iconURL = getClass().getResource("/images/tetris.gif");
if (iconURL != null) {
ImageIcon icon = new ImageIcon(iconURL);
setIconImage(icon.getImage());
}
tetrisWnd.addScoreListener(new ScoreListener() {
public void scoreChanged(ScoreEvent e) {
updateScore(e);
}
});
tetrisWnd.addBrickListener(new BrickListener() {
public void brickChanged(BrickEvent e) {
updateBrick(e);
}
});
scores.updateScores(Boolean.valueOf(prefs.getProperty(PREFS_ACTIVE_ONLY)));
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
}
/**
* Toggles wich way the block should turn
*
* @param rotateLeft sets the block to rotate left
*/
private void setRotateLeft(boolean rotateLeft){
this.rotateLeft = rotateLeft;
}
/**
* Toggles preview on and of.
*
* @param show Preview status.
*/
protected void showPreview(boolean show) {
gameNextlabel.setVisible(show);
gameNextWindow.setVisible(show);
gameInfoPanel.validate();
}
/**
* Toggles display of scores list.
*
* @param show status.
*/
protected void showScoreLists(boolean show) {
scores.setVisible(show);
this.getContentPane().validate();
}
/**
* This method is called when <code>BrickEvent</code>s occur.
*/
protected void updateBrick(BrickEvent e) {
gameNextWindow.drawNextBlock(e.getNext());
}
/*
public static void main(String[] args) {
Locale.setDefault(new Locale("no", "NO"));
Server server;
if (System.getSecurityManager() == null) {
System.setSecurityManager(new RMISecurityManager());
}
try {
String s;
if (args.length > 0) {
s = args[0];
}
else {
s = "localhost";
}
String name = "//" + s + "/" + "Server";
server = (Server) Naming.lookup(name);
} catch (Exception e) {
Log.m("Tetris.main: Couldn't connect to the server. Tetris will run in offline mode", 0);
Log.e(e, 0);
server = null;
}
Log.m("Tetris.main: Server is " + server);
String key = null;
if (server != null) {
LoginDialog loginDialog = new LoginDialog(null);
String user;
String pass;
try {
do {
loginDialog.pack();
loginDialog.setVisible(true);
user = loginDialog.getUserName();
pass = loginDialog.getPassword();
loginDialog.setVisible(false);
key = server.login(user, pass);
} while (key == null);
} catch (Exception e) {
Log.m("Tetris.main: Exception logging in.");
Log.e(e);
}
}
final Tetris tetris = new Tetris();
tetris.setSize(800, 400);
tetris.setLocation(0, 100);
tetris.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
if (LoginContext.server != null) {
try {
LoginContext.server.logout(LoginContext.sessionKey);
} catch (Exception ex) {
Log.m(this, "windowClosing",
"Error logging out from server");
Log.e(ex);
}
}
System.exit(0);
}
});
tetris.setVisible(true);
}
*/
protected void updateScore(ScoreEvent e) {
gameScoreText.setText(String.valueOf(e.getScore()));
gameLevelText.setText(String.valueOf(e.getLevel()));
gameLinesText.setText(String.valueOf(e.getLines()));
if (score != null) {
score.setScore(mActiveGame.getScore());
score.setLevel(mActiveGame.getLevel());
score.setLines(mActiveGame.getLines());
try {
scores.insertScore(score);
} catch (Exception ex) {
log.error("Exception updating score tables");
}
if (lineCount < e.getLines()) {
try {
LoginContext.server.updateScore(score, LoginContext.sessionKey);
} catch (Exception ex) {
log.error("Error updating score server.", ex);
}
lineCount = e.getLines();
}
}
if (e.isFinal()) {
endGame();
}
}
private void jbInit() {
strings = ResourceBundle.getBundle("org.pegadi.games.tetris.TetrisStrings");
uiShared = ResourceBundle.getBundle("org.pegadi.client.UIStrings");
this.setTitle(strings.getString("frame_title"));
border1 = new EtchedBorder(EtchedBorder.RAISED,Color.white,new Color(134, 134, 134));
titledBorder1 = new TitledBorder(border1,strings.getString("game_info"));
border2 = BorderFactory.createCompoundBorder(titledBorder1,BorderFactory.createEmptyBorder(10,10,10,10));
this.getContentPane().setLayout(borderLayout1);
levelLabel.setDisplayedMnemonic('L');
levelLabel.setText(strings.getString("level_combo"));
gamePanel.setLayout(gameLayout);
gameScoreText.setHorizontalAlignment(SwingConstants.RIGHT);
gameScoreText.setText("0");
gameLevelLabel.setText(strings.getString("level_label"));
gameScoreLabel.setText(strings.getString("score_label"));
gameInfoPanel.setLayout(gameInfoLayout);
gameLevelText.setHorizontalAlignment(SwingConstants.RIGHT);
gameLevelText.setText("1");
gameLinesLabel.setText(strings.getString("lines_label"));
gameLinesText.setHorizontalAlignment(SwingConstants.RIGHT);
gameLinesText.setText("0");
gameInfoPanel.setBorder(border2);
gameInfoPanel.setToolTipText("");
gamePanel.setAlignmentX((float) 0.0);
//gamePanel.setPreferredSize(new Dimension(200, 99));
gameNextlabel.setText(strings.getString("next_label"));
gameStatusButton.setText(strings.getString("new_game"));
gameStatusButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
gameStatusButton_actionPerformed(e);
}
});
gameMenu.setMnemonic(strings.getString("menu_game_mnem").charAt(0));
gameMenu.setText(strings.getString("menu_game"));
helpMenu.setMnemonic(uiShared.getString("menu_help_mnem").charAt(0));
helpMenu.setText(uiShared.getString("menu_help"));
aboutItem.setMnemonic(uiShared.getString("menu_help_about_mnem").charAt(0));
aboutItem.setText(uiShared.getString("menu_help_about"));
aboutItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
aboutItem_actionPerformed(e);
}
});
//exitItem.setMnemonic(uiShared.getString("menu_file_exit_mnem").charAt(0));
exitItem.setText(uiShared.getString("menu_file_close"));
exitItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(87, java.awt.event.KeyEvent.CTRL_MASK, false));
exitItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
dispose();
}
});
pauseItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(80, java.awt.event.KeyEvent.CTRL_MASK, false));
pauseItem.setEnabled(false);
pauseItem.setText(strings.getString("menu_game_pause"));
pauseItem.setMnemonic(strings.getString("menu_game_pause_mnem").charAt(0));
pauseItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
pauseItem_actionPerformed(e);
}
});
editMenu.setMnemonic(uiShared.getString("menu_edit_mnem").charAt(0));
editMenu.setText(uiShared.getString("menu_edit"));
preferencesItem.setMnemonic(uiShared.getString("menu_edit_pref_mnem").charAt(0));
preferencesItem.setText(uiShared.getString("menu_edit_pref"));
preferencesItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
preferencesItem_actionPerformed(e);
}
});
gamePanel.add(gameStatusButton, new GridBagConstraints2(1, 1, 1, 1, 0.0, 0.0
,GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
gamePanel.add(tetrisWnd, new GridBagConstraints2(1, 1, 1, 1, 0.0, 0.0
,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 15, 0, 15), 0, 0));
gamePanel.add(gameInfoPanel, new GridBagConstraints2(2, 1, 1, 1, 0.0, 0.0
,GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 15, 0, 15), 0, 0));
gameInfoPanel.add(gameScoreLabel, new GridBagConstraints2(0, 0, 1, 1, 0.0, 0.0
,GridBagConstraints2.WEST, GridBagConstraints2.NONE, new Insets(0, 0, 0, 5), 0, 0));
gameInfoPanel.add(gameScoreText, new GridBagConstraints2(1, 0, 1, 1, 0.0, 0.0
,GridBagConstraints2.EAST, GridBagConstraints2.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
gameInfoPanel.add(gameLevelLabel, new GridBagConstraints2(0, 1, 2, 1, 0.0, 0.0
,GridBagConstraints2.WEST, GridBagConstraints2.NONE, new Insets(0, 0, 0, 5), 0, 0));
gameInfoPanel.add(levelCombo, new GridBagConstraints2(1, 1, 1, 1, 0.0, 0.0
,GridBagConstraints2.EAST, GridBagConstraints2.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
gameInfoPanel.add(gameLinesLabel, new GridBagConstraints2(0, 2, 1, 1, 0.0, 0.0
,GridBagConstraints2.WEST, GridBagConstraints2.NONE, new Insets(0, 0, 0, 5), 0, 0));
gameInfoPanel.add(gameLinesText, new GridBagConstraints2(1, 2, 1, 1, 0.0, 0.0
,GridBagConstraints2.EAST, GridBagConstraints2.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
gameInfoPanel.add(gameNextlabel, new GridBagConstraints2(0, 3, 1, 1, 0.0, 0.0
,GridBagConstraints2.NORTHWEST, GridBagConstraints2.NONE, new Insets(0, 0, 0, 0), 0, 0));
gameInfoPanel.add(gameNextWindow, new GridBagConstraints2(1, 3, 1, 1, 0.0, 0.0
,GridBagConstraints2.WEST, GridBagConstraints2.NONE, new Insets(5, 0, 10, 0), 3, 3));
menuBar.add(gameMenu);
menuBar.add(editMenu);
menuBar.add(helpMenu);
helpMenu.add(aboutItem);
gameMenu.add(newGameAction);
gameMenu.add(pauseItem);
gameMenu.addSeparator();
gameMenu.add(exitItem);
editMenu.add(preferencesItem);
setJMenuBar(menuBar);
// toolbar starts
JPanel topPanel = new JPanel();
this.getContentPane().add(topPanel, BorderLayout.NORTH);
topPanel.setLayout(new GridLayout(0, 1));
topPanel.add(toolBar);
// new game
toolBar.add(newGameAction);
// exit
JButton tempButton;
tempButton = toolBar.add(new AbstractAction() {
public void actionPerformed(ActionEvent actionEvent) {
dispose();
}
});
tempButton.setToolTipText(exitItem.getText());
ImageIcon quitIcon = new ImageIcon(getClass().getResource(strings.getString("icon_close")));
tempButton.setIcon(quitIcon);
//gamePanel.setBackground(Color.red);
this.getContentPane().add(gamePanel, BorderLayout.CENTER);
this.getContentPane().add(scores, BorderLayout.WEST);
tetrisWnd.addFocusListener(new FocusAdapter() {
public void focusLost(FocusEvent e) {
if (tetrisWnd != null) {
if (!tetrisWnd.isPaused()) {
tetrisWnd.setPause(true);
pauseItem.setState(true);
}
}
}
});
}
public void startGame() {
gameStatusButton.setVisible(false);
gameInfoPanel.remove(levelCombo);
gameInfoPanel.add(gameLevelText, new GridBagConstraints2(1, 1, 1, 1, 0.0, 0.0
,GridBagConstraints2.EAST, GridBagConstraints2.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
// start game
tetrisWnd.init();
gameNextWindow.init();
lineCount = 0;
try {
Score s = LoginContext.server.startGame("tetris", LoginContext.sessionKey);
if (s != null) {
if (s instanceof TetrisScore) {
score = (TetrisScore)s;
}
else {
log.warn(
"Score from server is not a TetrisScore");
}
}
else {
log.warn(
"Score from server is NULL!");
}
} catch (Exception ex) {
log.error(
"Error starting score on server", ex);
}
int level;
if (levelCombo.getSelectedItem() instanceof Integer) {
level = (Integer) levelCombo.getSelectedItem();
}
else {
level = 1;
}
mActiveGame = new TetrisGame(level, rotateLeft);
tetrisWnd.startNewGame(mActiveGame);
mActiveTimer = new Thread(tetrisWnd);
mActiveTimer.start();
tetrisWnd.setPause(false);
tetrisWnd.requestFocus();
pauseItem.setEnabled(true);
newGameAction.setEnabled(false);
lineCount = 0;
scores.updateScores(Boolean.valueOf(prefs.getProperty(PREFS_ACTIVE_ONLY)));
}
protected void endGame() {
try {
LoginContext.server.endGame(score, LoginContext.sessionKey);
} catch (Exception ex) {
log.error(
"Error reporting final score to server. The score is NOT recorded.", ex);
}
scores.updateScores(Boolean.valueOf(prefs.getProperty(PREFS_ACTIVE_ONLY)));
gameStatusButton.setVisible(true);
pauseItem.setEnabled(false);
newGameAction.setEnabled(true);
gameInfoPanel.remove(gameLevelText);
gameInfoPanel.add(levelCombo, new GridBagConstraints2(1, 1, 1, 1, 0.0, 0.0
,GridBagConstraints2.EAST, GridBagConstraints2.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
}
/**
* Load preferences from the server and apply.
*/
protected void loadPrefs() {
try {
prefs = LoginContext.server.getPreferences(PREFS_DOMAIN, LoginContext.sessionKey);
} catch (Exception e) {
log.error(
"Exception getting preferences for domain " + PREFS_DOMAIN, e);
prefs = new Properties();
}
String preview = prefs.getProperty(PREFS_PREVIEW);
if (preview == null) {
preview = "true";
prefs.put(PREFS_PREVIEW, preview);
}
showPreview(Boolean.valueOf(preview));
String rotateLeft = prefs.getProperty(PREFS_ROTATELEFT);
if (rotateLeft == null) {
rotateLeft = "false";
prefs.put(PREFS_ROTATELEFT, rotateLeft);
}
setRotateLeft(Boolean.valueOf(rotateLeft));
String start = prefs.getProperty(PREFS_START);
if (start == null) {
levelCombo.setSelectedIndex(0);
}
else {
try {
int s = Integer.parseInt(start);
levelCombo.setSelectedIndex(s-1);
} catch (Exception e) {
log.error("Preference " + PREFS_START + " is not a number: " + start, e);
levelCombo.setSelectedIndex(0);
}
}
String activeOnly = prefs.getProperty(PREFS_ACTIVE_ONLY);
if(activeOnly == null) {
prefs.put(PREFS_ACTIVE_ONLY, String.valueOf(false));
}
String scoreLists = prefs.getProperty(PREFS_SCORES);
if (scoreLists == null) {
scoreLists = "true";
prefs.put(PREFS_SCORES, scoreLists);
}
showScoreLists(Boolean.valueOf(scoreLists));
String hiscore = prefs.getProperty(PREFS_HIGH);
if (hiscore == null) {
prefs.put(PREFS_HIGH, "10");
scores.setHighLenght(10);
}
else {
scores.setHighLenght(Integer.valueOf(hiscore));
}
String today = prefs.getProperty(PREFS_TODAY);
if (today == null) {
prefs.put(PREFS_TODAY, "5");
scores.setTodayLenght(5);
}
else {
scores.setTodayLenght(Integer.valueOf(today));
}
String pers = prefs.getProperty(PREFS_PERS);
if (pers == null) {
prefs.put(PREFS_PERS, "5");
scores.setPersonalLenght(5);
}
else {
scores.setPersonalLenght(Integer.valueOf(pers));
}
}
protected void gameStatusButton_actionPerformed(ActionEvent e) {
startGame();
}
/**
* Called when "Exit" is chosen from the menu.
*/
public void dispose() {
tetrisWnd.stop();
tetrisWnd = null;
super.dispose();
}
protected void pauseItem_actionPerformed(ActionEvent e) {
if (tetrisWnd != null) {
boolean pause = pauseItem.getState();
tetrisWnd.setPause(pause);
pauseItem.setState(pause);
if (!pause) {
tetrisWnd.requestFocus();
}
}
}
protected void aboutItem_actionPerformed(ActionEvent e) {
JLabel msg = new JLabel();
msg.setText(strings.getString("about_message"));
JOptionPane.showMessageDialog(this, msg);
}
protected void levelCombo_itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
Integer i = (Integer)e.getItem();
log.info("Changed to level" + i);
try {
LoginContext.server.savePreference(PREFS_DOMAIN, PREFS_START, i.toString(),LoginContext.sessionKey);
} catch (Exception ex) {
log.error(
"Unable to save pref " + PREFS_START + " with value " + i.toString(), ex);
}
}
}
protected void preferencesItem_actionPerformed(ActionEvent e) {
PrefsDialog pd = new PrefsDialog(this, prefs);
pd.setVisible(true);
if (pd.okResult()) {
Properties changed = pd.getChangedPreferences();
boolean updateScores = false;
Enumeration en = changed.keys();
while (en.hasMoreElements()) {
String key = en.nextElement().toString();
String value = changed.getProperty(key);
prefs.put(key, value);
try {
LoginContext.server.savePreference(PREFS_DOMAIN, key, value,LoginContext.sessionKey);
} catch (Exception ex) {
log.error(
"Unable to save pref: " + key + "=" + value, ex);
}
if (key.equals(PREFS_PREVIEW)) {
showPreview(Boolean.valueOf(value));
} else if (key.equals(PREFS_SCORES)) {
showScoreLists(Boolean.valueOf(value));
} else if (key.equals(PREFS_HIGH)) {
scores.setHighLenght(Integer.parseInt(value));
updateScores = true;
} else if (key.equals(PREFS_PERS)) {
scores.setPersonalLenght(Integer.parseInt(value));
updateScores = true;
} else if (key.equals(PREFS_TODAY)) {
scores.setTodayLenght(Integer.parseInt(value));
updateScores = true;
} else if (key.equals(PREFS_ROTATELEFT)) {
setRotateLeft(Boolean.valueOf(value));
} else if(key.equals(PREFS_ACTIVE_ONLY)) {
scores.updateScores(Boolean.valueOf(prefs.getProperty(PREFS_ACTIVE_ONLY)));
}
else {
log.warn(
"Unrecognized preference '" + key + "'");
}
} // While enumeration
if (updateScores) {
scores.updateScores(Boolean.valueOf(prefs.getProperty(PREFS_ACTIVE_ONLY)));
}
} // if okResult
} // Method preferencesItem_actionPerformed
}