--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/de/uapcore/sudoku/SudokuTextField.java Sat Jul 25 14:01:28 2020 +0200 @@ -0,0 +1,136 @@ +/* + * Copyright 2013 Mike Becker. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +package de.uapcore.sudoku; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; + +/** + * + * @author mike + */ +public final class SudokuTextField extends JTextField { + + private boolean modified; + + public SudokuTextField() { + setBorder(null); + setBackground(Color.WHITE); + + setFont(new Font("Dialog", Font.PLAIN, 18)); + setHorizontalAlignment(JTextField.CENTER); + + Dimension dim = new Dimension(40,40); + setPreferredSize(dim); + setMinimumSize(dim); + setMaximumSize(dim); + + addKeyListener(new KeyAdapter() { + private void handle(KeyEvent e) { + char c = e.getKeyChar(); + if (!e.isAltDown() && !e.isControlDown() && + !Character.isISOControl(c)) { + // Perform clean input check + if (getText().length() > 0 && getSelectedText() == null) { + if (c != KeyEvent.CHAR_UNDEFINED) { + e.consume(); + } + } else { + if (c < '1' || c > '9') { + e.consume(); + } else { + setModified(true); + } + } + } else { + // We can still be tricked by hotkeys, so do it the hard way + if (!getText().matches("^[1-9]$")) { + setText(""); + } + } + } + + @Override + public void keyPressed(KeyEvent e) { + handle(e); + } + + @Override + public void keyTyped(KeyEvent e) { + handle(e); + } + + @Override + public void keyReleased(KeyEvent e) { + handle(e); + } + + }); + addFocusListener(new FocusAdapter() { + @Override + public void focusGained(FocusEvent e) { + selectAll(); + } + @Override + public void focusLost(FocusEvent e) { + select(0, 0); + } + }); + } + + public int getValue() { + if (getText().length() > 0) { + return Integer.valueOf(getText()); + } else { + return 0; + } + } + + public void setValue(int v) { + if (v == 0) { + setText(""); + } else if (v < 10) { + setText(String.valueOf(v)); + } else { + throw new IllegalArgumentException( + "Sudoku numbers must be in range 0-9 (0 means 'not set')"); + } + } + + public void setModified(boolean modified) { + this.modified = modified; + setForeground(modified?Color.BLUE:Color.BLACK); + } + + public boolean isModified() { + return modified; + } +}