tag editor

This commit is contained in:
Honfika
2014-02-02 14:49:52 +01:00
parent 908a7b335d
commit 1bc392764a
11 changed files with 752 additions and 10 deletions

View File

@@ -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);
}
}

View File

@@ -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);
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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
}
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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
}
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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
}
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
package com.jpexs.decompiler.flash.gui.generictageditors;
/**
*
* @author JPEXS
*/
public interface GenericTagEditor {
public void save();
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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
}
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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
}
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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
}
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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
}
}
}

View File

@@ -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 <code>rows</code> * <code>cols</code>
* components of <code>parent</code> 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 <code>rows</code> * <code>cols</code>
* components of <code>parent</code> 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);
}
}