Java tutorial
/** * Copyright (c) 2014 Matthias Jaenicke <matthias.jaenicke@student.kit.edu>, * Matthias Plappert <undkc@student.kit.edu>, * Julien Duman <uncyc@student.kit.edu>, * Christian Dreher <uaeef@student.kit.edu>, * Wasilij Beskorovajnov <uajkm@student.kit.edu> and * Aydin Tekin <aydin.tekin@student.kit.edu> * * Released under the MIT license (refer to LICENSE.md) * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package edu.kit.iks.cryptographicslib.common.view.partial; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Font; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import java.io.InputStream; import javax.imageio.ImageIO; import javax.swing.BoxLayout; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JPanel; import javax.swing.JTextField; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.JDOMException; import org.jdom2.input.SAXBuilder; import edu.kit.iks.cryptographicslib.util.Logger; /** * A displayable keyboard for character input per mouse click or touchscreen. * Contains the numbers from 0 to 9, Backspace and Enter. * * @author Matthias Jaenicke * @author Christian Dreher */ public class NumpadView extends JPanel implements ActionListener { /** * Serial Version UID. */ private static final long serialVersionUID = 5986894202162733671L; private Element resources; /** * When digit mode is used, the buttons pressed will replace * the number in the given input field. */ public static final int DIGIT_MODE = 0; /** * When number mode is used, the buttons pressed will append * the number in the given input field. */ public static final int NUMBER_MODE = 1; /** * The input mode set by the constructor. */ private int inputMode; /** * The text field passed through the constructor. */ private JTextField textField; /** * The matrix of all buttons that this view paints. */ private JButton[][] keys; /** * Constructor initializing a new instance of numpad view * by passed text field (the textField which should be manipulated * by this numpad) and the mode. The mode can either be the * NumpadView.DIGIT_MODE, in which the text in the textField will * always be replaced by the button pressed, or NumpadView.NUMBER_MODE, * in which the button pressed will only be appended to the text in the * textField. * * @param textField Text field to be manipulated by this numpad * @param mode The input mode (Either DIGIT_MODE or NUMBER_MODE) */ public NumpadView(JTextField textField, int mode) { super(); this.initResources(); this.textField = textField; this.inputMode = mode; this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); this.initKeyboardButtons(); Dimension keySize = new Dimension(45, 45); Insets keyMargin = new Insets(0, 5, 0, 5); Font keyFont = new Font("Arial", Font.BOLD, 14); for (int i = 0; i < this.keys.length; i++) { JPanel row = new JPanel(new FlowLayout()); for (int j = 0; j < this.keys[i].length; j++) { if (this.keys[i][j] != null) { this.keys[i][j].setMargin(keyMargin); this.keys[i][j].setFont(keyFont); this.keys[i][j].setPreferredSize(keySize); this.keys[i][j].addActionListener(this); row.add(this.keys[i][j]); } } this.add(row); } //this.setSize(firstRow.getWidth(), firstRow.getHeight() * 3); this.setVisible(true); } @Override public void actionPerformed(ActionEvent e) { JButton trigger = (JButton) e.getSource(); String buttonLabel = trigger.getText(); String buttonName = trigger.getName(); if (buttonName.equals("button-enter")) { Logger.debug("NumpadView", "actionPerformed", "Enter pressed"); this.textField.getActionListeners()[0].actionPerformed(e); } else if (buttonName.equals("button-backspace")) { Logger.debug("NumpadView", "actionPerformed", "Backspace pressed"); String currentText = this.textField.getText(); if (currentText.length() > 1) { String trimmedText = currentText.substring(0, currentText.length() - 1); this.textField.setText(trimmedText); } else { this.textField.setText(""); } } else if (buttonName.equals("button-key")) { Logger.debug("NumpadView", "actionPerformed", "Key pressed"); if (this.inputMode == NumpadView.NUMBER_MODE) { String currentText = this.textField.getText(); String newText = currentText + buttonLabel; this.textField.setText(newText); } else if (this.inputMode == NumpadView.DIGIT_MODE) { this.textField.setText(buttonLabel); } } } private void initResources() { SAXBuilder saxBuilder = new SAXBuilder(); // obtain file object InputStream is = this.getClass().getResourceAsStream("/icons/IconResources.xml"); try { // converted file to document object Document document = saxBuilder.build(is); // get root node from xml this.resources = document.getRootElement().getChild("Keyboard"); } catch (JDOMException | IOException e) { Logger.error(e); } } private void initKeyboardButtons() { JButton[][] keysInit = { // First row { kf("7"), kf("8"), kf("9") }, // Second row { kf("4"), kf("5"), kf("6") }, // Third row { kf("1"), kf("2"), kf("3") }, // Fourth row { kf("BS", "bs"), kf("0"), kf("E", "e") } }; this.keys = keysInit; } /** * Creates a new JButton instance with given String as label. * kf stands for "Key factory" and is a factory method to * instantiate new buttons more convenient. * * @param label The label of the button * * @return new Instance of JButton */ private JButton kf(String label) { return kf(label, "key"); } /** * Creates a new JButton instance as special purpose button. * If given name is "bs" (BackSpace), a backspace button * will be created. If given name is "e" (Enter), an enter * button will be created. All other will result in a normal * button representing a character. * * @param label The label of the button * @param name (bs|e|?), according to the button which should be created * * @return new Instance of JButton */ private JButton kf(String label, String name) { JButton button; if (name.equals("bs")) { ImageIcon backspace = this.loadIcon(this.resources.getChild("Backspace").getAttributeValue("path")); button = new JButton(backspace); button.setName("button-backspace"); } else if (name.equals("e")) { ImageIcon enter = this.loadIcon(this.resources.getChild("Enter").getAttributeValue("path")); button = new JButton(enter); button.setName("button-enter"); } else { button = new JButton(label); button.setName("button-key"); } return button; } /** * Loads an image icon from given path. * * @param path path to image * @return ImageIcon instance */ private ImageIcon loadIcon(String path) { ImageIcon image = null; try { InputStream is = this.getClass().getResourceAsStream(path); image = new ImageIcon(ImageIO.read(is)); } catch (IOException e) { Logger.error(e); } return image; } }