View Javadoc

1   /**
2    * This program is free software: you can redistribute it and/or modify
3    * it under the terms of the GNU General Public License as published by
4    * the Free Software Foundation, version 3.
5    *
6    * This program is distributed in the hope that it will be useful,
7    * but WITHOUT ANY WARRANTY; without even the implied warranty of
8    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9    * GNU General Public License for more details.
10   *
11   * You should have received a copy of the GNU General Public License
12   * along with this program. If not, see <http://www.gnu.org/licenses/>.
13   */
14  
15  package net.curre.prefcount.gui;
16  
17  import java.awt.*;
18  import java.awt.event.WindowAdapter;
19  import java.awt.event.WindowEvent;
20  import java.util.ArrayList;
21  import java.util.List;
22  import java.util.ResourceBundle;
23  import java.util.logging.Logger;
24  import javax.swing.*;
25  
26  import net.curre.prefcount.App;
27  import net.curre.prefcount.PrefCountRegistry;
28  import net.curre.prefcount.event.StartAskingQuestionsListener;
29  import net.curre.prefcount.gui.aa.AAJButton;
30  import net.curre.prefcount.gui.aa.AAJPanel;
31  import net.curre.prefcount.gui.aa.AAJLabel;
32  import net.curre.prefcount.gui.menu.PrefCountMenuBar;
33  import net.curre.prefcount.bean.GameResultBean;
34  import net.curre.prefcount.bean.PlayerStatistics;
35  import net.curre.prefcount.bean.Settings;
36  import net.curre.prefcount.service.LafThemeService;
37  import net.curre.prefcount.service.SettingsService;
38  import net.curre.prefcount.util.Utilities;
39  
40  /**
41   * This class represent the main frame, which contains
42   * the intro message and the score board.
43   * <p/>
44   * Creation date: Mar 8, 2007
45   *
46   * @author Yevgeny Nyden
47   */
48  public class MainWindow extends JFrameWithAnimatedInnerPanel {
49  
50    /** Private class logger. */
51    private static Logger log = Logger.getLogger(MainWindow.class.toString());
52  
53    /** Reference to the result bean */
54    public GameResultBean playerResults;
55  
56    /** Reference to the player dialog frame. */
57    public PlayerDialogBasePanel playerDialogFrame;
58  
59    protected JPanel mainPanel;
60    protected JPanel topPanel;
61    protected JButton button3;
62    protected JButton button4;
63    protected JLabel introLabel;
64    protected ScoreBoardPanel scoreBoardPanel;
65  
66    /** Flag to indicate that player dialog has started. */
67    private boolean dialogStarted = false;
68  
69    /** Reference to the prefcount main window menu bar. */
70    private PrefCountMenuBar menuBar;
71  
72    /** Default constructor. */
73    public MainWindow() {
74      this(true);
75    }
76  
77    /**
78     * Constructor that sets frame visibility.
79     *
80     * @param isVisible True when the frame should be made visible by default;
81     *                  false when the frame shoudl be invisible instead.
82     */
83    public MainWindow(boolean isVisible) {
84      super(ResourceBundle.getBundle("default").getString("pref.scoreboard.title"));
85  
86      log.fine("Creating main window");
87  
88      // creating and setting the windows icon
89      Image appImg = Toolkit.getDefaultToolkit().createImage(App.class.getResource("images/PrefCount-16x16.png"));
90      super.setIconImage(appImg);
91  
92      ResourceBundle bundle = ResourceBundle.getBundle("default");
93      Settings settings = SettingsService.getSettings();
94      LafThemeService.getInstance().setLookAndFeel(settings.getLafSkinId(), true);
95  
96      final String introWord = bundle.getString("pref.scoreboard.intro");
97      playerResults = new GameResultBean();
98  
99      super.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
100     super.setResizable(true);
101     super.setSize(settings.getMainFrameWidth(), settings.getMainFrameHeight());
102 
103     topPanel = new AAJPanel(new BorderLayout());
104     JPanel buttonsInnerPanel = new JPanel();
105     button3 = createPlayerNumberButton(3);
106     button4 = createPlayerNumberButton(4);
107     buttonsInnerPanel.add("Button 3", button3);
108     buttonsInnerPanel.add("Button 4", button4);
109     topPanel.add(buttonsInnerPanel, BorderLayout.CENTER);
110 
111     mainPanel = new AAJPanel(new CardLayout());
112     introLabel = new AAJLabel(introWord, JLabel.CENTER);
113     mainPanel.add(introLabel, "Intro panel");
114     scoreBoardPanel = new ScoreBoardPanel(playerResults);
115     mainPanel.add(scoreBoardPanel, "Score board panel");
116 
117     super.getContentPane().add(topPanel, BorderLayout.PAGE_START);
118     super.getContentPane().add(mainPanel, BorderLayout.CENTER);
119 
120     // focusing the first button when the frame gets visible
121     super.addWindowListener(new WindowAdapter() {
122       public void windowOpened(WindowEvent e) {
123         button3.setFocusable(true);
124         button3.requestFocus();
125       }
126     });
127     menuBar = PrefCountRegistry.getInstance().addMainWindowMenuBar(this, topPanel);
128     resetFrameKeyShortcuts();
129     super.setVisible(isVisible);
130   }
131 
132   /**
133    * Opens the player dialog frame after user
134    * choses number of players option.
135    *
136    * @param numberOfPlayers Number of players chosen.
137    */
138   public void startPlayerDialog(int numberOfPlayers) {
139 
140     // disabling the action and language menus on the menu bar
141     menuBar.disableActionMenu();
142     menuBar.disableLanguageMenu();
143 
144     // setting the selected button and disabling the otherone
145     JButton actButton;
146     if (numberOfPlayers == 3) {
147       actButton = button3;
148       button4.setEnabled(false);
149     } else {
150       actButton = button4;
151       button3.setEnabled(false);
152     }
153     scoreBoardPanel.locationsMap.initialize(numberOfPlayers);
154 
155     actButton.setSelected(true);
156     actButton.setBorderPainted(false);
157     actButton.setFocusPainted(false);
158     int size = actButton.getActionListeners().length;
159     for (int i = 0; i < size; ++i) {
160       actButton.removeActionListener(actButton.getActionListeners()[0]);
161     }
162 
163     CardLayout clay = (CardLayout) mainPanel.getLayout();
164     clay.next(mainPanel);
165 
166     // creating the stats
167     List<PlayerStatistics> stats = new ArrayList<PlayerStatistics>();
168     for (int i = 0; i < numberOfPlayers; ++i) {
169       PlayerStatistics stat = new PlayerStatistics(playerResults, i);
170       stat.setPlayerName("");
171       stats.add(stat);
172     }
173     playerResults.setPlayerStats(stats);
174     playerDialogFrame = new PlayerDialogBasePanel(numberOfPlayers, this);
175 
176     dialogStarted = true;
177     InputMap map = topPanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
178     map.clear();
179   }
180 
181   /**
182    * This will refresh the main and dialog frames
183    * (i.e. update text on all components according to the
184    * current default locale, change the frame size, etc.).
185    */
186   public void repaint() {
187     Settings settings = SettingsService.getSettings();
188     super.setSize(settings.getMainFrameWidth(), settings.getMainFrameHeight());
189     super.repaint();
190     ResourceBundle bundle = ResourceBundle.getBundle("default");
191 
192     // the components below are null at initialization time
193     if (introLabel != null) {
194       introLabel.setText(bundle.getString("pref.scoreboard.intro"));
195       button3.setText(generateButtonLabel(3));
196       button4.setText(generateButtonLabel(4));
197       menuBar.refreshMenuItemsLabels();
198       if (dialogStarted == false) {
199         resetFrameKeyShortcuts();
200       }
201     }
202 
203     super.setTitle(bundle.getString("pref.scoreboard.title"));
204 
205     // repainting the player dialog frame
206     if (playerDialogFrame != null) {
207       playerDialogFrame.repaint();
208     }
209   }
210 
211   /** Displays the about information pane. */
212   public void showAboutInfo() {
213     super.openAnimatedInnerPanel(new AboutJOptionPane());
214   }
215 
216   /** *********** PRIVATE METHODS *************** */
217 
218   /**
219    * Creates a player number button.
220    * <p/>
221    * Note, that the button label underlined letter is
222    * hardcoded and needs to be changed if the action shortcuts
223    * (added to the menu items accelerators) are changed.
224    *
225    * @param playersNumber The number of players in the game.
226    * @return Created button.
227    */
228   private JButton createPlayerNumberButton(int playersNumber) {
229     StartAskingQuestionsListener eventListener =
230         new StartAskingQuestionsListener(playersNumber);
231     JButton button = new AAJButton(generateButtonLabel(playersNumber));
232     button.addActionListener(eventListener);
233     button.addKeyListener(eventListener);
234     button.setBorderPainted(true);
235     // developer note: key shortcuts are not added here,
236     // menu item accelerators are used instead
237     return button;
238   }
239 
240   /**
241    * Generates a player number button label.
242    * Note, that the label underlined letter is hardcoded
243    * and needs to be changed if the action shortcuts
244    * (added to the menu items accelerators) are changed.
245    *
246    * @param playerNumber Number of players on the button.
247    * @return String that represents the players number button label.
248    */
249   private String generateButtonLabel(int playerNumber) {
250     ResourceBundle bundle = ResourceBundle.getBundle("default");
251     String str = bundle.getString("pref.scoreboard.button" + playerNumber);
252     return Utilities.underlineLetter(str, str.lastIndexOf(")") - 1);
253   }
254 
255   /**
256    * Adds/resets key shortcuts on the topPanel if not on Mac OS;
257    * this method assumes that action mappings for the buttons
258    * actions have already been created; Note that on Mac,
259    * shortcuts should be added to the menu items
260    * (since almost everything will be on the menu bar).
261    */
262   private void resetFrameKeyShortcuts() {
263     if (Utilities.isMacOs()) {
264       return;
265     }
266     InputMap map = topPanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
267     map.clear();
268     ResourceBundle bundle = ResourceBundle.getBundle("default");
269     // adding the button shortcuts (so it works for all layouts)
270     String key = bundle.getString("pref.scoreboard.button3.shortcut");
271     map.put(KeyStroke.getKeyStroke("control " + key.charAt(0)), "button3Action");
272     key = bundle.getString("pref.scoreboard.button4.shortcut");
273     map.put(KeyStroke.getKeyStroke("control " + key.charAt(0)), "button4Action");
274   }
275 
276 }