src/main/java/de/uapcore/sudoku/SudokuTextField.java

Mon, 27 Jul 2020 11:56:41 +0200

author
Mike Becker <universe@uap-core.de>
date
Mon, 27 Jul 2020 11:56:41 +0200
changeset 13
5e69b1bb707f
parent 12
1c62c6009161
permissions
-rw-r--r--

adds SudokuTextFieldTest

universe@3 1 /*
universe@3 2 * Copyright 2013 Mike Becker. All rights reserved.
universe@3 3 *
universe@3 4 * Redistribution and use in source and binary forms, with or without
universe@3 5 * modification, are permitted provided that the following conditions are met:
universe@3 6 *
universe@3 7 * 1. Redistributions of source code must retain the above copyright
universe@3 8 * notice, this list of conditions and the following disclaimer.
universe@3 9 *
universe@3 10 * 2. Redistributions in binary form must reproduce the above copyright
universe@3 11 * notice, this list of conditions and the following disclaimer in the
universe@3 12 * documentation and/or other materials provided with the distribution.
universe@3 13 *
universe@3 14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
universe@3 15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
universe@3 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
universe@3 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
universe@3 18 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
universe@3 19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
universe@3 20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
universe@3 21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
universe@3 22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
universe@3 23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
universe@3 24 * POSSIBILITY OF SUCH DAMAGE.
universe@3 25 */
universe@3 26
universe@1 27 package de.uapcore.sudoku;
universe@1 28
universe@9 29 import javax.swing.*;
universe@9 30 import java.awt.*;
universe@1 31 import java.awt.event.FocusAdapter;
universe@1 32 import java.awt.event.FocusEvent;
universe@1 33 import java.awt.event.KeyAdapter;
universe@1 34 import java.awt.event.KeyEvent;
universe@1 35
universe@1 36 /**
universe@10 37 * A custom text field specifically for Sudoku number fields.
universe@1 38 */
universe@2 39 public final class SudokuTextField extends JTextField {
universe@2 40
universe@2 41 private boolean modified;
universe@1 42
universe@1 43 public SudokuTextField() {
universe@1 44 setBorder(null);
universe@1 45 setBackground(Color.WHITE);
universe@1 46
universe@1 47 setFont(new Font("Dialog", Font.PLAIN, 18));
universe@1 48 setHorizontalAlignment(JTextField.CENTER);
universe@1 49
universe@1 50 Dimension dim = new Dimension(40,40);
universe@1 51 setPreferredSize(dim);
universe@1 52 setMinimumSize(dim);
universe@1 53 setMaximumSize(dim);
universe@1 54
universe@1 55 addKeyListener(new KeyAdapter() {
universe@1 56 private void handle(KeyEvent e) {
universe@3 57 char c = e.getKeyChar();
universe@3 58 if (!e.isAltDown() && !e.isControlDown() &&
universe@6 59 !Character.isISOControl(c)) {
universe@3 60 // Perform clean input check
universe@3 61 if (getText().length() > 0 && getSelectedText() == null) {
universe@6 62 if (c != KeyEvent.CHAR_UNDEFINED) {
universe@6 63 e.consume();
universe@6 64 }
universe@3 65 } else {
universe@3 66 if (c < '1' || c > '9') {
universe@3 67 e.consume();
universe@3 68 } else {
universe@3 69 setModified(true);
universe@3 70 }
universe@1 71 }
universe@1 72 } else {
universe@3 73 // We can still be tricked by hotkeys, so do it the hard way
universe@3 74 if (!getText().matches("^[1-9]$")) {
universe@3 75 setText("");
universe@1 76 }
universe@1 77 }
universe@1 78 }
universe@1 79
universe@1 80 @Override
universe@1 81 public void keyPressed(KeyEvent e) {
universe@1 82 handle(e);
universe@1 83 }
universe@1 84
universe@1 85 @Override
universe@1 86 public void keyTyped(KeyEvent e) {
universe@1 87 handle(e);
universe@1 88 }
universe@1 89
universe@1 90 @Override
universe@1 91 public void keyReleased(KeyEvent e) {
universe@1 92 handle(e);
universe@1 93 }
universe@1 94
universe@1 95 });
universe@1 96 addFocusListener(new FocusAdapter() {
universe@1 97 @Override
universe@1 98 public void focusGained(FocusEvent e) {
universe@1 99 selectAll();
universe@1 100 }
universe@4 101 @Override
universe@4 102 public void focusLost(FocusEvent e) {
universe@4 103 select(0, 0);
universe@4 104 }
universe@1 105 });
universe@1 106 }
universe@10 107
universe@10 108 /**
universe@10 109 * Returns the current value in the field or zero if the field is empty.
universe@10 110 *
universe@10 111 * @return the number from 1 to 9 or zero if empty
universe@10 112 */
universe@2 113 public int getValue() {
universe@10 114 if (getText().isEmpty()) {
universe@10 115 return 0;
universe@10 116 } else {
universe@12 117 return Integer.parseInt(getText());
universe@2 118 }
universe@2 119 }
universe@10 120
universe@10 121 /**
universe@10 122 * Sets the field's value.
universe@10 123 *
universe@10 124 * @param v the number from 1 to 9 or zero to clear the field
universe@12 125 * @throws IllegalArgumentException if v is not between 0 and 9
universe@10 126 */
universe@2 127 public void setValue(int v) {
universe@2 128 if (v == 0) {
universe@2 129 setText("");
universe@13 130 } else if (v > 0 && v < 10) {
universe@2 131 setText(String.valueOf(v));
universe@2 132 } else {
universe@2 133 throw new IllegalArgumentException(
universe@2 134 "Sudoku numbers must be in range 0-9 (0 means 'not set')");
universe@2 135 }
universe@2 136 }
universe@10 137
universe@10 138 /**
universe@10 139 * Sets the modified state of this field.
universe@10 140 *
universe@10 141 * Modified fields are displayed in blue color.
universe@10 142 *
universe@10 143 * @param modified a flag indicating whether this field is modified
universe@10 144 */
universe@2 145 public void setModified(boolean modified) {
universe@2 146 this.modified = modified;
universe@2 147 setForeground(modified?Color.BLUE:Color.BLACK);
universe@2 148 }
universe@10 149
universe@10 150 /**
universe@10 151 * Checks whether this field is in modified state.
universe@10 152 *
universe@10 153 * @return true if this field is modified
universe@10 154 */
universe@2 155 public boolean isModified() {
universe@2 156 return modified;
universe@2 157 }
universe@1 158 }

mercurial