/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.eas.client.forms;
import com.bearsoft.gui.grid.header.GridColumnsNode;
import com.bearsoft.gui.grid.header.MultiLevelHeader;
import com.eas.client.forms.components.Button;
import com.eas.client.forms.components.CheckBox;
import com.eas.client.forms.components.DesktopPane;
import com.eas.client.forms.components.DropDownButton;
import com.eas.client.forms.components.FormattedField;
import com.eas.client.forms.components.HtmlArea;
import com.eas.client.forms.components.Label;
import com.eas.client.forms.components.PasswordField;
import com.eas.client.forms.components.ProgressBar;
import com.eas.client.forms.components.RadioButton;
import com.eas.client.forms.components.Slider;
import com.eas.client.forms.components.TextArea;
import com.eas.client.forms.components.TextField;
import com.eas.client.forms.components.ToggleButton;
import com.eas.client.forms.components.model.ModelCheckBox;
import com.eas.client.forms.components.model.ModelCombo;
import com.eas.client.forms.components.model.ModelDate;
import com.eas.client.forms.components.model.ModelFormattedField;
import com.eas.client.forms.components.model.ModelSpin;
import com.eas.client.forms.components.model.ModelTextArea;
import com.eas.client.forms.components.model.ModelWidget;
import com.eas.client.forms.components.model.grid.ModelGrid;
import com.eas.client.forms.components.model.grid.columns.ModelColumn;
import com.eas.client.forms.components.model.grid.header.CheckGridColumn;
import com.eas.client.forms.components.model.grid.header.ModelGridColumn;
import com.eas.client.forms.components.model.grid.header.RadioGridColumn;
import com.eas.client.forms.components.model.grid.header.ServiceGridColumn;
import com.eas.client.forms.components.rt.HasEditable;
import com.eas.client.forms.components.rt.HasEmptyText;
import com.eas.client.forms.components.rt.HasGroup;
import com.eas.client.forms.components.rt.VFormattedField;
import com.eas.client.forms.containers.AnchorsPane;
import com.eas.client.forms.containers.BorderPane;
import com.eas.client.forms.containers.BoxPane;
import com.eas.client.forms.containers.ButtonGroup;
import com.eas.client.forms.containers.CardPane;
import com.eas.client.forms.containers.FlowPane;
import com.eas.client.forms.containers.GridPane;
import com.eas.client.forms.containers.ScrollPane;
import com.eas.client.forms.containers.SplitPane;
import com.eas.client.forms.containers.TabbedPane;
import com.eas.client.forms.containers.ToolBar;
import com.eas.client.forms.layouts.BoxLayout;
import com.eas.client.forms.layouts.CardLayout;
import com.eas.client.forms.layouts.Margin;
import com.eas.client.forms.layouts.MarginConstraints;
import com.eas.client.forms.layouts.MarginLayout;
import com.eas.client.forms.menu.CheckMenuItem;
import com.eas.client.forms.menu.Menu;
import com.eas.client.forms.menu.MenuBar;
import com.eas.client.forms.menu.MenuItem;
import com.eas.client.forms.menu.MenuSeparator;
import com.eas.client.forms.menu.PopupMenu;
import com.eas.client.forms.menu.RadioMenuItem;
import com.eas.gui.ScriptColor;
import com.eas.script.HasPublished;
import com.eas.script.Scripts;
import com.eas.xml.dom.XmlDomUtils;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.AbstractButton;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import jdk.nashorn.api.scripting.JSObject;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
/**
*
* @author mg
*/
public class FormFactory {
public static final String OLD_FORM_ROOT_CONTAINER_NAME = "Form";
protected Element element;
protected JComponent viewWidget;
protected JSObject model;
protected Form form;
protected Map<String, JComponent> widgets = new HashMap<>();
protected List<JComponent> widgetsList = new ArrayList<>();
protected boolean oldFormat;
protected String rootContainerName;
//
protected List<Consumer<Map<String, JComponent>>> resolvers = new ArrayList<>();
public FormFactory(Element anElement, JSObject aModel) {
super();
element = anElement;
model = aModel;
}
public Map<String, JComponent> getWidgets() {
return widgets;
}
public List<JComponent> getWidgetsList() {
return widgetsList;
}
public Form getForm() throws Exception {
if (form == null) {
form = new Form(viewWidget);
form.setDefaultCloseOperation(readIntegerAttribute(element, "dco", "defaultCloseOperation", JFrame.DISPOSE_ON_CLOSE));
resolveIcon(XmlDomUtils.getAttribute(element, "i", "icon"), (ImageIcon aLoaded) -> {
form.setIcon(aLoaded);
}, (Exception ex) -> {
Logger.getLogger(FormFactory.class.getName()).log(Level.SEVERE, ex.getMessage());
});
form.setTitle(XmlDomUtils.getAttribute(element, "tl", "title"));
form.setClosable(readBooleanAttribute(element, "cle", "closable", Boolean.TRUE));
form.setMaximizable(readBooleanAttribute(element, "mxe", "maximizable", Boolean.TRUE));
form.setMinimizable(readBooleanAttribute(element, "mne", "minimizable", Boolean.TRUE));
form.setResizable(readBooleanAttribute(element, "rs", "resizable", Boolean.TRUE));
form.setUndecorated(readBooleanAttribute(element, "udr", "undecorated", Boolean.FALSE));
form.setOpacity(readFloatAttribute(element, "opc", "opacity", 1.0f));
form.setAlwaysOnTop(readBooleanAttribute(element, "aot", "alwaysOnTop", Boolean.FALSE));
form.setLocationByPlatform(readBooleanAttribute(element, "lbp", "locationByPlatform", Boolean.TRUE));
form.setDesignedViewSize(viewWidget.getPreferredSize());
}
return form;
}
public void parse() throws Exception {
oldFormat = !element.hasAttribute(Form.VIEW_SCRIPT_NAME);
if (oldFormat) {
List<Element> widgetsElements = XmlDomUtils.elementsByTagName(element, "widget", "widget");
List<Element> legacyNonVisualElements = XmlDomUtils.elementsByTagName(element, "nonvisual", "nonvisual");
widgetsElements.addAll(legacyNonVisualElements);
widgetsElements.stream().sequential().forEach((Element aElement) -> {
try {
JComponent widget = readWidget(aElement);
if (widget != null) {
String wName = widget.getName();
assert wName != null && !wName.isEmpty() : "A widget is expected to be a named item.";
widgets.put(wName, widget);
widgetsList.add(widget);
} else {
Logger.getLogger(FormFactory.class.getName()).log(Level.WARNING, "Unknown widget tag name: {0}. skipping.", aElement.getTagName());
}
} catch (Exception ex) {
Logger.getLogger(FormFactory.class.getName()).log(Level.SEVERE, null, ex);
}
});
} else {
rootContainerName = element.getAttribute(Form.VIEW_SCRIPT_NAME);
Node childNode = element.getFirstChild();
while (childNode != null) {
if (childNode instanceof Element) {
JComponent widget = readWidget((Element) childNode);
String wName = widget.getName();
assert wName != null && !wName.isEmpty() : "A widget is expected to be a named item.";
widgets.put(wName, widget);
widgetsList.add(widget);
}
childNode = childNode.getNextSibling();
}
}
if (oldFormat) {
element.setAttribute("type", "PanelDesignInfo");
viewWidget = readWidget(element);
Dimension rootPrefSize = readPrefSize(element);
viewWidget.setName(Form.VIEW_SCRIPT_NAME);
viewWidget.setPreferredSize(rootPrefSize);
} else {
viewWidget = widgets.get(rootContainerName);
}
if (viewWidget == null) {
viewWidget = new AnchorsPane();
viewWidget.setPreferredSize(new Dimension(400, 300));
Logger.getLogger(FormFactory.class.getName()).log(Level.WARNING, "view widget missing. Falling back to AnchrosPane.");
}
viewWidget.setSize(viewWidget.getPreferredSize());
//
resolvers.stream().sequential().forEach((Consumer<Map<String, JComponent>> aResolver) -> {
aResolver.accept(widgets);
});
}
protected Dimension readPrefSize(Element anElement) throws NumberFormatException {
Dimension prefSize = new Dimension();
String prefWidth = XmlDomUtils.getAttribute(anElement, "pw", "prefWidth");
String prefHeight = XmlDomUtils.getAttribute(anElement, "ph", "prefHeight");
if (prefWidth.length() > 2 && prefWidth.endsWith("px")) {
prefSize.width = Integer.parseInt(prefWidth.substring(0, prefWidth.length() - 2));
}
if (prefHeight.length() > 2 && prefHeight.endsWith("px")) {
prefSize.height = Integer.parseInt(prefHeight.substring(0, prefHeight.length() - 2));
}
return prefSize;
}
protected void resolveIcon(String aIconName, Consumer<ImageIcon> onLoad, Consumer<Exception> onFailure) {
if (aIconName != null && !aIconName.isEmpty()) {
Scripts.Space space = Scripts.getSpace();
try {
IconResources.load(aIconName, null, space, onLoad, onFailure);
} catch (Exception ex) {
Logger.getLogger(FormFactory.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
protected JSObject resolveEntity(String aEntityName) throws Exception {
if (model.hasMember(aEntityName)) {
Object oEntity = model.getMember(aEntityName);
if (oEntity instanceof JSObject) {
return (JSObject) oEntity;
}
}
return null;
}
protected JSObject resolveEntity(long aEntityId) throws Exception {
return null;
}
private JComponent readWidget(Element anElement) throws Exception {
String type;
if (oldFormat) {
if (anElement.getTagName().equals("controlInfo")) {
type = anElement.getAttribute("classHint");
} else {
type = anElement.getAttribute("type");
}
if (type == null || type.isEmpty()) {
return null;
}
} else {
type = anElement.getTagName();
}
switch (type) {
// widgets
case "lb":
case "Label":
case "LabelDesignInfo":
Label label = new Label();
readGeneralProps(anElement, label);
if (XmlDomUtils.hasAttribute(anElement, "i", "icon")) {
resolveIcon(XmlDomUtils.getAttribute(anElement, "i", "icon"), (ImageIcon aLoaded) -> {
label.setIcon(aLoaded);
}, (Exception ex) -> {
Logger.getLogger(FormFactory.class.getName()).log(Level.SEVERE, ex.getMessage());
});
}
if (XmlDomUtils.hasAttribute(anElement, "tx", "text")) {
label.setText(XmlDomUtils.getAttribute(anElement, "tx", "text"));
}
label.setHorizontalAlignment(readIntegerAttribute(anElement, "ha", "horizontalAlignment", Label.LEFT));
label.setVerticalAlignment(readIntegerAttribute(anElement, "va", "verticalAlignment", Label.CENTER));
label.setIconTextGap(readIntegerAttribute(anElement, "itg", "iconTextGap", 4));
label.setHorizontalTextPosition(readIntegerAttribute(anElement, "htp", "horizontalTextPosition", Label.RIGHT));
label.setVerticalTextPosition(readIntegerAttribute(anElement, "vtp", "verticalTextPosition", Label.CENTER));
if (XmlDomUtils.hasAttribute(anElement, "lf", "labelFor")) {
String labelForName = XmlDomUtils.getAttribute(anElement, "lf", "labelFor");
resolvers.add((Map<String, JComponent> aWidgets) -> {
if (aWidgets.containsKey(labelForName)) {
label.setLabelFor(aWidgets.get(labelForName));
}
});
}
return label;
case "bt":
case "Button":
case "ButtonDesignInfo":
Button button = new Button();
readGeneralProps(anElement, button);
readButton(anElement, button);
return button;
case "ddb":
case "DropDownButton":
case "DropDownButtonDesignInfo":
DropDownButton dropDownButton = new DropDownButton();
readGeneralProps(anElement, dropDownButton);
readButton(anElement, dropDownButton);
if (XmlDomUtils.hasAttribute(anElement, "ddm", "dropDownMenu")) {
String dropDownMenuName = XmlDomUtils.getAttribute(anElement, "ddm", "dropDownMenu");
resolvers.add((Map<String, JComponent> aWidgets) -> {
if (aWidgets.containsKey(dropDownMenuName)) {
JComponent compMenu = aWidgets.get(dropDownMenuName);
if (compMenu instanceof PopupMenu) {
dropDownButton.setDropDownMenu((PopupMenu) compMenu);
}
}
});
}
return dropDownButton;
case "bg":
case "ButtonGroup":
case "ButtonGroupDesignInfo":
ButtonGroup buttonGroup = new ButtonGroup();
if (XmlDomUtils.hasAttribute(anElement, "n", "name")) {
buttonGroup.setName(XmlDomUtils.getAttribute(anElement, "n", "name"));
}
return buttonGroup;
case "cb":
case "CheckBox":
case "CheckDesignInfo":
CheckBox checkBox = new CheckBox();
readGeneralProps(anElement, checkBox);
readButton(anElement, checkBox);
if (XmlDomUtils.hasAttribute(anElement, "st", "selected")) {
boolean selected = readBooleanAttribute(anElement, "st", "selected", Boolean.FALSE);
checkBox.setSelected(selected);
}
if (XmlDomUtils.hasAttribute(anElement, "tx", "text")) {
checkBox.setText(XmlDomUtils.getAttribute(anElement, "tx", "text"));
}
return checkBox;
case "ta":
case "TextArea":
case "TextPaneDesignInfo":
TextArea textArea = new TextArea();
readGeneralProps(anElement, textArea);
if (XmlDomUtils.hasAttribute(anElement, "tx", "text")) {
textArea.setText(XmlDomUtils.getAttribute(anElement, "tx", "text"));
}
return textArea;
case "ha":
case "HtmlArea":
case "EditorPaneDesignInfo":
HtmlArea htmlArea = new HtmlArea();
readGeneralProps(anElement, htmlArea);
if (XmlDomUtils.hasAttribute(anElement, "tx", "text")) {
htmlArea.setText(XmlDomUtils.getAttribute(anElement, "tx", "text"));
}
return htmlArea;
case "ff":
case "FormattedField":
case "FormattedFieldDesignInfo": {
FormattedField formattedField = new FormattedField();
readGeneralProps(anElement, formattedField);
String format = XmlDomUtils.getAttribute(anElement, "fr", "format");
int valueType = readIntegerAttribute(anElement, "vt", "valueType", VFormattedField.REGEXP);
formattedField.setValueType(valueType);
formattedField.setFormat(format);
if (XmlDomUtils.hasAttribute(anElement, "tx", "text")) {
formattedField.setText(XmlDomUtils.getAttribute(anElement, "tx", "text"));
}
return formattedField;
}
case "pf":
case "PasswordField":
case "PasswordFieldDesignInfo":
PasswordField passwordField = new PasswordField();
readGeneralProps(anElement, passwordField);
if (XmlDomUtils.hasAttribute(anElement, "tx", "text")) {
passwordField.setText(XmlDomUtils.getAttribute(anElement, "tx", "text"));
}
return passwordField;
case "pb":
case "ProgressBar":
case "ProgressBarDesignInfo": {
ProgressBar progressBar = new ProgressBar();
readGeneralProps(anElement, progressBar);
int minimum = readIntegerAttribute(anElement, "mm", "minimum", 0);
int value = readIntegerAttribute(anElement, "vl", "value", 0);
int maximum = readIntegerAttribute(anElement, "mx", "maximum", 100);
progressBar.setMinimum(minimum);
progressBar.setMaximum(maximum);
progressBar.setValue(value);
if (XmlDomUtils.hasAttribute(anElement, "tx", "text")) {
progressBar.setText(XmlDomUtils.getAttribute(anElement, "tx", "text"));
}
return progressBar;
}
case "rb":
case "RadioButton":
case "RadioDesignInfo":
RadioButton radio = new RadioButton();
readGeneralProps(anElement, radio);
readButton(anElement, radio);
if (XmlDomUtils.hasAttribute(anElement, "st", "selected")) {
boolean selected = readBooleanAttribute(anElement, "st", "selected", Boolean.FALSE);
radio.setSelected(selected);
}
if (XmlDomUtils.hasAttribute(anElement, "tx", "text")) {
radio.setText(XmlDomUtils.getAttribute(anElement, "tx", "text"));
}
return radio;
case "s":
case "Slider":
case "SliderDesignInfo":
Slider slider = new Slider();
readGeneralProps(anElement, slider);
int minimum = readIntegerAttribute(anElement, "mn", "minimum", 0);
int value = readIntegerAttribute(anElement, "vl", "value", 0);
int maximum = readIntegerAttribute(anElement, "mx", "maximum", 100);
slider.setMinimum(minimum);
slider.setMaximum(maximum);
slider.setValue(value);
return slider;
case "tf":
case "TextField":
case "TextFieldDesignInfo":
TextField textField = new TextField();
readGeneralProps(anElement, textField);
if (XmlDomUtils.hasAttribute(anElement, "tx", "text")) {
textField.setText(XmlDomUtils.getAttribute(anElement, "tx", "text"));
}
return textField;
case "tb":
case "ToggleButton":
case "ToggleButtonDesignInfo":
ToggleButton toggle = new ToggleButton();
readGeneralProps(anElement, toggle);
readButton(anElement, toggle);
if (XmlDomUtils.hasAttribute(anElement, "st", "selected")) {
boolean selected = readBooleanAttribute(anElement, "st", "selected", Boolean.FALSE);
toggle.setSelected(selected);
}
return toggle;
case "dp":
case "DesktopPane":
case "DesktopDesignInfo":
DesktopPane desktop = new DesktopPane();
readGeneralProps(anElement, desktop);
return desktop;
// model widgets
case "mcb":
case "ModelCheckBox":
case "DbCheckDesignInfo":
ModelCheckBox modelCheckBox = new ModelCheckBox();
readGeneralProps(anElement, modelCheckBox);
if (XmlDomUtils.hasAttribute(anElement, "tx", "text")) {
modelCheckBox.setText(XmlDomUtils.getAttribute(anElement, "tx", "text"));
}
if (XmlDomUtils.hasAttribute(anElement, "nl", "nullable")) {
modelCheckBox.setNullable(readBooleanAttribute(anElement, "nl", "nullable", true));
}
return modelCheckBox;
case "mc":
case "ModelCombo":
case "DbComboDesignInfo":
ModelCombo modelCombo = new ModelCombo();
readGeneralProps(anElement, modelCombo);
boolean list = readBooleanAttribute(anElement, "ls", "list", Boolean.TRUE);
modelCombo.setList(list);
if (oldFormat) {
Element displayField = XmlDomUtils.getElementByTagName(anElement, null, "displayField");
if (displayField != null && displayField.hasAttribute("fieldName")) {
modelCombo.setDisplayField(displayField.getAttribute("fieldName"));
}
Element valueField = XmlDomUtils.getElementByTagName(anElement, null, "valueField");
if (valueField != null && valueField.hasAttribute("entityId")) {
String entityId = valueField.getAttribute("entityId");
modelCombo.setDisplayList(resolveEntity(Long.valueOf(entityId)));
}
} else {
if (XmlDomUtils.hasAttribute(anElement, "dl", "displayList")) {
String displayList = XmlDomUtils.getAttribute(anElement, "dl", "displayList");
modelCombo.setDisplayList(resolveEntity(displayList));
}
if (XmlDomUtils.hasAttribute(anElement, "df", "displayField")) {
String displayField = XmlDomUtils.getAttribute(anElement, "df", "displayField");
modelCombo.setDisplayField(displayField);
}
}
if (XmlDomUtils.hasAttribute(anElement, "nl", "nullable")) {
modelCombo.setNullable(readBooleanAttribute(anElement, "nl", "nullable", true));
}
return modelCombo;
case "md":
case "ModelDate":
case "DbDateDesignInfo":
ModelDate modelDate = new ModelDate();
readGeneralProps(anElement, modelDate);
if (XmlDomUtils.hasAttribute(anElement, "fr", "format")) {
String dateFormat = XmlDomUtils.getAttribute(anElement, "fr", "format");
try {
modelDate.setFormat(dateFormat);
} catch (Exception ex) {
Logger.getLogger(FormFactory.class.getName()).log(Level.SEVERE, null, ex);
}
}
if (XmlDomUtils.hasAttribute(anElement, "dtp", "datePicker")) {
boolean selected = readBooleanAttribute(anElement, "dtp", "datePicker", Boolean.FALSE);
modelDate.setDatePicker(selected);
}
if (XmlDomUtils.hasAttribute(anElement, "tmp", "timePicker")) {
boolean selected = readBooleanAttribute(anElement, "tmp", "timePicker", Boolean.FALSE);
modelDate.setTimePicker(selected);
}
if (XmlDomUtils.hasAttribute(anElement, "nl", "nullable")) {
modelDate.setNullable(readBooleanAttribute(anElement, "nl", "nullable", true));
}
return modelDate;
case "mff":
case "ModelFormattedField":
case "DbLabelDesignInfo":
ModelFormattedField modelFormattedField = new ModelFormattedField();
readGeneralProps(anElement, modelFormattedField);
try {
String format = XmlDomUtils.getAttribute(anElement, "fr", "format");
int valueType = readIntegerAttribute(anElement, "vt", "valueType", VFormattedField.REGEXP);
modelFormattedField.setValueType(valueType);
modelFormattedField.setFormat(format);
if (XmlDomUtils.hasAttribute(anElement, "tx", "text")) {
modelFormattedField.setText(XmlDomUtils.getAttribute(anElement, "tx", "text"));
}
} catch (Exception ex) {
Logger.getLogger(FormFactory.class.getName()).log(Level.SEVERE, null, ex);
}
if (XmlDomUtils.hasAttribute(anElement, "nl", "nullable")) {
modelFormattedField.setNullable(readBooleanAttribute(anElement, "nl", "nullable", true));
}
return modelFormattedField;
case "msp":
case "ModelSpin":
case "DbSpinDesignInfo":
ModelSpin modelSpin = new ModelSpin();
readGeneralProps(anElement, modelSpin);
Double min = null;
if (anElement.hasAttribute("min")) {
min = XmlDomUtils.readDoubleAttribute(anElement, "min", -Double.MAX_VALUE);
}
double step = XmlDomUtils.readDoubleAttribute(anElement, "step", 1.0d);
Double max = null;
if (anElement.hasAttribute("max")) {
max = XmlDomUtils.readDoubleAttribute(anElement, "max", Double.MAX_VALUE);
}
try {
modelSpin.setMin(min);
modelSpin.setMax(max);
modelSpin.setStep(step);
} catch (Exception ex) {
Logger.getLogger(FormFactory.class.getName()).log(Level.SEVERE, null, ex);
}
if (XmlDomUtils.hasAttribute(anElement, "nl", "nullable")) {
modelSpin.setNullable(readBooleanAttribute(anElement, "nl", "nullable", true));
}
return modelSpin;
case "mta":
case "ModelTextArea":
case "DbTextDesignInfo":
ModelTextArea modelTextArea = new ModelTextArea();
readGeneralProps(anElement, modelTextArea);
if (XmlDomUtils.hasAttribute(anElement, "tx", "text")) {
try {
modelTextArea.setText(XmlDomUtils.getAttribute(anElement, "tx", "text"));
} catch (Exception ex) {
Logger.getLogger(FormFactory.class.getName()).log(Level.SEVERE, null, ex);
}
}
if (XmlDomUtils.hasAttribute(anElement, "nl", "nullable")) {
modelTextArea.setNullable(readBooleanAttribute(anElement, "nl", "nullable", true));
}
return modelTextArea;
case "mg":
case "ModelGrid":
case "DbGridDesignInfo": {
ModelGrid grid = new ModelGrid();
readGeneralProps(anElement, grid);
GridColumnsNode oldFormatRowsHeader = null;
if (oldFormat) {
Element rowsColumns = XmlDomUtils.getElementByTagName(anElement, null, "rowsColumnsDesignInfo");
if (rowsColumns != null) {
Element rowsDatasource = XmlDomUtils.getElementByTagName(rowsColumns, null, "rowsDatasource");
if (rowsDatasource != null) {
String entityId = rowsDatasource.getAttribute("entityId");
try {
grid.setData(resolveEntity(Long.valueOf(entityId)));
} catch (Exception ex) {
Logger.getLogger(FormFactory.class.getName()).log(Level.SEVERE, "While setting data to named model's property ({0}) in old format to grid {1} exception occured: {2}", new Object[]{entityId, grid.getName(), ex.getMessage()});
}
}
int rowsHeaderType = 1;// Usual
if (rowsColumns.hasAttribute("rowsHeaderType")) {
rowsHeaderType = Integer.valueOf(rowsColumns.getAttribute("rowsHeaderType"));
}
switch (rowsHeaderType) {
case 1:// Usual
oldFormatRowsHeader = new ServiceGridColumn();
break;
case 2:// Check
oldFormatRowsHeader = new CheckGridColumn();
break;
case 3:// Radio
oldFormatRowsHeader = new RadioGridColumn();
break;
}
}
Element tree = XmlDomUtils.getElementByTagName(anElement, null, "treeDesignInfo");
}
int frozenColumns = readIntegerAttribute(anElement, "frc", "frozenColumns", 0);
int frozenRows = readIntegerAttribute(anElement, "frr", "frozenRows", 0);
boolean insertable = readBooleanAttribute(anElement, "ie", "insertable", Boolean.TRUE);
boolean deletable = readBooleanAttribute(anElement, "de", "deletable", Boolean.TRUE);
boolean editable = readBooleanAttribute(anElement, "e", "editable", Boolean.TRUE);
boolean headerVisible = readBooleanAttribute(anElement, "hv", "headerVisible", Boolean.TRUE);
boolean draggableRows = readBooleanAttribute(anElement, "dr", "draggableRows", Boolean.FALSE);
boolean showHorizontalLines = readBooleanAttribute(anElement, "shl", "showHorizontalLines", Boolean.TRUE);
boolean showVerticalLines = readBooleanAttribute(anElement, "svl", "showVerticalLines", Boolean.TRUE);
boolean showOddRowsInOtherColor = readBooleanAttribute(anElement, "soc", "showOddRowsInOtherColor", Boolean.TRUE);
int rowsHeight = readIntegerAttribute(anElement, "rh", "rowsHeight", 30);
grid.setHeaderVisible(headerVisible);
grid.setDraggableRows(draggableRows);
grid.setRowsHeight(rowsHeight);
grid.setShowOddRowsInOtherColor(showOddRowsInOtherColor);
grid.setShowVerticalLines(showVerticalLines);
grid.setShowHorizontalLines(showHorizontalLines);
grid.setEditable(editable);
grid.setDeletable(deletable);
grid.setInsertable(insertable);
grid.setFrozenColumns(frozenColumns);
grid.setFrozenRows(frozenRows);
if (XmlDomUtils.hasAttribute(anElement, "orc", "oddRowsColor")) {
String oddRowsColorDesc = XmlDomUtils.getAttribute(anElement, "orc", "oddRowsColor");
grid.setOddRowsColor(new ScriptColor(oddRowsColorDesc));
}
if (XmlDomUtils.hasAttribute(anElement, "gc", "gridColor")) {
String gridColorDesc = XmlDomUtils.getAttribute(anElement, "gc", "gridColor");
grid.setGridColor(new ScriptColor(gridColorDesc));
}
if (XmlDomUtils.hasAttribute(anElement, "pf", "parentField")) {
String parentFieldPath = XmlDomUtils.getAttribute(anElement, "pf", "parentField");
grid.setParentField(parentFieldPath);
}
if (XmlDomUtils.hasAttribute(anElement, "cf", "childrenField")) {
String childrenFieldPath = XmlDomUtils.getAttribute(anElement, "cf", "childrenField");
grid.setChildrenField(childrenFieldPath);
}
List<GridColumnsNode> roots = readColumns(anElement);
List<ModelColumn> columns = new ArrayList<>();
List<GridColumnsNode> leaves = new ArrayList<>();
MultiLevelHeader.achieveLeaves(roots, leaves);
leaves.stream().sequential().forEach((leaf) -> {
columns.add((ModelColumn) leaf.getTableColumn());
});
if (oldFormatRowsHeader != null) {
roots.add(0, oldFormatRowsHeader);
columns.add(0, (ModelColumn) oldFormatRowsHeader.getTableColumn());
}
grid.setColumns(columns.toArray(new ModelColumn[]{}));
grid.setHeader(roots);
if (XmlDomUtils.hasAttribute(anElement, "d", "data")) {
String entityName = XmlDomUtils.getAttribute(anElement, "d", "data");
try {
grid.setData(resolveEntity(entityName));
} catch (Exception ex) {
Logger.getLogger(FormFactory.class.getName()).log(Level.SEVERE, "While setting data to property ({0}) of widget {1} exception occured: {2}", new Object[]{entityName, grid.getName(), ex.getMessage()});
}
}
if (XmlDomUtils.hasAttribute(anElement, "f", "field")) {
String dataPropertyPath = XmlDomUtils.getAttribute(anElement, "f", "field");
grid.setField(dataPropertyPath);
}
if (Scripts.isInitialized()) {
injectColumns(grid, roots);
}
return grid;
}
// containers
// layouted containers
case "PanelDesignInfo":// oldFormat
Element layoutTag = XmlDomUtils.getElementByTagName(anElement, null, "layout");
assert layoutTag != null : "tag layout is required for panel containers.";
JComponent container = readOldStyleLayoutedContainer(layoutTag);
readGeneralProps(anElement, container);
return container;
case "ap":
case "AnchorsPane":
JComponent anchorsPane = createAnchorsPane();
readGeneralProps(anElement, anchorsPane);
return anchorsPane;
case "bp":
case "BorderPane": {
int hgap = XmlDomUtils.readIntegerAttribute(anElement, "hgap", 0);
int vgap = XmlDomUtils.readIntegerAttribute(anElement, "vgap", 0);
JComponent borderPane = createBorderPane(hgap, vgap);
readGeneralProps(anElement, borderPane);
return borderPane;
}
case "bx":
case "BoxPane": {
int hgap = XmlDomUtils.readIntegerAttribute(anElement, "hgap", 0);
int vgap = XmlDomUtils.readIntegerAttribute(anElement, "vgap", 0);
int orientation = readIntegerAttribute(anElement, "on", "orientation", Orientation.HORIZONTAL);
JComponent boxPane = createBoxPane(orientation, hgap, vgap);
readGeneralProps(anElement, boxPane);
return boxPane;
}
case "cp":
case "CardPane": {
int hgap = XmlDomUtils.readIntegerAttribute(anElement, "hgap", 0);
int vgap = XmlDomUtils.readIntegerAttribute(anElement, "vgap", 0);
JComponent cardPane = createCardPane(hgap, vgap);
readGeneralProps(anElement, cardPane);
return cardPane;
}
case "fp":
case "FlowPane": {
int hgap = XmlDomUtils.readIntegerAttribute(anElement, "hgap", 0);
int vgap = XmlDomUtils.readIntegerAttribute(anElement, "vgap", 0);
JComponent flowPane = createFlowPane(hgap, vgap);
readGeneralProps(anElement, flowPane);
return flowPane;
}
case "gp":
case "GridPane": {
int hgap = XmlDomUtils.readIntegerAttribute(anElement, "hgap", 0);
int vgap = XmlDomUtils.readIntegerAttribute(anElement, "vgap", 0);
int rows = XmlDomUtils.readIntegerAttribute(anElement, "rows", 0);
int columns = XmlDomUtils.readIntegerAttribute(anElement, "columns", 0);
JComponent gridPane = createGridPane(rows, columns, hgap, vgap);
readGeneralProps(anElement, gridPane);
return gridPane;
}
// predefined layout containers
case "sp":
case "ScrollPane":
case "ScrollDesignInfo":
ScrollPane scroll = new ScrollPane();
readGeneralProps(anElement, scroll);
boolean wheelScrollingEnabled = readBooleanAttribute(anElement, "wse", "wheelScrollingEnabled", Boolean.TRUE);
int horizontalScrollBarPolicy = readIntegerAttribute(anElement, "hsp", "horizontalScrollBarPolicy", ScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
int verticalScrollBarPolicy = readIntegerAttribute(anElement, "vsp", "verticalScrollBarPolicy", ScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
scroll.setHorizontalScrollBarPolicy(horizontalScrollBarPolicy);
scroll.setVerticalScrollBarPolicy(verticalScrollBarPolicy);
return scroll;
case "spl":
case "SplitPane":
case "SplitDesignInfo":
SplitPane split = new SplitPane();
readGeneralProps(anElement, split);
boolean oneTouchExpandable = readBooleanAttribute(anElement, "ote", "oneTouchExpandable", true);
int dividerLocation = readIntegerAttribute(anElement, "dvl", "dividerLocation", 0);
int dividerSize = readIntegerAttribute(anElement, "ds", "dividerSize", 5);
int orientation = readIntegerAttribute(anElement, "on", "orientation", Orientation.VERTICAL);
split.setDividerLocation(dividerLocation);
split.setDividerSize(dividerSize);
split.setOrientation(orientation);
split.setOneTouchExpandable(oneTouchExpandable);
if (XmlDomUtils.hasAttribute(anElement, "lc", "leftComponent")) {
String leftComponentName = XmlDomUtils.getAttribute(anElement, "lc", "leftComponent");
resolvers.add((Map<String, JComponent> aWidgets) -> {
JComponent leftComponent = aWidgets.get(leftComponentName);
split.setLeftComponent(leftComponent);
});
}
if (XmlDomUtils.hasAttribute(anElement, "rc", "rightComponent")) {
String rightComponentName = XmlDomUtils.getAttribute(anElement, "rc", "rightComponent");
resolvers.add((Map<String, JComponent> aWidgets) -> {
JComponent rightComponent = aWidgets.get(rightComponentName);
split.setRightComponent(rightComponent);
});
}
return split;
case "tp":
case "TabbedPane":
case "TabsDesignInfo":
TabbedPane tabs = new TabbedPane();
readGeneralProps(anElement, tabs);
int tabPlacement = readIntegerAttribute(anElement, "tp", "tabPlacement", TabbedPane.TOP);
tabs.setTabPlacement(tabPlacement);
return tabs;
case "tl":
case "ToolBar":
case "ToolbarDesignInfo":
ToolBar toolbar = new ToolBar();
readGeneralProps(anElement, toolbar);
return toolbar;
// menus
case "m":
case "Menu":
case "MenuDesignInfo":
Menu menu = new Menu();
readGeneralProps(anElement, menu);
if (XmlDomUtils.hasAttribute(anElement, "tx", "text")) {
menu.setText(XmlDomUtils.getAttribute(anElement, "tx", "text"));
}
return menu;
case "mi":
case "MenuItem":
case "MenuItemDesignInfo":
MenuItem menuitem = new MenuItem();
readGeneralProps(anElement, menuitem);
readButton(anElement, menuitem);
if (XmlDomUtils.hasAttribute(anElement, "tx", "text")) {
menuitem.setText(XmlDomUtils.getAttribute(anElement, "tx", "text"));
}
return menuitem;
case "cmi":
case "CheckMenuItem":
case "MenuCheckItemDesignInfo":
CheckMenuItem checkMenuItem = new CheckMenuItem();
readGeneralProps(anElement, checkMenuItem);
readButton(anElement, checkMenuItem);
if (XmlDomUtils.hasAttribute(anElement, "st", "selected")) {
boolean selected = readBooleanAttribute(anElement, "st", "selected", Boolean.FALSE);
checkMenuItem.setSelected(selected);
}
if (XmlDomUtils.hasAttribute(anElement, "tx", "text")) {
checkMenuItem.setText(XmlDomUtils.getAttribute(anElement, "tx", "text"));
}
return checkMenuItem;
case "rmi":
case "RadioMenuItem":
case "MenuRadioItemDesignInfo":
RadioMenuItem radioMenuItem = new RadioMenuItem();
readGeneralProps(anElement, radioMenuItem);
readButton(anElement, radioMenuItem);
if (XmlDomUtils.hasAttribute(anElement, "st", "selected")) {
boolean selected = readBooleanAttribute(anElement, "st", "selected", Boolean.FALSE);
radioMenuItem.setSelected(selected);
}
if (XmlDomUtils.hasAttribute(anElement, "tx", "text")) {
radioMenuItem.setText(XmlDomUtils.getAttribute(anElement, "tx", "text"));
}
return radioMenuItem;
case "ms":
case "MenuSeparator":
case "MenuSeparatorDesignInfo":
MenuSeparator menuSeparator = new MenuSeparator();
readGeneralProps(anElement, menuSeparator);
return menuSeparator;
case "mb":
case "MenuBar":
case "MenubarDesignInfo":
MenuBar menuBar = new MenuBar();
readGeneralProps(anElement, menuBar);
return menuBar;
case "pm":
case "PopupMenu":
case "PopupDesignInfo":
PopupMenu popupMenu = new PopupMenu();
readGeneralProps(anElement, popupMenu);
return popupMenu;
default:
return null;
}
}
protected void readButton(Element anElement, AbstractButton button) {
if (XmlDomUtils.hasAttribute(anElement, "i", "icon")) {
resolveIcon(XmlDomUtils.getAttribute(anElement, "i", "icon"), (ImageIcon aLoaded) -> {
button.setIcon(aLoaded);
}, (Exception ex) -> {
Logger.getLogger(FormFactory.class.getName()).log(Level.SEVERE, ex.getMessage());
});
}
if (XmlDomUtils.hasAttribute(anElement, "tx", "text")) {
button.setText(XmlDomUtils.getAttribute(anElement, "tx", "text"));
}
button.setHorizontalAlignment(readIntegerAttribute(anElement, "ha", "horizontalAlignment", Button.CENTER));
button.setVerticalAlignment(readIntegerAttribute(anElement, "va", "verticalAlignment", Button.CENTER));
button.setIconTextGap(readIntegerAttribute(anElement, "itg", "iconTextGap", 4));
button.setHorizontalTextPosition(readIntegerAttribute(anElement, "htp", "horizontalTextPosition", Button.RIGHT));
button.setVerticalTextPosition(readIntegerAttribute(anElement, "vtp", "verticalTextPosition", Button.CENTER));
}
protected JComponent readOldStyleLayoutedContainer(Element aLayoutElement) {
String type = aLayoutElement.getAttribute("type");
assert type != null && !type.isEmpty() : "type attribute is required for layouts to be read from a file";
int hgap = XmlDomUtils.readIntegerAttribute(aLayoutElement, "hgap", 0);
int vgap = XmlDomUtils.readIntegerAttribute(aLayoutElement, "vgap", 0);
switch (type) {
case "BorderLayoutDesignInfo": {
return createBorderPane(hgap, vgap);
}
case "BoxLayoutDesignInfo": {
int axis = XmlDomUtils.readIntegerAttribute(aLayoutElement, "axis", BoxLayout.LINE_AXIS);
return createBoxPane(axis, hgap, vgap);
}
case "CardLayoutDesignInfo": {
return createCardPane(hgap, vgap);
}
case "FlowLayoutDesignInfo": {
int alignment = XmlDomUtils.readIntegerAttribute(aLayoutElement, "alignment", 0);
return createFlowPane(hgap, vgap);
}
case "GridLayoutDesignInfo": {
int rows = XmlDomUtils.readIntegerAttribute(aLayoutElement, "rows", 0);
int columns = XmlDomUtils.readIntegerAttribute(aLayoutElement, "columns", 0);
return createGridPane(rows, columns, hgap, vgap);
}
case "AbsoluteLayoutDesignInfo":
case "MarginLayoutDesignInfo":
return createAnchorsPane();
default:
return null;
}
}
protected JComponent createAnchorsPane() {
return new AnchorsPane();
}
protected JComponent createGridPane(int rows, int columns, int hgap, int vgap) {
return new GridPane(rows, columns, hgap, vgap);
}
protected JComponent createFlowPane(int hgap, int vgap) {
return new FlowPane(hgap, vgap);
}
protected JComponent createCardPane(int hgap, int vgap) {
return new CardPane(hgap, vgap);
}
protected JComponent createBoxPane(int orientation, int hgap, int vgap) {
return new BoxPane(orientation, hgap, vgap);
}
protected JComponent createBorderPane(int hgap, int vgap) {
return new BorderPane(hgap, vgap);
}
private void readGeneralProps(Element anElement, JComponent aTarget) {
if (XmlDomUtils.hasAttribute(anElement, "n", "name")) {
aTarget.setName(XmlDomUtils.getAttribute(anElement, "n", "name"));
}
if (XmlDomUtils.hasAttribute(anElement, "e", "editable") && aTarget instanceof HasEditable) {
((HasEditable) aTarget).setEditable(readBooleanAttribute(anElement, "e", "editable", Boolean.TRUE));
}
if (XmlDomUtils.hasAttribute(anElement, "et", "emptyText") && aTarget instanceof HasEmptyText) {
((HasEmptyText) aTarget).setEmptyText(XmlDomUtils.getAttribute(anElement, "et", "emptyText"));
}
if (XmlDomUtils.hasAttribute(anElement, "f", "field") && aTarget instanceof ModelWidget) {
String fieldPath = XmlDomUtils.getAttribute(anElement, "f", "field");
try {
((ModelWidget) aTarget).setField(fieldPath);
} catch (Exception ex) {
Logger.getLogger(FormFactory.class.getName()).log(Level.SEVERE, "While setting field ({0}) to widget {1} exception occured: {2}", new Object[]{fieldPath, aTarget.getName(), ex.getMessage()});
}
}
if (oldFormat) {
if (aTarget instanceof ModelWidget) {
Element datamodelElement = XmlDomUtils.getElementByTagName(anElement, null, "datamodelElement");
if (datamodelElement != null) {
String entityId = datamodelElement.getAttribute("entityId");
try {
((ModelWidget) aTarget).setData(resolveEntity(Long.valueOf(entityId)));
} catch (Exception ex) {
Logger.getLogger(FormFactory.class.getName()).log(Level.SEVERE, "While setting data to named model's property ({0}) in old format to widget {1} exception occured: {2}", new Object[]{entityId, aTarget.getName(), ex.getMessage()});
}
String fieldName = datamodelElement.getAttribute("fieldName");
try {
((ModelWidget) aTarget).setField("cursor." + fieldName);
} catch (Exception ex) {
Logger.getLogger(FormFactory.class.getName()).log(Level.SEVERE, "While setting data to named model's property ({0}) in old format to widget {1} exception occured: {2}", new Object[]{entityId, aTarget.getName(), ex.getMessage()});
}
}
}
if (anElement.hasAttribute("backgroundColor")) {
ScriptColor background = new ScriptColor(anElement.getAttribute("backgroundColor"));
aTarget.setBackground(background);
}
if (anElement.hasAttribute("foregroundColor")) {
ScriptColor foreground = new ScriptColor(anElement.getAttribute("foregroundColor"));
aTarget.setForeground(foreground);
}
} else {
if (XmlDomUtils.hasAttribute(anElement, "bg", "background")) {
ScriptColor background = new ScriptColor(XmlDomUtils.getAttribute(anElement, "bg", "background"));
aTarget.setBackground(background);
}
if (XmlDomUtils.hasAttribute(anElement, "fg", "foreground")) {
ScriptColor foreground = new ScriptColor(XmlDomUtils.getAttribute(anElement, "fg", "foreground"));
aTarget.setForeground(foreground);
}
if (XmlDomUtils.hasAttribute(anElement, "d", "data") && aTarget instanceof ModelWidget) {
String entityName = XmlDomUtils.getAttribute(anElement, "d", "data");
try {
((ModelWidget) aTarget).setData(resolveEntity(entityName));
} catch (Exception ex) {
Logger.getLogger(FormFactory.class.getName()).log(Level.SEVERE, "While setting data to named model's property ({0}) to widget {1} exception occured: {2}", new Object[]{entityName, aTarget.getName(), ex.getMessage()});
}
}
}
aTarget.setEnabled(readBooleanAttribute(anElement, "en", "enabled", Boolean.TRUE));
aTarget.setFocusable(readBooleanAttribute(anElement, "fc", "focusable", Boolean.TRUE));
Font font = readFont(anElement);
if (font != null) {
aTarget.setFont(font);
}
if (XmlDomUtils.hasAttribute(anElement, "o", "opaque")) {
aTarget.setOpaque(readBooleanAttribute(anElement, "o", "opaque", Boolean.TRUE));
}
if (XmlDomUtils.hasAttribute(anElement, "ttt", "toolTipText")) {
aTarget.setToolTipText(XmlDomUtils.getAttribute(anElement, "ttt", "toolTipText"));
}
int cursorId = readIntegerAttribute(anElement, "cr", "cursor", com.eas.gui.Cursor.DEFAULT_CURSOR);
aTarget.setCursor(new com.eas.gui.Cursor(cursorId));
if (XmlDomUtils.hasAttribute(anElement, "v", "visible")) {
aTarget.setVisible(readBooleanAttribute(anElement, "v", "visible", Boolean.TRUE));
}
if (XmlDomUtils.hasAttribute(anElement, "nfc", "nextFocusableComponent")) {
String nextFocusableName = XmlDomUtils.getAttribute(anElement, "nfc", "nextFocusableComponent");
if (!nextFocusableName.isEmpty()) {
resolvers.add((Map<String, JComponent> aWidgets) -> {
JComponent nextFocusable = aWidgets.get(nextFocusableName);
aTarget.setNextFocusableComponent(nextFocusable);
});
}
}
if (XmlDomUtils.hasAttribute(anElement, "cpm", "componentPopupMenu")) {
String popupName = XmlDomUtils.getAttribute(anElement, "cpm", "componentPopupMenu");
if (!popupName.isEmpty()) {
resolvers.add((Map<String, JComponent> aWidgets) -> {
JComponent popup = aWidgets.get(popupName);
if (popup instanceof PopupMenu) {
aTarget.setComponentPopupMenu((PopupMenu) popup);
}
});
}
}
if (XmlDomUtils.hasAttribute(anElement, "bgr", "buttonGroup") && aTarget instanceof HasGroup) {
String buttonGroupName = XmlDomUtils.getAttribute(anElement, "bgr", "buttonGroup");
if (!buttonGroupName.isEmpty()) {
resolvers.add((Map<String, JComponent> aWidgets) -> {
JComponent buttonGroup = aWidgets.get(buttonGroupName);
if (buttonGroup instanceof ButtonGroup) {
ButtonGroup bg = (ButtonGroup) buttonGroup;
((HasGroup) aTarget).setButtonGroup(bg);
}
});
}
}
if (XmlDomUtils.hasAttribute(anElement, "p", "parent")) {
String parentName = XmlDomUtils.getAttribute(anElement, "p", "parent");
if (!parentName.isEmpty()) {
resolvers.add((Map<String, JComponent> aWidgets) -> {
JComponent parent = oldFormat && OLD_FORM_ROOT_CONTAINER_NAME.equalsIgnoreCase(parentName) ? viewWidget : aWidgets.get(parentName);
addToParent(anElement, aTarget, parent);
});
}
}
if (!oldFormat && rootContainerName.equals(aTarget.getName())) {
aTarget.setPreferredSize(readPrefSize(anElement));
}
}
protected com.eas.gui.Font readFont(Element anElement) {
com.eas.gui.Font font = readFontTag(anElement, "ft", "font");
if (font != null) {
return font;
} else if (oldFormat) {
return readFontTag(anElement, "easFont", "easFont");
} else {
return null;
}
}
private com.eas.gui.Font readFontTag(Element anElement, String aSubTagShortName, String aSubTagLongName) {
Element easFontElement = XmlDomUtils.getElementByTagName(anElement, aSubTagShortName, aSubTagLongName);
if (easFontElement != null) {
String name = XmlDomUtils.getAttribute(easFontElement, "n", "name");
if (name == null || name.isEmpty() || "null".equals(name)) {
name = "Arial";
}
int style = readIntegerAttribute(easFontElement, "stl", "style", 0);
int size = readIntegerAttribute(easFontElement, "sz", "size", 12);
return new com.eas.gui.Font(name, style, size);
} else {
return null;
}
}
private void addToParent(Element anElement, JComponent aTarget, JComponent parent) {
Element constraintsElement = XmlDomUtils.getElementByTagName(anElement, null, "constraints");
if (parent instanceof MenuBar) {
((MenuBar) parent).add(aTarget);
} else if (parent instanceof PopupMenu) {
((PopupMenu) parent).add(aTarget);
} else if (parent instanceof Menu) {
((Menu) parent).add(aTarget);
} else if (parent instanceof ToolBar) {
Dimension prefSize = readPrefSize(anElement);
aTarget.setPreferredSize(prefSize);
aTarget.setSize(prefSize);
((ToolBar) parent).add(aTarget);
} else if (parent instanceof TabbedPane) {
if (constraintsElement == null) {// new format
constraintsElement = XmlDomUtils.getElementByTagName(anElement, "tpc", "TabbedPaneConstraints");
}
String tabTitle = XmlDomUtils.getAttribute(constraintsElement, "tt", "tabTitle");
String tabIconName = XmlDomUtils.getAttribute(constraintsElement, "ti", "tabIcon");
String tabTooltipText;
if (oldFormat) {
tabTooltipText = constraintsElement.getAttribute("tabToolTip");
} else {
tabTooltipText = XmlDomUtils.getAttribute(constraintsElement, "ttp", "tabTooltipText");
}
TabbedPane tabs = (TabbedPane) parent;
tabs.add(aTarget, tabTitle);
int tabIndex = tabs.getTabCount() - 1;
tabs.setToolTipTextAt(tabIndex, tabTooltipText);
resolveIcon(tabIconName, (ImageIcon aLoaded) -> {
if (tabIndex >= 0 && tabIndex < tabs.getTabCount()) {
tabs.setIconAt(tabIndex, aLoaded);
}
}, (Exception ex) -> {
Logger.getLogger(FormFactory.class.getName()).log(Level.SEVERE, null, ex);
});
} else if (parent instanceof SplitPane) {
// Split pane children are:
// - left component
// - right component
// Theese children are setted while resolving component references of a split pane.
} else if (parent instanceof ScrollPane) {
ScrollPane scroll = (ScrollPane) parent;
Dimension prefSize = readPrefSize(anElement);
aTarget.setPreferredSize(prefSize);
aTarget.setSize(prefSize);
scroll.setView(aTarget);
} else if (parent != null && parent.getLayout() instanceof BorderLayout) {
if (constraintsElement == null) {// new format
constraintsElement = XmlDomUtils.getElementByTagName(anElement, "bpc", "BorderPaneConstraints");
}
Dimension prefSize = readPrefSize(anElement);
Integer place = HorizontalPosition.CENTER;
if (oldFormat) {
String sPlace = constraintsElement.getAttribute("place");
if (sPlace != null && !sPlace.isEmpty()) {
switch (sPlace) {
case BorderLayout.LINE_START:
case BorderLayout.WEST:
place = HorizontalPosition.LEFT;
break;
case BorderLayout.LINE_END:
case BorderLayout.EAST:
place = HorizontalPosition.RIGHT;
break;
case BorderLayout.PAGE_START:
case BorderLayout.NORTH:
place = VerticalPosition.TOP;
break;
case BorderLayout.PAGE_END:
case BorderLayout.SOUTH:
place = VerticalPosition.BOTTOM;
break;
default:
place = HorizontalPosition.CENTER;
}
}
} else {
place = readIntegerAttribute(constraintsElement, "pl", "place", HorizontalPosition.CENTER);
}
Integer size = 0;
switch (place) {
case HorizontalPosition.LEFT:
size = prefSize.width;
break;
case HorizontalPosition.RIGHT:
size = prefSize.width;
break;
case VerticalPosition.TOP:
size = prefSize.height;
break;
case VerticalPosition.BOTTOM:
size = prefSize.height;
break;
}
addToBorderPane(parent, aTarget, place, size);
} else if (parent != null && parent.getLayout() instanceof BoxLayout) {
Dimension prefSize = readPrefSize(anElement);
addToBoxPane(parent, aTarget, prefSize);
} else if (parent != null && parent.getLayout() instanceof CardLayout) {
if (constraintsElement == null) {// new format
constraintsElement = XmlDomUtils.getElementByTagName(anElement, "cpc", "CardPaneConstraints");
}
String cardName = XmlDomUtils.getAttribute(constraintsElement, "cn", "cardName");
addToCardPane(parent, aTarget, cardName);
} else if (parent != null && parent.getLayout() instanceof FlowLayout) {
Dimension prefSize = readPrefSize(anElement);
addToFlowPane(parent, aTarget, prefSize);
} else if (parent != null && parent.getLayout() instanceof GridLayout) {
addToGridPane(parent, aTarget);
} else if (parent != null && parent.getLayout() instanceof MarginLayout) {
if (constraintsElement == null) {// new format
constraintsElement = XmlDomUtils.getElementByTagName(anElement, "apc", "AnchorsPaneConstraints");
}
MarginConstraints constraints = readMarginConstraints(constraintsElement);
addToAnchorsPane(parent, aTarget, constraints);
}
}
protected void addToAnchorsPane(JComponent parent, JComponent aTarget, MarginConstraints constraints) {
AnchorsPane anchors = (AnchorsPane) parent;
anchors.add(aTarget, constraints);
}
protected void addToGridPane(JComponent parent, JComponent aTarget) {
((GridPane) parent).add(aTarget);
}
protected void addToFlowPane(JComponent parent, JComponent aTarget, Dimension prefSize) {
((FlowPane) parent).add(aTarget);
aTarget.setPreferredSize(prefSize);
}
protected void addToCardPane(JComponent parent, JComponent aTarget, String cardName) {
((CardPane) parent).add(aTarget, cardName);
}
protected void addToBoxPane(JComponent parent, JComponent aTarget, Dimension prefSize) {
BoxPane box = (BoxPane) parent;
if (box.getOrientation() == Orientation.HORIZONTAL) {
box.add(aTarget, prefSize.width);
} else {
box.add(aTarget, prefSize.height);
}
}
protected void addToBorderPane(JComponent parent, JComponent aTarget, Integer place, Integer size) {
BorderPane borderPane = (BorderPane) parent;
borderPane.add(aTarget, place, size);
}
private static boolean readBooleanAttribute(Element anElement, String aShortName, String aLongName, boolean aDefaultValue) {
if (anElement.hasAttribute(aShortName)) {
return XmlDomUtils.readBooleanAttribute(anElement, aShortName, aDefaultValue);
} else {
return XmlDomUtils.readBooleanAttribute(anElement, aLongName, aDefaultValue);
}
}
private static float readFloatAttribute(Element anElement, String aShortName, String aLongName, float aDefaultValue) {
if (anElement.hasAttribute(aShortName)) {
return XmlDomUtils.readFloatAttribute(anElement, aShortName, aDefaultValue);
} else {
return XmlDomUtils.readFloatAttribute(anElement, aLongName, aDefaultValue);
}
}
private static int readIntegerAttribute(Element anElement, String aShortName, String aLongName, int aDefaultValue) {
if (anElement.hasAttribute(aShortName)) {
return XmlDomUtils.readIntegerAttribute(anElement, aShortName, aDefaultValue);
} else {
return XmlDomUtils.readIntegerAttribute(anElement, aLongName, aDefaultValue);
}
}
private static MarginConstraints readMarginConstraints(Element anElement) {
MarginConstraints result = new MarginConstraints();
if (anElement.hasAttribute("l")) {
result.setLeft(Margin.parse(anElement.getAttribute("l")));
} else if (anElement.hasAttribute("left")) {
result.setLeft(Margin.parse(anElement.getAttribute("left")));
}
if (anElement.hasAttribute("r")) {
result.setRight(Margin.parse(anElement.getAttribute("r")));
} else if (anElement.hasAttribute("right")) {
result.setRight(Margin.parse(anElement.getAttribute("right")));
}
if (anElement.hasAttribute("t")) {
result.setTop(Margin.parse(anElement.getAttribute("t")));
} else if (anElement.hasAttribute("top")) {
result.setTop(Margin.parse(anElement.getAttribute("top")));
}
if (anElement.hasAttribute("b")) {
result.setBottom(Margin.parse(anElement.getAttribute("b")));
} else if (anElement.hasAttribute("bottom")) {
result.setBottom(Margin.parse(anElement.getAttribute("bottom")));
}
if (anElement.hasAttribute("w")) {
result.setWidth(Margin.parse(anElement.getAttribute("w")));
} else if (anElement.hasAttribute("width")) {
result.setWidth(Margin.parse(anElement.getAttribute("width")));
}
if (anElement.hasAttribute("h")) {
result.setHeight(Margin.parse(anElement.getAttribute("h")));
} else if (anElement.hasAttribute("height")) {
result.setHeight(Margin.parse(anElement.getAttribute("height")));
}
return result;
}
private List<GridColumnsNode> readColumns(Element aColumnsElement) throws Exception {
List<GridColumnsNode> nodes = new ArrayList<>();
Node childNode = aColumnsElement.getFirstChild();
while (childNode != null) {
if (childNode instanceof Element) {
Element childTag = (Element) childNode;
String columnType;
if (oldFormat) {
if ("column".equals(childTag.getTagName())) {
columnType = "ModelGridColumn";
} else {
childNode = childNode.getNextSibling();
continue;
}
} else {
columnType = childTag.getTagName();
}
switch (columnType) {
case "cgc":
case "CheckGridColumn": {
CheckGridColumn columnn = new CheckGridColumn();
readColumnNode(columnn, childTag);
nodes.add(columnn);
List<GridColumnsNode> children = readColumns(childTag);
columnn.getChildren().addAll(children);
break;
}
case "rgc":
case "RadioGridColumn": {
RadioGridColumn columnn = new RadioGridColumn();
readColumnNode(columnn, childTag);
nodes.add(columnn);
List<GridColumnsNode> children = readColumns(childTag);
columnn.getChildren().addAll(children);
break;
}
case "sgc":
case "ServiceGridColumn": {
ServiceGridColumn columnn = new ServiceGridColumn();
readColumnNode(columnn, childTag);
nodes.add(columnn);
List<GridColumnsNode> children = readColumns(childTag);
columnn.getChildren().addAll(children);
break;
}
case "mgc":
case "ModelGridColumn": {
ModelGridColumn columnn = new ModelGridColumn();
readColumnNode(columnn, childTag);
if (XmlDomUtils.hasAttribute(childTag, "f", "field")) {
columnn.setField(XmlDomUtils.getAttribute(childTag, "f", "field"));
}
if (XmlDomUtils.hasAttribute(childTag, "sf", "sortField")) {
columnn.setSortField(XmlDomUtils.getAttribute(childTag, "sf", "sortField"));
}
Node _childNode = childTag.getFirstChild();
while (_childNode != null) {
if (_childNode instanceof Element) {
Element _childTag = (Element) _childNode;
if (oldFormat) {
if (_childTag.getTagName().equals("datamodelElement")) {
if (_childTag.hasAttribute("fieldName")) {
columnn.setField(_childTag.getAttribute("fieldName"));
}
}
}
JComponent editorComp = readWidget(_childTag);
if (editorComp instanceof ModelWidget) {
ModelColumn col = (ModelColumn) columnn.getTableColumn();
col.setEditor((ModelWidget) editorComp);
ModelWidget viewComp = (ModelWidget) readWidget((Element) _childNode);
col.setView(viewComp);
if (!oldFormat) {
break;
}
}
}
_childNode = _childNode.getNextSibling();
}
nodes.add(columnn);
List<GridColumnsNode> children = readColumns(childTag);
columnn.getChildren().addAll(children);
break;
}
}
}
childNode = childNode.getNextSibling();
}
return nodes;
}
private void readColumnNode(GridColumnsNode aNode, Element anElement) throws Exception {
((ModelColumn) aNode.getTableColumn()).setName(XmlDomUtils.getAttribute(anElement, "n", "name"));
if (XmlDomUtils.hasAttribute(anElement, "tl", "title")) {
aNode.setTitle(XmlDomUtils.getAttribute(anElement, "tl", "title"));
}
if (XmlDomUtils.hasAttribute(anElement, "bg", "background")) {
ScriptColor background = new ScriptColor(XmlDomUtils.getAttribute(anElement, "bg", "background"));
aNode.setBackground(background);
}
if (XmlDomUtils.hasAttribute(anElement, "fg", "foreground")) {
ScriptColor foreground = new ScriptColor(XmlDomUtils.getAttribute(anElement, "fg", "foreground"));
aNode.setForeground(foreground);
}
aNode.setReadonly(readBooleanAttribute(anElement, "ro", "readonly", Boolean.FALSE));
aNode.setEnabled(readBooleanAttribute(anElement, "en", "enabled", Boolean.TRUE));
Font font = readFont(anElement);
if (font != null) {
aNode.setFont(font);
}
if (XmlDomUtils.hasAttribute(anElement, "w", "width")) {
String width = XmlDomUtils.getAttribute(anElement, "w", "width");
if (width.length() > 2 && width.endsWith("px")) {
aNode.setWidth(Integer.parseInt(width.substring(0, width.length() - 2)));
}
}
if (XmlDomUtils.hasAttribute(anElement, "mw", "minWidth")) {
String minWidth = XmlDomUtils.getAttribute(anElement, "mw", "minWidth");
if (minWidth.length() > 2 && minWidth.endsWith("px")) {
aNode.setMinWidth(Integer.parseInt(minWidth.substring(0, minWidth.length() - 2)));
}
}
if (XmlDomUtils.hasAttribute(anElement, "mxw", "maxWidth")) {
String maxWidth = XmlDomUtils.getAttribute(anElement, "mxw", "maxWidth");
if (maxWidth.length() > 2 && maxWidth.endsWith("px")) {
aNode.setMaxWidth(Integer.parseInt(maxWidth.substring(0, maxWidth.length() - 2)));
}
}
if (XmlDomUtils.hasAttribute(anElement, "prw", "preferredWidth")) {
String preferredWidth = XmlDomUtils.getAttribute(anElement, "prw", "preferredWidth");
if (preferredWidth.length() > 2 && preferredWidth.endsWith("px")) {
aNode.setPreferredWidth(Integer.parseInt(preferredWidth.substring(0, preferredWidth.length() - 2)));
}
}
aNode.setMovable(readBooleanAttribute(anElement, "m", "movable", Boolean.TRUE));
aNode.setResizable(readBooleanAttribute(anElement, "rs", "resizable", Boolean.TRUE));
aNode.setSelectOnly(readBooleanAttribute(anElement, "so", "selectOnly", Boolean.FALSE));
aNode.setSortable(readBooleanAttribute(anElement, "s", "sortable", Boolean.TRUE));
aNode.setVisible(readBooleanAttribute(anElement, "v", "visible", Boolean.TRUE));
}
private void injectColumns(ModelGrid grid, List<GridColumnsNode> roots) {
JSObject publishedGrid = grid.getPublished();
roots.stream().forEach((node) -> {
publishedGrid.setMember(((ModelColumn) node.getTableColumn()).getName(), ((HasPublished) node).getPublished());
injectColumns(grid, node.getChildren());
});
}
}