Return-Path: X-Original-To: apmail-chemistry-commits-archive@www.apache.org Delivered-To: apmail-chemistry-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id CFDE790E2 for ; Tue, 3 Apr 2012 05:38:17 +0000 (UTC) Received: (qmail 90975 invoked by uid 500); 3 Apr 2012 05:38:17 -0000 Delivered-To: apmail-chemistry-commits-archive@chemistry.apache.org Received: (qmail 90920 invoked by uid 500); 3 Apr 2012 05:38:17 -0000 Mailing-List: contact commits-help@chemistry.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@chemistry.apache.org Delivered-To: mailing list commits@chemistry.apache.org Received: (qmail 90873 invoked by uid 99); 3 Apr 2012 05:38:15 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 03 Apr 2012 05:38:15 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 03 Apr 2012 05:38:01 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id D24022388C35; Tue, 3 Apr 2012 05:37:13 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1308703 [10/21] - in /chemistry/site/trunk/content/java/0.7.0/maven/chemistry-opencmis-workbench: ./ chemistry-opencmis-workbench/ chemistry-opencmis-workbench/css/ chemistry-opencmis-workbench/images/ chemistry-opencmis-workbench/images/l... Date: Tue, 03 Apr 2012 05:37:08 -0000 To: commits@chemistry.apache.org From: gabriele@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20120403053713.D24022388C35@eris.apache.org> Added: chemistry/site/trunk/content/java/0.7.0/maven/chemistry-opencmis-workbench/chemistry-opencmis-workbench/xref/org/apache/chemistry/opencmis/workbench/PropertyEditorFrame.html URL: http://svn.apache.org/viewvc/chemistry/site/trunk/content/java/0.7.0/maven/chemistry-opencmis-workbench/chemistry-opencmis-workbench/xref/org/apache/chemistry/opencmis/workbench/PropertyEditorFrame.html?rev=1308703&view=auto ============================================================================== --- chemistry/site/trunk/content/java/0.7.0/maven/chemistry-opencmis-workbench/chemistry-opencmis-workbench/xref/org/apache/chemistry/opencmis/workbench/PropertyEditorFrame.html (added) +++ chemistry/site/trunk/content/java/0.7.0/maven/chemistry-opencmis-workbench/chemistry-opencmis-workbench/xref/org/apache/chemistry/opencmis/workbench/PropertyEditorFrame.html Tue Apr 3 05:37:04 2012 @@ -0,0 +1,764 @@ + + + + +PropertyEditorFrame xref + + + +
+
+1   /*
+2    * Licensed to the Apache Software Foundation (ASF) under one
+3    * or more contributor license agreements.  See the NOTICE file
+4    * distributed with this work for additional information
+5    * regarding copyright ownership.  The ASF licenses this file
+6    * to you under the Apache License, Version 2.0 (the
+7    * "License"); you may not use this file except in compliance
+8    * with the License.  You may obtain a copy of the License at
+9    *
+10   * http://www.apache.org/licenses/LICENSE-2.0
+11   *
+12   * Unless required by applicable law or agreed to in writing,
+13   * software distributed under the License is distributed on an
+14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+15   * KIND, either express or implied.  See the License for the
+16   * specific language governing permissions and limitations
+17   * under the License.
+18   */
+19  package org.apache.chemistry.opencmis.workbench;
+20  
+21  import java.awt.BorderLayout;
+22  import java.awt.Color;
+23  import java.awt.Cursor;
+24  import java.awt.Dimension;
+25  import java.awt.FlowLayout;
+26  import java.awt.Font;
+27  import java.awt.event.ActionEvent;
+28  import java.awt.event.ActionListener;
+29  import java.awt.event.KeyEvent;
+30  import java.awt.event.KeyListener;
+31  import java.math.BigDecimal;
+32  import java.text.DecimalFormat;
+33  import java.text.Format;
+34  import java.util.ArrayList;
+35  import java.util.Calendar;
+36  import java.util.Collections;
+37  import java.util.GregorianCalendar;
+38  import java.util.HashMap;
+39  import java.util.LinkedList;
+40  import java.util.List;
+41  import java.util.Map;
+42  import java.util.TimeZone;
+43  
+44  import javax.swing.BorderFactory;
+45  import javax.swing.BoxLayout;
+46  import javax.swing.ImageIcon;
+47  import javax.swing.JButton;
+48  import javax.swing.JComboBox;
+49  import javax.swing.JComponent;
+50  import javax.swing.JFormattedTextField;
+51  import javax.swing.JFrame;
+52  import javax.swing.JLabel;
+53  import javax.swing.JPanel;
+54  import javax.swing.JScrollPane;
+55  import javax.swing.JSpinner;
+56  import javax.swing.JTextField;
+57  import javax.swing.SpinnerListModel;
+58  import javax.swing.SpinnerNumberModel;
+59  import javax.swing.UIManager;
+60  import javax.swing.event.ChangeEvent;
+61  import javax.swing.event.ChangeListener;
+62  
+63  import org.apache.chemistry.opencmis.client.api.CmisObject;
+64  import org.apache.chemistry.opencmis.client.api.ObjectId;
+65  import org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition;
+66  import org.apache.chemistry.opencmis.commons.enums.Action;
+67  import org.apache.chemistry.opencmis.commons.enums.Cardinality;
+68  import org.apache.chemistry.opencmis.commons.enums.Updatability;
+69  import org.apache.chemistry.opencmis.workbench.PropertyEditorFrame.UpdateStatus.StatusFlag;
+70  import org.apache.chemistry.opencmis.workbench.model.ClientModel;
+71  
+72  /**
+73   * Simple property editor.
+74   */
+75  public class PropertyEditorFrame extends JFrame {
+76  
+77      private static final long serialVersionUID = 1L;
+78  
+79      private static final String WINDOW_TITLE = "Property Editor";
+80      private static final ImageIcon ICON_ADD = ClientHelper.getIcon("add.png");
+81  
+82      private final ClientModel model;
+83      private final CmisObject object;
+84      private List<PropertyInputPanel> propertyPanels;
+85  
+86      public PropertyEditorFrame(final ClientModel model, final CmisObject object) {
+87          super();
+88  
+89          this.model = model;
+90          this.object = object;
+91  
+92          createGUI();
+93      }
+94  
+95      private void createGUI() {
+96          setTitle(WINDOW_TITLE);
+97          setPreferredSize(new Dimension(800, 600));
+98          setMinimumSize(new Dimension(300, 120));
+99  
+100         setLayout(new BorderLayout());
+101 
+102         final JPanel panel = new JPanel();
+103         panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
+104 
+105         final Font labelFont = UIManager.getFont("Label.font");
+106         final Font boldFont = labelFont.deriveFont(Font.BOLD, labelFont.getSize2D() * 1.2f);
+107 
+108         final JPanel topPanel = new JPanel();
+109         topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.Y_AXIS));
+110         topPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
+111         final JLabel nameLabel = new JLabel(object.getName());
+112         nameLabel.setFont(boldFont);
+113         topPanel.add(nameLabel);
+114         topPanel.add(new JLabel(object.getId()));
+115         add(topPanel, BorderLayout.PAGE_START);
+116 
+117         JScrollPane scrollPane = new JScrollPane(panel);
+118         add(scrollPane, BorderLayout.CENTER);
+119 
+120         propertyPanels = new ArrayList<PropertyEditorFrame.PropertyInputPanel>();
+121 
+122         int position = 0;
+123         for (PropertyDefinition<?> propDef : object.getType().getPropertyDefinitions().values()) {
+124             boolean isUpdatable = (propDef.getUpdatability() == Updatability.READWRITE)
+125                     || (propDef.getUpdatability() == Updatability.WHENCHECKEDOUT && object.getAllowableActions()
+126                             .getAllowableActions().contains(Action.CAN_CHECK_IN));
+127 
+128             if (isUpdatable) {
+129                 PropertyInputPanel propertyPanel = new PropertyInputPanel(propDef, object.getPropertyValue(propDef
+130                         .getId()), position++);
+131 
+132                 propertyPanels.add(propertyPanel);
+133                 panel.add(propertyPanel);
+134             }
+135         }
+136 
+137         JButton updateButton = new JButton("Update");
+138         updateButton.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
+139         updateButton.setDefaultCapable(true);
+140         updateButton.addActionListener(new ActionListener() {
+141             public void actionPerformed(ActionEvent event) {
+142                 if (doUpdate()) {
+143                     dispose();
+144                 }
+145             }
+146         });
+147 
+148         add(updateButton, BorderLayout.PAGE_END);
+149 
+150         setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+151         pack();
+152         setLocationRelativeTo(null);
+153         setVisible(true);
+154     }
+155 
+156     /**
+157      * Performs the update.
+158      */
+159     private boolean doUpdate() {
+160         try {
+161             setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+162 
+163             Map<String, Object> properties = new HashMap<String, Object>();
+164             for (PropertyInputPanel propertyPanel : propertyPanels) {
+165                 if (propertyPanel.includeInUpdate()) {
+166                     properties.put(propertyPanel.getId(), propertyPanel.getValue());
+167                 }
+168             }
+169 
+170             if (properties.isEmpty()) {
+171                 return false;
+172             }
+173 
+174             ObjectId newId = object.updateProperties(properties, false);
+175 
+176             if ((newId != null) && newId.getId().equals(model.getCurrentObject().getId())) {
+177                 try {
+178                     model.reloadObject();
+179                     model.reloadFolder();
+180                 } catch (Exception ex) {
+181                     ClientHelper.showError(null, ex);
+182                 }
+183             }
+184 
+185             return true;
+186         } catch (Exception ex) {
+187             ClientHelper.showError(this, ex);
+188             return false;
+189         } finally {
+190             setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+191         }
+192     }
+193 
+194     interface UpdateStatus {
+195         enum StatusFlag {
+196             DontChange, Update, Unset
+197         }
+198 
+199         void setStatus(StatusFlag status);
+200 
+201         StatusFlag getStatus();
+202     }
+203 
+204     interface MultivalueManager {
+205         void addNewValue();
+206 
+207         void removeValue(int pos);
+208 
+209         void moveUp(int pos);
+210 
+211         void moveDown(int pos);
+212     }
+213 
+214     /**
+215      * Property input panel.
+216      */
+217     public static class PropertyInputPanel extends JPanel implements UpdateStatus, MultivalueManager {
+218         private static final long serialVersionUID = 1L;
+219 
+220         private static final Color BACKGROUND1 = UIManager.getColor("Table:\"Table.cellRenderer\".background");
+221         private static final Color BACKGROUND2 = UIManager.getColor("Table.alternateRowColor");
+222         private static final Color LINE = new Color(0xB8, 0xB8, 0xB8);
+223 
+224         private final PropertyDefinition<?> propDef;
+225         private final Object value;
+226         private final Color bgColor;
+227         private JComboBox changeBox;
+228         private LinkedList<JComponent> valueComponents;
+229 
+230         public PropertyInputPanel(PropertyDefinition<?> propDef, Object value, int position) {
+231             super();
+232             this.propDef = propDef;
+233             this.value = value;
+234             bgColor = (position % 2 == 0 ? BACKGROUND1 : BACKGROUND2);
+235             createGUI();
+236         }
+237 
+238         private void createGUI() {
+239             setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
+240 
+241             setBackground(bgColor);
+242             setBorder(BorderFactory.createCompoundBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, LINE),
+243                     BorderFactory.createEmptyBorder(10, 5, 10, 5)));
+244 
+245             Font labelFont = UIManager.getFont("Label.font");
+246             Font boldFont = labelFont.deriveFont(Font.BOLD, labelFont.getSize2D() * 1.2f);
+247 
+248             JPanel titlePanel = new JPanel();
+249             titlePanel.setLayout(new BorderLayout());
+250             titlePanel.setBackground(bgColor);
+251             titlePanel.setToolTipText("<html><b>" + propDef.getPropertyType().value() + "</b> ("
+252                     + propDef.getCardinality().value() + " value)"
+253                     + (propDef.getDescription() != null ? "<br>" + propDef.getDescription() : ""));
+254             add(titlePanel);
+255 
+256             JPanel namePanel = new JPanel();
+257             namePanel.setLayout(new BoxLayout(namePanel, BoxLayout.Y_AXIS));
+258             namePanel.setBackground(bgColor);
+259             JLabel displayNameLabel = new JLabel(propDef.getDisplayName());
+260             displayNameLabel.setFont(boldFont);
+261             namePanel.add(displayNameLabel);
+262             JLabel idLabel = new JLabel(propDef.getId());
+263             namePanel.add(idLabel);
+264 
+265             titlePanel.add(namePanel, BorderLayout.LINE_START);
+266 
+267             changeBox = new JComboBox(new Object[] { "Don't change     ", "Update    ", "Unset     " });
+268             titlePanel.add(changeBox, BorderLayout.LINE_END);
+269 
+270             valueComponents = new LinkedList<JComponent>();
+271             if (propDef.getCardinality() == Cardinality.SINGLE) {
+272                 JComponent valueField = createInputField(value);
+273                 valueComponents.add(valueField);
+274                 add(valueField);
+275             } else {
+276                 if (value instanceof List<?>) {
+277                     for (Object v : (List<?>) value) {
+278                         JComponent valueField = new MultiValuePropertyInputField(createInputField(v), this, bgColor);
+279                         valueComponents.add(valueField);
+280                         add(valueField);
+281                     }
+282                 }
+283 
+284                 JPanel addPanel = new JPanel(new BorderLayout());
+285                 addPanel.setBackground(bgColor);
+286                 JButton addButton = new JButton(ICON_ADD);
+287                 addButton.addActionListener(new ActionListener() {
+288                     @Override
+289                     public void actionPerformed(ActionEvent e) {
+290                         addNewValue();
+291                         setStatus(StatusFlag.Update);
+292                     }
+293                 });
+294                 addPanel.add(addButton, BorderLayout.LINE_END);
+295                 add(addPanel);
+296 
+297                 updatePositions();
+298             }
+299 
+300             setMaximumSize(new Dimension(Short.MAX_VALUE, getPreferredSize().height));
+301         }
+302 
+303         protected JComponent createInputField(Object value) {
+304             switch (propDef.getPropertyType()) {
+305             case INTEGER:
+306                 return new IntegerPropertyInputField(value, this, bgColor);
+307             case DECIMAL:
+308                 return new DecimalPropertyInputField(value, this, bgColor);
+309             case DATETIME:
+310                 return new DateTimePropertyInputField(value, this, bgColor);
+311             case BOOLEAN:
+312                 return new BooleanPropertyInputField(value, this, bgColor);
+313             default:
+314                 return new StringPropertyInputField(value, this, bgColor);
+315             }
+316         }
+317 
+318         private void updatePositions() {
+319             int n = valueComponents.size();
+320             for (int i = 0; i < n; i++) {
+321                 MultiValuePropertyInputField comp = (MultiValuePropertyInputField) valueComponents.get(i);
+322                 comp.updatePosition(i, i + 1 == n);
+323             }
+324         }
+325 
+326         public void addNewValue() {
+327             JComponent valueField = new MultiValuePropertyInputField(createInputField(null), this, bgColor);
+328             valueComponents.add(valueField);
+329             add(valueField, getComponentCount() - 1);
+330 
+331             updatePositions();
+332             setStatus(StatusFlag.Update);
+333 
+334             revalidate();
+335         }
+336 
+337         public void removeValue(int pos) {
+338             remove(valueComponents.remove(pos));
+339 
+340             updatePositions();
+341             setStatus(StatusFlag.Update);
+342 
+343             revalidate();
+344         }
+345 
+346         public void moveUp(int pos) {
+347             JComponent comp = valueComponents.get(pos);
+348             Collections.swap(valueComponents, pos, pos - 1);
+349 
+350             remove(comp);
+351             add(comp, pos);
+352 
+353             updatePositions();
+354             setStatus(StatusFlag.Update);
+355 
+356             revalidate();
+357         }
+358 
+359         public void moveDown(int pos) {
+360             JComponent comp = valueComponents.get(pos);
+361             Collections.swap(valueComponents, pos, pos + 1);
+362 
+363             remove(comp);
+364             add(comp, pos + 2);
+365 
+366             updatePositions();
+367             setStatus(StatusFlag.Update);
+368 
+369             revalidate();
+370         }
+371 
+372         public String getId() {
+373             return propDef.getId();
+374         }
+375 
+376         public Object getValue() {
+377             Object result = null;
+378 
+379             if (getStatus() == StatusFlag.Update) {
+380                 try {
+381                     if (propDef.getCardinality() == Cardinality.SINGLE) {
+382                         result = ((PropertyValue) valueComponents.get(0)).getPropertyValue();
+383                     } else {
+384                         List<Object> list = new ArrayList<Object>();
+385                         for (JComponent comp : valueComponents) {
+386                             list.add(((PropertyValue) comp).getPropertyValue());
+387                         }
+388                         result = list;
+389                     }
+390                 } catch (Exception ex) {
+391                     ClientHelper.showError(this, ex);
+392                 }
+393             }
+394 
+395             return result;
+396         }
+397 
+398         public boolean includeInUpdate() {
+399             return getStatus() != StatusFlag.DontChange;
+400         }
+401 
+402         public void setStatus(StatusFlag status) {
+403             switch (status) {
+404             case Update:
+405                 changeBox.setSelectedIndex(1);
+406                 break;
+407             case Unset:
+408                 changeBox.setSelectedIndex(2);
+409                 break;
+410             default:
+411                 changeBox.setSelectedIndex(0);
+412             }
+413         }
+414 
+415         public StatusFlag getStatus() {
+416             switch (changeBox.getSelectedIndex()) {
+417             case 1:
+418                 return StatusFlag.Update;
+419             case 2:
+420                 return StatusFlag.Unset;
+421             default:
+422                 return StatusFlag.DontChange;
+423             }
+424         }
+425 
+426         public Dimension getMaximumSize() {
+427             Dimension size = getPreferredSize();
+428             size.width = Short.MAX_VALUE;
+429             return size;
+430         }
+431     }
+432 
+433     /**
+434      * Property value interface.
+435      */
+436     public interface PropertyValue {
+437         Object getPropertyValue() throws Exception;
+438     }
+439 
+440     /**
+441      * String property.
+442      */
+443     public static class StringPropertyInputField extends JTextField implements PropertyValue {
+444         private static final long serialVersionUID = 1L;
+445 
+446         public StringPropertyInputField(final Object value, final UpdateStatus status, final Color bgColor) {
+447             super(value == null ? "" : value.toString());
+448 
+449             addKeyListener(new KeyListener() {
+450                 @Override
+451                 public void keyTyped(KeyEvent e) {
+452                 }
+453 
+454                 @Override
+455                 public void keyReleased(KeyEvent e) {
+456                     status.setStatus(StatusFlag.Update);
+457                 }
+458 
+459                 @Override
+460                 public void keyPressed(KeyEvent e) {
+461                 }
+462             });
+463         }
+464 
+465         public Object getPropertyValue() {
+466             return getText();
+467         }
+468     }
+469 
+470     /**
+471      * Formatted property.
+472      */
+473     public static class AbstractFormattedPropertyInputField extends JFormattedTextField implements PropertyValue {
+474         private static final long serialVersionUID = 1L;
+475 
+476         public AbstractFormattedPropertyInputField(final Object value, final Format format, final UpdateStatus status,
+477                 final Color bgColor) {
+478             super(format);
+479             if (value != null) {
+480                 setValue(value);
+481             }
+482 
+483             addKeyListener(new KeyListener() {
+484                 @Override
+485                 public void keyTyped(KeyEvent e) {
+486                 }
+487 
+488                 @Override
+489                 public void keyReleased(KeyEvent e) {
+490                     status.setStatus(StatusFlag.Update);
+491                 }
+492 
+493                 @Override
+494                 public void keyPressed(KeyEvent e) {
+495                 }
+496             });
+497         }
+498 
+499         public Object getPropertyValue() throws Exception {
+500             commitEdit();
+501             return getValue();
+502         }
+503     }
+504 
+505     /**
+506      * Integer property.
+507      */
+508     public static class IntegerPropertyInputField extends AbstractFormattedPropertyInputField {
+509         private static final long serialVersionUID = 1L;
+510 
+511         public IntegerPropertyInputField(final Object value, final UpdateStatus status, final Color bgColor) {
+512             super(value, createFormat(), status, bgColor);
+513             setHorizontalAlignment(JTextField.RIGHT);
+514         }
+515 
+516         private static DecimalFormat createFormat() {
+517             DecimalFormat result = new DecimalFormat("#,##0");
+518             result.setParseBigDecimal(true);
+519             result.setParseIntegerOnly(true);
+520             return result;
+521         }
+522 
+523         public Object getPropertyValue() throws Exception {
+524             return ((BigDecimal) super.getValue()).toBigIntegerExact();
+525         }
+526     }
+527 
+528     /**
+529      * Decimal property.
+530      */
+531     public static class DecimalPropertyInputField extends AbstractFormattedPropertyInputField {
+532         private static final long serialVersionUID = 1L;
+533 
+534         public DecimalPropertyInputField(final Object value, final UpdateStatus status, final Color bgColor) {
+535             super(value, createFormat(), status, bgColor);
+536             setHorizontalAlignment(JTextField.RIGHT);
+537         }
+538 
+539         private static DecimalFormat createFormat() {
+540             DecimalFormat result = new DecimalFormat("#,##0.#############################");
+541             result.setParseBigDecimal(true);
+542             return result;
+543         }
+544     }
+545 
+546     /**
+547      * Boolean property.
+548      */
+549     public static class BooleanPropertyInputField extends JComboBox implements PropertyValue {
+550         private static final long serialVersionUID = 1L;
+551 
+552         public BooleanPropertyInputField(final Object value, final UpdateStatus status, final Color bgColor) {
+553             super(new Object[] { true, false });
+554             setSelectedItem(value == null ? true : value);
+555 
+556             addActionListener(new ActionListener() {
+557                 @Override
+558                 public void actionPerformed(ActionEvent e) {
+559                     status.setStatus(StatusFlag.Update);
+560                 }
+561             });
+562         }
+563 
+564         public Object getPropertyValue() {
+565             return getSelectedItem();
+566         }
+567     }
+568 
+569     /**
+570      * DateTime property.
+571      */
+572     public static class DateTimePropertyInputField extends JPanel implements PropertyValue {
+573         private static final long serialVersionUID = 1L;
+574 
+575         private static final String[] MONTH_STRINGS;
+576 
+577         static {
+578             String[] months = new java.text.DateFormatSymbols().getMonths();
+579             int lastIndex = months.length - 1;
+580 
+581             if (months[lastIndex] == null || months[lastIndex].length() <= 0) {
+582                 String[] monthStrings = new String[lastIndex];
+583                 System.arraycopy(months, 0, monthStrings, 0, lastIndex);
+584                 MONTH_STRINGS = monthStrings;
+585             } else {
+586                 MONTH_STRINGS = months;
+587             }
+588         }
+589 
+590         private final SpinnerNumberModel day;
+591         private final SpinnerListModel month;
+592         private final SpinnerNumberModel year;
+593         private final SpinnerNumberModel hour;
+594         private final SpinnerNumberModel min;
+595         private final SpinnerNumberModel sec;
+596         private final TimeZone timezone;
+597 
+598         public DateTimePropertyInputField(final Object value, final UpdateStatus status, final Color bgColor) {
+599             setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
+600             setBackground(bgColor);
+601 
+602             GregorianCalendar cal = (value == null ? new GregorianCalendar() : (GregorianCalendar) value);
+603             timezone = cal.getTimeZone();
+604 
+605             day = new SpinnerNumberModel(cal.get(Calendar.DATE), 1, 31, 1);
+606             addSpinner(new JSpinner(day), status);
+607 
+608             month = new SpinnerListModel(MONTH_STRINGS);
+609             month.setValue(MONTH_STRINGS[cal.get(Calendar.MONTH)]);
+610             JSpinner monthSpinner = new JSpinner(month);
+611             JComponent editor = monthSpinner.getEditor();
+612             if (editor instanceof JSpinner.DefaultEditor) {
+613                 JFormattedTextField tf = ((JSpinner.DefaultEditor) editor).getTextField();
+614                 tf.setColumns(6);
+615                 tf.setHorizontalAlignment(JTextField.RIGHT);
+616             }
+617             addSpinner(monthSpinner, status);
+618 
+619             year = new SpinnerNumberModel(cal.get(Calendar.YEAR), 0, 9999, 1);
+620             JSpinner yearSpinner = new JSpinner(year);
+621             yearSpinner.setEditor(new JSpinner.NumberEditor(yearSpinner, "#"));
+622             yearSpinner.getEditor().setBackground(bgColor);
+623             addSpinner(yearSpinner, status);
+624 
+625             add(new JLabel("  "));
+626 
+627             hour = new SpinnerNumberModel(cal.get(Calendar.HOUR_OF_DAY), 0, 23, 1);
+628             JSpinner hourSpinner = new JSpinner(hour);
+629             addSpinner(hourSpinner, status);
+630 
+631             add(new JLabel(":"));
+632 
+633             min = new SpinnerNumberModel(cal.get(Calendar.MINUTE), 0, 59, 1);
+634             JSpinner minSpinner = new JSpinner(min);
+635             addSpinner(minSpinner, status);
+636 
+637             add(new JLabel(":"));
+638 
+639             sec = new SpinnerNumberModel(cal.get(Calendar.SECOND), 0, 59, 1);
+640             JSpinner secSpinner = new JSpinner(sec);
+641             addSpinner(secSpinner, status);
+642 
+643             add(new JLabel(" " + timezone.getDisplayName(true, TimeZone.SHORT)));
+644         }
+645 
+646         private void addSpinner(final JSpinner spinner, final UpdateStatus status) {
+647             spinner.addChangeListener(new ChangeListener() {
+648                 @Override
+649                 public void stateChanged(ChangeEvent e) {
+650                     status.setStatus(StatusFlag.Update);
+651                 }
+652             });
+653 
+654             add(spinner);
+655         }
+656 
+657         public Object getPropertyValue() {
+658             GregorianCalendar result = new GregorianCalendar();
+659 
+660             result.setTimeZone(timezone);
+661 
+662             result.set(Calendar.YEAR, year.getNumber().intValue());
+663             int mi = 0;
+664             String ms = month.getValue().toString();
+665             for (int i = 0; i < MONTH_STRINGS.length; i++) {
+666                 if (MONTH_STRINGS[i].equals(ms)) {
+667                     mi = i;
+668                     break;
+669                 }
+670             }
+671             result.set(Calendar.MONTH, mi);
+672             result.set(Calendar.DATE, day.getNumber().intValue());
+673             result.set(Calendar.HOUR_OF_DAY, hour.getNumber().intValue());
+674             result.set(Calendar.MINUTE, min.getNumber().intValue());
+675             result.set(Calendar.SECOND, sec.getNumber().intValue());
+676 
+677             return result;
+678         }
+679     }
+680 
+681     /**
+682      * Multi value property.
+683      */
+684     public static class MultiValuePropertyInputField extends JPanel implements PropertyValue {
+685         private static final long serialVersionUID = 1L;
+686 
+687         private static final ImageIcon ICON_UP = ClientHelper.getIcon("up.png");
+688         private static final ImageIcon ICON_DOWN = ClientHelper.getIcon("down.png");
+689         private static final ImageIcon ICON_REMOVE = ClientHelper.getIcon("remove.png");
+690 
+691         private final JComponent component;
+692         private int position;
+693 
+694         private JButton upButton;
+695         private JButton downButton;
+696 
+697         public MultiValuePropertyInputField(final JComponent component, final MultivalueManager mutlivalueManager,
+698                 final Color bgColor) {
+699             super();
+700             this.component = component;
+701 
+702             setLayout(new BorderLayout());
+703             setBackground(bgColor);
+704 
+705             add(component, BorderLayout.CENTER);
+706 
+707             JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 0, 0));
+708             buttonPanel.setBackground(bgColor);
+709 
+710             upButton = new JButton(ICON_UP);
+711             upButton.addActionListener(new ActionListener() {
+712                 @Override
+713                 public void actionPerformed(ActionEvent e) {
+714                     mutlivalueManager.moveUp(MultiValuePropertyInputField.this.position);
+715                 }
+716             });
+717             buttonPanel.add(upButton);
+718 
+719             downButton = new JButton(ICON_DOWN);
+720             downButton.addActionListener(new ActionListener() {
+721                 @Override
+722                 public void actionPerformed(ActionEvent e) {
+723                     mutlivalueManager.moveDown(MultiValuePropertyInputField.this.position);
+724                 }
+725             });
+726             buttonPanel.add(downButton);
+727 
+728             JButton removeButton = new JButton(ICON_REMOVE);
+729             removeButton.addActionListener(new ActionListener() {
+730                 @Override
+731                 public void actionPerformed(ActionEvent e) {
+732                     mutlivalueManager.removeValue(MultiValuePropertyInputField.this.position);
+733                 }
+734             });
+735             buttonPanel.add(removeButton);
+736 
+737             add(buttonPanel, BorderLayout.LINE_END);
+738         }
+739 
+740         public void updatePosition(int position, boolean isLast) {
+741             this.position = position;
+742             upButton.setEnabled(position > 0);
+743             downButton.setEnabled(!isLast);
+744         }
+745 
+746         public Object getPropertyValue() throws Exception {
+747             return ((PropertyValue) component).getPropertyValue();
+748         }
+749     }
+750 }
+
+
+ +