From abd66fde99c8b4ac0ed3e3582cbd70aab72d90d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=F8=EDk?= Date: Sun, 9 Feb 2014 14:20:05 +0100 Subject: [PATCH] hiding conditional fields in generic tag editor (simple conditions only) --- .../decompiler/flash/gui/GenericTagPanel.java | 137 +++++++++++++++--- .../gui/generictageditors/BooleanEditor.java | 34 ++++- .../gui/generictageditors/ChangeListener.java | 26 ++++ .../generictageditors/GenericTagEditor.java | 7 + .../gui/generictageditors/NumberEditor.java | 66 ++++++--- .../gui/generictageditors/StringEditor.java | 37 ++++- 6 files changed, 262 insertions(+), 45 deletions(-) create mode 100644 trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/ChangeListener.java diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/GenericTagPanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/GenericTagPanel.java index ffdadbe9f..1c368a77a 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/GenericTagPanel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/GenericTagPanel.java @@ -17,6 +17,7 @@ package com.jpexs.decompiler.flash.gui; import com.jpexs.decompiler.flash.gui.generictageditors.BooleanEditor; +import com.jpexs.decompiler.flash.gui.generictageditors.ChangeListener; import com.jpexs.decompiler.flash.gui.generictageditors.GenericTagEditor; import com.jpexs.decompiler.flash.gui.generictageditors.NumberEditor; import com.jpexs.decompiler.flash.gui.generictageditors.StringEditor; @@ -24,13 +25,17 @@ import com.jpexs.decompiler.flash.gui.helpers.SpringUtilities; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.flash.tags.Tag; import com.jpexs.decompiler.flash.types.annotations.Calculated; +import com.jpexs.decompiler.flash.types.annotations.Conditional; import com.jpexs.decompiler.flash.types.annotations.SWFType; import java.awt.BorderLayout; import java.awt.Component; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.JEditorPane; @@ -43,13 +48,18 @@ import javax.swing.SpringLayout; * * @author JPEXS */ -public class GenericTagPanel extends JPanel { +public class GenericTagPanel extends JPanel implements ChangeListener { private final JEditorPane genericTagPropertiesEditorPane; private final JPanel genericTagPropertiesEditPanel; private final JScrollPane genericTagPropertiesEditorPaneScrollPanel; private final JScrollPane genericTagPropertiesEditPanelScrollPanel; private Tag tag; + private List keys = new ArrayList<>(); + private Map editors = new HashMap<>(); + private Map labels = new HashMap<>(); + private Map types = new HashMap<>(); + private Map> fieldPaths = new HashMap<>(); public GenericTagPanel() { super(new BorderLayout()); @@ -116,10 +126,19 @@ public class GenericTagPanel extends JPanel { } public void generateEditControls(Tag tag) { + editors.clear(); + fieldPaths.clear(); + labels.clear(); + types.clear(); + keys.clear(); genericTagPropertiesEditPanel.removeAll(); genericTagPropertiesEditPanel.setSize(0, 0); this.tag = tag; - int propCount = generateEditControlsRecursive(tag, ""); + generateEditControlsRecursive(tag, "", new ArrayList()); + change(null); + } + + private void relayout(int propCount) { //Lay out the panel. SpringUtilities.makeCompactGrid(genericTagPropertiesEditPanel, propCount, 3, //rows, cols @@ -128,7 +147,7 @@ public class GenericTagPanel extends JPanel { repaint(); } - private int generateEditControlsRecursive(Object obj, String parent) { + private int generateEditControlsRecursive(Object obj, String parent, List parentFields) { if (obj == null) { return 0; } @@ -146,7 +165,7 @@ public class GenericTagPanel extends JPanel { if (value != null) { int i = 0; for (Object obj1 : (Iterable) value) { - propCount += addEditor(name + "[" + i + "]", obj, field, i, obj1.getClass(), obj1); + propCount += addEditor(name + "[" + i + "]", obj, field, i, obj1.getClass(), obj1, parentFields); i++; } } @@ -154,11 +173,11 @@ public class GenericTagPanel extends JPanel { if (value != null) { for (int i = 0; i < Array.getLength(value); i++) { Object item = Array.get(value, i); - propCount += addEditor(name + "[" + i + "]", obj, field, i, item.getClass(), item); + propCount += addEditor(name + "[" + i + "]", obj, field, i, item.getClass(), item, parentFields); } } } else { - propCount += addEditor(name, obj, field, 0, field.getType(), value); + propCount += addEditor(name, obj, field, 0, field.getType(), value, parentFields); } } catch (IllegalArgumentException | IllegalAccessException ex) { Logger.getLogger(GenericTagPanel.class.getName()).log(Level.SEVERE, null, ex); @@ -167,38 +186,50 @@ public class GenericTagPanel extends JPanel { return propCount; } - private int addEditor(String name, Object obj, Field field, int index, Class type, Object value) throws IllegalArgumentException, IllegalAccessException { + private int addEditor(String name, Object obj, Field field, int index, Class type, Object value, List parentList) throws IllegalArgumentException, IllegalAccessException { Calculated calculated = field.getAnnotation(Calculated.class); if (calculated != null) { return 0; } + List parList = new ArrayList<>(parentList); + parList.add(field); SWFType swfType = field.getAnnotation(SWFType.class); Component editor; - 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(obj, field, index, type, swfType); + 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(name, obj, field, index, type, swfType); } else if (type.equals(boolean.class) || type.equals(Boolean.class)) { - editor = new BooleanEditor(obj, field, index, type); + editor = new BooleanEditor(name, obj, field, index, type); } else if (type.equals(String.class)) { - editor = new StringEditor(obj, field, index, type); + editor = new StringEditor(name, obj, field, index, type); } else { - return generateEditControlsRecursive(value, field.getName() + "."); - /*} else { - JTextArea textArea = new JTextArea(value == null ? "" : value.toString()); - textArea.setLineWrap(true); - textArea.setEditable(false); - editor = textArea;*/ + return generateEditControlsRecursive(value, field.getName() + ".", parList); + /*} else { + JTextArea textArea = new JTextArea(value == null ? "" : value.toString()); + textArea.setLineWrap(true); + textArea.setEditable(false); + editor = textArea;*/ + } + if (editor instanceof GenericTagEditor) { + GenericTagEditor ce = (GenericTagEditor) editor; + ce.addChangeListener(this); + editors.put(name, ce); + fieldPaths.put(name, parList); } JLabel label = new JLabel(name + ":", JLabel.TRAILING); genericTagPropertiesEditPanel.add(label); label.setLabelFor(editor); + labels.put(name, label); genericTagPropertiesEditPanel.add(editor); JLabel typeLabel = new JLabel(swfTypeToString(swfType), JLabel.TRAILING); genericTagPropertiesEditPanel.add(typeLabel); + types.put(name, typeLabel); + keys.add(name); + return 1; } @@ -232,8 +263,70 @@ public class GenericTagPanel extends JPanel { tag.setModified(true); setTagText(tag); } - + public Tag getTag() { return tag; } + + @Override + public void change(GenericTagEditor ed) { + for (String key : editors.keySet()) { + GenericTagEditor dependentEditor = editors.get(key); + Component dependentLabel = labels.get(key); + Component dependentTypeLabel = types.get(key); + List path = fieldPaths.get(key); + String p = ""; + boolean conditionMet = true; + for (Field f : path) { + String par = p; + if (!p.equals("")) { + p += "."; + } + p += f.getName(); + Conditional cond = f.getAnnotation(Conditional.class); + if (cond != null) { + String condVals[] = cond.value(); + if (condVals != null) { + for (String condVal : condVals) { //TODO: complex conditions + String ckey = ""; + if (!par.equals("")) { + ckey = par + "."; + } + ckey += condVal; + if (editors.containsKey(ckey)) { + GenericTagEditor editor = editors.get(ckey); + Object val = editor.getChangedValue(); + if (val instanceof Boolean) { + if (conditionMet) { + conditionMet = (Boolean) val; + } + } + ((Component) dependentEditor).setVisible(conditionMet); + dependentLabel.setVisible(conditionMet); + dependentTypeLabel.setVisible(conditionMet); + } + } + } + } + if (!conditionMet) { + break; + } + } + } + genericTagPropertiesEditPanel.removeAll(); + genericTagPropertiesEditPanel.setSize(0, 0); + int propCount = 0; + for (String key : keys) { + Component dependentEditor = (Component) editors.get(key); + Component dependentLabel = labels.get(key); + Component dependentTypeLabel = types.get(key); + if (dependentEditor.isVisible()) { + genericTagPropertiesEditPanel.add(dependentLabel); + genericTagPropertiesEditPanel.add(((Component) dependentEditor)); + genericTagPropertiesEditPanel.add(dependentTypeLabel); + propCount++; + } + } + relayout(propCount); + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/BooleanEditor.java b/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/BooleanEditor.java index b03b80d41..3fce3c0b6 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/BooleanEditor.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/BooleanEditor.java @@ -16,7 +16,8 @@ */ package com.jpexs.decompiler.flash.gui.generictageditors; -import java.awt.Color; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import java.lang.reflect.Field; import javax.swing.JCheckBox; @@ -30,13 +31,15 @@ public class BooleanEditor extends JCheckBox implements GenericTagEditor { private final Field field; private final int index; private final Class type; + private String fieldName; - public BooleanEditor(Object obj, Field field, int index, Class type) { + public BooleanEditor(String fieldName,Object obj, Field field, int index, Class type) { super(); this.obj = obj; this.field = field; this.index = index; this.type = type; + this.fieldName = fieldName; try { setSelected((boolean) ReflectionTools.getValue(obj, field, index)); } catch (IllegalArgumentException | IllegalAccessException ex) { @@ -52,4 +55,31 @@ public class BooleanEditor extends JCheckBox implements GenericTagEditor { // ignore } } + + @Override + public void addChangeListener(final ChangeListener l) { + final GenericTagEditor t=this; + addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + l.change(t); + } + }); + } + + @Override + public Object getChangedValue() { + return isSelected(); + } + + public String getFieldName() { + return fieldName; + } + + public Field getField() { + return field; + } + + } diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/ChangeListener.java b/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/ChangeListener.java new file mode 100644 index 000000000..4794adf4e --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/ChangeListener.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2014 JPEXS + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.jpexs.decompiler.flash.gui.generictageditors; + +/** + * + * @author JPEXS + */ +public interface ChangeListener { + public void change(GenericTagEditor editor); +} diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/GenericTagEditor.java b/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/GenericTagEditor.java index 8b39e6f0e..f2e8471fa 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/GenericTagEditor.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/GenericTagEditor.java @@ -16,6 +16,8 @@ */ package com.jpexs.decompiler.flash.gui.generictageditors; +import java.lang.reflect.Field; + /** * * @author JPEXS @@ -23,4 +25,9 @@ package com.jpexs.decompiler.flash.gui.generictageditors; public interface GenericTagEditor { public void save(); + + public void addChangeListener(ChangeListener l); + public Object getChangedValue(); + public String getFieldName(); + public Field getField(); } diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/NumberEditor.java b/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/NumberEditor.java index adb233e59..3c2f3716c 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/NumberEditor.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/NumberEditor.java @@ -18,7 +18,8 @@ package com.jpexs.decompiler.flash.gui.generictageditors; import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.annotations.SWFType; -import java.awt.Color; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; import java.lang.reflect.Field; import javax.swing.JSpinner; import javax.swing.SpinnerModel; @@ -35,8 +36,9 @@ public class NumberEditor extends JSpinner implements GenericTagEditor { private final int index; private final Class type; private final SWFType swfType; + private String fieldName; - public NumberEditor(Object obj, Field field, int index, Class type, SWFType swfType) { + public NumberEditor(String fieldName,Object obj, Field field, int index, Class type, SWFType swfType) { setSize(100, getSize().height); setMaximumSize(getSize()); this.obj = obj; @@ -44,30 +46,19 @@ public class NumberEditor extends JSpinner implements GenericTagEditor { this.index = index; this.type = type; this.swfType = swfType; + this.fieldName = fieldName; try { Object value = ReflectionTools.getValue(obj, field, index); setModel(getModel(swfType, value)); } catch (IllegalArgumentException | IllegalAccessException ex) { // ignore - } + } } @Override public void save() { try { - Object value = null; - if (type.equals(int.class) || type.equals(Integer.class)) { - value = Integer.parseInt(getValue().toString()); - } else if (type.equals(short.class) || type.equals(Short.class)) { - value = Short.parseShort(getValue().toString()); - } else if (type.equals(long.class) || type.equals(Long.class)) { - value = Long.parseLong(getValue().toString()); - } else if (type.equals(double.class) || type.equals(Double.class)) { - value = Double.parseDouble(getValue().toString()); - } else if (type.equals(float.class) || type.equals(Float.class)) { - value = Float.parseFloat(getValue().toString()); - } - + Object value = getChangedValue(); if (value != null) { ReflectionTools.setValue(obj, field, index, value); } @@ -75,7 +66,7 @@ public class NumberEditor extends JSpinner implements GenericTagEditor { // ignore } } - + private SpinnerModel getModel(SWFType swfType, Object value) { SpinnerNumberModel m = null; BasicType basicType = swfType == null ? BasicType.NONE : swfType.value(); @@ -130,7 +121,7 @@ public class NumberEditor extends JSpinner implements GenericTagEditor { } return m; } - + private double toDouble(Object value) { if (value instanceof Float) { return (double) (Float) value; @@ -163,4 +154,43 @@ public class NumberEditor extends JSpinner implements GenericTagEditor { } return 0; } + + @Override + public void addChangeListener(final ChangeListener l) { + final GenericTagEditor t = this; + addFocusListener(new FocusAdapter() { + + @Override + public void focusLost(FocusEvent e) { + l.change(t); + } + + }); + } + + @Override + public Object getChangedValue() { + Object value = null; + if (type.equals(int.class) || type.equals(Integer.class)) { + value = Integer.parseInt(getValue().toString()); + } else if (type.equals(short.class) || type.equals(Short.class)) { + value = Short.parseShort(getValue().toString()); + } else if (type.equals(long.class) || type.equals(Long.class)) { + value = Long.parseLong(getValue().toString()); + } else if (type.equals(double.class) || type.equals(Double.class)) { + value = Double.parseDouble(getValue().toString()); + } else if (type.equals(float.class) || type.equals(Float.class)) { + value = Float.parseFloat(getValue().toString()); + } + return value; + } + + public String getFieldName() { + return fieldName; + } + + public Field getField() { + return field; + } + } diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/StringEditor.java b/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/StringEditor.java index af12f074c..b84e9fe24 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/StringEditor.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/StringEditor.java @@ -16,7 +16,8 @@ */ package com.jpexs.decompiler.flash.gui.generictageditors; -import java.awt.Color; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; import java.lang.reflect.Field; import javax.swing.JTextArea; @@ -30,13 +31,15 @@ public class StringEditor extends JTextArea implements GenericTagEditor { private final Field field; private final int index; private final Class type; + private String fieldName; - public StringEditor(Object obj, Field field, int index, Class type) { + public StringEditor(String fieldName,Object obj, Field field, int index, Class type) { setLineWrap(true); this.obj = obj; this.field = field; this.index = index; - this.type = type; + this.type = type; + this.fieldName = fieldName; try { setText((String) ReflectionTools.getValue(obj, field, index)); } catch (IllegalArgumentException | IllegalAccessException ex) { @@ -52,4 +55,32 @@ public class StringEditor extends JTextArea implements GenericTagEditor { // ignore } } + + @Override + public void addChangeListener(final ChangeListener l) { + final GenericTagEditor t = this; + addFocusListener(new FocusAdapter() { + + @Override + public void focusLost(FocusEvent e) { + l.change(t); + } + + }); + } + + @Override + public Object getChangedValue() { + return getText(); + } + + @Override + public String getFieldName() { + return fieldName; + } + + public Field getField() { + return field; + } + }