From 472002ca1c62affc71c13eae728b6731424a5f48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Sun, 24 May 2015 21:14:35 +0200 Subject: [PATCH] Generic tag editor: Improved tables editing (Import/Export assets, etc.) --- .../tags/DefineSceneAndFrameLabelDataTag.java | 5 + .../flash/tags/ExportAssetsTag.java | 3 + .../flash/tags/ImportAssets2Tag.java | 3 + .../flash/tags/ImportAssetsTag.java | 3 + .../decompiler/flash/tags/SymbolClassTag.java | 3 + .../flash/types/annotations/Table.java | 35 ++ .../flash/gui/GenericTagTreePanel.java | 324 ++++++++++++------ 7 files changed, 267 insertions(+), 109 deletions(-) create mode 100644 libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/annotations/Table.java diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineSceneAndFrameLabelDataTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineSceneAndFrameLabelDataTag.java index 70adcbd83..dca28fe59 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineSceneAndFrameLabelDataTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineSceneAndFrameLabelDataTag.java @@ -22,6 +22,7 @@ import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.annotations.SWFArray; import com.jpexs.decompiler.flash.types.annotations.SWFType; +import com.jpexs.decompiler.flash.types.annotations.Table; import com.jpexs.helpers.ByteArrayRange; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -39,16 +40,20 @@ public class DefineSceneAndFrameLabelDataTag extends Tag { @SWFType(value = BasicType.EncodedU32) @SWFArray(value = "offset", countField = "sceneCount") + @Table(value = "scenes", itemName = "scene") public long[] sceneOffsets; @SWFArray(value = "name", countField = "sceneCount") + @Table(value = "scenes", itemName = "scene") public String[] sceneNames; @SWFType(value = BasicType.EncodedU32) @SWFArray(value = "frameNum", countField = "frameLabelCount") + @Table(value = "frames", itemName = "frame") public long[] frameNums; @SWFArray(countField = "frameLabelCount") + @Table(value = "frames", itemName = "frame") public String[] frameNames; /** diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/ExportAssetsTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/ExportAssetsTag.java index c04f19624..e81beddf8 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/ExportAssetsTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/ExportAssetsTag.java @@ -23,6 +23,7 @@ import com.jpexs.decompiler.flash.tags.base.SymbolClassTypeTag; import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.annotations.SWFArray; import com.jpexs.decompiler.flash.types.annotations.SWFType; +import com.jpexs.decompiler.flash.types.annotations.Table; import com.jpexs.helpers.ByteArrayRange; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -46,9 +47,11 @@ public class ExportAssetsTag extends SymbolClassTypeTag { */ @SWFType(value = BasicType.UI16) @SWFArray(value = "tag", countField = "count") + @Table(value = "assets", itemName = "asset") public List tags; @SWFArray(value = "name", countField = "count") + @Table(value = "assets", itemName = "asset") public List names; /** diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/ImportAssets2Tag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/ImportAssets2Tag.java index 0eb0676c1..4a8a82078 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/ImportAssets2Tag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/ImportAssets2Tag.java @@ -24,6 +24,7 @@ import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.annotations.Reserved; import com.jpexs.decompiler.flash.types.annotations.SWFArray; import com.jpexs.decompiler.flash.types.annotations.SWFType; +import com.jpexs.decompiler.flash.types.annotations.Table; import com.jpexs.helpers.ByteArrayRange; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -59,9 +60,11 @@ public class ImportAssets2Tag extends Tag implements ImportTag { */ @SWFType(value = BasicType.UI16) @SWFArray(value = "tag", countField = "count") + @Table(value = "assets", itemName = "asset") public List tags; @SWFArray(value = "name", countField = "count") + @Table(value = "assets", itemName = "asset") public List names; /** diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/ImportAssetsTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/ImportAssetsTag.java index 4626871f8..733284bca 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/ImportAssetsTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/ImportAssetsTag.java @@ -23,6 +23,7 @@ import com.jpexs.decompiler.flash.tags.base.ImportTag; import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.annotations.SWFArray; import com.jpexs.decompiler.flash.types.annotations.SWFType; +import com.jpexs.decompiler.flash.types.annotations.Table; import com.jpexs.helpers.ByteArrayRange; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -50,9 +51,11 @@ public class ImportAssetsTag extends Tag implements ImportTag { */ @SWFType(value = BasicType.UI16) @SWFArray(value = "tag", countField = "count") + @Table(value = "assets", itemName = "asset") public List tags; @SWFArray(value = "name", countField = "count") + @Table(value = "assets", itemName = "asset") public List names; /** diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/SymbolClassTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/SymbolClassTag.java index a2d4b0ac6..be19fe3fb 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/SymbolClassTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/SymbolClassTag.java @@ -23,6 +23,7 @@ import com.jpexs.decompiler.flash.tags.base.SymbolClassTypeTag; import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.annotations.SWFArray; import com.jpexs.decompiler.flash.types.annotations.SWFType; +import com.jpexs.decompiler.flash.types.annotations.Table; import com.jpexs.helpers.ByteArrayRange; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -38,9 +39,11 @@ public class SymbolClassTag extends SymbolClassTypeTag { @SWFType(value = BasicType.UI16) @SWFArray(value = "tag", countField = "numSymbols") + @Table(value = "symbols", itemName = "symbol") public List tags; @SWFArray(value = "name", countField = "numSymbols") + @Table(value = "symbols", itemName = "symbol") public List names; /** diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/annotations/Table.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/annotations/Table.java new file mode 100644 index 000000000..9987b4aef --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/annotations/Table.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.types.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * + * @author JPEXS + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface Table { + + String value(); + + String itemName() default ""; +} diff --git a/src/com/jpexs/decompiler/flash/gui/GenericTagTreePanel.java b/src/com/jpexs/decompiler/flash/gui/GenericTagTreePanel.java index 4208c4941..d6c21eae3 100644 --- a/src/com/jpexs/decompiler/flash/gui/GenericTagTreePanel.java +++ b/src/com/jpexs/decompiler/flash/gui/GenericTagTreePanel.java @@ -33,6 +33,7 @@ import com.jpexs.decompiler.flash.types.annotations.Internal; import com.jpexs.decompiler.flash.types.annotations.Multiline; import com.jpexs.decompiler.flash.types.annotations.SWFArray; import com.jpexs.decompiler.flash.types.annotations.SWFType; +import com.jpexs.decompiler.flash.types.annotations.Table; import com.jpexs.decompiler.flash.types.annotations.parser.AnnotationParseException; import com.jpexs.decompiler.flash.types.annotations.parser.ConditionEvaluator; import com.jpexs.helpers.ReflectionTools; @@ -66,6 +67,7 @@ import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JScrollPane; +import javax.swing.JTable; import javax.swing.JTree; import javax.swing.event.TreeModelListener; import javax.swing.plaf.basic.BasicLabelUI; @@ -90,6 +92,7 @@ public class GenericTagTreePanel extends GenericTagPanel { private Tag editedTag; private static final Map> fieldCache = new HashMap<>(); + private static final int FIELD_INDEX = 0; private class MyTree extends JTree { @@ -113,7 +116,7 @@ public class GenericTagTreePanel extends GenericTagPanel { private class MyTreeCellEditor extends AbstractCellEditor implements TreeCellEditor { - private GenericTagEditor editor = null; + private List editors = null; private final JTree tree; @@ -127,56 +130,68 @@ public class GenericTagTreePanel extends GenericTagPanel { public Component getTreeCellEditorComponent(JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row) { if (value instanceof FieldNode) { fnode = (FieldNode) value; - Field field = fnode.field; - int index = fnode.index; - Object obj = fnode.obj; - Class type; - try { - type = ReflectionTools.getValue(obj, field, index).getClass(); - } catch (IllegalArgumentException | IllegalAccessException ex) { - logger.log(Level.SEVERE, "Fixing characters order failed, recursion detected."); - return null; - } - SWFType swfType = field.getAnnotation(SWFType.class); - Multiline multiline = field.getAnnotation(Multiline.class); - if (type.equals(int.class) || type.equals(Integer.class) - || type.equals(short.class) || type.equals(Short.class) - || type.equals(long.class) || type.equals(Long.class) - || type.equals(double.class) || type.equals(Double.class) - || type.equals(float.class) || type.equals(Float.class)) { - editor = new NumberEditor(field.getName(), obj, field, index, type, swfType); - } else if (type.equals(boolean.class) || type.equals(Boolean.class)) { - editor = new BooleanEditor(field.getName(), obj, field, index, type); - } else if (type.equals(String.class)) { - editor = new StringEditor(field.getName(), obj, field, index, type, multiline != null); - } else if (type.equals(RGB.class) || type.equals(RGBA.class) || type.equals(ARGB.class)) { - editor = new ColorEditor(field.getName(), obj, field, index, type); - } - JPanel pan = new JPanel(); - FlowLayout fl = new FlowLayout(FlowLayout.LEFT, 0, 0); - fl.setAlignOnBaseline(true); - pan.setLayout(fl); - JLabel nameLabel = new JLabel(fnode.getNameType() + " = ") { - - @Override - public BaselineResizeBehavior getBaselineResizeBehavior() { - return Component.BaselineResizeBehavior.CONSTANT_ASCENT; + JPanel panSum = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); + panSum.setOpaque(false); + for (int i = 0; i < fnode.fieldSet.size(); i++) { + Field field = fnode.fieldSet.get(i);//fnode.fieldSet.get(FIELD_INDEX); + int index = fnode.index; + Object obj = fnode.obj; + Class type; + try { + type = ReflectionTools.getValue(obj, field, index).getClass(); + } catch (IllegalArgumentException | IllegalAccessException ex) { + logger.log(Level.SEVERE, "Fixing characters order failed, recursion detected."); + return null; } - - @Override - public int getBaseline(int width, int height) { - return 0; + GenericTagEditor editor = null; + SWFType swfType = field.getAnnotation(SWFType.class); + Multiline multiline = field.getAnnotation(Multiline.class); + if (type.equals(int.class) || type.equals(Integer.class) + || type.equals(short.class) || type.equals(Short.class) + || type.equals(long.class) || type.equals(Long.class) + || type.equals(double.class) || type.equals(Double.class) + || type.equals(float.class) || type.equals(Float.class)) { + editor = new NumberEditor(field.getName(), obj, field, index, type, swfType); + } else if (type.equals(boolean.class) || type.equals(Boolean.class)) { + editor = new BooleanEditor(field.getName(), obj, field, index, type); + } else if (type.equals(String.class)) { + editor = new StringEditor(field.getName(), obj, field, index, type, multiline != null); + } else if (type.equals(RGB.class) || type.equals(RGBA.class) || type.equals(ARGB.class)) { + editor = new ColorEditor(field.getName(), obj, field, index, type); } + if (editor != null) { + if (editors == null) { + editors = new ArrayList<>(); + } + editors.add(editor); + } + JPanel pan = new JPanel(); + FlowLayout fl = new FlowLayout(FlowLayout.LEFT, 0, 0); + fl.setAlignOnBaseline(true); + pan.setLayout(fl); + JLabel nameLabel = new JLabel(fnode.getNameType(i) + " = ") { - }; - pan.setBackground(Color.white); - nameLabel.setSize(nameLabel.getWidth(), ((Component) editor).getHeight()); - nameLabel.setAlignmentY(TOP_ALIGNMENT); - ((JComponent) editor).setAlignmentY(TOP_ALIGNMENT); - pan.add(nameLabel); - pan.add((Component) editor); - pan.setPreferredSize(new Dimension((int) nameLabel.getPreferredSize().getWidth() + 5 + (int) ((Component) editor).getPreferredSize().getWidth(), (int) ((Component) editor).getPreferredSize().getHeight())); - return pan; + @Override + public BaselineResizeBehavior getBaselineResizeBehavior() { + return Component.BaselineResizeBehavior.CONSTANT_ASCENT; + } + + @Override + public int getBaseline(int width, int height) { + return 0; + } + + }; + pan.setBackground(Color.white); + nameLabel.setSize(nameLabel.getWidth(), ((Component) editor).getHeight()); + nameLabel.setAlignmentY(TOP_ALIGNMENT); + ((JComponent) editor).setAlignmentY(TOP_ALIGNMENT); + pan.add(nameLabel); + pan.add((Component) editor); + pan.setPreferredSize(new Dimension((int) nameLabel.getPreferredSize().getWidth() + 5 + (int) ((Component) editor).getPreferredSize().getWidth(), (int) ((Component) editor).getPreferredSize().getHeight())); + panSum.add(pan); + } + return panSum; } return null; @@ -184,7 +199,11 @@ public class GenericTagTreePanel extends GenericTagPanel { @Override public Object getCellEditorValue() { - return editor.getChangedValue(); + List ret = new ArrayList<>(); + for (GenericTagEditor editor : editors) { + ret.add(editor.getChangedValue()); + } + return ret; } @Override @@ -215,8 +234,13 @@ public class GenericTagTreePanel extends GenericTagPanel { if (!depends.isEmpty()) { dep = true; } */ - editor.save(); - ((MyTreeModel) tree.getModel()).vchanged(tree.getSelectionPath()); + for (GenericTagEditor editor : editors) { + editor.save(); + } + TreePath sp = tree.getSelectionPath(); + if (sp != null) { + ((MyTreeModel) tree.getModel()).vchanged(sp); + } refreshTree(); return true; } @@ -241,18 +265,22 @@ public class GenericTagTreePanel extends GenericTagPanel { Object selObject = selPath.getLastPathComponent(); if (selObject instanceof FieldNode) { final FieldNode fnode = (FieldNode) selObject; - SWFArray swfArray = fnode.field.getAnnotation(SWFArray.class); + SWFArray swfArray = fnode.fieldSet.get(FIELD_INDEX).getAnnotation(SWFArray.class); + String itemStr = ""; if (swfArray != null) { itemStr = swfArray.value(); } + if (!fnode.fieldSet.itemName.isEmpty()) { + itemStr = fnode.fieldSet.itemName; + } if (itemStr.isEmpty()) { itemStr = AppStrings.translate("generictag.array.item"); } - if (ReflectionTools.needsIndex(fnode.field)) { + if (ReflectionTools.needsIndex(fnode.fieldSet.get(FIELD_INDEX))) { boolean canAdd = true; - if (!ReflectionTools.canAddToField(fnode.obj, fnode.field)) { + if (!ReflectionTools.canAddToField(fnode.obj, fnode.fieldSet.get(FIELD_INDEX))) { canAdd = false; } JPopupMenu p = new JPopupMenu(); @@ -262,7 +290,7 @@ public class GenericTagTreePanel extends GenericTagPanel { @Override public void actionPerformed(ActionEvent e) { - addItem(fnode.obj, fnode.field, 0); + addItem(fnode.obj, fnode.fieldSet.get(FIELD_INDEX), 0); } }); if (!canAdd) { @@ -276,7 +304,7 @@ public class GenericTagTreePanel extends GenericTagPanel { @Override public void actionPerformed(ActionEvent e) { - addItem(fnode.obj, fnode.field, fnode.index); + addItem(fnode.obj, fnode.fieldSet.get(FIELD_INDEX), fnode.index); } }); if (!canAdd) { @@ -289,7 +317,7 @@ public class GenericTagTreePanel extends GenericTagPanel { @Override public void actionPerformed(ActionEvent e) { - removeItem(fnode.obj, fnode.field, fnode.index); + removeItem(fnode.obj, fnode.fieldSet.get(FIELD_INDEX), fnode.index); } }); p.add(mi); @@ -299,7 +327,7 @@ public class GenericTagTreePanel extends GenericTagPanel { @Override public void actionPerformed(ActionEvent e) { - addItem(fnode.obj, fnode.field, fnode.index + 1); + addItem(fnode.obj, fnode.fieldSet.get(FIELD_INDEX), fnode.index + 1); } }); if (!canAdd) { @@ -313,7 +341,7 @@ public class GenericTagTreePanel extends GenericTagPanel { @Override public void actionPerformed(ActionEvent e) { - addItem(fnode.obj, fnode.field, ReflectionTools.getFieldSubSize(fnode.obj, fnode.field)); + addItem(fnode.obj, fnode.fieldSet.get(FIELD_INDEX), ReflectionTools.getFieldSubSize(fnode.obj, fnode.fieldSet.get(FIELD_INDEX))); } }); if (!canAdd) { @@ -349,28 +377,39 @@ public class GenericTagTreePanel extends GenericTagPanel { } + private static final class TableFieldNodes extends DefaultMutableTreeNode { + + List subnodes; + + public TableFieldNodes(List subnodes) { + this.subnodes = subnodes; + } + } + private static final class FieldNode extends DefaultMutableTreeNode { private Object obj; - private Field field; + private FieldSet fieldSet; private int index; - public FieldNode(Object obj, Field field, int index) { + public FieldNode(Object obj, FieldSet fieldSet, int index) { this.obj = obj; - this.field = field; + this.fieldSet = fieldSet; this.index = index; - if (getValue() == null) { - try { - if (List.class.isAssignableFrom(field.getType())) { - ReflectionTools.setValue(obj, field, new ArrayList<>()); - } else if (field.getType().isArray()) { - ReflectionTools.setValue(obj, field, Array.newInstance(field.getType().getComponentType(), 0)); + for (int i = 0; i < fieldSet.size(); i++) { + if (getValue(i) == null) { + try { + if (List.class.isAssignableFrom(fieldSet.get(i).getType())) { + ReflectionTools.setValue(obj, fieldSet.get(i), new ArrayList<>()); + } else if (fieldSet.get(i).getType().isArray()) { + ReflectionTools.setValue(obj, fieldSet.get(i), Array.newInstance(fieldSet.get(i).getType().getComponentType(), 0)); + } + } catch (IllegalArgumentException | IllegalAccessException ex) { + logger.log(Level.SEVERE, null, ex); } - } catch (IllegalArgumentException | IllegalAccessException ex) { - logger.log(Level.SEVERE, null, ex); } } } @@ -384,12 +423,38 @@ public class GenericTagTreePanel extends GenericTagPanel { */ @Override public String toString() { + String ret = ""; + if (index > -1) { + for (int i = 0; i < fieldSet.size(); i++) { + if (i > 0) { + ret += ", "; + } + ret += toString(i); + } + return ret; + } + if (fieldSet.size() == 1) { + ret = toString(0); + } else { + ret = fieldSet.name; + SWFArray t = fieldSet.get(0).getAnnotation(SWFArray.class); + if (t != null) { + ret += " [" + t.countField() + "]"; + } else { + ret += " []"; + } + } + + return "" + ret + ""; + } + + public String toString(int fieldIndex) { String valStr = ""; - if (ReflectionTools.needsIndex(field) && (index == -1)) { + if (ReflectionTools.needsIndex(fieldSet.get(fieldIndex)) && (index == -1)) { valStr += ""; - } else if (hasEditor(obj, field, index)) { - Object val = getValue(); + } else if (hasEditor(obj, fieldSet.get(fieldIndex), index)) { + Object val = getValue(fieldIndex); Color color = null; String colorAdd = ""; if (val instanceof RGB) { //Note: Can be RGBA too @@ -405,47 +470,47 @@ public class GenericTagTreePanel extends GenericTagPanel { valStr += " = " + colorAdd + val.toString(); } - return "" + getNameType() + valStr + ""; + return getNameType(fieldIndex) + valStr; } - public String getType() { - SWFType swfType = field.getAnnotation(SWFType.class); - SWFArray swfArray = field.getAnnotation(SWFArray.class); + public String getType(int fieldIndex) { + SWFType swfType = fieldSet.get(fieldIndex).getAnnotation(SWFType.class); + SWFArray swfArray = fieldSet.get(fieldIndex).getAnnotation(SWFArray.class); String typeStr = null; - if ((swfType != null || swfArray != null) && !(ReflectionTools.needsIndex(field) && (index > -1))) { - Class type = field.getType(); - if (ReflectionTools.needsIndex(field)) { - type = ReflectionTools.getFieldSubType(obj, field); + if ((swfType != null || swfArray != null) && !(ReflectionTools.needsIndex(fieldSet.get(fieldIndex)) && (index > -1))) { + Class type = fieldSet.get(fieldIndex).getType(); + if (ReflectionTools.needsIndex(fieldSet.get(fieldIndex))) { + type = ReflectionTools.getFieldSubType(obj, fieldSet.get(fieldIndex)); } typeStr = swfTypeToString(type, swfType, swfArray); } return typeStr; } - public String getNameType() { - String typeStr = getType(); - return getName() + (typeStr != null ? " : " + typeStr : ""); + public String getNameType(int fieldIndex) { + String typeStr = getType(fieldIndex); + return getName(fieldIndex) + (typeStr != null ? " : " + typeStr : ""); } - public String getName() { - SWFArray swfArray = field.getAnnotation(SWFArray.class); + public String getName(int fieldIndex) { + SWFArray swfArray = fieldSet.get(fieldIndex).getAnnotation(SWFArray.class); String name = ""; if (swfArray != null) { name = swfArray.value(); } - return (index > -1 ? name + "[" + index + "]" : field.getName()); + return (index > -1 ? name + "[" + index + "]" : fieldSet.get(fieldIndex).getName()); } - public Object getValue() { + public Object getValue(int fieldIndex) { try { - if (ReflectionTools.needsIndex(field) && (index == -1)) { - return ReflectionTools.getValue(obj, field); + if (ReflectionTools.needsIndex(fieldSet.get(fieldIndex)) && (index == -1)) { + return ReflectionTools.getValue(obj, fieldSet.get(fieldIndex)); } - Object val = ReflectionTools.getValue(obj, field, index); + Object val = ReflectionTools.getValue(obj, fieldSet.get(fieldIndex), index); if (val == null) { try { - val = ReflectionTools.newInstanceOf(field.getType()); - ReflectionTools.setValue(obj, field, index, val); + val = ReflectionTools.newInstanceOf(fieldSet.get(fieldIndex).getType()); + ReflectionTools.setValue(obj, fieldSet.get(fieldIndex), index, val); } catch (InstantiationException | IllegalAccessException ex) { logger.log(Level.SEVERE, null, ex); return null; @@ -461,7 +526,7 @@ public class GenericTagTreePanel extends GenericTagPanel { public int hashCode() { int hash = 7; hash = 11 * hash + Objects.hashCode(this.obj); - hash = 11 * hash + Objects.hashCode(this.field); + hash = 11 * hash + Objects.hashCode(this.fieldSet.get(FIELD_INDEX)); hash = 11 * hash + this.index; return hash; } @@ -478,7 +543,7 @@ public class GenericTagTreePanel extends GenericTagPanel { if (!Objects.equals(this.obj, other.obj)) { return false; } - if (!Objects.equals(this.field, other.field)) { + if (!Objects.equals(this.fieldSet.get(FIELD_INDEX), other.fieldSet.get(FIELD_INDEX))) { return false; } return this.index == other.index; @@ -521,7 +586,7 @@ public class GenericTagTreePanel extends GenericTagPanel { public void getDependentFields(String dependence, String currentPath, Object node, List ret) { if (node instanceof FieldNode) { FieldNode fnode = (FieldNode) node; - Conditional cond = fnode.field.getAnnotation(Conditional.class); + Conditional cond = fnode.fieldSet.get(FIELD_INDEX).getAnnotation(Conditional.class); if (cond != null) { ConditionEvaluator ev = new ConditionEvaluator(cond); String parentPath = currentPath.indexOf('.') == -1 ? "" : currentPath.substring(0, currentPath.lastIndexOf('.')); @@ -541,7 +606,7 @@ public class GenericTagTreePanel extends GenericTagPanel { int count = getChildCount(node); for (int i = 0; i < count; i++) { FieldNode f = (FieldNode) getChild(node, i); - getDependentFields(dependence, currentPath + "." + f.getName(), f, ret); + getDependentFields(dependence, currentPath + "." + f.getName(FIELD_INDEX), f, ret); } } @@ -557,7 +622,7 @@ public class GenericTagTreePanel extends GenericTagPanel { } if (obj instanceof FieldNode) { FieldNode fn = (FieldNode) obj; - parentPath += fn.getName(); + parentPath += fn.getName(FIELD_INDEX); } else { parentPath += obj.getClass().getSimpleName(); } @@ -579,11 +644,11 @@ public class GenericTagTreePanel extends GenericTagPanel { return new FieldNode(mtroot, filterFields(this, mtroot.getClass().getSimpleName(), mtroot.getClass(), limited).get(index), -1); } FieldNode fnode = (FieldNode) parent; - Field field = fnode.field; - if (ReflectionTools.needsIndex(field) && (fnode.index == -1)) { //Arrays ot Lists - return new FieldNode(fnode.obj, field, index); + Field field = fnode.fieldSet.get(FIELD_INDEX); + if (ReflectionTools.needsIndex(field) && (fnode.index == -1)) { //Arrays ot Lists + return new FieldNode(fnode.obj, fnode.fieldSet, index); } - parent = fnode.getValue(); + parent = fnode.getValue(FIELD_INDEX); return new FieldNode(parent, filterFields(this, getNodePathName(fnode), parent.getClass(), limited).get(index), -1); } @@ -605,7 +670,7 @@ public class GenericTagTreePanel extends GenericTagPanel { if (isLeaf(fnode)) { return 0; } - Field field = fnode.field; + Field field = fnode.fieldSet.get(FIELD_INDEX); if (ReflectionTools.needsIndex(field) && (fnode.index == -1)) { //Arrays or Lists try { if (field.get(fnode.obj) == null) { @@ -618,7 +683,7 @@ public class GenericTagTreePanel extends GenericTagPanel { return ReflectionTools.getFieldSubSize(fnode.obj, field); } - parent = fnode.getValue(); + parent = fnode.getValue(FIELD_INDEX); return filterFields(this, getNodePathName(fnode), parent.getClass(), limited).size(); } @@ -630,7 +695,7 @@ public class GenericTagTreePanel extends GenericTagPanel { } FieldNode fnode = (FieldNode) node; - Field field = fnode.field; + Field field = fnode.fieldSet.get(FIELD_INDEX); if (ReflectionTools.needsIndex(field) && fnode.index == -1) { return false; } @@ -777,9 +842,38 @@ public class GenericTagTreePanel extends GenericTagPanel { } } - private static List filterFields(MyTreeModel mod, String parentPath, Class cls, boolean limited) { - List ret = new ArrayList<>(); + private static class FieldSet { + + public List fields; + public String name; + public String itemName; + + public FieldSet(Field field) { + fields = new ArrayList<>(); + fields.add(field); + name = field.getName(); + } + + public FieldSet(List fields, String name, String itemName) { + this.fields = fields; + this.name = name; + this.itemName = itemName; + } + + public Field get(int index) { + return fields.get(index); + } + + public int size() { + return fields.size(); + } + + } + + private static List
filterFields(MyTreeModel mod, String parentPath, Class cls, boolean limited) { + List
ret = new ArrayList<>(); List fields = getAvailableFields(cls); + Map> tables = new HashMap<>(); for (Field f : fields) { if (limited) { Conditional cond = f.getAnnotation(Conditional.class); @@ -792,7 +886,7 @@ public class GenericTagTreePanel extends GenericTagPanel { FieldNode condnode = (FieldNode) (mod).getNodeByPath(fulldf); if (condnode != null) { - Object value = ReflectionTools.getValue(condnode.obj, condnode.field, condnode.index); + Object value = ReflectionTools.getValue(condnode.obj, condnode.fieldSet.get(FIELD_INDEX), condnode.index); if (value instanceof Boolean) { fieldMap.put(sf, (Boolean) value); } else if (value instanceof Integer) { @@ -817,7 +911,19 @@ public class GenericTagTreePanel extends GenericTagPanel { } } } - ret.add(f); + Table t = f.getAnnotation(Table.class); + List ret1; + if (t != null) { + String tableName = t.value(); + if (!tables.containsKey(tableName)) { + ret1 = new ArrayList<>(); + tables.put(tableName, ret1); + ret.add(new FieldSet(ret1, tableName, t.itemName())); + } + tables.get(tableName).add(f); + } else { + ret.add(new FieldSet(f)); + } } return ret; }