package org.openswing.swing.client;
import java.beans.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import org.openswing.swing.domains.java.*;
import org.openswing.swing.util.client.*;
/**
* <p>Title: OpenSwing Framework</p>
* <p>Description: Combo box input control: its items are retrieved from ClientSettings.getDomain method,
* that uses domainId property to identify the correct domain to use.</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 ComboBoxControl extends BaseInputControl implements InputControl,SearchControl {
static {
UIManager.put("ComboBox.disabledForeground", UIManager.get("ComboBox.foreground"));
UIManager.put("ComboBox.disabledBackground", UIManager.get("TextField.inactiveBackground"));
UIManager.put("ComboBox.selectionForeground", Color.black );
UIManager.put("ComboBox.selectionBackground", ClientSettings.BACKGROUND_SEL_COLOR );
}
/** combo box */
private JComboBox combo = new JComboBox();
/** domain related to this input control */
private Domain domain = null;
/** domain identifier */
private String domainId = null;
/** combo box model */
private DefaultComboBoxModel model = new DefaultComboBoxModel();
/** background color when the input control is enabled */
private Color enabledBackColor = combo.getBackground();
/** define if in insert mode combo box has no item selected; default value: <code>false</code> i.e. the first item is pre-selected */
private boolean nullAsDefaultValue = false;
/** define if description in combo items must be translated; default value: <code>true</code> */
private boolean translateItemDescriptions = true;
/**
* Contructor.
*/
public ComboBoxControl() {
this.setLayout(new GridBagLayout());
this.add(combo, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
// setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
// add(combo);
setOpaque(false);
combo.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (e.getKeyCode()==e.VK_CANCEL || e.getKeyCode()==e.VK_BACK_SPACE || e.getKeyCode()==e.VK_DELETE)
combo.setSelectedIndex(-1);
}
});
// intercepts key events listened by combo box...1
combo.setKeySelectionManager(new JComboBox.KeySelectionManager() {
public int selectionForKey(char aKey, ComboBoxModel aModel) {
return -1;
}
});
new SearchWindowManager(this);
if (ClientSettings.TEXT_ORIENTATION!=null)
setComponentOrientation(ClientSettings.TEXT_ORIENTATION);
initListeners();
}
/**
* Set the domain identifier, so the control can retrieve its items from the domain.
* @param domainId domain identifier
*/
public final void setDomainId(String domainId) {
this.domainId = domainId;
if (Beans.isDesignTime())
return;
Domain domain = ClientSettings.getInstance().getDomain(domainId);
setDomain(domain);
}
/**
* Set the specified domain and retrieve the combo items from the domain.
* @param domain domain to use to retrieve the combo items
*/
public final void setDomain(Domain domain) {
this.domain = domain;
model.removeAllElements();
if (domain!=null) {
DomainPair[] pairs = domain.getDomainPairList();
for(int i=0;i<pairs.length;i++)
if (translateItemDescriptions)
model.addElement(ClientSettings.getInstance().getResources().getResource(pairs[i].getDescription()));
else
model.addElement(pairs[i].getDescription());
combo.setModel(model);
combo.revalidate();
combo.setSelectedIndex(-1);
}
}
/**
* @return domain identifier
*/
public final String getDomainId() {
return domainId;
}
/**
* Select the combo item related to the specified code.
* @param code used to retrieve the corresponding item and to select that item in the combo
*/
public final void setValue(Object code) {
if (code==null)
combo.setSelectedIndex(-1);
if (domain==null)
return;
DomainPair pair = domain.getDomainPair(code);
if (pair!=null) {
if (translateItemDescriptions)
combo.setSelectedItem( ClientSettings.getInstance().getResources().getResource(pair.getDescription()) );
else
combo.setSelectedItem( pair.getDescription() );
}
}
/**
* @return code related to the selected combo item; it return null if no item is selected
*/
public final Object getValue() {
if (domain==null)
return null;
DomainPair[] pairs = domain.getDomainPairList();
for(int i=0;i<pairs.length;i++)
if (combo.getSelectedItem()==null)
return null;
else {
if (translateItemDescriptions) {
if (combo.getSelectedItem().equals( ClientSettings.getInstance().getResources().getResource(pairs[i].getDescription()) ))
return pairs[i].getCode();
}
else {
if (combo.getSelectedItem().equals( pairs[i].getDescription()) )
return pairs[i].getCode();
}
}
return null;
}
/**
* @return combo box
*/
public final JComboBox getComboBox() {
return combo;
}
public void setEnabled(boolean enabled) {
combo.setEnabled(enabled);
combo.setFocusable(enabled || ClientSettings.DISABLED_INPUT_CONTROLS_FOCUSABLE);
if (!enabled)
combo.setBackground((Color)UIManager.get("TextField.inactiveBackground"));
else
combo.setBackground(enabledBackColor);
}
/**
* @return current input control abilitation
*/
public final boolean isEnabled() {
try {
return combo.isEnabled();
}
catch (Exception ex) {
return false;
}
}
/**
* @return component inside this whose contains the value
*/
public JComponent getBindingComponent() {
return combo;
}
/**
* Adds the specified focus listener to receive focus events from
* this component when this component gains input focus.
* If listener <code>l</code> is <code>null</code>,
* no exception is thrown and no action is performed.
*
* @param l the focus listener
* @see java.awt.event.FocusEvent
* @see java.awt.event.FocusListener
* @see #removeFocusListener
* @see #getFocusListeners
* @since JDK1.1
*/
public final void addFocusListener(FocusListener l) {
try {
if(combo != null) combo.addFocusListener(l);
}
catch (Exception ex) {
}
}
/**
* Removes the specified focus listener so that it no longer
* receives focus events from this component. This method performs
* no function, nor does it throw an exception, if the listener
* specified by the argument was not previously added to this component.
* If listener <code>l</code> is <code>null</code>,
* no exception is thrown and no action is performed.
*
* @param l the focus listener
* @see java.awt.event.FocusEvent
* @see java.awt.event.FocusListener
* @see #addFocusListener
* @see #getFocusListeners
* @since JDK1.1
*/
public final void removeFocusListener(FocusListener l) {
try {
combo.removeFocusListener(l);
}
catch (Exception ex) {
}
}
/**
* Adds the specified action listener to receive
* action events from this textfield.
*
* @param l the action listener to be added
*/
public final void addActionListener(ActionListener l) {
try {
combo.addActionListener(l);
}
catch (Exception ex) {
}
}
/**
* Removes the specified action listener so that it no longer
* receives action events from this textfield.
*
* @param l the action listener to be removed
*/
public final void removeActionListener(ActionListener l) {
try {
combo.removeActionListener(l);
}
catch (Exception ex) {
}
}
/**
* Adds an <code>ItemListener</code>.
* <p>
* <code>aListener</code> will receive one or two <code>ItemEvent</code>s when
* the selected item changes.
*
* @param aListener the <code>ItemListener</code> that is to be notified
* @see #setSelectedItem
*/
public final void addItemListener(ItemListener alistener) {
try {
combo.addItemListener(alistener);
}
catch (Exception ex) {
}
}
/** Removes an <code>ItemListener</code>.
*
* @param aListener the <code>ItemListener</code> to remove
*/
public final void removeItemListener(ItemListener alistener) {
try {
combo.removeItemListener(alistener);
}
catch (Exception ex) {
}
}
/**
* @return define if in insert mode combo box has no item selected
*/
public final boolean isNullAsDefaultValue() {
return nullAsDefaultValue;
}
/**
* Define if in insert mode combo box has no item selected.
* @param nullAsDefaultValue define if in insert mode combo box has no item selected
*/
public final void setNullAsDefaultValue(boolean nullAsDefaultValue) {
this.nullAsDefaultValue = nullAsDefaultValue;
}
/**
* @return domain to use to retrieve the combo items
*/
public final Domain getDomain() {
return domain;
}
/**
* @return the selected index in the input control
*/
public final int getSelectedIndex() {
return combo.getSelectedIndex();
}
/**
* Set the selected index.
*/
public final void setSelectedIndex(int index) {
combo.setSelectedIndex(index);
}
/**
* @return total rows count in the input control
*/
public final int getRowCount() {
return combo.getItemCount();
}
/**
* @return the element at the specified index, converted in String format
*/
public final String getValueAt(int index) {
return combo.getItemAt(index)==null?"":combo.getItemAt(index).toString();
}
/**
* @return combo control
*/
public final JComponent getComponent() {
return combo;
}
/**
* @return <code>true</code> if the input control is in read only mode (so search is enabled), <code>false</code> otherwise
*/
public final boolean isReadOnly() {
return isEnabled();
}
/**
* @return <code>true</code> to disable key listening on input control (for instance, in case of nested grids), <code>false</code> to listen for key events
*/
public final boolean disableListener() {
return false;
}
/**
* @return define if description in combo items must be translated
*/
public final boolean isTranslateItemDescriptions() {
return translateItemDescriptions;
}
/**
* Define if description in combo items must be translated; default value: <code>true</code>.
* @param translateItemDescriptions flag used to define if description in combo items must be translated
*/
public final void setTranslateItemDescriptions(boolean translateItemDescriptions) {
this.translateItemDescriptions = translateItemDescriptions;
}
/**
* Method invoked by SearchWindowManager when the specified "textToSeach" pattern has not matchings in the current content
* of binded control.
* This callback can be used to retrieve additional data into control and to search inside new data.
* @param textToSeach patten of text to search
* @return -1 if no additional data is available, otherwise the row index of data just added that satify the pattern
*/
public final int search(String textToSeach) {
return -1;
}
/**
* Set the component orientation: from left to right or from right to left.
* @param o component orientation
*/
public final void setTextOrientation(ComponentOrientation o) {
combo.setComponentOrientation(o);
}
/**
* @return component orientation
*/
public final ComponentOrientation getTextOrientation() {
try {
return combo.getComponentOrientation();
}
catch (Exception ex) {
return null;
}
}
}