diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/GenericTagPanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/GenericTagPanel.java index 1f8b7547d..ac2a7dc7b 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/GenericTagPanel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/GenericTagPanel.java @@ -16,16 +16,33 @@ */ package com.jpexs.decompiler.flash.gui; +import com.jpexs.decompiler.flash.gui.generictageditors.BooleanEditor; +import com.jpexs.decompiler.flash.gui.generictageditors.DoubleEditor; +import com.jpexs.decompiler.flash.gui.generictageditors.FloatEditor; +import com.jpexs.decompiler.flash.gui.generictageditors.GenericTagEditor; +import com.jpexs.decompiler.flash.gui.generictageditors.IntegerEditor; +import com.jpexs.decompiler.flash.gui.generictageditors.LongEditor; +import com.jpexs.decompiler.flash.gui.generictageditors.ShortEditor; +import com.jpexs.decompiler.flash.gui.generictageditors.StringEditor; +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.RECT; +import com.jpexs.decompiler.flash.types.RGB; +import com.jpexs.decompiler.flash.types.ZONERECORD; import java.awt.BorderLayout; +import java.awt.Component; import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.JEditorPane; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; +import javax.swing.JTextArea; +import javax.swing.SpringLayout; /** * @@ -37,6 +54,7 @@ public class GenericTagPanel extends JPanel { private final JPanel genericTagPropertiesEditPanel; private final JScrollPane genericTagPropertiesEditorPaneScrollPanel; private final JScrollPane genericTagPropertiesEditPanelScrollPanel; + private Tag tag; public GenericTagPanel() { super(new BorderLayout()); @@ -52,9 +70,15 @@ public class GenericTagPanel extends JPanel { add(genericTagPropertiesEditorPaneScrollPanel); genericTagPropertiesEditPanel = new JPanel(); + genericTagPropertiesEditPanel.setLayout(new SpringLayout()); genericTagPropertiesEditPanelScrollPanel = new JScrollPane(genericTagPropertiesEditPanel); } + public void clear() { + tag = null; + genericTagPropertiesEditPanel.removeAll(); + } + public void setEditMode(boolean edit) { if (edit) { remove(genericTagPropertiesEditorPaneScrollPanel); @@ -75,16 +99,83 @@ public class GenericTagPanel extends JPanel { sb.append(field.getName()).append(": ").append(field.get(tag)); sb.append(GraphTextWriter.NEW_LINE); } catch (IllegalArgumentException | IllegalAccessException ex) { - Logger.getLogger(MainPanel.class.getName()).log(Level.SEVERE, null, ex); + Logger.getLogger(GenericTagPanel.class.getName()).log(Level.SEVERE, null, ex); } } genericTagPropertiesEditorPane.setText(sb.toString()); genericTagPropertiesEditorPane.setCaretPosition(0); } - public void generateEditControls() { + public void generateEditControls(Tag tag) { genericTagPropertiesEditPanel.removeAll(); - genericTagPropertiesEditPanel.add(new JLabel("aa")); + this.tag = tag; + int propCount = generateEditControlsRecursive(tag, ""); + //Lay out the panel. + SpringUtilities.makeCompactGrid(genericTagPropertiesEditPanel, + propCount, 2, //rows, cols + 6, 6, //initX, initY + 6, 6); //xPad, yPad repaint(); } + + private int generateEditControlsRecursive(Object obj, String parent) { + Field[] fields = obj.getClass().getDeclaredFields(); + int propCount = 0; + for (Field field : fields) { + try { + if (Modifier.isStatic(field.getModifiers())) { + continue; + } + field.setAccessible(true); + Class type = field.getType(); + String name = parent + field.getName(); + Component editor = null; + Object value = field.get(obj); + if (type.equals(int.class) || type.equals(Integer.class)) { + editor = new IntegerEditor(obj, field); + } else if (type.equals(short.class) || type.equals(Short.class)) { + editor = new ShortEditor(obj, field); + } else if (type.equals(long.class) || type.equals(Long.class)) { + editor = new LongEditor(obj, field); + } else if (type.equals(double.class) || type.equals(Double.class)) { + editor = new DoubleEditor(obj, field); + } else if (type.equals(float.class) || type.equals(Float.class)) { + editor = new FloatEditor(obj, field); + } else if (type.equals(boolean.class) || type.equals(Boolean.class)) { + editor = new BooleanEditor(obj, field); + } else if (type.equals(String.class)) { + editor = new StringEditor(obj, field); + } else if (type.equals(RECT.class) || type.equals(RGB.class) || type.equals(ZONERECORD.class)) { + // todo: add other swf releated classes + propCount += generateEditControlsRecursive(field.get(obj), field.getName() + "."); + } else if (value instanceof Iterable) { + // todo: add list/array support + } else { + JTextArea textArea = new JTextArea(field.get(obj).toString()); + textArea.setLineWrap(true); + textArea.setEditable(false); + editor = textArea; + } + if (editor != null) { + JLabel label = new JLabel(name + ":", JLabel.TRAILING); + genericTagPropertiesEditPanel.add(label); + label.setLabelFor(editor); + genericTagPropertiesEditPanel.add(editor); + propCount++; + } + } catch (IllegalArgumentException | IllegalAccessException ex) { + Logger.getLogger(GenericTagPanel.class.getName()).log(Level.SEVERE, null, ex); + } + } + return propCount; + } + + public void save() { + for (Object component : genericTagPropertiesEditPanel.getComponents()) { + if (component instanceof GenericTagEditor) { + ((GenericTagEditor) component).save(); + } + } + setTagText(tag); + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/MainPanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/MainPanel.java index 093389d33..f3c2af6b7 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/MainPanel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/MainPanel.java @@ -526,7 +526,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec genericButtonsPanel.add(genericSaveButton); genericButtonsPanel.add(genericCancelButton); // todo: honfika: temporary hide edit button - //genericTagCard.add(genericButtonsPanel, BorderLayout.SOUTH); + genericTagCard.add(genericButtonsPanel, BorderLayout.SOUTH); return genericTagCard; } @@ -996,6 +996,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec swfs.clear(); oldNode = null; oldTag = null; + genericTagPanel.clear(); if (abcPanel != null) { abcPanel.clearSwf(); } @@ -1020,6 +1021,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec } oldNode = null; oldTag = null; + genericTagPanel.clear(); updateUi(); updateTagTree(); } @@ -2103,7 +2105,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec if (tagObj instanceof TreeNode) { item = ((TreeNode) tagObj).getItem(); } - if (tagObj instanceof DefineBinaryDataTag) { + if (item instanceof DefineBinaryDataTag) { DefineBinaryDataTag bt = (DefineBinaryDataTag) item; JFileChooser fc = new JFileChooser(); fc.setCurrentDirectory(new File(Configuration.lastOpenDir.get())); @@ -2121,14 +2123,26 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec } break; case ACTION_EDIT_GENERIC_TAG: { - genericEditButton.setVisible(false); - genericSaveButton.setVisible(true); - genericCancelButton.setVisible(true); - genericTagPanel.setEditMode(true); - genericTagPanel.generateEditControls(); + Object tagObj = tagTree.getLastSelectedPathComponent(); + if (tagObj == null) { + return; + } + + TreeItem item = null; + if (tagObj instanceof TreeNode) { + item = ((TreeNode) tagObj).getItem(); + } + if (item instanceof Tag) { + genericEditButton.setVisible(false); + genericSaveButton.setVisible(true); + genericCancelButton.setVisible(true); + genericTagPanel.setEditMode(true); + genericTagPanel.generateEditControls((Tag) item); + } } break; case ACTION_SAVE_GENERIC_TAG: { + genericTagPanel.save(); genericEditButton.setVisible(true); genericSaveButton.setVisible(false); genericCancelButton.setVisible(false); @@ -2438,6 +2452,10 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec } else if (tagObj instanceof Tag) { showCard(CARDGENEICTAGPANEL); genericTagPanel.setTagText((Tag) tagObj); + genericEditButton.setVisible(true); + genericSaveButton.setVisible(false); + genericCancelButton.setVisible(false); + genericTagPanel.setEditMode(false); } else { showCard(CARDEMPTYPANEL); } diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/BooleanEditor.java b/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/BooleanEditor.java new file mode 100644 index 000000000..ed25b8a43 --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/BooleanEditor.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2010-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; + +import java.awt.Color; +import java.lang.reflect.Field; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.JCheckBox; + +/** + * + * @author JPEXS + */ +public class BooleanEditor extends JCheckBox implements GenericTagEditor { + + private final Object obj; + private final Field field; + + public BooleanEditor(Object obj, Field field) { + setBackground(Color.white); + this.obj = obj; + this.field = field; + try { + setSelected((boolean) field.get(obj)); + } catch (IllegalArgumentException | IllegalAccessException ex) { + // ignore + } + } + + @Override + public void save() { + try { + field.set(obj, isSelected()); + } catch (IllegalArgumentException | IllegalAccessException ex) { + // ignore + } + } +} diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/DoubleEditor.java b/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/DoubleEditor.java new file mode 100644 index 000000000..034f9b4c6 --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/DoubleEditor.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2010-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; + +import java.awt.Color; +import java.lang.reflect.Field; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.JTextArea; + +/** + * + * @author JPEXS + */ +public class DoubleEditor extends JTextArea implements GenericTagEditor { + + private final Object obj; + private final Field field; + + public DoubleEditor(Object obj, Field field) { + setBackground(Color.white); + setSize(100, getSize().height); + setWrapStyleWord(true); + this.obj = obj; + this.field = field; + try { + setText(field.get(obj).toString()); + } catch (IllegalArgumentException | IllegalAccessException ex) { + // ignore + } + } + + @Override + public void save() { + try { + field.set(obj, Double.parseDouble(getText())); + } catch (IllegalArgumentException | IllegalAccessException ex) { + // ignore + } + } +} diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/FloatEditor.java b/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/FloatEditor.java new file mode 100644 index 000000000..2342556c2 --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/FloatEditor.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2010-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; + +import java.awt.Color; +import java.lang.reflect.Field; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.JTextArea; + +/** + * + * @author JPEXS + */ +public class FloatEditor extends JTextArea implements GenericTagEditor { + + private final Object obj; + private final Field field; + + public FloatEditor(Object obj, Field field) { + setBackground(Color.white); + setSize(100, getSize().height); + setWrapStyleWord(true); + this.obj = obj; + this.field = field; + try { + setText(field.get(obj).toString()); + } catch (IllegalArgumentException | IllegalAccessException ex) { + // ignore + } + } + + @Override + public void save() { + try { + field.set(obj, Float.parseFloat(getText())); + } catch (IllegalArgumentException | IllegalAccessException ex) { + // ignore + } + } +} diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/GenericTagEditor.java b/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/GenericTagEditor.java new file mode 100644 index 000000000..8b39e6f0e --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/GenericTagEditor.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2010-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 GenericTagEditor { + + public void save(); +} diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/IntegerEditor.java b/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/IntegerEditor.java new file mode 100644 index 000000000..90212e596 --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/IntegerEditor.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2010-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; + +import java.awt.Color; +import java.lang.reflect.Field; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.JTextArea; + +/** + * + * @author JPEXS + */ +public class IntegerEditor extends JTextArea implements GenericTagEditor { + + private final Object obj; + private final Field field; + + public IntegerEditor(Object obj, Field field) { + setBackground(Color.white); + setSize(100, getSize().height); + setWrapStyleWord(true); + this.obj = obj; + this.field = field; + try { + setText(field.get(obj).toString()); + } catch (IllegalArgumentException | IllegalAccessException ex) { + // ignore + } + } + + @Override + public void save() { + try { + field.set(obj, Integer.parseInt(getText())); + } catch (IllegalArgumentException | IllegalAccessException ex) { + // ignore + } + } +} diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/LongEditor.java b/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/LongEditor.java new file mode 100644 index 000000000..a6e3b904f --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/LongEditor.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2010-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; + +import java.awt.Color; +import java.lang.reflect.Field; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.JTextArea; + +/** + * + * @author JPEXS + */ +public class LongEditor extends JTextArea implements GenericTagEditor { + + private final Object obj; + private final Field field; + + public LongEditor(Object obj, Field field) { + setBackground(Color.white); + setSize(100, getSize().height); + setWrapStyleWord(true); + this.obj = obj; + this.field = field; + try { + setText(field.get(obj).toString()); + } catch (IllegalArgumentException | IllegalAccessException ex) { + // ignore + } + } + + @Override + public void save() { + try { + field.set(obj, Long.parseLong(getText())); + } catch (IllegalArgumentException | IllegalAccessException ex) { + // ignore + } + } +} diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/ShortEditor.java b/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/ShortEditor.java new file mode 100644 index 000000000..78581cf88 --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/ShortEditor.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2010-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; + +import java.awt.Color; +import java.lang.reflect.Field; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.JTextArea; + +/** + * + * @author JPEXS + */ +public class ShortEditor extends JTextArea implements GenericTagEditor { + + private final Object obj; + private final Field field; + + public ShortEditor(Object obj, Field field) { + setBackground(Color.white); + setSize(100, getSize().height); + setWrapStyleWord(true); + this.obj = obj; + this.field = field; + try { + setText(field.get(obj).toString()); + } catch (IllegalArgumentException | IllegalAccessException ex) { + // ignore + } + } + + @Override + public void save() { + try { + field.set(obj, Short.parseShort(getText())); + } catch (IllegalArgumentException | IllegalAccessException ex) { + // ignore + } + } +} diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/StringEditor.java b/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/StringEditor.java new file mode 100644 index 000000000..76aa7e772 --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/StringEditor.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2010-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; + +import java.awt.Color; +import java.lang.reflect.Field; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.JTextArea; + +/** + * + * @author JPEXS + */ +public class StringEditor extends JTextArea implements GenericTagEditor { + + private final Object tag; + private final Field field; + + public StringEditor(Object obj, Field field) { + setBackground(Color.white); + setLineWrap(true); + this.tag = obj; + this.field = field; + try { + setText((String) field.get(obj)); + } catch (IllegalArgumentException | IllegalAccessException ex) { + // ignore + } + } + + @Override + public void save() { + try { + field.set(tag, getText()); + } catch (IllegalArgumentException | IllegalAccessException ex) { + // ignore + } + } +} diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/helpers/SpringUtilities.java b/trunk/src/com/jpexs/decompiler/flash/gui/helpers/SpringUtilities.java new file mode 100644 index 000000000..63cc8dce4 --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/gui/helpers/SpringUtilities.java @@ -0,0 +1,225 @@ +/* + * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle or the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.jpexs.decompiler.flash.gui.helpers; + +import javax.swing.*; +import javax.swing.SpringLayout; +import java.awt.*; + +/** + * A 1.4 file that provides utility methods for + * creating form- or grid-style layouts with SpringLayout. + * These utilities are used by several programs, such as + * SpringBox and SpringCompactGrid. + */ +public class SpringUtilities { + /** + * A debugging utility that prints to stdout the component's + * minimum, preferred, and maximum sizes. + */ + public static void printSizes(Component c) { + System.out.println("minimumSize = " + c.getMinimumSize()); + System.out.println("preferredSize = " + c.getPreferredSize()); + System.out.println("maximumSize = " + c.getMaximumSize()); + } + + /** + * Aligns the first rows * cols + * components of parent in + * a grid. Each component is as big as the maximum + * preferred width and height of the components. + * The parent is made just big enough to fit them all. + * + * @param rows number of rows + * @param cols number of columns + * @param initialX x location to start the grid at + * @param initialY y location to start the grid at + * @param xPad x padding between cells + * @param yPad y padding between cells + */ + public static void makeGrid(Container parent, + int rows, int cols, + int initialX, int initialY, + int xPad, int yPad) { + SpringLayout layout; + try { + layout = (SpringLayout)parent.getLayout(); + } catch (ClassCastException exc) { + System.err.println("The first argument to makeGrid must use SpringLayout."); + return; + } + + Spring xPadSpring = Spring.constant(xPad); + Spring yPadSpring = Spring.constant(yPad); + Spring initialXSpring = Spring.constant(initialX); + Spring initialYSpring = Spring.constant(initialY); + int max = rows * cols; + + //Calculate Springs that are the max of the width/height so that all + //cells have the same size. + Spring maxWidthSpring = layout.getConstraints(parent.getComponent(0)). + getWidth(); + Spring maxHeightSpring = layout.getConstraints(parent.getComponent(0)). + getHeight(); + for (int i = 1; i < max; i++) { + SpringLayout.Constraints cons = layout.getConstraints( + parent.getComponent(i)); + + maxWidthSpring = Spring.max(maxWidthSpring, cons.getWidth()); + maxHeightSpring = Spring.max(maxHeightSpring, cons.getHeight()); + } + + //Apply the new width/height Spring. This forces all the + //components to have the same size. + for (int i = 0; i < max; i++) { + SpringLayout.Constraints cons = layout.getConstraints( + parent.getComponent(i)); + + cons.setWidth(maxWidthSpring); + cons.setHeight(maxHeightSpring); + } + + //Then adjust the x/y constraints of all the cells so that they + //are aligned in a grid. + SpringLayout.Constraints lastCons = null; + SpringLayout.Constraints lastRowCons = null; + for (int i = 0; i < max; i++) { + SpringLayout.Constraints cons = layout.getConstraints( + parent.getComponent(i)); + if (i % cols == 0) { //start of new row + lastRowCons = lastCons; + cons.setX(initialXSpring); + } else { //x position depends on previous component + cons.setX(Spring.sum(lastCons.getConstraint(SpringLayout.EAST), + xPadSpring)); + } + + if (i / cols == 0) { //first row + cons.setY(initialYSpring); + } else { //y position depends on previous row + cons.setY(Spring.sum(lastRowCons.getConstraint(SpringLayout.SOUTH), + yPadSpring)); + } + lastCons = cons; + } + + //Set the parent's size. + SpringLayout.Constraints pCons = layout.getConstraints(parent); + pCons.setConstraint(SpringLayout.SOUTH, + Spring.sum( + Spring.constant(yPad), + lastCons.getConstraint(SpringLayout.SOUTH))); + pCons.setConstraint(SpringLayout.EAST, + Spring.sum( + Spring.constant(xPad), + lastCons.getConstraint(SpringLayout.EAST))); + } + + /* Used by makeCompactGrid. */ + private static SpringLayout.Constraints getConstraintsForCell( + int row, int col, + Container parent, + int cols) { + SpringLayout layout = (SpringLayout) parent.getLayout(); + Component c = parent.getComponent(row * cols + col); + return layout.getConstraints(c); + } + + /** + * Aligns the first rows * cols + * components of parent in + * a grid. Each component in a column is as wide as the maximum + * preferred width of the components in that column; + * height is similarly determined for each row. + * The parent is made just big enough to fit them all. + * + * @param rows number of rows + * @param cols number of columns + * @param initialX x location to start the grid at + * @param initialY y location to start the grid at + * @param xPad x padding between cells + * @param yPad y padding between cells + */ + public static void makeCompactGrid(Container parent, + int rows, int cols, + int initialX, int initialY, + int xPad, int yPad) { + SpringLayout layout; + try { + layout = (SpringLayout)parent.getLayout(); + } catch (ClassCastException exc) { + System.err.println("The first argument to makeCompactGrid must use SpringLayout."); + return; + } + + //Align all cells in each column and make them the same width. + Spring x = Spring.constant(initialX); + for (int c = 0; c < cols; c++) { + Spring width = Spring.constant(0); + for (int r = 0; r < rows; r++) { + width = Spring.max(width, + getConstraintsForCell(r, c, parent, cols). + getWidth()); + } + for (int r = 0; r < rows; r++) { + SpringLayout.Constraints constraints = + getConstraintsForCell(r, c, parent, cols); + constraints.setX(x); + constraints.setWidth(width); + } + x = Spring.sum(x, Spring.sum(width, Spring.constant(xPad))); + } + + //Align all cells in each row and make them the same height. + Spring y = Spring.constant(initialY); + for (int r = 0; r < rows; r++) { + Spring height = Spring.constant(0); + for (int c = 0; c < cols; c++) { + height = Spring.max(height, + getConstraintsForCell(r, c, parent, cols). + getHeight()); + } + for (int c = 0; c < cols; c++) { + SpringLayout.Constraints constraints = + getConstraintsForCell(r, c, parent, cols); + constraints.setY(y); + constraints.setHeight(height); + } + y = Spring.sum(y, Spring.sum(height, Spring.constant(yPad))); + } + + //Set the parent's size. + SpringLayout.Constraints pCons = layout.getConstraints(parent); + pCons.setConstraint(SpringLayout.SOUTH, y); + pCons.setConstraint(SpringLayout.EAST, x); + } +} \ No newline at end of file