package com.revolsys.swing.component; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.Dialog.ModalityType; import java.awt.FlowLayout; import java.awt.Image; import java.awt.LayoutManager; import java.awt.Window; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import javax.swing.ActionMap; import javax.swing.InputMap; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JPanel; import javax.swing.JRootPane; import javax.swing.KeyStroke; import javax.swing.SwingUtilities; import javax.swing.WindowConstants; import org.jdesktop.swingx.VerticalLayout; import com.revolsys.swing.Icons; import com.revolsys.swing.SwingUtil; import com.revolsys.swing.action.RunnableAction; import com.revolsys.swing.field.Field; import com.revolsys.swing.field.FieldSupport; import com.revolsys.swing.undo.UndoManager; import com.revolsys.util.CaseConverter; import com.revolsys.util.Exceptions; public class ValueField extends JPanel implements Field { private static final long serialVersionUID = 1L; private boolean saved = false; private final FieldSupport fieldSupport; private String title; private Runnable saveAction = null; private Runnable cancelAction = null; private Image iconImage; public ValueField() { this("fieldValue", null); } public ValueField(final LayoutManager layout) { this(layout, null, null); setOpaque(false); } public ValueField(final LayoutManager layout, final String fieldName, final Object fieldValue) { super(layout, true); setOpaque(false); this.fieldSupport = new FieldSupport(this, fieldName, fieldValue, true); setTitle(CaseConverter.toCapitalizedWords(fieldName)); } public ValueField(final Object fieldValue) { this(null, fieldValue); } public ValueField(final String fieldName, final Object fieldValue) { this(new VerticalLayout(), fieldName, fieldValue); } public final void cancel() { cancelDo(); this.saved = false; } public void cancel(final JDialog dialog) { cancel(); SwingUtil.setVisible(dialog, false); } protected void cancelDo() { if (this.cancelAction != null) { this.cancelAction.run(); } } @Override public Field clone() { try { return (Field)super.clone(); } catch (final CloneNotSupportedException e) { return Exceptions.throwUncheckedException(e); } } @Override public void firePropertyChange(final String propertyName, final Object oldValue, final Object newValue) { super.firePropertyChange(propertyName, oldValue, newValue); } @Override public FieldSupport getFieldSupport() { return this.fieldSupport; } public String getTitle() { return this.title; } public boolean isSaved() { return this.saved; } public void save() { save(this); saveDo(); } private void save(final Container container) { final Component[] components = container.getComponents(); for (final Component component : components) { if (component instanceof ValueField) { final ValueField valuePanel = (ValueField)component; valuePanel.save(); } else if (component instanceof Field) { final Field field = (Field)component; field.updateFieldValue(); } else if (component instanceof Container) { final Container childContainer = (Container)component; save(childContainer); } } this.saved = true; } public void save(final JDialog dialog) { save(); dialog.setVisible(false); } protected void saveDo() { if (this.saveAction != null) { this.saveAction.run(); } } public void setCancelAction(final Runnable cancelAction) { this.cancelAction = cancelAction; } protected void setColor(final Color foregroundColor, final Color backgroundColor) { setForeground(foregroundColor); setBackground(backgroundColor); } @Override public void setEditable(final boolean editable) { setEnabled(editable); } @Override public void setFieldToolTip(final String toolTip) { setToolTipText(toolTip); } public void setIconImage(final Image icon) { this.iconImage = icon; } public void setIconImage(final String iconName) { this.iconImage = Icons.getImage(iconName); } public void setSaveAction(final Runnable saveAction) { this.saveAction = saveAction; } public void setTitle(final String title) { this.title = title; } @Override public void setToolTipText(final String text) { if (this.fieldSupport == null || this.fieldSupport.setOriginalTooltipText(text)) { super.setToolTipText(text); } } @Override public void setUndoManager(final UndoManager undoManager) { } @SuppressWarnings("unchecked") public <V> V showDialog() { return (V)showDialog(null); } @SuppressWarnings("unchecked") public <V> V showDialog(final Component parent) { Window window; if (parent == null) { window = SwingUtil.getActiveWindow(); } else if (parent instanceof Window) { window = (Window)parent; } else { window = SwingUtilities.windowForComponent(parent); } final JDialog dialog = new JDialog(window, this.title, ModalityType.APPLICATION_MODAL); if (this.iconImage != null) { dialog.setIconImage(this.iconImage); } dialog.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE); dialog.setLayout(new BorderLayout()); dialog.addKeyListener(new KeyListener() { @Override public void keyPressed(final KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { cancel(dialog); } else if (e.getKeyCode() == KeyEvent.VK_ENTER) { save(dialog); } } @Override public void keyReleased(final KeyEvent e) { } @Override public void keyTyped(final KeyEvent e) { } }); dialog.add(this, BorderLayout.CENTER); final JRootPane rootPane = dialog.getRootPane(); final InputMap inputMap = rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); final ActionMap actionMap = rootPane.getActionMap(); final JPanel buttons = new JPanel(new FlowLayout(FlowLayout.RIGHT)); final Runnable cancelRunnable = () -> cancel(dialog); buttons.add(RunnableAction.newButton("Cancel", cancelRunnable)); final KeyStroke escapeStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0); inputMap.put(escapeStroke, "cancel"); actionMap.put("cancel", new RunnableAction(cancelRunnable)); final Runnable saveRunnable = () -> save(dialog); buttons.add(RunnableAction.newButton("OK", saveRunnable)); dialog.add(buttons, BorderLayout.SOUTH); final KeyStroke enterStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0); inputMap.put(enterStroke, "save"); actionMap.put("save", new RunnableAction(saveRunnable)); dialog.pack(); SwingUtil.autoAdjustPosition(dialog); this.saved = false; dialog.setVisible(true); final V value = (V)getFieldValue(); SwingUtil.dispose(dialog); return value; } @Override public String toString() { return getFieldName() + "=" + getFieldValue(); } @Override public void updateFieldValue() { } }