OSDN Git Service

Support Polish language thanks to Monika Viste
[sudokuki/sudokuki.git] / src / classes / net / jankenpoi / sudokuki / ui / swing / SelectMemosPanel.java
1 /*
2  * Sudokuki - essential sudoku game
3  * Copyright (C) 2007-2016 Sylvain Vedrenne
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  * 
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  * 
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 package net.jankenpoi.sudokuki.ui.swing;
19
20 import java.awt.BorderLayout;
21 import java.awt.Component;
22 import java.awt.Font;
23 import java.awt.GridLayout;
24 import java.awt.event.FocusAdapter;
25 import java.awt.event.FocusEvent;
26 import java.awt.event.KeyAdapter;
27 import java.awt.event.KeyEvent;
28 import java.util.HashSet;
29 import java.util.Iterator;
30
31 import javax.swing.JButton;
32 import javax.swing.JCheckBox;
33 import javax.swing.JPanel;
34 import javax.swing.JToggleButton;
35 import static net.jankenpoi.i18n.I18n.gtxt;
36
37 /**
38  * 
39  * @author svedrenne
40  */
41 @SuppressWarnings("serial")
42 public class SelectMemosPanel extends JPanel {
43
44         private JButton btnClear;
45         private JCheckBox[] ckb = new JCheckBox[9];
46         private int focusedElement = 4;
47         private JButton btnConfirm;
48         private JPanel panelClear = new JPanel(new GridLayout());
49         private JPanel panel789 = new JPanel(new GridLayout());
50         private JPanel panel456 = new JPanel(new GridLayout());
51         private JPanel panel123 = new JPanel(new GridLayout());
52         private JPanel panelConfirm = new JPanel(new GridLayout());
53         private HashSet<Byte> memos = new HashSet<Byte>();
54         private HashSet<Byte> previousMemos = new HashSet<Byte>();
55
56         private Font NORMAL_FONT = new Font("Serif", Font.PLAIN, 18);
57
58         private InnerKeyListener innerKeyListener = new InnerKeyListener();
59         private InnerFocusListener innerFocusListener = new InnerFocusListener();
60         
61         private DualSelectionDialog parent;
62         
63         public SelectMemosPanel(DualSelectionDialog parent, Byte[] previousMemos) {
64                 super(true);
65                 this.parent = parent;
66                 initComponents(previousMemos);
67                 parent.getTabbedPane().addKeyListener(innerKeyListener);
68                 parent.getTabbedPane().addFocusListener(innerFocusListener);
69         }
70
71         private void configureCheckBox(JCheckBox btn, String text, final int button) {
72
73                 btn.setFont(NORMAL_FONT);
74
75                 btn.setToolTipText(text);
76                 btn.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR));
77                 btn.addActionListener(new java.awt.event.ActionListener() {
78                         public void actionPerformed(java.awt.event.ActionEvent evt) {
79                                 buttonClicked(button);
80                         }
81                 });
82                 btn.addKeyListener(innerKeyListener);
83                 btn.addFocusListener(innerFocusListener);
84         }
85
86         private void initComponents(Byte[] previousMemos) {
87
88                 if (previousMemos != null) {
89                         for (int i = 0; i < previousMemos.length; i++) {
90                                 memos.add(previousMemos[i]);
91                                 this.previousMemos.add(previousMemos[i]);
92                         }
93                 }
94                 for (int i = 0; i < ckb.length; i++) {
95                         ckb[i] = new JCheckBox(String.valueOf(i+1));
96                 }
97                 btnConfirm = new JButton();
98
99                 btnClear = new JButton();
100                 btnClear.setText(gtxt("Clear memos"));
101                 btnClear.setEnabled(true);
102                 btnClear.addActionListener(new java.awt.event.ActionListener() {
103                         public void actionPerformed(java.awt.event.ActionEvent evt) {
104                                 clearClicked();
105                         }
106                         private void clearClicked() {
107                                 for (byte i=1; i<=ckb.length; i++) {
108                                         memos.remove(Byte.valueOf(i));
109                                         ckb[i-1].setSelected(false);
110                                 }
111                         }
112                 });
113                 btnClear.addKeyListener(innerKeyListener);
114                 btnClear.addFocusListener(innerFocusListener);
115                 configureCheckBox(ckb[6], "7", 6);
116                 configureCheckBox(ckb[7], "8", 7);
117                 configureCheckBox(ckb[8], "9", 8);
118                 configureCheckBox(ckb[3], "4", 3);
119                 configureCheckBox(ckb[4], "5", 4);
120                 configureCheckBox(ckb[5], "6", 5);
121                 configureCheckBox(ckb[0], "1", 0);
122                 configureCheckBox(ckb[1], "2", 1);
123                 configureCheckBox(ckb[2], "3", 2);
124                 btnConfirm.setText(gtxt("Ok"));
125                 btnConfirm.setEnabled(true);
126                 btnConfirm.addActionListener(new java.awt.event.ActionListener() {
127                         public void actionPerformed(java.awt.event.ActionEvent evt) {
128                                 confirmClicked();
129                         }
130
131                         private void confirmClicked() {
132                                 parent.memosPanelConfirmed();
133                         }
134                 });
135                 btnConfirm.addKeyListener(innerKeyListener);
136                 btnConfirm.addFocusListener(innerFocusListener);
137
138                 Iterator<Byte> it = memos.iterator();
139                 while (it.hasNext()) {
140                         JToggleButton button = ckb[it.next().intValue()-1];
141                         button.setSelected(true);
142                 }
143                 
144
145                 GridLayout btnLayout = new GridLayout(5, 1);
146                 setLayout(btnLayout);
147                 add(panelClear);
148                 add(panel123);
149                 add(panel456);
150                 add(panel789);
151                 add(panelConfirm);
152
153                 panelClear.add(btnClear);
154                 panel789.add(ckb[6], BorderLayout.LINE_START);
155                 panel789.add(ckb[7], BorderLayout.CENTER);
156                 panel789.add(ckb[8], BorderLayout.LINE_END);
157                 panel456.add(ckb[3], BorderLayout.LINE_START);
158                 panel456.add(ckb[4], BorderLayout.CENTER);
159                 panel456.add(ckb[5], BorderLayout.LINE_END);
160                 panel123.add(ckb[0], BorderLayout.LINE_START);
161                 panel123.add(ckb[1], BorderLayout.CENTER);
162                 panel123.add(ckb[2], BorderLayout.LINE_END);
163                 panelConfirm.add(btnConfirm);
164
165                 ckb[4].requestFocusInWindow();
166                 focusedElement = 4;
167         }
168
169         private boolean isTabSelected() {
170                 int idx = parent.getTabbedPane().getSelectedIndex();
171                 return (idx == 1);
172         }
173         
174         private void buttonClicked(int button) {
175                 byte value = (byte)(button + 1);
176                 if (ckb[button].isSelected()) {
177                         memos.add(Byte.valueOf(value));
178                 } else {
179                         memos.remove(Byte.valueOf(value));
180                 }
181         }
182
183         public byte[] getSelectedMemos() {
184                 byte[] memosArray = new byte[memos.size()];
185
186                 Iterator<Byte> it = memos.iterator();
187                 int i = 0;
188                 while (it.hasNext()) {
189                         memosArray[i] = it.next().byteValue();
190                         i++;
191                 }
192                 return memosArray;
193         }
194
195         private class InnerKeyListener extends KeyAdapter {
196                 @Override
197                 public void keyPressed(KeyEvent ke) {
198                         if (isTabSelected() && focusedTabPane()) {
199                                 int code = ke.getKeyCode();
200                                 if (code == KeyEvent.VK_H) {
201                                         int index = parent.getTabbedPane().getSelectedIndex();
202                                         int newIndex = (index == 0)?1:0;
203                                         parent.getTabbedPane().setSelectedIndex(newIndex);
204                                         parent.getTabbedPane().requestFocusInWindow();
205                                         return;
206                                 }
207                                 else if (code == KeyEvent.VK_L) {
208                                         return;
209                                 }
210                         }
211                         if (!isTabSelected()) {
212                                 return;
213                         }
214                         int code = ke.getKeyCode();
215                         if (code == KeyEvent.VK_KP_UP || code == KeyEvent.VK_UP || code == KeyEvent.VK_K) {
216                                 if (focusedTabPane()) {
217                                         return;
218                                 }
219                                 if (focusedClearButton()) {
220                                         parent.getTabbedPane().requestFocusInWindow();
221                                         return;
222                                 }
223                                 if (focusedOkButton()) {
224                                         ckb[focusedElement].requestFocusInWindow();
225                                         return;
226                                 }
227                                 if (focusedElement / 3 == 0) {
228                                         btnClear.requestFocusInWindow();
229                                         return;
230                                 }
231                                 focusedElement = Math.max(0, focusedElement-3);
232                                 ckb[focusedElement].requestFocusInWindow();
233                         }
234                         else if (code == KeyEvent.VK_KP_DOWN || code == KeyEvent.VK_DOWN || code == KeyEvent.VK_J) {
235                                 if (focusedTabPane()) {
236                                         btnClear.requestFocusInWindow();
237                                         return;
238                                 }
239                                 if (focusedOkButton()) {
240                                         return;
241                                 }
242                                 if (focusedClearButton()) {
243                                         focusedElement = 1;
244                                         ckb[focusedElement].requestFocusInWindow();
245                                         return;
246                                 }
247                                 if (focusedElement / 3 == 2) {
248                                         btnConfirm.requestFocusInWindow();
249                                         return;
250                                 }
251                                 focusedElement = Math.min(8, focusedElement+3);
252                                 ckb[focusedElement].requestFocusInWindow();
253                         }
254                         else if (code == KeyEvent.VK_KP_LEFT || code == KeyEvent.VK_LEFT || code == KeyEvent.VK_H) {
255                                 if (focusedElement%3 == 0 || btnConfirm.hasFocus() || btnClear.hasFocus()) {
256                                         return;
257                                 }
258                                 focusedElement = Math.max(0, focusedElement-1);
259                                 ckb[focusedElement].requestFocusInWindow();
260                         }
261                         else if (code == KeyEvent.VK_KP_RIGHT || code == KeyEvent.VK_RIGHT || code == KeyEvent.VK_L) {
262                                 if (focusedElement%3 == 2 || focusedOkButton() || focusedClearButton()) {
263                                         return;
264                                 }
265                                 focusedElement = Math.min(8, focusedElement+1);
266                                 ckb[focusedElement].requestFocusInWindow();
267                         }
268                         else if (code == KeyEvent.VK_ESCAPE) {
269                                 parent.memosPanelEscaped();
270                         }
271                 }
272
273                 private boolean focusedTabPane() {
274                         return parent.getTabbedPane().hasFocus();
275                 }
276
277                 @Override
278                 public void keyReleased(KeyEvent ke) {
279                         if (!isTabSelected()) {
280                                 return;
281                         }
282                         int code = ke.getKeyCode();
283                         if (code == KeyEvent.VK_ENTER) {
284                                 if (focusedClearButton() || focusedOkButton()) {
285                                         /*
286                                          * Buttons actions are managing this so Nothing to do.
287                                          */
288                                         return;
289                                 }
290                                 parent.memosPanelConfirmed();
291                         }
292                 }
293
294         }
295         
296         private class InnerFocusListener extends FocusAdapter {
297
298                 @Override
299                 public void focusGained(FocusEvent e) {
300                         
301                         Component comp = e.getComponent();
302                         if (comp == ckb[focusedElement]) {
303                                 return;
304                         }
305                         for (int i=0; i<ckb.length; i++) {
306                                 if (comp == ckb[i]) {
307                                         focusedElement = i;
308                                         return;
309                                 }
310                         }
311                 }
312         }
313         
314         private boolean focusedOkButton() {
315                 return btnConfirm.hasFocus();
316         }
317
318         private boolean focusedClearButton() {
319                 return btnClear.hasFocus();
320         }
321
322         public boolean memosChanged() {
323                 if (previousMemos.equals(memos)) {
324                         return false;
325                 }
326                 return true;
327         }
328 }