xy.reflect.ui.control.swing.editor.AbstractEditorWindowBuilder Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (C) 2018 OTK Software
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* The GNU General Public License allows you also to freely redistribute
* the libraries under the same license, if you provide the terms of the
* GNU General Public License with them and add the following
* copyright notice at the appropriate place (with a link to
* http://javacollection.net/reflectionui/ web site when possible).
******************************************************************************/
package xy.reflect.ui.control.swing.editor;
import java.awt.Component;
import java.awt.Image;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import xy.reflect.ui.ReflectionUI;
import xy.reflect.ui.control.swing.DialogBuilder;
import xy.reflect.ui.control.swing.renderer.Form;
import xy.reflect.ui.control.swing.renderer.WindowManager;
import xy.reflect.ui.info.ValueReturnMode;
import xy.reflect.ui.info.app.IApplicationInfo;
import xy.reflect.ui.info.type.ITypeInfo;
import xy.reflect.ui.undo.IModification;
import xy.reflect.ui.undo.ModificationStack;
import xy.reflect.ui.util.Accessor;
import xy.reflect.ui.util.ReflectionUIUtils;
import xy.reflect.ui.util.SwingRendererUtils;
/**
* This is a base class for editor window factories.
*
* @author olitank
*
*/
public abstract class AbstractEditorWindowBuilder extends AbstractEditorFormBuilder {
protected DialogBuilder dialogBuilder;
protected Form createdEditorForm;
protected JFrame createdFrame;
protected boolean parentModificationStackImpacted = false;
/**
* @return the owner component of the editor dialog or null.
*/
public abstract Component getOwnerComponent();
/**
* @return whether the editing session should be cancellable (a cancel button
* will be displayed) or not. Note that it only makes sense if a editor
* dialog (not a frame) is created.
*/
public boolean isCancellable() {
Object encapsualted = getCapsule();
ITypeInfo encapsulatedObjectType = getSwingRenderer().getReflectionUI()
.getTypeInfo(getSwingRenderer().getReflectionUI().getTypeInfoSource(encapsualted));
return encapsulatedObjectType.isModificationStackAccessible();
}
/**
* @return the title of the editor window.
*/
public String getEditorWindowTitle() {
Object encapsulatedObject = getCapsule();
ITypeInfo encapsulatedObjectType = getSwingRenderer().getReflectionUI()
.getTypeInfo(getSwingRenderer().getReflectionUI().getTypeInfoSource(encapsulatedObject));
return encapsulatedObjectType.getCaption();
}
/**
* @return the icon image of the editor window.
*/
public Image getEditorWindowIconImage() {
ensureIsInitialized();
Image result = getSwingRenderer().getObjectIconImage(initialObjectValue);
if (result == null) {
ReflectionUI reflectionUI = getSwingRenderer().getReflectionUI();
IApplicationInfo appInfo = reflectionUI.getApplicationInfo();
if (appInfo.getIconImagePath() != null) {
result = SwingRendererUtils.loadImageThroughcache(appInfo.getIconImagePath(),
ReflectionUIUtils.getErrorLogListener(reflectionUI));
}
}
return result;
}
/**
* @return the text of the 'Cancel' button.
*/
public String getCancelCaption() {
return "Cancel";
}
/**
* @return the text of the 'OK' button.
*/
public String getOKCaption() {
return "OK";
}
/**
* @return the text of the 'Close' button.
*/
public String getCloseCaption() {
return "Close";
}
/**
* @return additional controls that will be laid on the button bar.
*/
public List getAdditionalButtonBarControls() {
return Collections.emptyList();
}
/**
* @return common controls that will be laid on the button bar.
*/
protected List createCommonButtonBarControls() {
List result = new ArrayList();
List commonButtonBarControls = createdEditorForm.createButtonBarControls();
if (commonButtonBarControls != null) {
result.addAll(commonButtonBarControls);
}
List additionalButtonBarComponents = getAdditionalButtonBarControls();
if (additionalButtonBarComponents != null) {
result.addAll(additionalButtonBarComponents);
}
return result;
}
/**
* Creates and returns the editor frame.
*
* @return the created editor frame.
*/
public JFrame createFrame() {
createdEditorForm = createEditorForm(false, false);
createdFrame = new JFrame();
WindowManager windowManager = getSwingRenderer().createWindowManager(createdFrame);
windowManager.set(createdEditorForm, new Accessor>() {
@Override
public List get() {
return new ArrayList(createCommonButtonBarControls());
}
}, getEditorWindowTitle(), getEditorWindowIconImage());
createdFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
return createdFrame;
}
/**
* @return the created editor frame.
*/
public JFrame getCreatedFrame() {
return createdFrame;
}
/**
* Creates and shows the editor frame.
*/
public void createAndShowFrame() {
getSwingRenderer().showFrame(createFrame());
}
/**
* @return the dialog builder used to build the editor dialog.
*/
protected DialogBuilder createDelegateDialogBuilder() {
return getSwingRenderer().getDialogBuilder(getOwnerComponent());
}
/**
* Creates and returns the editor dialog.
*
* @return the created editor dialog.
*/
public JDialog createDialog() {
createdEditorForm = createEditorForm(false, false);
dialogBuilder = createDelegateDialogBuilder();
dialogBuilder.setContentComponent(createdEditorForm);
dialogBuilder.setTitle(getEditorWindowTitle());
dialogBuilder.setIconImage(getEditorWindowIconImage());
dialogBuilder.setButtonBarControlsAccessor(new Accessor>() {
@Override
public List get() {
List buttonBarControls = new ArrayList(createCommonButtonBarControls());
if (isCancellable()) {
List okCancelButtons = dialogBuilder.createStandardOKCancelDialogButtons(getOKCaption(),
getCancelCaption());
buttonBarControls.addAll(okCancelButtons);
} else {
buttonBarControls.add(dialogBuilder.createDialogClosingButton(getCloseCaption(), null));
}
return buttonBarControls;
}
});
return dialogBuilder.createDialog();
}
/**
* @return the created editor dialog.
*/
public JDialog getCreatedDialog() {
if (dialogBuilder == null) {
return null;
}
return dialogBuilder.getCreatedDialog();
}
/**
* Creates and shows the editor dialog.
*/
public void createAndShowDialog() {
getSwingRenderer().showDialog(createDialog(), true);
getSwingRenderer().showBusyDialogWhile(getOwnerComponent(), new Runnable() {
@Override
public void run() {
if (hasParentObject()) {
if (canPotentiallyModifyParentObject()) {
impactParent();
}
} else {
if (isCancelled()) {
ModificationStack modifStack = getModificationStack();
modifStack.undoAll();
if (modifStack.wasInvalidated()) {
getSwingRenderer().getReflectionUI().logDebug(
"WARNING: Cannot undo completely invalidated modification stack: " + modifStack);
}
}
}
}
}, getParentModificationTitle());
}
/**
* @return the created editor form.
*/
public Form getCreatedEditorForm() {
return createdEditorForm;
}
/**
* Update the parent object and its modification stack according to the target
* value/object modifications and the current editor builder specifications.
*/
public void impactParent() {
ModificationStack parentObjectModifStack = getParentModificationStack();
if (parentObjectModifStack == null) {
return;
}
ModificationStack valueModifStack = getModificationStack();
ValueReturnMode valueReturnMode = getReturnModeFromParent();
Object currentValue = getCurrentValue();
boolean valueReplaced = isValueReplaced();
IModification commitModif;
if (!canCommitToParent()) {
commitModif = null;
} else {
commitModif = createParentCommitModification(currentValue);
}
boolean valueModifAccepted = shouldAcceptNewObjectValue(currentValue) && ((!isCancellable()) || !isCancelled());
String editSessionTitle = getParentModificationTitle();
parentModificationStackImpacted = ReflectionUIUtils.finalizeSeparateObjectValueEditSession(
parentObjectModifStack, valueModifStack, valueModifAccepted, valueReturnMode, valueReplaced,
commitModif, editSessionTitle,
ReflectionUIUtils.getDebugLogListener(getSwingRenderer().getReflectionUI()));
}
/**
* @return whether the user cancelled the editor dialog.
*/
public boolean isCancelled() {
if (dialogBuilder == null) {
return false;
}
return !dialogBuilder.wasOkPressed();
}
/**
* @return the modification stack of the target value/object.
*/
public ModificationStack getModificationStack() {
if (createdEditorForm == null) {
return null;
}
return createdEditorForm.getModificationStack();
}
/**
* @return whether a potential modification of the parent object is detected.
*/
public boolean isParentModificationStackImpacted() {
return parentModificationStackImpacted;
}
}