public abstract class ALcyDomainObjectCustomizerPanel extends ALcyCustomizerPanel
Abstract class that facilitates the implementation of ILcyCustomizerPanel
for domain
objects. This class can only be used to edit instances of TLcyDomainObjectContext
.
This class adds listeners to the model and the layer so that when the set domain object
changes or when the editable property of the layer changes,
updateCustomizerPanelFromObject(boolean)
is called. Furthermore it adds several
convenience methods to easily retrieve the domain object and its model, layer and view.
It is however up to the extension of this class to ensure that:
applyChangesImpl()
method
updateCustomizerPanelFromObject(boolean)
method.
JPanel.AccessibleJPanel
JComponent.AccessibleJComponent
Container.AccessibleAWTContainer
Component.AccessibleAWTComponent, Component.BaselineResizeBehavior, Component.BltBufferStrategy, Component.FlipBufferStrategy
listenerList, TOOL_TIP_TEXT_KEY, ui, UNDEFINED_CONDITION, WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, WHEN_FOCUSED, WHEN_IN_FOCUSED_WINDOW
accessibleContext, BOTTOM_ALIGNMENT, CENTER_ALIGNMENT, LEFT_ALIGNMENT, RIGHT_ALIGNMENT, TOP_ALIGNMENT
HINT_PINNED, HORIZONTAL_ALIGNMENT_HINT, LONG_DESCRIPTION, NAME, SHORT_DESCRIPTION, SMALL_ICON
ABORT, ALLBITS, ERROR, FRAMEBITS, HEIGHT, PROPERTIES, SOMEBITS, WIDTH
Modifier | Constructor and Description |
---|---|
protected |
ALcyDomainObjectCustomizerPanel(ILcdFilter aDomainObjectContextFilter,
String aName)
Create a new
ALcyDomainObjectCustomizerPanel instance |
Modifier and Type | Method and Description |
---|---|
boolean |
applyChanges()
Updates the set
Object according to the current state of the user interface. |
protected abstract boolean |
applyChangesImpl()
Apply any pending changes.
|
boolean |
canSetObject(Object aObject)
Returns
true if and only if setObject would not throw an
IllegalArgumentException . |
protected Object |
getDomainObject()
Convenience method to return the domain object (e.g. polyline) that was set by setting
a
TLcyDomainObjectContext using setObject . |
protected TLcyDomainObjectContext |
getDomainObjectContext()
Returns the
TLcyDomainObjectContext object that was set on this customizer. |
protected ILcdLayer |
getLayer()
Convenience method to return the
ILcdLayer that was set by setting
a TLcyDomainObjectContext using setObject . |
protected ILcdModel |
getModel()
Convenience method to return the
ILcdModel that was set by setting
a TLcyDomainObjectContext using setObject . |
protected ILcdView |
getView()
Convenience method to return the
ILcdView that was set by setting
a TLcyDomainObjectContext using setObject . |
protected boolean |
isPanelEditable()
Returns whether the panel is editable or not.
|
void |
setObject(Object aObject)
Set the object to be edited.
|
protected void |
updateCustomizerPanelFromObject()
Calls
updateCustomizerPanelFromObject( isPanelEditable() ) . |
protected abstract void |
updateCustomizerPanelFromObject(boolean aPanelEditable)
This means updating the user interface state according to the current state of the set
Object . |
addUndoableListener, cancelChanges, fireUndoableHappened, getObject, getObjectFilter, getValue, isChangesPending, isChangesValid, putValue, removeUndoableListener, setChangesPending, setChangesValid, setName, setObjectFilter
getAccessibleContext, getUI, getUIClassID, paramString, setUI, updateUI
addAncestorListener, addNotify, addVetoableChangeListener, computeVisibleRect, contains, createToolTip, disable, enable, firePropertyChange, firePropertyChange, firePropertyChange, fireVetoableChange, getActionForKeyStroke, getActionMap, getAlignmentX, getAlignmentY, getAncestorListeners, getAutoscrolls, getBaseline, getBaselineResizeBehavior, getBorder, getBounds, getClientProperty, getComponentGraphics, getComponentPopupMenu, getConditionForKeyStroke, getDebugGraphicsOptions, getDefaultLocale, getFontMetrics, getGraphics, getHeight, getInheritsPopupMenu, getInputMap, getInputMap, getInputVerifier, getInsets, getInsets, getListeners, getLocation, getMaximumSize, getMinimumSize, getNextFocusableComponent, getPopupLocation, getPreferredSize, getRegisteredKeyStrokes, getRootPane, getSize, getToolTipLocation, getToolTipText, getToolTipText, getTopLevelAncestor, getTransferHandler, getVerifyInputWhenFocusTarget, getVetoableChangeListeners, getVisibleRect, getWidth, getX, getY, grabFocus, hide, isDoubleBuffered, isLightweightComponent, isManagingFocus, isOpaque, isOptimizedDrawingEnabled, isPaintingForPrint, isPaintingOrigin, isPaintingTile, isRequestFocusEnabled, isValidateRoot, paint, paintBorder, paintChildren, paintComponent, paintImmediately, paintImmediately, print, printAll, printBorder, printChildren, printComponent, processComponentKeyEvent, processKeyBinding, processKeyEvent, processMouseEvent, processMouseMotionEvent, putClientProperty, registerKeyboardAction, registerKeyboardAction, removeAncestorListener, removeNotify, removeVetoableChangeListener, repaint, repaint, requestDefaultFocus, requestFocus, requestFocus, requestFocusInWindow, requestFocusInWindow, resetKeyboardActions, reshape, revalidate, scrollRectToVisible, setActionMap, setAlignmentX, setAlignmentY, setAutoscrolls, setBackground, setBorder, setComponentPopupMenu, setDebugGraphicsOptions, setDefaultLocale, setDoubleBuffered, setEnabled, setFocusTraversalKeys, setFont, setForeground, setInheritsPopupMenu, setInputMap, setInputVerifier, setMaximumSize, setMinimumSize, setNextFocusableComponent, setOpaque, setPreferredSize, setRequestFocusEnabled, setToolTipText, setTransferHandler, setUI, setVerifyInputWhenFocusTarget, setVisible, unregisterKeyboardAction, update
add, add, add, add, add, addContainerListener, addImpl, addPropertyChangeListener, addPropertyChangeListener, applyComponentOrientation, areFocusTraversalKeysSet, countComponents, deliverEvent, doLayout, findComponentAt, findComponentAt, getComponent, getComponentAt, getComponentAt, getComponentCount, getComponents, getComponentZOrder, getContainerListeners, getFocusTraversalKeys, getFocusTraversalPolicy, getLayout, getMousePosition, insets, invalidate, isAncestorOf, isFocusCycleRoot, isFocusCycleRoot, isFocusTraversalPolicyProvider, isFocusTraversalPolicySet, layout, list, list, locate, minimumSize, paintComponents, preferredSize, printComponents, processContainerEvent, processEvent, remove, remove, removeAll, removeContainerListener, setComponentZOrder, setFocusCycleRoot, setFocusTraversalPolicy, setFocusTraversalPolicyProvider, setLayout, transferFocusDownCycle, validate, validateTree
action, add, addComponentListener, addFocusListener, addHierarchyBoundsListener, addHierarchyListener, addInputMethodListener, addKeyListener, addMouseListener, addMouseMotionListener, addMouseWheelListener, bounds, checkImage, checkImage, coalesceEvents, contains, createImage, createImage, createVolatileImage, createVolatileImage, disableEvents, dispatchEvent, enable, enableEvents, enableInputMethods, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, getBackground, getBounds, getColorModel, getComponentListeners, getComponentOrientation, getCursor, getDropTarget, getFocusCycleRootAncestor, getFocusListeners, getFocusTraversalKeysEnabled, getFont, getForeground, getGraphicsConfiguration, getHierarchyBoundsListeners, getHierarchyListeners, getIgnoreRepaint, getInputContext, getInputMethodListeners, getInputMethodRequests, getKeyListeners, getLocale, getLocation, getLocationOnScreen, getMouseListeners, getMouseMotionListeners, getMousePosition, getMouseWheelListeners, getName, getParent, getPeer, getPropertyChangeListeners, getPropertyChangeListeners, getSize, getToolkit, getTreeLock, gotFocus, handleEvent, hasFocus, imageUpdate, inside, isBackgroundSet, isCursorSet, isDisplayable, isEnabled, isFocusable, isFocusOwner, isFocusTraversable, isFontSet, isForegroundSet, isLightweight, isMaximumSizeSet, isMinimumSizeSet, isPreferredSizeSet, isShowing, isValid, isVisible, keyDown, keyUp, list, list, list, location, lostFocus, mouseDown, mouseDrag, mouseEnter, mouseExit, mouseMove, mouseUp, move, nextFocus, paintAll, postEvent, prepareImage, prepareImage, processComponentEvent, processFocusEvent, processHierarchyBoundsEvent, processHierarchyEvent, processInputMethodEvent, processMouseWheelEvent, remove, removeComponentListener, removeFocusListener, removeHierarchyBoundsListener, removeHierarchyListener, removeInputMethodListener, removeKeyListener, removeMouseListener, removeMouseMotionListener, removeMouseWheelListener, removePropertyChangeListener, removePropertyChangeListener, repaint, repaint, repaint, resize, resize, setBounds, setBounds, setComponentOrientation, setCursor, setDropTarget, setFocusable, setFocusTraversalKeysEnabled, setIgnoreRepaint, setLocale, setLocation, setLocation, setSize, setSize, show, show, size, toString, transferFocus, transferFocusBackward, transferFocusUpCycle
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
addPropertyChangeListener, getPropertyChangeListeners, getPropertyChangeListeners, removePropertyChangeListener
addPropertyChangeListener, removePropertyChangeListener
protected ALcyDomainObjectCustomizerPanel(ILcdFilter aDomainObjectContextFilter, String aName)
Create a new ALcyDomainObjectCustomizerPanel
instance
aDomainObjectContextFilter
- The ILcdFilter
that defines which objects are accepted by
canSetObject
and setObject
.
When specified, this filter should only accept TLcyDomainObjectContext
instances.aName
- The name for this ALcyCustomizerPanel
, see ILcyCustomizerPanel.NAME
.public boolean applyChanges()
Object
according to the current state of the user interface. This means
all pending changes are committed.
If there were any pending changes, so isChangesPending
returned true
, it should return
false
after this method has finished, and therefore also a "changesPending"
property
change event must be fired.
E.g. consider that a ILcdGXYLayer
object is set and a new label text is entered in a text field. When
this method is called, the new label text should be set to the ILcdGXYLayer
(using
ILcdGXYLayer.setLabel
).
This implementation invokes ALcyCustomizerPanel.applyChangesImpl()
and sets the "changesPending" property.
As a result, the "changesPending" event is fired when needed.
Note: you should never override this method.
Instead, you need to implement the applyChangesImpl()
method.
applyChanges
in interface ILcyCustomizerPanel
applyChanges
in class ALcyCustomizerPanel
True
if the changes were applied or if there were no changes, false
if the
changes could not be applied because they are invalid. In that event, isChangesValid
returns
false
.applyChangesImpl()
protected abstract boolean applyChangesImpl()
Apply any pending changes. This method should do the same as ALcyCustomizerPanel.applyChanges()
, except
that it should not take care of "changesPending".
Note that the implementation of this method needs
ILcdModel.elementChanged(Object, int)
if the domain object is actually adapted
A typical implementation of this method would look like
@Override
protected boolean applyChangesImpl() {
Object domainObject = getDomainObject();
if (domainObject != null) {
ILcdModel model = getModel();
try (TLcdLockUtil.Lock autoUnlock = TLcdLockUtil.writeLock(model)) {
//Thanks to the write lock, it is now safe to update the domain object
updateDomainObject(domainObject);
model.elementChanged(domainObject, ILcdModel.FIRE_LATER);
} finally {
model.fireCollectedModelChanges();
}
}
return true;
}
applyChangesImpl
in class ALcyCustomizerPanel
ALcyCustomizerPanel.applyChanges()
for more detailed information.protected ILcdView getView()
ILcdView
that was set by setting
a TLcyDomainObjectContext
using setObject
.TLcyDomainObjectContext
is set, the ILcdView
related to that
context object otherwise.protected ILcdLayer getLayer()
ILcdLayer
that was set by setting
a TLcyDomainObjectContext
using setObject
.TLcyDomainObjectContext
is set, the ILcdLayer
related to that
context object otherwise.protected ILcdModel getModel()
ILcdModel
that was set by setting
a TLcyDomainObjectContext
using setObject
.TLcyDomainObjectContext
is set, the ILcdModel
related to that
context object otherwise.protected Object getDomainObject()
TLcyDomainObjectContext
using setObject
.TLcyDomainObjectContext
object is set, the domain object (e.g., polyline) related to that
context object otherwise.public boolean canSetObject(Object aObject)
ALcyCustomizerPanel
true
if and only if setObject
would not throw an
IllegalArgumentException
.
Only accepts null
or objects that pass the object filter. If the
filter itself is null
, all objects are accepted.canSetObject
in interface ILcyCustomizerPanel
canSetObject
in class ALcyCustomizerPanel
aObject
- The object to check.true
if setObject
would accept the object, false
if it would throw an exception.public void setObject(Object aObject)
ILcyCustomizerPanel
has been
added to any parent AWT container. It can be called afterwards as well however. In this case the user interface
should update itself to represent the newly set object.
A value of null
is set to inform this ILcyCustomizerPanel
to (temporarily) deinitialize
itself, it allows to perform cleanup tasks, such as removing listeners.
Invokes ALcyCustomizerPanel.updateCustomizerPanelFromObject()
to update the user interface.
Also adds a ILcdModelListener
to the model of the set TLcyDomainObjectContext
that calls updateCustomizerPanelFromObject
whenever the set domain object
changes in that model, as well as a PropertyChangeListener
to the layer
of the set TLcyDomainObjectContext
that does the same when the "editable"
property of the layer changes.
setObject
in interface ILcyCustomizerPanel
setObject
in class ALcyCustomizerPanel
aObject
- The object to be customized, or null
to inform that editing is temporarily disabled.protected final TLcyDomainObjectContext getDomainObjectContext()
Returns the TLcyDomainObjectContext
object that was set on this customizer. This
context object can be used to retrieve the domain object and the model, layer and view in which
it is contained.
TLcyDomainObjectContext
. This object can be null
when this customizer was deinitialized (with setObject(null)
).protected void updateCustomizerPanelFromObject()
Calls updateCustomizerPanelFromObject( isPanelEditable() )
.
Updates the user interface state according to the current state of the set
Object
. This method is called whenever a new object is set using
setObject
, or when the changes are canceled using cancelChanges
.
It does not need to take care of "changesPending"
.
Consider for example that a TLcyLayerContext
is set and a new label
text is entered in a text field. When this method is called, the new label text should be
cleared and the original label of the ILcdLayer
(getLabel()
)
should be put in the text field.
Note: you should never override this method.
Instead, you need to implement the applyChangesImpl()
method.
updateCustomizerPanelFromObject
in class ALcyCustomizerPanel
protected abstract void updateCustomizerPanelFromObject(boolean aPanelEditable)
This means updating the user interface state according to the current state of the set
Object
. This method is called whenever a new object is set using
setObject
, or when the changes are canceled using cancelChanges
.
It does not need to take care of "changesPending"
.
Consider for example that a TLcyLayerContext
is set and a new label text is entered in a text field.
When this method is called, the new label text should be cleared and the original label of the ILcdLayer
(getLabel()
) should be put in the text field.
Note that the implementation of this method needs to take a read lock on the model before querying the domain object.
A typical implementation of this method would look like
@Override
protected void updateCustomizerPanelFromObject(boolean aPanelEditable){
updateEditableState( aPanelEditable );
Object domainObject = getDomainObject();
if ( domainObject != null ){
ILcdModel model = getModel();
try( TLcdLockUtil.Lock autoUnlock = TLcdLockUtil.readLock(model) ){
//thanks to the read lock, the domain object can now safely be queried
updateUI( domainObject );
}
}
}
aPanelEditable
- true
if the panel should be editable, false
otherwise.
See isPanelEditable()
for more information.protected boolean isPanelEditable()
getLayer().isEditableSupported() && getLayer().isEditable()
or true
if getLayer()
is null
.
Override this method to redefine when the panel is editable or not.True
if the panel should be editable, false
otherwise.