/** * 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 }