/*
* Copyright 2008-2017 by Emeric Vernat
*
* This file is part of Java Melody.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.bull.javamelody.swing;
import java.awt.Toolkit;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JTextField;
import javax.swing.text.Document;
/**
* Classe abstraite servant de base aux champs de saisie. Cette classe hérite de JTextField.
* @param <T> Type de la valeur saisie
* @author Emeric Vernat
*/
public abstract class MTextField<T> extends JTextField {
static final boolean TEXT_SELECTION_ON_FOCUS_GAINED = true;
private static final long serialVersionUID = 1L;
// ces gestionnaires d'événement sont statiques et non réinstanciés pour économie mémoire
// l'instance du composant est déduite à partir de la source de l'événement
private static final FocusHandler FOCUS_HANDLER = new FocusHandler();
private static final KeyHandler KEY_HANDLER = new KeyHandler();
/**
* FocusListener.
* @author Emeric Vernat
*/
private static class FocusHandler implements FocusListener {
/**
* Constructeur.
*/
FocusHandler() {
super();
}
@Override
public void focusGained(final FocusEvent focusEvent) {
final Object source = focusEvent.getSource();
if (source instanceof MTextField) {
final MTextField<?> field = (MTextField<?>) source;
if (TEXT_SELECTION_ON_FOCUS_GAINED && field.isEditable()) {
field.selectAll();
}
}
}
@Override
public void focusLost(final FocusEvent focusEvent) {
final Object source = focusEvent.getSource();
if (source instanceof MTextField) {
@SuppressWarnings("unchecked")
final MTextField<Object> field = (MTextField<Object>) source;
final Object value = field.getValue();
field.setValue(value);
}
}
}
/**
* KeyListener.
* @author Emeric Vernat
*/
private static class KeyHandler implements KeyListener {
/**
* Constructeur.
*/
KeyHandler() {
super();
}
@Override
public void keyPressed(final KeyEvent keyEvent) {
final Object source = keyEvent.getSource();
if (source instanceof MTextField) {
((MTextField<?>) source).keyEvent(keyEvent);
}
}
@Override
public void keyReleased(final KeyEvent keyEvent) {
final Object source = keyEvent.getSource();
if (source instanceof MTextField) {
((MTextField<?>) source).keyEvent(keyEvent);
}
}
@Override
public void keyTyped(final KeyEvent keyEvent) {
final Object source = keyEvent.getSource();
if (source instanceof MTextField) {
((MTextField<?>) source).keyEvent(keyEvent);
}
}
}
/**
* Constructeur.
*/
protected MTextField() {
this(null);
}
/**
* Constructeur.
* @param document
* Document
*/
protected MTextField(Document document) {
super(document, null, 0);
addFocusListener(FOCUS_HANDLER);
addKeyListener(KEY_HANDLER);
// setDragEnabled(true);
}
/**
* Retourne la valeur saisie.
* @return TypeValue
*/
public abstract T getValue();
/**
* Définit la valeur à afficher.
* @param value TypeValue
*/
public abstract void setValue(T value);
/**
* Cette méthode appelée en cas de saisie invalide émet un beep.
*/
protected void beep() {
Toolkit.getDefaultToolkit().beep();
}
/**
* Gestion des événements claviers. <br/>
* La touche Entrée valide la saisie comme à la perte du focus. <br/>
* Cette méthode est surchargée dans MDateField pour la date du jour
* @param event
* KeyEvent
*/
protected void keyEvent(final KeyEvent event) {
try {
if (event.getID() == KeyEvent.KEY_PRESSED && event.getKeyCode() == KeyEvent.VK_ENTER
&& isEditable()) {
// voir aussi focusEvent
setValue(getValue());
}
} catch (final Exception e) {
beep();
}
}
}