package org.openswing.swing.client; import java.beans.*; import java.math.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; import org.openswing.swing.lookup.client.*; import org.openswing.swing.util.client.ClientSettings; /** * <p>Title: OpenSwing Framework</p> * <p>Description: Input Control used to digit a code. A code can be an alphanumeric or a numeric value. * When focus is lost from this control, a code validation is executed (only if the specified code is changed). * </p> * <p>Copyright: Copyright (C) 2006 Mauro Carniel</p> * * <p> This file is part of OpenSwing Framework. * This library is free software; you can redistribute it and/or * modify it under the terms of the (LGPL) Lesser General Public * License as published by the Free Software Foundation; * * GNU LESSER GENERAL PUBLIC LICENSE * Version 2.1, February 1999 * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * The author may be contacted at: * maurocarniel@tin.it</p> * * @author Mauro Carniel * @version 1.0 */ public class CodBox extends JTextField { /** maximum code length */ private int maxCharacters = 1; /** previous code value; initial value = "" */ private String oldValue = ""; /** code container (code controller) */ private CodBoxContainer container = null; /** define if the cod box allows numeric values only */ private boolean allowOnlyNumbers = false; public CodBox() { if (Beans.isDesignTime()) return; this.addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent e) { if (e.getKeyCode()==e.VK_TAB && ClientSettings.FORCE_FOCUS_ON_LOOKUP_CONTROL) { CodBox.this.transferFocus(); if (CodBox.this.getText().trim().length()>0 && container instanceof CodLookupControl) // cod box is empty: focus is automatically setted to the component next to lookup button SwingUtilities.invokeLater(new Runnable() { public void run() { FocusManager.getCurrentManager().getFocusOwner().transferFocus(); } }); } } public void keyTyped(KeyEvent e) { if (e.getKeyChar()=='\n' && !(ClientSettings.AS_TAB!=null && ClientSettings.AS_TAB.getKeyChar()=='\n')) { if (isEnabled() && isEditable()) // start validation when press ENTER button... startValidation(); } else if (e.getKeyChar()=='\b') return; if (allowOnlyNumbers && (e.getKeyChar()<'0' || e.getKeyChar()>'9')) e.consume(); else if ((getSelectedText()==null || getSelectedText().length()==0) && (getText().length()>=maxCharacters)) e.consume(); else if (getText()!=null && getSelectedText()!=null && getText().length()-getSelectedText().length()>=maxCharacters) e.consume(); } }); this.addFocusListener(new FocusAdapter() { public void focusLost(FocusEvent e) { if (isEnabled() && isEditable()) // start validation on lost focus... startValidation(); } public void focusGained(FocusEvent e) { // oldValue = getText(); } }); StringBuffer s = new StringBuffer(getColumns()); for(int i=0;i<getColumns();i++) s.append("W"); int w = getFontMetrics(getFont()).stringWidth(s.toString())+10; int h = getPreferredSize().height; setMinimumSize(new Dimension(w,h)); setPreferredSize(new Dimension(w,h)); if (ClientSettings.FORCE_FOCUS_ON_LOOKUP_CONTROL) // disable transfer focus management: in this way TAB event will be listened... setFocusTraversalKeysEnabled(false); } /** * This method executes the code validation. */ private void startValidation() { // the code is trimmed... super.setText(getText().trim().toUpperCase()); // code validation is executed ONLY if: // - the specified code value is not equals to the previous code value and // - there exists a code container (code controller) if (container!=null && ( oldValue!=null && !oldValue.equals(getText()) || oldValue==null && getText()!=null )) { oldValue = getText(); try { container.validateCode(getText()); oldValue = getText(); } catch (RestoreFocusOnInvalidCodeException ex) { oldValue = ""; SwingUtilities.invokeLater(new Runnable() { public void run() { if (!CodBox.this.hasFocus()) CodBox.this.requestFocus(); } }); } catch (Exception ex) { ex.printStackTrace(); } } } public void setEnabled(boolean enabled) { setEditable(enabled); if (this.container!=null) this.container.setEnabled(enabled); } public final void setEditable(boolean enabled) { super.setEditable(enabled); try { if (enabled) { setForeground(UIManager.getColor("TextField.foreground")); setBackground(UIManager.getColor("TextField.background")); } else { setForeground(UIManager.getColor("TextField.foreground")); setBackground(UIManager.getColor("TextField.inactiveBackground")); } } catch (Exception ex) { } } /** * @return maximum code length */ public final int getMaxCharacters() { return maxCharacters; } /** * Set maximum code length. * @param maxCharacters maximum code length */ public final void setMaxCharacters(int maxCharacters) { this.maxCharacters = maxCharacters; } /** * Set code container. * @param container code container */ public final void setContainer(CodBoxContainer container) { this.container = container; } /** * @return code value; null when no code is specified */ public final Object getValue() { if (getText().length()==0) return null; else if (allowOnlyNumbers) return new BigDecimal(getText()); else return getText(); } /** * Set code value. * @param value code value */ public final void setValue(Object value) { super.setText(value==null?null:value.toString()); oldValue = value==null?null:value.toString(); } /** * Set code value (like setValue method). * @param text code value */ public final void setText(String text) { setValue(text); } /** * Method called by code container when the code validation is completed. * @param validated validation result */ public final void codeValidated(boolean validated) { if (!validated) { super.setText(""); requestFocus(); } else if (getText().length()>0) { oldValue = getText(); } } /** * Force validation. * This method can be called by the developer to force a code validation, without losting focus. */ public void forceValidate() { try { oldValue = null; startValidation(); } catch (Exception ex) { ex.printStackTrace(); } } /** * @return define if the cod box allows numeric values only */ public final boolean isAllowOnlyNumbers() { return allowOnlyNumbers; } /** * Define if the cod box allows numeric values only. * @param allowOnlyNumbers define if the cod box allows numeric values only */ public final void setAllowOnlyNumbers(boolean allowOnlyNumbers) { this.allowOnlyNumbers = allowOnlyNumbers; } }