/*
* Copyright 2009 Peter Karich, peat_hal 'at' users 'dot' sourceforge 'dot' net.
*
* 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.
* under the License.
*/
package de.timefinder.core.ui.form;
import de.timefinder.data.algo.DataPoolSettings;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import org.springframework.binding.form.FormModel;
import org.springframework.richclient.form.binding.support.CustomBinding;
/**
* This binding binds the start property of the class Event to two
* virtual properties (day, slot) only available in the GUI
*
* @author Peter Karich, peat_hal 'at' users 'dot' sourceforge 'dot' net
*/
class EventStartBinding extends CustomBinding {
private JComboBox slotCombo;
private JComboBox dayCombo;
private static final String EMPTY = " ";
private JLabel dateLabel = new JLabel(EMPTY);
private DataPoolSettings settings;
/**
* valueModelChange reflects update from model to GUI (MG)
* actionPerformed reflects update from GUI to model (GM)
*
* without the fireFurther-logic we will get:
* if we change the day in the GUI from 0 to 1
* => GM (start==5) => MG of slot (start==5) => GM (slot==1)
* MG of day (start==5)
*
* now we change the slot from 0 to 4
* => GM (start==9) => MG of slot+day => GM (day==2)
* => GM (start==14) => MG of slot+day => GM (slot==3)
*
* but this does not change functionality (we could add if(!fireFurther) return to 2*actionPerformed and valueModelChange)
*/
private volatile boolean fireFurther = true;
public EventStartBinding(FormModel formModel, DataPoolSettings settings) {
super(formModel, "start", Integer.class);
this.settings = settings;
slotCombo = new JComboBox(createList(0, settings.getTimeslotsPerDay()));
dayCombo = new JComboBox(createList(0, settings.getNumberOfDays()));
/* if the internal value changes */
slotCombo.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setSlot((Integer) slotCombo.getSelectedItem());
}
});
dayCombo.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setDay((Integer) dayCombo.getSelectedItem());
}
});
}
private void changedStart(Integer start) {
if (start == null)
dateLabel.setText(EMPTY);
else {
String str = settings.toDateTime(start).toString(getMessage("dateTimeFormat"));
dateLabel.setText(str);
}
}
public static Object[] createList(int start, int end) {
List<Integer> list = new ArrayList();
for (int i = start; i < end; i++) {
list.add(i);
}
return list.toArray();
}
@Override
public String getProperty() {
return super.getProperty();
}
public String getFormPropertyPath() {
return formPropertyPath;
}
private int getStart() {
return (Integer) getFormModel().getValueModel("start").getValue();
}
private void setStart(int start) {
getFormModel().getValueModel("start").setValue(start);
changedStart(start);
}
public int getSlot() {
return getStart() % settings.getTimeslotsPerDay();
}
public void setSlot(int slot) {
setStart(getDay() * settings.getTimeslotsPerDay() + slot);
}
public int getDay() {
return (int) (getStart() / settings.getTimeslotsPerDay());
}
public void setDay(int day) {
setStart(day * settings.getTimeslotsPerDay() + getSlot());
}
@Override
protected void valueModelChanged(Object newValue) {
if (newValue instanceof Integer) {
int start = (Integer) newValue;
changedStart(start);
slotCombo.setSelectedItem(getSlot());
dayCombo.setSelectedItem(getDay());
} else {
changedStart(null);
slotCombo.setSelectedItem(null);
dayCombo.setSelectedItem(null);
}
}
@Override
protected JComponent doBindControl() {
JPanel panel = new JPanel();
panel.add(createLabelFor("day", dayCombo));
panel.add(dayCombo);
panel.add(createLabelFor("slot", slotCombo));
panel.add(slotCombo);
panel.add(dateLabel);
return panel;
}
@Override
protected void enabledChanged() {
slotCombo.setEnabled(isEnabled() && !isReadOnly());
dayCombo.setEnabled(isEnabled() && !isReadOnly());
}
@Override
protected void readOnlyChanged() {
slotCombo.setEnabled(isEnabled() && !isReadOnly());
dayCombo.setEnabled(isEnabled() && !isReadOnly());
}
/**
* stolen from AbstractFormBuilder.createLabelFor
*/
protected JLabel createLabelFor(String fieldName, JComponent component) {
JLabel label = getComponentFactory().createLabel("");
getFormModel().getFieldFace(fieldName).configure(label);
label.setLabelFor(component);
return label;
}
}