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

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

mercurial