/** * * Copyright * 2009-2015 Jayway Products AB * 2016-2017 Föreningen Sambruk * * Licensed under AGPL, Version 3.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.gnu.org/licenses/agpl.txt * * 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 se.streamsource.streamflow.client.util; import org.jdesktop.swingx.JXDatePicker; import org.jdesktop.swingx.JXLabel; import org.qi4j.api.common.QualifiedName; import org.qi4j.api.injection.scope.Structure; import org.qi4j.api.property.StateHolder; import org.qi4j.api.util.DateFunctions; import org.qi4j.api.util.ListMap; import org.qi4j.api.value.ValueComposite; import org.qi4j.spi.Qi4jSPI; import org.restlet.data.Form; import org.restlet.data.Parameter; import se.streamsource.dci.value.link.LinkValue; import se.streamsource.streamflow.client.ui.workspace.cases.general.RemovableLabel; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JEditorPane; import javax.swing.JLabel; import javax.swing.JPasswordField; import javax.swing.JRadioButton; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.JTextPane; import javax.swing.text.JTextComponent; import java.awt.Color; import java.awt.Component; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import static java.lang.Integer.*; /** * Bind components to value names to allow them to be updated from a given source */ public class ValueBinder { @Structure Qi4jSPI spi; Map<Class<? extends Component>, Binder> binders = new HashMap<Class<? extends Component>, Binder>(); ListMap<String, Binding> bindings = new ListMap<String, Binding>(); public ValueBinder() { Binder defaultBinder = new DefaultBinder(); registerBinder( defaultBinder, JXLabel.class, JLabel.class, JTextField.class, JTextArea.class, JTextPane.class, JEditorPane.class, JScrollPane.class, JPasswordField.class, JCheckBox.class, JXDatePicker.class, JComboBox.class, JRadioButton.class, RemovableLabel.class, StreamflowJXColorSelectionButton.class, StreamflowSelectableLabel.class); } public void registerBinder( Binder binder, Class<? extends Component>... componentTypes ) { for (Class<? extends Component> componentType : componentTypes) { binders.put( componentType, binder ); } } public <T extends Component> T bind( String name, T component ) { return bind(name, component, null); } public <T extends Component> T bind( String name, T component, Converter converter) { Component boundComponent = component; if (boundComponent instanceof JScrollPane) { boundComponent = ((JScrollPane)boundComponent).getViewport().getView(); } Binder binder = binders.get( boundComponent.getClass() ); if (binder == null) throw new IllegalArgumentException( "No binder registered for component type:" + boundComponent.getClass().getSimpleName() ); bindings.add(name, new Binding(converter, boundComponent, binder)); return component; } public void update( ValueComposite source ) { spi.getState( source ).visitProperties( new StateHolder.StateVisitor<RuntimeException>() { public void visitProperty( QualifiedName name, Object value ) throws RuntimeException { Iterable<Binding> binding = bindings.get( name.name() ); if (binding != null) for (Binding binding1 : binding) { binding1.update( value ); } } } ); } public void update(Form form) { for (Parameter parameter : form) { List<Binding> bindings1 = bindings.get(parameter.getName()); if (bindings1 != null) for (Binding binding : bindings1) { binding.update(parameter.getValue()); } } } public void update( String name, Object value ) { List<Binding> bindings1 = bindings.get(name); if (bindings1 != null) for (Binding binding : bindings1) { binding.update( value ); } } public class Binding { Converter converter; Component component; Binder binder; public Binding( Converter converter, Component component, Binder binder ) { this.converter = converter; this.component = component; this.binder = binder; } void update(Object value) { if (converter != null) value = converter.toComponent( value ); binder.updateComponent( component, value ); } } public interface Binder { void updateComponent( Component component, Object value ); } private class DefaultBinder implements Binder { public DefaultBinder() { } public void updateComponent( Component component, Object value ) { if (component instanceof JLabel) { JLabel label = (JLabel) component; label.setText( value == null ? "" : value.toString() ); } else if (component instanceof JPasswordField) { JPasswordField passwordField = (JPasswordField) component; passwordField.setText( value == null ? "" : value.toString() ); } else if (component instanceof JTextComponent) { JTextComponent textField = (JTextComponent) component; String text = value == null ? "" : value.toString(); textField.setText( text ); textField.setCaretPosition( 0 ); } else if (component instanceof JCheckBox) { JCheckBox checkBox = (JCheckBox) component; if (value instanceof String) { value = Boolean.parseBoolean(value.toString()); } checkBox.setSelected( ((Boolean) value) ); } else if (component instanceof JLabel) { JLabel label = (JLabel) component; label.setText( value == null ? "" : value.toString() ); } else if (component instanceof JXDatePicker) { JXDatePicker datePicker = (JXDatePicker) component; if (value instanceof String) { if (!((String) value).isEmpty()) { datePicker.setDate( DateFunctions.fromString( (String) value ) ); } } else { datePicker.setDate( (Date) value ); } }else if (component instanceof StreamflowJXColorSelectionButton) { StreamflowJXColorSelectionButton colorSelectionButton = (StreamflowJXColorSelectionButton) component; if (value instanceof String) { if (!((String) value).isEmpty()) { colorSelectionButton.setBackground( new Color( parseInt( (String) value ) ) ); } } } else if (component instanceof JComboBox) { JComboBox box = (JComboBox) component; box.setSelectedItem( value ); } else if (component instanceof JRadioButton) { JRadioButton button = (JRadioButton) component; button.setSelected( button.getActionCommand().equals( value.toString() ) ); } else if (component instanceof RemovableLabel) { RemovableLabel label = (RemovableLabel) component; label.setRemoveLink((LinkValue) value); } } } public interface Converter<FROM,TO> { TO toComponent( FROM value ); } }