mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-01 19:04:38 +00:00
Generic tag editor: Add+Remove item from List/Array, match countField
This commit is contained in:
@@ -37,22 +37,33 @@ import com.jpexs.decompiler.flash.types.annotations.parser.ConditionEvaluator;
|
||||
import com.jpexs.decompiler.flash.types.annotations.parser.ParseException;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Component;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.AdjustmentEvent;
|
||||
import java.awt.event.AdjustmentListener;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.swing.Box;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JEditorPane;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollBar;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.SpringLayout;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -72,6 +83,9 @@ public class GenericTagPanel extends JPanel implements ChangeListener {
|
||||
private Map<String, List<Field>> fieldPaths = new HashMap<>();
|
||||
private Map<String, List<Integer>> fieldIndices = new HashMap<>();
|
||||
private HeaderLabel hdr;
|
||||
private Set<String> addKeys = new HashSet<>();
|
||||
private Map<String, Component> addButtons = new HashMap<>();
|
||||
private Map<String, Component> removeButtons = new HashMap<>();
|
||||
|
||||
public GenericTagPanel() {
|
||||
super(new BorderLayout());
|
||||
@@ -101,6 +115,9 @@ public class GenericTagPanel extends JPanel implements ChangeListener {
|
||||
labels.clear();
|
||||
types.clear();
|
||||
keys.clear();
|
||||
addKeys.clear();
|
||||
addButtons.clear();
|
||||
removeButtons.clear();
|
||||
genericTagPropertiesEditPanel.removeAll();
|
||||
genericTagPropertiesEditPanel.setSize(0, 0);
|
||||
}
|
||||
@@ -125,21 +142,21 @@ public class GenericTagPanel extends JPanel implements ChangeListener {
|
||||
for (String key : keys) {
|
||||
GenericTagEditor ed = editors.get(key);
|
||||
if (((Component) ed).isVisible()) {
|
||||
val += key + " : " + ed.getReadOnlyValue()+ "<br>";
|
||||
val += key + " : " + ed.getReadOnlyValue() + "<br>";
|
||||
}
|
||||
}
|
||||
//HTML for colors:
|
||||
val = "<html>"+val+"</html>";
|
||||
val = "<html>" + val + "</html>";
|
||||
genericTagPropertiesEditorPane.setContentType("text/html");
|
||||
genericTagPropertiesEditorPane.setText(val);
|
||||
genericTagPropertiesEditorPane.setCaretPosition(0);
|
||||
hdr.setText(tag.toString());
|
||||
hdr.setText(tag.toString());
|
||||
}
|
||||
|
||||
public void generateEditControls(Tag tag, boolean readonly) {
|
||||
clear();
|
||||
this.tag = tag;
|
||||
generateEditControlsRecursive(tag, "", new ArrayList<Field>(),new ArrayList<Integer>(), readonly);
|
||||
generateEditControlsRecursive(tag, "", new ArrayList<Field>(), new ArrayList<Integer>(), readonly);
|
||||
change(null);
|
||||
}
|
||||
|
||||
@@ -152,37 +169,81 @@ public class GenericTagPanel extends JPanel implements ChangeListener {
|
||||
repaint();
|
||||
}
|
||||
|
||||
private int generateEditControlsRecursive(Object obj, String parent, List<Field> parentFields, List<Integer> parentIndices, boolean readonly) {
|
||||
private int generateEditControlsRecursive(final Object obj, String parent, List<Field> parentFields, List<Integer> parentIndices, boolean readonly) {
|
||||
if (obj == null) {
|
||||
return 0;
|
||||
}
|
||||
Field[] fields = obj.getClass().getDeclaredFields();
|
||||
int propCount = 0;
|
||||
for (Field field : fields) {
|
||||
for (final Field field : fields) {
|
||||
try {
|
||||
if (Modifier.isStatic(field.getModifiers())) {
|
||||
continue;
|
||||
}
|
||||
field.setAccessible(true);
|
||||
String name = parent + field.getName();
|
||||
Object value = field.get(obj);
|
||||
final Object value = field.get(obj);
|
||||
if (List.class.isAssignableFrom(field.getType())) {
|
||||
if (value != null) {
|
||||
int i = 0;
|
||||
for (Object obj1 : (Iterable) value) {
|
||||
propCount += addEditor(name + "[" + i + "]", obj, field, i, obj1.getClass(), obj1, parentFields,parentIndices, readonly);
|
||||
final String subname = name + "[" + i + "]";
|
||||
propCount += addEditor(subname, obj, field, i, obj1.getClass(), obj1, parentFields, parentIndices, readonly);
|
||||
final int fi = i;
|
||||
i++;
|
||||
JButton removeButton = new JButton(View.getIcon("close16"));
|
||||
removeButton.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
removeItem(obj, field, fi);
|
||||
}
|
||||
});
|
||||
removeButtons.put(subname, removeButton);
|
||||
}
|
||||
}
|
||||
} else if (field.getType().isArray()) {
|
||||
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, parentFields,parentIndices, readonly);
|
||||
String subname = name + "[" + i + "]";
|
||||
propCount += addEditor(subname, obj, field, i, item.getClass(), item, parentFields, parentIndices, readonly);
|
||||
final int fi = i;
|
||||
JButton removeButton = new JButton(View.getIcon("close16"));
|
||||
removeButton.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
removeItem(obj, field, fi);
|
||||
}
|
||||
});
|
||||
removeButtons.put(subname, removeButton);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
propCount += addEditor(name, obj, field, 0, field.getType(), value, parentFields,parentIndices, readonly);
|
||||
propCount += addEditor(name, obj, field, 0, field.getType(), value, parentFields, parentIndices, readonly);
|
||||
}
|
||||
if (ReflectionTools.needsIndex(field) && !readonly) {
|
||||
JButton addButton = new JButton(View.getIcon("add16"));
|
||||
addButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
addItem(obj, field);
|
||||
}
|
||||
});
|
||||
name += "[]";
|
||||
|
||||
List<Field> parList = new ArrayList<>(parentFields);
|
||||
parList.add(field);
|
||||
fieldPaths.put(name, parList);
|
||||
|
||||
List<Integer> parIndices = new ArrayList<>(parentIndices);
|
||||
parIndices.add(0);
|
||||
fieldIndices.put(name, parIndices);
|
||||
|
||||
addRow(name, addButton, field);
|
||||
addKeys.add(name);
|
||||
addButtons.put(name, addButton);
|
||||
}
|
||||
} catch (IllegalArgumentException | IllegalAccessException ex) {
|
||||
Logger.getLogger(GenericTagPanel.class.getName()).log(Level.SEVERE, null, ex);
|
||||
@@ -191,14 +252,114 @@ public class GenericTagPanel extends JPanel implements ChangeListener {
|
||||
return propCount;
|
||||
}
|
||||
|
||||
private int addEditor(String name, Object obj, Field field, int index, Class<?> type, Object value, List<Field> parentList,List<Integer> parentIndices, boolean readonly) throws IllegalArgumentException, IllegalAccessException {
|
||||
private void removeItem(Object obj, Field field, int index) {
|
||||
final JScrollBar sb = genericTagPropertiesEditPanelScrollPanel.getVerticalScrollBar();
|
||||
final int val = sb.getValue(); //save scroll top
|
||||
SWFType swfType = field.getAnnotation(SWFType.class);
|
||||
if (swfType != null && !swfType.countField().equals("")) { //Fields with same countField must be removed from too
|
||||
Field fields[] = obj.getClass().getDeclaredFields();
|
||||
for (int f = 0; f < fields.length; f++) {
|
||||
SWFType fieldSwfType = fields[f].getAnnotation(SWFType.class);
|
||||
if (fieldSwfType != null && fieldSwfType.countField().equals(swfType.countField())) {
|
||||
ReflectionTools.removeFromField(obj, fields[f], index);
|
||||
}
|
||||
}
|
||||
try {
|
||||
//If countField exists, decrement, otherwise do nothing
|
||||
Field countField = obj.getClass().getDeclaredField(swfType.countField());
|
||||
if(countField!=null){
|
||||
int cnt = countField.getInt(obj);
|
||||
cnt--;
|
||||
countField.setInt(obj, cnt);
|
||||
}
|
||||
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) {
|
||||
//ignored
|
||||
}
|
||||
} else {
|
||||
ReflectionTools.removeFromField(obj, field, index);
|
||||
}
|
||||
|
||||
|
||||
generateEditControls(tag, false);
|
||||
|
||||
//Restore scroll top after some time. TODO: Handle this better. I don't know how :-(.
|
||||
new Thread() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Thread.sleep(500);
|
||||
} catch (InterruptedException ex) {
|
||||
Logger.getLogger(GenericTagPanel.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
View.execInEventDispatch(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
genericTagPropertiesEditPanelScrollPanel.getVerticalScrollBar().setValue(val);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}.start();
|
||||
}
|
||||
|
||||
private void addItem(Object obj, Field field) {
|
||||
final JScrollBar sb = genericTagPropertiesEditPanelScrollPanel.getVerticalScrollBar();
|
||||
final int val = sb.getValue(); //save scroll top
|
||||
SWFType swfType = field.getAnnotation(SWFType.class);
|
||||
if (swfType != null && !swfType.countField().equals("")) { //Fields with same countField must be enlarged too
|
||||
Field fields[] = obj.getClass().getDeclaredFields();
|
||||
for (int f = 0; f < fields.length; f++) {
|
||||
SWFType fieldSwfType = fields[f].getAnnotation(SWFType.class);
|
||||
if (fieldSwfType != null && fieldSwfType.countField().equals(swfType.countField())) {
|
||||
ReflectionTools.enlargeField(obj, fields[f], true);
|
||||
}
|
||||
}
|
||||
try {
|
||||
//If countField exists, increment, otherwise do nothing
|
||||
Field countField = obj.getClass().getDeclaredField(swfType.countField());
|
||||
if(countField!=null){
|
||||
int cnt = countField.getInt(obj);
|
||||
cnt++;
|
||||
countField.setInt(obj, cnt);
|
||||
}
|
||||
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) {
|
||||
//ignored
|
||||
}
|
||||
} else {
|
||||
ReflectionTools.enlargeField(obj, field, true);
|
||||
}
|
||||
generateEditControls(tag, false);
|
||||
|
||||
//Restore scroll top after some time. TODO: Handle this better. I don't know how :-(.
|
||||
new Thread() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Thread.sleep(500);
|
||||
} catch (InterruptedException ex) {
|
||||
Logger.getLogger(GenericTagPanel.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
View.execInEventDispatch(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
genericTagPropertiesEditPanelScrollPanel.getVerticalScrollBar().setValue(val);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}.start();
|
||||
}
|
||||
|
||||
private int addEditor(String name, Object obj, Field field, int index, Class<?> type, Object value, List<Field> parentList, List<Integer> parentIndices, boolean readonly) throws IllegalArgumentException, IllegalAccessException {
|
||||
Calculated calculated = field.getAnnotation(Calculated.class);
|
||||
if (calculated != null) {
|
||||
return 0;
|
||||
}
|
||||
List<Field> parList = new ArrayList<>(parentList);
|
||||
parList.add(field);
|
||||
|
||||
|
||||
List<Integer> parIndices = new ArrayList<>(parentIndices);
|
||||
parIndices.add(index);
|
||||
Internal inter = field.getAnnotation(Internal.class);
|
||||
@@ -217,9 +378,9 @@ public class GenericTagPanel extends JPanel implements ChangeListener {
|
||||
editor = new BooleanEditor(name, obj, field, index, type);
|
||||
} else if (type.equals(String.class)) {
|
||||
editor = new StringEditor(name, obj, field, index, type);
|
||||
} else if (type.equals(RGB.class) || type.equals(RGBA.class) || type.equals(ARGB.class)){
|
||||
} else if (type.equals(RGB.class) || type.equals(RGBA.class) || type.equals(ARGB.class)) {
|
||||
editor = new ColorEditor(name, obj, field, index, type);
|
||||
}else {
|
||||
} else {
|
||||
if (value == null) {
|
||||
if (readonly) {
|
||||
return 0;
|
||||
@@ -227,7 +388,7 @@ public class GenericTagPanel extends JPanel implements ChangeListener {
|
||||
Optional opt = field.getAnnotation(Optional.class);
|
||||
if (opt == null) {
|
||||
try {
|
||||
value = field.getType().newInstance();
|
||||
value = ReflectionTools.newInstanceOf(field.getType());
|
||||
field.set(obj, value);
|
||||
} catch (InstantiationException | IllegalAccessException ex) {
|
||||
Logger.getLogger(GenericTagPanel.class.getName()).log(Level.SEVERE, null, ex);
|
||||
@@ -237,28 +398,31 @@ public class GenericTagPanel extends JPanel implements ChangeListener {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return generateEditControlsRecursive(value, name + ".", parList,parIndices, readonly);
|
||||
return generateEditControlsRecursive(value, name + ".", parList, parIndices, readonly);
|
||||
}
|
||||
if (editor instanceof GenericTagEditor) {
|
||||
GenericTagEditor ce = (GenericTagEditor) editor;
|
||||
ce.addChangeListener(this);
|
||||
editors.put(name, ce);
|
||||
fieldPaths.put(name, parList);
|
||||
fieldIndices.put(name,parIndices);
|
||||
fieldIndices.put(name, parIndices);
|
||||
addRow(name, editor, field);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
private void addRow(String name, Component editor, Field field) {
|
||||
JLabel label = new JLabel(name + ":", JLabel.TRAILING);
|
||||
label.setVerticalAlignment(JLabel.TOP);
|
||||
genericTagPropertiesEditPanel.add(label);
|
||||
label.setLabelFor(editor);
|
||||
labels.put(name, label);
|
||||
genericTagPropertiesEditPanel.add(editor);
|
||||
JLabel typeLabel = new JLabel(swfTypeToString(swfType), JLabel.TRAILING);
|
||||
JLabel typeLabel = new JLabel(swfTypeToString(field.getAnnotation(SWFType.class)), JLabel.TRAILING);
|
||||
typeLabel.setVerticalAlignment(JLabel.TOP);
|
||||
genericTagPropertiesEditPanel.add(typeLabel);
|
||||
types.put(name, typeLabel);
|
||||
keys.add(name);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
public String swfTypeToString(SWFType swfType) {
|
||||
@@ -305,17 +469,17 @@ public class GenericTagPanel extends JPanel implements ChangeListener {
|
||||
List<Field> path = fieldPaths.get(key);
|
||||
List<Integer> indices = fieldIndices.get(key);
|
||||
String p = "";
|
||||
boolean conditionMet = true;
|
||||
for (int i=0;i<path.size();i++) {
|
||||
boolean conditionMet = true;
|
||||
for (int i = 0; i < path.size(); i++) {
|
||||
Field f = path.get(i);
|
||||
int index=indices.get(i);
|
||||
int index = indices.get(i);
|
||||
String par = p;
|
||||
if (!p.equals("")) {
|
||||
p += ".";
|
||||
}
|
||||
p += f.getName();
|
||||
if(ReflectionTools.needsIndex(f)){
|
||||
p+="["+index+"]";
|
||||
if (ReflectionTools.needsIndex(f)) {
|
||||
p += "[" + index + "]";
|
||||
}
|
||||
Conditional cond = f.getAnnotation(Conditional.class);
|
||||
if (cond != null) {
|
||||
@@ -359,7 +523,18 @@ public class GenericTagPanel extends JPanel implements ChangeListener {
|
||||
genericTagPropertiesEditPanel.setSize(0, 0);
|
||||
int propCount = 0;
|
||||
for (String key : keys) {
|
||||
Component dependentEditor = (Component) editors.get(key);
|
||||
|
||||
Component dependentEditor = null;
|
||||
if (addKeys.contains(key)) {
|
||||
dependentEditor = addButtons.get(key);
|
||||
} else if (removeButtons.containsKey(key)) { //It's array/list, add remove button
|
||||
JPanel editRemPanel = new JPanel(new FlowLayout());
|
||||
editRemPanel.add((Component) editors.get(key));
|
||||
editRemPanel.add(removeButtons.get(key));
|
||||
dependentEditor = editRemPanel;
|
||||
} else {
|
||||
dependentEditor = (Component) editors.get(key);
|
||||
}
|
||||
Component dependentLabel = labels.get(key);
|
||||
Component dependentTypeLabel = types.get(key);
|
||||
if (dependentEditor.isVisible()) {
|
||||
@@ -368,10 +543,10 @@ public class GenericTagPanel extends JPanel implements ChangeListener {
|
||||
genericTagPropertiesEditPanel.add(dependentTypeLabel);
|
||||
propCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
genericTagPropertiesEditPanel.add(new JPanel());
|
||||
genericTagPropertiesEditPanel.add(new JPanel());
|
||||
genericTagPropertiesEditPanel.add(new JPanel());
|
||||
relayout(propCount+1);
|
||||
relayout(propCount + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,10 @@ package com.jpexs.decompiler.flash.gui.generictageditors;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -31,35 +34,171 @@ public class ReflectionTools {
|
||||
if (List.class.isAssignableFrom(field.getType())) {
|
||||
return ((List) value).get(index);
|
||||
}
|
||||
|
||||
|
||||
if (field.getType().isArray()) {
|
||||
return Array.get(value, index);
|
||||
}
|
||||
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static boolean needsIndex(Field field){
|
||||
|
||||
public static boolean needsIndex(Field field) {
|
||||
if (List.class.isAssignableFrom(field.getType())) {
|
||||
return true;
|
||||
}
|
||||
else if (field.getType().isArray()) {
|
||||
} else if (field.getType().isArray()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void setValue(Object obj, Field field, int index, Object newValue) throws IllegalArgumentException, IllegalAccessException {
|
||||
Object value = field.get(obj);
|
||||
if (List.class.isAssignableFrom(field.getType())) {
|
||||
((List) value).set(index, newValue);
|
||||
}
|
||||
else if (field.getType().isArray()) {
|
||||
} else if (field.getType().isArray()) {
|
||||
Array.set(value, index, newValue);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
field.set(obj, newValue);
|
||||
}
|
||||
}
|
||||
|
||||
public static Object newInstanceOf(Class cls) throws InstantiationException, IllegalAccessException {
|
||||
if (cls == Integer.class || cls == int.class) {
|
||||
return new Integer(0);
|
||||
} else if (cls == Float.class || cls == float.class) {
|
||||
return new Float(0.0f);
|
||||
} else if (cls == Double.class || cls == double.class ) {
|
||||
return new Double(0);
|
||||
} else if(cls == Long.class || cls == long.class){
|
||||
return new Long(0L);
|
||||
}
|
||||
return cls.newInstance();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static boolean enlargeList(Object object, Field field) {
|
||||
if (!List.class.isAssignableFrom(field.getType())) {
|
||||
return false;
|
||||
}
|
||||
List list;
|
||||
try {
|
||||
list = (List) field.get(object);
|
||||
} catch (IllegalArgumentException | IllegalAccessException ex) {
|
||||
Logger.getLogger(ReflectionTools.class.getName()).log(Level.SEVERE, null, ex);
|
||||
return false;
|
||||
}
|
||||
ParameterizedType listType = (ParameterizedType) field.getGenericType();
|
||||
Class<?> parameterClass = (Class<?>) listType.getActualTypeArguments()[0];
|
||||
try {
|
||||
Object val = newInstanceOf(parameterClass);
|
||||
list.add(val);
|
||||
} catch (InstantiationException | IllegalAccessException ex) {
|
||||
Logger.getLogger(ReflectionTools.class.getName()).log(Level.SEVERE, null, ex);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean enlargeArray(Object object, Field field, boolean notnull) {
|
||||
if (!field.getType().isArray()) {
|
||||
return false;
|
||||
}
|
||||
Object arrValue;
|
||||
try {
|
||||
arrValue = field.get(object);
|
||||
} catch (IllegalArgumentException | IllegalAccessException ex) {
|
||||
Logger.getLogger(ReflectionTools.class.getName()).log(Level.SEVERE, null, ex);
|
||||
return false;
|
||||
}
|
||||
Class componentClass = arrValue.getClass().getComponentType();
|
||||
int originalSize = Array.getLength(arrValue);
|
||||
Object copy = Array.newInstance(componentClass, originalSize + 1);
|
||||
for (int i = 0; i < originalSize; i++) {
|
||||
Array.set(copy, i, Array.get(arrValue, i));
|
||||
}
|
||||
if (!componentClass.isPrimitive() && notnull) {
|
||||
try {
|
||||
Array.set(copy, originalSize, componentClass.newInstance());
|
||||
} catch (InstantiationException | IllegalAccessException ex) {
|
||||
Logger.getLogger(ReflectionTools.class.getName()).log(Level.SEVERE, null, ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
try {
|
||||
field.set(object, copy);
|
||||
} catch (IllegalArgumentException | IllegalAccessException ex) {
|
||||
Logger.getLogger(ReflectionTools.class.getName()).log(Level.SEVERE, null, ex);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean enlargeField(Object object, Field field, boolean notnull) {
|
||||
if (List.class.isAssignableFrom(field.getType())) {
|
||||
return enlargeList(object, field);
|
||||
}
|
||||
|
||||
if (field.getType().isArray()) {
|
||||
return enlargeArray(object, field, notnull);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean removeFromField(Object object, Field field,int index){
|
||||
if (List.class.isAssignableFrom(field.getType())) {
|
||||
return removeFromList(object, field,index);
|
||||
}
|
||||
|
||||
if (field.getType().isArray()) {
|
||||
return removeFromArray(object, field, index);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean removeFromList(Object object, Field field,int index){
|
||||
List list;
|
||||
try {
|
||||
list=(List)field.get(object);
|
||||
} catch (IllegalArgumentException | IllegalAccessException ex) {
|
||||
Logger.getLogger(ReflectionTools.class.getName()).log(Level.SEVERE, null, ex);
|
||||
return false;
|
||||
}
|
||||
if(index<0 || index>=list.size()){
|
||||
return false;
|
||||
}
|
||||
list.remove(index);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean removeFromArray(Object object, Field field, int index){
|
||||
Object arrValue;
|
||||
try {
|
||||
arrValue = field.get(object);
|
||||
} catch (IllegalArgumentException | IllegalAccessException ex) {
|
||||
Logger.getLogger(ReflectionTools.class.getName()).log(Level.SEVERE, null, ex);
|
||||
return false;
|
||||
}
|
||||
Class componentClass = arrValue.getClass().getComponentType();
|
||||
int originalSize = Array.getLength(arrValue);
|
||||
Object copy = Array.newInstance(componentClass, originalSize - 1);
|
||||
int pos=0;
|
||||
//copy all before index
|
||||
for (int i = 0; i < index; i++) {
|
||||
Array.set(copy, pos, Array.get(arrValue, i));
|
||||
pos++;
|
||||
}
|
||||
//copy all after index
|
||||
for (int i = index+1; i <originalSize ; i++) {
|
||||
Array.set(copy, pos, Array.get(arrValue, i));
|
||||
pos++;
|
||||
}
|
||||
try {
|
||||
field.set(object, copy);
|
||||
} catch (IllegalArgumentException | IllegalAccessException ex) {
|
||||
Logger.getLogger(ReflectionTools.class.getName()).log(Level.SEVERE, null, ex);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
BIN
trunk/src/com/jpexs/decompiler/flash/gui/graphics/add16.png
Normal file
BIN
trunk/src/com/jpexs/decompiler/flash/gui/graphics/add16.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 733 B |
@@ -33,14 +33,15 @@ import java.io.OutputStream;
|
||||
*/
|
||||
public class DefineSceneAndFrameLabelDataTag extends Tag {
|
||||
|
||||
@SWFType(BasicType.EncodedU32)
|
||||
@SWFType(value=BasicType.EncodedU32,countField="sceneCount")
|
||||
public long[] sceneOffsets;
|
||||
|
||||
@SWFType(countField="sceneCount")
|
||||
public String[] sceneNames;
|
||||
|
||||
@SWFType(BasicType.EncodedU32)
|
||||
@SWFType(value=BasicType.EncodedU32,countField="frameLabelCount")
|
||||
public long[] frameNums;
|
||||
|
||||
@SWFType(countField = "frameLabelCount")
|
||||
public String[] frameNames;
|
||||
public static final int ID = 86;
|
||||
|
||||
|
||||
@@ -38,15 +38,16 @@ public class ExportAssetsTag extends Tag {
|
||||
/**
|
||||
* HashMap with assets
|
||||
*/
|
||||
@SWFType(BasicType.UI16)
|
||||
@SWFType(value = BasicType.UI16,countField = "count")
|
||||
public List<Integer> tags;
|
||||
@SWFType(countField = "count")
|
||||
public List<String> names;
|
||||
public static final int ID = 56;
|
||||
|
||||
public ExportAssetsTag() {
|
||||
super(null, ID, "ExportAssets", new byte[]{}, 0);
|
||||
tags = new ArrayList<>();
|
||||
names = new ArrayList<>();
|
||||
names = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -27,7 +27,10 @@ import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Imports characters from another file, v2
|
||||
@@ -46,7 +49,10 @@ public class ImportAssets2Tag extends Tag implements ImportTag {
|
||||
/**
|
||||
* HashMap with assets
|
||||
*/
|
||||
public HashMap<Integer, String> assets;
|
||||
@SWFType(value=BasicType.UI16,countField = "count")
|
||||
public List<Integer> characterIds;
|
||||
@SWFType(countField = "count")
|
||||
public List<String> names;
|
||||
public static final int ID = 71;
|
||||
|
||||
/**
|
||||
@@ -60,16 +66,18 @@ public class ImportAssets2Tag extends Tag implements ImportTag {
|
||||
*/
|
||||
public ImportAssets2Tag(SWF swf, byte[] data, int version, long pos) throws IOException {
|
||||
super(swf, ID, "ImportAssets2", data, pos);
|
||||
assets = new HashMap<>();
|
||||
characterIds = new ArrayList<>();
|
||||
names = new ArrayList<>();
|
||||
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
|
||||
url = sis.readString();
|
||||
reserved1 = sis.readUI8();//reserved, must be 1
|
||||
reserved2 = sis.readUI8();//reserved, must be 0
|
||||
int count = sis.readUI16();
|
||||
for (int i = 0; i < count; i++) {
|
||||
int characterId = sis.readUI16();
|
||||
String name = sis.readString();
|
||||
assets.put(characterId, name);
|
||||
int charId = sis.readUI16();
|
||||
String tagName = sis.readString();
|
||||
characterIds.add(charId);
|
||||
names.add(tagName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,10 +96,10 @@ public class ImportAssets2Tag extends Tag implements ImportTag {
|
||||
sos.writeString(url);
|
||||
sos.writeUI8(reserved1);
|
||||
sos.writeUI8(reserved2);
|
||||
sos.writeUI16(assets.size());
|
||||
for (int characterId : assets.keySet()) {
|
||||
sos.writeUI16(characterId);
|
||||
sos.writeString(assets.get(characterId));
|
||||
sos.writeUI16(characterIds.size());
|
||||
for (int i=0;i<characterIds.size();i++) {
|
||||
sos.writeUI16(characterIds.get(i));
|
||||
sos.writeString(names.get(i));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
@@ -99,7 +107,11 @@ public class ImportAssets2Tag extends Tag implements ImportTag {
|
||||
}
|
||||
|
||||
@Override
|
||||
public HashMap<Integer, String> getAssets() {
|
||||
public Map<Integer, String> getAssets() {
|
||||
Map<Integer, String> assets = new HashMap<>();
|
||||
for (int i = 0; i < characterIds.size(); i++) {
|
||||
assets.put(characterIds.get(i), names.get(i));
|
||||
}
|
||||
return assets;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,11 +20,16 @@ import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.ImportTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Imports characters from another file
|
||||
@@ -37,7 +42,10 @@ public class ImportAssetsTag extends Tag implements ImportTag {
|
||||
/**
|
||||
* HashMap with assets
|
||||
*/
|
||||
public HashMap<Integer, String> assets;
|
||||
@SWFType(value=BasicType.UI16,countField = "count")
|
||||
public List<Integer> characterIds;
|
||||
@SWFType(countField = "count")
|
||||
public List<String> names;
|
||||
public static final int ID = 57;
|
||||
|
||||
/**
|
||||
@@ -51,14 +59,16 @@ public class ImportAssetsTag extends Tag implements ImportTag {
|
||||
*/
|
||||
public ImportAssetsTag(SWF swf, byte[] data, int version, long pos) throws IOException {
|
||||
super(swf, ID, "ImportAssets", data, pos);
|
||||
assets = new HashMap<>();
|
||||
characterIds = new ArrayList<>();
|
||||
names = new ArrayList<>();
|
||||
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
|
||||
url = sis.readString();
|
||||
int count = sis.readUI16();
|
||||
for (int i = 0; i < count; i++) {
|
||||
int characterId = sis.readUI16();
|
||||
String name = sis.readString();
|
||||
assets.put(characterId, name);
|
||||
int charId = sis.readUI16();
|
||||
String tagName = sis.readString();
|
||||
characterIds.add(charId);
|
||||
names.add(tagName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,10 +85,10 @@ public class ImportAssetsTag extends Tag implements ImportTag {
|
||||
SWFOutputStream sos = new SWFOutputStream(os, version);
|
||||
try {
|
||||
sos.writeString(url);
|
||||
sos.writeUI16(assets.size());
|
||||
for (int characterId : assets.keySet()) {
|
||||
sos.writeUI16(characterId);
|
||||
sos.writeString(assets.get(characterId));
|
||||
sos.writeUI16(characterIds.size());
|
||||
for (int i = 0; i < characterIds.size(); i++) {
|
||||
sos.writeUI16(characterIds.get(i));
|
||||
sos.writeString(names.get(i));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
@@ -86,7 +96,11 @@ public class ImportAssetsTag extends Tag implements ImportTag {
|
||||
}
|
||||
|
||||
@Override
|
||||
public HashMap<Integer, String> getAssets() {
|
||||
public Map<Integer, String> getAssets() {
|
||||
Map<Integer, String> assets = new HashMap<>();
|
||||
for (int i = 0; i < characterIds.size(); i++) {
|
||||
assets.put(characterIds.get(i), names.get(i));
|
||||
}
|
||||
return assets;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,8 +28,9 @@ import java.io.OutputStream;
|
||||
|
||||
public class SymbolClassTag extends Tag {
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
@SWFType(value=BasicType.UI16,countField = "numSymbols")
|
||||
public int[] tagIDs;
|
||||
@SWFType(countField = "numSymbols")
|
||||
public String[] classNames;
|
||||
public static final int ID = 76;
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.jpexs.decompiler.flash.tags.base;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -25,6 +26,6 @@ import java.util.HashMap;
|
||||
public interface ImportTag {
|
||||
|
||||
public String getUrl();
|
||||
|
||||
public HashMap<Integer, String> getAssets();
|
||||
|
||||
public Map<Integer, String> getAssets();
|
||||
}
|
||||
|
||||
@@ -36,5 +36,6 @@ public enum BasicType {
|
||||
FLOAT16,
|
||||
FIXED,
|
||||
FIXED8,
|
||||
NONE
|
||||
NONE,
|
||||
OTHER
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ import java.lang.annotation.Target;
|
||||
public @interface SWFType {
|
||||
|
||||
/// Type of value
|
||||
BasicType value();
|
||||
BasicType value() default BasicType.OTHER;
|
||||
|
||||
/// Alternate type when condition is met
|
||||
BasicType alternateValue() default BasicType.NONE;
|
||||
|
||||
@@ -34,11 +34,12 @@ public class GRADIENTBEVELFILTER extends FILTER {
|
||||
/**
|
||||
* Gradient colors
|
||||
*/
|
||||
@SWFType(countField = "numColors")
|
||||
public RGBA[] gradientColors = new RGBA[0];
|
||||
/**
|
||||
* Gradient ratios
|
||||
*/
|
||||
@SWFType(BasicType.UI8)
|
||||
@SWFType(value=BasicType.UI8,countField = "numColors")
|
||||
public int[] gradientRatio = new int[0];
|
||||
/**
|
||||
* Horizontal blur amount
|
||||
|
||||
@@ -34,11 +34,12 @@ public class GRADIENTGLOWFILTER extends FILTER {
|
||||
/**
|
||||
* Gradient colors
|
||||
*/
|
||||
@SWFType(countField = "numColors")
|
||||
public RGBA[] gradientColors = new RGBA[0];
|
||||
/**
|
||||
* Gradient ratios
|
||||
*/
|
||||
@SWFType(BasicType.UI8)
|
||||
@SWFType(value=BasicType.UI8,countField = "numColors")
|
||||
public int[] gradientRatio;
|
||||
/**
|
||||
* Horizontal blur amount
|
||||
|
||||
Reference in New Issue
Block a user