4
* Copyright (C) Federico Vera 2010-2011 <dktcoding [at] gmail>
6
* PictoGame is free software: you can redistribute it and/or modify it
7
* under the terms of the GNU General Public License as published by the
8
* Free Software Foundation, either version 3 of the License, or any later
11
* PictoGame is distributed in the hope that it will be useful, but
12
* WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
* See the GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License along
17
* with this program. If not, see <http://www.gnu.org/licenses/>.
20
package picto.app.gui;
23
import java.awt.event.ActionEvent;
24
import java.awt.event.ActionListener;
25
import java.awt.event.KeyEvent;
26
import java.awt.event.KeyListener;
27
import java.awt.event.MouseAdapter;
28
import java.awt.event.MouseEvent;
29
import java.awt.event.MouseWheelEvent;
30
import java.awt.event.MouseWheelListener;
31
import java.io.BufferedReader;
32
import java.io.FileReader;
33
import java.io.IOException;
34
import java.io.InputStreamReader;
35
import java.util.ArrayList;
36
import java.util.Arrays;
37
import java.util.Random;
38
import java.util.logging.Level;
39
import java.util.logging.Logger;
40
import javax.swing.AbstractListModel;
41
import javax.swing.BorderFactory;
42
import javax.swing.DefaultComboBoxModel;
43
import javax.swing.GroupLayout;
44
import javax.swing.GroupLayout.Alignment;
45
import javax.swing.JButton;
46
import javax.swing.JComboBox;
47
import javax.swing.JDialog;
48
import javax.swing.JFileChooser;
49
import javax.swing.JLabel;
50
import javax.swing.JList;
51
import javax.swing.JOptionPane;
52
import javax.swing.JPanel;
53
import javax.swing.JScrollPane;
54
import javax.swing.JSpinner;
55
import javax.swing.JTextField;
56
import javax.swing.JTextPane;
57
import javax.swing.LayoutStyle.ComponentPlacement;
58
import javax.swing.ListSelectionModel;
59
import javax.swing.SpinnerNumberModel;
60
import javax.swing.SwingConstants;
61
import javax.swing.event.ChangeEvent;
62
import javax.swing.event.ChangeListener;
63
import javax.swing.event.ListSelectionEvent;
64
import javax.swing.event.ListSelectionListener;
65
import javax.swing.filechooser.FileNameExtensionFilter;
66
import picto.utils.Picto;
67
import picto.app.interfaces.Localizable;
68
import picto.utils.Text;
70
import static picto.utils.Text._;
74
* @author Fido <dktcoding [at] gmail>
76
public class GameLoader extends JDialog implements Localizable, KeyListener{
77
private static final long serialVersionUID = -63765627876372891L;
78
private MainWindow father;
79
private int NUMBER_OF_PATTERNS;
82
* Creates new form GameLoader
85
public GameLoader(MainWindow father) {
89
descriptionTextPane.setEditable(false);
90
descriptionTextPane.setContentType("text/html");
91
setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
96
updateList(generateDisplayedGameList());
97
rowSpinner.setModel(new SpinnerNumberModel(10, 5, 64, 1));
98
columnSpinner.setModel(new SpinnerNumberModel(10, 5, 64, 1));
99
// Yes... I know this is stupid... but windows 7 needs it...
100
setSize(getSize().width+1, getSize().height);
103
public void getRandomGame(){
104
father.setGame(games[new Random().nextInt(games.length)]);
107
@Override public final void updateTexts() {
108
setTitle(_("Load game"));
109
authorsComboBox.setModel(new DefaultComboBoxModel(getAuthorNameList()));
110
conditionComboBox.setModel(new DefaultComboBoxModel(new String[]
111
{_("Any size"), _("Bigger than"), _("Smaller than"), _("Equal to")}));
112
authorsComboBox.setToolTipText(_("Author"));
113
conditionComboBox.setToolTipText(_("Size condition"));
114
filterPanel.setBorder(BorderFactory.createTitledBorder(_("Filter")));
115
rowsLabel.setText(_("Rows"));
116
columnsLabel.setText(_("Columns"));
117
openFromFileButton.setText(_("Open from file"));
118
openSelectedButton.setText(_("Open"));
119
rowSpinner.setEnabled(conditionComboBox.getSelectedIndex() != 0);
120
columnSpinner.setEnabled(conditionComboBox.getSelectedIndex() != 0);
124
@Override public final void addWeakReference() {
125
Text.addWeakReference(this);
129
* Sets the game description in the description panel
131
private void setDescription(){
132
int idx = gameList.getSelectedIndex();
134
descriptionTextPane.setText(_("No element selected"));
137
StringBuilder tmpStr = new StringBuilder(200);
138
tmpStr.append("<html><b>")
141
.append(displayedGames[idx].getTitle())
143
.append(_("Author:"))
145
.append(_(displayedGames[idx].getAuthor()))
149
.append(displayedGames[idx].getDate())
153
.append(displayedGames[idx].getNumberOfRows())
155
.append(displayedGames[idx].getNumberOfColumns())
157
descriptionTextPane.setText(tmpStr.toString());
159
private static final String b = "<b>";
160
private static final String br = "<br><b>";
161
private static final String _b = " </b>";
164
/** Internal path to the patterns*/
165
private static final String path = "/res/patterns/";
166
/** This array contains the games that are currently shown in the list*/
167
private static Picto[] displayedGames;
168
/** This array contains all the games*/
169
private static Picto[] games;
172
* This method loads all the games in the array
174
private void loadList(){
175
BufferedReader reader = new BufferedReader(new InputStreamReader(
176
GameLoader.class.getResourceAsStream(path + "patterns.list")));
177
ArrayList<String> list = new ArrayList<String>(200);
178
//Load the 'patterns.list' file
180
String line = reader.readLine();
181
while (line != null){
183
if(!line.startsWith("#") && !line.isEmpty()){
185
line = reader.readLine();
186
NUMBER_OF_PATTERNS++;
190
} catch (IOException ex) {
191
Logger.getLogger(GameLoader.class.getName()).log(Level.SEVERE, null, ex);
193
// Load the games that appear in 'patterns.list'
194
games = new Picto[list.size()];
196
for (String element : list){
197
games[i++] = new Picto(GameLoader.class.getResourceAsStream
198
(path + element + ".pattern"), true);
203
* Generates a string array containing the names of all the authors
205
* @return String array with authors names
207
private String[] getAuthorNameList(){
208
ArrayList<String> authorListName = new ArrayList<String>(10);
209
authorListName.add(_("All..."));
210
for (Picto game : games){
211
String name = game.getAuthor();
215
name = "<html>" + name + "</html>";//Sorry for this...
216
if (!authorListName.contains(name)){
217
authorListName.add(name);
220
return authorListName.toArray(new String[0]);
224
* Add the action listeners to all the elements
226
private void addActionListeners(){
227
openFromFileButton.addActionListener(new ActionListener() {
228
@Override public void actionPerformed(ActionEvent e) {
229
JFileChooser fc = new JFileChooser();
230
fc.setDialogTitle(_("Open pattern"));
231
fc.setDialogType(JFileChooser.OPEN_DIALOG);
232
fc.setMultiSelectionEnabled(false);
233
fc.setFileHidingEnabled(true);
234
fc.setFileFilter(new FileNameExtensionFilter(
235
_("PictoGame Pattern file"), "pattern", "sgriddler"));
236
if (fc.showOpenDialog(father) == JFileChooser.APPROVE_OPTION){
238
if (fc.getSelectedFile().getCanonicalFile().toString().endsWith("pattern")){
239
Picto temp = new Picto(new BufferedReader(
240
new FileReader(fc.getSelectedFile())));
241
father.setGame(temp);
243
} else if (fc.getSelectedFile().getCanonicalFile().toString().endsWith("sgriddler")){
244
father.setGame(Picto.loadBoardFromSGriddlerFile(fc.getSelectedFile()));
247
} catch (Exception ex){
248
JOptionPane.showMessageDialog(null, _("Error opening file!"),
249
_("Oops..."), JOptionPane.ERROR_MESSAGE);
254
authorsComboBox.addItemListener(new java.awt.event.ItemListener() {
255
@Override public void itemStateChanged(java.awt.event.ItemEvent evt) {
259
conditionComboBox.addItemListener(new java.awt.event.ItemListener() {
260
@Override public void itemStateChanged(java.awt.event.ItemEvent evt) {
261
rowSpinner.setEnabled(conditionComboBox.getSelectedIndex() != 0);
262
columnSpinner.setEnabled(conditionComboBox.getSelectedIndex() != 0);
266
openSelectedButton.addActionListener(new ActionListener() {
267
@Override public void actionPerformed(ActionEvent e) {
268
father.setGame(displayedGames[gameList.getSelectedIndex()]);
272
gameList.addListSelectionListener(new ListSelectionListener() {
273
@Override public void valueChanged(ListSelectionEvent evt) {
277
gameList.addMouseListener(new MouseAdapter() {
278
@Override public void mouseClicked(MouseEvent e) {
279
if (e.getClickCount() == 2){
280
openSelectedButton.doClick();
284
rowSpinner.addMouseWheelListener(new MouseWheelListener() {
285
@Override public void mouseWheelMoved(MouseWheelEvent e) {
286
if (e.getWheelRotation() < 0){
287
if (rowSpinner.getNextValue() != null) {
288
rowSpinner.setValue(rowSpinner.getNextValue());
291
if (rowSpinner.getPreviousValue() != null) {
292
rowSpinner.setValue(rowSpinner.getPreviousValue());
297
columnSpinner.addMouseWheelListener(new MouseWheelListener() {
298
@Override public void mouseWheelMoved(MouseWheelEvent e) {
299
if (e.getWheelRotation() < 0){
300
if (columnSpinner.getNextValue() != null) {
301
columnSpinner.setValue(columnSpinner.getNextValue());
304
if (columnSpinner.getPreviousValue() != null) {
305
columnSpinner.setValue(columnSpinner.getPreviousValue());
310
rowSpinner.addChangeListener(new ChangeListener() {
311
@Override public void stateChanged(ChangeEvent evt) {
315
columnSpinner.addChangeListener(new ChangeListener() {
316
@Override public void stateChanged(ChangeEvent evt) {
323
* Generates the game list by author
325
* @return Game list by selected author
327
private ArrayList<Picto> generateDisplayedGameList(){
328
String name = (String)authorsComboBox.getSelectedItem();
329
ArrayList<Picto> list = new ArrayList<Picto>(NUMBER_OF_PATTERNS);
330
for (Picto game : games){
331
String foo = "<html>"+game.getAuthor()+"</html>";//Sorry...
332
if (foo.equals("<html></html>")){
335
if (authorsComboBox.getSelectedIndex() == 0){
337
} else if (foo.startsWith(name)){
345
* Filters the list generated by generateDisplayedGameList()
347
private void filterBySize(){
348
int rows = (Integer)rowSpinner.getValue();
349
int columns = (Integer)columnSpinner.getValue();
350
ArrayList<Picto> list = generateDisplayedGameList();
351
ArrayList<Picto> lis = new ArrayList<Picto>(NUMBER_OF_PATTERNS);
352
switch (conditionComboBox.getSelectedIndex()){
356
case 1: // Bigger than
357
for (Picto game : list){
358
if (game.getNumberOfColumns() > columns
359
&& game.getNumberOfRows () > rows){
364
case 2: // Smaller than
365
for (Picto game : list){
366
if (game.getNumberOfColumns() < columns
367
&& game.getNumberOfRows () < rows){
373
for (Picto game : list){
374
if (game.getNumberOfColumns() == columns
375
&& game.getNumberOfRows () == rows){
381
assert false : "Filter list found unknown operator";
384
updateList(filterByContent(lis, filterTextField.getText().toLowerCase()));
388
* Generates the list of names, and adds the elements to the panel
390
* @param list filtered list by author and size
392
@SuppressWarnings("unchecked")
393
private void updateList(ArrayList<Picto> list){
394
int displayedGamesLength = list.size();
395
int length = String.valueOf(displayedGamesLength).length();
396
displayedGames = list.toArray(new Picto[0]);
397
openSelectedButton.setEnabled(!list.isEmpty());
398
final String[] elements = new String[displayedGamesLength];
399
for (int i = 0; i < displayedGamesLength; i++){
400
builder.append(zeros(i, length))
402
.append('.').append(' ')
403
.append(displayedGames[i].getTitle());
404
elements[i] = builder.toString();
405
builder.delete(0, builder.length());
407
gameList.setModel(new AbstractListModel() {
408
private static final long serialVersionUID = 19415617846756343L;
409
String[] strings = elements;
410
@Override public int getSize() {return strings.length;}
411
@Override public Object getElementAt(int i) {return strings[i];}
413
gameList.setSelectedIndex(0);
416
private StringBuilder builder = new StringBuilder(60);
417
private char[][] zeros = new char[][]{
423
{'0','0','0','0','0'},
425
private char[] zeros(int i, int lenght){
426
int n_zeros = lenght - String.valueOf(i).length();
427
if (n_zeros < zeros.length){
428
return zeros[n_zeros];
430
char[] temp = new char[n_zeros];
431
Arrays.fill(temp, '0');
435
private ArrayList<Picto> filterByContent (ArrayList<Picto> list, String filter){
436
if (filter.isEmpty()){
439
ArrayList<Picto> temp = new ArrayList<Picto>(list.size());
440
for (Picto pic : list){
441
if (pic.getTitle().toLowerCase().indexOf(filter) != -1){
448
@SuppressWarnings("unchecked")
449
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
450
private void initComponents() {
452
jScrollPane1 = new JScrollPane();
453
gameList = new JList();
454
openSelectedButton = new JButton();
455
openFromFileButton = new JButton();
456
jScrollPane2 = new JScrollPane();
457
descriptionTextPane = new JTextPane();
458
filterPanel = new JPanel();
459
authorsComboBox = new JComboBox();
460
columnSpinner = new JSpinner();
461
rowSpinner = new JSpinner();
462
columnsLabel = new JLabel();
463
rowsLabel = new JLabel();
464
conditionComboBox = new JComboBox();
465
filterTextField = new JTextField();
467
gameList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
468
jScrollPane1.setViewportView(gameList);
470
openSelectedButton.setText("Open");
472
openFromFileButton.setText("Open from file");
474
descriptionTextPane.setFont(new Font("DejaVu Sans", 0, 14));
475
jScrollPane2.setViewportView(descriptionTextPane);
477
filterPanel.setBorder(BorderFactory.createTitledBorder("Filter"));
479
authorsComboBox.setModel(new DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
481
rowSpinner.setModel(new SpinnerNumberModel(10, 5, 64, 1));
483
columnsLabel.setHorizontalAlignment(SwingConstants.TRAILING);
484
columnsLabel.setText("Columns:");
486
rowsLabel.setHorizontalAlignment(SwingConstants.TRAILING);
487
rowsLabel.setText("Rows:");
489
conditionComboBox.setModel(new DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
491
GroupLayout filterPanelLayout = new GroupLayout(filterPanel);
492
filterPanel.setLayout(filterPanelLayout);
493
filterPanelLayout.setHorizontalGroup(
494
filterPanelLayout.createParallelGroup(Alignment.LEADING)
495
.addGroup(filterPanelLayout.createSequentialGroup()
497
.addGroup(filterPanelLayout.createParallelGroup(Alignment.LEADING)
498
.addGroup(filterPanelLayout.createSequentialGroup()
499
.addGroup(filterPanelLayout.createParallelGroup(Alignment.TRAILING)
500
.addComponent(rowsLabel, GroupLayout.DEFAULT_SIZE, 152, Short.MAX_VALUE)
501
.addComponent(columnsLabel, GroupLayout.DEFAULT_SIZE, 152, Short.MAX_VALUE))
502
.addPreferredGap(ComponentPlacement.RELATED)
503
.addGroup(filterPanelLayout.createParallelGroup(Alignment.LEADING, false)
504
.addComponent(rowSpinner, Alignment.TRAILING)
505
.addComponent(columnSpinner, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 79, Short.MAX_VALUE)))
506
.addComponent(authorsComboBox, Alignment.TRAILING, 0, 243, Short.MAX_VALUE)
507
.addComponent(conditionComboBox, 0, 243, Short.MAX_VALUE))
510
filterPanelLayout.setVerticalGroup(
511
filterPanelLayout.createParallelGroup(Alignment.LEADING)
512
.addGroup(Alignment.TRAILING, filterPanelLayout.createSequentialGroup()
513
.addComponent(authorsComboBox, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
514
.addPreferredGap(ComponentPlacement.RELATED)
515
.addComponent(conditionComboBox, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
516
.addPreferredGap(ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
517
.addGroup(filterPanelLayout.createParallelGroup(Alignment.BASELINE)
518
.addComponent(columnSpinner, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
519
.addComponent(columnsLabel))
520
.addPreferredGap(ComponentPlacement.RELATED)
521
.addGroup(filterPanelLayout.createParallelGroup(Alignment.BASELINE)
522
.addComponent(rowSpinner, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
523
.addComponent(rowsLabel))
527
filterTextField.addKeyListener(this);
529
GroupLayout layout = new GroupLayout(getContentPane());
530
getContentPane().setLayout(layout);
531
layout.setHorizontalGroup(
532
layout.createParallelGroup(Alignment.LEADING)
533
.addGroup(layout.createSequentialGroup()
535
.addGroup(layout.createParallelGroup(Alignment.LEADING, false)
536
.addComponent(filterTextField, Alignment.TRAILING)
537
.addComponent(jScrollPane1, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 245, Short.MAX_VALUE))
538
.addGroup(layout.createParallelGroup(Alignment.LEADING)
539
.addGroup(layout.createSequentialGroup()
540
.addPreferredGap(ComponentPlacement.RELATED)
541
.addGroup(layout.createParallelGroup(Alignment.LEADING)
542
.addComponent(jScrollPane2, GroupLayout.DEFAULT_SIZE, 279, Short.MAX_VALUE)
543
.addComponent(filterPanel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
544
.addGroup(Alignment.TRAILING, layout.createSequentialGroup()
546
.addComponent(openFromFileButton)
547
.addPreferredGap(ComponentPlacement.RELATED)
548
.addComponent(openSelectedButton)))
551
layout.setVerticalGroup(
552
layout.createParallelGroup(Alignment.LEADING)
553
.addGroup(layout.createSequentialGroup()
555
.addGroup(layout.createParallelGroup(Alignment.LEADING)
556
.addComponent(jScrollPane1, GroupLayout.DEFAULT_SIZE, 372, Short.MAX_VALUE)
557
.addGroup(Alignment.TRAILING, layout.createSequentialGroup()
558
.addComponent(jScrollPane2, GroupLayout.DEFAULT_SIZE, 197, Short.MAX_VALUE)
559
.addPreferredGap(ComponentPlacement.RELATED)
560
.addComponent(filterPanel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)))
561
.addPreferredGap(ComponentPlacement.RELATED)
562
.addGroup(layout.createParallelGroup(Alignment.BASELINE)
563
.addComponent(openSelectedButton)
564
.addComponent(openFromFileButton)
565
.addComponent(filterTextField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
572
// Code for dispatching events from components to event handlers.
574
public void keyPressed(java.awt.event.KeyEvent evt) {
577
public void keyReleased(java.awt.event.KeyEvent evt) {
578
if (evt.getSource() == filterTextField) {
579
GameLoader.this.filterTextFieldKeyReleased(evt);
583
public void keyTyped(java.awt.event.KeyEvent evt) {
584
}// </editor-fold>//GEN-END:initComponents
586
private void filterTextFieldKeyReleased(KeyEvent evt) {//GEN-FIRST:event_filterTextFieldKeyReleased
588
}//GEN-LAST:event_filterTextFieldKeyReleased
590
// Variables declaration - do not modify//GEN-BEGIN:variables
591
private JComboBox authorsComboBox;
592
private JSpinner columnSpinner;
593
private JLabel columnsLabel;
594
private JComboBox conditionComboBox;
595
private JTextPane descriptionTextPane;
596
private JPanel filterPanel;
597
private JTextField filterTextField;
598
private JList gameList;
599
private JScrollPane jScrollPane1;
600
private JScrollPane jScrollPane2;
601
private JButton openFromFileButton;
602
private JButton openSelectedButton;
603
private JSpinner rowSpinner;
604
private JLabel rowsLabel;
605
// End of variables declaration//GEN-END:variables