2 * Sudokuki - essential sudoku game
3 * Copyright (C) 2007-2012 Sylvain Vedrenne
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.
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.
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/>.
18 package net.jankenpoi.sudokuki.ui.swing;
20 import java.awt.BorderLayout;
21 import java.awt.Component;
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;
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._;
41 @SuppressWarnings("serial")
42 public class SelectMemosPanel extends JPanel {
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>();
56 private Font BOLD_FONT = new Font("Serif", Font.BOLD, 18);
57 private Font NORMAL_FONT = new Font("Serif", Font.PLAIN, 18);
59 private InnerKeyListener innerKeyListener = new InnerKeyListener();
60 private InnerFocusListener innerFocusListener = new InnerFocusListener();
62 private DualSelectionDialog parent;
64 public SelectMemosPanel(DualSelectionDialog parent, Byte[] previousMemos) {
67 initComponents(previousMemos);
68 parent.getTabbedPane().addKeyListener(innerKeyListener);
69 parent.getTabbedPane().addFocusListener(innerFocusListener);
72 private void configureCheckBox(JCheckBox btn, String text, final int button) {
74 btn.setFont(NORMAL_FONT);
76 btn.setToolTipText(text);
77 btn.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR));
78 btn.addActionListener(new java.awt.event.ActionListener() {
79 public void actionPerformed(java.awt.event.ActionEvent evt) {
80 buttonClicked(button);
83 btn.addKeyListener(innerKeyListener);
84 btn.addFocusListener(innerFocusListener);
87 private void initComponents(Byte[] previousMemos) {
89 if (previousMemos != null) {
90 for (int i = 0; i < previousMemos.length; i++) {
91 memos.add(previousMemos[i]);
92 this.previousMemos.add(previousMemos[i]);
95 for (int i = 0; i < ckb.length; i++) {
96 ckb[i] = new JCheckBox(String.valueOf(i+1));
98 btnConfirm = new JButton();
100 btnClear = new JButton();
101 btnClear.setText(_("Clear memos"));
102 btnClear.setEnabled(true);
103 btnClear.addActionListener(new java.awt.event.ActionListener() {
104 public void actionPerformed(java.awt.event.ActionEvent evt) {
107 private void clearClicked() {
108 for (byte i=1; i<=ckb.length; i++) {
109 memos.remove(Byte.valueOf(i));
110 ckb[i-1].setFont(NORMAL_FONT);
111 ckb[i-1].setSelected(false);
115 btnClear.addKeyListener(innerKeyListener);
116 btnClear.addFocusListener(innerFocusListener);
117 configureCheckBox(ckb[6], "7", 6);
118 configureCheckBox(ckb[7], "8", 7);
119 configureCheckBox(ckb[8], "9", 8);
120 configureCheckBox(ckb[3], "4", 3);
121 configureCheckBox(ckb[4], "5", 4);
122 configureCheckBox(ckb[5], "6", 5);
123 configureCheckBox(ckb[0], "1", 0);
124 configureCheckBox(ckb[1], "2", 1);
125 configureCheckBox(ckb[2], "3", 2);
126 btnConfirm.setText(_("Ok"));
127 btnConfirm.setEnabled(true);
128 btnConfirm.addActionListener(new java.awt.event.ActionListener() {
129 public void actionPerformed(java.awt.event.ActionEvent evt) {
133 private void confirmClicked() {
134 parent.memosPanelConfirmed();
137 btnConfirm.addKeyListener(innerKeyListener);
138 btnConfirm.addFocusListener(innerFocusListener);
140 Iterator<Byte> it = memos.iterator();
141 while (it.hasNext()) {
142 JToggleButton button = ckb[it.next()-1];
143 button.setSelected(true);
144 button.setFont(BOLD_FONT);
148 GridLayout btnLayout = new GridLayout(5, 1);
149 setLayout(btnLayout);
156 panelClear.add(btnClear);
157 panel789.add(ckb[6], BorderLayout.LINE_START);
158 panel789.add(ckb[7], BorderLayout.CENTER);
159 panel789.add(ckb[8], BorderLayout.LINE_END);
160 panel456.add(ckb[3], BorderLayout.LINE_START);
161 panel456.add(ckb[4], BorderLayout.CENTER);
162 panel456.add(ckb[5], BorderLayout.LINE_END);
163 panel123.add(ckb[0], BorderLayout.LINE_START);
164 panel123.add(ckb[1], BorderLayout.CENTER);
165 panel123.add(ckb[2], BorderLayout.LINE_END);
166 panelConfirm.add(btnConfirm);
168 ckb[4].requestFocusInWindow();
172 private boolean isTabSelected() {
173 int idx = parent.getTabbedPane().getSelectedIndex();
177 private void buttonClicked(int button) {
178 byte value = (byte)(button + 1);
179 if (ckb[button].isSelected()) {
181 ckb[button].setFont(BOLD_FONT);
184 ckb[button].setFont(NORMAL_FONT);
188 public byte[] getSelectedMemos() {
189 byte[] memosArray = new byte[memos.size()];
191 Iterator<Byte> it = memos.iterator();
193 while (it.hasNext()) {
194 memosArray[i] = it.next();
200 private class InnerKeyListener extends KeyAdapter {
202 public void keyPressed(KeyEvent ke) {
203 if (isTabSelected() && focusedTabPane()) {
204 int code = ke.getKeyCode();
205 if (code == KeyEvent.VK_H) {
206 int index = parent.getTabbedPane().getSelectedIndex();
207 int newIndex = (index == 0)?1:0;
208 parent.getTabbedPane().setSelectedIndex(newIndex);
209 parent.getTabbedPane().requestFocusInWindow();
212 else if (code == KeyEvent.VK_L) {
216 if (!isTabSelected()) {
219 int code = ke.getKeyCode();
220 if (code == KeyEvent.VK_KP_UP || code == KeyEvent.VK_UP || code == KeyEvent.VK_K) {
221 if (focusedTabPane()) {
224 if (focusedClearButton()) {
225 parent.getTabbedPane().requestFocusInWindow();
228 if (focusedOkButton()) {
229 ckb[focusedElement].requestFocusInWindow();
232 if (focusedElement / 3 == 0) {
233 btnClear.requestFocusInWindow();
236 focusedElement = Math.max(0, focusedElement-3);
237 ckb[focusedElement].requestFocusInWindow();
239 else if (code == KeyEvent.VK_KP_DOWN || code == KeyEvent.VK_DOWN || code == KeyEvent.VK_J) {
240 if (focusedTabPane()) {
241 btnClear.requestFocusInWindow();
244 if (focusedOkButton()) {
247 if (focusedClearButton()) {
249 ckb[focusedElement].requestFocusInWindow();
252 if (focusedElement / 3 == 2) {
253 btnConfirm.requestFocusInWindow();
256 focusedElement = Math.min(8, focusedElement+3);
257 ckb[focusedElement].requestFocusInWindow();
259 else if (code == KeyEvent.VK_KP_LEFT || code == KeyEvent.VK_LEFT || code == KeyEvent.VK_H) {
260 if (focusedElement%3 == 0 || btnConfirm.hasFocus() || btnClear.hasFocus()) {
263 focusedElement = Math.max(0, focusedElement-1);
264 ckb[focusedElement].requestFocusInWindow();
266 else if (code == KeyEvent.VK_KP_RIGHT || code == KeyEvent.VK_RIGHT || code == KeyEvent.VK_L) {
267 if (focusedElement%3 == 2 || focusedOkButton() || focusedClearButton()) {
270 focusedElement = Math.min(8, focusedElement+1);
271 ckb[focusedElement].requestFocusInWindow();
273 else if (code == KeyEvent.VK_ESCAPE) {
274 parent.memosPanelEscaped();
278 private boolean focusedTabPane() {
279 return parent.getTabbedPane().hasFocus();
283 public void keyReleased(KeyEvent ke) {
284 if (!isTabSelected()) {
287 int code = ke.getKeyCode();
288 if (code == KeyEvent.VK_ENTER) {
289 if (focusedClearButton() || focusedOkButton()) {
291 * Buttons actions are managing this so Nothing to do.
295 parent.memosPanelConfirmed();
301 private class InnerFocusListener extends FocusAdapter {
304 public void focusGained(FocusEvent e) {
306 Component comp = e.getComponent();
307 if (comp == ckb[focusedElement]) {
310 for (int i=0; i<ckb.length; i++) {
311 if (comp == ckb[i]) {
319 private boolean focusedOkButton() {
320 return btnConfirm.hasFocus();
323 private boolean focusedClearButton() {
324 return btnClear.hasFocus();
327 public boolean memosChanged() {
328 if (previousMemos.equals(memos)) {