| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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. |
| */ |
| package org.apache.chemistry.opencmis.workbench; |
| |
| import java.awt.BorderLayout; |
| import java.awt.Color; |
| import java.awt.Cursor; |
| import java.awt.Dimension; |
| import java.awt.FlowLayout; |
| import java.awt.Font; |
| import java.awt.event.ActionEvent; |
| import java.awt.event.ActionListener; |
| import java.awt.event.KeyEvent; |
| import java.awt.event.KeyListener; |
| import java.math.BigDecimal; |
| import java.text.DecimalFormat; |
| import java.text.Format; |
| import java.text.ParseException; |
| import java.util.ArrayList; |
| import java.util.Calendar; |
| import java.util.Collections; |
| import java.util.GregorianCalendar; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.TimeZone; |
| |
| import javax.swing.BorderFactory; |
| import javax.swing.BoxLayout; |
| import javax.swing.ImageIcon; |
| import javax.swing.JButton; |
| import javax.swing.JComboBox; |
| import javax.swing.JComponent; |
| import javax.swing.JFormattedTextField; |
| import javax.swing.JFrame; |
| import javax.swing.JLabel; |
| import javax.swing.JPanel; |
| import javax.swing.JScrollPane; |
| import javax.swing.JSpinner; |
| import javax.swing.JTextField; |
| import javax.swing.SpinnerListModel; |
| import javax.swing.SpinnerNumberModel; |
| import javax.swing.UIManager; |
| import javax.swing.event.ChangeEvent; |
| import javax.swing.event.ChangeListener; |
| |
| import org.apache.chemistry.opencmis.client.api.CmisObject; |
| import org.apache.chemistry.opencmis.client.api.ObjectId; |
| import org.apache.chemistry.opencmis.client.api.ObjectType; |
| import org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition; |
| import org.apache.chemistry.opencmis.commons.enums.Action; |
| import org.apache.chemistry.opencmis.commons.enums.Cardinality; |
| import org.apache.chemistry.opencmis.commons.enums.Updatability; |
| import org.apache.chemistry.opencmis.workbench.PropertyEditorFrame.UpdateStatus.StatusFlag; |
| import org.apache.chemistry.opencmis.workbench.model.ClientModel; |
| |
| /** |
| * Simple property editor. |
| */ |
| public class PropertyEditorFrame extends JFrame { |
| |
| private static final long serialVersionUID = 1L; |
| |
| private static final String WINDOW_TITLE = "Property Editor"; |
| private static final ImageIcon ICON_ADD = ClientHelper.getIcon("add.png"); |
| |
| private final ClientModel model; |
| private final CmisObject object; |
| private List<PropertyInputPanel> propertyPanels; |
| |
| public PropertyEditorFrame(final ClientModel model, final CmisObject object) { |
| super(); |
| |
| this.model = model; |
| this.object = object; |
| |
| createGUI(); |
| } |
| |
| private void createGUI() { |
| setTitle(WINDOW_TITLE); |
| setPreferredSize(new Dimension(800, 600)); |
| setMinimumSize(new Dimension(300, 120)); |
| |
| setLayout(new BorderLayout()); |
| |
| final JPanel panel = new JPanel(); |
| panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS)); |
| |
| final Font labelFont = UIManager.getFont("Label.font"); |
| final Font boldFont = labelFont.deriveFont(Font.BOLD, labelFont.getSize2D() * 1.2f); |
| |
| final JPanel topPanel = new JPanel(); |
| topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.Y_AXIS)); |
| topPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); |
| final JLabel nameLabel = new JLabel(object.getName()); |
| nameLabel.setFont(boldFont); |
| topPanel.add(nameLabel); |
| topPanel.add(new JLabel(object.getId())); |
| add(topPanel, BorderLayout.PAGE_START); |
| |
| JScrollPane scrollPane = new JScrollPane(panel); |
| add(scrollPane, BorderLayout.CENTER); |
| |
| propertyPanels = new ArrayList<PropertyEditorFrame.PropertyInputPanel>(); |
| |
| int position = 0; |
| |
| // primary type |
| for (PropertyDefinition<?> propDef : object.getType().getPropertyDefinitions().values()) { |
| boolean isUpdatable = (propDef.getUpdatability() == Updatability.READWRITE) |
| || (propDef.getUpdatability() == Updatability.WHENCHECKEDOUT && object |
| .hasAllowableAction(Action.CAN_CHECK_IN)); |
| |
| if (isUpdatable) { |
| PropertyInputPanel propertyPanel = new PropertyInputPanel(propDef, object.getPropertyValue(propDef |
| .getId()), position++); |
| |
| propertyPanels.add(propertyPanel); |
| panel.add(propertyPanel); |
| } |
| } |
| |
| // secondary types |
| if (object.getSecondaryTypes() != null) { |
| for (ObjectType secType : object.getSecondaryTypes()) { |
| if (secType.getPropertyDefinitions() != null) { |
| for (PropertyDefinition<?> propDef : secType.getPropertyDefinitions().values()) { |
| boolean isUpdatable = (propDef.getUpdatability() == Updatability.READWRITE) |
| || (propDef.getUpdatability() == Updatability.WHENCHECKEDOUT && object |
| .hasAllowableAction(Action.CAN_CHECK_IN)); |
| |
| if (isUpdatable) { |
| PropertyInputPanel propertyPanel = new PropertyInputPanel(propDef, |
| object.getPropertyValue(propDef.getId()), position++); |
| |
| propertyPanels.add(propertyPanel); |
| panel.add(propertyPanel); |
| } |
| } |
| } |
| } |
| } |
| |
| JButton updateButton = new JButton("Update"); |
| updateButton.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); |
| updateButton.setDefaultCapable(true); |
| updateButton.addActionListener(new ActionListener() { |
| public void actionPerformed(ActionEvent event) { |
| if (doUpdate()) { |
| dispose(); |
| } |
| } |
| }); |
| |
| add(updateButton, BorderLayout.PAGE_END); |
| |
| setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); |
| pack(); |
| setLocationRelativeTo(null); |
| setVisible(true); |
| } |
| |
| /** |
| * Performs the update. |
| */ |
| private boolean doUpdate() { |
| try { |
| setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); |
| |
| Map<String, Object> properties = new HashMap<String, Object>(); |
| for (PropertyInputPanel propertyPanel : propertyPanels) { |
| if (propertyPanel.includeInUpdate()) { |
| properties.put(propertyPanel.getId(), propertyPanel.getValue()); |
| } |
| } |
| |
| if (properties.isEmpty()) { |
| return false; |
| } |
| |
| ObjectId newId = object.updateProperties(properties, false); |
| |
| if ((newId != null) && newId.getId().equals(model.getCurrentObject().getId())) { |
| try { |
| model.reloadObject(); |
| model.reloadFolder(); |
| } catch (Exception ex) { |
| ClientHelper.showError(null, ex); |
| } |
| } |
| |
| return true; |
| } catch (Exception ex) { |
| ClientHelper.showError(this, ex); |
| return false; |
| } finally { |
| setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); |
| } |
| } |
| |
| interface UpdateStatus { |
| enum StatusFlag { |
| DONT_CHANGE, UPDATE, UNSET |
| } |
| |
| void setStatus(StatusFlag status); |
| |
| StatusFlag getStatus(); |
| } |
| |
| interface MultivalueManager { |
| void addNewValue(); |
| |
| void removeValue(int pos); |
| |
| void moveUp(int pos); |
| |
| void moveDown(int pos); |
| } |
| |
| /** |
| * Property input panel. |
| */ |
| public static class PropertyInputPanel extends JPanel implements UpdateStatus, MultivalueManager { |
| private static final long serialVersionUID = 1L; |
| |
| private static final Color BACKGROUND1 = UIManager.getColor("Table:\"Table.cellRenderer\".background"); |
| private static final Color BACKGROUND2 = UIManager.getColor("Table.alternateRowColor"); |
| private static final Color LINE = new Color(0xB8, 0xB8, 0xB8); |
| |
| private final PropertyDefinition<?> propDef; |
| private final Object value; |
| private final Color bgColor; |
| private JComboBox changeBox; |
| private List<JComponent> valueComponents; |
| |
| public PropertyInputPanel(PropertyDefinition<?> propDef, Object value, int position) { |
| super(); |
| this.propDef = propDef; |
| this.value = value; |
| bgColor = (position % 2 == 0 ? BACKGROUND1 : BACKGROUND2); |
| createGUI(); |
| } |
| |
| private void createGUI() { |
| setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS)); |
| |
| setBackground(bgColor); |
| setBorder(BorderFactory.createCompoundBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, LINE), |
| BorderFactory.createEmptyBorder(10, 5, 10, 5))); |
| |
| Font labelFont = UIManager.getFont("Label.font"); |
| Font boldFont = labelFont.deriveFont(Font.BOLD, labelFont.getSize2D() * 1.2f); |
| |
| JPanel titlePanel = new JPanel(); |
| titlePanel.setLayout(new BorderLayout()); |
| titlePanel.setBackground(bgColor); |
| titlePanel.setToolTipText("<html><b>" |
| + propDef.getPropertyType().value() |
| + "</b> (" |
| + propDef.getCardinality().value() |
| + " value)" |
| + (propDef.getDescription() != null ? "<br>" |
| + ClientHelper.encodeHtml(new StringBuilder(), propDef.getDescription()) : "")); |
| add(titlePanel); |
| |
| JPanel namePanel = new JPanel(); |
| namePanel.setLayout(new BoxLayout(namePanel, BoxLayout.Y_AXIS)); |
| namePanel.setBackground(bgColor); |
| JLabel displayNameLabel = new JLabel(propDef.getDisplayName()); |
| displayNameLabel.setFont(boldFont); |
| namePanel.add(displayNameLabel); |
| JLabel idLabel = new JLabel(propDef.getId()); |
| namePanel.add(idLabel); |
| |
| titlePanel.add(namePanel, BorderLayout.LINE_START); |
| |
| changeBox = new JComboBox(new Object[] { "Don't change ", "Update ", "Unset " }); |
| titlePanel.add(changeBox, BorderLayout.LINE_END); |
| |
| valueComponents = new ArrayList<JComponent>(); |
| if (propDef.getCardinality() == Cardinality.SINGLE) { |
| JComponent valueField = createInputField(value); |
| valueComponents.add(valueField); |
| add(valueField); |
| } else { |
| if (value instanceof List<?>) { |
| for (Object v : (List<?>) value) { |
| JComponent valueField = new MultiValuePropertyInputField(createInputField(v), this, bgColor); |
| valueComponents.add(valueField); |
| add(valueField); |
| } |
| } |
| |
| JPanel addPanel = new JPanel(new BorderLayout()); |
| addPanel.setBackground(bgColor); |
| JButton addButton = new JButton(ICON_ADD); |
| addButton.addActionListener(new ActionListener() { |
| @Override |
| public void actionPerformed(ActionEvent e) { |
| addNewValue(); |
| setStatus(StatusFlag.UPDATE); |
| } |
| }); |
| addPanel.add(addButton, BorderLayout.LINE_END); |
| add(addPanel); |
| |
| updatePositions(); |
| } |
| |
| setMaximumSize(new Dimension(Short.MAX_VALUE, getPreferredSize().height)); |
| } |
| |
| private JComponent createInputField(Object value) { |
| switch (propDef.getPropertyType()) { |
| case INTEGER: |
| return new IntegerPropertyInputField(value, this, bgColor); |
| case DECIMAL: |
| return new DecimalPropertyInputField(value, this, bgColor); |
| case DATETIME: |
| return new DateTimePropertyInputField(value, this, bgColor); |
| case BOOLEAN: |
| return new BooleanPropertyInputField(value, this, bgColor); |
| default: |
| return new StringPropertyInputField(value, this, bgColor); |
| } |
| } |
| |
| private void updatePositions() { |
| int n = valueComponents.size(); |
| for (int i = 0; i < n; i++) { |
| MultiValuePropertyInputField comp = (MultiValuePropertyInputField) valueComponents.get(i); |
| comp.updatePosition(i, i + 1 == n); |
| } |
| } |
| |
| public void addNewValue() { |
| JComponent valueField = new MultiValuePropertyInputField(createInputField(null), this, bgColor); |
| valueComponents.add(valueField); |
| add(valueField, getComponentCount() - 1); |
| |
| updatePositions(); |
| setStatus(StatusFlag.UPDATE); |
| |
| revalidate(); |
| } |
| |
| public void removeValue(int pos) { |
| remove(valueComponents.remove(pos)); |
| |
| updatePositions(); |
| setStatus(StatusFlag.UPDATE); |
| |
| revalidate(); |
| } |
| |
| public void moveUp(int pos) { |
| JComponent comp = valueComponents.get(pos); |
| Collections.swap(valueComponents, pos, pos - 1); |
| |
| remove(comp); |
| add(comp, pos); |
| |
| updatePositions(); |
| setStatus(StatusFlag.UPDATE); |
| |
| revalidate(); |
| } |
| |
| public void moveDown(int pos) { |
| JComponent comp = valueComponents.get(pos); |
| Collections.swap(valueComponents, pos, pos + 1); |
| |
| remove(comp); |
| add(comp, pos + 2); |
| |
| updatePositions(); |
| setStatus(StatusFlag.UPDATE); |
| |
| revalidate(); |
| } |
| |
| public String getId() { |
| return propDef.getId(); |
| } |
| |
| public Object getValue() { |
| Object result = null; |
| |
| if (getStatus() == StatusFlag.UPDATE) { |
| try { |
| if (propDef.getCardinality() == Cardinality.SINGLE) { |
| result = ((PropertyValue) valueComponents.get(0)).getPropertyValue(); |
| } else { |
| List<Object> list = new ArrayList<Object>(); |
| for (JComponent comp : valueComponents) { |
| list.add(((PropertyValue) comp).getPropertyValue()); |
| } |
| result = list; |
| } |
| } catch (Exception ex) { |
| ClientHelper.showError(this, ex); |
| } |
| } |
| |
| return result; |
| } |
| |
| public boolean includeInUpdate() { |
| return getStatus() != StatusFlag.DONT_CHANGE; |
| } |
| |
| public void setStatus(StatusFlag status) { |
| switch (status) { |
| case UPDATE: |
| changeBox.setSelectedIndex(1); |
| break; |
| case UNSET: |
| changeBox.setSelectedIndex(2); |
| break; |
| default: |
| changeBox.setSelectedIndex(0); |
| } |
| } |
| |
| public StatusFlag getStatus() { |
| switch (changeBox.getSelectedIndex()) { |
| case 1: |
| return StatusFlag.UPDATE; |
| case 2: |
| return StatusFlag.UNSET; |
| default: |
| return StatusFlag.DONT_CHANGE; |
| } |
| } |
| |
| public Dimension getMaximumSize() { |
| Dimension size = getPreferredSize(); |
| size.width = Short.MAX_VALUE; |
| return size; |
| } |
| } |
| |
| /** |
| * Property value interface. |
| */ |
| public interface PropertyValue { |
| Object getPropertyValue() throws Exception; |
| } |
| |
| /** |
| * String property. |
| */ |
| public static class StringPropertyInputField extends JTextField implements PropertyValue { |
| private static final long serialVersionUID = 1L; |
| |
| public StringPropertyInputField(final Object value, final UpdateStatus status, final Color bgColor) { |
| super(value == null ? "" : value.toString()); |
| |
| addKeyListener(new KeyListener() { |
| @Override |
| public void keyTyped(KeyEvent e) { |
| } |
| |
| @Override |
| public void keyReleased(KeyEvent e) { |
| status.setStatus(StatusFlag.UPDATE); |
| } |
| |
| @Override |
| public void keyPressed(KeyEvent e) { |
| } |
| }); |
| } |
| |
| public Object getPropertyValue() { |
| return getText(); |
| } |
| } |
| |
| /** |
| * Formatted property. |
| */ |
| public static class AbstractFormattedPropertyInputField extends JFormattedTextField implements PropertyValue { |
| private static final long serialVersionUID = 1L; |
| |
| public AbstractFormattedPropertyInputField(final Object value, final Format format, final UpdateStatus status, |
| final Color bgColor) { |
| super(format); |
| if (value != null) { |
| setValue(value); |
| } |
| |
| addKeyListener(new KeyListener() { |
| @Override |
| public void keyTyped(KeyEvent e) { |
| } |
| |
| @Override |
| public void keyReleased(KeyEvent e) { |
| status.setStatus(StatusFlag.UPDATE); |
| } |
| |
| @Override |
| public void keyPressed(KeyEvent e) { |
| } |
| }); |
| } |
| |
| public Object getPropertyValue() throws ParseException { |
| commitEdit(); |
| return getValue(); |
| } |
| } |
| |
| /** |
| * Integer property. |
| */ |
| public static class IntegerPropertyInputField extends AbstractFormattedPropertyInputField { |
| private static final long serialVersionUID = 1L; |
| |
| public IntegerPropertyInputField(final Object value, final UpdateStatus status, final Color bgColor) { |
| super(value, createFormat(), status, bgColor); |
| setHorizontalAlignment(JTextField.RIGHT); |
| } |
| |
| private static DecimalFormat createFormat() { |
| DecimalFormat result = new DecimalFormat("#,##0"); |
| result.setParseBigDecimal(true); |
| result.setParseIntegerOnly(true); |
| return result; |
| } |
| |
| public Object getPropertyValue() { |
| return ((BigDecimal) super.getValue()).toBigIntegerExact(); |
| } |
| } |
| |
| /** |
| * Decimal property. |
| */ |
| public static class DecimalPropertyInputField extends AbstractFormattedPropertyInputField { |
| private static final long serialVersionUID = 1L; |
| |
| public DecimalPropertyInputField(final Object value, final UpdateStatus status, final Color bgColor) { |
| super(value, createFormat(), status, bgColor); |
| setHorizontalAlignment(JTextField.RIGHT); |
| } |
| |
| private static DecimalFormat createFormat() { |
| DecimalFormat result = new DecimalFormat("#,##0.#############################"); |
| result.setParseBigDecimal(true); |
| return result; |
| } |
| } |
| |
| /** |
| * Boolean property. |
| */ |
| public static class BooleanPropertyInputField extends JComboBox implements PropertyValue { |
| private static final long serialVersionUID = 1L; |
| |
| public BooleanPropertyInputField(final Object value, final UpdateStatus status, final Color bgColor) { |
| super(new Object[] { true, false }); |
| setSelectedItem(value == null ? true : value); |
| |
| addActionListener(new ActionListener() { |
| @Override |
| public void actionPerformed(ActionEvent e) { |
| status.setStatus(StatusFlag.UPDATE); |
| } |
| }); |
| } |
| |
| public Object getPropertyValue() { |
| return getSelectedItem(); |
| } |
| } |
| |
| /** |
| * DateTime property. |
| */ |
| public static class DateTimePropertyInputField extends JPanel implements PropertyValue { |
| private static final long serialVersionUID = 1L; |
| |
| private static final String[] MONTH_STRINGS; |
| |
| static { |
| String[] months = new java.text.DateFormatSymbols().getMonths(); |
| int lastIndex = months.length - 1; |
| |
| if (months[lastIndex] == null || months[lastIndex].length() <= 0) { |
| String[] monthStrings = new String[lastIndex]; |
| System.arraycopy(months, 0, monthStrings, 0, lastIndex); |
| MONTH_STRINGS = monthStrings; |
| } else { |
| MONTH_STRINGS = months; |
| } |
| } |
| |
| private final SpinnerNumberModel day; |
| private final SpinnerListModel month; |
| private final SpinnerNumberModel year; |
| private final SpinnerNumberModel hour; |
| private final SpinnerNumberModel min; |
| private final SpinnerNumberModel sec; |
| private final TimeZone timezone; |
| |
| public DateTimePropertyInputField(final Object value, final UpdateStatus status, final Color bgColor) { |
| setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0)); |
| setBackground(bgColor); |
| |
| GregorianCalendar cal = (value == null ? new GregorianCalendar() : (GregorianCalendar) value); |
| timezone = cal.getTimeZone(); |
| |
| day = new SpinnerNumberModel(cal.get(Calendar.DATE), 1, 31, 1); |
| addSpinner(new JSpinner(day), status); |
| |
| month = new SpinnerListModel(MONTH_STRINGS); |
| month.setValue(MONTH_STRINGS[cal.get(Calendar.MONTH)]); |
| JSpinner monthSpinner = new JSpinner(month); |
| JComponent editor = monthSpinner.getEditor(); |
| if (editor instanceof JSpinner.DefaultEditor) { |
| JFormattedTextField tf = ((JSpinner.DefaultEditor) editor).getTextField(); |
| tf.setColumns(6); |
| tf.setHorizontalAlignment(JTextField.RIGHT); |
| } |
| addSpinner(monthSpinner, status); |
| |
| year = new SpinnerNumberModel(cal.get(Calendar.YEAR), 0, 9999, 1); |
| JSpinner yearSpinner = new JSpinner(year); |
| yearSpinner.setEditor(new JSpinner.NumberEditor(yearSpinner, "#")); |
| yearSpinner.getEditor().setBackground(bgColor); |
| addSpinner(yearSpinner, status); |
| |
| add(new JLabel(" ")); |
| |
| hour = new SpinnerNumberModel(cal.get(Calendar.HOUR_OF_DAY), 0, 23, 1); |
| JSpinner hourSpinner = new JSpinner(hour); |
| addSpinner(hourSpinner, status); |
| |
| add(new JLabel(":")); |
| |
| min = new SpinnerNumberModel(cal.get(Calendar.MINUTE), 0, 59, 1); |
| JSpinner minSpinner = new JSpinner(min); |
| addSpinner(minSpinner, status); |
| |
| add(new JLabel(":")); |
| |
| sec = new SpinnerNumberModel(cal.get(Calendar.SECOND), 0, 59, 1); |
| JSpinner secSpinner = new JSpinner(sec); |
| addSpinner(secSpinner, status); |
| |
| add(new JLabel(" " + timezone.getDisplayName(true, TimeZone.SHORT))); |
| } |
| |
| private void addSpinner(final JSpinner spinner, final UpdateStatus status) { |
| spinner.addChangeListener(new ChangeListener() { |
| @Override |
| public void stateChanged(ChangeEvent e) { |
| status.setStatus(StatusFlag.UPDATE); |
| } |
| }); |
| |
| add(spinner); |
| } |
| |
| public Object getPropertyValue() { |
| GregorianCalendar result = new GregorianCalendar(); |
| |
| result.setTimeZone(timezone); |
| |
| result.set(Calendar.YEAR, year.getNumber().intValue()); |
| int mi = 0; |
| String ms = month.getValue().toString(); |
| for (int i = 0; i < MONTH_STRINGS.length; i++) { |
| if (MONTH_STRINGS[i].equals(ms)) { |
| mi = i; |
| break; |
| } |
| } |
| result.set(Calendar.MONTH, mi); |
| result.set(Calendar.DATE, day.getNumber().intValue()); |
| result.set(Calendar.HOUR_OF_DAY, hour.getNumber().intValue()); |
| result.set(Calendar.MINUTE, min.getNumber().intValue()); |
| result.set(Calendar.SECOND, sec.getNumber().intValue()); |
| |
| return result; |
| } |
| } |
| |
| /** |
| * Multi value property. |
| */ |
| public static class MultiValuePropertyInputField extends JPanel implements PropertyValue { |
| private static final long serialVersionUID = 1L; |
| |
| private static final ImageIcon ICON_UP = ClientHelper.getIcon("up.png"); |
| private static final ImageIcon ICON_DOWN = ClientHelper.getIcon("down.png"); |
| private static final ImageIcon ICON_REMOVE = ClientHelper.getIcon("remove.png"); |
| |
| private final JComponent component; |
| private int position; |
| |
| private JButton upButton; |
| private JButton downButton; |
| |
| public MultiValuePropertyInputField(final JComponent component, final MultivalueManager mutlivalueManager, |
| final Color bgColor) { |
| super(); |
| this.component = component; |
| |
| setLayout(new BorderLayout()); |
| setBackground(bgColor); |
| |
| add(component, BorderLayout.CENTER); |
| |
| JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 0, 0)); |
| buttonPanel.setBackground(bgColor); |
| |
| upButton = new JButton(ICON_UP); |
| upButton.addActionListener(new ActionListener() { |
| @Override |
| public void actionPerformed(ActionEvent e) { |
| mutlivalueManager.moveUp(MultiValuePropertyInputField.this.position); |
| } |
| }); |
| buttonPanel.add(upButton); |
| |
| downButton = new JButton(ICON_DOWN); |
| downButton.addActionListener(new ActionListener() { |
| @Override |
| public void actionPerformed(ActionEvent e) { |
| mutlivalueManager.moveDown(MultiValuePropertyInputField.this.position); |
| } |
| }); |
| buttonPanel.add(downButton); |
| |
| JButton removeButton = new JButton(ICON_REMOVE); |
| removeButton.addActionListener(new ActionListener() { |
| @Override |
| public void actionPerformed(ActionEvent e) { |
| mutlivalueManager.removeValue(MultiValuePropertyInputField.this.position); |
| } |
| }); |
| buttonPanel.add(removeButton); |
| |
| add(buttonPanel, BorderLayout.LINE_END); |
| } |
| |
| private void updatePosition(int position, boolean isLast) { |
| this.position = position; |
| upButton.setEnabled(position > 0); |
| downButton.setEnabled(!isLast); |
| } |
| |
| public Object getPropertyValue() throws Exception { |
| return ((PropertyValue) component).getPropertyValue(); |
| } |
| } |
| } |