/*
* (c) Copyright 2010-2011 AgileBirds
*
* This file is part of OpenFlexo.
*
* OpenFlexo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenFlexo 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenFlexo. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.openflexo.fib.view.widget;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.BorderFactory;
import javax.swing.ComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JPanel;
import org.openflexo.fib.controller.FIBController;
import org.openflexo.fib.model.FIBDropDown;
import org.openflexo.fib.model.FIBModelObject;
import org.openflexo.localization.FlexoLocalization;
import org.openflexo.toolbox.ToolBox;
public class FIBDropDownWidget extends FIBMultipleValueWidget<FIBDropDown, JComboBox, Object> {
static final Logger logger = Logger.getLogger(FIBDropDownWidget.class.getPackage().getName());
private final JButton resetButton;
private final JPanel dropdownPanel;
protected JComboBox jComboBox;
public FIBDropDownWidget(FIBDropDown model, FIBController controller) {
super(model, controller);
initJComboBox();
dropdownPanel = new JPanel(new BorderLayout());
resetButton = new JButton();
resetButton.setText(FlexoLocalization.localizedForKey(FIBModelObject.LOCALIZATION, "reset", resetButton));
resetButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
jComboBox.getModel().setSelectedItem(null);
setValue(null);
}
});
if (!ToolBox.isMacOSLaf()) {
dropdownPanel.setBorder(BorderFactory.createEmptyBorder(TOP_COMPENSATING_BORDER, LEFT_COMPENSATING_BORDER,
BOTTOM_COMPENSATING_BORDER, RIGHT_COMPENSATING_BORDER));
}
dropdownPanel.add(jComboBox, BorderLayout.CENTER);
if (model.showReset) {
dropdownPanel.add(resetButton, BorderLayout.EAST);
}
dropdownPanel.setOpaque(false);
dropdownPanel.addFocusListener(this);
updateFont();
}
protected void initJComboBox() {
if (logger.isLoggable(Level.FINE)) {
logger.fine("initJComboBox()");
}
Point locTemp = null;
Container parentTemp = null;
if (jComboBox != null && jComboBox.getParent() != null) {
locTemp = jComboBox.getLocation();
parentTemp = jComboBox.getParent();
parentTemp.remove(jComboBox);
parentTemp.remove(resetButton);
}
listModel = null;
jComboBox = new JComboBox(getListModel());
/*if (getDataObject() == null) {
Vector<Object> defaultValue = new Vector<Object>();
defaultValue.add(FlexoLocalization.localizedForKey("no_selection"));
_jComboBox = new JComboBox(defaultValue);
} else {
// TODO: Verify that there is no reason for this comboBoxModel to be cached.
listModel=null;
_jComboBox = new JComboBox(getListModel());
}*/
jComboBox.setFont(getFont());
jComboBox.setRenderer(getListCellRenderer());
jComboBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (logger.isLoggable(Level.FINE)) {
logger.fine("Action performed in " + this.getClass().getName());
}
updateModelFromWidget();
}
});
if (parentTemp != null) {
// _jComboBox.setSize(dimTemp);
jComboBox.setLocation(locTemp);
((JPanel) parentTemp).add(jComboBox, BorderLayout.CENTER);
if (getWidget().showReset) {
((JPanel) parentTemp).add(resetButton, BorderLayout.EAST);
}
}
// Important: otherwise might be desynchronized
jComboBox.revalidate();
if ((getWidget().getData() == null || !getWidget().getData().isValid()) && getWidget().getAutoSelectFirstRow()
&& getListModel().getSize() > 0) {
jComboBox.setSelectedIndex(0);
}
jComboBox.setEnabled(isComponentEnabled());
}
@Override
public synchronized boolean updateWidgetFromModel() {
if (notEquals(getValue(), jComboBox.getSelectedItem()) || listModelRequireChange()) {
if (logger.isLoggable(Level.FINE)) {
logger.fine("updateWidgetFromModel()");
}
widgetUpdating = true;
initJComboBox();
jComboBox.setSelectedItem(getValue());
widgetUpdating = false;
if (getValue() == null && getWidget().getAutoSelectFirstRow() && getListModel().getSize() > 0) {
jComboBox.setSelectedIndex(0);
}
return true;
}
return false;
}
/**
* Update the model given the actual state of the widget
*/
@Override
public synchronized boolean updateModelFromWidget() {
if (widgetUpdating || modelUpdating) {
return false;
}
if (notEquals(getValue(), jComboBox.getSelectedItem())) {
modelUpdating = true;
if (logger.isLoggable(Level.FINE)) {
logger.fine("updateModelFromWidget with " + jComboBox.getSelectedItem());
}
if (jComboBox.getSelectedItem() != null && !widgetUpdating) {
setValue(jComboBox.getSelectedItem());
}
modelUpdating = false;
return true;
}
return false;
}
@Override
public MyComboBoxModel getListModel() {
return (MyComboBoxModel) super.getListModel();
}
@Override
protected MyComboBoxModel updateListModelWhenRequired() {
if (listModel == null) {
listModel = new MyComboBoxModel(getValue());
if (jComboBox != null) {
jComboBox.setModel((MyComboBoxModel) listModel);
}
} else {
MyComboBoxModel aNewMyComboBoxModel = new MyComboBoxModel(getValue());
if (!aNewMyComboBoxModel.equals(listModel)) {
listModel = aNewMyComboBoxModel;
jComboBox.setModel((MyComboBoxModel) listModel);
}
}
return (MyComboBoxModel) listModel;
}
protected class MyComboBoxModel extends FIBMultipleValueModel implements ComboBoxModel {
protected Object selectedItem = null;
public MyComboBoxModel(Object selectedObject) {
super();
}
@Override
public void setSelectedItem(Object anItem) {
if (selectedItem != anItem) {
widgetUpdating = true;
selectedItem = anItem;
// logger.info("setSelectedItem() with " + anItem + " widgetUpdating=" + widgetUpdating + " modelUpdating=" +
// modelUpdating);
getDynamicModel().setSelected(anItem);
getDynamicModel().setSelectedIndex(indexOf(anItem));
if (!widgetUpdating && !modelUpdating) {
notifyDynamicModelChanged();
}
widgetUpdating = false;
}
}
@Override
public Object getSelectedItem() {
return selectedItem;
}
@Override
public int hashCode() {
return selectedItem == null ? 0 : selectedItem.hashCode();
}
@Override
public boolean equals(Object object) {
if (object instanceof MyComboBoxModel) {
if (selectedItem != ((MyComboBoxModel) object).selectedItem) {
return false;
}
}
return super.equals(object);
}
}
@Override
public JPanel getJComponent() {
return dropdownPanel;
}
@Override
public JComboBox getDynamicJComponent() {
return jComboBox;
}
@Override
public void updateFont() {
super.updateFont();
if (getFont() != null) {
jComboBox.setFont(getFont());
}
}
}