pax_global_header00006660000000000000000000000064132410156320014507gustar00rootroot0000000000000052 comment=391752a7c1878873f2d487956dfaa417754e56d7
miglayout-5.1/000077500000000000000000000000001324101563200133665ustar00rootroot00000000000000miglayout-5.1/.gitignore000077500000000000000000000011661324101563200153650ustar00rootroot00000000000000
/core/.settings
/core/target
/core/.project
/core/.classpath
/demo/.project
/demo/.settings
/demo/target
/demo/.classpath
/examples/.project
/examples/.settings
/examples/target
/examples/.classpath
/ideutil/.project
/ideutil/.settings
/ideutil/target
/ideutil/.classpath
/swing/.project
/swing/.settings
/swing/target
/swing/.classpath
/swt/.project
/swt/.settings
/swt/target
/swt/.classpath
/target
/release.properties
/javafx/.project
/javafx/.settings
/javafx/target
/javafx/.classpath
#
# ignore target folders in the build tree
#
**/target
#
# ignore eclipse local settings files
#
**/.project
**/.classpath
**/.settings
miglayout-5.1/README.md000066400000000000000000000016021324101563200146440ustar00rootroot00000000000000# miglayout
Official MiG Layout for Swing, SWT and JavaFX
For Java developers writing GUI layouts by hand that wants simplicity, power and automatic per platform fidelity, that are dissatisfied with the current layout managers in Swing, JavaFX and SWT, MigLayout solves your layout problems. User interfaces created with MigLayout is easy to maintain, you will understand how the layout will look like just by looking at the source code.
MigLayout is a superbly versatile JavaFX/SWT/Swing layout manager that makes layout problems trivial. It is using String or API type-checked constraints to format the layout. MigLayout can produce flowing, grid based, absolute (with links), grouped and docking layouts. You will never have to switch to another layout manager ever again! MigLayout is created to be to manually coded layouts what Matisse/GroupLayout is to IDE supported visual layouts.
miglayout-5.1/core/000077500000000000000000000000001324101563200143165ustar00rootroot00000000000000miglayout-5.1/core/pom.xml000077500000000000000000000012021324101563200156310ustar00rootroot00000000000000
4.0.0
com.miglayout
miglayout-parent
5.1-SNAPSHOT
../pom.xml
miglayout-core
jar
MiGLayout Core
MiGLayout - core layout logic
miglayout-5.1/core/src/000077500000000000000000000000001324101563200151055ustar00rootroot00000000000000miglayout-5.1/core/src/main/000077500000000000000000000000001324101563200160315ustar00rootroot00000000000000miglayout-5.1/core/src/main/java/000077500000000000000000000000001324101563200167525ustar00rootroot00000000000000miglayout-5.1/core/src/main/java/net/000077500000000000000000000000001324101563200175405ustar00rootroot00000000000000miglayout-5.1/core/src/main/java/net/miginfocom/000077500000000000000000000000001324101563200216675ustar00rootroot00000000000000miglayout-5.1/core/src/main/java/net/miginfocom/layout/000077500000000000000000000000001324101563200232045ustar00rootroot00000000000000miglayout-5.1/core/src/main/java/net/miginfocom/layout/AC.java000077500000000000000000000620571324101563200243470ustar00rootroot00000000000000package net.miginfocom.layout;
import java.io.*;
import java.util.ArrayList;
/*
* License (BSD):
* ==============
*
* Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
* 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 the MiG InfoCom AB nor 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.
*
* @version 1.0
* @author Mikael Grev, MiG InfoCom AB
* Date: 2006-sep-08
*/
/** A constraint that holds the column or row constraints for the grid. It also holds the gaps between the rows and columns.
*
* This class is a holder and builder for a number of {@link net.miginfocom.layout.DimConstraint}s.
*
* For a more thorough explanation of what these constraints do, and how to build the constraints, see the White Paper or Cheat Sheet at www.migcomponents.com.
*
* Note that there are two way to build this constraint. Through String (e.g. "[100]3[200,fill]"
or through API (E.g.
* new AC().size("100").gap("3").size("200").fill()
.
*/
public final class AC implements Externalizable
{
private final ArrayList cList = new ArrayList(1);
private transient int curIx = 0;
/** Constructor. Creates an instance that can be configured manually. Will be initialized with a default
* {@link net.miginfocom.layout.DimConstraint}.
*/
public AC()
{
cList.add(new DimConstraint());
}
/** Property. The different {@link net.miginfocom.layout.DimConstraint}s that this object consists of.
* These DimConstraints
contains all information in this class.
*
* Yes, we are embarrassingly aware that the method is misspelled.
* @return The different {@link net.miginfocom.layout.DimConstraint}s that this object consists of. A new list and
* never null
.
*/
public final DimConstraint[] getConstaints()
{
return cList.toArray(new DimConstraint[cList.size()]);
}
/** Sets the different {@link net.miginfocom.layout.DimConstraint}s that this object should consists of.
*
* Yes, we are embarrassingly aware that the method is misspelled.
* @param constr The different {@link net.miginfocom.layout.DimConstraint}s that this object consists of. The list
* will be copied for storage. null
or and empty array will reset the constraints to one DimConstraint
* with default values.
*/
public final void setConstaints(DimConstraint[] constr)
{
if (constr == null || constr.length < 1 )
constr = new DimConstraint[] {new DimConstraint()};
cList.clear();
cList.ensureCapacity(constr.length);
for (DimConstraint c : constr)
cList.add(c);
}
/** Returns the number of rows/columns that this constraints currently have.
* @return The number of rows/columns that this constraints currently have. At least 1.
*/
public int getCount()
{
return cList.size();
}
/** Sets the total number of rows/columns to size
. If the number of rows/columns is already more
* than size
nothing will happen.
* @param size The total number of rows/columns
* @return this
so it is possible to chain calls. E.g. new AxisConstraint().noGrid().gap().fill()
.
*/
public final AC count(int size)
{
makeSize(size);
return this;
}
/** Specifies that the current row/column should not be grid-like. The while row/column will have its components layed out
* in one single cell. It is the same as to say that the cells in this column/row will all be merged (a.k.a spanned).
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return this
so it is possible to chain calls. E.g. new AxisConstraint().noGrid().gap().fill()
.
*/
public final AC noGrid()
{
return noGrid(curIx);
}
/** Specifies that the indicated rows/columns should not be grid-like. The while row/column will have its components layed out
* in one single cell. It is the same as to say that the cells in this column/row will all be merged (a.k.a spanned).
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
* @return this
so it is possible to chain calls. E.g. new AxisConstraint().noGrid().gap().fill()
.
*/
public final AC noGrid(int... indexes)
{
for (int i = indexes.length - 1; i >= 0; i--) {
int ix = indexes[i];
makeSize(ix);
cList.get(ix).setNoGrid(true);
}
return this;
}
/** Sets the current row/column to i
. If the current number of rows/columns is less than i
a call
* to {@link #count(int)} will set the size accordingly.
*
* The next call to any of the constraint methods (e.g. {@link net.miginfocom.layout.AC#noGrid}) will be carried
* out on this new row/column.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param i The new current row/column.
* @return this
so it is possible to chain calls. E.g. new AxisConstraint().noGrid().gap().fill()
.
*/
public final AC index(int i)
{
makeSize(i);
curIx = i;
return this;
}
/** Specifies that the current row/column's component should grow by default. It does not affect the size of the row/column.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return this
so it is possible to chain calls. E.g. new AxisConstraint().noGrid().gap().fill()
.
*/
public final AC fill()
{
return fill(curIx);
}
/** Specifies that the indicated rows'/columns' component should grow by default. It does not affect the size of the row/column.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
* @return this
so it is possible to chain calls. E.g. new AxisConstraint().noGrid().gap().fill()
.
*/
public final AC fill(int... indexes)
{
for (int i = indexes.length - 1; i >= 0; i--) {
int ix = indexes[i];
makeSize(ix);
cList.get(ix).setFill(true);
}
return this;
}
// /** Specifies that the current row/column should be put in the end group s
and will thus share the same ending
// * coordinate within the group.
// *
// * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
// * @param s A name to associate on the group that should be the same for other rows/columns in the same group.
// * @return this
so it is possible to chain calls. E.g. new AxisConstraint().noGrid().gap().fill()
.
// */
// public final AxisConstraint endGroup(String s)
// {
// return endGroup(s, curIx);
// }
//
// /** Specifies that the indicated rows/columns should be put in the end group s
and will thus share the same ending
// * coordinate within the group.
// *
// * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
// * @param s A name to associate on the group that should be the same for other rows/columns in the same group.
// * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
// * @return this
so it is possible to chain calls. E.g. new AxisConstraint().noGrid().gap().fill()
.
// */
// public final AxisConstraint endGroup(String s, int... indexes)
// {
// for (int i = indexes.length - 1; i >= 0; i--) {
// int ix = indexes[i];
// makeSize(ix);
// cList.get(ix).setEndGroup(s);
// }
// return this;
// }
/** Specifies that the current row/column should be put in the size group s
and will thus share the same size
* constraints as the other components in the group.
*
* Same as sizeGroup("")
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return this
so it is possible to chain calls. E.g. new AxisConstraint().noGrid().gap().fill()
.
* @since 3.7.2
*/
public final AC sizeGroup()
{
return sizeGroup("", curIx);
}
/** Specifies that the current row/column should be put in the size group s
and will thus share the same size
* constraints as the other components in the group.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param s A name to associate on the group that should be the same for other rows/columns in the same group.
* @return this
so it is possible to chain calls. E.g. new AxisConstraint().noGrid().gap().fill()
.
*/
public final AC sizeGroup(String s)
{
return sizeGroup(s, curIx);
}
/** Specifies that the indicated rows/columns should be put in the size group s
and will thus share the same size
* constraints as the other components in the group.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param s A name to associate on the group that should be the same for other rows/columns in the same group.
* @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
* @return this
so it is possible to chain calls. E.g. new AxisConstraint().noGrid().gap().fill()
.
*/
public final AC sizeGroup(String s, int... indexes)
{
for (int i = indexes.length - 1; i >= 0; i--) {
int ix = indexes[i];
makeSize(ix);
cList.get(ix).setSizeGroup(s);
}
return this;
}
/** Specifies the current row/column's min and/or preferred and/or max size. E.g. "10px"
or "50:100:200"
.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param s The minimum and/or preferred and/or maximum size of this row. The string will be interpreted
* as a BoundSize . For more info on how BoundSize is formatted see the documentation.
* @return this
so it is possible to chain calls. E.g. new AxisConstraint().noGrid().gap().fill()
.
*/
public final AC size(String s)
{
return size(s, curIx);
}
/** Specifies the indicated rows'/columns' min and/or preferred and/or max size. E.g. "10px"
or "50:100:200"
.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param size The minimum and/or preferred and/or maximum size of this row. The string will be interpreted
* as a BoundSize . For more info on how BoundSize is formatted see the documentation.
* @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
* @return this
so it is possible to chain calls. E.g. new AxisConstraint().noGrid().gap().fill()
.
*/
public final AC size(String size, int... indexes)
{
BoundSize bs = ConstraintParser.parseBoundSize(size, false, true);
for (int i = indexes.length - 1; i >= 0; i--) {
int ix = indexes[i];
makeSize(ix);
cList.get(ix).setSize(bs);
}
return this;
}
/** Specifies the gap size to be the default one AND moves to the next column/row. The method is called .gap()
* rather the more natural .next()
to indicate that it is very much related to the other .gap(..)
methods.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return this
so it is possible to chain calls. E.g. new AxisConstraint().noGrid().gap().fill()
.
*/
public final AC gap()
{
curIx++;
makeSize(curIx);
return this;
}
/** Specifies the gap size to size
AND moves to the next column/row.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param size minimum and/or preferred and/or maximum size of the gap between this and the next row/column.
* The string will be interpreted as a BoundSize . For more info on how BoundSize is formatted see the documentation.
* @return this
so it is possible to chain calls. E.g. new AxisConstraint().noGrid().gap().fill()
.
*/
public final AC gap(String size)
{
return gap(size, curIx++);
}
/** Specifies the indicated rows'/columns' gap size to size
.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param size minimum and/or preferred and/or maximum size of the gap between this and the next row/column.
* The string will be interpreted as a BoundSize . For more info on how BoundSize is formatted see the documentation.
* @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
* @return this
so it is possible to chain calls. E.g. new AxisConstraint().noGrid().gap().fill()
.
*/
public final AC gap(String size, int... indexes)
{
BoundSize bsa = size != null ? ConstraintParser.parseBoundSize(size, true, true) : null;
for (int i = indexes.length - 1; i >= 0; i--) {
int ix = indexes[i];
makeSize(ix + 1);
if (bsa != null)
cList.get(ix).setGapAfter(bsa);
}
return this;
}
/** Specifies the current row/column's columns default alignment for its components . It does not affect the positioning
* or size of the columns/row itself. For columns it is the horizontal alignment (e.g. "left") and for rows it is the vertical
* alignment (e.g. "top").
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param side The default side to align the components. E.g. "top" or "left", or "leading" or "trailing" or "bottom" or "right".
* @return this
so it is possible to chain calls. E.g. new AxisConstraint().noGrid().gap().fill()
.
*/
public final AC align(String side)
{
return align(side, curIx);
}
/** Specifies the indicated rows'/columns' columns default alignment for its components . It does not affect the positioning
* or size of the columns/row itself. For columns it is the horizontal alignment (e.g. "left") and for rows it is the vertical
* alignment (e.g. "top").
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param side The default side to align the components. E.g. "top" or "left", or "before" or "after" or "bottom" or "right".
* @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
* @return this
so it is possible to chain calls. E.g. new AxisConstraint().noGrid().gap().fill()
.
*/
public final AC align(String side, int... indexes)
{
UnitValue al = ConstraintParser.parseAlignKeywords(side, true);
if (al == null)
al = ConstraintParser.parseAlignKeywords(side, false);
for (int i = indexes.length - 1; i >= 0; i--) {
int ix = indexes[i];
makeSize(ix);
cList.get(ix).setAlign(al);
}
return this;
}
/** Specifies the current row/column's grow priority.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param p The new grow priority.
* @return this
so it is possible to chain calls. E.g. new AxisConstraint().noGrid().gap().fill()
.
*/
public final AC growPrio(int p)
{
return growPrio(p, curIx);
}
/** Specifies the indicated rows'/columns' grow priority.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param p The new grow priority.
* @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
* @return this
so it is possible to chain calls. E.g. new AxisConstraint().noGrid().gap().fill()
.
*/
public final AC growPrio(int p, int... indexes)
{
for (int i = indexes.length - 1; i >= 0; i--) {
int ix = indexes[i];
makeSize(ix);
cList.get(ix).setGrowPriority(p);
}
return this;
}
/** Specifies the current row/column's grow weight within columns/rows with the grow priority
100f.
*
* Same as grow(100f)
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return this
so it is possible to chain calls. E.g. new AxisConstraint().noGrid().gap().fill()
.
* @since 3.7.2
*/
public final AC grow()
{
return grow(100f, curIx);
}
/** Specifies the current row/column's grow weight within columns/rows with the same grow priority
.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param w The new grow weight.
* @return this
so it is possible to chain calls. E.g. new AxisConstraint().noGrid().gap().fill()
.
*/
public final AC grow(float w)
{
return grow(w, curIx);
}
/** Specifies the indicated rows'/columns' grow weight within columns/rows with the same grow priority
.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param w The new grow weight.
* @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
* @return this
so it is possible to chain calls. E.g. new AxisConstraint().noGrid().gap().fill()
.
*/
public final AC grow(float w, int... indexes)
{
Float gw = new Float(w);
for (int i = indexes.length - 1; i >= 0; i--) {
int ix = indexes[i];
makeSize(ix);
cList.get(ix).setGrow(gw);
}
return this;
}
/** Specifies the current row/column's shrink priority.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param p The new shrink priority.
* @return this
so it is possible to chain calls. E.g. new AxisConstraint().noGrid().gap().fill()
.
*/
public final AC shrinkPrio(int p)
{
return shrinkPrio(p, curIx);
}
/** Specifies the indicated rows'/columns' shrink priority.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param p The new shrink priority.
* @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
* @return this
so it is possible to chain calls. E.g. new AxisConstraint().noGrid().gap().fill()
.
*/
public final AC shrinkPrio(int p, int... indexes)
{
for (int i = indexes.length - 1; i >= 0; i--) {
int ix = indexes[i];
makeSize(ix);
cList.get(ix).setShrinkPriority(p);
}
return this;
}
/** Specifies that the current row/column's shrink weight within the columns/rows with the shrink priority
100f.
*
* Same as shrink(100f)
.
*
* For a more thorough explanation of what this constraint does see the White Paper or Cheat Sheet at www.migcomponents.com.
* @return this
so it is possible to chain calls. E.g. new AxisConstraint().noGrid().gap().fill()
.
* @since 3.7.2
*/
public final AC shrink()
{
return shrink(100f, curIx);
}
/** Specifies that the current row/column's shrink weight within the columns/rows with the same shrink priority
.
*
* For a more thorough explanation of what this constraint does see the White Paper or Cheat Sheet at www.migcomponents.com.
* @param w The shrink weight.
* @return this
so it is possible to chain calls. E.g. new AxisConstraint().noGrid().gap().fill()
.
* @since 3.7.2
*/
public final AC shrink(float w)
{
return shrink(w, curIx);
}
/** Specifies the indicated rows'/columns' shrink weight within the columns/rows with the same shrink priority
.
*
* For a more thorough explanation of what this constraint does see the White Paper or Cheat Sheet at www.migcomponents.com.
* @param w The shrink weight.
* @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
* @return this
so it is possible to chain calls. E.g. new AxisConstraint().noGrid().gap().fill()
.
* @since 3.7.2
*/
public final AC shrink(float w, int... indexes)
{
Float sw = new Float(w);
for (int i = indexes.length - 1; i >= 0; i--) {
int ix = indexes[i];
makeSize(ix);
cList.get(ix).setShrink(sw);
}
return this;
}
/** Specifies that the current row/column's shrink weight within the columns/rows with the same shrink priority
.
*
* For a more thorough explanation of what this constraint does see the White Paper or Cheat Sheet at www.migcomponents.com.
* @param w The shrink weight.
* @return this
so it is possible to chain calls. E.g. new AxisConstraint().noGrid().gap().fill()
.
* @deprecated in 3.7.2. Use {@link #shrink(float)} instead.
*/
public final AC shrinkWeight(float w)
{
return shrink(w);
}
/** Specifies the indicated rows'/columns' shrink weight within the columns/rows with the same shrink priority
.
*
* For a more thorough explanation of what this constraint does see the White Paper or Cheat Sheet at www.migcomponents.com.
* @param w The shrink weight.
* @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
* @return this
so it is possible to chain calls. E.g. new AxisConstraint().noGrid().gap().fill()
.
* @deprecated in 3.7.2. Use {@link #shrink(float, int...)} instead.
*/
public final AC shrinkWeight(float w, int... indexes)
{
return shrink(w, indexes);
}
private void makeSize(int sz)
{
if (cList.size() <= sz) {
cList.ensureCapacity(sz);
for (int i = cList.size(); i <= sz; i++)
cList.add(new DimConstraint());
}
}
// ************************************************
// Persistence Delegate and Serializable combined.
// ************************************************
private Object readResolve() throws ObjectStreamException
{
return LayoutUtil.getSerializedObject(this);
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
{
LayoutUtil.setSerializedObject(this, LayoutUtil.readAsXML(in));
}
@Override
public void writeExternal(ObjectOutput out) throws IOException
{
if (getClass() == AC.class)
LayoutUtil.writeAsXML(out, this);
}
}miglayout-5.1/core/src/main/java/net/miginfocom/layout/AnimSpec.java000066400000000000000000000073141324101563200255530ustar00rootroot00000000000000package net.miginfocom.layout;
/*
* License (BSD):
* ==============
*
* Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
* 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 the MiG InfoCom AB nor 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.
*
* @version 1.0
*/
import java.io.Serializable;
/**
* @author Mikael Grev, MiG InfoCom AB
* Date: 14-09-24
* Time: 17:05
*/
public class AnimSpec implements Serializable
{
// public static final AnimSpec OFF = new AnimSpec(-1, 0, 0);
public static final AnimSpec DEF = new AnimSpec(0, 0, 0.2f, 0.2f);
private final int prio;
private final int durMillis;
private final float easeIn, easeOut;
/**
* @param prio The animation priority. When added with the general animation priority of the layout the animation will
* be done if the resulting value is > 0.
* @param durMillis Duration in milliseconds. <=0 means default value should be used and > 0 is the number of millis
* @param easeIn 0 is linear (no ease). 1 is max ease. Always clamped between these values.
* @param easeOut 0 is linear (no ease). 1 is max ease. Always clamped between these values.
*/
public AnimSpec(int prio, int durMillis, float easeIn, float easeOut)
{
this.prio = prio;
this.durMillis = durMillis;
this.easeIn = LayoutUtil.clamp(easeIn, 0, 1);
this.easeOut = LayoutUtil.clamp(easeOut, 0, 1);
}
/**
* @return The animation priority. When added with the general animation priority of the layout the animation will
* be done if the resulting value is > 0.
*/
public int getPriority()
{
return prio;
}
/**
* @param defMillis Default used if the millis in the spec is set to "default".
* @return Duration in milliseconds. <=0 means default value should be used and > 0 is the number of millis
*/
public int getDurationMillis(int defMillis)
{
return durMillis > 0 ? durMillis : defMillis;
}
/**
* @return Duration in milliseconds. <= 0 means default value should be used and > 0 is the number of millis
*/
public int getDurationMillis()
{
return durMillis;
}
/**
* @return A value between 0 and 1 where 0 is no ease in and 1 is maximum ease in.
*/
public float getEaseIn()
{
return easeIn;
}
/**
* @return A value between 0 and 1 where 0 is no ease out and 1 is maximum ease out.
*/
public float getEaseOut()
{
return easeOut;
}
}
miglayout-5.1/core/src/main/java/net/miginfocom/layout/BoundSize.java000077500000000000000000000245251324101563200257640ustar00rootroot00000000000000package net.miginfocom.layout;
import java.beans.Encoder;
import java.beans.Expression;
import java.beans.PersistenceDelegate;
import java.io.*;
/*
* License (BSD):
* ==============
*
* Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
* 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 the MiG InfoCom AB nor 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.
*
* @version 1.0
* @author Mikael Grev, MiG InfoCom AB
* Date: 2006-sep-08
*/
/** A size that contains minimum, preferred and maximum size of type {@link UnitValue}.
*
* This class is a simple value container and it is immutable.
*
* If a size is missing (i.e., null
) that boundary should be considered "not in use".
*
* You can create a BoundSize from a String with the use of {@link ConstraintParser#parseBoundSize(String, boolean, boolean)}
*/
public class BoundSize implements Serializable
{
public static final BoundSize NULL_SIZE = new BoundSize(null, null);
public static final BoundSize ZERO_PIXEL = new BoundSize(UnitValue.ZERO, "0px");
private final transient UnitValue min;
private final transient UnitValue pref;
private final transient UnitValue max;
private final transient boolean gapPush;
/** Constructor that use the same value for min/preferred/max size.
* @param minMaxPref The value to use for min/preferred/max size.
* @param createString The string used to create the BoundsSize.
*/
public BoundSize(UnitValue minMaxPref, String createString)
{
this(minMaxPref, minMaxPref, minMaxPref, createString);
}
/** Constructor. This method is here for serialization only and should normally not be used. Use
* {@link ConstraintParser#parseBoundSize(String, boolean, boolean)} instead.
* @param min The minimum size. May be null
.
* @param preferred The preferred size. May be null
.
* @param max The maximum size. May be null
.
* @param createString The string used to create the BoundsSize.
*/
public BoundSize(UnitValue min, UnitValue preferred, UnitValue max, String createString) // Bound to old delegate!!!!!
{
this(min, preferred, max, false, createString);
}
/** Constructor. This method is here for serialization only and should normally not be used. Use
* {@link ConstraintParser#parseBoundSize(String, boolean, boolean)} instead.
* @param min The minimum size. May be null
.
* @param preferred The preferred size. May be null
.
* @param max The maximum size. May be null
.
* @param gapPush If the size should be hinted as "pushing" and thus want to occupy free space if no one else is claiming it.
* @param createString The string used to create the BoundsSize.
*/
public BoundSize(UnitValue min, UnitValue preferred, UnitValue max, boolean gapPush, String createString)
{
this.min = min;
this.pref = preferred;
this.max = max;
this.gapPush = gapPush;
LayoutUtil.putCCString(this, createString); // this escapes!!
}
/** Returns the minimum size as sent into the constructor.
* @return The minimum size as sent into the constructor. May be null
.
*/
public final UnitValue getMin()
{
return min;
}
/** Returns the preferred size as sent into the constructor.
* @return The preferred size as sent into the constructor. May be null
.
*/
public final UnitValue getPreferred()
{
return pref;
}
/** Returns the maximum size as sent into the constructor.
* @return The maximum size as sent into the constructor. May be null
.
*/
public final UnitValue getMax()
{
return max;
}
/** If the size should be hinted as "pushing" and thus want to occupy free space if no one else is claiming it.
* @return The value.
*/
public boolean getGapPush()
{
return gapPush;
}
/** Returns if this bound size has no min, preferred and maximum size set (they are all null
)
* @return If unset.
*/
public boolean isUnset()
{
// Most common case by far is this == ZERO_PIXEL...
return this == ZERO_PIXEL || (pref == null && min == null && max == null && gapPush == false);
}
/** Makes sure that size
is within min and max of this size.
* @param size The size to constrain.
* @param refValue The reference to use for relative sizes.
* @param parent The parent container.
* @return The size, constrained within min and max.
*/
public int constrain(int size, float refValue, ContainerWrapper parent)
{
if (max != null)
size = Math.min(size, max.getPixels(refValue, parent, parent));
if (min != null)
size = Math.max(size, min.getPixels(refValue, parent, parent));
return size;
}
/** Returns the minimum, preferred or maximum size for this bounded size.
* @param sizeType The type. LayoutUtil.MIN
, LayoutUtil.PREF
or LayoutUtil.MAX
.
* @return
*/
final UnitValue getSize(int sizeType)
{
switch(sizeType) {
case LayoutUtil.MIN:
return min;
case LayoutUtil.PREF:
return pref;
case LayoutUtil.MAX:
return max;
default:
throw new IllegalArgumentException("Unknown size: " + sizeType);
}
}
/** Convert the bound sizes to pixels.
*
* null
bound sizes will be 0 for min and preferred and {@link net.miginfocom.layout.LayoutUtil#INF} for max.
* @param refSize The reference size.
* @param parent The parent. Not null
.
* @param comp The component, if applicable, can be null
.
* @return An array of length three (min,pref,max).
*/
final int[] getPixelSizes(float refSize, ContainerWrapper parent, ComponentWrapper comp)
{
return new int[] {
min != null ? min.getPixels(refSize, parent, comp) : 0,
pref != null ? pref.getPixels(refSize, parent, comp) : 0,
max != null ? max.getPixels(refSize, parent, comp) : LayoutUtil.INF
};
}
/** Returns the a constraint string that can be re-parsed to be the exact same UnitValue.
* @return A String. Never null
.
*/
String getConstraintString()
{
String cs = LayoutUtil.getCCString(this);
if (cs != null)
return cs;
if (min == pref && pref == max)
return min != null ? (min.getConstraintString() + "!") : "null";
StringBuilder sb = new StringBuilder(16);
if (min != null)
sb.append(min.getConstraintString()).append(':');
if (pref != null) {
if (min == null && max != null)
sb.append(":");
sb.append(pref.getConstraintString());
} else if (min != null) {
sb.append('n');
}
if (max != null)
sb.append(sb.length() == 0 ? "::" : ":").append(max.getConstraintString());
if (gapPush) {
if (sb.length() > 0)
sb.append(':');
sb.append("push");
}
return sb.toString();
}
void checkNotLinked()
{
if (isLinked())
throw new IllegalArgumentException("Size may not contain links");
}
boolean isLinked()
{
return min != null && min.isLinkedDeep() || pref != null && pref.isLinkedDeep() || max != null && max.isLinkedDeep();
}
boolean isAbsolute()
{
return (min == null || min.isAbsoluteDeep()) && (pref == null || pref.isAbsoluteDeep()) && (max == null || max.isAbsoluteDeep());
}
public String toString()
{
return "BoundSize{" + "min=" + min + ", pref=" + pref + ", max=" + max + ", gapPush=" + gapPush +'}';
}
static {
if(LayoutUtil.HAS_BEANS){
LayoutUtil.setDelegate(BoundSize.class, new PersistenceDelegate() {
@Override
protected Expression instantiate(Object oldInstance, Encoder out)
{
BoundSize bs = (BoundSize) oldInstance;
if (Grid.TEST_GAPS) {
return new Expression(oldInstance, BoundSize.class, "new", new Object[] {
bs.getMin(), bs.getPreferred(), bs.getMax(), bs.getGapPush(), bs.getConstraintString()
});
} else {
return new Expression(oldInstance, BoundSize.class, "new", new Object[] {
bs.getMin(), bs.getPreferred(), bs.getMax(), bs.getConstraintString()
});
}
}
});
}
}
// ************************************************
// Persistence Delegate and Serializable combined.
// ************************************************
private static final long serialVersionUID = 1L;
protected Object readResolve() throws ObjectStreamException
{
return LayoutUtil.getSerializedObject(this);
}
private void writeObject(ObjectOutputStream out) throws IOException
{
if (getClass() == BoundSize.class)
LayoutUtil.writeAsXML(out, this);
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
{
LayoutUtil.setSerializedObject(this, LayoutUtil.readAsXML(in));
}
}
miglayout-5.1/core/src/main/java/net/miginfocom/layout/CC.java000077500000000000000000002362321324101563200243470ustar00rootroot00000000000000package net.miginfocom.layout;
import java.io.*;
import java.util.ArrayList;
/*
* License (BSD):
* ==============
*
* Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
* 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 the MiG InfoCom AB nor 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.
*
* @version 1.0
* @author Mikael Grev, MiG InfoCom AB
* Date: 2006-sep-08
*/
/** A simple value holder for one component's constraint.
*/
public final class CC implements Externalizable
{
private static final BoundSize DEF_GAP = BoundSize.NULL_SIZE; // Only used to denote default wrap/newline gap.
static final String[] DOCK_SIDES = {"north", "west", "south", "east"};
// See the getters and setters for information about the properties below.
private int dock = -1;
private UnitValue[] pos = null; // [x1, y1, x2, y2]
private UnitValue[] padding = null; // top, left, bottom, right
private UnitValue[] visualPadding = null; // top, left, bottom, right
private Boolean flowX = null;
private int skip = 0;
private int split = 1;
private int spanX = 1, spanY = 1;
private int cellX = -1, cellY = 0; // If cellX is -1 then cellY is also considered -1. cellY is never negative.
private String tag = null;
private String id = null;
private int hideMode = -1;
private DimConstraint hor = new DimConstraint();
private DimConstraint ver = new DimConstraint();
private BoundSize newline = null;
private BoundSize wrap = null;
private boolean boundsInGrid = true;
private boolean external = false;
private Float pushX = null, pushY = null;
private AnimSpec animSpec = AnimSpec.DEF;
// ***** Tmp cache field
private static final String[] EMPTY_ARR = new String[0];
private transient String[] linkTargets = null;
/** Empty constructor.
*/
public CC()
{
}
String[] getLinkTargets()
{
if (linkTargets == null) {
final ArrayList targets = new ArrayList(2);
if (pos != null) {
for (int i = 0; i < pos.length ; i++)
addLinkTargetIDs(targets, pos[i]);
}
linkTargets = targets.size() == 0 ? EMPTY_ARR : targets.toArray(new String[targets.size()]);
}
return linkTargets;
}
private void addLinkTargetIDs(ArrayList targets, UnitValue uv)
{
if (uv != null) {
String linkId = uv.getLinkTargetId();
if (linkId != null) {
targets.add(linkId);
} else {
for (int i = uv.getSubUnitCount() - 1; i >= 0; i--) {
UnitValue subUv = uv.getSubUnitValue(i);
if (subUv.isLinkedDeep())
addLinkTargetIDs(targets, subUv);
}
}
}
}
// **********************************************************
// Chaining constraint setters
// **********************************************************
/** Specifies that the component should be put in the end group s
and will thus share the same ending
* coordinate as them within the group.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param s A name to associate on the group that should be the same for other rows/columns in the same group.
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
*/
public final CC endGroupX(String s)
{
hor.setEndGroup(s);
return this;
}
/** Specifies that the component should be put in the size group s
and will thus share the same size
* as them within the group.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param s A name to associate on the group that should be the same for other rows/columns in the same group.
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
*/
public final CC sizeGroupX(String s)
{
hor.setSizeGroup(s);
return this;
}
/** The minimum size for the component. The value will override any value that is set on the component itself.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param size The size expressed as a UnitValue
. E.g. "100px" or "200mm".
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
*/
public final CC minWidth(String size)
{
hor.setSize(LayoutUtil.derive(hor.getSize(), ConstraintParser.parseUnitValue(size, true), null, null));
return this;
}
/** The size for the component as a min and/or preferred and/or maximum size. The value will override any value that is set on
* the component itself.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param size The size expressed as a BoundSize
. E.g. "50:100px:200mm" or "100px".
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
*/
public final CC width(String size)
{
hor.setSize(ConstraintParser.parseBoundSize(size, false, true));
return this;
}
/** The maximum size for the component. The value will override any value that is set on the component itself.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param size The size expressed as a UnitValue
. E.g. "100px" or "200mm".
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
*/
public final CC maxWidth(String size)
{
hor.setSize(LayoutUtil.derive(hor.getSize(), null, null, ConstraintParser.parseUnitValue(size, true)));
return this;
}
/** The horizontal gap before and/or after the component. The gap is towards cell bounds and/or other component bounds.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param before The size of the gap expressed as a BoundSize
. E.g. "50:100px:200mm" or "100px!".
* @param after The size of the gap expressed as a BoundSize
. E.g. "50:100px:200mm" or "100px!".
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
*/
public final CC gapX(String before, String after)
{
if (before != null)
hor.setGapBefore(ConstraintParser.parseBoundSize(before, true, true));
if (after != null)
hor.setGapAfter(ConstraintParser.parseBoundSize(after, true, true));
return this;
}
/** Same functionality as getHorizontal().setAlign(ConstraintParser.parseUnitValue(unitValue, true))
only this method
* returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param align The align keyword or for instance "100px". E.g "left", "right", "leading" or "trailing".
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
*/
public final CC alignX(String align)
{
hor.setAlign(ConstraintParser.parseUnitValueOrAlign(align, true, null));
return this;
}
/** The grow priority compared to other components in the same cell.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param p The grow priority.
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
*/
public final CC growPrioX(int p)
{
hor.setGrowPriority(p);
return this;
}
/** Grow priority for the component horizontally and optionally vertically.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param widthHeight The new shrink weight and height. 1-2 arguments, never null.
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
* @since 3.7.2
*/
public final CC growPrio(int ... widthHeight)
{
switch (widthHeight.length) {
default:
throw new IllegalArgumentException("Illegal argument count: " + widthHeight.length);
case 2:
growPrioY(widthHeight[1]);
case 1:
growPrioX(widthHeight[0]);
}
return this;
}
/** Grow weight for the component horizontally. It default to weight 100
.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
* @see #growX(float)
*/
public final CC growX()
{
hor.setGrow(ResizeConstraint.WEIGHT_100);
return this;
}
/** Grow weight for the component horizontally.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param w The new grow weight.
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
*/
public final CC growX(float w)
{
hor.setGrow(new Float(w));
return this;
}
/** grow weight for the component horizontally and optionally vertically.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param widthHeight The new shrink weight and height. 1-2 arguments, never null.
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
* @since 3.7.2
*/
public final CC grow(float ... widthHeight)
{
switch (widthHeight.length) {
default:
throw new IllegalArgumentException("Illegal argument count: " + widthHeight.length);
case 2:
growY(widthHeight[1]);
case 1:
growX(widthHeight[0]);
}
return this;
}
/** The shrink priority compared to other components in the same cell.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param p The shrink priority.
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
*/
public final CC shrinkPrioX(int p)
{
hor.setShrinkPriority(p);
return this;
}
/** Shrink priority for the component horizontally and optionally vertically.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param widthHeight The new shrink weight and height. 1-2 arguments, never null.
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
* @since 3.7.2
*/
public final CC shrinkPrio(int ... widthHeight)
{
switch (widthHeight.length) {
default:
throw new IllegalArgumentException("Illegal argument count: " + widthHeight.length);
case 2:
shrinkPrioY(widthHeight[1]);
case 1:
shrinkPrioX(widthHeight[0]);
}
return this;
}
/** Shrink weight for the component horizontally.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param w The new shrink weight.
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
*/
public final CC shrinkX(float w)
{
hor.setShrink(new Float(w));
return this;
}
/** Shrink weight for the component horizontally and optionally vertically.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param widthHeight The new shrink weight and height. 1-2 arguments, never null.
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
* @since 3.7.2
*/
public final CC shrink(float ... widthHeight)
{
switch (widthHeight.length) {
default:
throw new IllegalArgumentException("Illegal argument count: " + widthHeight.length);
case 2:
shrinkY(widthHeight[1]);
case 1:
shrinkX(widthHeight[0]);
}
return this;
}
/** The end group that this component should be placed in.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param s The name of the group. If null
that means no group (default)
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
*/
public final CC endGroupY(String s)
{
ver.setEndGroup(s);
return this;
}
/** The end group(s) that this component should be placed in.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param xy The end group for x and y respectively. 1-2 arguments, not null.
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
* @since 3.7.2
*/
public final CC endGroup(String ... xy)
{
switch (xy.length) {
default:
throw new IllegalArgumentException("Illegal argument count: " + xy.length);
case 2:
endGroupY(xy[1]);
case 1:
endGroupX(xy[0]);
}
return this;
}
/** The size group that this component should be placed in.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param s The name of the group. If null
that means no group (default)
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
*/
public final CC sizeGroupY(String s)
{
ver.setSizeGroup(s);
return this;
}
/** The size group(s) that this component should be placed in.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param xy The size group for x and y respectively. 1-2 arguments, not null.
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
* @since 3.7.2
*/
public final CC sizeGroup(String ... xy)
{
switch (xy.length) {
default:
throw new IllegalArgumentException("Illegal argument count: " + xy.length);
case 2:
sizeGroupY(xy[1]);
case 1:
sizeGroupX(xy[0]);
}
return this;
}
/** The minimum size for the component. The value will override any value that is set on the component itself.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param size The size expressed as a UnitValue
. E.g. "100px" or "200mm".
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
*/
public final CC minHeight(String size)
{
ver.setSize(LayoutUtil.derive(ver.getSize(), ConstraintParser.parseUnitValue(size, false), null, null));
return this;
}
/** The size for the component as a min and/or preferred and/or maximum size. The value will override any value that is set on
* the component itself.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param size The size expressed as a BoundSize
. E.g. "50:100px:200mm" or "100px".
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
*/
public final CC height(String size)
{
ver.setSize(ConstraintParser.parseBoundSize(size, false, false));
return this;
}
/** The maximum size for the component. The value will override any value that is set on the component itself.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param size The size expressed as a UnitValue
. E.g. "100px" or "200mm".
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
*/
public final CC maxHeight(String size)
{
ver.setSize(LayoutUtil.derive(ver.getSize(), null, null, ConstraintParser.parseUnitValue(size, false)));
return this;
}
/** The vertical gap before (normally above) and/or after (normally below) the component. The gap is towards cell bounds and/or other component bounds.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param before The size of the gap expressed as a BoundSize
. E.g. "50:100px:200mm" or "100px!".
* @param after The size of the gap expressed as a BoundSize
. E.g. "50:100px:200mm" or "100px!".
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
*/
public final CC gapY(String before, String after)
{
if (before != null)
ver.setGapBefore(ConstraintParser.parseBoundSize(before, true, false));
if (after != null)
ver.setGapAfter(ConstraintParser.parseBoundSize(after, true, false));
return this;
}
/** Same functionality as getVertical().setAlign(ConstraintParser.parseUnitValue(unitValue, true))
only this method
* returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param align The align keyword or for instance "100px". E.g "top" or "bottom".
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
*/
public final CC alignY(String align)
{
ver.setAlign(ConstraintParser.parseUnitValueOrAlign(align, false, null));
return this;
}
/** The grow priority compared to other components in the same cell.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param p The grow priority.
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
*/
public final CC growPrioY(int p)
{
ver.setGrowPriority(p);
return this;
}
/** Grow weight for the component vertically. Defaults to 100
.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
* @see #growY(Float)
*/
public final CC growY()
{
ver.setGrow(ResizeConstraint.WEIGHT_100);
return this;
}
/** Grow weight for the component vertically.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param w The new grow weight.
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
*/
public final CC growY(float w)
{
ver.setGrow(w);
return this;
}
/** Grow weight for the component vertically.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param w The new grow weight.
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
*/
@Deprecated
public final CC growY(Float w)
{
ver.setGrow(w);
return this;
}
/** The shrink priority compared to other components in the same cell.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param p The shrink priority.
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
*/
public final CC shrinkPrioY(int p)
{
ver.setShrinkPriority(p);
return this;
}
/** Shrink weight for the component horizontally.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param w The new shrink weight.
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
*/
public final CC shrinkY(float w)
{
ver.setShrink(new Float(w));
return this;
}
/** How this component, if hidden (not visible), should be treated.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param mode The mode. Default to the mode in the {@link net.miginfocom.layout.LC}.
* 0 == Normal. Bounds will be calculated as if the component was visible.
* 1 == If hidden the size will be 0, 0 but the gaps remain.
* 2 == If hidden the size will be 0, 0 and gaps set to zero.
* 3 == If hidden the component will be disregarded completely and not take up a cell in the grid..
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
*/
public final CC hideMode(int mode)
{
setHideMode(mode);
return this;
}
/** The id used to reference this component in some constraints.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param s The id or null
. May consist of a groupID and an componentID which are separated by a dot: ".". E.g. "grp1.id1".
* The dot should never be first or last if present.
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
*/
public final CC id(String s)
{
setId(s);
return this;
}
/** Same functionality as {@link #setTag(String tag)} only this method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param tag The new tag. May be null
.
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
* @see #setTag(String)
*/
public final CC tag(String tag)
{
setTag(tag);
return this;
}
/** Set the cell(s) that the component should occupy in the grid. Same functionality as {@link #setCellX(int col)} and
* {@link #setCellY(int row)} together with {@link #setSpanX(int width)} and {@link #setSpanY(int height)}. This method
* returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param colRowWidthHeight cellX, cellY, spanX, spanY respectively. 1-4 arguments, not null.
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
* @see #setCellX(int)
* @see #setCellY(int)
* @see #setSpanX(int)
* @see #setSpanY(int)
* @since 3.7.2. Replacing cell(int, int) and cell(int, int, int, int)
*/
public final CC cell(int ... colRowWidthHeight)
{
switch (colRowWidthHeight.length) {
default:
throw new IllegalArgumentException("Illegal argument count: " + colRowWidthHeight.length);
case 4:
setSpanY(colRowWidthHeight[3]);
case 3:
setSpanX(colRowWidthHeight[2]);
case 2:
setCellY(colRowWidthHeight[1]);
case 1:
setCellX(colRowWidthHeight[0]);
}
return this;
}
/** Same functionality as spanX(cellsX).spanY(cellsY)
which means this cell will span cells in both x and y.
* This method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* Since 3.7.2 this takes an array/vararg whereas it previously only took two specific values, xSpan and ySpan.
* @param cells spanX and spanY, when present, and in that order.
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
* @see #setSpanY(int)
* @see #setSpanX(int)
* @see #spanY()
* @see #spanX()
* @since 3.7.2 Replaces span(int, int).
*/
public final CC span(int ... cells)
{
if (cells == null || cells.length == 0) {
setSpanX(LayoutUtil.INF);
setSpanY(1);
} else if (cells.length == 1) {
setSpanX(cells[0]);
setSpanY(1);
} else {
setSpanX(cells[0]);
setSpanY(cells[1]);
}
return this;
}
/** Corresponds exactly to the "gap left right top bottom" keyword.
* @param args Same as for the "gap" keyword. Length 1-4, never null buf elements can be null.
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
* @since 3.7.2
*/
public final CC gap(String ... args)
{
switch (args.length) {
default:
throw new IllegalArgumentException("Illegal argument count: " + args.length);
case 4:
gapBottom(args[3]);
case 3:
gapTop(args[2]);
case 2:
gapRight(args[1]);
case 1:
gapLeft(args[0]);
}
return this;
}
/** Sets the horizontal gap before the component.
*
* Note! This is currently same as gapLeft(). This might change in 4.x.
* @param boundsSize The size of the gap expressed as a BoundSize
. E.g. "50:100px:200mm" or "100px!".
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
* @since 3.7.2
*/
public final CC gapBefore(String boundsSize)
{
hor.setGapBefore(ConstraintParser.parseBoundSize(boundsSize, true, true));
return this;
}
/** Sets the horizontal gap after the component.
*
* Note! This is currently same as gapRight(). This might change in 4.x.
* @param boundsSize The size of the gap expressed as a BoundSize
. E.g. "50:100px:200mm" or "100px!".
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
* @since 3.7.2
*/
public final CC gapAfter(String boundsSize)
{
hor.setGapAfter(ConstraintParser.parseBoundSize(boundsSize, true, true));
return this;
}
/** Sets the gap above the component.
* @param boundsSize The size of the gap expressed as a BoundSize
. E.g. "50:100px:200mm" or "100px!".
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
* @since 3.7.2
*/
public final CC gapTop(String boundsSize)
{
ver.setGapBefore(ConstraintParser.parseBoundSize(boundsSize, true, false));
return this;
}
/** Sets the gap to the left the component.
* @param boundsSize The size of the gap expressed as a BoundSize
. E.g. "50:100px:200mm" or "100px!".
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
* @since 3.7.2
*/
public final CC gapLeft(String boundsSize)
{
hor.setGapBefore(ConstraintParser.parseBoundSize(boundsSize, true, true));
return this;
}
/** Sets the gap below the component.
* @param boundsSize The size of the gap expressed as a BoundSize
. E.g. "50:100px:200mm" or "100px!".
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
* @since 3.7.2
*/
public final CC gapBottom(String boundsSize)
{
ver.setGapAfter(ConstraintParser.parseBoundSize(boundsSize, true, false));
return this;
}
/** Sets the gap to the right of the component.
* @param boundsSize The size of the gap expressed as a BoundSize
. E.g. "50:100px:200mm" or "100px!".
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
* @since 3.7.2
*/
public final CC gapRight(String boundsSize)
{
hor.setGapAfter(ConstraintParser.parseBoundSize(boundsSize, true, true));
return this;
}
/** Same functionality as calling {@link #setSpanY(int)} with LayoutUtil.INF
which means this cell will span the rest of the column.
* This method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
* @see #setSpanY(int)
* @see #spanY()
*/
public final CC spanY()
{
return spanY(LayoutUtil.INF);
}
/** Same functionality as {@link #setSpanY(int)} only this method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param cells The number of cells to span (i.e. merge).
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
* @see #setSpanY(int)
*/
public final CC spanY(int cells)
{
setSpanY(cells);
return this;
}
/** Same functionality as {@link #setSpanX(int)} which means this cell will span the rest of the row.
* This method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
* @see #setSpanX(int)
* @see #spanX()
*/
public final CC spanX()
{
return spanX(LayoutUtil.INF);
}
/** Same functionality as {@link #setSpanX(int)} only this method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param cells The number of cells to span (i.e. merge).
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
* @see #setSpanY(int)
*/
public final CC spanX(int cells)
{
setSpanX(cells);
return this;
}
/** Same functionality as pushX().pushY()
which means this cell will push in both x and y dimensions.
* This method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
* @see #setPushX(Float)
* @see #setPushX(Float)
* @see #pushY()
* @see #pushX()
*/
public final CC push()
{
return pushX().pushY();
}
/** Same functionality as pushX(weightX).pushY(weightY)
which means this cell will push in both x and y dimensions.
* This method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param weightX The weight used in the push.
* @param weightY The weight used in the push.
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
* @see #setPushY(Float)
* @see #setPushX(Float)
* @see #pushY()
* @see #pushX()
*/
public final CC push(Float weightX, Float weightY)
{
return pushX(weightX).pushY(weightY);
}
/** Same functionality as {@link #setPushY(Float)} which means this cell will push the rest of the column.
* This method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
* @see #setPushY(Float)
*/
public final CC pushY()
{
return pushY(ResizeConstraint.WEIGHT_100);
}
/** Same functionality as {@link #setPushY(Float weight)} only this method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param weight The weight used in the push.
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
* @see #setPushY(Float)
*/
public final CC pushY(Float weight)
{
setPushY(weight);
return this;
}
/** Same functionality as {@link #setPushX(Float)} which means this cell will push the rest of the row.
* This method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
* @see #setPushX(Float)
*/
public final CC pushX()
{
return pushX(ResizeConstraint.WEIGHT_100);
}
/** Same functionality as {@link #setPushX(Float weight)} only this method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param weight The weight used in the push.
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
* @see #setPushY(Float)
*/
public final CC pushX(Float weight)
{
setPushX(weight);
return this;
}
/** Same functionality as {@link #setSplit(int parts)} only this method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param parts The number of parts (i.e. component slots) the cell should be divided into.
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
* @see #setSplit(int)
*/
public final CC split(int parts)
{
setSplit(parts);
return this;
}
/** Same functionality as split(LayoutUtil.INF), which means split until one of the keywords that breaks the split is found for
* a component after this one (e.g. wrap, newline and skip).
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
* @see #setSplit(int)
* @since 3.7.2
*/
public final CC split()
{
setSplit(LayoutUtil.INF);
return this;
}
/** Same functionality as {@link #setSkip(int)} only this method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param cells How many cells in the grid that should be skipped before the component that this constraint belongs to
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
* @see #setSkip(int)
*/
public final CC skip(int cells)
{
setSkip(cells);
return this;
}
/** Same functionality as skip(1).
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
* @see #setSkip(int)
* @since 3.7.2
*/
public final CC skip()
{
setSkip(1);
return this;
}
/** Same functionality as calling {@link #setExternal(boolean)} with true
only this method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
* @see #setExternal(boolean)
*/
public final CC external()
{
setExternal(true);
return this;
}
/** Same functionality as calling {@link #setFlowX(Boolean)} with Boolean.TRUE
only this method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
* @see #setFlowX(Boolean)
*/
public final CC flowX()
{
setFlowX(Boolean.TRUE);
return this;
}
/** Same functionality as calling {@link #setFlowX(Boolean)} with Boolean.FALSE
only this method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
* @see #setFlowX(Boolean)
*/
public final CC flowY()
{
setFlowX(Boolean.FALSE);
return this;
}
/** Same functionality as {@link #growX()} and {@link #growY()}.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
* @see #growX()
* @see #growY()
*/
public final CC grow()
{
growX();
growY();
return this;
}
/** Same functionality as calling {@link #setNewline(boolean)} with true
only this method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
* @see #setNewline(boolean)
*/
public final CC newline()
{
setNewline(true);
return this;
}
/** Same functionality as {@link #setNewlineGapSize(BoundSize)} only this method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param gapSize The gap size that will override the gap size in the row/column constraints if != null
. E.g. "5px" or "unrel".
* If null
or ""
the newline size will be set to the default size and turned on. This is different compared to
* {@link #setNewlineGapSize(BoundSize)}.
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
* @see #setNewlineGapSize(BoundSize)
*/
public final CC newline(String gapSize)
{
BoundSize bs = ConstraintParser.parseBoundSize(gapSize, true, (flowX != null && flowX == false));
if (bs != null) {
setNewlineGapSize(bs);
} else {
setNewline(true);
}
return this;
}
/** Same functionality as calling {@link #setWrap(boolean)} with true
only this method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
* @see #setWrap(boolean)
*/
public final CC wrap()
{
setWrap(true);
return this;
}
/** Same functionality as {@link #setWrapGapSize(BoundSize)} only this method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param gapSize The gap size that will override the gap size in the row/column constraints if != null
. E.g. "5px" or "unrel".
* If null
or ""
the wrap size will be set to the default size and turned on. This is different compared to
* {@link #setWrapGapSize(BoundSize)}.
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
* @see #setWrapGapSize(BoundSize)
*/
public final CC wrap(String gapSize)
{
BoundSize bs = ConstraintParser.parseBoundSize(gapSize, true, (flowX != null && flowX == false));
if (bs != null) {
setWrapGapSize(bs);
} else {
setWrap(true);
}
return this;
}
/** Same functionality as calling {@link #setDockSide(int)} with 0
only this method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
* @see #setDockSide(int)
*/
public final CC dockNorth()
{
setDockSide(0);
return this;
}
/** Same functionality as calling {@link #setDockSide(int)} with 1
only this method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
* @see #setDockSide(int)
*/
public final CC dockWest()
{
setDockSide(1);
return this;
}
/** Same functionality as calling {@link #setDockSide(int)} with 2
only this method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
* @see #setDockSide(int)
*/
public final CC dockSouth()
{
setDockSide(2);
return this;
}
/** Same functionality as calling {@link #setDockSide(int)} with 3
only this method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
* @see #setDockSide(int)
*/
public final CC dockEast()
{
setDockSide(3);
return this;
}
/** Sets the x-coordinate for the component. This is used to set the x coordinate position to a specific value. The component
* bounds is still precalculated to the grid cell and this method should be seen as a way to correct the x position.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param x The x position as a UnitValue. E.g. "10" or "40mm" or "container.x+10".
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
* @see #setPos(UnitValue[])
* @see #setBoundsInGrid(boolean)
*/
public final CC x(String x)
{
return corrPos(x, 0);
}
/** Sets the y-coordinate for the component. This is used to set the y coordinate position to a specific value. The component
* bounds is still precalculated to the grid cell and this method should be seen as a way to correct the y position.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param y The y position as a UnitValue. E.g. "10" or "40mm" or "container.x+10".
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
* @see #setPos(UnitValue[])
* @see #setBoundsInGrid(boolean)
*/
public final CC y(String y)
{
return corrPos(y, 1);
}
/** Sets the x2-coordinate for the component (right side). This is used to set the x2 coordinate position to a specific value. The component
* bounds is still precalculated to the grid cell and this method should be seen as a way to correct the x position.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param x2 The x2 side's position as a UnitValue. E.g. "10" or "40mm" or "container.x2 - 10".
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
* @see #setPos(UnitValue[])
* @see #setBoundsInGrid(boolean)
*/
public final CC x2(String x2)
{
return corrPos(x2, 2);
}
/** Sets the y2-coordinate for the component (bottom side). This is used to set the y2 coordinate position to a specific value. The component
* bounds is still precalculated to the grid cell and this method should be seen as a way to correct the y position.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param y2 The y2 side's position as a UnitValue. E.g. "10" or "40mm" or "container.x2 - 10".
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
* @see #setPos(UnitValue[])
* @see #setBoundsInGrid(boolean)
*/
public final CC y2(String y2)
{
return corrPos(y2, 3);
}
private final CC corrPos(String uv, int ix)
{
UnitValue[] b = getPos();
if (b == null)
b = new UnitValue[4];
b[ix] = ConstraintParser.parseUnitValue(uv, (ix % 2 == 0));
setPos(b);
setBoundsInGrid(true);
return this;
}
/** Same functionality as {@link #x(String x)} and {@link #y(String y)} together.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param x The x position as a UnitValue. E.g. "10" or "40mm" or "container.x+10".
* @param y The y position as a UnitValue. E.g. "10" or "40mm" or "container.x+10".
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
* @see #setPos(UnitValue[])
*/
public final CC pos(String x, String y)
{
UnitValue[] b = getPos();
if (b == null)
b = new UnitValue[4];
b[0] = ConstraintParser.parseUnitValue(x, true);
b[1] = ConstraintParser.parseUnitValue(y, false);
setPos(b);
setBoundsInGrid(false);
return this;
}
/** Same functionality as {@link #x(String x)}, {@link #y(String y)}, {@link #y2(String y)} and {@link #y2(String y)} together.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param x The x position as a UnitValue. E.g. "10" or "40mm" or "container.x+10".
* @param y The y position as a UnitValue. E.g. "10" or "40mm" or "container.x+10".
* @param x2 The x2 side's position as a UnitValue. E.g. "10" or "40mm" or "container.x2 - 10".
* @param y2 The y2 side's position as a UnitValue. E.g. "10" or "40mm" or "container.x2 - 10".
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
* @see #setPos(UnitValue[])
*/
public final CC pos(String x, String y, String x2, String y2)
{
setPos(new UnitValue[] {
ConstraintParser.parseUnitValue(x, true),
ConstraintParser.parseUnitValue(y, false),
ConstraintParser.parseUnitValue(x2, true),
ConstraintParser.parseUnitValue(y2, false),
});
setBoundsInGrid(false);
return this;
}
/** Same functionality as {@link #setPadding(UnitValue[])} but the unit values as absolute pixels. This method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param top The top padding that will be added to the y coordinate at the last stage in the layout.
* @param left The top padding that will be added to the x coordinate at the last stage in the layout.
* @param bottom The top padding that will be added to the y2 coordinate at the last stage in the layout.
* @param right The top padding that will be added to the x2 coordinate at the last stage in the layout.
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
* @see #setTag(String)
*/
public final CC pad(int top, int left, int bottom, int right)
{
setPadding(new UnitValue[] {
new UnitValue(top), new UnitValue(left), new UnitValue(bottom), new UnitValue(right)
});
return this;
}
/** Same functionality as setPadding(ConstraintParser.parseInsets(pad, false))}
only this method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param pad The string to parse. E.g. "10 10 10 10" or "20". If less than 4 groups the last will be used for the missing.
* @return this
so it is possible to chain calls. E.g. new ComponentConstraint().noGrid().gap().fill()
.
* @see #setTag(String)
*/
public final CC pad(String pad)
{
setPadding(pad != null ? ConstraintParser.parseInsets(pad, false) : null);
return this;
}
// **********************************************************
// Bean properties
// **********************************************************
/** Returns the horizontal dimension constraint for this component constraint. It has constraints for the horizontal size
* and grow/shrink priorities and weights.
*
* Note! If any changes is to be made it must be made direct when the object is returned. It is not allowed to save the
* constraint for later use.
* @return The current dimension constraint. Never null
.
*/
public DimConstraint getHorizontal()
{
return hor;
}
/** Sets the horizontal dimension constraint for this component constraint. It has constraints for the horizontal size
* and grow/shrink priorities and weights.
* @param h The new dimension constraint. If null
it will be reset to new DimConstraint();
*/
public void setHorizontal(DimConstraint h)
{
hor = h != null ? h : new DimConstraint();
}
/** Returns the vertical dimension constraint for this component constraint. It has constraints for the vertical size
* and grow/shrink priorities and weights.
*
* Note! If any changes is to be made it must be made direct when the object is returned. It is not allowed to save the
* constraint for later use.
* @return The current dimension constraint. Never null
.
*/
public DimConstraint getVertical()
{
return ver;
}
/** Sets the vertical dimension constraint for this component constraint. It has constraints for the vertical size
* and grow/shrink priorities and weights.
* @param v The new dimension constraint. If null
it will be reset to new DimConstraint();
*/
public void setVertical(DimConstraint v)
{
ver = v != null ? v : new DimConstraint();
}
/** Returns the vertical or horizontal dim constraint.
*
* Note! If any changes is to be made it must be made direct when the object is returned. It is not allowed to save the
* constraint for later use.
* @param isHor If the horizontal constraint should be returned.
* @return The dim constraint. Never null
.
*/
public DimConstraint getDimConstraint(boolean isHor)
{
return isHor ? hor : ver;
}
/** Returns the absolute positioning of one or more of the edges. This will be applied last in the layout cycle and will not
* affect the flow or grid positions. The positioning is relative to the parent and can not (as padding) be used
* to adjust the edges relative to the old value. May be null
and elements may be null
.
* null
value(s) for the x2 and y2 will be interpreted as to keep the preferred size and thus the x1
* and x2 will just absolutely positions the component.
*
* Note that {@link #setBoundsInGrid(boolean)} changes the interpretation of this property slightly.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return The current value as a new array, free to modify.
*/
public UnitValue[] getPos()
{
return pos != null ? new UnitValue[] {pos[0], pos[1], pos[2], pos[3]} : null;
}
/** Sets absolute positioning of one or more of the edges. This will be applied last in the layout cycle and will not
* affect the flow or grid positions. The positioning is relative to the parent and can not (as padding) be used
* to adjust the edges relative to the old value. May be null
and elements may be null
.
* null
value(s) for the x2 and y2 will be interpreted as to keep the preferred size and thus the x1
* and x2 will just absolutely positions the component.
*
* Note that {@link #setBoundsInGrid(boolean)} changes the interpretation of this property slightly.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param pos UnitValue[] {x, y, x2, y2}
. Must be null
or of length 4. Elements can be null
.
*/
public void setPos(UnitValue[] pos)
{
this.pos = pos != null ? new UnitValue[] {pos[0], pos[1], pos[2], pos[3]} : null;
linkTargets = null;
}
/** Returns if the absolute pos
value should be corrections to the component that is in a normal cell. If false
* the value of pos
is truly absolute in that it will not affect the grid or have a default bounds in the grid.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return The current value.
* @see #getPos()
*/
public boolean isBoundsInGrid()
{
return boundsInGrid;
}
/** Sets if the absolute pos
value should be corrections to the component that is in a normal cell. If false
* the value of pos
is truly absolute in that it will not affect the grid or have a default bounds in the grid.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param b true
for bounds taken from the grid position. false
is default.
* @see #setPos(UnitValue[])
*/
void setBoundsInGrid(boolean b)
{
this.boundsInGrid = b;
}
/** Returns the absolute cell position in the grid or -1
if cell positioning is not used.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return The current value.
*/
public int getCellX()
{
return cellX;
}
/** Set an absolute cell x-position in the grid. If >= 0 this point points to the absolute cell that this constaint's component should occupy.
* If there's already a component in that cell they will split the cell. The flow will then continue after this cell.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param x The x-position or -1
to disable cell positioning.
*/
public void setCellX(int x)
{
cellX = x;
}
/** Returns the absolute cell position in the grid or -1
if cell positioning is not used.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return The current value.
*/
public int getCellY()
{
return cellX < 0 ? -1 : cellY;
}
/** Set an absolute cell x-position in the grid. If >= 0 this point points to the absolute cell that this constaint's component should occupy.
* If there's already a component in that cell they will split the cell. The flow will then continue after this cell.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param y The y-position or -1
to disable cell positioning.
*/
public void setCellY(int y)
{
if (y < 0)
cellX = -1;
cellY = y < 0 ? 0 : y;
}
/** Sets the docking side. -1 means no docking.
* Valid sides are: north = 0, west = 1, south = 2, east = 3
.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return The current side.
*/
public int getDockSide()
{
return dock;
}
/** Sets the docking side. -1 means no docking.
* Valid sides are: north = 0, west = 1, south = 2, east = 3
.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param side -1 or 0-3.
*/
public void setDockSide(int side)
{
if (side < -1 || side > 3)
throw new IllegalArgumentException("Illegal dock side: " + side);
dock = side;
}
/** Returns if this component should have its bounds handled by an external source and not this layout manager.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return The current value.
*/
public boolean isExternal()
{
return external;
}
/** If this boolean is true this component is not handled in any way by the layout manager and the component can have its bounds set by an external
* handler which is normally by the use of some component.setBounds(x, y, width, height)
directly (for Swing).
*
* The bounds will not affect the minimum and preferred size of the container.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param b true
means that the bounds are not changed.
*/
public void setExternal(boolean b)
{
this.external = b;
}
/** Returns if the flow in the cell is in the horizontal dimension. Vertical if false
. Only the first
* component is a cell can set the flow.
*
* If null
the flow direction is inherited by from the {@link net.miginfocom.layout.LC}.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return The current value.
*/
public Boolean getFlowX()
{
return flowX;
}
/** Sets if the flow in the cell is in the horizontal dimension. Vertical if false
. Only the first
* component is a cell can set the flow.
*
* If null
the flow direction is inherited by from the {@link net.miginfocom.layout.LC}.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param b Boolean.TRUE
means horizontal flow in the cell.
*/
public void setFlowX(Boolean b)
{
this.flowX = b;
}
/** Sets how a component that is hidden (not visible) should be treated by default.
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return The mode:
* 0 == Normal. Bounds will be calculated as if the component was visible.
* 1 == If hidden the size will be 0, 0 but the gaps remain.
* 2 == If hidden the size will be 0, 0 and gaps set to zero.
* 3 == If hidden the component will be disregarded completely and not take up a cell in the grid..
*/
public int getHideMode()
{
return hideMode;
}
/** Sets how a component that is hidden (not visible) should be treated by default.
* @param mode The mode:
* 0 == Normal. Bounds will be calculated as if the component was visible.
* 1 == If hidden the size will be 0, 0 but the gaps remain.
* 2 == If hidden the size will be 0, 0 and gaps set to zero.
* 3 == If hidden the component will be disregarded completely and not take up a cell in the grid..
*/
public void setHideMode(int mode)
{
if (mode < -1 || mode > 3)
throw new IllegalArgumentException("Wrong hideMode: " + mode);
hideMode = mode;
}
/** Returns the id used to reference this component in some constraints.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return The id or null
. May consist of a groupID and an componentID which are separated by a dot: ".". E.g. "grp1.id1".
* The dot should never be first or last if present.
*/
public String getId()
{
return id;
}
/** Sets the id used to reference this component in some constraints.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param id The id or null
. May consist of a groupID and an componentID which are separated by a dot: ".". E.g. "grp1.id1".
* The dot should never be first or last if present.
*/
public void setId(String id)
{
this.id = id;
}
/** Returns the absolute resizing in the last stage of the layout cycle. May be null
and elements may be null
.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return The current value. null
or of length 4.
*/
public UnitValue[] getPadding()
{
return padding != null ? new UnitValue[] {padding[0], padding[1], padding[2], padding[3]} : null;
}
/** Sets the absolute resizing in the last stage of the layout cycle. These values are added to the edges and can thus for
* instance be used to grow or reduce the size or move the component an absolute number of pixels. May be null
* and elements may be null
.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param sides top, left, bottom right. Must be null
or of length 4.
*/
public void setPadding(UnitValue[] sides)
{
this.padding = sides != null ? new UnitValue[] {sides[0], sides[1], sides[2], sides[3]} : null;
}
/** Returns the visual padding used when laying out this Component. May be null
and elements may be null
.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return The current value. null
or of length 4.
*/
public UnitValue[] getVisualPadding()
{
return visualPadding != null ? new UnitValue[] {visualPadding[0], visualPadding[1], visualPadding[2], visualPadding[3]} : null;
}
/** Sets the visual padding used when laying out this Component.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param sides top, left, bottom right. Must be null
or of length 4.
*/
public void setVisualPadding(UnitValue[] sides)
{
this.visualPadding = sides != null ? new UnitValue[] {sides[0], sides[1], sides[2], sides[3]} : null;
}
/** Returns how many cells in the grid that should be skipped before the component that this constraint belongs to.
*
* Note that only the first component will be checked for this property.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return The current value. 0 if no skip.
*/
public int getSkip()
{
return skip;
}
/** Sets how many cells in the grid that should be skipped before the component that this constraint belongs to.
*
* Note that only the first component will be checked for this property.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param cells How many cells in the grid that should be skipped before the component that this constraint belongs to
*/
public void setSkip(int cells)
{
this.skip = cells;
}
/** Returns the number of cells the cell that this constraint's component will span in the indicated dimension. 1
is default and
* means that it only spans the current cell. LayoutUtil.INF
is used to indicate a span to the end of the column/row.
*
* Note that only the first component will be checked for this property.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return The current value.
*/
public int getSpanX()
{
return spanX;
}
/** Sets the number of cells the cell that this constraint's component will span in the indicated dimension. 1
is default and
* means that it only spans the current cell. LayoutUtil.INF
is used to indicate a span to the end of the column/row.
*
* Note that only the first component will be checked for this property.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param cells The number of cells to span (i.e. merge).
*/
public void setSpanX(int cells)
{
this.spanX = cells;
}
/** Returns the number of cells the cell that this constraint's component will span in the indicated dimension. 1
is default and
* means that it only spans the current cell. LayoutUtil.INF
is used to indicate a span to the end of the column/row.
*
* Note that only the first component will be checked for this property.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return The current value.
*/
public int getSpanY()
{
return spanY;
}
/** Sets the number of cells the cell that this constraint's component will span in the indicated dimension. 1
is default and
* means that it only spans the current cell. LayoutUtil.INF
is used to indicate a span to the end of the column/row.
*
* Note that only the first component will be checked for this property.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param cells The number of cells to span (i.e. merge).
*/
public void setSpanY(int cells)
{
this.spanY = cells;
}
/** "pushx" indicates that the column that this component is in (this first if the component spans) should default to growing.
* If any other column has been set to grow this push value on the component does nothing as the column's explicit grow weight
* will take precedence. Push is normally used when the grid has not been defined in the layout.
*
* If multiple components in a column has push weights set the largest one will be used for the column.
* @return The current push value. Default is null
.
*/
public Float getPushX()
{
return pushX;
}
/** "pushx" indicates that the column that this component is in (this first if the component spans) should default to growing.
* If any other column has been set to grow this push value on the component does nothing as the column's explicit grow weight
* will take precedence. Push is normally used when the grid has not been defined in the layout.
*
* If multiple components in a column has push weights set the largest one will be used for the column.
* @param weight The new push value. Default is null
.
*/
public void setPushX(Float weight)
{
this.pushX = weight;
}
/** "pushx" indicates that the row that this component is in (this first if the component spans) should default to growing.
* If any other row has been set to grow this push value on the component does nothing as the row's explicit grow weight
* will take precedence. Push is normally used when the grid has not been defined in the layout.
*
* If multiple components in a row has push weights set the largest one will be used for the row.
* @return The current push value. Default is null
.
*/
public Float getPushY()
{
return pushY;
}
/** "pushx" indicates that the row that this component is in (this first if the component spans) should default to growing.
* If any other row has been set to grow this push value on the component does nothing as the row's explicit grow weight
* will take precedence. Push is normally used when the grid has not been defined in the layout.
*
* If multiple components in a row has push weights set the largest one will be used for the row.
* @param weight The new push value. Default is null
.
*/
public void setPushY(Float weight)
{
this.pushY = weight;
}
/** Returns in how many parts the current cell (that this constraint's component will be in) should be split in. If for instance
* it is split in two, the next component will also share the same cell. Note that the cell can also span a number of
* cells, which means that you can for instance span three cells and split that big cell for two components. Split can be
* set to a very high value to make all components in the same row/column share the same cell (e.g. LayoutUtil.INF
).
*
* Note that only the first component will be checked for this property.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return The current value.
*/
public int getSplit()
{
return split;
}
/** Sets in how many parts the current cell (that this constraint's component will be in) should be split in. If for instance
* it is split in two, the next component will also share the same cell. Note that the cell can also span a number of
* cells, which means that you can for instance span three cells and split that big cell for two components. Split can be
* set to a very high value to make all components in the same row/column share the same cell (e.g. LayoutUtil.INF
).
*
* Note that only the first component will be checked for this property.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param parts The number of parts (i.e. component slots) the cell should be divided into.
*/
public void setSplit(int parts)
{
this.split = parts;
}
/** Tags the component with metadata. Currently only used to tag buttons with for instance "cancel" or "ok" to make them
* show up in the correct order depending on platform. See {@link PlatformDefaults#setButtonOrder(String)} for information.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return The current value. May be null
.
*/
public String getTag()
{
return tag;
}
/** Optional tag that gives more context to this constraint's component. It is for instance used to tag buttons in a
* button bar with the button type such as "ok", "help" or "cancel".
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param tag The new tag. May be null
.
*/
public void setTag(String tag)
{
this.tag = tag;
}
/** Returns if the flow should wrap to the next line/column after the component that this constraint belongs to.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return The current value.
*/
public boolean isWrap()
{
return wrap != null;
}
/** Sets if the flow should wrap to the next line/column after the component that this constraint belongs to.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param b true
means wrap after.
*/
public void setWrap(boolean b)
{
wrap = b ? (wrap == null ? DEF_GAP : wrap) : null;
}
/** Returns the wrap size if it is a custom size. If wrap was set to true with {@link #setWrap(boolean)} then this method will
* return null
since that means that the gap size should be the default one as defined in the rows spec.
* @return The custom gap size. NOTE! Will return null
for both no wrap and default wrap.
* @see #isWrap()
* @see #setWrap(boolean)
* @since 2.4.2
*/
public BoundSize getWrapGapSize()
{
return wrap == DEF_GAP ? null : wrap;
}
/** Set the wrap size and turns wrap on if != null
.
* @param s The custom gap size. NOTE! null
will not turn on or off wrap, it will only set the wrap gap size to "default".
* A non-null value will turn on wrap though.
* @see #isWrap()
* @see #setWrap(boolean)
* @since 2.4.2
*/
public void setWrapGapSize(BoundSize s)
{
wrap = s == null ? (wrap != null ? DEF_GAP : null) : s;
}
/** Returns if the flow should wrap to the next line/column before the component that this constraint belongs to.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return The current value.
*/
public boolean isNewline()
{
return newline != null;
}
/** Sets if the flow should wrap to the next line/column before the component that this constraint belongs to.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param b true
means wrap before.
*/
public void setNewline(boolean b)
{
newline = b ? (newline == null ? DEF_GAP : newline) : null;
}
/** Returns the newline size if it is a custom size. If newline was set to true with {@link #setNewline(boolean)} then this method will
* return null
since that means that the gap size should be the default one as defined in the rows spec.
* @return The custom gap size. NOTE! Will return null
for both no newline and default newline.
* @see #isNewline()
* @see #setNewline(boolean)
* @since 2.4.2
*/
public BoundSize getNewlineGapSize()
{
return newline == DEF_GAP ? null : newline;
}
/** Set the newline size and turns newline on if != null
.
* @param s The custom gap size. NOTE! null
will not turn on or off newline, it will only set the newline gap size to "default".
* A non-null value will turn on newline though.
* @see #isNewline()
* @see #setNewline(boolean)
* @since 2.4.2
*/
public void setNewlineGapSize(BoundSize s)
{
newline = s == null ? (newline != null ? DEF_GAP : null) : s;
}
/** Returns the animation spec. Default is a spec where animation is off (prio 0).
* @return Never null.
*/
public AnimSpec getAnimSpec()
{
return animSpec;
}
// ************************************************
// Persistence Delegate and Serializable combined.
// ************************************************
private Object readResolve() throws ObjectStreamException
{
return LayoutUtil.getSerializedObject(this);
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
{
LayoutUtil.setSerializedObject(this, LayoutUtil.readAsXML(in));
}
@Override
public void writeExternal(ObjectOutput out) throws IOException
{
if (getClass() == CC.class)
LayoutUtil.writeAsXML(out, this);
}
}miglayout-5.1/core/src/main/java/net/miginfocom/layout/ComponentWrapper.java000077500000000000000000000351001324101563200273540ustar00rootroot00000000000000package net.miginfocom.layout;
/*
* License (BSD):
* ==============
*
* Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
* 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 the MiG InfoCom AB nor 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.
*
* @version 1.0
* @author Mikael Grev, MiG InfoCom AB
* Date: 2006-sep-08
*/
/** A class that wraps the important parts of a Component.
*
* NOTE! .equals() and .hashcode() should be forwarded to the wrapped component. E.g.
*
* public int hashCode()
{
return getComponent().hashCode();
}
public final boolean equals(Object o)
{
if (o instanceof ComponentWrapper == false)
return false;
return getComponent().equals(((ComponentWrapper) o).getComponent());
}
*
*/
public interface ComponentWrapper
{
static final int TYPE_UNSET = -1;
public static final int TYPE_UNKNOWN = 0;
public static final int TYPE_CONTAINER = 1;
public static final int TYPE_LABEL = 2;
public static final int TYPE_TEXT_FIELD = 3;
public static final int TYPE_TEXT_AREA = 4;
public static final int TYPE_BUTTON = 5;
public static final int TYPE_LIST = 6;
public static final int TYPE_TABLE = 7;
public static final int TYPE_SCROLL_PANE = 8;
public static final int TYPE_IMAGE = 9;
public static final int TYPE_PANEL = 10;
public static final int TYPE_COMBO_BOX = 11;
public static final int TYPE_SLIDER = 12;
public static final int TYPE_SPINNER = 13;
public static final int TYPE_PROGRESS_BAR = 14;
public static final int TYPE_TREE = 15;
public static final int TYPE_CHECK_BOX = 16;
public static final int TYPE_SCROLL_BAR = 17;
public static final int TYPE_SEPARATOR = 18;
public static final int TYPE_TABBED_PANE = 19;
/** Returns the actual object that this wrapper is aggregating. This might be needed for getting
* information about the object that the wrapper interface does not provide.
*
* If this is a container the container should be returned instead.
* @return The actual object that this wrapper is aggregating. Not null
.
*/
public abstract Object getComponent();
/** Returns the current x coordinate for this component.
* @return The current x coordinate for this component.
*/
public abstract int getX();
/** Returns the current y coordinate for this component.
* @return The current y coordinate for this component.
*/
public abstract int getY();
/** Returns the current width for this component.
* @return The current width for this component.
*/
public abstract int getWidth();
/** Returns the current height for this component.
* @return The current height for this component.
*/
public abstract int getHeight();
/** Returns the screen x-coordinate for the upper left coordinate of the component layout-able bounds.
* @return The screen x-coordinate for the upper left coordinate of the component layout-able bounds.
*/
public abstract int getScreenLocationX();
/** Returns the screen y-coordinate for the upper left coordinate of the component layout-able bounds.
* @return The screen y-coordinate for the upper left coordinate of the component layout-able bounds.
*/
public abstract int getScreenLocationY();
/** Returns the minimum width of the component.
* @param hHint The Size hint for the other dimension. An implementation can use this value or the
* current size for the widget in this dimension, or a combination of both, to calculate the correct size.
* Use -1 to denote that there is no hint. This corresponds with SWT.DEFAULT.
* @return The minimum width of the component.
* @since 3.5. Added the hint as a parameter knowing that a correction and recompilation is necessary for
* any implementing classes. This change was worth it though.
*/
public abstract int getMinimumWidth(int hHint);
/** Returns the minimum height of the component.
* @param wHint The Size hint for the other dimension. An implementation can use this value or the
* current size for the widget in this dimension, or a combination of both, to calculate the correct size.
* Use -1 to denote that there is no hint. This corresponds with SWT.DEFAULT.
* @return The minimum height of the component.
* @since 3.5. Added the hint as a parameter knowing that a correction and recompilation is necessary for
* any implementing classes. This change was worth it though.
*/
public abstract int getMinimumHeight(int wHint);
/** Returns the preferred width of the component.
* @param hHint The Size hint for the other dimension. An implementation can use this value or the
* current size for the widget in this dimension, or a combination of both, to calculate the correct size.
* Use -1 to denote that there is no hint. This corresponds with SWT.DEFAULT.
* @return The preferred width of the component.
* @since 3.5. Added the hint as a parameter knowing that a correction and recompilation is necessary for
* any implementing classes. This change was worth it though.
*/
public abstract int getPreferredWidth(int hHint);
/** Returns the preferred height of the component.
* @param wHint The Size hint for the other dimension. An implementation can use this value or the
* current size for the widget in this dimension, or a combination of both, to calculate the correct size.
* Use -1 to denote that there is no hint. This corresponds with SWT.DEFAULT.
* @return The preferred height of the component.
* @since 3.5. Added the hint as a parameter knowing that a correction and recompilation is necessary for
* any implementing classes. This change was worth it though.
*/
public abstract int getPreferredHeight(int wHint);
/** Returns the maximum width of the component.
* @param hHint The Size hint for the other dimension. An implementation can use this value or the
* current size for the widget in this dimension, or a combination of both, to calculate the correct size.
* Use -1 to denote that there is no hint. This corresponds with SWT.DEFAULT.
* @return The maximum width of the component.
* @since 3.5. Added the hint as a parameter knowing that a correction and recompilation is necessary for
* any implementing classes. This change was worth it though.
*/
public abstract int getMaximumWidth(int hHint);
/** Returns the maximum height of the component.
* @param wHint The Size hint for the other dimension. An implementation can use this value or the
* current size for the widget in this dimension, or a combination of both, to calculate the correct size.
* Use -1 to denote that there is no hint. This corresponds with SWT.DEFAULT.
* @return The maximum height of the component.
* @since 3.5. Added the hint as a parameter knowing that a correction and recompilation is necessary for
* any implementing classes. This change was worth it though.
*/
public abstract int getMaximumHeight(int wHint);
/** Sets the component's bounds.
* @param x The x coordinate.
* @param y The y coordinate.
* @param width The width.
* @param height The height.
*/
public abstract void setBounds(int x, int y, int width, int height);
/** Returns if the component's visibility is set to true
. This should not return if the component is
* actually visible, but if the visibility is set to true or not.
* @return true
means visible.
*/
public abstract boolean isVisible();
/** Returns the baseline for the component given the suggested height.
* @param width The width to calculate for if other than the current. If -1
the current size should be used.
* @param height The height to calculate for if other than the current. If -1
the current size should be used.
* @return The baseline from the top or -1 if not applicable.
*/
public abstract int getBaseline(int width, int height);
/** Returns if the component has a baseline and if it can be retrieved. Should for instance return
* false
for Swing before mustang.
* @return If the component has a baseline and if it can be retrieved.
*/
public abstract boolean hasBaseline();
/** Returns the container for this component.
* @return The container for this component. Will return null
if the component has no parent.
*/
public abstract ContainerWrapper getParent();
/** Returns the pixel unit factor for the horizontal or vertical dimension.
*
* The factor is 1 for both dimensions on the normal font in a JPanel on Windows. The factor should increase with a bigger "X".
*
* This is the Swing version:
*
* Rectangle2D r = fm.getStringBounds("X", parent.getGraphics());
* wFactor = r.getWidth() / 6;
* hFactor = r.getHeight() / 13.27734375f;
*
* @param isHor If it is the horizontal factor that should be returned.
* @return The factor.
*/
public abstract float getPixelUnitFactor(boolean isHor);
/** Returns the DPI (Dots Per Inch) of the screen the component is currently in or for the default
* screen if the component is not visible.
*
* If headless mode {@link net.miginfocom.layout.PlatformDefaults#getDefaultDPI} will be returned.
* @return The DPI.
*/
public abstract int getHorizontalScreenDPI();
/** Returns the DPI (Dots Per Inch) of the screen the component is currently in or for the default
* screen if the component is not visible.
*
* If headless mode {@link net.miginfocom.layout.PlatformDefaults#getDefaultDPI} will be returned.
* @return The DPI.
*/
public abstract int getVerticalScreenDPI();
/** Returns the pixel size of the screen that the component is currently in or for the default
* screen if the component is not visible or null
.
*
* If in headless mode 1024
is returned.
* @return The screen size. E.g. 1280
.
*/
public abstract int getScreenWidth();
/** Returns the pixel size of the screen that the component is currently in or for the default
* screen if the component is not visible or null
.
*
* If in headless mode 768
is returned.
* @return The screen size. E.g. 1024
.
*/
public abstract int getScreenHeight();
/** Returns a String id that can be used to reference the component in link constraints. This value should
* return the default id for the component. The id can be set for a component in the constraints and if
* so the value returned by this method will never be used. If there are no sensible id for the component
* null
should be returned.
*
* For instance the Swing implementation returns the string returned from Component.getName()
.
* @return The string link id or null
.
*/
public abstract String getLinkId();
/** Returns a hash code that should be reasonably different for anything that might change the layout. This value is used to
* know if the component layout needs to clear any caches.
* @return A hash code that should be reasonably different for anything that might change the layout. Returns -1 if the widget is
* disposed.
*/
public abstract int getLayoutHashCode();
/** Returns the padding on a component by component basis. This method can be overridden to return padding to compensate for example for
* borders that have shadows or where the outer most pixel is not the visual "edge" to align to.
*
* Default implementation returns null
for all components except for Windows XP's JTabbedPane which will return new Insets(0, 0, 2, 2).
*
* NOTE! To reduce generated garbage the returned padding should never be changed so that the same insets can be returned many times.
* @return null
if no padding. NOTE! To reduce generated garbage the returned padding should never be changed so that
* the same insets can be returned many times. [top, left, bottom, right]
*/
public int[] getVisualPadding();
/** Paints component outline to indicate where it is.
* @param showVisualPadding If the visual padding should be shown in the debug drawing.
*/
public abstract void paintDebugOutline(boolean showVisualPadding);
/** Returns the type of component that this wrapper is wrapping.
*
* This method can be invoked often so the result should be cached.
*
* @param disregardScrollPane Is true
any wrapping scroll pane should be disregarded and the type
* of the scrolled component should be returned.
* @return The type of component that this wrapper is wrapping. E.g. {@link #TYPE_LABEL}.
*/
public abstract int getComponentType(boolean disregardScrollPane);
/** Returns in what way the min/pref/max sizes relates to it's height or width for the current settings of the component (like wrapText).
* If the min/pref/max height depends on it's width return {@link net.miginfocom.layout.LayoutUtil#HORIZONTAL}
* If the min/pref/max width depends on it's height (not common) return {@link net.miginfocom.layout.LayoutUtil#VERTICAL}
* If there is no connection between the preferred min/pref/max and the size of the component return -1.
* @since 5.0
*/
public abstract int getContentBias();
}miglayout-5.1/core/src/main/java/net/miginfocom/layout/ConstraintParser.java000077500000000000000000001434161324101563200273640ustar00rootroot00000000000000package net.miginfocom.layout;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/*
* License (BSD):
* ==============
*
* Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
* 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 the MiG InfoCom AB nor 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.
*
* @version 1.0
* @author Mikael Grev, MiG InfoCom AB
* Date: 2006-sep-08
*/
/** Parses string constraints.
*/
public final class ConstraintParser
{
private ConstraintParser()
{
}
/** Parses the layout constraints and stores the parsed values in the transient (cache) member variables.
* @param s The String to parse. Should not be null
and must be lower case and trimmed .
* @throws RuntimeException if the constraint was not valid.
* @return The parsed constraint. Never null
.
*/
public static LC parseLayoutConstraint(String s)
{
LC lc = new LC();
if (s.isEmpty())
return lc;
String[] parts = toTrimmedTokens(s, ',');
// First check for "ltr" or "rtl" since that will affect the interpretation of the other constraints.
for (int i = 0; i < parts.length; i++) {
String part = parts[i];
if (part == null)
continue;
int len = part.length();
if (len == 3 || len == 11) { // Optimization
if (part.equals("ltr") || part.equals("rtl") || part.equals("lefttoright") || part.equals("righttoleft")) {
lc.setLeftToRight(part.charAt(0) == 'l' ? Boolean.TRUE : Boolean.FALSE);
parts[i] = null; // So we will not try to interpret it again
}
if (part.equals("ttb") || part.equals("btt") || part.equals("toptobottom") || part.equals("bottomtotop")) {
lc.setTopToBottom(part.charAt(0) == 't');
parts[i] = null; // So we will not try to interpret it again
}
}
}
for (String part : parts) {
if (part == null || part.length() == 0)
continue;
try {
int ix = -1;
char c = part.charAt(0);
if (c == 'w' || c == 'h') {
ix = startsWithLenient(part, "wrap", -1, true);
if (ix > -1) {
String num = part.substring(ix).trim();
lc.setWrapAfter(num.length() != 0 ? Integer.parseInt(num) : 0);
continue;
}
boolean isHor = c == 'w';
if (isHor && (part.startsWith("w ") || part.startsWith("width "))) {
String sz = part.substring(part.charAt(1) == ' ' ? 2 : 6).trim();
lc.setWidth(parseBoundSize(sz, false, true));
continue;
}
if (!isHor && (part.startsWith("h ") || part.startsWith("height "))) {
String uvStr = part.substring(part.charAt(1) == ' ' ? 2 : 7).trim();
lc.setHeight(parseBoundSize(uvStr, false, false));
continue;
}
if (part.length() > 5) {
String sz = part.substring(5).trim();
if (part.startsWith("wmin ")) {
lc.minWidth(sz);
continue;
} else if (part.startsWith("wmax ")) {
lc.maxWidth(sz);
continue;
} else if (part.startsWith("hmin ")) {
lc.minHeight(sz);
continue;
} else if (part.startsWith("hmax ")) {
lc.maxHeight(sz);
continue;
}
}
if (part.startsWith("hidemode ")) {
lc.setHideMode(Integer.parseInt(part.substring(9)));
continue;
}
}
if (c == 'g') {
if (part.startsWith("gapx ")) {
lc.setGridGapX(parseBoundSize(part.substring(5).trim(), true, true));
continue;
}
if (part.startsWith("gapy ")) {
lc.setGridGapY(parseBoundSize(part.substring(5).trim(), true, false));
continue;
}
if (part.startsWith("gap ")) {
String[] gaps = toTrimmedTokens(part.substring(4).trim(), ' ');
lc.setGridGapX(parseBoundSize(gaps[0], true, true));
lc.setGridGapY(gaps.length > 1 ? parseBoundSize(gaps[1], true, false) : lc.getGridGapX());
continue;
}
}
if (c == 'd') {
ix = startsWithLenient(part, "debug", 5, true);
if (ix > -1) {
String millis = part.substring(ix).trim();
lc.setDebugMillis(millis.length() > 0 ? Integer.parseInt(millis) : 1000);
continue;
}
}
if (c == 'n') {
if (part.equals("nogrid")) {
lc.setNoGrid(true);
continue;
}
if (part.equals("nocache")) {
lc.setNoCache(true);
continue;
}
if (part.equals("novisualpadding")) {
lc.setVisualPadding(false);
continue;
}
}
if (c == 'f') {
if (part.equals("fill") || part.equals("fillx") || part.equals("filly")) {
lc.setFillX(part.length() == 4 || part.charAt(4) == 'x');
lc.setFillY(part.length() == 4 || part.charAt(4) == 'y');
continue;
}
if (part.equals("flowy")) {
lc.setFlowX(false);
continue;
}
if (part.equals("flowx")) {
lc.setFlowX(true); // This is the default but added for consistency
continue;
}
}
if (c == 'i') {
ix = startsWithLenient(part, "insets", 3, true);
if (ix > -1) {
String insStr = part.substring(ix).trim();
UnitValue[] ins = parseInsets(insStr, true);
LayoutUtil.putCCString(ins, insStr);
lc.setInsets(ins);
continue;
}
}
if (c == 'a') {
ix = startsWithLenient(part, new String[]{"aligny", "ay"}, new int[]{6, 2}, true);
if (ix > -1) {
UnitValue align = parseUnitValueOrAlign(part.substring(ix).trim(), false, null);
if (align == UnitValue.BASELINE_IDENTITY)
throw new IllegalArgumentException("'baseline' can not be used to align the whole component group.");
lc.setAlignY(align);
continue;
}
ix = startsWithLenient(part, new String[]{"alignx", "ax"}, new int[]{6, 2}, true);
if (ix > -1) {
lc.setAlignX(parseUnitValueOrAlign(part.substring(ix).trim(), true, null));
continue;
}
ix = startsWithLenient(part, "align", 2, true);
if (ix > -1) {
String[] gaps = toTrimmedTokens(part.substring(ix).trim(), ' ');
lc.setAlignX(parseUnitValueOrAlign(gaps[0], true, null));
if (gaps.length > 1) {
UnitValue align = parseUnitValueOrAlign(gaps[1], false, null);
if (align == UnitValue.BASELINE_IDENTITY)
throw new IllegalArgumentException("'baseline' can not be used to align the whole component group.");
lc.setAlignY(align);
}
continue;
}
}
if (c == 'p') {
if (part.startsWith("packalign ")) {
String[] packs = toTrimmedTokens(part.substring(10).trim(), ' ');
lc.setPackWidthAlign(packs[0].length() > 0 ? Float.parseFloat(packs[0]) : 0.5f);
if (packs.length > 1)
lc.setPackHeightAlign(Float.parseFloat(packs[1]));
continue;
}
if (part.startsWith("pack ") || part.equals("pack")) {
String ps = part.substring(4).trim();
String[] packs = toTrimmedTokens(ps.length() > 0 ? ps : "pref pref", ' ');
lc.setPackWidth(parseBoundSize(packs[0], false, true));
if (packs.length > 1)
lc.setPackHeight(parseBoundSize(packs[1], false, false));
continue;
}
}
if (lc.getAlignX() == null) {
UnitValue alignX = parseAlignKeywords(part, true);
if (alignX != null) {
lc.setAlignX(alignX);
continue;
}
}
UnitValue alignY = parseAlignKeywords(part, false);
if (alignY != null) {
lc.setAlignY(alignY);
continue;
}
throw new IllegalArgumentException("Unknown Constraint: '" + part + "'\n");
} catch (Exception ex) {
throw new IllegalArgumentException("Illegal Constraint: '" + part + "'\n" + ex.getMessage());
}
}
// lc = (LC) serializeTest(lc);
return lc;
}
/** Parses the column or rows constraints. They normally looks something like "[min:pref]rel[10px][]"
.
* @param s The string to parse. Not null
.
* @return An array of {@link DimConstraint}s that is as many are there exist "[...]" sections in the string that is parsed.
* @throws RuntimeException if the constraint was not valid.
*/
public static AC parseRowConstraints(String s)
{
return parseAxisConstraint(s, false);
}
/** Parses the column or rows constraints. They normally looks something like "[min:pref]rel[10px][]"
.
* @param s The string to parse. Not null
.
* @return An array of {@link DimConstraint}s that is as many are there exist "[...]" sections in the string that is parsed.
* @throws RuntimeException if the constraint was not valid.
*/
public static AC parseColumnConstraints(String s)
{
return parseAxisConstraint(s, true);
}
/** Parses the column or rows constraints. They normally looks something like "[min:pref]rel[10px][]"
.
* @param s The string to parse. Not null
.
* @param isCols If this for columns rather than rows.
* @return An array of {@link DimConstraint}s that is as many are there exist "[...]" sections in the string that is parsed.
* @throws RuntimeException if the constraint was not valid.
*/
private static AC parseAxisConstraint(String s, boolean isCols)
{
s = s.trim();
if (s.length() == 0)
return new AC(); // Short circuit for performance.
s = s.toLowerCase();
ArrayList parts = getRowColAndGapsTrimmed(s);
BoundSize[] gaps = new BoundSize[(parts.size() >> 1) + 1];
for (int i = 0, iSz = parts.size(), gIx = 0; i < iSz; i += 2, gIx++)
gaps[gIx] = parseBoundSize(parts.get(i), true, isCols);
DimConstraint[] colSpecs = new DimConstraint[parts.size() >> 1];
for (int i = 0, gIx = 0; i < colSpecs.length; i++, gIx++) {
if (gIx >= gaps.length - 1)
gIx = gaps.length - 2;
colSpecs[i] = parseDimConstraint(parts.get((i << 1) + 1), gaps[gIx], gaps[gIx + 1], isCols);
}
AC ac = new AC();
ac.setConstaints(colSpecs);
// ac = (AC) serializeTest(ac);
return ac;
}
/** Parses a single column or row constraint.
* @param s The single constraint to parse. May look something like "min:pref,fill,grow"
. Should not be null
and must
* be lower case and trimmed .
* @param gapBefore The default gap "before" the column/row constraint. Can be overridden with a "gap"
section within s
.
* @param gapAfter The default gap "after" the column/row constraint. Can be overridden with a "gap"
section within s
.
* @param isCols If the constraints are column constraints rather than row constraints.
* @return A single constraint. Never null
.
* @throws RuntimeException if the constraint was not valid.
*/
private static DimConstraint parseDimConstraint(String s, BoundSize gapBefore, BoundSize gapAfter, boolean isCols)
{
DimConstraint dimConstraint = new DimConstraint();
// Default values.
dimConstraint.setGapBefore(gapBefore);
dimConstraint.setGapAfter(gapAfter);
String[] parts = toTrimmedTokens(s, ',');
for (int i = 0; i < parts.length; i++) {
String part = parts[i];
try {
if (part.length() == 0)
continue;
if (part.equals("fill")) {
dimConstraint.setFill(true);
// dimConstraint.setAlign(null); // Can not have both fill and alignment (changed for 3.5 since it can have "growy 0")
continue;
}
if (part.equals("nogrid")) {
dimConstraint.setNoGrid(true);
continue;
}
int ix = -1;
char c = part.charAt(0);
if (c == 's') {
ix = startsWithLenient(part, new String[] {"sizegroup", "sg"}, new int[] {5, 2}, true);
if (ix > -1) {
dimConstraint.setSizeGroup(part.substring(ix).trim());
continue;
}
ix = startsWithLenient(part, new String[] {"shrinkprio", "shp"}, new int[] {10, 3}, true);
if (ix > -1) {
dimConstraint.setShrinkPriority(Integer.parseInt(part.substring(ix).trim()));
continue;
}
ix = startsWithLenient(part, "shrink", 6, true);
if (ix > -1) {
dimConstraint.setShrink(parseFloat(part.substring(ix).trim(), ResizeConstraint.WEIGHT_100));
continue;
}
}
if (c == 'g') {
ix = startsWithLenient(part, new String[] {"growpriority", "gp"}, new int[] {5, 2}, true);
if (ix > -1) {
dimConstraint.setGrowPriority(Integer.parseInt(part.substring(ix).trim()));
continue;
}
ix = startsWithLenient(part, "grow", 4, true);
if (ix > -1) {
dimConstraint.setGrow(parseFloat(part.substring(ix).trim(), ResizeConstraint.WEIGHT_100));
continue;
}
}
if (c == 'a') {
ix = startsWithLenient(part, "align", 2, true);
if (ix > -1) {
// if (dimConstraint.isFill() == false) // Swallow, but ignore if fill is set. (changed for 3.5 since it can have "growy 0")
dimConstraint.setAlign(parseUnitValueOrAlign(part.substring(ix).trim(), isCols, null));
continue;
}
}
UnitValue align = parseAlignKeywords(part, isCols);
if (align != null) {
// if (dimConstraint.isFill() == false) // Swallow, but ignore if fill is set. (changed for 3.5 since it can have "growy 0")
dimConstraint.setAlign(align);
continue;
}
// Only min:pref:max still left that is ok
dimConstraint.setSize(parseBoundSize(part, false, isCols));
} catch (Exception ex) {
throw new IllegalArgumentException("Illegal constraint: '" + part + "'\n" + ex.getMessage());
}
}
return dimConstraint;
}
/** Parses all component constraints and stores the parsed values in the transient (cache) member variables.
* @param constrMap The constraints as String
s. Strings must be lower case and trimmed
* @return The parsed constraints. Never null
.
*/
public static Map parseComponentConstraints(Map constrMap)
{
HashMap flowConstrMap = new HashMap();
for (Iterator> it = constrMap.entrySet().iterator(); it.hasNext();) {
Map.Entry entry = it.next();
flowConstrMap.put(entry.getKey(), parseComponentConstraint(entry.getValue()));
}
return flowConstrMap;
}
/** Parses one component constraint and returns the parsed value.
* @param s The string to parse. Must be lower case and trimmed .
* @throws RuntimeException if the constraint was not valid.
* @return The parsed constraint. Never null
.
*/
public static CC parseComponentConstraint(String s)
{
CC cc = new CC();
if (s == null || s.isEmpty())
return cc;
String[] parts = toTrimmedTokens(s, ',');
for (String part : parts) {
try {
if (part.length() == 0)
continue;
int ix = -1;
char c = part.charAt(0);
if (c == 'n') {
if (part.equals("north")) {
cc.setDockSide(0);
continue;
}
if (part.equals("newline")) {
cc.setNewline(true);
continue;
}
if (part.startsWith("newline ")) {
String gapSz = part.substring(7).trim();
cc.setNewlineGapSize(parseBoundSize(gapSz, true, true));
continue;
}
}
if (c == 'f' && (part.equals("flowy") || part.equals("flowx"))) {
cc.setFlowX(part.charAt(4) == 'x' ? Boolean.TRUE : Boolean.FALSE);
continue;
}
if (c == 's') {
ix = startsWithLenient(part, "skip", 4, true);
if (ix > -1) {
String num = part.substring(ix).trim();
cc.setSkip(num.length() != 0 ? Integer.parseInt(num) : 1);
continue;
}
ix = startsWithLenient(part, "split", 5, true);
if (ix > -1) {
String split = part.substring(ix).trim();
cc.setSplit(split.length() > 0 ? Integer.parseInt(split) : LayoutUtil.INF);
continue;
}
if (part.equals("south")) {
cc.setDockSide(2);
continue;
}
ix = startsWithLenient(part, new String[]{"spany", "sy"}, new int[]{5, 2}, true);
if (ix > -1) {
cc.setSpanY(parseSpan(part.substring(ix).trim()));
continue;
}
ix = startsWithLenient(part, new String[]{"spanx", "sx"}, new int[]{5, 2}, true);
if (ix > -1) {
cc.setSpanX(parseSpan(part.substring(ix).trim()));
continue;
}
ix = startsWithLenient(part, "span", 4, true);
if (ix > -1) {
String[] spans = toTrimmedTokens(part.substring(ix).trim(), ' ');
cc.setSpanX(spans[0].length() > 0 ? Integer.parseInt(spans[0]) : LayoutUtil.INF);
cc.setSpanY(spans.length > 1 ? Integer.parseInt(spans[1]) : 1);
continue;
}
ix = startsWithLenient(part, "shrinkx", 7, true);
if (ix > -1) {
cc.getHorizontal().setShrink(parseFloat(part.substring(ix).trim(), ResizeConstraint.WEIGHT_100));
continue;
}
ix = startsWithLenient(part, "shrinky", 7, true);
if (ix > -1) {
cc.getVertical().setShrink(parseFloat(part.substring(ix).trim(), ResizeConstraint.WEIGHT_100));
continue;
}
ix = startsWithLenient(part, "shrink", 6, false);
if (ix > -1) {
String[] shrinks = toTrimmedTokens(part.substring(ix).trim(), ' ');
cc.getHorizontal().setShrink(parseFloat(shrinks[0], ResizeConstraint.WEIGHT_100));
if (shrinks.length > 1)
cc.getVertical().setShrink(parseFloat(shrinks[1], ResizeConstraint.WEIGHT_100));
continue;
}
ix = startsWithLenient(part, new String[]{"shrinkprio", "shp"}, new int[]{10, 3}, true);
if (ix > -1) {
String sp = part.substring(ix).trim();
if (sp.startsWith("x") || sp.startsWith("y")) { // To handle "gpx", "gpy", "shrinkpriorityx", shrinkpriorityy"
(sp.startsWith("x") ? cc.getHorizontal() : cc.getVertical()).setShrinkPriority(Integer.parseInt(sp.substring(2)));
} else {
String[] shrinks = toTrimmedTokens(sp, ' ');
cc.getHorizontal().setShrinkPriority(Integer.parseInt(shrinks[0]));
if (shrinks.length > 1)
cc.getVertical().setShrinkPriority(Integer.parseInt(shrinks[1]));
}
continue;
}
ix = startsWithLenient(part, new String[]{"sizegroupx", "sizegroupy", "sgx", "sgy"}, new int[]{9, 9, 2, 2}, true);
if (ix > -1) {
String sg = part.substring(ix).trim();
char lc = part.charAt(ix - 1);
if (lc != 'y')
cc.getHorizontal().setSizeGroup(sg);
if (lc != 'x')
cc.getVertical().setSizeGroup(sg);
continue;
}
}
if (c == 'g') {
ix = startsWithLenient(part, "growx", 5, true);
if (ix > -1) {
cc.getHorizontal().setGrow(parseFloat(part.substring(ix).trim(), ResizeConstraint.WEIGHT_100));
continue;
}
ix = startsWithLenient(part, "growy", 5, true);
if (ix > -1) {
cc.getVertical().setGrow(parseFloat(part.substring(ix).trim(), ResizeConstraint.WEIGHT_100));
continue;
}
ix = startsWithLenient(part, "grow", 4, false);
if (ix > -1) {
String[] grows = toTrimmedTokens(part.substring(ix).trim(), ' ');
cc.getHorizontal().setGrow(parseFloat(grows[0], ResizeConstraint.WEIGHT_100));
cc.getVertical().setGrow(parseFloat(grows.length > 1 ? grows[1] : "", ResizeConstraint.WEIGHT_100));
continue;
}
ix = startsWithLenient(part, new String[]{"growprio", "gp"}, new int[]{8, 2}, true);
if (ix > -1) {
String gp = part.substring(ix).trim();
char c0 = gp.length() > 0 ? gp.charAt(0) : ' ';
if (c0 == 'x' || c0 == 'y') { // To handle "gpx", "gpy", "growpriorityx", growpriorityy"
(c0 == 'x' ? cc.getHorizontal() : cc.getVertical()).setGrowPriority(Integer.parseInt(gp.substring(2)));
} else {
String[] grows = toTrimmedTokens(gp, ' ');
cc.getHorizontal().setGrowPriority(Integer.parseInt(grows[0]));
if (grows.length > 1)
cc.getVertical().setGrowPriority(Integer.parseInt(grows[1]));
}
continue;
}
if (part.startsWith("gap")) {
BoundSize[] gaps = parseGaps(part); // Changes order!!
if (gaps[0] != null)
cc.getVertical().setGapBefore(gaps[0]);
if (gaps[1] != null)
cc.getHorizontal().setGapBefore(gaps[1]);
if (gaps[2] != null)
cc.getVertical().setGapAfter(gaps[2]);
if (gaps[3] != null)
cc.getHorizontal().setGapAfter(gaps[3]);
continue;
}
}
if (c == 'a') {
ix = startsWithLenient(part, new String[]{"aligny", "ay"}, new int[]{6, 2}, true);
if (ix > -1) {
cc.getVertical().setAlign(parseUnitValueOrAlign(part.substring(ix).trim(), false, null));
continue;
}
ix = startsWithLenient(part, new String[]{"alignx", "ax"}, new int[]{6, 2}, true);
if (ix > -1) {
cc.getHorizontal().setAlign(parseUnitValueOrAlign(part.substring(ix).trim(), true, null));
continue;
}
ix = startsWithLenient(part, "align", 2, true);
if (ix > -1) {
String[] gaps = toTrimmedTokens(part.substring(ix).trim(), ' ');
cc.getHorizontal().setAlign(parseUnitValueOrAlign(gaps[0], true, null));
if (gaps.length > 1)
cc.getVertical().setAlign(parseUnitValueOrAlign(gaps[1], false, null));
continue;
}
}
if ((c == 'x' || c == 'y') && part.length() > 2) {
char c2 = part.charAt(1);
if (c2 == ' ' || (c2 == '2' && part.charAt(2) == ' ')) {
if (cc.getPos() == null) {
cc.setPos(new UnitValue[4]);
} else if (cc.isBoundsInGrid() == false) {
throw new IllegalArgumentException("Cannot combine 'position' with 'x/y/x2/y2' keywords.");
}
int edge = (c == 'x' ? 0 : 1) + (c2 == '2' ? 2 : 0);
UnitValue[] pos = cc.getPos();
pos[edge] = parseUnitValue(part.substring(2).trim(), null, c == 'x');
cc.setPos(pos);
cc.setBoundsInGrid(true);
continue;
}
}
if (c == 'c') {
ix = startsWithLenient(part, "cell", 4, true);
if (ix > -1) {
String[] grs = toTrimmedTokens(part.substring(ix).trim(), ' ');
if (grs.length < 2)
throw new IllegalArgumentException("At least two integers must follow " + part);
cc.setCellX(Integer.parseInt(grs[0]));
cc.setCellY(Integer.parseInt(grs[1]));
if (grs.length > 2)
cc.setSpanX(Integer.parseInt(grs[2]));
if (grs.length > 3)
cc.setSpanY(Integer.parseInt(grs[3]));
continue;
}
}
if (c == 'p') {
ix = startsWithLenient(part, "pos", 3, true);
if (ix > -1) {
if (cc.getPos() != null && cc.isBoundsInGrid())
throw new IllegalArgumentException("Can not combine 'pos' with 'x/y/x2/y2' keywords.");
String[] pos = toTrimmedTokens(part.substring(ix).trim(), ' ');
UnitValue[] bounds = new UnitValue[4];
for (int j = 0; j < pos.length; j++)
bounds[j] = parseUnitValue(pos[j], null, j % 2 == 0);
if (bounds[0] == null && bounds[2] == null || bounds[1] == null && bounds[3] == null)
throw new IllegalArgumentException("Both x and x2 or y and y2 can not be null!");
cc.setPos(bounds);
cc.setBoundsInGrid(false);
continue;
}
ix = startsWithLenient(part, "pad", 3, true);
if (ix > -1) {
UnitValue[] p = parseInsets(part.substring(ix).trim(), false);
cc.setPadding(new UnitValue[]{
p[0],
p.length > 1 ? p[1] : null,
p.length > 2 ? p[2] : null,
p.length > 3 ? p[3] : null});
continue;
}
ix = startsWithLenient(part, "pushx", 5, true);
if (ix > -1) {
cc.setPushX(parseFloat(part.substring(ix).trim(), ResizeConstraint.WEIGHT_100));
continue;
}
ix = startsWithLenient(part, "pushy", 5, true);
if (ix > -1) {
cc.setPushY(parseFloat(part.substring(ix).trim(), ResizeConstraint.WEIGHT_100));
continue;
}
ix = startsWithLenient(part, "push", 4, false);
if (ix > -1) {
String[] pushs = toTrimmedTokens(part.substring(ix).trim(), ' ');
cc.setPushX(parseFloat(pushs[0], ResizeConstraint.WEIGHT_100));
cc.setPushY(parseFloat(pushs.length > 1 ? pushs[1] : "", ResizeConstraint.WEIGHT_100));
continue;
}
}
if (c == 't') {
ix = startsWithLenient(part, "tag", 3, true);
if (ix > -1) {
cc.setTag(part.substring(ix).trim());
continue;
}
}
if (c == 'w' || c == 'h') {
if (part.equals("wrap")) {
cc.setWrap(true);
continue;
}
if (part.startsWith("wrap ")) {
String gapSz = part.substring(5).trim();
cc.setWrapGapSize(parseBoundSize(gapSz, true, true));
continue;
}
boolean isHor = c == 'w';
if (isHor && (part.startsWith("w ") || part.startsWith("width "))) {
String uvStr = part.substring(part.charAt(1) == ' ' ? 2 : 6).trim();
cc.getHorizontal().setSize(parseBoundSize(uvStr, false, true));
continue;
}
if (!isHor && (part.startsWith("h ") || part.startsWith("height "))) {
String uvStr = part.substring(part.charAt(1) == ' ' ? 2 : 7).trim();
cc.getVertical().setSize(parseBoundSize(uvStr, false, false));
continue;
}
if (part.startsWith("wmin ") || part.startsWith("wmax ") || part.startsWith("hmin ") || part.startsWith("hmax ")) {
String uvStr = part.substring(5).trim();
if (uvStr.length() > 0) {
UnitValue uv = parseUnitValue(uvStr, null, isHor);
boolean isMin = part.charAt(3) == 'n';
DimConstraint dc = isHor ? cc.getHorizontal() : cc.getVertical();
dc.setSize(new BoundSize(
isMin ? uv : dc.getSize().getMin(),
dc.getSize().getPreferred(),
isMin ? (dc.getSize().getMax()) : uv,
uvStr
));
continue;
}
}
if (part.equals("west")) {
cc.setDockSide(1);
continue;
}
if (part.startsWith("hidemode ")) {
cc.setHideMode(Integer.parseInt(part.substring(9)));
continue;
}
}
if (c == 'i' && part.startsWith("id ")) {
cc.setId(part.substring(3).trim());
int dIx = cc.getId().indexOf('.');
if (dIx == 0 || dIx == cc.getId().length() - 1)
throw new IllegalArgumentException("Dot must not be first or last!");
continue;
}
if (c == 'e') {
if (part.equals("east")) {
cc.setDockSide(3);
continue;
}
if (part.equals("external")) {
cc.setExternal(true);
continue;
}
ix = startsWithLenient(part, new String[]{"endgroupx", "endgroupy", "egx", "egy"}, new int[]{-1, -1, -1, -1}, true);
if (ix > -1) {
String sg = part.substring(ix).trim();
char lc = part.charAt(ix - 1);
DimConstraint dc = (lc == 'x' ? cc.getHorizontal() : cc.getVertical());
dc.setEndGroup(sg);
continue;
}
}
if (c == 'd') {
if (part.equals("dock north")) {
cc.setDockSide(0);
continue;
}
if (part.equals("dock west")) {
cc.setDockSide(1);
continue;
}
if (part.equals("dock south")) {
cc.setDockSide(2);
continue;
}
if (part.equals("dock east")) {
cc.setDockSide(3);
continue;
}
if (part.equals("dock center")) {
cc.getHorizontal().setGrow(100f);
cc.getVertical().setGrow(100f);
cc.setPushX(100f);
cc.setPushY(100f);
continue;
}
}
if (c == 'v') {
ix = startsWithLenient(part, new String[] {"visualpadding", "vp"}, new int[] {3, 2}, true);
if (ix > -1) {
UnitValue[] p = parseInsets(part.substring(ix).trim(), false);
cc.setVisualPadding(new UnitValue[] {
p[0],
p.length > 1 ? p[1] : null,
p.length > 2 ? p[2] : null,
p.length > 3 ? p[3] : null});
continue;
}
}
UnitValue horAlign = parseAlignKeywords(part, true);
if (horAlign != null) {
cc.getHorizontal().setAlign(horAlign);
continue;
}
UnitValue verAlign = parseAlignKeywords(part, false);
if (verAlign != null) {
cc.getVertical().setAlign(verAlign);
continue;
}
throw new IllegalArgumentException("Unknown keyword.");
} catch (Exception ex) {
throw new IllegalArgumentException("Error parsing Constraint: '" + part + "'", ex);
}
}
// cc = (CC) serializeTest(cc);
return cc;
}
/** Parses insets which consists of 1-4 UnitValue
s.
* @param s The string to parse. E.g. "10 10 10 10" or "20". If less than 4 groups the last will be used for the missing.
* @param acceptPanel If "panel" and "dialog" should be accepted. They are used to access platform defaults.
* @return An array of length 4 with the parsed insets.
* @throws IllegalArgumentException if the parsing could not be done.
*/
public static UnitValue[] parseInsets(String s, boolean acceptPanel)
{
if (s.length() == 0 || s.equals("dialog") || s.equals("panel")) {
if (acceptPanel == false)
throw new IllegalArgumentException("Insets now allowed: " + s + "\n");
boolean isPanel = s.startsWith("p");
UnitValue[] ins = new UnitValue[4];
for (int j = 0; j < 4; j++)
ins[j] = isPanel ? PlatformDefaults.getPanelInsets(j) : PlatformDefaults.getDialogInsets(j);
return ins;
} else {
String[] insS = toTrimmedTokens(s, ' ');
UnitValue[] ins = new UnitValue[4];
for (int j = 0; j < 4; j++) {
UnitValue insSz = parseUnitValue(insS[j < insS.length ? j : insS.length - 1], UnitValue.ZERO, j % 2 == 1);
ins[j] = insSz != null ? insSz : PlatformDefaults.getPanelInsets(j);
}
return ins;
}
}
/** Parses gaps.
* @param s The string that contains gap information. Should start with "gap".
* @return The gaps as specified in s
. Indexed: [top,left,bottom,right][min,pref,max]
or
* [before,after][min,pref,max] if oneDim
is true.
*/
private static BoundSize[] parseGaps(String s)
{
BoundSize[] ret = new BoundSize[4];
int ix = startsWithLenient(s, "gaptop", -1, true);
if (ix > -1) {
s = s.substring(ix).trim();
ret[0] = parseBoundSize(s, true, false);
return ret;
}
ix = startsWithLenient(s, "gapleft", -1, true);
if (ix > -1) {
s = s.substring(ix).trim();
ret[1] = parseBoundSize(s, true, true);
return ret;
}
ix = startsWithLenient(s, "gapbottom", -1, true);
if (ix > -1) {
s = s.substring(ix).trim();
ret[2] = parseBoundSize(s, true, false);
return ret;
}
ix = startsWithLenient(s, "gapright", -1, true);
if (ix > -1) {
s = s.substring(ix).trim();
ret[3] = parseBoundSize(s, true, true);
return ret;
}
ix = startsWithLenient(s, "gapbefore", -1, true);
if (ix > -1) {
s = s.substring(ix).trim();
ret[1] = parseBoundSize(s, true, true);
return ret;
}
ix = startsWithLenient(s, "gapafter", -1, true);
if (ix > -1) {
s = s.substring(ix).trim();
ret[3] = parseBoundSize(s, true, true);
return ret;
}
ix = startsWithLenient(s, new String[] {"gapx", "gapy"}, null, true);
if (ix > -1) {
boolean x = s.charAt(3) == 'x';
String[] gaps = toTrimmedTokens(s.substring(ix).trim(), ' ');
ret[x ? 1 : 0] = parseBoundSize(gaps[0], true, x);
if (gaps.length > 1)
ret[x ? 3 : 2] = parseBoundSize(gaps[1], true, !x);
return ret;
}
ix = startsWithLenient(s, "gap ", 1, true);
if (ix > -1) {
String[] gaps = toTrimmedTokens(s.substring(ix).trim(), ' ');
ret[1] = parseBoundSize(gaps[0], true, true); // left
if (gaps.length > 1) {
ret[3] = parseBoundSize(gaps[1], true, false); // right
if (gaps.length > 2) {
ret[0] = parseBoundSize(gaps[2], true, true); // top
if (gaps.length > 3)
ret[2] = parseBoundSize(gaps[3], true, false); // bottom
}
}
return ret;
}
throw new IllegalArgumentException("Unknown Gap part: '" + s + "'");
}
private static int parseSpan(String s)
{
return s.length() > 0 ? Integer.parseInt(s) : LayoutUtil.INF;
}
private static Float parseFloat(String s, Float nullVal)
{
return s.length() > 0 ? new Float(Float.parseFloat(s)) : nullVal;
}
/** Parses a single "min:pref:max" value. May look something like "10px:20lp:30%"
or "pref!"
.
* @param s The string to parse. Not null
.
* @param isGap If this bound size is a gap (different empty string handling).
* @param isHor If the size is for the horizontal dimension.
* @return A bound size that may be null
if the string was "null", "n" or null
.
*/
public static BoundSize parseBoundSize(String s, boolean isGap, boolean isHor)
{
if (s.length() == 0 || s.equals("null") || s.equals("n"))
return null;
String cs = s;
boolean push = false;
if (s.endsWith("push")) {
push = true;
int l = s.length();
s = s.substring(0, l - (s.endsWith(":push") ? 5 : 4));
if (s.length() == 0)
return new BoundSize(null, null, null, true, cs);
}
String[] sizes = toTrimmedTokens(s, ':');
String s0 = sizes[0];
if (sizes.length == 1) {
boolean hasEM = s0.endsWith("!");
if (hasEM)
s0 = s0.substring(0, s0.length() - 1);
UnitValue uv = parseUnitValue(s0, null, isHor);
return new BoundSize(((isGap || hasEM) ? uv : null), uv, (hasEM ? uv : null), push, cs);
} else if (sizes.length == 2) {
return new BoundSize(parseUnitValue(s0, null, isHor), parseUnitValue(sizes[1], null, isHor), null, push, cs);
} else if (sizes.length == 3) {
return new BoundSize(parseUnitValue(s0, null, isHor), parseUnitValue(sizes[1], null, isHor), parseUnitValue(sizes[2], null, isHor), push, cs);
} else {
throw new IllegalArgumentException("Min:Preferred:Max size section must contain 0, 1 or 2 colons. '" + cs + "'");
}
}
/** Parses a single unit value that may also be an alignment as parsed by {@link #parseAlignKeywords(String, boolean)}.
* @param s The string to parse. Not null
. May look something like "10px"
or "5dlu"
.
* @param isHor If the value is for the horizontal dimension.
* @param emptyReplacement A replacement if s
is empty. May be null
.
* @return The parsed unit value. May be null
.
*/
public static UnitValue parseUnitValueOrAlign(String s, boolean isHor, UnitValue emptyReplacement)
{
if (s.length() == 0)
return emptyReplacement;
UnitValue align = parseAlignKeywords(s, isHor);
if (align != null)
return align;
return parseUnitValue(s, emptyReplacement, isHor);
}
/** Parses a single unit value. E.g. "10px" or "5in"
* @param s The string to parse. Not null
. May look something like "10px"
or "5dlu"
.
* @param isHor If the value is for the horizontal dimension.
* @return The parsed unit value. null
is empty string,
*/
public static UnitValue parseUnitValue(String s, boolean isHor)
{
return parseUnitValue(s, null, isHor);
}
/** Parses a single unit value.
* @param s The string to parse. May be null
. May look something like "10px"
or "5dlu"
.
* @param emptyReplacement A replacement s
is empty or null
. May be null
.
* @param isHor If the value is for the horizontal dimension.
* @return The parsed unit value. May be null
.
*/
private static UnitValue parseUnitValue(String s, UnitValue emptyReplacement, boolean isHor)
{
if (s == null || s.length() == 0)
return emptyReplacement;
String cs = s; // Save creation string.
char c0 = s.charAt(0);
// Remove start and end parentheses, if there.
if (c0 == '(' && s.charAt(s.length() - 1) == ')')
s = s.substring(1, s.length() - 1);
if (c0 == 'n' && (s.equals("null") || s.equals("n")))
return null;
if (c0 == 'i' && s.equals("inf"))
return UnitValue.INF;
int oper = getOper(s);
boolean inline = oper == UnitValue.ADD || oper == UnitValue.SUB || oper == UnitValue.MUL || oper == UnitValue.DIV;
if (oper != UnitValue.STATIC) { // It is a multi-value
String[] uvs;
if (inline == false) { // If the format is of type "opr(xxx,yyy)" (compared to in-line "10%+15px")
String sub = s.substring(4, s.length() - 1).trim();
uvs = toTrimmedTokens(sub, ',');
if (uvs.length == 1)
return parseUnitValue(sub, null, isHor);
} else {
char delim;
if (oper == UnitValue.ADD) {
delim = '+';
} else if (oper == UnitValue.SUB) {
delim = '-';
} else if (oper == UnitValue.MUL) {
delim = '*';
} else { // div left
delim = '/';
}
uvs = toTrimmedTokens(s, delim);
if (uvs.length > 2) { // More than one +-*/.
String last = uvs[uvs.length - 1];
String first = s.substring(0, s.length() - last.length() - 1);
uvs = new String[] {first, last};
}
}
if (uvs.length != 2)
throw new IllegalArgumentException("Malformed UnitValue: '" + s + "'");
UnitValue sub1 = parseUnitValue(uvs[0], null, isHor);
UnitValue sub2 = parseUnitValue(uvs[1], null, isHor);
if (sub1 == null || sub2 == null)
throw new IllegalArgumentException("Malformed UnitValue. Must be two sub-values: '" + s + "'");
return new UnitValue(isHor, oper, sub1, sub2, cs);
} else {
try {
String[] numParts = getNumTextParts(s);
float value = numParts[0].length() > 0 ? Float.parseFloat(numParts[0]) : 1; // e.g. "related" has no number part..
return new UnitValue(value, numParts[1], isHor, oper, cs);
} catch(Exception e) {
throw new IllegalArgumentException("Malformed UnitValue: '" + s + "'", e);
}
}
}
/** Parses alignment keywords and returns the appropriate UnitValue
.
* @param s The string to parse. Not null
.
* @param isHor If alignments for horizontal is checked. false
means vertical.
* @return The unit value or null
if not recognized (no exception).
*/
static UnitValue parseAlignKeywords(String s, boolean isHor)
{
if (startsWithLenient(s, "center", 1, false) != -1)
return UnitValue.CENTER;
if (isHor) {
if (startsWithLenient(s, "left", 1, false) != -1)
return UnitValue.LEFT;
if (startsWithLenient(s, "right", 1, false) != -1)
return UnitValue.RIGHT;
if (startsWithLenient(s, "leading", 4, false) != -1)
return UnitValue.LEADING;
if (startsWithLenient(s, "trailing", 5, false) != -1)
return UnitValue.TRAILING;
if (startsWithLenient(s, "label", 5, false) != -1)
return UnitValue.LABEL;
} else {
if (startsWithLenient(s, "baseline", 4, false) != -1)
return UnitValue.BASELINE_IDENTITY;
if (startsWithLenient(s, "top", 1, false) != -1)
return UnitValue.TOP;
if (startsWithLenient(s, "bottom", 1, false) != -1)
return UnitValue.BOTTOM;
}
return null;
}
/** Splits a text-number combination such as "hello 10.0" into {"hello", "10.0"}
.
* @param s The string to split. Not null
. Needs be be reasonably formatted since the method
* only finds the first 0-9 or . and cuts the string in half there.
* @return Always length 2 and no null
elements. Elements are "" if no part found.
*/
private static String[] getNumTextParts(String s)
{
for (int i = 0, iSz = s.length(); i < iSz; i++) {
char c = s.charAt(i);
if (c == ' ')
throw new IllegalArgumentException("Space in UnitValue: '" + s + "'");
if ((c < '0' || c > '9') && c != '.' && c != '-')
return new String[] {s.substring(0, i).trim(), s.substring(i).trim()};
}
return new String[] {s, ""};
}
/** Returns the operation depending on the start character.
* @param s The string to check. Not null
.
* @return E.g. UnitValue.ADD, UnitValue.SUB or UnitValue.STATIC. Returns negative value for in-line operations.
*/
private static int getOper(String s)
{
int len = s.length();
if (len < 3)
return UnitValue.STATIC;
if (len > 5 && s.charAt(3) == '(' && s.charAt(len - 1) == ')') {
if (s.startsWith("min("))
return UnitValue.MIN;
if (s.startsWith("max("))
return UnitValue.MAX;
if (s.startsWith("mid("))
return UnitValue.MID;
}
// Try in-line add/sub. E.g. "pref+10px".
for (int j = 0; j < 2; j++) { // First +- then */ (precedence)
for (int i = len - 1, p = 0; i > 0; i--) {
char c = s.charAt(i);
if (c == ')') {
p++;
} else if (c == '(') {
p--;
} else if (p == 0) {
if (j == 0) {
if (c == '+')
return UnitValue.ADD;
if (c == '-')
return UnitValue.SUB;
} else {
if (c == '*')
return UnitValue.MUL;
if (c == '/')
return UnitValue.DIV;
}
}
}
}
return UnitValue.STATIC;
}
/** Returns if a string shares at least a specified numbers starting characters with a number of matches.
*
* This method just exercise {@link #startsWithLenient(String, String, int, boolean)} with every one of
* matches
and minChars
.
* @param s The string to check. Not null
.
* @param matches A number of possible starts for s
.
* @param minChars The minimum number of characters to match for every element in matches
. Needs
* to be of same length as matches
. Can be null
.
* @param acceptTrailing If after the required number of characters are matched on recognized characters that are not
* in one of the the matches
string should be accepted. For instance if "abczz" should be matched with
* "abcdef" and min chars 3.
* @return The index of the first unmatched character if minChars
was reached or -1
if a match was not
* found.
*/
private static int startsWithLenient(String s, String[] matches, int[] minChars, boolean acceptTrailing)
{
for (int i = 0; i < matches.length; i++) {
int minChar = minChars != null ? minChars[i] : -1;
int ix = startsWithLenient(s, matches[i], minChar, acceptTrailing);
if (ix > -1)
return ix;
}
return -1;
}
/** Returns if a string shares at least a specified numbers starting characters with a match.
* @param s The string to check. Not null
and must be trimmed.
* @param match The possible start for s
. Not null
and must be trimmed.
* @param minChars The mimimum number of characters to match to s
for it this to be considered a match. -1 means
* the full length of match
.
* @param acceptTrailing If after the required number of charecters are matched unrecognized characters that are not
* in one of the the matches
string should be accepted. For instance if "abczz" should be matched with
* "abcdef" and min chars 3.
* @return The index of the first unmatched character if minChars
was reached or -1
if a match was not
* found.
*/
private static int startsWithLenient(String s, String match, int minChars, boolean acceptTrailing)
{
if (s.charAt(0) != match.charAt(0)) // Fast sanity check.
return -1;
if (minChars == -1)
minChars = match.length();
int sSz = s.length();
if (sSz < minChars)
return -1;
int mSz = match.length();
int sIx = 0;
for (int mIx = 0; mIx < mSz; sIx++, mIx++) {
while (sIx < sSz && (s.charAt(sIx) == ' ' || s.charAt(sIx) == '_')) // Disregard spaces and _
sIx++;
if (sIx >= sSz || s.charAt(sIx) != match.charAt(mIx))
return mIx >= minChars && (acceptTrailing || sIx >= sSz) && (sIx >= sSz || s.charAt(sIx - 1) == ' ') ? sIx : -1;
}
return sIx >= sSz || acceptTrailing ||s.charAt(sIx) == ' ' ? sIx : -1;
}
/** Parses a string and returns it in those parts of the string that are separated with a sep
character.
*
* separator characters within parentheses will not be counted or handled in any way, whatever the depth.
*
* A space separator will be a hit to one or more spaces and thus not return empty strings.
* @param s The string to parse. If it starts and/or ends with a sep
the first and/or last element returned will be "". If
* two sep
are next to each other and empty element will be "between" the periods. The sep
themselves will never be returned.
* @param sep The separator char.
* @return Those parts of the string that are separated with sep
. Never null and at least of size 1
* @since 6.7.2 Changed so more than one space in a row works as one space.
*/
private static String[] toTrimmedTokens(String s, char sep)
{
int toks = 0, sSize = s.length();
boolean disregardDoubles = sep == ' ';
// Count the sep:s
int p = 0;
for(int i = 0; i < sSize; i++) {
char c = s.charAt(i);
if (c == '(') {
p++;
} else if (c == ')') {
p--;
} else if (p == 0 && c == sep) {
toks++;
while (disregardDoubles && i < sSize - 1 && s.charAt(i + 1) == ' ')
i++;
}
if (p < 0)
throw new IllegalArgumentException("Unbalanced parentheses: '" + s + "'");
}
if (p != 0)
throw new IllegalArgumentException("Unbalanced parentheses: '" + s + "'");
if (toks == 0)
return new String [] {s.trim()};
String[] retArr = new String[toks + 1];
int st = 0, pNr = 0;
p = 0;
for (int i = 0; i < sSize; i++) {
char c = s.charAt(i);
if (c == '(') {
p++;
} else if (c == ')') {
p--;
} else if (p == 0 && c == sep) {
retArr[pNr++] = s.substring(st, i).trim();
st = i + 1;
while (disregardDoubles && i < sSize - 1 && s.charAt(i + 1) == ' ')
i++;
}
}
retArr[pNr++] = s.substring(st, sSize).trim();
return retArr;
}
/** Parses "AAA[BBB]CCC[DDD]EEE" into {"AAA", "BBB", "CCC", "DDD", "EEE", "FFF"}. Handles empty parts. Will always start and end outside
* a [] block so that the number of returned elemets will always be uneven and at least of length 3.
*
* "|" is interpreted as "][".
* @param s The string. Might be "" but not null. Should be trimmed.
* @return The string divided into elements. Never null
and at least of length 3.
* @throws IllegalArgumentException If a [] mismatch of some kind. (If not same [ as ] count or if the interleave.)
*/
private static ArrayList getRowColAndGapsTrimmed(String s)
{
if (s.indexOf('|') != -1)
s = s.replaceAll("\\|", "][");
ArrayList retList = new ArrayList(Math.max(s.length() >> 2 + 1, 3)); // Approx return length.
int s0 = 0, s1 = 0; // '[' and ']' count.
int st = 0; // Start of "next token to add".
for (int i = 0, iSz = s.length(); i < iSz; i++) {
char c = s.charAt(i);
if (c == '[') {
s0++;
} else if (c == ']') {
s1++;
} else {
continue;
}
if (s0 != s1 && (s0 - 1) != s1)
break; // Wrong [ or ] found. Break for throw.
retList.add(s.substring(st, i).trim());
st = i + 1;
}
if (s0 != s1)
throw new IllegalArgumentException("'[' and ']' mismatch in row/column format string: " + s);
if (s0 == 0) {
retList.add("");
retList.add(s);
retList.add("");
} else if (retList.size() % 2 == 0) {
retList.add(s.substring(st, s.length()));
}
return retList;
}
/** Makes null
"", trims and converts to lower case.
* @param s The string
* @return Not null.
*/
public static String prepare(String s)
{
return s != null ? s.trim().toLowerCase() : "";
}
// /** Tests to serialize and deserialize the object with both XMLEncoder/Decoder and through Serializable
// * @param o The object to serialize
// * @return The same object after a tri through the process.
// */
// public static final Object serializeTest(Object o)
// {
// try {
// ByteArrayOutputStream barr = new ByteArrayOutputStream();
// XMLEncoder enc = new XMLEncoder(barr);
// enc.writeObject(o);
// enc.close();
//
// XMLDecoder dec = new XMLDecoder(new ByteArrayInputStream(barr.toByteArray()));
// o = dec.readObject();
// dec.close();
// } catch (Exception e) {
// e.printStackTrace();
// }
//
// try {
// ByteArrayOutputStream barr = new ByteArrayOutputStream();
// ObjectOutputStream oos = new ObjectOutputStream(barr);
// oos.writeObject(o);
// oos.close();
//
// ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(barr.toByteArray()));
// o = ois.readObject();
// ois.close();
// } catch (Exception e) {
// e.printStackTrace();
// }
//
// return o;
// }
}
miglayout-5.1/core/src/main/java/net/miginfocom/layout/ContainerWrapper.java000077500000000000000000000061761324101563200273470ustar00rootroot00000000000000package net.miginfocom.layout;
/*
* License (BSD):
* ==============
*
* Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
* 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 the MiG InfoCom AB nor 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.
*
* @version 1.0
* @author Mikael Grev, MiG InfoCom AB
* Date: 2006-sep-08
*/
/** A class that wraps a container that contains components.
*/
public interface ContainerWrapper extends ComponentWrapper
{
/** Returns the components of the container that wrapper is wrapping.
* @return The components of the container that wrapper is wrapping. Never null
.
*/
public abstract ComponentWrapper[] getComponents();
/** Returns the number of components that this parent has.
* @return The number of components that this parent has.
*/
public abstract int getComponentCount();
/** Returns the LayoutHandler
(in Swing terms) that is handling the layout of this container.
* If there exist no such class the method should return the same as {@link #getComponent()}, which is the
* container itself.
* @return The layout handler instance. Never null
.
*/
public abstract Object getLayout();
/** Returns if this container is using left-to-right component ordering.
* @return If this container is using left-to-right component ordering.
*/
public abstract boolean isLeftToRight();
/** Paints a cell to indicate where it is.
* @param x The x coordinate to start the drawing.
* @param y The x coordinate to start the drawing.
* @param width The width to draw/fill
* @param height The height to draw/fill
*/
public abstract void paintDebugCell(int x, int y, int width, int height);
}
miglayout-5.1/core/src/main/java/net/miginfocom/layout/DimConstraint.java000077500000000000000000000467371324101563200266510ustar00rootroot00000000000000package net.miginfocom.layout;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.ObjectStreamException;
/*
* License (BSD):
* ==============
*
* Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
* 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 the MiG InfoCom AB nor 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.
*
* @version 1.0
* @author Mikael Grev, MiG InfoCom AB
* Date: 2006-sep-08
*/
/** A simple value holder for a constraint for one dimension.
*/
public final class DimConstraint implements Externalizable
{
/** How this entity can be resized in the dimension that this constraint represents.
*/
final ResizeConstraint resize = new ResizeConstraint();
// Look at the properties' getter/setter methods for explanation
private String sizeGroup = null; // A "context" compared with equals.
private BoundSize size = BoundSize.NULL_SIZE; // Min, pref, max. Never null, but sizes can be null.
private BoundSize gapBefore = null, gapAfter = null;
private UnitValue align = null;
// ************** Only applicable on components! *******************
private String endGroup = null; // A "context" compared with equals.
// ************** Only applicable on rows/columns! *******************
private boolean fill = false;
private boolean noGrid = false;
/** Empty constructor.
*/
public DimConstraint()
{
}
/** Returns the grow priority. Relative priority is used for determining which entities gets the extra space first.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return The grow priority.
*/
public int getGrowPriority()
{
return resize.growPrio;
}
/** Sets the grow priority. Relative priority is used for determining which entities gets the extra space first.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param p The new grow priority.
*/
public void setGrowPriority(int p)
{
resize.growPrio = p;
}
/** Returns the grow weight.
* Grow weight is how flexible the entity should be, relative to other entities, when it comes to growing. null
or
* zero mean it will never grow. An entity that has twice the grow weight compared to another entity will get twice
* as much of available space.
*
* GrowWeight are only compared within the same GrowPrio.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return The current grow weight.
*/
public Float getGrow()
{
return resize.grow;
}
/** Sets the grow weight.
* Grow weight is how flexible the entity should be, relative to other entities, when it comes to growing. null
or
* zero mean it will never grow. An entity that has twice the grow weight compared to another entity will get twice
* as much of available space.
*
* GrowWeight are only compared within the same GrowPrio.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param weight The new grow weight.
*/
public void setGrow(Float weight)
{
resize.grow = weight;
}
/** Returns the shrink priority. Relative priority is used for determining which entities gets smaller first when space is scarce.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return The shrink priority.
*/
public int getShrinkPriority()
{
return resize.shrinkPrio;
}
/** Sets the shrink priority. Relative priority is used for determining which entities gets smaller first when space is scarce.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param p The new shrink priority.
*/
public void setShrinkPriority(int p)
{
resize.shrinkPrio = p;
}
/** Returns the shrink priority. Relative priority is used for determining which entities gets smaller first when space is scarce.
* Shrink weight is how flexible the entity should be, relative to other entities, when it comes to shrinking. null
or
* zero mean it will never shrink (default). An entity that has twice the shrink weight compared to another entity will get twice
* as much of available space.
*
* Shrink(Weight) are only compared within the same ShrinkPrio.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return The current shrink weight.
*/
public Float getShrink()
{
return resize.shrink;
}
/** Sets the shrink priority. Relative priority is used for determining which entities gets smaller first when space is scarce.
* Shrink weight is how flexible the entity should be, relative to other entities, when it comes to shrinking. null
or
* zero mean it will never shrink (default). An entity that has twice the shrink weight compared to another entity will get twice
* as much of available space.
*
* Shrink(Weight) are only compared within the same ShrinkPrio.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param weight The new shrink weight.
*/
public void setShrink(Float weight)
{
resize.shrink = weight;
}
public UnitValue getAlignOrDefault(boolean isCols)
{
if (align != null)
return align;
if (isCols)
return UnitValue.LEADING;
return fill || PlatformDefaults.getDefaultRowAlignmentBaseline() == false ? UnitValue.CENTER : UnitValue.BASELINE_IDENTITY;
}
/** Returns the alignment used either as a default value for sub-entities or for this entity.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return The alignment.
*/
public UnitValue getAlign()
{
return align;
}
/** Sets the alignment used wither as a default value for sub-entities or for this entity.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param uv The new shrink priority. E.g. {@link UnitValue#CENTER} or {@link net.miginfocom.layout.UnitValue#LEADING}.
*/
public void setAlign(UnitValue uv)
{
this.align = uv;
}
/** Returns the gap after this entity. The gap is an empty space and can have a min/preferred/maximum size so that it can shrink and
* grow depending on available space. Gaps are against other entities' edges and not against other entities' gaps.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return The gap after this entity
*/
public BoundSize getGapAfter()
{
return gapAfter;
}
/** Sets the gap after this entity. The gap is an empty space and can have a min/preferred/maximum size so that it can shrink and
* grow depending on available space. Gaps are against other entities' edges and not against other entities' gaps.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param size The new gap.
* @see net.miginfocom.layout.ConstraintParser#parseBoundSize(String, boolean, boolean)
*/
public void setGapAfter(BoundSize size)
{
this.gapAfter = size;
}
boolean hasGapAfter()
{
return gapAfter != null && gapAfter.isUnset() == false;
}
boolean isGapAfterPush()
{
return gapAfter != null && gapAfter.getGapPush();
}
/** Returns the gap before this entity. The gap is an empty space and can have a min/preferred/maximum size so that it can shrink and
* grow depending on available space. Gaps are against other entities' edges and not against other entities' gaps.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return The gap before this entity
*/
public BoundSize getGapBefore()
{
return gapBefore;
}
/** Sets the gap before this entity. The gap is an empty space and can have a min/preferred/maximum size so that it can shrink and
* grow depending on available space. Gaps are against other entities' edges and not against other entities' gaps.
*
* See also {@link net.miginfocom.layout.ConstraintParser#parseBoundSize(String, boolean, boolean)}.
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param size The new gap.
*/
public void setGapBefore(BoundSize size)
{
this.gapBefore = size;
}
boolean hasGapBefore()
{
return gapBefore != null && gapBefore.isUnset() == false;
}
boolean isGapBeforePush()
{
return gapBefore != null && gapBefore.getGapPush();
}
/** Returns the min/preferred/max size for the entity in the dimension that this object describes.
*
* See also {@link net.miginfocom.layout.ConstraintParser#parseBoundSize(String, boolean, boolean)}.
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return The current size. Never null
since v3.5.
*/
public BoundSize getSize()
{
return size;
}
/** Sets the min/preferred/max size for the entity in the dimension that this object describes.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param size The new size. May be null
.
*/
public void setSize(BoundSize size)
{
if (size != null)
size.checkNotLinked();
this.size = size;
}
/** Returns the size group that this entity should be in for the dimension that this object is describing.
* If this constraint is in a size group that is specified here. null
means no size group
* and all other values are legal. Comparison with .equals(). Components/columns/rows in the same size group
* will have the same min/preferred/max size; that of the largest in the group for the first two and the
* smallest for max.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return The current size group. May be null
.
*/
public String getSizeGroup()
{
return sizeGroup;
}
/** Sets the size group that this entity should be in for the dimension that this object is describing.
* If this constraint is in a size group that is specified here. null
means no size group
* and all other values are legal. Comparison with .equals(). Components/columns/rows in the same size group
* will have the same min/preferred/max size; that of the largest in the group for the first two and the
* smallest for max.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param s The new size group. null
disables size grouping.
*/
public void setSizeGroup(String s)
{
sizeGroup = s;
}
// ************** Only applicable on components ! *******************
/** Returns the end group that this entity should be in for the dimension that this object is describing.
* If this constraint is in an end group that is specified here. null
means no end group
* and all other values are legal. Comparison with .equals(). Components in the same end group
* will have the same end coordinate.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return The current end group. null
may be returned.
*/
public String getEndGroup()
{
return endGroup;
}
/** Sets the end group that this entity should be in for the dimension that this object is describing.
* If this constraint is in an end group that is specified here. null
means no end group
* and all other values are legal. Comparison with .equals(). Components in the same end group
* will have the same end coordinate.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param s The new end group. null
disables end grouping.
*/
public void setEndGroup(String s)
{
endGroup = s;
}
// ************** Not applicable on components below ! *******************
/** Returns if the component in the row/column that this constraint should default be grown in the same dimension that
* this constraint represents (width for column and height for a row).
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return true
means that components should grow.
*/
public boolean isFill()
{
return fill;
}
/** Sets if the component in the row/column that this constraint should default be grown in the same dimension that
* this constraint represents (width for column and height for a row).
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param b true
means that components should grow.
*/
public void setFill(boolean b)
{
fill = b;
}
/** Returns if the row/column should default to flow and not to grid behaviour. This means that the whole row/column
* will be one cell and all components will end up in that cell.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return true
means that the whole row/column should be one cell.
*/
public boolean isNoGrid()
{
return noGrid;
}
/** Sets if the row/column should default to flow and not to grid behaviour. This means that the whole row/column
* will be one cell and all components will end up in that cell.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param b true
means that the whole row/column should be one cell.
*/
public void setNoGrid(boolean b)
{
this.noGrid = b;
}
/** Returns the gaps as pixel values.
* @param parent The parent. Used to get the pixel values.
* @param defGap The default gap to use if there is no gap set on this object (i.e. it is null).
* @param refSize The reference size used to get the pixel sizes.
* @param before IF it is the gap before rather than the gap after to return.
* @return The [min,preferred,max] sizes for the specified gap. Uses {@link net.miginfocom.layout.LayoutUtil#NOT_SET}
* for gap sizes that are null
. Returns null
if there was no gap specified. A new and free to use array.
*/
int[] getRowGaps(ContainerWrapper parent, BoundSize defGap, int refSize, boolean before)
{
BoundSize gap = before ? gapBefore : gapAfter;
if (gap == null || gap.isUnset())
gap = defGap;
if (gap == null || gap.isUnset())
return null;
int[] ret = new int[3];
for (int i = LayoutUtil.MIN; i <= LayoutUtil.MAX; i++) {
UnitValue uv = gap.getSize(i);
ret[i] = uv != null ? uv.getPixels(refSize, parent, null) : LayoutUtil.NOT_SET;
}
return ret;
}
/** Returns the gaps as pixel values.
* @param parent The parent. Used to get the pixel values.
* @param comp The component that the gap is for. If not for a component it is null
.
* @param adjGap The gap that the adjacent component, if any, has towards comp
.
* @param adjacentComp The adjacent component if any. May be null
.
* @param refSize The reference size used to get the pixel sizes.
* @param adjacentSide What side the adjacentComp
is on. 0 = top, 1 = left, 2 = bottom, 3 = right.
* @param tag The tag string that the component might be tagged with in the component constraints. May be null
.
* @param isLTR If it is left-to-right.
* @return The [min,preferred,max] sizes for the specified gap. Uses {@link net.miginfocom.layout.LayoutUtil#NOT_SET}
* for gap sizes that are null
. Returns null
if there was no gap specified. A new and free to use array.
*/
int[] getComponentGaps(ContainerWrapper parent, ComponentWrapper comp, BoundSize adjGap, ComponentWrapper adjacentComp, String tag, int refSize, int adjacentSide, boolean isLTR)
{
BoundSize gap = adjacentSide < 2 ? gapBefore : gapAfter;
boolean hasGap = gap != null && gap.getGapPush();
if ((gap == null || gap.isUnset()) && (adjGap == null || adjGap.isUnset()) && comp != null)
gap = PlatformDefaults.getDefaultComponentGap(comp, adjacentComp, adjacentSide + 1, tag, isLTR);
if (gap == null)
return hasGap ? new int[] {0, 0, LayoutUtil.NOT_SET} : null;
int[] ret = new int[3];
for (int i = LayoutUtil.MIN; i <= LayoutUtil.MAX; i++) {
UnitValue uv = gap.getSize(i);
ret[i] = uv != null ? uv.getPixels(refSize, parent, null) : LayoutUtil.NOT_SET;
}
return ret;
}
// ************************************************
// Persistence Delegate and Serializable combined.
// ************************************************
private Object readResolve() throws ObjectStreamException
{
return LayoutUtil.getSerializedObject(this);
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
{
LayoutUtil.setSerializedObject(this, LayoutUtil.readAsXML(in));
}
@Override
public void writeExternal(ObjectOutput out) throws IOException
{
if (getClass() == DimConstraint.class)
LayoutUtil.writeAsXML(out, this);
}
}
miglayout-5.1/core/src/main/java/net/miginfocom/layout/Grid.java000077500000000000000000002552621324101563200247530ustar00rootroot00000000000000package net.miginfocom.layout;
import java.lang.ref.WeakReference;
import java.util.*;
/*
* License (BSD):
* ==============
*
* Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
* 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 the MiG InfoCom AB nor 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.
*
* @version 1.0
* @author Mikael Grev, MiG InfoCom AB
* Date: 2006-sep-08
*/
/** Holds components in a grid. Does most of the logic behind the layout manager.
*/
public final class Grid
{
public static final boolean TEST_GAPS = true;
private static final Float[] GROW_100 = new Float[] {ResizeConstraint.WEIGHT_100};
private static final DimConstraint DOCK_DIM_CONSTRAINT = new DimConstraint();
static {
DOCK_DIM_CONSTRAINT.setGrowPriority(0);
}
/** This is the maximum grid position for "normal" components. Docking components use the space out to
* MAX_DOCK_GRID
and below 0.
*/
private static final int MAX_GRID = 30000;
/** Docking components will use the grid coordinates -MAX_DOCK_GRID -> 0
and MAX_GRID -> MAX_DOCK_GRID
.
*/
private static final int MAX_DOCK_GRID = 32767;
/** A constraint used for gaps.
*/
private static final ResizeConstraint GAP_RC_CONST = new ResizeConstraint(200, ResizeConstraint.WEIGHT_100, 50, null);
private static final ResizeConstraint GAP_RC_CONST_PUSH = new ResizeConstraint(200, ResizeConstraint.WEIGHT_100, 50, ResizeConstraint.WEIGHT_100);
/** Used for components that doesn't have a CC set. Not that it's really really important that the CC is never changed in this Grid class.
*/
private static final CC DEF_CC = new CC();
/** The constraints. Never null
.
*/
private final LC lc;
/** The parent that is layout out and this grid is done for. Never null
.
*/
private final ContainerWrapper container;
/** An x, y array implemented as a sparse array to accommodate for any grid size without wasting memory (or rather 15 bit (0-MAX_GRID * 0-MAX_GRID).
*/
private final LinkedHashMap grid = new LinkedHashMap(); // [(y << 16) + x] -> Cell. null key for absolute positioned compwraps
private HashMap wrapGapMap = null; // Row or Column index depending in the dimension that "wraps". Normally row indexes but may be column indexes if "flowy". 0 means before first row/col.
/** The size of the grid. Row count and column count.
*/
private final TreeSet rowIndexes = new TreeSet(), colIndexes = new TreeSet();
/** The row and column specifications.
*/
private final AC rowConstr, colConstr;
/** The in the constructor calculated min/pref/max sizes of the rows and columns.
*/
private FlowSizeSpec colFlowSpecs = null, rowFlowSpecs = null;
/** Components that are connections in one dimension (such as baseline alignment for instance) are grouped together and stored here.
* One for each row/column.
*/
private final ArrayList[] colGroupLists, rowGroupLists; //[(start)row/col number]
/** The in the constructor calculated min/pref/max size of the whole grid.
*/
private int[] width = null, height = null;
/** If debug is on contains the bounds for things to paint when calling {@link ContainerWrapper#paintDebugCell(int, int, int, int)}
*/
private ArrayList debugRects = null; // [x, y, width, height]
/** If any of the absolute coordinates for component bounds has links the name of the target is in this Set.
* Since it requires some memory and computations this is checked at the creation so that
* the link information is only created if needed later.
*
* The boolean is true for groups id:s and null for normal id:s.
*/
private HashMap linkTargetIDs = null;
private final int dockOffY, dockOffX;
private final Float[] pushXs, pushYs;
private final ArrayList callbackList;
/** Constructor.
* @param container The container that will be laid out.
* @param lc The form flow constraints.
* @param rowConstr The rows specifications. If more cell rows are required, the last element will be used for when there is no corresponding element in this array.
* @param colConstr The columns specifications. If more cell rows are required, the last element will be used for when there is no corresponding element in this array.
* @param ccMap The map containing the parsed constraints for each child component of parent
. Will not be altered. Can have null CC which will use a common
* cached one.
* @param callbackList A list of callbacks or null
if none. Will not be altered.
*/
public Grid(ContainerWrapper container, LC lc, AC rowConstr, AC colConstr, Map ccMap, ArrayList callbackList)
{
this.lc = lc;
this.rowConstr = rowConstr;
this.colConstr = colConstr;
this.container = container;
this.callbackList = callbackList;
int wrap = lc.getWrapAfter() != 0 ? lc.getWrapAfter() : (lc.isFlowX() ? colConstr : rowConstr).getConstaints().length;
boolean useVisualPadding = lc.isVisualPadding();
final ComponentWrapper[] comps = container.getComponents();
boolean hasTagged = false; // So we do not have to sort if it will not do any good
boolean hasPushX = false, hasPushY = false;
boolean hitEndOfRow = false;
final int[] cellXY = new int[2];
final ArrayList spannedRects = new ArrayList(2);
final DimConstraint[] specs = (lc.isFlowX() ? rowConstr : colConstr).getConstaints();
int sizeGroupsX = 0, sizeGroupsY = 0;
int[] dockInsets = null; // top, left, bottom, right insets for docks.
LinkHandler.clearTemporaryBounds(container.getLayout());
for (int i = 0; i < comps.length;) {
ComponentWrapper comp = comps[i];
CC rootCc = getCC(comp, ccMap);
addLinkIDs(rootCc);
int hideMode = comp.isVisible() ? -1 : rootCc.getHideMode() != -1 ? rootCc.getHideMode() : lc.getHideMode();
if (hideMode == 3) { // To work with situations where there are components that does not have a layout manager, or not this one.
setLinkedBounds(comp, rootCc, comp.getX(), comp.getY(), comp.getWidth(), comp.getHeight(), rootCc.isExternal());
i++;
continue; // The "external" component should not be handled further.
}
if (rootCc.getHorizontal().getSizeGroup() != null)
sizeGroupsX++;
if (rootCc.getVertical().getSizeGroup() != null)
sizeGroupsY++;
// Special treatment of absolute positioned components.
if (getPos(comp, rootCc) != null || rootCc.isExternal()) {
CompWrap cw = new CompWrap(comp, rootCc, hideMode, useVisualPadding);
Cell cell = grid.get(null);
if (cell == null) {
grid.put(null, new Cell(cw));
} else {
cell.compWraps.add(cw);
}
if (!rootCc.isBoundsInGrid() || rootCc.isExternal()) {
setLinkedBounds(comp, rootCc, comp.getX(), comp.getY(), comp.getWidth(), comp.getHeight(), rootCc.isExternal());
i++;
continue;
}
}
if (rootCc.getDockSide() != -1) {
if (dockInsets == null)
dockInsets = new int[] {-MAX_DOCK_GRID, -MAX_DOCK_GRID, MAX_DOCK_GRID, MAX_DOCK_GRID};
addDockingCell(dockInsets, rootCc.getDockSide(), new CompWrap(comp, rootCc, hideMode, useVisualPadding));
i++;
continue;
}
Boolean cellFlowX = rootCc.getFlowX();
Cell cell = null;
if (rootCc.isNewline()) {
wrap(cellXY, rootCc.getNewlineGapSize());
} else if (hitEndOfRow) {
wrap(cellXY, null);
}
hitEndOfRow = false;
final boolean rowNoGrid = lc.isNoGrid() || ((DimConstraint) LayoutUtil.getIndexSafe(specs, lc.isFlowX() ? cellXY[1] : cellXY[0])).isNoGrid();
// Move to a free y, x if no absolute grid specified
int cx = rootCc.getCellX();
int cy = rootCc.getCellY();
if ((cx < 0 || cy < 0) && rowNoGrid == false && rootCc.getSkip() == 0) { // 3.7.2: If skip, don't find an empty cell first.
while (isCellFree(cellXY[1], cellXY[0], spannedRects) == false) {
if (Math.abs(increase(cellXY, 1)) >= wrap)
wrap(cellXY, null);
}
} else {
if (cx >= 0 && cy >= 0) {
if (cy >= 0) {
cellXY[0] = cx;
cellXY[1] = cy;
} else { // Only one coordinate is specified. Use the current row (flowx) or column (flowy) to fill in.
if (lc.isFlowX()) {
cellXY[0] = cx;
} else {
cellXY[1] = cx;
}
}
ensureIndexSizes(cx, cy);
}
cell = getCell(cellXY[1], cellXY[0]); // Might be null
}
// Skip a number of cells. Changed for 3.6.1 to take wrap into account and thus "skip" to the next and possibly more rows.
for (int s = 0, skipCount = rootCc.getSkip(); s < skipCount; s++) {
do {
if (Math.abs(increase(cellXY, 1)) >= wrap)
wrap(cellXY, null);
} while (isCellFree(cellXY[1], cellXY[0], spannedRects) == false);
}
// If cell is not created yet, create it and set it.
if (cell == null) {
int spanx = Math.min(rowNoGrid && lc.isFlowX() ? LayoutUtil.INF : rootCc.getSpanX(), MAX_GRID - cellXY[0]);
int spany = Math.min(rowNoGrid && !lc.isFlowX() ? LayoutUtil.INF : rootCc.getSpanY(), MAX_GRID - cellXY[1]);
cell = new Cell(spanx, spany, cellFlowX != null ? cellFlowX : lc.isFlowX());
setCell(cellXY[1], cellXY[0], cell);
// Add a rectangle so we can know that spanned cells occupy more space.
if (spanx > 1 || spany > 1)
spannedRects.add(new int[] {cellXY[0], cellXY[1], spanx, spany});
}
// Add the one, or all, components that split the grid position to the same Cell.
boolean wrapHandled = false;
int splitLeft = rowNoGrid ? LayoutUtil.INF : rootCc.getSplit() - 1;
boolean splitExit = false;
final boolean spanRestOfRow = (lc.isFlowX() ? rootCc.getSpanX() : rootCc.getSpanY()) == LayoutUtil.INF;
for (; splitLeft >= 0 && i < comps.length; splitLeft--) {
ComponentWrapper compAdd = comps[i];
CC cc = getCC(compAdd, ccMap);
addLinkIDs(cc);
boolean visible = compAdd.isVisible();
hideMode = visible ? -1 : cc.getHideMode() != -1 ? cc.getHideMode() : lc.getHideMode();
if (cc.isExternal() || hideMode == 3) {
i++;
splitLeft++; // Added for 3.5.5 so that these components does not "take" a split slot.
continue; // To work with situations where there are components that does not have a layout manager, or not this one.
}
hasPushX |= (visible || hideMode > 1) && (cc.getPushX() != null);
hasPushY |= (visible || hideMode > 1) && (cc.getPushY() != null);
if (cc != rootCc) { // If not first in a cell
if (cc.isNewline() || cc.isBoundsInGrid() == false || cc.getDockSide() != -1)
break;
if (splitLeft > 0 && cc.getSkip() > 0) {
splitExit = true;
break;
}
}
CompWrap cw = new CompWrap(compAdd, cc, hideMode, useVisualPadding);
cell.compWraps.add(cw);
cell.hasTagged |= cc.getTag() != null;
hasTagged |= cell.hasTagged;
if (cc != rootCc) {
if (cc.getHorizontal().getSizeGroup() != null)
sizeGroupsX++;
if (cc.getVertical().getSizeGroup() != null)
sizeGroupsY++;
}
i++;
if ((cc.isWrap() || (spanRestOfRow && splitLeft == 0))) {
if (cc.isWrap()) {
wrap(cellXY, cc.getWrapGapSize());
} else {
hitEndOfRow = true;
}
wrapHandled = true;
break;
}
}
if (wrapHandled == false && rowNoGrid == false) {
int span = lc.isFlowX() ? cell.spanx : cell.spany;
if (Math.abs((lc.isFlowX() ? cellXY[0] : cellXY[1])) + span >= wrap) {
hitEndOfRow = true;
} else {
increase(cellXY, splitExit ? span - 1 : span);
}
}
}
// If there were size groups, calculate the largest values in the groups (for min/pref/max) and enforce them on the rest in the group.
if (sizeGroupsX > 0 || sizeGroupsY > 0) {
HashMap sizeGroupMapX = sizeGroupsX > 0 ? new HashMap(sizeGroupsX) : null;
HashMap sizeGroupMapY = sizeGroupsY > 0 ? new HashMap(sizeGroupsY) : null;
ArrayList sizeGroupCWs = new ArrayList(Math.max(sizeGroupsX, sizeGroupsY));
for (Cell cell : grid.values()) {
for (int i = 0; i < cell.compWraps.size(); i++) {
CompWrap cw = cell.compWraps.get(i);
String sgx = cw.cc.getHorizontal().getSizeGroup();
String sgy = cw.cc.getVertical().getSizeGroup();
if (sgx != null || sgy != null) {
if (sgx != null && sizeGroupMapX != null)
addToSizeGroup(sizeGroupMapX, sgx, cw.getSizes(true));
if (sgy != null && sizeGroupMapY != null)
addToSizeGroup(sizeGroupMapY, sgy, cw.getSizes(false));
sizeGroupCWs.add(cw);
}
}
}
// Set/equalize the sizeGroups to same the values.
for (CompWrap cw : sizeGroupCWs) {
if (sizeGroupMapX != null)
cw.setForcedSizes(sizeGroupMapX.get(cw.cc.getHorizontal().getSizeGroup()), true); // Target method handles null sizes
if (sizeGroupMapY != null)
cw.setForcedSizes(sizeGroupMapY.get(cw.cc.getVertical().getSizeGroup()), false); // Target method handles null sizes
}
} // Component loop
if (hasTagged)
sortCellsByPlatform(grid.values(), container);
// Calculate gaps now that the cells are filled and we know all adjacent components.
boolean ltr = LayoutUtil.isLeftToRight(lc, container);
for (Cell cell : grid.values()) {
ArrayList cws = cell.compWraps;
for (int i = 0, lastI = cws.size() - 1; i <= lastI; i++) {
CompWrap cw = cws.get(i);
ComponentWrapper cwBef = i > 0 ? cws.get(i - 1).comp : null;
ComponentWrapper cwAft = i < lastI ? cws.get(i + 1).comp : null;
String tag = getCC(cw.comp, ccMap).getTag();
CC ccBef = cwBef != null ? getCC(cwBef, ccMap) : null;
CC ccAft = cwAft != null ? getCC(cwAft, ccMap) : null;
cw.calcGaps(cwBef, ccBef, cwAft, ccAft, tag, cell.flowx, ltr);
}
}
dockOffX = getDockInsets(colIndexes);
dockOffY = getDockInsets(rowIndexes);
// Add synthetic indexes for empty rows and columns so they can get a size
ensureIndexSizes(colConstr.getCount(), rowConstr.getCount());
colGroupLists = divideIntoLinkedGroups(false);
rowGroupLists = divideIntoLinkedGroups(true);
pushXs = hasPushX || lc.isFillX() ? getDefaultPushWeights(false) : null;
pushYs = hasPushY || lc.isFillY() ? getDefaultPushWeights(true) : null;
if (LayoutUtil.isDesignTime(container))
saveGrid(container, grid);
}
private void ensureIndexSizes(int colCount, int rowCount)
{
for (int i = 0; i < colCount; i++)
colIndexes.add(i);
for (int i = 0; i < rowCount; i++)
rowIndexes.add(i);
}
private static CC getCC(ComponentWrapper comp, Map ccMap)
{
CC cc = ccMap.get(comp);
return cc != null ? cc : DEF_CC;
}
private void addLinkIDs(CC cc)
{
String[] linkIDs = cc.getLinkTargets();
for (String linkID : linkIDs) {
if (linkTargetIDs == null)
linkTargetIDs = new HashMap();
linkTargetIDs.put(linkID, null);
}
}
/** If the container (parent) that this grid is laying out has changed its bounds, call this method to
* clear any cached values min/pref/max sizes of the components and rows/columns.
*
* If any component can have changed cell the grid needs to be recreated.
*/
public void invalidateContainerSize()
{
colFlowSpecs = null;
invalidateComponentSizes();
}
private void invalidateComponentSizes()
{
for (Cell cell : grid.values()) {
for (CompWrap compWrap : cell.compWraps)
compWrap.invalidateSizes();
}
}
/**
* @deprecated since 5.0 Last boolean is not needed and is gotten from the new {@link net.miginfocom.layout.ComponentWrapper#getContentBias()} instead;
*/
public boolean layout(int[] bounds, UnitValue alignX, UnitValue alignY, boolean debug, boolean notUsed)
{
return layoutImpl(bounds, alignX, alignY, debug, false);
}
/** Does the actual layout. Uses many values calculated in the constructor.
* @param bounds The bounds to layout against. Normally that of the parent. [x, y, width, height].
* @param alignX The alignment for the x-axis. Can be null.
* @param alignY The alignment for the y-axis. Can be null.
* @param debug If debug information should be saved in {@link #debugRects}.
* @return If the layout has changed the preferred size and there is need for a new layout. This can happen if one or more components
* in the grid has a content bias according to {@link net.miginfocom.layout.ComponentWrapper#getContentBias()}.
* @since 5.0
*/
public boolean layout(int[] bounds, UnitValue alignX, UnitValue alignY, boolean debug)
{
return layoutImpl(bounds, alignX, alignY, debug, false);
}
/** Does the actual layout. Uses many values calculated in the constructor.
* @param bounds The bounds to layout against. Normally that of the parent. [x, y, width, height].
* @param alignX The alignment for the x-axis. Can be null.
* @param alignY The alignment for the y-axis. Can be null.
* @param debug If debug information should be saved in {@link #debugRects}.
* @param trialRun If true the bounds calculated will not be transferred to the components. Only the internal size
* of the components will be calculated.
* @return If the layout has changed the preferred size and there is need for a new layout. This can happen if one or more components
* in the grid has a content bias according to {@link net.miginfocom.layout.ComponentWrapper#getContentBias()}.
* @since 5.0
*/
private boolean layoutImpl(int[] bounds, UnitValue alignX, UnitValue alignY, boolean debug, boolean trialRun)
{
if (debug)
debugRects = new ArrayList();
if (colFlowSpecs == null)
checkSizeCalcs(bounds[2], bounds[3]);
resetLinkValues(true, true);
layoutInOneDim(bounds[2], alignX, false, pushXs);
layoutInOneDim(bounds[3], alignY, true, pushYs);
HashMap endGrpXMap = null, endGrpYMap = null;
int compCount = container.getComponentCount();
// Transfer the calculated bound from the ComponentWrappers to the actual Components.
boolean addVisualPadding = lc.isVisualPadding();
boolean layoutAgain = false;
if (compCount > 0) {
for (int j = 0; j < (linkTargetIDs != null ? 2 : 1); j++) { // First do the calculations (maybe more than once) then set the bounds when done
boolean doAgain;
int count = 0;
do {
doAgain = false;
for (Cell cell : grid.values()) {
for (CompWrap cw : cell.compWraps) {
if (j == 0) {
doAgain |= doAbsoluteCorrections(cw, bounds);
if (!doAgain) { // If we are going to do this again, do not bother this time around
if (cw.cc.getHorizontal().getEndGroup() != null)
endGrpXMap = addToEndGroup(endGrpXMap, cw.cc.getHorizontal().getEndGroup(), cw.x + cw.w);
if (cw.cc.getVertical().getEndGroup() != null)
endGrpYMap = addToEndGroup(endGrpYMap, cw.cc.getVertical().getEndGroup(), cw.y + cw.h);
}
// @since 3.7.2 Needed or absolute "pos" pointing to "visual" or "container" didn't work if
// their bounds changed during the layout cycle. At least not in SWT.
if (linkTargetIDs != null && (linkTargetIDs.containsKey("visual") || linkTargetIDs.containsKey("container"))) {
layoutAgain = true;
}
}
if (linkTargetIDs == null || j == 1) {
if (cw.cc.getHorizontal().getEndGroup() != null)
cw.w = endGrpXMap.get(cw.cc.getHorizontal().getEndGroup()) - cw.x;
if (cw.cc.getVertical().getEndGroup() != null)
cw.h = endGrpYMap.get(cw.cc.getVertical().getEndGroup()) - cw.y;
cw.x += bounds[0];
cw.y += bounds[1];
if (!trialRun)
cw.transferBounds(addVisualPadding);
if (callbackList != null) {
for (LayoutCallback callback : callbackList)
callback.correctBounds(cw.comp);
}
}
}
}
clearGroupLinkBounds();
if (++count > ((compCount << 3) + 10)) {
System.err.println("Unstable cyclic dependency in absolute linked values.");
break;
}
} while (doAgain);
}
}
// Add debug shapes for the "cells". Use the CompWraps as base for inding the cells.
if (debug) {
for (Cell cell : grid.values()) {
ArrayList compWraps = cell.compWraps;
for (CompWrap cw : compWraps) {
LinkedDimGroup hGrp = getGroupContaining(colGroupLists, cw);
LinkedDimGroup vGrp = getGroupContaining(rowGroupLists, cw);
if (hGrp != null && vGrp != null)
debugRects.add(new int[]{hGrp.lStart + bounds[0] - (hGrp.fromEnd ? hGrp.lSize : 0), vGrp.lStart + bounds[1] - (vGrp.fromEnd ? vGrp.lSize : 0), hGrp.lSize, vGrp.lSize});
}
}
}
return layoutAgain;
}
public void paintDebug()
{
if (debugRects != null) {
container.paintDebugOutline(lc.isVisualPadding());
ArrayList painted = new ArrayList();
for (int[] r : debugRects) {
if (!painted.contains(r)) {
container.paintDebugCell(r[0], r[1], r[2], r[3]);
painted.add(r);
}
}
for (Cell cell : grid.values()) {
ArrayList compWraps = cell.compWraps;
for (CompWrap compWrap : compWraps)
compWrap.comp.paintDebugOutline(lc.isVisualPadding());
}
}
}
public ContainerWrapper getContainer()
{
return container;
}
public final int[] getWidth()
{
return getWidth(lastRefHeight);
}
public final int[] getWidth(int refHeight)
{
checkSizeCalcs(lastRefWidth, refHeight);
return width.clone();
}
public final int[] getHeight()
{
return getHeight(lastRefWidth);
}
public final int[] getHeight(int refWidth)
{
checkSizeCalcs(refWidth, lastRefHeight);
return height.clone();
}
private int lastRefWidth = 0, lastRefHeight = 0;
private void checkSizeCalcs(int refWidth, int refHeight)
{
if (colFlowSpecs == null)
calcGridSizes(refWidth, refHeight);
if ((refWidth > 0 && refWidth != lastRefWidth) || (refHeight > 0 && refHeight != lastRefHeight)) {
int[] refBounds = new int[] {0, 0, (refWidth > 0 ? refWidth : width[LayoutUtil.PREF]), (refHeight > 0 ? refHeight : height[LayoutUtil.PREF])};
layoutImpl(refBounds, null, null, false, true);
calcGridSizes(refWidth, refHeight);
}
lastRefWidth = refWidth;
lastRefHeight = refHeight;
}
private void calcGridSizes(int refWidth, int refHeight)
{
// Note, in these calls the grid can be invalidated and specs set to null. Therefore use local versions.
FlowSizeSpec colSpecs = calcRowsOrColsSizes(true, refWidth);
FlowSizeSpec rowSpecs = calcRowsOrColsSizes(false, refHeight);
colFlowSpecs = colSpecs;
rowFlowSpecs = rowSpecs;
width = getMinPrefMaxSumSize(true, colSpecs.sizes);
height = getMinPrefMaxSumSize(false, rowSpecs.sizes);
if (linkTargetIDs == null) {
resetLinkValues(false, true);
} else {
// This call makes some components flicker on SWT. They get their bounds changed twice since
// the change might affect the absolute size adjustment below. There's no way around this that
// I know of.
layout(new int[]{0, 0, refWidth, refHeight}, null, null, false);
resetLinkValues(false, false);
}
adjustSizeForAbsolute(true);
adjustSizeForAbsolute(false);
}
private UnitValue[] getPos(ComponentWrapper cw, CC cc)
{
UnitValue[] callbackPos = null;
if (callbackList != null) {
for (int i = 0; i < callbackList.size() && callbackPos == null; i++)
callbackPos = callbackList.get(i).getPosition(cw); // NOT a copy!
}
// If one is null, return the other (which many also be null)
UnitValue[] ccPos = cc.getPos(); // A copy!!
if (callbackPos == null || ccPos == null)
return callbackPos != null ? callbackPos : ccPos;
// Merge
for (int i = 0; i < 4; i++) {
UnitValue cbUv = callbackPos[i];
if (cbUv != null)
ccPos[i] = cbUv;
}
return ccPos;
}
private BoundSize[] getCallbackSize(ComponentWrapper cw)
{
if (callbackList != null) {
for (LayoutCallback callback : callbackList) {
BoundSize[] bs = callback.getSize(cw); // NOT a copy!
if (bs != null)
return bs;
}
}
return null;
}
private static int getDockInsets(TreeSet set)
{
int c = 0;
for (Integer i : set) {
if (i < -MAX_GRID) {
c++;
} else {
break; // Since they are sorted we can break
}
}
return c;
}
/**
* @param cw Never null
.
* @param cc Never null
.
* @param external The bounds should be stored even if they are not in {@link #linkTargetIDs}.
* @return If a change has been made.
*/
private boolean setLinkedBounds(ComponentWrapper cw, CC cc, int x, int y, int w, int h, boolean external)
{
String id = cc.getId() != null ? cc.getId() : cw.getLinkId();
if (id == null)
return false;
String gid = null;
int grIx = id.indexOf('.');
if (grIx != -1 ) {
gid = id.substring(0, grIx);
id = id.substring(grIx + 1);
}
Object lay = container.getLayout();
boolean changed = false;
if (external || (linkTargetIDs != null && linkTargetIDs.containsKey(id)))
changed = LinkHandler.setBounds(lay, id, x, y, w, h, !external, false);
if (gid != null && (external || (linkTargetIDs != null && linkTargetIDs.containsKey(gid)))) {
if (linkTargetIDs == null)
linkTargetIDs = new HashMap(4);
linkTargetIDs.put(gid, Boolean.TRUE);
changed |= LinkHandler.setBounds(lay, gid, x, y, w, h, !external, true);
}
return changed;
}
/** Go to next cell.
* @param p The point to increase
* @param cnt How many cells to advance.
* @return The new value in the "increasing" dimension.
*/
private int increase(int[] p, int cnt)
{
return lc.isFlowX() ? (p[0] += cnt) : (p[1] += cnt);
}
/** Wraps to the next row or column depending on if horizontal flow or vertical flow is used.
* @param cellXY The point to wrap and thus set either x or y to 0 and increase the other one.
* @param gapSize The gaps size specified in a "wrap XXX" or "newline XXX" or null
if none.
*/
private void wrap(int[] cellXY, BoundSize gapSize)
{
boolean flowx = lc.isFlowX();
cellXY[0] = flowx ? 0 : cellXY[0] + 1;
cellXY[1] = flowx ? cellXY[1] + 1 : 0;
if (gapSize != null) {
if (wrapGapMap == null)
wrapGapMap = new HashMap(8);
wrapGapMap.put(cellXY[flowx ? 1 : 0], gapSize);
}
// add the row/column so that the gap in the last row/col will not be removed.
if (flowx) {
rowIndexes.add(cellXY[1]);
} else {
colIndexes.add(cellXY[0]);
}
}
/** Sort components (normally buttons in a button bar) so they appear in the correct order.
* @param cells The cells to sort.
* @param parent The parent.
*/
private static void sortCellsByPlatform(Collection cells, ContainerWrapper parent)
{
String order = PlatformDefaults.getButtonOrder();
String orderLo = order.toLowerCase();
int unrelSize = PlatformDefaults.convertToPixels(1, "u", true, 0, parent, null);
if (unrelSize == UnitConverter.UNABLE)
throw new IllegalArgumentException("'unrelated' not recognized by PlatformDefaults!");
int[] gapUnrel = new int[] {unrelSize, unrelSize, LayoutUtil.NOT_SET};
int[] flGap = new int[] {0, 0, LayoutUtil.NOT_SET};
for (Cell cell : cells) {
if (cell.hasTagged == false)
continue;
CompWrap prevCW = null;
boolean nextUnrel = false;
boolean nextPush = false;
ArrayList sortedList = new ArrayList(cell.compWraps.size());
for (int i = 0, iSz = orderLo.length(); i < iSz; i++) {
char c = orderLo.charAt(i);
if (c == '+' || c == '_') {
nextUnrel = true;
if (c == '+')
nextPush = true;
} else {
String tag = PlatformDefaults.getTagForChar(c);
if (tag != null) {
for (int j = 0, jSz = cell.compWraps.size(); j < jSz; j++) {
CompWrap cw = cell.compWraps.get(j);
if (tag.equals(cw.cc.getTag())) {
if (Character.isUpperCase(order.charAt(i)))
cw.adjustMinHorSizeUp((int) PlatformDefaults.getMinimumButtonWidthIncludingPadding(0, parent, cw.comp));
sortedList.add(cw);
if (nextUnrel) {
(prevCW != null ? prevCW : cw).mergeGapSizes(gapUnrel, cell.flowx, prevCW == null);
if (nextPush) {
cw.forcedPushGaps = 1;
nextUnrel = false;
nextPush = false;
}
}
// "unknown" components will always get an Unrelated gap.
if (c == 'u')
nextUnrel = true;
prevCW = cw;
}
}
}
}
}
// If we have a gap that was supposed to push but no more components was found to but the "gap before" then compensate.
if (sortedList.size() > 0) {
CompWrap cw = sortedList.get(sortedList.size() - 1);
if (nextUnrel) {
cw.mergeGapSizes(gapUnrel, cell.flowx, false);
if (nextPush)
cw.forcedPushGaps |= 2;
}
// Remove first and last gap if not set explicitly.
if (cw.cc.getHorizontal().getGapAfter() == null)
cw.setGaps(flGap, 3);
cw = sortedList.get(0);
if (cw.cc.getHorizontal().getGapBefore() == null)
cw.setGaps(flGap, 1);
}
// Exchange the unsorted CompWraps for the sorted one.
if (cell.compWraps.size() == sortedList.size()) {
cell.compWraps.clear();
} else {
cell.compWraps.removeAll(sortedList);
}
cell.compWraps.addAll(sortedList);
}
}
private Float[] getDefaultPushWeights(boolean isRows)
{
ArrayList[] groupLists = isRows ? rowGroupLists : colGroupLists;
Float[] pushWeightArr = GROW_100; // Only create specific if any of the components have grow.
for (int i = 0, ix = 1; i < groupLists.length; i++, ix += 2) {
ArrayList grps = groupLists[i];
Float rowPushWeight = null;
for (LinkedDimGroup grp : grps) {
for (int c = 0; c < grp._compWraps.size(); c++) {
CompWrap cw = grp._compWraps.get(c);
int hideMode = cw.comp.isVisible() ? -1 : cw.cc.getHideMode() != -1 ? cw.cc.getHideMode() : lc.getHideMode();
Float pushWeight = hideMode < 2 ? (isRows ? cw.cc.getPushY() : cw.cc.getPushX()) : null;
if (rowPushWeight == null || (pushWeight != null && pushWeight.floatValue() > rowPushWeight.floatValue()))
rowPushWeight = pushWeight;
}
}
if (rowPushWeight != null) {
if (pushWeightArr == GROW_100)
pushWeightArr = new Float[(groupLists.length << 1) + 1];
pushWeightArr[ix] = rowPushWeight;
}
}
return pushWeightArr;
}
private void clearGroupLinkBounds()
{
if (linkTargetIDs == null)
return;
for (Map.Entry o : linkTargetIDs.entrySet()) {
if (o.getValue() == Boolean.TRUE)
LinkHandler.clearBounds(container.getLayout(), o.getKey());
}
}
private void resetLinkValues(boolean parentSize, boolean compLinks)
{
Object lay = container.getLayout();
if (compLinks)
LinkHandler.clearTemporaryBounds(lay);
boolean defIns = !hasDocks();
int parW = parentSize ? lc.getWidth().constrain(container.getWidth(), getParentSize(container, true), container) : 0;
int parH = parentSize ? lc.getHeight().constrain(container.getHeight(), getParentSize(container, false), container) : 0;
int insX = LayoutUtil.getInsets(lc, 0, defIns).getPixels(0, container, null);
int insY = LayoutUtil.getInsets(lc, 1, defIns).getPixels(0, container, null);
int visW = parW - insX - LayoutUtil.getInsets(lc, 2, defIns).getPixels(0, container, null);
int visH = parH - insY - LayoutUtil.getInsets(lc, 3, defIns).getPixels(0, container, null);
LinkHandler.setBounds(lay, "visual", insX, insY, visW, visH, true, false);
LinkHandler.setBounds(lay, "container", 0, 0, parW, parH, true, false);
}
/** Returns the {@link net.miginfocom.layout.Grid.LinkedDimGroup} that has the {@link net.miginfocom.layout.Grid.CompWrap}
* cw .
* @param groupLists The lists to search in.
* @param cw The component wrap to find.
* @return The linked group or null if none had the component wrap.
*/
private static LinkedDimGroup getGroupContaining(ArrayList[] groupLists, CompWrap cw)
{
for (ArrayList groups : groupLists) {
for (int j = 0, jSz = groups.size(); j < jSz; j++) {
ArrayList cwList = groups.get(j)._compWraps;
for (int k = 0, kSz = cwList.size(); k < kSz; k++) {
if (cwList.get(k) == cw)
return groups.get(j);
}
}
}
return null;
}
private boolean doAbsoluteCorrections(CompWrap cw, int[] bounds)
{
boolean changed = false;
int[] stSz = getAbsoluteDimBounds(cw, bounds[2], true);
if (stSz != null)
cw.setDimBounds(stSz[0], stSz[1], true);
stSz = getAbsoluteDimBounds(cw, bounds[3], false);
if (stSz != null)
cw.setDimBounds(stSz[0], stSz[1], false);
// If there is a link id, store the new bounds.
if (linkTargetIDs != null)
changed = setLinkedBounds(cw.comp, cw.cc, cw.x, cw.y, cw.w, cw.h, false);
return changed;
}
/** Adjust grid's width or height for the absolute components' positions.
*/
private void adjustSizeForAbsolute(boolean isHor)
{
int[] curSizes = isHor ? width : height;
Cell absCell = grid.get(null);
if (absCell == null || absCell.compWraps.size() == 0)
return;
ArrayList cws = absCell.compWraps;
int maxEnd = 0;
for (int j = 0, cwSz = absCell.compWraps.size(); j < cwSz + 3; j++) { // "Do Again" max absCell.compWraps.size() + 3 times.
boolean doAgain = false;
for (int i = 0; i < cwSz; i++) {
CompWrap cw = cws.get(i);
int[] stSz = getAbsoluteDimBounds(cw, 0, isHor);
int end = stSz[0] + stSz[1];
if (maxEnd < end)
maxEnd = end;
// If there is a link id, store the new bounds.
if (linkTargetIDs != null)
doAgain |= setLinkedBounds(cw.comp, cw.cc, stSz[0], stSz[0], stSz[1], stSz[1], false);
}
if (doAgain == false)
break;
// We need to check this again since the coords may be smaller this round.
maxEnd = 0;
clearGroupLinkBounds();
}
maxEnd += LayoutUtil.getInsets(lc, isHor ? 3 : 2, !hasDocks()).getPixels(0, container, null);
if (curSizes[LayoutUtil.MIN] < maxEnd)
curSizes[LayoutUtil.MIN] = maxEnd;
if (curSizes[LayoutUtil.PREF] < maxEnd)
curSizes[LayoutUtil.PREF] = maxEnd;
}
private int[] getAbsoluteDimBounds(CompWrap cw, int refSize, boolean isHor)
{
if (cw.cc.isExternal()) {
if (isHor) {
return new int[] {cw.comp.getX(), cw.comp.getWidth()};
} else {
return new int[] {cw.comp.getY(), cw.comp.getHeight()};
}
}
UnitValue[] pad = cw.cc.getPadding();
// If no changes do not create a lot of objects
UnitValue[] pos = getPos(cw.comp, cw.cc);
if (pos == null && pad == null)
return null;
// Set start
int st = isHor ? cw.x : cw.y;
int sz = isHor ? cw.w : cw.h;
// If absolute, use those coordinates instead.
if (pos != null) {
UnitValue stUV = pos != null ? pos[isHor ? 0 : 1] : null;
UnitValue endUV = pos != null ? pos[isHor ? 2 : 3] : null;
int minSz = cw.getSize(LayoutUtil.MIN, isHor);
int maxSz = cw.getSize(LayoutUtil.MAX, isHor);
sz = Math.min(Math.max(cw.getSize(LayoutUtil.PREF, isHor), minSz), maxSz);
if (stUV != null) {
st = stUV.getPixels(stUV.getUnit() == UnitValue.ALIGN ? sz : refSize, container, cw.comp);
if (endUV != null) // if (endUV == null && cw.cc.isBoundsIsGrid() == true)
sz = Math.min(Math.max((isHor ? (cw.x + cw.w) : (cw.y + cw.h)) - st, minSz), maxSz);
}
if (endUV != null) {
if (stUV != null) { // if (stUV != null || cw.cc.isBoundsIsGrid()) {
sz = Math.min(Math.max(endUV.getPixels(refSize, container, cw.comp) - st, minSz), maxSz);
} else {
st = endUV.getPixels(refSize, container, cw.comp) - sz;
}
}
}
// If constraint has padding -> correct the start/size
if (pad != null) {
UnitValue uv = pad[isHor ? 1 : 0];
int p = uv != null ? uv.getPixels(refSize, container, cw.comp) : 0;
st += p;
uv = pad[isHor ? 3 : 2];
sz += -p + (uv != null ? uv.getPixels(refSize, container, cw.comp) : 0);
}
return new int[] {st, sz};
}
private void layoutInOneDim(int refSize, UnitValue align, boolean isRows, Float[] defaultPushWeights)
{
boolean fromEnd = !(isRows ? lc.isTopToBottom() : LayoutUtil.isLeftToRight(lc, container));
DimConstraint[] primDCs = (isRows ? rowConstr : colConstr).getConstaints();
FlowSizeSpec fss = isRows ? rowFlowSpecs : colFlowSpecs;
ArrayList[] rowCols = isRows ? rowGroupLists : colGroupLists;
int[] rowColSizes = LayoutUtil.calculateSerial(fss.sizes, fss.resConstsInclGaps, defaultPushWeights, LayoutUtil.PREF, refSize);
if (LayoutUtil.isDesignTime(container)) {
TreeSet indexes = isRows ? rowIndexes : colIndexes;
int[] ixArr = new int[indexes.size()];
int ix = 0;
for (Integer i : indexes)
ixArr[ix++] = i;
putSizesAndIndexes(container.getComponent(), rowColSizes, ixArr, isRows);
}
int curPos = align != null ? align.getPixels(refSize - LayoutUtil.sum(rowColSizes), container, null) : 0;
if (fromEnd)
curPos = refSize - curPos;
for (int i = 0 ; i < rowCols.length; i++) {
ArrayList linkedGroups = rowCols[i];
int scIx = i - (isRows ? dockOffY : dockOffX);
int bIx = i << 1;
int bIx2 = bIx + 1;
curPos += (fromEnd ? -rowColSizes[bIx] : rowColSizes[bIx]);
DimConstraint primDC = scIx >= 0 ? primDCs[scIx >= primDCs.length ? primDCs.length - 1 : scIx] : DOCK_DIM_CONSTRAINT;
int rowSize = rowColSizes[bIx2];
for (LinkedDimGroup group : linkedGroups) {
int groupSize = rowSize;
if (group.span > 1)
groupSize = LayoutUtil.sum(rowColSizes, bIx2, Math.min((group.span << 1) - 1, rowColSizes.length - bIx2 - 1));
group.layout(primDC, curPos, groupSize, group.span);
}
curPos += (fromEnd ? -rowSize : rowSize);
}
}
private static void addToSizeGroup(HashMap sizeGroups, String sizeGroup, int[] size)
{
int[] sgSize = sizeGroups.get(sizeGroup);
if (sgSize == null) {
sizeGroups.put(sizeGroup, new int[] {size[LayoutUtil.MIN], size[LayoutUtil.PREF], size[LayoutUtil.MAX]});
} else {
sgSize[LayoutUtil.MIN] = Math.max(size[LayoutUtil.MIN], sgSize[LayoutUtil.MIN]);
sgSize[LayoutUtil.PREF] = Math.max(size[LayoutUtil.PREF], sgSize[LayoutUtil.PREF]);
sgSize[LayoutUtil.MAX] = Math.min(size[LayoutUtil.MAX], sgSize[LayoutUtil.MAX]);
}
}
private static HashMap addToEndGroup(HashMap endGroups, String endGroup, int end)
{
if (endGroup != null) {
if (endGroups == null)
endGroups = new HashMap(4);
Integer oldEnd = endGroups.get(endGroup);
if (oldEnd == null || end > oldEnd)
endGroups.put(endGroup, end);
}
return endGroups;
}
/** Calculates Min, Preferred and Max size for the columns OR rows.
* @param isHor If it is the horizontal dimension to calculate.
* @param containerSize The reference container size in the dimension. If <= 0 it will be replaced by the actual container's size.
* @return The sizes in a {@link net.miginfocom.layout.Grid.FlowSizeSpec}.
*/
private FlowSizeSpec calcRowsOrColsSizes(boolean isHor, int containerSize)
{
ArrayList[] groupsLists = isHor ? colGroupLists : rowGroupLists;
Float[] defPush = isHor ? pushXs : pushYs;
if (containerSize <= 0)
containerSize = isHor ? container.getWidth() : container.getHeight();
BoundSize cSz = isHor ? lc.getWidth() : lc.getHeight();
if (!cSz.isUnset())
containerSize = cSz.constrain(containerSize, getParentSize(container, isHor), container);
DimConstraint[] primDCs = (isHor? colConstr : rowConstr).getConstaints();
TreeSet primIndexes = isHor ? colIndexes : rowIndexes;
int[][] rowColBoundSizes = new int[primIndexes.size()][];
HashMap sizeGroupMap = new HashMap(4);
DimConstraint[] allDCs = new DimConstraint[primIndexes.size()];
Iterator primIt = primIndexes.iterator();
for (int r = 0; r < rowColBoundSizes.length; r++) {
int cellIx = primIt.next();
int[] rowColSizes = new int[3];
if (cellIx >= -MAX_GRID && cellIx <= MAX_GRID) { // If not dock cell
allDCs[r] = primDCs[cellIx >= primDCs.length ? primDCs.length - 1 : cellIx];
} else {
allDCs[r] = DOCK_DIM_CONSTRAINT;
}
ArrayList groups = groupsLists[r];
int[] groupSizes = new int[] {
getTotalGroupsSizeParallel(groups, LayoutUtil.MIN, false),
getTotalGroupsSizeParallel(groups, LayoutUtil.PREF, false),
LayoutUtil.INF};
correctMinMax(groupSizes);
BoundSize dimSize = allDCs[r].getSize();
for (int sType = LayoutUtil.MIN; sType <= LayoutUtil.MAX; sType++) {
int rowColSize = groupSizes[sType];
UnitValue uv = dimSize.getSize(sType);
if (uv != null) {
// If the size of the column is a link to some other size, use that instead
int unit = uv.getUnit();
if (unit == UnitValue.PREF_SIZE) {
rowColSize = groupSizes[LayoutUtil.PREF];
} else if (unit == UnitValue.MIN_SIZE) {
rowColSize = groupSizes[LayoutUtil.MIN];
} else if (unit == UnitValue.MAX_SIZE) {
rowColSize = groupSizes[LayoutUtil.MAX];
} else {
rowColSize = uv.getPixels(containerSize, container, null);
}
} else if (cellIx >= -MAX_GRID && cellIx <= MAX_GRID && rowColSize == 0) {
rowColSize = LayoutUtil.isDesignTime(container) ? LayoutUtil.getDesignTimeEmptySize() : 0; // Empty rows with no size set gets XX pixels if design time
}
rowColSizes[sType] = rowColSize;
}
correctMinMax(rowColSizes);
addToSizeGroup(sizeGroupMap, allDCs[r].getSizeGroup(), rowColSizes);
rowColBoundSizes[r] = rowColSizes;
}
// Set/equalize the size groups to same the values.
if (sizeGroupMap.size() > 0) {
for (int r = 0; r < rowColBoundSizes.length; r++) {
if (allDCs[r].getSizeGroup() != null)
rowColBoundSizes[r] = sizeGroupMap.get(allDCs[r].getSizeGroup());
}
}
// Add the gaps
ResizeConstraint[] resConstrs = getRowResizeConstraints(allDCs);
boolean[] fillInPushGaps = new boolean[allDCs.length + 1];
int[][] gapSizes = getRowGaps(allDCs, containerSize, isHor, fillInPushGaps);
FlowSizeSpec fss = mergeSizesGapsAndResConstrs(resConstrs, fillInPushGaps, rowColBoundSizes, gapSizes);
// Spanning components are not handled yet. Check and adjust the multi-row min/pref they enforce.
adjustMinPrefForSpanningComps(allDCs, defPush, fss, groupsLists);
return fss;
}
private static int getParentSize(ComponentWrapper cw, boolean isHor)
{
ContainerWrapper p = cw.getParent();
return p != null ? (isHor ? cw.getWidth() : cw.getHeight()) : 0;
}
private int[] getMinPrefMaxSumSize(boolean isHor, int[][] sizes)
{
int[] retSizes = new int[3];
BoundSize sz = isHor ? lc.getWidth() : lc.getHeight();
for (int i = 0; i < sizes.length; i++) {
if (sizes[i] != null) {
int[] size = sizes[i];
for (int sType = LayoutUtil.MIN; sType <= LayoutUtil.MAX; sType++) {
if (sz.getSize(sType) != null) {
if (i == 0)
retSizes[sType] = sz.getSize(sType).getPixels(getParentSize(container, isHor), container, null);
} else {
int s = size[sType];
if (s != LayoutUtil.NOT_SET) {
if (sType == LayoutUtil.PREF) {
int bnd = size[LayoutUtil.MAX];
if (bnd != LayoutUtil.NOT_SET && bnd < s)
s = bnd;
bnd = size[LayoutUtil.MIN];
if (bnd > s) // Includes s == LayoutUtil.NOT_SET since < 0.
s = bnd;
}
retSizes[sType] += s; // MAX compensated below.
}
// So that MAX is always correct.
if (size[LayoutUtil.MAX] == LayoutUtil.NOT_SET || retSizes[LayoutUtil.MAX] > LayoutUtil.INF)
retSizes[LayoutUtil.MAX] = LayoutUtil.INF;
}
}
}
}
correctMinMax(retSizes);
return retSizes;
}
private static ResizeConstraint[] getRowResizeConstraints(DimConstraint[] specs)
{
ResizeConstraint[] resConsts = new ResizeConstraint[specs.length];
for (int i = 0; i < resConsts.length; i++)
resConsts[i] = specs[i].resize;
return resConsts;
}
private static ResizeConstraint[] getComponentResizeConstraints(ArrayList compWraps, boolean isHor)
{
ResizeConstraint[] resConsts = new ResizeConstraint[compWraps.size()];
for (int i = 0; i < resConsts.length; i++) {
CC fc = compWraps.get(i).cc;
resConsts[i] = fc.getDimConstraint(isHor).resize;
// Always grow docking components in the correct dimension.
int dock = fc.getDockSide();
if (isHor ? (dock == 0 || dock == 2) : (dock == 1 || dock == 3)) {
ResizeConstraint dc = resConsts[i];
resConsts[i] = new ResizeConstraint(dc.shrinkPrio, dc.shrink, dc.growPrio, ResizeConstraint.WEIGHT_100);
}
}
return resConsts;
}
private static boolean[] getComponentGapPush(ArrayList compWraps, boolean isHor)
{
// Make one element bigger and or the after gap with the next before gap.
boolean[] barr = new boolean[compWraps.size() + 1];
for (int i = 0; i < barr.length; i++) {
boolean push = i > 0 && compWraps.get(i - 1).isPushGap(isHor, false);
if (push == false && i < (barr.length - 1))
push = compWraps.get(i).isPushGap(isHor, true);
barr[i] = push;
}
return barr;
}
/** Returns the row gaps in pixel sizes. One more than there are specs sent in.
* @param specs
* @param refSize
* @param isHor
* @param fillInPushGaps If the gaps are pushing. NOTE! this argument will be filled in and thus changed!
* @return The row gaps in pixel sizes. One more than there are specs sent in.
*/
private int[][] getRowGaps(DimConstraint[] specs, int refSize, boolean isHor, boolean[] fillInPushGaps)
{
BoundSize defGap = isHor ? lc.getGridGapX() : lc.getGridGapY();
if (defGap == null)
defGap = isHor ? PlatformDefaults.getGridGapX() : PlatformDefaults.getGridGapY();
int[] defGapArr = defGap.getPixelSizes(refSize, container, null);
boolean defIns = !hasDocks();
UnitValue firstGap = LayoutUtil.getInsets(lc, isHor ? 1 : 0, defIns);
UnitValue lastGap = LayoutUtil.getInsets(lc, isHor ? 3 : 2, defIns);
int[][] retValues = new int[specs.length + 1][];
for (int i = 0, wgIx = 0; i < retValues.length; i++) {
DimConstraint specBefore = i > 0 ? specs[i - 1] : null;
DimConstraint specAfter = i < specs.length ? specs[i] : null;
// No gap if between docking components.
boolean edgeBefore = (specBefore == DOCK_DIM_CONSTRAINT || specBefore == null);
boolean edgeAfter = (specAfter == DOCK_DIM_CONSTRAINT || specAfter == null);
if (edgeBefore && edgeAfter)
continue;
BoundSize wrapGapSize = (wrapGapMap == null || isHor == lc.isFlowX() ? null : wrapGapMap.get(Integer.valueOf(wgIx++)));
if (wrapGapSize == null) {
int[] gapBefore = specBefore != null ? specBefore.getRowGaps(container, null, refSize, false) : null;
int[] gapAfter = specAfter != null ? specAfter.getRowGaps(container, null, refSize, true) : null;
if (edgeBefore && gapAfter == null && firstGap != null) {
int bef = firstGap.getPixels(refSize, container, null);
retValues[i] = new int[] {bef, bef, bef};
} else if (edgeAfter && gapBefore == null && firstGap != null) {
int aft = lastGap.getPixels(refSize, container, null);
retValues[i] = new int[] {aft, aft, aft};
} else {
retValues[i] = gapAfter != gapBefore ? mergeSizes(gapAfter, gapBefore) : new int[] {defGapArr[0], defGapArr[1], defGapArr[2]};
}
if (specBefore != null && specBefore.isGapAfterPush() || specAfter != null && specAfter.isGapBeforePush())
fillInPushGaps[i] = true;
} else {
if (wrapGapSize.isUnset()) {
retValues[i] = new int[] {defGapArr[0], defGapArr[1], defGapArr[2]};
} else {
retValues[i] = wrapGapSize.getPixelSizes(refSize, container, null);
}
fillInPushGaps[i] = wrapGapSize.getGapPush();
}
}
return retValues;
}
private static int[][] getGaps(ArrayList compWraps, boolean isHor)
{
int compCount = compWraps.size();
int[][] retValues = new int[compCount + 1][];
retValues[0] = compWraps.get(0).getGaps(isHor, true);
for (int i = 0; i < compCount; i++) {
int[] gap1 = compWraps.get(i).getGaps(isHor, false);
int[] gap2 = i < compCount - 1 ? compWraps.get(i + 1).getGaps(isHor, true) : null;
retValues[i + 1] = mergeSizes(gap1, gap2);
}
return retValues;
}
private boolean hasDocks()
{
return (dockOffX > 0 || dockOffY > 0 || rowIndexes.last() > MAX_GRID || colIndexes.last() > MAX_GRID);
}
/** Adjust min/pref size for columns(or rows) that has components that spans multiple columns (or rows).
* @param specs The specs for the columns or rows. Last index will be used if count is greater than this array's length.
* @param defPush The default grow weight if the specs does not have anyone that will grow. Comes from "push" in the CC.
* @param fss
* @param groupsLists
*/
private void adjustMinPrefForSpanningComps(DimConstraint[] specs, Float[] defPush, FlowSizeSpec fss, ArrayList[] groupsLists)
{
for (int r = groupsLists.length - 1; r >= 0; r--) { // Since 3.7.3 Iterate from end to start. Will solve some multiple spanning components hard to solve problems.
ArrayList groups = groupsLists[r];
for (LinkedDimGroup group : groups) {
if (group.span == 1)
continue;
int[] sizes = group.getMinPrefMax();
for (int s = LayoutUtil.MIN; s <= LayoutUtil.PREF; s++) {
int cSize = sizes[s];
if (cSize == LayoutUtil.NOT_SET)
continue;
int rowSize = 0;
int sIx = (r << 1) + 1;
int len = Math.min((group.span << 1), fss.sizes.length - sIx) - 1;
for (int j = sIx; j < sIx + len; j++) {
int sz = fss.sizes[j][s];
if (sz != LayoutUtil.NOT_SET)
rowSize += sz;
}
if (rowSize < cSize && len > 0) {
for (int eagerness = 0, newRowSize = 0; eagerness < 4 && newRowSize < cSize; eagerness++)
newRowSize = fss.expandSizes(specs, defPush, cSize, sIx, len, s, eagerness);
}
}
}
}
}
/** For one dimension divide the component wraps into logical groups. One group for component wraps that share a common something,
* line the property to layout by base line.
* @param isRows If rows, and not columns, are to be divided.
* @return One ArrayList for every row/column.
*/
private ArrayList[] divideIntoLinkedGroups(boolean isRows)
{
boolean fromEnd = !(isRows ? lc.isTopToBottom() : LayoutUtil.isLeftToRight(lc, container));
TreeSet primIndexes = isRows ? rowIndexes : colIndexes;
TreeSet secIndexes = isRows ? colIndexes : rowIndexes;
DimConstraint[] primDCs = (isRows ? rowConstr : colConstr).getConstaints();
@SuppressWarnings("unchecked")
ArrayList[] groupLists = new ArrayList[primIndexes.size()];
int gIx = 0;
for (int i : primIndexes) {
DimConstraint dc;
if (i >= -MAX_GRID && i <= MAX_GRID) { // If not dock cell
dc = primDCs[i >= primDCs.length ? primDCs.length - 1 : i];
} else {
dc = DOCK_DIM_CONSTRAINT;
}
ArrayList groupList = new ArrayList(4);
groupLists[gIx++] = groupList;
for (Integer ix : secIndexes) {
Cell cell = isRows ? getCell(i, ix) : getCell(ix, i);
if (cell == null || cell.compWraps.size() == 0)
continue;
int span = (isRows ? cell.spany : cell.spanx);
if (span > 1)
span = convertSpanToSparseGrid(i, span, primIndexes);
boolean isPar = (cell.flowx == isRows);
if ((isPar == false && cell.compWraps.size() > 1) || span > 1) {
int linkType = isPar ? LinkedDimGroup.TYPE_PARALLEL : LinkedDimGroup.TYPE_SERIAL;
LinkedDimGroup lg = new LinkedDimGroup("p," + ix, span, linkType, !isRows, fromEnd);
lg.setCompWraps(cell.compWraps);
groupList.add(lg);
} else {
for (int cwIx = 0; cwIx < cell.compWraps.size(); cwIx++) {
CompWrap cw = cell.compWraps.get(cwIx);
boolean rowBaselineAlign = (isRows && lc.isTopToBottom() && dc.getAlignOrDefault(!isRows) == UnitValue.BASELINE_IDENTITY); // Disable baseline for bottomToTop since I can not verify it working.
boolean isBaseline = isRows && cw.isBaselineAlign(rowBaselineAlign);
String linkCtx = isBaseline ? "baseline" : null;
// Find a group with same link context and put it in that group.
boolean foundList = false;
for (int glIx = 0, lastGl = groupList.size() - 1; glIx <= lastGl; glIx++) {
LinkedDimGroup group = groupList.get(glIx);
if (group.linkCtx == linkCtx || linkCtx != null && linkCtx.equals(group.linkCtx)) {
group.addCompWrap(cw);
foundList = true;
break;
}
}
// If none found and at last add a new group.
if (foundList == false) {
int linkType = isBaseline ? LinkedDimGroup.TYPE_BASELINE : LinkedDimGroup.TYPE_PARALLEL;
LinkedDimGroup lg = new LinkedDimGroup(linkCtx, 1, linkType, !isRows, fromEnd);
lg.addCompWrap(cw);
groupList.add(lg);
}
}
}
}
}
return groupLists;
}
/** Spanning is specified in the uncompressed grid number. They can for instance be more than 60000 for the outer
* edge dock grid cells. When the grid is compressed and indexed after only the cells that area occupied the span
* is erratic. This method use the row/col indexes and corrects the span to be correct for the compressed grid.
* @param span The span in the uncompressed grid. LayoutUtil.INF will be interpreted to span the rest
* of the column/row excluding the surrounding docking components.
* @param indexes The indexes in the correct dimension.
* @return The converted span.
*/
private static int convertSpanToSparseGrid(int curIx, int span, TreeSet indexes)
{
int lastIx = curIx + span;
int retSpan = 1;
for (Integer ix : indexes) {
if (ix <= curIx)
continue; // We have not arrived to the correct index yet
if (ix >= lastIx)
break;
retSpan++;
}
return retSpan;
}
private boolean isCellFree(int r, int c, ArrayList occupiedRects)
{
if (getCell(r, c) != null)
return false;
for (int[] rect : occupiedRects) {
if (rect[0] <= c && rect[1] <= r && rect[0] + rect[2] > c && rect[1] + rect[3] > r)
return false;
}
return true;
}
private Cell getCell(int r, int c)
{
return grid.get(Integer.valueOf((r << 16) + (c & 0xffff)));
}
private void setCell(int r, int c, Cell cell)
{
if (c < 0 || r < 0)
throw new IllegalArgumentException("Cell position cannot be negative. row: " + r + ", col: " + c);
if (c > MAX_GRID || r > MAX_GRID)
throw new IllegalArgumentException("Cell position out of bounds. Out of cells. row: " + r + ", col: " + c);
rowIndexes.add(r);
colIndexes.add(c);
grid.put((r << 16) + (c & 0xffff), cell);
}
/** Adds a docking cell. That cell is outside the normal cell indexes.
* @param dockInsets The current dock insets. Will be updated!
* @param side top == 0, left == 1, bottom = 2, right = 3.
* @param cw The compwrap to put in a cell and add.
*/
private void addDockingCell(int[] dockInsets, int side, CompWrap cw)
{
int r, c, spanx = 1, spany = 1;
switch (side) {
case 0:
case 2:
r = side == 0 ? dockInsets[0]++ : dockInsets[2]--;
c = dockInsets[1];
spanx = dockInsets[3] - dockInsets[1] + 1; // The +1 is for cell 0.
colIndexes.add(dockInsets[3]); // Make sure there is a receiving cell
break;
case 1:
case 3:
c = side == 1 ? dockInsets[1]++ : dockInsets[3]--;
r = dockInsets[0];
spany = dockInsets[2] - dockInsets[0] + 1; // The +1 is for cell 0.
rowIndexes.add(dockInsets[2]); // Make sure there is a receiving cell
break;
default:
throw new IllegalArgumentException("Internal error 123.");
}
rowIndexes.add(r);
colIndexes.add(c);
grid.put((r << 16) + (c & 0xffff), new Cell(cw, spanx, spany, spanx > 1));
}
/** A simple representation of a cell in the grid. Contains a number of component wraps, if they span more than one cell.
*/
private static class Cell
{
private final int spanx, spany;
private final boolean flowx;
private final ArrayList compWraps = new ArrayList(2);
private boolean hasTagged = false; // If one or more components have styles and need to be checked by the component sorter
private Cell(CompWrap cw)
{
this(cw, 1, 1, true);
}
private Cell(int spanx, int spany, boolean flowx)
{
this(null, spanx, spany, flowx);
}
private Cell(CompWrap cw, int spanx, int spany, boolean flowx)
{
if (cw != null)
compWraps.add(cw);
this.spanx = spanx;
this.spany = spany;
this.flowx = flowx;
}
}
/** A number of component wraps that share a layout "something" in one dimension
*/
private static class LinkedDimGroup
{
private static final int TYPE_SERIAL = 0;
private static final int TYPE_PARALLEL = 1;
private static final int TYPE_BASELINE = 2;
private final String linkCtx;
private final int span;
private final int linkType;
private final boolean isHor, fromEnd;
private final ArrayList _compWraps = new ArrayList(4);
private int lStart = 0, lSize = 0; // Currently mostly for debug painting
private LinkedDimGroup(String linkCtx, int span, int linkType, boolean isHor, boolean fromEnd)
{
this.linkCtx = linkCtx;
this.span = span;
this.linkType = linkType;
this.isHor = isHor;
this.fromEnd = fromEnd;
}
private void addCompWrap(CompWrap cw)
{
_compWraps.add(cw);
}
private void setCompWraps(ArrayList cws)
{
if (_compWraps != cws) {
_compWraps.clear();
_compWraps.addAll(cws);
}
}
private void layout(DimConstraint dc, int start, int size, int spanCount)
{
lStart = start;
lSize = size;
if (_compWraps.isEmpty())
return;
ContainerWrapper parent = _compWraps.get(0).comp.getParent();
if (linkType == TYPE_PARALLEL) {
layoutParallel(parent, _compWraps, dc, start, size, isHor, fromEnd);
} else if (linkType == TYPE_BASELINE) {
layoutBaseline(parent, _compWraps, dc, start, size, LayoutUtil.PREF, spanCount);
} else {
layoutSerial(parent, _compWraps, dc, start, size, isHor, spanCount, fromEnd);
}
}
/** Returns the min/pref/max sizes for this cell. Returned array must not be altered
* @return A shared min/pref/max array of sizes. Always of length 3 and never null . Will always be of type STATIC and PIXEL.
*/
private int[] getMinPrefMax()
{
int[] sizes = new int[3];
if (!_compWraps.isEmpty()) {
for (int sType = LayoutUtil.MIN; sType <= LayoutUtil.PREF; sType++) {
if (linkType == TYPE_PARALLEL) {
sizes[sType] = getTotalSizeParallel(_compWraps, sType, isHor);
} else if (linkType == TYPE_BASELINE) {
int[] aboveBelow = getBaselineAboveBelow(_compWraps, sType, false);
sizes[sType] = aboveBelow[0] + aboveBelow[1];
} else {
sizes[sType] = getTotalSizeSerial(_compWraps, sType, isHor);
}
}
sizes[LayoutUtil.MAX] = LayoutUtil.INF;
}
return sizes;
}
}
/** Wraps a {@link java.awt.Component} together with its constraint. Caches a lot of information about the component so
* for instance not the preferred size has to be calculated more than once.
*
* Note! Does not ask the min/pref/max sizes again after the constructor. This means that
*/
private final class CompWrap
{
private final ComponentWrapper comp;
private final CC cc;
private final int eHideMode;
private final boolean useVisualPadding;
private boolean sizesOk = false;
private boolean isAbsolute;
private int[][] gaps; // [top,left(actually before),bottom,right(actually after)][min,pref,max]
private final int[] horSizes = new int[3];
private final int[] verSizes = new int[3];
private int x = LayoutUtil.NOT_SET, y = LayoutUtil.NOT_SET, w = LayoutUtil.NOT_SET, h = LayoutUtil.NOT_SET;
private int forcedPushGaps = 0; // 1 == before, 2 = after. Bitwise.
/**
* @param c
* @param cc
* @param eHideMode Effective hide mode. <= 0 means visible.
* @param useVisualPadding
*/
private CompWrap(ComponentWrapper c, CC cc, int eHideMode, boolean useVisualPadding)
{
this.comp = c;
this.cc = cc;
this.eHideMode = eHideMode;
this.useVisualPadding = useVisualPadding;
this.isAbsolute = cc.getHorizontal().getSize().isAbsolute() && cc.getVertical().getSize().isAbsolute();
if (eHideMode > 1) {
gaps = new int[4][];
for (int i = 0; i < gaps.length; i++)
gaps[i] = new int[3];
}
}
private int[] getSizes(boolean isHor)
{
validateSize();
return isHor ? horSizes : verSizes;
}
private void validateSize()
{
BoundSize[] callbackSz = getCallbackSize(comp);
if (isAbsolute && sizesOk && callbackSz == null)
return;
if (eHideMode <= 0) {
int contentBias = comp.getContentBias();
int sizeHint = contentBias == -1 ? -1 : (contentBias == 0 ? (w != LayoutUtil.NOT_SET ? w : comp.getWidth()) : (h != LayoutUtil.NOT_SET ? h : comp.getHeight()));
BoundSize hBS = (callbackSz != null && callbackSz[0] != null) ? callbackSz[0] : cc.getHorizontal().getSize();
BoundSize vBS = (callbackSz != null && callbackSz[1] != null) ? callbackSz[1] : cc.getVertical().getSize();
for (int i = LayoutUtil.MIN; i <= LayoutUtil.MAX; i++) {
switch (contentBias) {
case -1: // None
default:
horSizes[i] = getSize(hBS, i, true, useVisualPadding, -1);
verSizes[i] = getSize(vBS, i, false, useVisualPadding, -1);
break;
case 0: // Hor
horSizes[i] = getSize(hBS, i, true, useVisualPadding, -1);
verSizes[i] = getSize(vBS, i, false, useVisualPadding, sizeHint > 0 ? sizeHint : horSizes[i]);
break;
case 1: // Ver
verSizes[i] = getSize(vBS, i, false, useVisualPadding, -1);
horSizes[i] = getSize(hBS, i, true, useVisualPadding, sizeHint > 0 ? sizeHint : verSizes[i]);
break;
}
}
correctMinMax(horSizes);
correctMinMax(verSizes);
} else {
Arrays.fill(horSizes, 0); // Needed if component goes from visible -> invisible without recreating the grid.
Arrays.fill(verSizes, 0);
}
sizesOk = true;
}
private int getSize(BoundSize uvs, int sizeType, boolean isHor, boolean useVP, int sizeHint)
{
int size;
if (uvs == null || uvs.getSize(sizeType) == null) {
switch(sizeType) {
case LayoutUtil.MIN:
size = isHor ? comp.getMinimumWidth(sizeHint) : comp.getMinimumHeight(sizeHint);
break;
case LayoutUtil.PREF:
size = isHor ? comp.getPreferredWidth(sizeHint) : comp.getPreferredHeight(sizeHint);
break;
default:
size = isHor ? comp.getMaximumWidth(sizeHint) : comp.getMaximumHeight(sizeHint);
break;
}
if (useVP) {
//Do not include visual padding when calculating layout
int[] visualPadding = comp.getVisualPadding();
// Assume visualPadding is of length 4: top, left, bottom, right
if (visualPadding != null && visualPadding.length > 0)
size -= isHor ? (visualPadding[1] + visualPadding[3]) : (visualPadding[0] + visualPadding[2]);
}
} else {
ContainerWrapper par = comp.getParent();
float refValue = isHor ? par.getWidth() : par.getHeight();
size = uvs.getSize(sizeType).getPixels(refValue, par, comp);
}
return size;
}
private void calcGaps(ComponentWrapper before, CC befCC, ComponentWrapper after, CC aftCC, String tag, boolean flowX, boolean isLTR)
{
ContainerWrapper par = comp.getParent();
int parW = par.getWidth();
int parH = par.getHeight();
BoundSize befGap = before != null ? (flowX ? befCC.getHorizontal() : befCC.getVertical()).getGapAfter() : null;
BoundSize aftGap = after != null ? (flowX ? aftCC.getHorizontal() : aftCC.getVertical()).getGapBefore() : null;
mergeGapSizes(cc.getVertical().getComponentGaps(par, comp, befGap, (flowX ? null : before), tag, parH, 0, isLTR), false, true);
mergeGapSizes(cc.getHorizontal().getComponentGaps(par, comp, befGap, (flowX ? before : null), tag, parW, 1, isLTR), true, true);
mergeGapSizes(cc.getVertical().getComponentGaps(par, comp, aftGap, (flowX ? null : after), tag, parH, 2, isLTR), false, false);
mergeGapSizes(cc.getHorizontal().getComponentGaps(par, comp, aftGap, (flowX ? after : null), tag, parW, 3, isLTR), true, false);
}
private void setDimBounds(int start, int size, boolean isHor)
{
if (isHor) {
if (start != x || w != size) {
x = start;
w = size;
if (comp.getContentBias() == LayoutUtil.HORIZONTAL)
invalidateSizes(); // Only for components that have a bias the sizes will have changed.
}
} else {
if (start != y || h != size) {
y = start;
h = size;
if (comp.getContentBias() == LayoutUtil.VERTICAL)
invalidateSizes(); // Only for components that have a bias the sizes will have changed.
}
}
}
void invalidateSizes()
{
sizesOk = false;
}
private boolean isPushGap(boolean isHor, boolean isBefore)
{
if (isHor && ((isBefore ? 1 : 2) & forcedPushGaps) != 0)
return true; // Forced
DimConstraint dc = cc.getDimConstraint(isHor);
BoundSize s = isBefore ? dc.getGapBefore() : dc.getGapAfter();
return s != null && s.getGapPush();
}
/** Transfers the bounds to the component
*/
private void transferBounds(boolean addVisualPadding)
{
if (cc.isExternal())
return;
int compX = x;
int compY = y;
int compW = w;
int compH = h;
if (addVisualPadding) {
//Add the visual padding back to the component when changing its size
int[] visualPadding = comp.getVisualPadding();
if (visualPadding != null) {
//assume visualPadding is of length 4: top, left, bottom, right
compX -= visualPadding[1];
compY -= visualPadding[0];
compW += (visualPadding[1] + visualPadding[3]);
compH += (visualPadding[0] + visualPadding[2]);
}
}
comp.setBounds(compX, compY, compW, compH);
}
private void setForcedSizes(int[] sizes, boolean isHor)
{
if (sizes == null)
return;
System.arraycopy(sizes, 0, getSizes(isHor), 0, 3);
sizesOk = true;
}
private void setGaps(int[] minPrefMax, int ix)
{
if (gaps == null)
gaps = new int[][] {null, null, null, null};
gaps[ix] = minPrefMax;
}
private void mergeGapSizes(int[] sizes, boolean isHor, boolean isTL)
{
if (gaps == null)
gaps = new int[][] {null, null, null, null};
if (sizes == null)
return;
int gapIX = getGapIx(isHor, isTL);
int[] oldGaps = gaps[gapIX];
if (oldGaps == null) {
oldGaps = new int[] {0, 0, LayoutUtil.INF};
gaps[gapIX] = oldGaps;
}
oldGaps[LayoutUtil.MIN] = Math.max(sizes[LayoutUtil.MIN], oldGaps[LayoutUtil.MIN]);
oldGaps[LayoutUtil.PREF] = Math.max(sizes[LayoutUtil.PREF], oldGaps[LayoutUtil.PREF]);
oldGaps[LayoutUtil.MAX] = Math.min(sizes[LayoutUtil.MAX], oldGaps[LayoutUtil.MAX]);
}
private int getGapIx(boolean isHor, boolean isTL)
{
return isHor ? (isTL ? 1 : 3) : (isTL ? 0 : 2);
}
private int getSizeInclGaps(int sizeType, boolean isHor)
{
return filter(sizeType, getGapBefore(sizeType, isHor) + getSize(sizeType, isHor) + getGapAfter(sizeType, isHor));
}
private int getSize(int sizeType, boolean isHor)
{
return filter(sizeType, getSizes(isHor)[sizeType]);
}
private int getGapBefore(int sizeType, boolean isHor)
{
int[] gaps = getGaps(isHor, true);
return gaps != null ? filter(sizeType, gaps[sizeType]) : 0;
}
private int getGapAfter(int sizeType, boolean isHor)
{
int[] gaps = getGaps(isHor, false);
return gaps != null ? filter(sizeType, gaps[sizeType]) : 0;
}
private int[] getGaps(boolean isHor, boolean isTL)
{
return gaps[getGapIx(isHor, isTL)];
}
private int filter(int sizeType, int size)
{
if (size == LayoutUtil.NOT_SET)
return sizeType != LayoutUtil.MAX ? 0 : LayoutUtil.INF;
return constrainSize(size);
}
private boolean isBaselineAlign(boolean defValue)
{
Float g = cc.getVertical().getGrow();
if (g != null && g.intValue() != 0)
return false;
UnitValue al = cc.getVertical().getAlign();
return (al != null ? al == UnitValue.BASELINE_IDENTITY : defValue) && comp.hasBaseline();
}
private int getBaseline(int sizeType)
{
return comp.getBaseline(getSize(sizeType, true), getSize(sizeType, false));
}
public void adjustMinHorSizeUp(int minSize)
{
int[] sz = getSizes(true);
if (sz[LayoutUtil.MIN] < minSize)
sz[LayoutUtil.MIN] = minSize;
correctMinMax(sz);
}
}
//***************************************************************************************
//* Helper Methods
//***************************************************************************************
private static void layoutBaseline(ContainerWrapper parent, ArrayList compWraps, DimConstraint dc, int start, int size, int sizeType, int spanCount)
{
int[] aboveBelow = getBaselineAboveBelow(compWraps, sizeType, true);
int blRowSize = aboveBelow[0] + aboveBelow[1];
CC cc = compWraps.get(0).cc;
// Align for the whole baseline component array
UnitValue align = cc.getVertical().getAlign();
if (spanCount == 1 && align == null)
align = dc.getAlignOrDefault(false);
if (align == UnitValue.BASELINE_IDENTITY)
align = UnitValue.CENTER;
int offset = start + aboveBelow[0] + (align != null ? Math.max(0, align.getPixels(size - blRowSize, parent, null)) : 0);
for (CompWrap cw : compWraps) {
cw.y += offset;
if (cw.y + cw.h > start + size)
cw.h = start + size - cw.y;
}
}
private static void layoutSerial(ContainerWrapper parent, ArrayList compWraps, DimConstraint dc, int start, int size, boolean isHor, int spanCount, boolean fromEnd)
{
FlowSizeSpec fss = mergeSizesGapsAndResConstrs(
getComponentResizeConstraints(compWraps, isHor),
getComponentGapPush(compWraps, isHor),
getComponentSizes(compWraps, isHor),
getGaps(compWraps, isHor));
Float[] pushW = dc.isFill() ? GROW_100 : null;
int[] sizes = LayoutUtil.calculateSerial(fss.sizes, fss.resConstsInclGaps, pushW, LayoutUtil.PREF, size);
setCompWrapBounds(parent, sizes, compWraps, dc.getAlignOrDefault(isHor), start, size, isHor, fromEnd);
}
private static void setCompWrapBounds(ContainerWrapper parent, int[] allSizes, ArrayList compWraps, UnitValue rowAlign, int start, int size, boolean isHor, boolean fromEnd)
{
int totSize = LayoutUtil.sum(allSizes);
CC cc = compWraps.get(0).cc;
UnitValue align = correctAlign(cc, rowAlign, isHor, fromEnd);
int cSt = start;
int slack = size - totSize;
if (slack > 0 && align != null) {
int al = Math.min(slack, Math.max(0, align.getPixels(slack, parent, null)));
cSt += (fromEnd ? -al : al);
}
for (int i = 0, bIx = 0, iSz = compWraps.size(); i < iSz; i++) {
CompWrap cw = compWraps.get(i);
if (fromEnd ) {
cSt -= allSizes[bIx++];
cw.setDimBounds(cSt - allSizes[bIx], allSizes[bIx], isHor);
cSt -= allSizes[bIx++];
} else {
cSt += allSizes[bIx++];
cw.setDimBounds(cSt, allSizes[bIx], isHor);
cSt += allSizes[bIx++];
}
}
}
private static void layoutParallel(ContainerWrapper parent, ArrayList compWraps, DimConstraint dc, int start, int size, boolean isHor, boolean fromEnd)
{
int[][] sizes = new int[compWraps.size()][]; // [compIx][gapBef,compSize,gapAft]
for (int i = 0; i < sizes.length; i++) {
CompWrap cw = compWraps.get(i);
DimConstraint cDc = cw.cc.getDimConstraint(isHor);
ResizeConstraint[] resConstr = new ResizeConstraint[] {
cw.isPushGap(isHor, true) ? GAP_RC_CONST_PUSH : GAP_RC_CONST,
cDc.resize,
cw.isPushGap(isHor, false) ? GAP_RC_CONST_PUSH : GAP_RC_CONST,
};
int[][] sz = new int[][] {
cw.getGaps(isHor, true), cw.getSizes(isHor), cw.getGaps(isHor, false)
};
Float[] pushW = dc.isFill() ? GROW_100 : null;
sizes[i] = LayoutUtil.calculateSerial(sz, resConstr, pushW, LayoutUtil.PREF, size);
}
UnitValue rowAlign = dc.getAlignOrDefault(isHor);
setCompWrapBounds(parent, sizes, compWraps, rowAlign, start, size, isHor, fromEnd);
}
private static void setCompWrapBounds(ContainerWrapper parent, int[][] sizes, ArrayList compWraps, UnitValue rowAlign, int start, int size, boolean isHor, boolean fromEnd)
{
for (int i = 0; i < sizes.length; i++) {
CompWrap cw = compWraps.get(i);
UnitValue align = correctAlign(cw.cc, rowAlign, isHor, fromEnd);
int[] cSizes = sizes[i];
int gapBef = cSizes[0];
int cSize = cSizes[1]; // No Math.min(size, cSizes[1]) here!
int gapAft = cSizes[2];
int cSt = fromEnd ? start - gapBef : start + gapBef;
int slack = size - cSize - gapBef - gapAft;
if (slack > 0 && align != null) {
int al = Math.min(slack, Math.max(0, align.getPixels(slack, parent, null)));
cSt += (fromEnd ? -al : al);
}
cw.setDimBounds(fromEnd ? cSt - cSize : cSt, cSize, isHor);
}
}
private static UnitValue correctAlign(CC cc, UnitValue rowAlign, boolean isHor, boolean fromEnd)
{
UnitValue align = (isHor ? cc.getHorizontal() : cc.getVertical()).getAlign();
if (align == null)
align = rowAlign;
if (align == UnitValue.BASELINE_IDENTITY)
align = UnitValue.CENTER;
if (fromEnd) {
if (align == UnitValue.LEFT)
align = UnitValue.RIGHT;
else if (align == UnitValue.RIGHT)
align = UnitValue.LEFT;
}
return align;
}
private static int[] getBaselineAboveBelow(ArrayList compWraps, int sType, boolean centerBaseline)
{
int maxAbove = Integer.MIN_VALUE;
int maxBelow = Integer.MIN_VALUE;
for (CompWrap cw : compWraps) {
int height = cw.getSize(sType, false);
if (height >= LayoutUtil.INF)
return new int[]{LayoutUtil.INF / 2, LayoutUtil.INF / 2};
int baseline = cw.getBaseline(sType);
int above = baseline + cw.getGapBefore(sType, false);
maxAbove = Math.max(above, maxAbove);
maxBelow = Math.max(height - baseline + cw.getGapAfter(sType, false), maxBelow);
if (centerBaseline)
cw.setDimBounds(-baseline, height, false);
}
return new int[] {maxAbove, maxBelow};
}
private static int getTotalSizeParallel(ArrayList compWraps, int sType, boolean isHor)
{
int size = sType == LayoutUtil.MAX ? LayoutUtil.INF : 0;
for (CompWrap cw : compWraps) {
int cwSize = cw.getSizeInclGaps(sType, isHor);
if (cwSize >= LayoutUtil.INF)
return LayoutUtil.INF;
if (sType == LayoutUtil.MAX ? cwSize < size : cwSize > size)
size = cwSize;
}
return constrainSize(size);
}
private static int getTotalSizeSerial(ArrayList compWraps, int sType, boolean isHor)
{
int totSize = 0;
for (int i = 0, iSz = compWraps.size(), lastGapAfter = 0; i < iSz; i++) {
CompWrap wrap = compWraps.get(i);
int gapBef = wrap.getGapBefore(sType, isHor);
if (gapBef > lastGapAfter)
totSize += gapBef - lastGapAfter;
totSize += wrap.getSize(sType, isHor);
totSize += (lastGapAfter = wrap.getGapAfter(sType, isHor));
if (totSize >= LayoutUtil.INF)
return LayoutUtil.INF;
}
return constrainSize(totSize);
}
private static int getTotalGroupsSizeParallel(ArrayList groups, int sType, boolean countSpanning)
{
int size = sType == LayoutUtil.MAX ? LayoutUtil.INF : 0;
for (LinkedDimGroup group : groups) {
if (countSpanning || group.span == 1) {
int grpSize = group.getMinPrefMax()[sType];
if (grpSize >= LayoutUtil.INF)
return LayoutUtil.INF;
if (sType == LayoutUtil.MAX ? grpSize < size : grpSize > size)
size = grpSize;
}
}
return constrainSize(size);
}
/**
* @param compWraps
* @param isHor
* @return Might contain LayoutUtil.NOT_SET
*/
private static int[][] getComponentSizes(ArrayList compWraps, boolean isHor)
{
int[][] compSizes = new int[compWraps.size()][];
for (int i = 0; i < compSizes.length; i++)
compSizes[i] = compWraps.get(i).getSizes(isHor);
return compSizes;
}
/** Merges sizes and gaps together with Resize Constraints. For gaps {@link #GAP_RC_CONST} is used.
* @param resConstr One resize constraint for every row/component. Can be lesser in length and the last element should be used for missing elements.
* @param gapPush If the corresponding gap should be considered pushing and thus want to take free space if left over. Should be one more than resConstrs!
* @param minPrefMaxSizes The sizes (min/pref/max) for every row/component.
* @param gapSizes The gaps before and after each row/component packed in one double sized array.
* @return A holder for the merged values.
*/
private static FlowSizeSpec mergeSizesGapsAndResConstrs(ResizeConstraint[] resConstr, boolean[] gapPush, int[][] minPrefMaxSizes, int[][] gapSizes)
{
int[][] sizes = new int[(minPrefMaxSizes.length << 1) + 1][]; // Make room for gaps around.
ResizeConstraint[] resConstsInclGaps = new ResizeConstraint[sizes.length];
sizes[0] = gapSizes[0];
for (int i = 0, crIx = 1; i < minPrefMaxSizes.length; i++, crIx += 2) {
// Component bounds and constraints
resConstsInclGaps[crIx] = resConstr[i];
sizes[crIx] = minPrefMaxSizes[i];
sizes[crIx + 1] = gapSizes[i + 1];
if (sizes[crIx - 1] != null)
resConstsInclGaps[crIx - 1] = gapPush[i < gapPush.length ? i : gapPush.length - 1] ? GAP_RC_CONST_PUSH : GAP_RC_CONST;
if (i == (minPrefMaxSizes.length - 1) && sizes[crIx + 1] != null)
resConstsInclGaps[crIx + 1] = gapPush[(i + 1) < gapPush.length ? (i + 1) : gapPush.length - 1] ? GAP_RC_CONST_PUSH : GAP_RC_CONST;
}
// Check for null and set it to 0, 0, 0.
for (int i = 0; i < sizes.length; i++) {
if (sizes[i] == null)
sizes[i] = new int[3];
}
return new FlowSizeSpec(sizes, resConstsInclGaps);
}
private static int[] mergeSizes(int[] oldValues, int[] newValues)
{
if (oldValues == null)
return newValues;
if (newValues == null)
return oldValues;
int[] ret = new int[oldValues.length];
for (int i = 0; i < ret.length; i++)
ret[i] = mergeSizes(oldValues[i], newValues[i], true);
return ret;
}
private static int mergeSizes(int oldValue, int newValue, boolean toMax)
{
if (oldValue == LayoutUtil.NOT_SET || oldValue == newValue)
return newValue;
if (newValue == LayoutUtil.NOT_SET)
return oldValue;
return toMax != oldValue > newValue ? newValue : oldValue;
}
private static int constrainSize(int s)
{
return s > 0 ? (s < LayoutUtil.INF ? s : LayoutUtil.INF) : 0;
}
private static void correctMinMax(int s[])
{
if (s[LayoutUtil.MIN] > s[LayoutUtil.MAX])
s[LayoutUtil.MIN] = s[LayoutUtil.MAX]; // Since MAX is almost always explicitly set use that
if (s[LayoutUtil.PREF] < s[LayoutUtil.MIN])
s[LayoutUtil.PREF] = s[LayoutUtil.MIN];
if (s[LayoutUtil.PREF] > s[LayoutUtil.MAX])
s[LayoutUtil.PREF] = s[LayoutUtil.MAX];
}
private static final class FlowSizeSpec
{
private final int[][] sizes; // [row/col index][min, pref, max]
private final ResizeConstraint[] resConstsInclGaps; // [row/col index]
private FlowSizeSpec(int[][] sizes, ResizeConstraint[] resConstsInclGaps)
{
this.sizes = sizes;
this.resConstsInclGaps = resConstsInclGaps;
}
/**
* @param specs The specs for the columns or rows. Last index will be used of fromIx + len is greater than this array's length.
* @param targetSize The size to try to meet.
* @param defGrow The default grow weight if the specs does not have anyone that will grow. Comes from "push" in the CC.
* @param fromIx
* @param len
* @param sizeType
* @param eagerness How eager the algorithm should be to try to expand the sizes.
* |
* 0 - Grow only rows/columns which have the sizeType
set to be the containing components AND which has a grow weight > 0.
* 1 - Grow only rows/columns which have the sizeType
set to be the containing components AND which has a grow weight > 0 OR unspecified.
* 2 - Grow all rows/columns that have a grow weight > 0.
* 3 - Grow all rows/columns that have a grow weight > 0 OR unspecified.
*
* @return The new size.
*/
private int expandSizes(DimConstraint[] specs, Float[] defGrow, int targetSize, int fromIx, int len, int sizeType, int eagerness)
{
ResizeConstraint[] resConstr = new ResizeConstraint[len];
int[][] sizesToExpand = new int[len][];
for (int i = 0; i < len; i++) {
int[] minPrefMax = sizes[i + fromIx];
sizesToExpand[i] = new int[] {minPrefMax[sizeType], minPrefMax[LayoutUtil.PREF], minPrefMax[LayoutUtil.MAX]};
if (eagerness <= 1 && i % 2 == 0) { // (i % 2 == 0) means only odd indexes, which is only rows/col indexes and not gaps.
int cIx = (i + fromIx - 1) >> 1;
DimConstraint spec = (DimConstraint) LayoutUtil.getIndexSafe(specs, cIx);
BoundSize sz = spec.getSize();
if ( (sizeType == LayoutUtil.MIN && sz.getMin() != null && sz.getMin().getUnit() != UnitValue.MIN_SIZE) ||
(sizeType == LayoutUtil.PREF && sz.getPreferred() != null && sz.getPreferred().getUnit() != UnitValue.PREF_SIZE)) {
continue;
}
}
resConstr[i] = (ResizeConstraint) LayoutUtil.getIndexSafe(resConstsInclGaps, i + fromIx);
}
Float[] growW = (eagerness == 1 || eagerness == 3) ? extractSubArray(specs, defGrow, fromIx, len): null;
int[] newSizes = LayoutUtil.calculateSerial(sizesToExpand, resConstr, growW, LayoutUtil.PREF, targetSize);
int newSize = 0;
for (int i = 0; i < len; i++) {
int s = newSizes[i];
sizes[i + fromIx][sizeType] = s;
newSize += s;
}
return newSize;
}
}
private static Float[] extractSubArray(DimConstraint[] specs, Float[] arr, int ix, int len)
{
if (arr == null || arr.length < ix + len) {
Float[] growLastArr = new Float[len];
// Handle a group where some rows (first one/few and/or last one/few) are docks.
for (int i = ix + len - 1; i >= 0; i -= 2) {
int specIx = (i >> 1);
if (specs[specIx] != DOCK_DIM_CONSTRAINT) {
growLastArr[i - ix] = ResizeConstraint.WEIGHT_100;
return growLastArr;
}
}
return growLastArr;
}
Float[] newArr = new Float[len];
for (int i = 0; i < len; i++)
newArr[i] = arr[ix + i];
return newArr;
}
private static WeakHashMap[] PARENT_ROWCOL_SIZES_MAP = null;
@SuppressWarnings( "unchecked" )
private static synchronized void putSizesAndIndexes(Object parComp, int[] sizes, int[] ixArr, boolean isRows)
{
if (PARENT_ROWCOL_SIZES_MAP == null) // Lazy since only if designing in IDEs
PARENT_ROWCOL_SIZES_MAP = new WeakHashMap[] {new WeakHashMap(4), new WeakHashMap(4)};
PARENT_ROWCOL_SIZES_MAP[isRows ? 0 : 1].put(parComp, new int[][]{ixArr, sizes});
}
static synchronized int[][] getSizesAndIndexes(Object parComp, boolean isRows)
{
if (PARENT_ROWCOL_SIZES_MAP == null)
return null;
return PARENT_ROWCOL_SIZES_MAP[isRows ? 0 : 1].get(parComp);
}
private static WeakHashMap> PARENT_GRIDPOS_MAP = null;
private static synchronized void saveGrid(ComponentWrapper parComp, LinkedHashMap grid)
{
if (PARENT_GRIDPOS_MAP == null) // Lazy since only if designing in IDEs
PARENT_GRIDPOS_MAP = new WeakHashMap>(4);
ArrayList weakCells = new ArrayList(grid.size());
for (Map.Entry e : grid.entrySet()) {
Cell cell = e.getValue();
Integer xyInt = e.getKey();
if (xyInt != null) {
int x = (xyInt << 16) >> 16;
int y = xyInt >> 16;
for (CompWrap cw : cell.compWraps)
weakCells.add(new WeakCell(cw.comp.getComponent(), x, y, cell.spanx, cell.spany));
}
}
PARENT_GRIDPOS_MAP.put(parComp.getComponent(), weakCells);
}
static synchronized HashMap getGridPositions(Object parComp)
{
ArrayList weakCells = PARENT_GRIDPOS_MAP != null ? PARENT_GRIDPOS_MAP.get(parComp) : null;
if (weakCells == null)
return null;
HashMap retMap = new HashMap();
for (WeakCell wc : weakCells) {
Object component = wc.componentRef.get();
if (component != null)
retMap.put(component, new int[] {wc.x, wc.y, wc.spanX, wc.spanY});
}
return retMap;
}
private static class WeakCell
{
private final WeakReference componentRef;
private final int x, y, spanX, spanY;
private WeakCell(Object component, int x, int y, int spanX, int spanY)
{
this.componentRef = new WeakReference(component);
this.x = x;
this.y = y;
this.spanX = spanX;
this.spanY = spanY;
}
}
}
miglayout-5.1/core/src/main/java/net/miginfocom/layout/InCellGapProvider.java000077500000000000000000000066221324101563200273710ustar00rootroot00000000000000package net.miginfocom.layout;
/*
* License (BSD):
* ==============
*
* Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
* 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 the MiG InfoCom AB nor 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.
*
* @version 1.0
* @author Mikael Grev, MiG InfoCom AB
* Date: 2006-sep-08
*/
/** An interface to implement if you want to decide the gaps between two types of components within the same cell.
*
* E.g.:
*
*
* {@code
* if (adjacentComp == null || adjacentSide == SwingConstants.LEFT || adjacentSide == SwingConstants.TOP)
* return null;
*
* boolean isHor = (adjacentSide == SwingConstants.LEFT || adjacentSide == SwingConstants.RIGHT);
*
* if (adjacentComp.getComponentType(false) == ComponentWrapper.TYPE_LABEL && comp.getComponentType(false) == ComponentWrapper.TYPE_TEXT_FIELD)
* return isHor ? UNRELATED_Y : UNRELATED_Y;
*
* return (adjacentSide == SwingConstants.LEFT || adjacentSide == SwingConstants.RIGHT) ? RELATED_X : RELATED_Y;
* }
*
*/
public interface InCellGapProvider
{
/** Returns the default gap between two components that are in the same cell .
* @param comp The component that the gap is for. Never null
.
* @param adjacentComp The adjacent component if any. May be null
.
* @param adjacentSide What side the adjacentComp
is on. {@link javax.swing.SwingUtilities#TOP} or
* {@link javax.swing.SwingUtilities#LEFT} or {@link javax.swing.SwingUtilities#BOTTOM} or {@link javax.swing.SwingUtilities#RIGHT}.
* @param tag The tag string that the component might be tagged with in the component constraints. May be null
.
* @param isLTR If it is left-to-right.
* @return The default gap between two components or null
if there should be no gap.
*/
public abstract BoundSize getDefaultGap(ComponentWrapper comp, ComponentWrapper adjacentComp, int adjacentSide, String tag, boolean isLTR);
}
miglayout-5.1/core/src/main/java/net/miginfocom/layout/LC.java000077500000000000000000001360021324101563200243520ustar00rootroot00000000000000package net.miginfocom.layout;
import java.io.*;
/*
* License (BSD):
* ==============
*
* Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
* 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 the MiG InfoCom AB nor 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.
*
* @version 1.0
* @author Mikael Grev, MiG InfoCom AB
* Date: 2006-sep-08
*/
/** Contains the constraints for an instance of the {@link LC} layout manager.
*/
public final class LC implements Externalizable
{
// See the corresponding set/get method for documentation of the property!
private int wrapAfter = LayoutUtil.INF;
private Boolean leftToRight = null;
private UnitValue[] insets = null; // Never null elements but if unset array is null
private UnitValue alignX = null, alignY = null;
private BoundSize gridGapX = null, gridGapY = null;
private BoundSize width = BoundSize.NULL_SIZE, height = BoundSize.NULL_SIZE;
private BoundSize packW = BoundSize.NULL_SIZE, packH = BoundSize.NULL_SIZE;
private float pwAlign = 0.5f, phAlign = 1.0f;
private int debugMillis = 0;
private int hideMode = 0;
private boolean noCache = false;
private boolean flowX = true;
private boolean fillX = false, fillY = false;
private boolean topToBottom = true;
private boolean noGrid = false;
private boolean visualPadding = true;
/** Empty constructor.
*/
public LC()
{
}
// ************************************************************************
// * JavaBean get/set methods.
// ************************************************************************
/** If components have sizes or positions linked to the bounds of the parent in some way (as for instance the "%"
unit has) the cache
* must be turned off for the panel. If components does not get the correct or expected size or position try to set this property to true
.
* @return true
means no cache and slightly slower layout.
*/
public boolean isNoCache()
{
return noCache;
}
/** If components have sizes or positions linked to the bounds of the parent in some way (as for instance the "%"
unit has) the cache
* must be turned off for the panel. If components does not get the correct or expected size or position try to set this property to true
.
* @param b true
means no cache and slightly slower layout.
*/
public void setNoCache(boolean b)
{
this.noCache = b;
}
/** If the laid out components' bounds in total is less than the final size of the container these align values will be used to align the components
* in the parent. null
is default and that means top/left alignment. The relative distances between the components will not be affected
* by this property.
* @return The current alignment.
*/
public final UnitValue getAlignX()
{
return alignX;
}
/** If the laid out components' bounds in total is less than the final size of the container these align values will be used to align the components
* in the parent. null
is default and that means top/left alignment. The relative distances between the components will not be affected
* by this property.
* @param uv The new alignment. Use {@link ConstraintParser#parseAlignKeywords(String, boolean)} to create the {@link UnitValue}. May be null
.
*/
public final void setAlignX(UnitValue uv)
{
this.alignX = uv;
}
/** If the laid out components' bounds in total is less than the final size of the container these align values will be used to align the components
* in the parent. null
is default and that means top/left alignment. The relative distances between the components will not be affected
* by this property.
* @return The current alignment.
*/
public final UnitValue getAlignY()
{
return alignY;
}
/** If the laid out components' bounds in total is less than the final size of the container these align values will be used to align the components
* in the parent. null
is default and that means top/left alignment. The relative distances between the components will not be affected
* by this property.
* @param uv The new alignment. Use {@link ConstraintParser#parseAlignKeywords(String, boolean)} to create the {@link UnitValue}. May be null
.
*/
public final void setAlignY(UnitValue uv)
{
this.alignY = uv;
}
/** If > 0
the debug decorations will be repainted every millis
. No debug information if <= 0
(default).
* @return The current debug repaint interval.
*/
public final int getDebugMillis()
{
return debugMillis;
}
/** If > 0
the debug decorations will be repainted every millis
. No debug information if <= 0
(default).
* @param millis The new debug repaint interval.
*/
public final void setDebugMillis(int millis)
{
this.debugMillis = millis;
}
/** If the layout should always claim the whole bounds of the laid out container even if the preferred size is smaller.
* @return true
means fill. false
is default.
*/
public final boolean isFillX()
{
return fillX;
}
/** If the layout should always claim the whole bounds of the laid out container even if the preferred size is smaller.
* @param b true
means fill. false
is default.
*/
public final void setFillX(boolean b)
{
this.fillX = b;
}
/** If the layout should always claim the whole bounds of the laid out container even if the preferred size is smaller.
* @return true
means fill. false
is default.
*/
public final boolean isFillY()
{
return fillY;
}
/** If the layout should always claim the whole bounds of the laid out container even if the preferred size is smaller.
* @param b true
means fill. false
is default.
*/
public final void setFillY(boolean b)
{
this.fillY = b;
}
/** The default flow direction. Normally (which is true
) this is horizontal and that means that the "next" component
* will be put in the cell to the right (or to the left if left-to-right is false).
* @return true
is the default flow horizontally.
* @see #setLeftToRight(Boolean)
*/
public final boolean isFlowX()
{
return flowX;
}
/** The default flow direction. Normally (which is true
) this is horizontal and that means that the "next" component
* will be put in the cell to the right (or to the left if left-to-right is false).
* @param b true
is the default flow horizontally.
* @see #setLeftToRight(Boolean)
*/
public final void setFlowX(boolean b)
{
this.flowX = b;
}
/** If non-null
(null
is default) these value will be used as the default gaps between the columns in the grid.
* @return The default grid gap between columns in the grid. null
if the platform default is used.
*/
public final BoundSize getGridGapX()
{
return gridGapX;
}
/** If non-null
(null
is default) these value will be used as the default gaps between the columns in the grid.
* @param x The default grid gap between columns in the grid. If null
the platform default is used.
*/
public final void setGridGapX(BoundSize x)
{
this.gridGapX = x;
}
/** If non-null
(null
is default) these value will be used as the default gaps between the rows in the grid.
* @return The default grid gap between rows in the grid. null
if the platform default is used.
*/
public final BoundSize getGridGapY()
{
return gridGapY;
}
/** If non-null
(null
is default) these value will be used as the default gaps between the rows in the grid.
* @param y The default grid gap between rows in the grid. If null
the platform default is used.
*/
public final void setGridGapY(BoundSize y)
{
this.gridGapY = y;
}
/** How a component that is hidden (not visible) should be treated by default.
* @return The mode:
* 0 == Normal. Bounds will be calculated as if the component was visible.
* 1 == If hidden the size will be 0, 0 but the gaps remain.
* 2 == If hidden the size will be 0, 0 and gaps set to zero.
* 3 == If hidden the component will be disregarded completely and not take up a cell in the grid..
*/
public final int getHideMode()
{
return hideMode;
}
/** How a component that is hidden (not visible) should be treated.
* @param mode The mode:
* 0 == Normal. Bounds will be calculated as if the component was visible.
* 1 == If hidden the size will be 0, 0 but the gaps remain.
* 2 == If hidden the size will be 0, 0 and gaps set to zero.
* 3 == If hidden the component will be disregarded completely and not take up a cell in the grid..
*/
public final void setHideMode(int mode)
{
if (mode < 0 || mode > 3)
throw new IllegalArgumentException("Wrong hideMode: " + mode);
this.hideMode = mode;
}
/** The insets for the layed out panel. The insets will be an empty space around the components in the panel. null
values
* means that the default panel insets for the platform is used. See {@link PlatformDefaults#setDialogInsets(net.miginfocom.layout.UnitValue, net.miginfocom.layout.UnitValue, net.miginfocom.layout.UnitValue, net.miginfocom.layout.UnitValue)}.
* @return The insets. Of length 4 (top, left, bottom, right) or null
. The elements (1 to 4) may be null
. The array is a copy and can be used freely.
* @see net.miginfocom.layout.ConstraintParser#parseInsets(String, boolean)
*/
public final UnitValue[] getInsets()
{
return insets != null ? new UnitValue[] {insets[0], insets[1], insets[2], insets[3]} : null;
}
/** The insets for the layed out panel. The insets will be an empty space around the components in the panel. null
values
* means that the default panel insets for the platform is used. See {@link PlatformDefaults#setDialogInsets(net.miginfocom.layout.UnitValue, net.miginfocom.layout.UnitValue, net.miginfocom.layout.UnitValue, net.miginfocom.layout.UnitValue)}.
* @param ins The new insets. Must be of length 4 (top, left, bottom, right) or null
. The elements (1 to 4) may be null
to use
* the platform default for that side. The array is copied for storage.
* @see net.miginfocom.layout.ConstraintParser#parseInsets(String, boolean)
*/
public final void setInsets(UnitValue[] ins)
{
this.insets = ins != null ? new UnitValue[] {ins[0], ins[1], ins[2], ins[3]} : null;
}
/** If the layout should be forced to be left-to-right or right-to-left. A value of null
is default and
* means that this will be picked up from the {@link java.util.Locale} that the container being layed out is reporting.
* @return Boolean.TRUE
if force left-to-right. Boolean.FALSE
if force tight-to-left. null
* for the default "let the current Locale decide".
*/
public final Boolean getLeftToRight()
{
return leftToRight;
}
/** If the layout should be forced to be left-to-right or right-to-left. A value of null
is default and
* means that this will be picked up from the {@link java.util.Locale} that the container being layed out is reporting.
* @param b Boolean.TRUE
to force left-to-right. Boolean.FALSE
to force tight-to-left. null
* for the default "let the current Locale decide".
*/
public final void setLeftToRight(Boolean b)
{
this.leftToRight = b;
}
/** If the whole layout should be non grid based. It is the same as setting the "nogrid" property on every row/column in the grid.
* @return true
means not grid based. false
is default.
*/
public final boolean isNoGrid()
{
return noGrid;
}
/** If the whole layout should be non grid based. It is the same as setting the "nogrid" property on every row/column in the grid.
* @param b true
means no grid. false
is default.
*/
public final void setNoGrid(boolean b)
{
this.noGrid = b;
}
/** If the layout should go from the default top-to-bottom in the grid instead of the optional bottom-to-top.
* @return true
for the default top-to-bottom.
*/
public final boolean isTopToBottom()
{
return topToBottom;
}
/** If the layout should go from the default top-to-bottom in the grid instead of the optional bottom-to-top.
* @param b true
for the default top-to-bottom.
*/
public final void setTopToBottom(boolean b)
{
this.topToBottom = b;
}
/** If visual padding should be automatically used and compensated for by this layout instance.
* @return true
if visual padding.
*/
public final boolean isVisualPadding()
{
return visualPadding;
}
/** If visual padding should be automatically used and compensated for by this layout instance.
* @param b true
turns on visual padding.
*/
public final void setVisualPadding(boolean b)
{
this.visualPadding = b;
}
/** Returns after what cell the grid should always auto wrap.
* @return After what cell the grid should always auto wrap. If 0
the number of columns/rows in the
* {@link net.miginfocom.layout.AC} is used. LayoutUtil.INF
is used for no auto wrap.
*/
public final int getWrapAfter()
{
return wrapAfter;
}
/** Sets after what cell the grid should always auto wrap.
* @param count After what cell the grid should always auto wrap. If 0
the number of columns/rows in the
* {@link net.miginfocom.layout.AC} is used. LayoutUtil.INF
is used for no auto wrap.
*/
public final void setWrapAfter(int count)
{
this.wrapAfter = count;
}
/** Returns the "pack width" for the window that this container is located in. When the size of this container changes
* the size of the window will be corrected to be within this BoundsSize. It can be used to set the minimum and/or maximum size of the window
* as well as the size window should optimally get. This optimal size is normally its "preferred" size which is why "preferred"
* is the normal value to set here.
*
* ":push" can be appended to the bound size to only push the size bigger and never shrink it if the preferred size gets smaller.
*
* E.g. "pref", "100:pref", "pref:700", "300::700", "pref:push"
* @return The current value. Never null
. Check if not set with .isUnset()
.
* @since 3.5
*/
public final BoundSize getPackWidth()
{
return packW;
}
/** Sets the "pack width" for the window that this container is located in. When the size of this container changes
* the size of the window will be corrected to be within this BoundsSize. It can be used to set the minimum and/or maximum size of the window
* as well as the size window should optimally get. This optimal size is normally its "preferred" size which is why "preferred"
* is the normal value to set here.
*
* ":push" can be appended to the bound size to only push the size bigger and never shrink it if the preferred size gets smaller.
*
* E.g. "pref", "100:pref", "pref:700", "300::700", "pref:push"
* @param size The new pack size. If null
it will be corrected to an "unset" BoundSize.
* @since 3.5
*/
public final void setPackWidth(BoundSize size)
{
packW = size != null ? size : BoundSize.NULL_SIZE;
}
/** Returns the "pack height" for the window that this container is located in. When the size of this container changes
* the size of the window will be corrected to be within this BoundsSize. It can be used to set the minimum and/or maximum size of the window
* as well as the size window should optimally get. This optimal size is normally its "preferred" size which is why "preferred"
* is the normal value to set here.
*
* ":push" can be appended to the bound size to only push the size bigger and never shrink it if the preferred size gets smaller.
*
* E.g. "pref", "100:pref", "pref:700", "300::700", "pref:push"
* @return The current value. Never null
. Check if not set with .isUnset()
.
* @since 3.5
*/
public final BoundSize getPackHeight()
{
return packH;
}
/** Sets the "pack height" for the window that this container is located in. When the size of this container changes
* the size of the window will be corrected to be within this BoundsSize. It can be used to set the minimum and/or maximum size of the window
* as well as the size window should optimally get. This optimal size is normally its "preferred" size which is why "preferred"
* is the normal value to set here.
*
* ":push" can be appended to the bound size to only push the size bigger and never shrink it if the preferred size gets smaller.
*
* E.g. "pref", "100:pref", "pref:700", "300::700", "pref:push"
* @param size The new pack size. If null
it will be corrected to an "unset" BoundSize.
* @since 3.5
*/
public final void setPackHeight(BoundSize size)
{
packH = size != null ? size : BoundSize.NULL_SIZE;
}
/** If there is a resize of the window due to packing (see {@link #setPackHeight(BoundSize)} this value, which is between 0f and 1f,
* decides where the extra/superfluous size is placed. 0f means that the window will resize so that the upper part moves up and the
* lower side stays in the same place. 0.5f will expand/reduce the window equally upwards and downwards. 1f will do the opposite of 0f
* of course.
* @return The pack alignment. Always between 0f and 1f, inclusive.
* @since 3.5
*/
public final float getPackHeightAlign()
{
return phAlign;
}
/** If there is a resize of the window due to packing (see {@link #setPackHeight(BoundSize)} this value, which is between 0f and 1f,
* decides where the extra/superfluous size is placed. 0f means that the window will resize so that the upper part moves up and the
* lower side stays in the same place. 0.5f will expand/reduce the window equally upwards and downwards. 1f will do the opposite of 0f
* of course.
* @param align The pack alignment. Always between 0f and 1f, inclusive. Values outside this will be truncated.
* @since 3.5
*/
public final void setPackHeightAlign(float align)
{
phAlign = Math.max(0f, Math.min(1f, align));
}
/** If there is a resize of the window due to packing (see {@link #setPackHeight(BoundSize)} this value, which is between 0f and 1f,
* decides where the extra/superfluous size is placed. 0f means that the window will resize so that the left part moves left and the
* right side stays in the same place. 0.5f will expand/reduce the window equally to the right and lefts. 1f will do the opposite of 0f
* of course.
* @return The pack alignment. Always between 0f and 1f, inclusive.
* @since 3.5
*/
public final float getPackWidthAlign()
{
return pwAlign;
}
/** If there is a resize of the window due to packing (see {@link #setPackHeight(BoundSize)} this value, which is between 0f and 1f,
* decides where the extra/superfluous size is placed. 0f means that the window will resize so that the left part moves left and the
* right side stays in the same place. 0.5f will expand/reduce the window equally to the right and lefts. 1f will do the opposite of 0f
* of course.
* @param align The pack alignment. Always between 0f and 1f, inclusive. Values outside this will be truncated.
* @since 3.5
*/
public final void setPackWidthAlign(float align)
{
pwAlign = Math.max(0f, Math.min(1f, align));
}
/** Returns the minimum/preferred/maximum size for the container that this layout constraint is set for. Any of these
* sizes that is not null
will be returned directly instead of determining the corresponding size through
* asking the components in this container.
* @return The width for the container that this layout constraint is set for. Not null
but
* all sizes can be null
.
* @since 3.5
*/
public final BoundSize getWidth()
{
return width;
}
/** Sets the minimum/preferred/maximum size for the container that this layout constraint is set for. Any of these
* sizes that is not null
will be returned directly instead of determining the corresponding size through
* asking the components in this container.
* @param size The width for the container that this layout constraint is set for. null
is translated to
* a bound size containing only null sizes.
* @since 3.5
*/
public final void setWidth(BoundSize size)
{
this.width = size != null ? size : BoundSize.NULL_SIZE;
}
/** Returns the minimum/preferred/maximum size for the container that this layout constraint is set for. Any of these
* sizes that is not null
will be returned directly instead of determining the corresponding size through
* asking the components in this container.
* @return The height for the container that this layout constraint is set for. Not null
but
* all sizes can be null
.
* @since 3.5
*/
public final BoundSize getHeight()
{
return height;
}
/** Sets the minimum/preferred/maximum size for the container that this layout constraint is set for. Any of these
* sizes that is not null
will be returned directly instead of determining the corresponding size through
* asking the components in this container.
* @param size The height for the container that this layout constraint is set for. null
is translated to
* a bound size containing only null sizes.
* @since 3.5
*/
public final void setHeight(BoundSize size)
{
this.height = size != null ? size : BoundSize.NULL_SIZE;
}
// ************************************************************************
// * Builder methods.
// ************************************************************************
/** Short for, and thus same as, .pack("pref", "pref")
.
*
* Same functionality as {@link #setPackHeight(BoundSize)} and {@link #setPackWidth(net.miginfocom.layout.BoundSize)}
* only this method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
* @since 3.5
*/
public final LC pack()
{
return pack("pref", "pref");
}
/** Sets the pack width and height.
*
* Same functionality as {@link #setPackHeight(BoundSize)} and {@link #setPackWidth(net.miginfocom.layout.BoundSize)}
* only this method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param width The pack width. May be null
.
* @param height The pack height. May be null
.
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
* @since 3.5
*/
public final LC pack(String width, String height)
{
setPackWidth(width != null ? ConstraintParser.parseBoundSize(width, false, true) : BoundSize.NULL_SIZE);
setPackHeight(height != null ? ConstraintParser.parseBoundSize(height, false, false) : BoundSize.NULL_SIZE);
return this;
}
/** Sets the pack width and height alignment.
*
* Same functionality as {@link #setPackHeightAlign(float)} and {@link #setPackWidthAlign(float)}
* only this method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param alignX The pack width alignment. 0.5f is default.
* @param alignY The pack height alignment. 0.5f is default.
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
* @since 3.5
*/
public final LC packAlign(float alignX, float alignY)
{
setPackWidthAlign(alignX);
setPackHeightAlign(alignY);
return this;
}
/** Sets a wrap after the number of columns/rows that is defined in the {@link net.miginfocom.layout.AC}.
*
* Same functionality as calling {@link #setWrapAfter(int)} with 0
only this method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
*/
public final LC wrap()
{
setWrapAfter(0);
return this;
}
/** Same functionality as {@link #setWrapAfter(int)} only this method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param count After what cell the grid should always auto wrap. If 0
the number of columns/rows in the
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
*/
public final LC wrapAfter(int count)
{
setWrapAfter(count);
return this;
}
/** Same functionality as calling {@link #setNoCache(boolean)} with true
only this method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
*/
public final LC noCache()
{
setNoCache(true);
return this;
}
/** Same functionality as calling {@link #setFlowX(boolean)} with false
only this method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
*/
public final LC flowY()
{
setFlowX(false);
return this;
}
/** Same functionality as calling {@link #setFlowX(boolean)} with true
only this method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
*/
public final LC flowX()
{
setFlowX(true);
return this;
}
/** Same functionality as calling {@link #setFillX(boolean)} with true
and {@link #setFillY(boolean)} with true
conmbined.T his method returns
* this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
*/
public final LC fill()
{
setFillX(true);
setFillY(true);
return this;
}
/** Same functionality as calling {@link #setFillX(boolean)} with true
only this method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
*/
public final LC fillX()
{
setFillX(true);
return this;
}
/** Same functionality as calling {@link #setFillY(boolean)} with true
only this method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
*/
public final LC fillY()
{
setFillY(true);
return this;
}
/** Same functionality as {@link #setLeftToRight(Boolean)} only this method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param b true
for forcing left-to-right. false
for forcing right-to-left.
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
*/
public final LC leftToRight(boolean b)
{
setLeftToRight(b ? Boolean.TRUE : Boolean.FALSE);
return this;
}
/** Same functionality as setLeftToRight(false) only this method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
* @since 3.7.2
*/
public final LC rightToLeft()
{
setLeftToRight(Boolean.FALSE);
return this;
}
/** Same functionality as calling {@link #setTopToBottom(boolean)} with false
only this method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
*/
public final LC bottomToTop()
{
setTopToBottom(false);
return this;
}
/** Same functionality as calling {@link #setTopToBottom(boolean)} with true
only this method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
* @since 3.7.2
*/
public final LC topToBottom()
{
setTopToBottom(true);
return this;
}
/** Same functionality as calling {@link #setNoGrid(boolean)} with true
only this method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
*/
public final LC noGrid()
{
setNoGrid(true);
return this;
}
/** Same functionality as calling {@link #setVisualPadding(boolean)} with false
only this method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
*/
public final LC noVisualPadding()
{
setVisualPadding(false);
return this;
}
/** Sets the same inset (expressed as a UnitValue
, e.g. "10px" or "20mm") all around.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param allSides The unit value to set for all sides. May be null
which means that the default panel insets
* for the platform is used.
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
* @see #setInsets(UnitValue[])
*/
public final LC insetsAll(String allSides)
{
UnitValue insH = ConstraintParser.parseUnitValue(allSides, true);
UnitValue insV = ConstraintParser.parseUnitValue(allSides, false);
insets = new UnitValue[] {insV, insH, insV, insH}; // No setter to avoid copy again
return this;
}
/** Same functionality as setInsets(ConstraintParser.parseInsets(s, true))
. This method returns this
* for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param s The string to parse. E.g. "10 10 10 10" or "20". If less than 4 groups the last will be used for the missing.
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
* @see #setInsets(UnitValue[])
*/
public final LC insets(String s)
{
insets = ConstraintParser.parseInsets(s, true);
return this;
}
/** Sets the different insets (expressed as a UnitValue
s, e.g. "10px" or "20mm") for the corresponding sides.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param top The top inset. E.g. "10px" or "10mm" or "related". May be null
in which case the default inset for this
* side for the platform will be used.
* @param left The left inset. E.g. "10px" or "10mm" or "related". May be null
in which case the default inset for this
* side for the platform will be used.
* @param bottom The bottom inset. E.g. "10px" or "10mm" or "related". May be null
in which case the default inset for this
* side for the platform will be used.
* @param right The right inset. E.g. "10px" or "10mm" or "related". May be null
in which case the default inset for this
* side for the platform will be used.
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
* @see #setInsets(UnitValue[])
*/
public final LC insets(String top, String left, String bottom, String right)
{
insets = new UnitValue[] { // No setter to avoid copy again
ConstraintParser.parseUnitValue(top, false),
ConstraintParser.parseUnitValue(left, true),
ConstraintParser.parseUnitValue(bottom, false),
ConstraintParser.parseUnitValue(right, true)};
return this;
}
/** Same functionality as setAlignX(ConstraintParser.parseUnitValueOrAlign(unitValue, true))
only this method returns this
* for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param align The align keyword or for instance "100px". E.g "left", "right", "leading" or "trailing".
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
* @see #setAlignX(UnitValue)
*/
public final LC alignX(String align)
{
setAlignX(ConstraintParser.parseUnitValueOrAlign(align, true, null));
return this;
}
/** Same functionality as setAlignY(ConstraintParser.parseUnitValueOrAlign(align, false))
only this method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param align The align keyword or for instance "100px". E.g "top" or "bottom".
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
* @see #setAlignY(UnitValue)
*/
public final LC alignY(String align)
{
setAlignY(ConstraintParser.parseUnitValueOrAlign(align, false, null));
return this;
}
/** Sets both the alignX and alignY as the same time.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param ax The align keyword or for instance "100px". E.g "left", "right", "leading" or "trailing".
* @param ay The align keyword or for instance "100px". E.g "top" or "bottom".
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
* @see #alignX(String)
* @see #alignY(String)
*/
public final LC align(String ax, String ay)
{
if (ax != null)
alignX(ax);
if (ay != null)
alignY(ay);
return this;
}
/** Same functionality as setGridGapX(ConstraintParser.parseBoundSize(boundsSize, true, true))
only this method
* returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param boundsSize The BoundSize
of the gap. This is a minimum and/or preferred and/or maximum size. E.g.
* "50:100:200"
or "100px"
.
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
* @see #setGridGapX(BoundSize)
*/
public final LC gridGapX(String boundsSize)
{
setGridGapX(ConstraintParser.parseBoundSize(boundsSize, true, true));
return this;
}
/** Same functionality as setGridGapY(ConstraintParser.parseBoundSize(boundsSize, true, false))
only this method
* returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param boundsSize The BoundSize
of the gap. This is a minimum and/or preferred and/or maximum size. E.g.
* "50:100:200"
or "100px"
.
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
* @see #setGridGapY(BoundSize)
*/
public final LC gridGapY(String boundsSize)
{
setGridGapY(ConstraintParser.parseBoundSize(boundsSize, true, false));
return this;
}
/** Sets both grid gaps at the same time. see {@link #gridGapX(String)} and {@link #gridGapY(String)}.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param gapx The BoundSize
of the gap. This is a minimum and/or preferred and/or maximum size. E.g.
* "50:100:200"
or "100px"
.
* @param gapy The BoundSize
of the gap. This is a minimum and/or preferred and/or maximum size. E.g.
* "50:100:200"
or "100px"
.
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
* @see #gridGapX(String)
* @see #gridGapY(String)
*/
public final LC gridGap(String gapx, String gapy)
{
if (gapx != null)
gridGapX(gapx);
if (gapy != null)
gridGapY(gapy);
return this;
}
/** Calls {@link #debug(int)} with 300 as an argument.
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
* @see #setDebugMillis(int)
*/
public final LC debug()
{
setDebugMillis(300);
return this;
}
/** Same functionality as {@link #setDebugMillis(int repaintMillis)} only this method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param repaintMillis The new debug repaint interval.
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
* @see #setDebugMillis(int)
*/
public final LC debug(int repaintMillis)
{
setDebugMillis(repaintMillis);
return this;
}
/** Same functionality as {@link #setHideMode(int mode)} only this method returns this
for chaining multiple calls.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
* @param mode The mode:
* 0 == Normal. Bounds will be calculated as if the component was visible.
* 1 == If hidden the size will be 0, 0 but the gaps remain.
* 2 == If hidden the size will be 0, 0 and gaps set to zero.
* 3 == If hidden the component will be disregarded completely and not take up a cell in the grid..
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
* @see #setHideMode(int)
*/
public final LC hideMode(int mode)
{
setHideMode(mode);
return this;
}
/** The minimum width for the container. The value will override any value that is set on the container itself.
*
* For a more thorough explanation of what this constraint does see the white paper or Cheat Sheet at www.migcontainers.com.
* @param width The width expressed as a UnitValue
. E.g. "100px" or "200mm".
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
*/
public final LC minWidth(String width)
{
setWidth(LayoutUtil.derive(getWidth(), ConstraintParser.parseUnitValue(width, true), null, null));
return this;
}
/** The width for the container as a min and/or preferred and/or maximum width. The value will override any value that is set on
* the container itself.
*
* For a more thorough explanation of what this constraint does see the white paper or Cheat Sheet at www.migcontainers.com.
* @param width The width expressed as a BoundSize
. E.g. "50:100px:200mm" or "100px".
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
*/
public final LC width(String width)
{
setWidth(ConstraintParser.parseBoundSize(width, false, true));
return this;
}
/** The maximum width for the container. The value will override any value that is set on the container itself.
*
* For a more thorough explanation of what this constraint does see the white paper or Cheat Sheet at www.migcontainers.com.
* @param width The width expressed as a UnitValue
. E.g. "100px" or "200mm".
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
*/
public final LC maxWidth(String width)
{
setWidth(LayoutUtil.derive(getWidth(), null, null, ConstraintParser.parseUnitValue(width, true)));
return this;
}
/** The minimum height for the container. The value will override any value that is set on the container itself.
*
* For a more thorough explanation of what this constraint does see the white paper or Cheat Sheet at www.migcontainers.com.
* @param height The height expressed as a UnitValue
. E.g. "100px" or "200mm".
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
*/
public final LC minHeight(String height)
{
setHeight(LayoutUtil.derive(getHeight(), ConstraintParser.parseUnitValue(height, false), null, null));
return this;
}
/** The height for the container as a min and/or preferred and/or maximum height. The value will override any value that is set on
* the container itself.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcontainers.com.
* @param height The height expressed as a BoundSize
. E.g. "50:100px:200mm" or "100px".
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
*/
public final LC height(String height)
{
setHeight(ConstraintParser.parseBoundSize(height, false, false));
return this;
}
/** The maximum height for the container. The value will override any value that is set on the container itself.
*
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcontainers.com.
* @param height The height expressed as a UnitValue
. E.g. "100px" or "200mm".
* @return this
so it is possible to chain calls. E.g. new LayoutConstraint().noGrid().gap().fill()
.
*/
public final LC maxHeight(String height)
{
setHeight(LayoutUtil.derive(getHeight(), null, null, ConstraintParser.parseUnitValue(height, false)));
return this;
}
// ************************************************
// Persistence Delegate and Serializable combined.
// ************************************************
private Object readResolve() throws ObjectStreamException
{
return LayoutUtil.getSerializedObject(this);
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
{
LayoutUtil.setSerializedObject(this, LayoutUtil.readAsXML(in));
}
@Override
public void writeExternal(ObjectOutput out) throws IOException
{
if (getClass() == LC.class)
LayoutUtil.writeAsXML(out, this);
}
}
miglayout-5.1/core/src/main/java/net/miginfocom/layout/LayoutCallback.java000077500000000000000000000070241324101563200267470ustar00rootroot00000000000000package net.miginfocom.layout;
/*
* License (BSD):
* ==============
*
* Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
* 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 the MiG InfoCom AB nor 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.
*
* @version 1.0
* @author Mikael Grev, MiG InfoCom AB
* Date: 2006-sep-08
*/
/** A class to extend if you want to provide more control over where a component is placed or the size of it.
*
* Note! Returned arrays from this class will never be altered. This means that caching of arrays in these methods
* is OK.
*/
public abstract class LayoutCallback
{
/** Returns a position similar to the "pos" the component constraint.
* @param comp The component wrapper that holds the actual component (JComponent is Swing and Control in SWT).
* Should not be altered.
* @return The [x, y, x2, y2] as explained in the documentation for "pos". If null
* is returned nothing is done and this is the default.
* @see UnitValue
* @see net.miginfocom.layout.ConstraintParser#parseUnitValue(String, boolean)
*/
public UnitValue[] getPosition(ComponentWrapper comp)
{
return null;
}
/** Returns a size similar to the "width" and "height" in the component constraint.
* @param comp The component wrapper that holds the actual component (JComponent is Swing and Control in SWT).
* Should not be altered.
* @return The [width, height] as explained in the documentation for "width" and "height". If null
* is returned nothing is done and this is the default.
* @see net.miginfocom.layout.BoundSize
* @see net.miginfocom.layout.ConstraintParser#parseBoundSize(String, boolean, boolean)
*/
public BoundSize[] getSize(ComponentWrapper comp)
{
return null;
}
/** A last minute change of the bounds. The bound for the layout cycle has been set and you can correct there
* after any set of rules you like.
* @param comp The component wrapper that holds the actual component (JComponent is Swing and Control in SWT).
*/
public void correctBounds(ComponentWrapper comp)
{
}
}
miglayout-5.1/core/src/main/java/net/miginfocom/layout/LayoutUtil.java000077500000000000000000000513011324101563200261650ustar00rootroot00000000000000package net.miginfocom.layout;
import java.beans.*;
import java.io.*;
import java.util.IdentityHashMap;
import java.util.TreeSet;
import java.util.WeakHashMap;
/*
* License (BSD):
* ==============
*
* Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
* 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 the MiG InfoCom AB nor 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.
*
* @version 1.0
* @author Mikael Grev, MiG InfoCom AB
* Date: 2006-sep-08
*/
/** A utility class that has only static helper methods.
*/
public final class LayoutUtil
{
/** A substitute value for a really large value. Integer.MAX_VALUE is not used since that means a lot of defensive code
* for potential overflow must exist in many places. This value is large enough for being unreasonable yet it is hard to
* overflow.
*/
public static final int INF = (Integer.MAX_VALUE >> 10) - 100; // To reduce likelihood of overflow errors when calculating.
/** Tag int for a value that in considered "not set". Used as "null" element in int arrays.
*/
static final int NOT_SET = Integer.MIN_VALUE + 12346; // Magic value...
// Index for the different sizes
public static final int MIN = 0;
public static final int PREF = 1;
public static final int MAX = 2;
public static final int HORIZONTAL = 0;
public static final int VERTICAL = 1;
private static volatile WeakHashMap CR_MAP = null;
private static volatile WeakHashMap DT_MAP = null; // The Containers that have design time. Value not used.
private static int eSz = 0;
private static int globalDebugMillis = 0;
public static final boolean HAS_BEANS = hasBeans();
private static boolean hasBeans()
{
try {
LayoutUtil.class.getClassLoader().loadClass("java.beans.Beans");
return true;
} catch (Throwable e) {
return false;
}
}
private LayoutUtil()
{
}
/** Returns the current version of MiG Layout.
* @return The current version of MiG Layout. E.g. "3.6.3" or "4.0"
*/
public static String getVersion()
{
return "5.0";
}
/** If global debug should be on or off. If > 0 then debug is turned on for all MigLayout
* instances.
* @return The current debug milliseconds.
* @see LC#setDebugMillis(int)
*/
public static int getGlobalDebugMillis()
{
return globalDebugMillis;
}
/** If global debug should be on or off. If > 0 then debug is turned on for all MigLayout
* instances.
*
* Note! This is a passive value and will be read by panels when the needed, which is normally
* when they repaint/layout.
* @param millis The new debug milliseconds. 0 turns of global debug and leaves debug up to every
* individual panel.
* @see LC#setDebugMillis(int)
*/
public static void setGlobalDebugMillis(int millis)
{
globalDebugMillis = millis;
}
/** Sets if design time is turned on for a Container in {@link ContainerWrapper}.
* @param cw The container to set design time for. null
is legal and can be used as
* a key to turn on/off design time "in general". Note though that design time "in general" is
* always on as long as there is at least one ContainerWrapper with design time.
*
* If this method has not ever been called it will default to what
* Beans.isDesignTime()
returns. This means that if you call
* this method you indicate that you will take responsibility for the design time value.
* @param b true
means design time on.
*/
public static void setDesignTime(ContainerWrapper cw, boolean b)
{
if (DT_MAP == null)
DT_MAP = new WeakHashMap();
DT_MAP.put((cw != null ? cw.getComponent() : null), b);
}
/** Returns if design time is turned on for a Container in {@link ContainerWrapper}.
* @param cw The container to set design time for. null
is legal will return true
* if there is at least one ContainerWrapper
(or null
) that have design time
* turned on.
* @return If design time is set for cw
.
*/
public static boolean isDesignTime(ContainerWrapper cw)
{
if (DT_MAP == null)
return HAS_BEANS && Beans.isDesignTime();
// assume design time "in general" (cw is null) if there is at least one container with design time
// (for storing constraints creation strings in method putCCString())
if (cw == null && DT_MAP != null && !DT_MAP.isEmpty() )
return true;
if (cw != null && DT_MAP.containsKey(cw.getComponent()) == false)
cw = null;
Boolean b = DT_MAP.get(cw != null ? cw.getComponent() : null);
return b != null && b;
}
/** The size of an empty row or columns in a grid during design time.
* @return The number of pixels. Default is 15.
*/
public static int getDesignTimeEmptySize()
{
return eSz;
}
/** The size of an empty row or columns in a grid during design time.
* @param pixels The number of pixels. Default is 0 (it was 15 prior to v3.7.2, but since that meant different behaviour
* under design time by default it was changed to be 0, same as non-design time). IDE vendors can still set it to 15 to
* get the old behaviour.
*/
public static void setDesignTimeEmptySize(int pixels)
{
eSz = pixels;
}
/** Associates con
with the creation string s
. The con
object should
* probably have an equals method that compares identities or con
objects that .equals() will only
* be able to have one creation string.
*
* If {@link LayoutUtil#isDesignTime(ContainerWrapper)} returns false
the method does nothing.
* @param con The object. if null
the method does nothing.
* @param s The creation string. if null
the method does nothing.
*/
static void putCCString(Object con, String s)
{
if (s != null && con != null && isDesignTime(null)) {
if (CR_MAP == null)
CR_MAP = new WeakHashMap(64);
CR_MAP.put(con, s);
}
}
/** Sets/add the persistence delegates to be used for a class.
* @param c The class to set the registered delegate for.
* @param del The new delegate or null
to erase to old one.
*/
static synchronized void setDelegate(Class c, PersistenceDelegate del)
{
try {
Introspector.getBeanInfo(c, Introspector.IGNORE_ALL_BEANINFO).getBeanDescriptor().setValue("persistenceDelegate", del);
} catch (Exception ignored) {
}
}
/** Returns strings set with {@link #putCCString(Object, String)} or null
if nothing is associated or
* {@link LayoutUtil#isDesignTime(ContainerWrapper)} returns false
.
* @param con The constrain object.
* @return The creation string or null
if nothing is registered with the con
object.
*/
static String getCCString(Object con)
{
return CR_MAP != null ? CR_MAP.get(con) : null;
}
static void throwCC()
{
throw new IllegalStateException("setStoreConstraintData(true) must be set for strings to be saved.");
}
/** Takes a number on min/preferred/max sizes and resize constraints and returns the calculated sizes which sum should add up to bounds
. Whether the sum
* will actually equal bounds
is dependent on the pref/max sizes and resize constraints.
* @param sizes [ix],[MIN][PREF][MAX]. Grid.CompWrap.NOT_SET will be treated as N/A or 0. A "[MIN][PREF][MAX]" array with null elements will be interpreted as very flexible (no bounds)
* but if the array itself is null it will not get any size.
* @param resConstr Elements can be null
and the whole array can be null
. null
means that the size will not be flexible at all.
* Can have length less than sizes
in which case the last element should be used for the elements missing.
* @param defPushWeights If there is no grow weight for a resConstr the corresponding value of this array is used.
* These forced resConstr will be grown last though and only if needed to fill to the bounds.
* @param startSizeType The initial size to use. E.g. {@link net.miginfocom.layout.LayoutUtil#MIN}.
* @param bounds To use for relative sizes.
* @return The sizes. Array length will match sizes
.
*/
static int[] calculateSerial(int[][] sizes, ResizeConstraint[] resConstr, Float[] defPushWeights, int startSizeType, int bounds)
{
float[] lengths = new float[sizes.length]; // heights/widths that are set
float usedLength = 0.0f;
// Give all preferred size to start with
for (int i = 0; i < sizes.length; i++) {
if (sizes[i] != null) {
float len = sizes[i][startSizeType] != NOT_SET ? sizes[i][startSizeType] : 0;
int newSizeBounded = getBrokenBoundary(len, sizes[i][MIN], sizes[i][MAX]);
if (newSizeBounded != NOT_SET)
len = newSizeBounded;
usedLength += len;
lengths[i] = len;
}
}
int useLengthI = Math.round(usedLength);
if (useLengthI != bounds && resConstr != null) {
boolean isGrow = useLengthI < bounds;
// Create a Set with the available priorities
TreeSet prioList = new TreeSet();
for (int i = 0; i < sizes.length; i++) {
ResizeConstraint resC = (ResizeConstraint) getIndexSafe(resConstr, i);
if (resC != null)
prioList.add(isGrow ? resC.growPrio : resC.shrinkPrio);
}
Integer[] prioIntegers = prioList.toArray(new Integer[prioList.size()]);
for (int force = 0; force <= ((isGrow && defPushWeights != null) ? 1 : 0); force++) { // Run twice if defGrow and the need for growing.
for (int pr = prioIntegers.length - 1; pr >= 0; pr--) {
int curPrio = prioIntegers[pr];
float totWeight = 0f;
Float[] resizeWeight = new Float[sizes.length];
for (int i = 0; i < sizes.length; i++) {
if (sizes[i] == null) // if no min/pref/max size at all do not grow or shrink.
continue;
ResizeConstraint resC = (ResizeConstraint) getIndexSafe(resConstr, i);
if (resC != null) {
int prio = isGrow ? resC.growPrio : resC.shrinkPrio;
if (curPrio == prio) {
if (isGrow) {
resizeWeight[i] = (force == 0 || resC.grow != null) ? resC.grow : (defPushWeights[i < defPushWeights.length ? i : defPushWeights.length - 1]);
} else {
resizeWeight[i] = resC.shrink;
}
if (resizeWeight[i] != null)
totWeight += resizeWeight[i];
}
}
}
if (totWeight > 0f) {
boolean hit;
do {
float toChange = bounds - usedLength;
hit = false;
float changedWeight = 0f;
for (int i = 0; i < sizes.length && totWeight > 0.0001f; i++) {
Float weight = resizeWeight[i];
if (weight != null) {
float sizeDelta = toChange * weight / totWeight;
float newSize = lengths[i] + sizeDelta;
if (sizes[i] != null) {
int newSizeBounded = getBrokenBoundary(newSize, sizes[i][MIN], sizes[i][MAX]);
if (newSizeBounded != NOT_SET) {
resizeWeight[i] = null;
hit = true;
changedWeight += weight;
newSize = newSizeBounded;
sizeDelta = newSize - lengths[i];
}
}
lengths[i] = newSize;
usedLength += sizeDelta;
}
}
totWeight -= changedWeight;
} while (hit);
}
}
}
}
return roundSizes(lengths);
}
static Object getIndexSafe(Object[] arr, int ix)
{
return arr != null ? arr[ix < arr.length ? ix : arr.length - 1] : null;
}
/** Returns the broken boundary if sz
is outside the boundaries lower
or upper
. If both boundaries
* are broken, the lower one is returned. If sz
is < 0 then new Float(0f)
is returned so that no sizes can be
* negative.
* @param sz The size to check
* @param lower The lower boundary (or null
for no boundary).
* @param upper The upper boundary (or null
for no boundary).
* @return The broken boundary.
*/
private static int getBrokenBoundary(float sz, int lower, int upper)
{
if (lower != NOT_SET) {
if (sz < lower)
return lower;
} else if (sz < 0f) {
return 0;
}
if (upper != NOT_SET && sz > upper)
return upper;
return NOT_SET;
}
static int sum(int[] terms, int start, int len)
{
int s = 0;
for (int i = start, iSz = start + len; i < iSz; i++)
s += terms[i];
return s;
}
static int sum(int[] terms)
{
return sum(terms, 0, terms.length);
}
/** Keeps f within min and max. Min is of higher priority if min is larger than max.
* @param f The value to clamp
* @param min
* @param max
* @return The clamped value, between min and max.
*/
static float clamp(float f, float min, float max)
{
return Math.max(min, Math.min(f, max));
}
/** Keeps i within min and max. Min is of higher priority if min is larger than max.
* @param i The value to clamp
* @param min
* @param max
* @return The clamped value, between min and max.
*/
static int clamp(int i, int min, int max)
{
return Math.max(min, Math.min(i, max));
}
public static int getSizeSafe(int[] sizes, int sizeType)
{
if (sizes == null || sizes[sizeType] == NOT_SET)
return sizeType == MAX ? LayoutUtil.INF : 0;
return sizes[sizeType];
}
static BoundSize derive(BoundSize bs, UnitValue min, UnitValue pref, UnitValue max)
{
if (bs == null || bs.isUnset())
return new BoundSize(min, pref, max, null);
return new BoundSize(
min != null ? min : bs.getMin(),
pref != null ? pref : bs.getPreferred(),
max != null ? max : bs.getMax(),
bs.getGapPush(),
null);
}
/** Returns if left-to-right orientation is used. If not set explicitly in the layout constraints the Locale
* of the parent
is used.
* @param lc The constraint if there is one. Can be null
.
* @param container The parent that may be used to get the left-to-right if lc does not specify this.
* @return If left-to-right orientation is currently used.
*/
public static boolean isLeftToRight(LC lc, ContainerWrapper container)
{
if (lc != null && lc.getLeftToRight() != null)
return lc.getLeftToRight();
return container == null || container.isLeftToRight();
}
/** Round a number of float sizes into int sizes so that the total length match up
* @param sizes The sizes to round
* @return An array of equal length as sizes
.
*/
static int[] roundSizes(float[] sizes)
{
int[] retInts = new int[sizes.length];
float posD = 0;
for (int i = 0; i < retInts.length; i++) {
int posI = (int) (posD + 0.5f);
posD += sizes[i];
retInts[i] = (int) (posD + 0.5f) - posI;
}
return retInts;
}
/** Safe equals. null == null, but null never equals anything else.
* @param o1 The first object. May be null
.
* @param o2 The second object. May be null
.
* @return Returns true
if o1
and o2
are equal (using .equals()) or both are null
.
*/
static boolean equals(Object o1, Object o2)
{
return o1 == o2 || (o1 != null && o2 != null && o1.equals(o2));
}
// static int getBaselineCorrect(Component comp)
// {
// Dimension pSize = comp.getPreferredSize();
// int baseline = comp.getBaseline(pSize.width, pSize.height);
// int nextBaseline = comp.getBaseline(pSize.width, pSize.height + 1);
//
// // Amount to add to height when calculating where baseline
// // lands for a particular height:
// int padding = 0;
//
// // Where the baseline is relative to the mid point
// int baselineOffset = baseline - pSize.height / 2;
// if (pSize.height % 2 == 0 && baseline != nextBaseline) {
// padding = 1;
// } else if (pSize.height % 2 == 1 && baseline == nextBaseline) {
// baselineOffset--;
// padding = 1;
// }
//
// // The following calculates where the baseline lands for
// // the height z:
// return (pSize.height + padding) / 2 + baselineOffset;
// }
/** Returns the insets for the side.
* @param side top == 0, left == 1, bottom = 2, right = 3.
* @param getDefault If true
the default insets will get retrieved if lc
has none set.
* @return The insets for the side. Never null
.
*/
static UnitValue getInsets(LC lc, int side, boolean getDefault)
{
UnitValue[] i = lc.getInsets();
return (i != null && i[side] != null) ? i[side] : (getDefault ? PlatformDefaults.getPanelInsets(side) : UnitValue.ZERO);
}
/** Writes the object and CLOSES the stream. Uses the persistence delegate registered in this class.
* @param os The stream to write to. Will be closed.
* @param o The object to be serialized.
* @param listener The listener to receive the exceptions if there are any. If null
not used.
*/
static void writeXMLObject(OutputStream os, Object o, ExceptionListener listener)
{
ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(LayoutUtil.class.getClassLoader());
XMLEncoder encoder = new XMLEncoder(os);
if (listener != null)
encoder.setExceptionListener(listener);
encoder.writeObject(o);
encoder.close(); // Must be closed to write.
Thread.currentThread().setContextClassLoader(oldClassLoader);
}
private static ByteArrayOutputStream writeOutputStream = null;
/** Writes an object to XML.
* @param out The object out to write to. Will not be closed.
* @param o The object to write.
*/
public static synchronized void writeAsXML(ObjectOutput out, Object o) throws IOException
{
if (writeOutputStream == null)
writeOutputStream = new ByteArrayOutputStream(16384);
writeOutputStream.reset();
writeXMLObject(writeOutputStream, o, new ExceptionListener() {
@Override
public void exceptionThrown(Exception e) {
e.printStackTrace();
}});
byte[] buf = writeOutputStream.toByteArray();
out.writeInt(buf.length);
out.write(buf);
}
private static byte[] readBuf = null;
/** Reads an object from in
using the
* @param in The object input to read from.
* @return The object. Never null
.
* @throws IOException If there was a problem saving as XML
*/
public static synchronized Object readAsXML(ObjectInput in) throws IOException
{
if (readBuf == null)
readBuf = new byte[16384];
Thread cThread = Thread.currentThread();
ClassLoader oldCL = null;
try {
oldCL = cThread.getContextClassLoader();
cThread.setContextClassLoader(LayoutUtil.class.getClassLoader());
} catch(SecurityException ignored) {
}
Object o = null;
try {
int length = in.readInt();
if (length > readBuf.length)
readBuf = new byte[length];
in.readFully(readBuf, 0, length);
o = new XMLDecoder(new ByteArrayInputStream(readBuf, 0, length)).readObject();
} catch(EOFException ignored) {
}
if (oldCL != null)
cThread.setContextClassLoader(oldCL);
return o;
}
private static final IdentityHashMap SER_MAP = new IdentityHashMap(2);
/** Sets the serialized object and associates it with caller
.
* @param caller The object created o
* @param o The just serialized object.
*/
public static void setSerializedObject(Object caller, Object o)
{
synchronized(SER_MAP) {
SER_MAP.put(caller, o);
}
}
/** Returns the serialized object that are associated with caller
. It also removes it from the list.
* @param caller The original creator of the object.
* @return The object.
*/
public static Object getSerializedObject(Object caller)
{
synchronized(SER_MAP) {
return SER_MAP.remove(caller);
}
}
}
miglayout-5.1/core/src/main/java/net/miginfocom/layout/LinkHandler.java000077500000000000000000000140071324101563200262470ustar00rootroot00000000000000package net.miginfocom.layout;
import java.util.HashMap;
import java.util.WeakHashMap;
/*
* License (BSD):
* ==============
*
* Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
* 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 the MiG InfoCom AB nor 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.
*
* @version 1.0
* @author Mikael Grev, MiG InfoCom AB
* Date: 2006-sep-08
*/
/**
*/
public final class LinkHandler
{
public static final int X = 0;
public static final int Y = 1;
public static final int WIDTH = 2;
public static final int HEIGHT = 3;
public static final int X2 = 4;
public static final int Y2 = 5;
// indices for values of LAYOUTS
private static final int VALUES = 0;
private static final int VALUES_TEMP = 1;
private static final WeakHashMap[]> LAYOUTS = new WeakHashMap[]>();
private LinkHandler()
{
}
public synchronized static Integer getValue(Object layout, String key, int type)
{
Integer ret = null;
HashMap[] layoutValues = LAYOUTS.get(layout);
if (layoutValues != null) {
int[] rect = layoutValues[VALUES_TEMP].get(key);
if (rect != null && rect[type] != LayoutUtil.NOT_SET) {
ret = rect[type];
} else {
rect = layoutValues[VALUES].get(key);
ret = (rect != null && rect[type] != LayoutUtil.NOT_SET) ? rect[type] : null;
}
}
return ret;
}
/** Sets a key that can be linked to from any component.
* @param layout The MigLayout instance
* @param key The key to link to. This is the same as the ID in a component constraint.
* @param x x
* @param y y
* @param width Width
* @param height Height
* @return If the value was changed
*/
public synchronized static boolean setBounds(Object layout, String key, int x, int y, int width, int height)
{
return setBounds(layout, key, x, y, width, height, false, false);
}
synchronized static boolean setBounds(Object layout, String key, int x, int y, int width, int height, boolean temporary, boolean incCur)
{
HashMap[] layoutValues = LAYOUTS.get(layout);
if (layoutValues != null) {
HashMap map = layoutValues[temporary ? VALUES_TEMP : VALUES];
int[] old = map.get(key);
if (old == null || old[X] != x || old[Y] != y || old[WIDTH] != width || old[HEIGHT] != height) {
if (old == null || incCur == false) {
map.put(key, new int[] {x, y, width, height, x + width, y + height});
return true;
} else {
boolean changed = false;
if (x != LayoutUtil.NOT_SET) {
if (old[X] == LayoutUtil.NOT_SET || x < old[X]) {
old[X] = x;
old[WIDTH] = old[X2] - x;
changed = true;
}
if (width != LayoutUtil.NOT_SET) {
int x2 = x + width;
if (old[X2] == LayoutUtil.NOT_SET || x2 > old[X2]) {
old[X2] = x2;
old[WIDTH] = x2 - old[X];
changed = true;
}
}
}
if (y != LayoutUtil.NOT_SET) {
if (old[Y] == LayoutUtil.NOT_SET || y < old[Y]) {
old[Y] = y;
old[HEIGHT] = old[Y2] - y;
changed = true;
}
if (height != LayoutUtil.NOT_SET) {
int y2 = y + height;
if (old[Y2] == LayoutUtil.NOT_SET || y2 > old[Y2]) {
old[Y2] = y2;
old[HEIGHT] = y2 - old[Y];
changed = true;
}
}
}
return changed;
}
}
return false;
}
int[] bounds = new int[] {x, y, width, height, x + width, y + height};
HashMap values_temp = new HashMap(4);
if (temporary)
values_temp.put(key, bounds);
HashMap values = new HashMap(4);
if (temporary == false)
values.put(key, bounds);
LAYOUTS.put(layout, new HashMap[] {values, values_temp});
return true;
}
/** This method clear any weak references right away instead of waiting for the GC. This might be advantageous
* if lots of layout are created and disposed of quickly to keep memory consumption down.
* @since 3.7.4
*/
public synchronized static void clearWeakReferencesNow()
{
LAYOUTS.clear();
}
public synchronized static boolean clearBounds(Object layout, String key)
{
HashMap[] layoutValues = LAYOUTS.get(layout);
if (layoutValues != null)
return layoutValues[VALUES].remove(key) != null;
return false;
}
synchronized static void clearTemporaryBounds(Object layout)
{
HashMap[] layoutValues = LAYOUTS.get(layout);
if (layoutValues != null)
layoutValues[VALUES_TEMP].clear();
}
}
miglayout-5.1/core/src/main/java/net/miginfocom/layout/PlatformDefaults.java000077500000000000000000001031201324101563200273230ustar00rootroot00000000000000package net.miginfocom.layout;
import java.util.HashMap;
/*
* License (BSD):
* ==============
*
* Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
* 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 the MiG InfoCom AB nor 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.
*
* @version 1.0
* @author Mikael Grev, MiG InfoCom AB
* Date: 2006-sep-08
* @author Xxxx Xxxx, Xxxx - Gnome support
* Date: 2008-jan-16
*/
/** Currently handles Windows, Mac OS X, and GNOME spacing.
*/
public final class PlatformDefaults
{
/** Property to use in LAF settings and as JComponent client property
* to specify the visual padding.
*
*/
public static String VISUAL_PADDING_PROPERTY = "visualPadding";
private static int DEF_H_UNIT = UnitValue.LPX;
private static int DEF_V_UNIT = UnitValue.LPY;
private static InCellGapProvider GAP_PROVIDER = null;
private static volatile int MOD_COUNT = 0;
// private static final UnitValue LPX1 = new UnitValue(1, UnitValue.LPX, null);
// private static final UnitValue LPX4 = new UnitValue(4, UnitValue.LPX, null);
private static final UnitValue LPX6 = new UnitValue(6, UnitValue.LPX, null);
private static final UnitValue LPX7 = new UnitValue(7, UnitValue.LPX, null);
// private static final UnitValue LPX8 = new UnitValue(8, UnitValue.LPX, null);
// private static final UnitValue LPX9 = new UnitValue(9, UnitValue.LPX, null);
// private static final UnitValue LPX10 = new UnitValue(10, UnitValue.LPX, null);
private static final UnitValue LPX11 = new UnitValue(11, UnitValue.LPX, null);
private static final UnitValue LPX12 = new UnitValue(12, UnitValue.LPX, null);
// private static final UnitValue LPX14 = new UnitValue(14, UnitValue.LPX, null);
private static final UnitValue LPX16 = new UnitValue(16, UnitValue.LPX, null);
private static final UnitValue LPX18 = new UnitValue(18, UnitValue.LPX, null);
private static final UnitValue LPX20 = new UnitValue(20, UnitValue.LPX, null);
// private static final UnitValue LPY1 = new UnitValue(1, UnitValue.LPY, null);
// private static final UnitValue LPY4 = new UnitValue(4, UnitValue.LPY, null);
private static final UnitValue LPY6 = new UnitValue(6, UnitValue.LPY, null);
private static final UnitValue LPY7 = new UnitValue(7, UnitValue.LPY, null);
// private static final UnitValue LPY8 = new UnitValue(8, UnitValue.LPY, null);
// private static final UnitValue LPY9 = new UnitValue(9, UnitValue.LPY, null);
// private static final UnitValue LPY10 = new UnitValue(10, UnitValue.LPY, null);
private static final UnitValue LPY11 = new UnitValue(11, UnitValue.LPY, null);
private static final UnitValue LPY12 = new UnitValue(12, UnitValue.LPY, null);
// private static final UnitValue LPY14 = new UnitValue(14, UnitValue.LPY, null);
private static final UnitValue LPY16 = new UnitValue(16, UnitValue.LPY, null);
private static final UnitValue LPY18 = new UnitValue(18, UnitValue.LPY, null);
private static final UnitValue LPY20 = new UnitValue(20, UnitValue.LPY, null);
public static final int WINDOWS_XP = 0;
public static final int MAC_OSX = 1;
public static final int GNOME = 2;
// private static final int KDE = 3;
private static int CUR_PLAF = WINDOWS_XP;
// Used for holding values.
private final static UnitValue[] PANEL_INS = new UnitValue[4];
private final static UnitValue[] DIALOG_INS = new UnitValue[4];
private static String BUTTON_FORMAT = null;
private static final HashMap HOR_DEFS = new HashMap(32);
private static final HashMap VER_DEFS = new HashMap(32);
private static BoundSize DEF_VGAP = null, DEF_HGAP = null;
static BoundSize RELATED_X = null, RELATED_Y = null, UNRELATED_X = null, UNRELATED_Y = null;
private static UnitValue BUTT_WIDTH = null;
private static UnitValue BUTT_PADDING = null;
private static Float horScale = null, verScale = null;
/** I value indicating that the size of the font for the container of the component
* will be used as a base for calculating the logical pixel size. This is much as how
* Windows calculated DLU (dialog units).
* @see net.miginfocom.layout.UnitValue#LPX
* @see net.miginfocom.layout.UnitValue#LPY
* @see #setLogicalPixelBase(int)
*/
public static final int BASE_FONT_SIZE = 100;
/** I value indicating that the screen DPI will be used as a base for calculating the
* logical pixel size.
*
* This is the default value.
* @see net.miginfocom.layout.UnitValue#LPX
* @see net.miginfocom.layout.UnitValue#LPY
* @see #setLogicalPixelBase(int)
* @see #setVerticalScaleFactor(Float)
* @see #setHorizontalScaleFactor(Float)
*/
public static final int BASE_SCALE_FACTOR = 101;
/** I value indicating that the size of a logical pixel should always be a real pixel
* and thus no compensation will be made.
* @see net.miginfocom.layout.UnitValue#LPX
* @see net.miginfocom.layout.UnitValue#LPY
* @see #setLogicalPixelBase(int)
*/
public static final int BASE_REAL_PIXEL = 102;
private static int LP_BASE = BASE_SCALE_FACTOR;
private static Integer BASE_DPI_FORCED = null;
private static int BASE_DPI = 96;
private static boolean dra = true;
private static final HashMap VISUAL_BOUNDS = new HashMap(64);
static {
setPlatform(getCurrentPlatform());
MOD_COUNT = 0;
}
/** Returns the platform that the JRE is running on currently.
* @return The platform that the JRE is running on currently. E.g. {@link #MAC_OSX}, {@link #WINDOWS_XP}, or {@link #GNOME}.
*/
public static int getCurrentPlatform()
{
final String os = System.getProperty("os.name");
if (os.startsWith("Mac OS")) {
return MAC_OSX;
} else if (os.startsWith("Linux")) {
return GNOME;
} else {
return WINDOWS_XP;
}
}
private PlatformDefaults()
{
}
/** Set the defaults to the default for the platform
* @param plaf The platform. PlatformDefaults.WINDOWS_XP
,
* PlatformDefaults.MAC_OSX
, or
* PlatformDefaults.GNOME
.
*/
public static void setPlatform(int plaf)
{
switch (plaf) {
case WINDOWS_XP:
setDefaultVisualPadding("TabbedPane." + VISUAL_PADDING_PROPERTY, new int[]{1, 0, 1, 2});
setRelatedGap(LPX7, LPY7);
setUnrelatedGap(LPX11, LPY11);
setParagraphGap(LPX20, LPY20);
setIndentGap(LPX11, LPY11);
setGridCellGap(LPX7, LPY7);
setMinimumButtonWidth(new UnitValue(75, UnitValue.LPX, null));
setButtonOrder("L_E+U+YNBXOCAH_I_R");
setDialogInsets(LPY11, LPX11, LPY11, LPX11);
setPanelInsets(LPY7, LPX7, LPY7, LPX7);
break;
case MAC_OSX:
setDefaultVisualPadding("Button." + VISUAL_PADDING_PROPERTY, new int[]{3, 6, 5, 6});
setDefaultVisualPadding("Button.icon." + VISUAL_PADDING_PROPERTY, new int[]{3, 2, 3, 2});
setDefaultVisualPadding("Button.square." + VISUAL_PADDING_PROPERTY, new int[]{4, 4, 4, 4});
setDefaultVisualPadding("Button.square.icon." + VISUAL_PADDING_PROPERTY, new int[]{4, 4, 4, 4});
setDefaultVisualPadding("Button.gradient." + VISUAL_PADDING_PROPERTY, new int[]{5, 4, 5, 4});
setDefaultVisualPadding("Button.gradient.icon." + VISUAL_PADDING_PROPERTY, new int[]{5, 4, 5, 4});
setDefaultVisualPadding("Button.bevel." + VISUAL_PADDING_PROPERTY, new int[]{2, 2, 3, 2});
setDefaultVisualPadding("Button.bevel.icon." + VISUAL_PADDING_PROPERTY, new int[]{2, 2, 3, 2});
setDefaultVisualPadding("Button.textured." + VISUAL_PADDING_PROPERTY, new int[]{3, 2, 3, 2});
setDefaultVisualPadding("Button.textured.icon." + VISUAL_PADDING_PROPERTY, new int[]{3, 2, 3, 2});
setDefaultVisualPadding("Button.roundRect." + VISUAL_PADDING_PROPERTY, new int[]{5, 4, 5, 4});
setDefaultVisualPadding("Button.roundRect.icon." + VISUAL_PADDING_PROPERTY, new int[]{5, 4, 5, 4});
setDefaultVisualPadding("Button.recessed." + VISUAL_PADDING_PROPERTY, new int[]{5, 4, 5, 4});
setDefaultVisualPadding("Button.recessed.icon." + VISUAL_PADDING_PROPERTY, new int[]{5, 4, 5, 4});
setDefaultVisualPadding("Button.help." + VISUAL_PADDING_PROPERTY, new int[]{4, 3, 3, 4});
setDefaultVisualPadding("Button.help.icon." + VISUAL_PADDING_PROPERTY, new int[]{4, 3, 3, 4});
setDefaultVisualPadding("ComboBox." + VISUAL_PADDING_PROPERTY, new int[]{2, 4, 4, 5});
setDefaultVisualPadding("ComboBox.isPopDown." + VISUAL_PADDING_PROPERTY, new int[]{2, 5, 4, 5});
setDefaultVisualPadding("ComboBox.isSquare." + VISUAL_PADDING_PROPERTY, new int[]{1, 6, 5, 7});
setDefaultVisualPadding("ComboBox.editable." + VISUAL_PADDING_PROPERTY, new int[]{3, 3, 3, 2});
setDefaultVisualPadding("ComboBox.editable.isSquare." + VISUAL_PADDING_PROPERTY, new int[]{3, 3, 3, 1});
setDefaultVisualPadding("TextField." + VISUAL_PADDING_PROPERTY, new int[]{3, 3, 3, 3});
setDefaultVisualPadding("TabbedPane." + VISUAL_PADDING_PROPERTY, new int[]{4, 8, 11, 8});
setDefaultVisualPadding("Spinner." + VISUAL_PADDING_PROPERTY, new int[]{3, 3, 3, 1});
setDefaultVisualPadding("RadioButton." + VISUAL_PADDING_PROPERTY, new int[]{4, 6, 3, 5});
setDefaultVisualPadding("RadioButton.small." + VISUAL_PADDING_PROPERTY, new int[]{4, 6, 3, 5});
setDefaultVisualPadding("RadioButton.mini." + VISUAL_PADDING_PROPERTY, new int[]{5, 7, 4, 5});
setDefaultVisualPadding("CheckBox." + VISUAL_PADDING_PROPERTY, new int[]{5, 7, 4, 5});
setDefaultVisualPadding("CheckBox.small." + VISUAL_PADDING_PROPERTY, new int[]{5, 7, 4, 5});
setDefaultVisualPadding("CheckBox.mini." + VISUAL_PADDING_PROPERTY, new int[]{6, 7, 3, 5});
setRelatedGap(LPX7, LPY7);
setUnrelatedGap(LPX11, LPY11);
setParagraphGap(LPX20, LPY20);
setIndentGap(LPX11, LPY11);
setGridCellGap(LPX7, LPY7);
setMinimumButtonWidth(new UnitValue(70, UnitValue.LPX, null));
setMinimumButtonPadding(new UnitValue(8, UnitValue.LPX, null));
setButtonOrder("L_HE+U+NYBXCOA_I_R");
setDialogInsets(LPY20, LPX20, LPY20, LPX20);
setPanelInsets(LPY16, LPX16, LPY16, LPX16);
break;
case GNOME:
setRelatedGap(LPX6, LPY6); // GNOME HIG 8.2.3
setUnrelatedGap(LPX12, LPY12); // GNOME HIG 8.2.3
setParagraphGap(LPX18, LPY18); // GNOME HIG 8.2.3
setIndentGap(LPX12, LPY12); // GNOME HIG 8.2.3
setGridCellGap(LPX6, LPY6); // GNOME HIG 8.2.3
// GtkButtonBox, child-min-width property default value
setMinimumButtonWidth(new UnitValue(85, UnitValue.LPX, null));
setButtonOrder("L_HE+UNYACBXO_I_R"); // GNOME HIG 3.4.2, 3.7.1
setDialogInsets(LPY12, LPX12, LPY12, LPX12); // GNOME HIG 3.4.3
setPanelInsets(LPY6, LPX6, LPY6, LPX6); // ???
break;
default:
throw new IllegalArgumentException("Unknown platform: " + plaf);
}
CUR_PLAF = plaf;
BASE_DPI = BASE_DPI_FORCED != null ? BASE_DPI_FORCED : getPlatformDPI(plaf);
}
/** Sets the visual bounds for a component type.
* @param key The component type. E.g. "TabbedPane.visualPadding" or "ComboBox.editable.isSquare.visualPadding". See source code for list.
* @param insets Top, left, bottom, right. Always length 4 or null.
* @see net.miginfocom.layout.ComponentWrapper#getVisualPadding()
*/
public static void setDefaultVisualPadding(String key, int[] insets)
{
VISUAL_BOUNDS.put(key, insets);
}
/** Returns the visual bounds for a component type.
* @param key The component type. E.g. "TabbedPane.visualPadding" or "ComboBox.editable.isSquare.visualPadding". See source code for list.
* @return insets Top, left, bottom, right. Always length 4 or null. Live object, MUST NOT BE CHANGED!.
* @see net.miginfocom.layout.ComponentWrapper#getVisualPadding()
*/
public static int[] getDefaultVisualPadding(String key)
{
return VISUAL_BOUNDS.get(key);
}
public static int getPlatformDPI(int plaf)
{
switch (plaf) {
case WINDOWS_XP:
case GNOME:
return 96;
case MAC_OSX:
try {
return java.awt.Toolkit.getDefaultToolkit().getScreenResolution();
} catch (Throwable t) {
return 72;
}
default:
throw new IllegalArgumentException("Unknown platform: " + plaf);
}
}
/** Returns the current platform
* @return PlatformDefaults.WINDOWS
or PlatformDefaults.MAC_OSX
*/
public static int getPlatform()
{
return CUR_PLAF;
}
public static int getDefaultDPI()
{
return BASE_DPI;
}
/** Sets the default platform DPI. Normally this is set in the {@link #setPlatform(int)} for the different platforms
* but it can be tweaked here. For instance SWT on Mac does this.
*
* Note that this is not the actual current DPI, but the base DPI for the toolkit.
* @param dpi The base DPI. If null the default DPI is reset to the platform base DPI.
*/
public static void setDefaultDPI(Integer dpi)
{
BASE_DPI = dpi != null ? dpi : getPlatformDPI(CUR_PLAF);
BASE_DPI_FORCED = dpi;
}
/** The forced scale factor that all screen relative units (e.g. millimeters, inches and logical pixels) will be multiplied
* with. If null
this will default to a scale that will scale the current screen to the default screen resolution
* (72 DPI for Mac and 92 DPI for Windows).
* @return The forced scale or null
for default scaling.
* @see #getHorizontalScaleFactor()
* @see ComponentWrapper#getHorizontalScreenDPI()
*/
public static Float getHorizontalScaleFactor()
{
return horScale;
}
/** The forced scale factor that all screen relative units (e.g. millimeters, inches and logical pixels) will be multiplied
* with. If null
this will default to a scale that will scale the current screen to the default screen resolution
* (72 DPI for Mac and 92 DPI for Windows).
* @param f The forced scale or null
for default scaling.
* @see #getHorizontalScaleFactor()
* @see ComponentWrapper#getHorizontalScreenDPI()
*/
public static void setHorizontalScaleFactor(Float f)
{
if (!LayoutUtil.equals(horScale, f)) {
horScale = f;
MOD_COUNT++;
}
}
/** The forced scale factor that all screen relative units (e.g. millimeters, inches and logical pixels) will be multiplied
* with. If null
this will default to a scale that will scale the current screen to the default screen resolution
* (72 DPI for Mac and 92 DPI for Windows).
* @return The forced scale or null
for default scaling.
* @see #getHorizontalScaleFactor()
* @see ComponentWrapper#getVerticalScreenDPI()
*/
public static Float getVerticalScaleFactor()
{
return verScale;
}
/** The forced scale factor that all screen relative units (e.g. millimeters, inches and logical pixels) will be multiplied
* with. If null
this will default to a scale that will scale the current screen to the default screen resolution
* (72 DPI for Mac and 92 DPI for Windows).
* @param f The forced scale or null
for default scaling.
* @see #getHorizontalScaleFactor()
* @see ComponentWrapper#getVerticalScreenDPI()
*/
public static void setVerticalScaleFactor(Float f)
{
if (!LayoutUtil.equals(verScale, f)) {
verScale = f;
MOD_COUNT++;
}
}
/** What base value should be used to calculate logical pixel sizes.
* @return The current base. Default is {@link #BASE_SCALE_FACTOR}
* @see #BASE_FONT_SIZE
* @see #BASE_SCALE_FACTOR
* @see #BASE_REAL_PIXEL
*/
public static int getLogicalPixelBase()
{
return LP_BASE;
}
/** What base value should be used to calculate logical pixel sizes.
* @param base The new base. Default is {@link #BASE_SCALE_FACTOR}
* @see #BASE_FONT_SIZE
* @see #BASE_SCALE_FACTOR
* @see #BASE_REAL_PIXEL
*/
public static void setLogicalPixelBase(int base)
{
if (LP_BASE != base) {
if (base < BASE_FONT_SIZE || base > BASE_REAL_PIXEL)
throw new IllegalArgumentException("Unrecognized base: " + base);
LP_BASE = base;
MOD_COUNT++;
}
}
/** Sets gap value for components that are "related".
* @param x The value that will be transformed to pixels. If null
the current value will not change.
* @param y The value that will be transformed to pixels. If null
the current value will not change.
*/
public static void setRelatedGap(UnitValue x, UnitValue y)
{
setUnitValue(new String[] {"r", "rel", "related"}, x, y);
RELATED_X = new BoundSize(x, x, null, "rel:rel");
RELATED_Y = new BoundSize(y, y, null, "rel:rel");
}
/** Sets gap value for components that are "unrelated".
* @param x The value that will be transformed to pixels. If null
the current value will not change.
* @param y The value that will be transformed to pixels. If null
the current value will not change.
*/
public static void setUnrelatedGap(UnitValue x, UnitValue y)
{
setUnitValue(new String[] {"u", "unrel", "unrelated"}, x, y);
UNRELATED_X = new BoundSize(x, x, null, "unrel:unrel");
UNRELATED_Y = new BoundSize(y, y, null, "unrel:unrel");
}
/** Sets paragraph gap value for components.
* @param x The value that will be transformed to pixels. If null
the current value will not change.
* @param y The value that will be transformed to pixels. If null
the current value will not change.
*/
public static void setParagraphGap(UnitValue x, UnitValue y)
{
setUnitValue(new String[] {"p", "para", "paragraph"}, x, y);
}
/** Sets gap value for components that are "intended".
* @param x The value that will be transformed to pixels. If null
the current value will not change.
* @param y The value that will be transformed to pixels. If null
the current value will not change.
*/
public static void setIndentGap(UnitValue x, UnitValue y)
{
setUnitValue(new String[] {"i", "ind", "indent"}, x, y);
}
/** Sets gap between two cells in the grid. Note that this is not a gap between component IN a cell, that has to be set
* on the component constraints. The value will be the min and preferred size of the gap.
* @param x The value that will be transformed to pixels. If null
the current value will not change.
* @param y The value that will be transformed to pixels. If null
the current value will not change.
*/
public static void setGridCellGap(UnitValue x, UnitValue y)
{
if (x != null)
DEF_HGAP = new BoundSize(x, x, null, null);
if (y != null)
DEF_VGAP = new BoundSize(y, y, null, null);
MOD_COUNT++;
}
/** Sets the recommended minimum button width.
* @param width The recommended minimum button width.
*/
public static void setMinimumButtonWidth(UnitValue width)
{
BUTT_WIDTH = width;
MOD_COUNT++;
}
/** Returns the recommended minimum button width depending on the current set platform.
* @return The recommended minimum button width depending on the current set platform.
*/
public static UnitValue getMinimumButtonWidth()
{
return BUTT_WIDTH;
}
public static void setMinimumButtonPadding(UnitValue padding)
{
BUTT_PADDING = padding;
MOD_COUNT++;
}
public static UnitValue getMinimumButtonPadding()
{
return BUTT_PADDING;
}
public static float getMinimumButtonWidthIncludingPadding(float refValue, ContainerWrapper parent, ComponentWrapper comp)
{
final int buttonMinWidth = getMinimumButtonWidth().getPixels(refValue, parent, comp);
if (comp != null && getMinimumButtonPadding() != null) {
return Math.max(comp.getMinimumWidth(comp.getWidth()) + getMinimumButtonPadding().getPixels(refValue, parent, comp) * 2, buttonMinWidth);
} else {
return buttonMinWidth;
}
}
/** Returns the unit value associated with the unit. (E.i. "related" or "indent"). Must be lower case.
* @param unit The unit string.
* @return The unit value associated with the unit. null
for unrecognized units.
*/
public static UnitValue getUnitValueX(String unit)
{
return HOR_DEFS.get(unit);
}
/** Returns the unit value associated with the unit. (E.i. "related" or "indent"). Must be lower case.
* @param unit The unit string.
* @return The unit value associated with the unit. null
for unrecognized units.
*/
public static UnitValue getUnitValueY(String unit)
{
return VER_DEFS.get(unit);
}
/** Sets the unit value associated with a unit string. This may be used to store values for new unit strings
* or modify old. Note that if a built in unit (such as "related") is modified all versions of it must be
* set (I.e. "r", "rel" and "related"). The build in values will be reset to the default ones if the platform
* is re-set.
* @param unitStrings The unit strings. E.g. "mu", "myunit". Will be converted to lower case and trimmed. Not null
.
* @param x The value for the horizontal dimension. If null
the value is not changed.
* @param y The value for the vertical dimension. Might be same object as for x
. If null
the value is not changed.
*/
public static void setUnitValue(String[] unitStrings, UnitValue x, UnitValue y)
{
for (String unitString : unitStrings) {
String s = unitString.toLowerCase().trim();
if (x != null)
HOR_DEFS.put(s, x);
if (y != null)
VER_DEFS.put(s, y);
}
MOD_COUNT++;
}
/** Understands ("r", "rel", "related") OR ("u", "unrel", "unrelated") OR ("i", "ind", "indent") OR ("p", "para", "paragraph").
*/
static int convertToPixels(float value, String unit, boolean isHor, float ref, ContainerWrapper parent, ComponentWrapper comp)
{
UnitValue uv = (isHor ? HOR_DEFS : VER_DEFS).get(unit);
return uv != null ? Math.round(value * uv.getPixels(ref, parent, comp)) : UnitConverter.UNABLE;
}
/** Returns the order for the typical buttons in a standard button bar. It is one letter per button type.
* @return The button order.
* @see #setButtonOrder(String)
*/
public static String getButtonOrder()
{
return BUTTON_FORMAT;
}
/** Sets the order for the typical buttons in a standard button bar. It is one letter per button type.
*
* Letter in upper case will get the minimum button width that the {@link #getMinimumButtonWidth()} specifies
* and letters in lower case will get the width the current look&feel specifies.
*
* Gaps will never be added to before the first component or after the last component. However, '+' (push) will be
* applied before and after as well, but with a minimum size of 0 if first/last so there will not be a gap
* before or after.
*
* If gaps are explicitly set on buttons they will never be reduced, but they may be increased.
*
* These are the characters that can be used:
*
* 'L'
- Buttons with this style tag will statically end up on the left end of the bar.
* 'R'
- Buttons with this style tag will statically end up on the right end of the bar.
* 'H'
- A tag for the "help" button that normally is supposed to be on the right.
* 'E'
- A tag for the "help2" button that normally is supposed to be on the left.
* 'Y'
- A tag for the "yes" button.
* 'N'
- A tag for the "no" button.
* 'X'
- A tag for the "next >" or "forward >" button.
* 'B'
- A tag for the "< back" or "< previous" button.
* 'I'
- A tag for the "finish" button.
* 'A'
- A tag for the "apply" button.
* 'C'
- A tag for the "cancel" or "close" button.
* 'O'
- A tag for the "ok" or "done" button.
* 'U'
- All Uncategorized, Other, or "Unknown" buttons. Tag will be "other".
* '+'
- A glue push gap that will take as much space as it can and at least an "unrelated" gap. (Platform dependent)
* '_'
- (underscore) An "unrelated" gap. (Platform dependent)
*
*
* Even though the style tags are normally applied to buttons this works with all components.
*
* The normal style for MAC OS X is "L_HE+U+NYBXCOA_I_R"
,
* for Windows is "L_E+U+YNBXOCAH_I_R"
, and for GNOME is
* "L_HE+UNYACBXO_I_R"
.
*
* @param order The new button order for the current platform.
*/
public static void setButtonOrder(String order)
{
BUTTON_FORMAT = order;
MOD_COUNT++;
}
/** Returns the tag (used in the {@link CC}) for a char. The char is same as used in {@link #getButtonOrder()}.
* @param c The char. Must be lower case!
* @return The tag that corresponds to the char or null
if the char is unrecognized.
*/
static String getTagForChar(char c)
{
switch (c) {
case 'o':
return "ok";
case 'c':
return "cancel";
case 'h':
return "help";
case 'e':
return "help2";
case 'y':
return "yes";
case 'n':
return "no";
case 'a':
return "apply";
case 'x':
return "next"; // a.k.a forward
case 'b':
return "back"; // a.k.a. previous
case 'i':
return "finish";
case 'l':
return "left";
case 'r':
return "right";
case 'u':
return "other";
default:
return null;
}
}
/** Returns the platform recommended inter-cell gap in the horizontal (x) dimension..
* @return The platform recommended inter-cell gap in the horizontal (x) dimension..
*/
public static BoundSize getGridGapX()
{
return DEF_HGAP;
}
/** Returns the platform recommended inter-cell gap in the vertical (x) dimension..
* @return The platform recommended inter-cell gap in the vertical (x) dimension..
*/
public static BoundSize getGridGapY()
{
return DEF_VGAP;
}
/** Returns the default dialog insets depending of the current platform.
* @param side top == 0, left == 1, bottom = 2, right = 3.
* @return The insets. Never null
.
*/
public static UnitValue getDialogInsets(int side)
{
return DIALOG_INS[side];
}
/** Sets the default insets for a dialog. Values that are null will not be changed.
* @param top The top inset. May be null
.
* @param left The left inset. May be null
.
* @param bottom The bottom inset. May be null
.
* @param right The right inset. May be null
.
*/
public static void setDialogInsets(UnitValue top, UnitValue left, UnitValue bottom, UnitValue right)
{
if (top != null)
DIALOG_INS[0] = top;
if (left != null)
DIALOG_INS[1] = left;
if (bottom != null)
DIALOG_INS[2] = bottom;
if (right != null)
DIALOG_INS[3] = right;
MOD_COUNT++;
}
/** Returns the default panel insets depending of the current platform.
* @param side top == 0, left == 1, bottom = 2, right = 3.
* @return The insets. Never null
.
*/
public static UnitValue getPanelInsets(int side)
{
return PANEL_INS[side];
}
/** Sets the default insets for a dialog. Values that are null will not be changed.
* @param top The top inset. May be null
.
* @param left The left inset. May be null
.
* @param bottom The bottom inset. May be null
.
* @param right The right inset. May be null
.
*/
public static void setPanelInsets(UnitValue top, UnitValue left, UnitValue bottom, UnitValue right)
{
if (top != null)
PANEL_INS[0] = top;
if (left != null)
PANEL_INS[1] = left;
if (bottom != null)
PANEL_INS[2] = bottom;
if (right != null)
PANEL_INS[3] = right;
MOD_COUNT++;
}
/** Returns the percentage used for alignment for labels (0 is left, 50 is center and 100 is right).
* @return The percentage used for alignment for labels
*/
public static float getLabelAlignPercentage()
{
return CUR_PLAF == MAC_OSX ? 1f : 0f;
}
/** Returns the default gap between two components that are in the same cell .
* @param comp The component that the gap is for. Never null
.
* @param adjacentComp The adjacent component if any. May be null
.
* @param adjacentSide What side the adjacentComp
is on. {@link javax.swing.SwingUtilities#TOP} (1) or
* {@link javax.swing.SwingUtilities#LEFT} (2) or {@link javax.swing.SwingUtilities#BOTTOM} (3) or {@link javax.swing.SwingUtilities#RIGHT} (4).
* @param tag The tag string that the component might be tagged with in the component constraints. May be null
.
* @param isLTR If it is left-to-right.
* @return The default gap between two components or null
if there should be no gap.
*/
static BoundSize getDefaultComponentGap(ComponentWrapper comp, ComponentWrapper adjacentComp, int adjacentSide, String tag, boolean isLTR)
{
if (GAP_PROVIDER != null)
return GAP_PROVIDER.getDefaultGap(comp, adjacentComp, adjacentSide, tag, isLTR);
if (adjacentComp == null)
return null;
// if (adjacentComp == null || adjacentSide == SwingConstants.LEFT || adjacentSide == SwingConstants.TOP)
// return null;
// SwingConstants.RIGHT == 4, SwingConstants.LEFT == 2
return (adjacentSide == 2 || adjacentSide == 4) ? RELATED_X : RELATED_Y;
}
/** Returns the current gap provider or null
if none is set and "related" should always be used.
* @return The current gap provider or null
if none is set and "related" should always be used.
*/
public static InCellGapProvider getGapProvider()
{
return GAP_PROVIDER;
}
/** Sets the current gap provider or null
if none is set and "related" should always be used.
* @param provider The current gap provider or null
if none is set and "related" should always be used.
*/
public static void setGapProvider(InCellGapProvider provider)
{
GAP_PROVIDER = provider;
}
/** Returns how many times the defaults has been changed. This can be used as a light weight check to
* see if layout caches needs to be refreshed.
* @return How many times the defaults has been changed.
*/
public static int getModCount()
{
return MOD_COUNT;
}
/** Tells all layout manager instances to revalidate and recalculated everything.
*/
public void invalidate()
{
MOD_COUNT++;
}
/** Returns the current default unit. The default unit is the unit used if no unit is set. E.g. "width 10".
* @return The current default unit.
* @see UnitValue#PIXEL
* @see UnitValue#LPX
*/
public static int getDefaultHorizontalUnit()
{
return DEF_H_UNIT;
}
/** Sets the default unit. The default unit is the unit used if no unit is set. E.g. "width 10".
* @param unit The new default unit.
* @see UnitValue#PIXEL
* @see UnitValue#LPX
*/
public static void setDefaultHorizontalUnit(int unit)
{
if (unit < UnitValue.PIXEL || unit > UnitValue.LABEL_ALIGN)
throw new IllegalArgumentException("Illegal Unit: " + unit);
if (DEF_H_UNIT != unit) {
DEF_H_UNIT = unit;
MOD_COUNT++;
}
}
/** Returns the current default unit. The default unit is the unit used if no unit is set. E.g. "width 10".
* @return The current default unit.
* @see UnitValue#PIXEL
* @see UnitValue#LPY
*/
public static int getDefaultVerticalUnit()
{
return DEF_V_UNIT;
}
/** Sets the default unit. The default unit is the unit used if no unit is set. E.g. "width 10".
* @param unit The new default unit.
* @see UnitValue#PIXEL
* @see UnitValue#LPY
*/
public static void setDefaultVerticalUnit(int unit)
{
if (unit < UnitValue.PIXEL || unit > UnitValue.LABEL_ALIGN)
throw new IllegalArgumentException("Illegal Unit: " + unit);
if (DEF_V_UNIT != unit) {
DEF_V_UNIT = unit;
MOD_COUNT++;
}
}
/** The default alignment for rows. Pre v3.5 this was false
but now it is
* true
.
* @return The current value. Default is true
.
* @since 3.5
*/
public static boolean getDefaultRowAlignmentBaseline()
{
return dra;
}
/** The default alignment for rows. Pre v3.5 this was false
but now it is
* true
.
* @param b The new value. Default is true
from v3.5.
* @since 3.5
*/
public static void setDefaultRowAlignmentBaseline(boolean b)
{
dra = b;
}
}
miglayout-5.1/core/src/main/java/net/miginfocom/layout/ResizeConstraint.java000077500000000000000000000066621324101563200273720ustar00rootroot00000000000000package net.miginfocom.layout;
import java.io.*;
/*
* License (BSD):
* ==============
*
* Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
* 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 the MiG InfoCom AB nor 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.
*
* @version 1.0
* @author Mikael Grev, MiG InfoCom AB
* Date: 2006-sep-08
*/
/** A parsed constraint that specifies how an entity (normally column/row or component) can shrink or
* grow compared to other entities.
*/
final class ResizeConstraint implements Externalizable
{
static final Float WEIGHT_100 = 100f;
/** How flexible the entity should be, relative to other entities, when it comes to growing. null
or
* zero mean it will never grow. An entity that has twice the growWeight compared to another entity will get twice
* as much of available space.
*
* "grow" are only compared within the same "growPrio".
*/
Float grow = null;
/** The relative priority used for determining which entities gets the extra space first.
*/
int growPrio = 100;
Float shrink = WEIGHT_100;
int shrinkPrio = 100;
public ResizeConstraint() // For Externalizable
{
}
ResizeConstraint(int shrinkPrio, Float shrinkWeight, int growPrio, Float growWeight)
{
this.shrinkPrio = shrinkPrio;
this.shrink = shrinkWeight;
this.growPrio = growPrio;
this.grow = growWeight;
}
// ************************************************
// Persistence Delegate and Serializable combined.
// ************************************************
private Object readResolve() throws ObjectStreamException
{
return LayoutUtil.getSerializedObject(this);
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
{
LayoutUtil.setSerializedObject(this, LayoutUtil.readAsXML(in));
}
@Override
public void writeExternal(ObjectOutput out) throws IOException
{
if (getClass() == ResizeConstraint.class)
LayoutUtil.writeAsXML(out, this);
}
}
miglayout-5.1/core/src/main/java/net/miginfocom/layout/UnitConverter.java000077500000000000000000000062051324101563200266640ustar00rootroot00000000000000package net.miginfocom.layout;
/*
* License (BSD):
* ==============
*
* Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
* 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 the MiG InfoCom AB nor 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.
*
* @version 1.0
* @author Mikael Grev, MiG InfoCom AB
* Date: 2006-sep-08
*/
/**
*/
public abstract class UnitConverter
{
/** Value to return if this converter can not handle the unit
sent in as an argument
* to the convert method.
*/
public static final int UNABLE = -87654312;
/** Converts value
to pixels.
* @param value The value to be converted.
* @param unit The unit of value
. Never null
and at least one character.
* @param refValue Some reference value that may of may not be used. If the unit is percent for instance this value
* is the value to take the percent from. Usually the size of the parent component in the appropriate dimension.
* @param isHor If the value is horizontal (true
) or vertical (false
).
* @param parent The parent of the target component that value
is to be applied to.
* Might for instance be needed to get the screen that the component is on in a multi screen environment.
*
* May be null
in which case a "best guess" value should be returned.
* @param comp The component, if applicable, or null
if none.
* @return The number of pixels if unit
is handled by this converter, UnitConverter.UNABLE
if not.
*/
public abstract int convertToPixels(float value, String unit, boolean isHor, float refValue, ContainerWrapper parent, ComponentWrapper comp);
}
miglayout-5.1/core/src/main/java/net/miginfocom/layout/UnitValue.java000077500000000000000000000520111324101563200257650ustar00rootroot00000000000000package net.miginfocom.layout;
/*
* License (BSD):
* ==============
*
* Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
* 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 the MiG InfoCom AB nor 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.
*
* @version 1.0
* @author Mikael Grev, MiG InfoCom AB
* Date: 2006-sep-08
*/
import java.beans.Encoder;
import java.beans.Expression;
import java.beans.PersistenceDelegate;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
public final class UnitValue implements Serializable
{
private static final HashMap UNIT_MAP = new HashMap(32);
private static final ArrayList CONVERTERS = new ArrayList();
/** An operation indicating a static value.
*/
public static final int STATIC = 100;
/** An operation indicating a addition of two sub units.
*/
public static final int ADD = 101; // Must have "sub-unit values"
/** An operation indicating a subtraction of two sub units
*/
public static final int SUB = 102; // Must have "sub-unit values"
/** An operation indicating a multiplication of two sub units.
*/
public static final int MUL = 103; // Must have "sub-unit values"
/** An operation indicating a division of two sub units.
*/
public static final int DIV = 104; // Must have "sub-unit values"
/** An operation indicating the minimum of two sub units
*/
public static final int MIN = 105; // Must have "sub-unit values"
/** An operation indicating the maximum of two sub units
*/
public static final int MAX = 106; // Must have "sub-unit values"
/** An operation indicating the middle value of two sub units
*/
public static final int MID = 107; // Must have "sub-unit values"
/** A unit indicating pixels.
*/
public static final int PIXEL = 0;
/** A unit indicating logical horizontal pixels.
*/
public static final int LPX = 1;
/** A unit indicating logical vertical pixels.
*/
public static final int LPY = 2;
/** A unit indicating millimeters.
*/
public static final int MM = 3;
/** A unit indicating centimeters.
*/
public static final int CM = 4;
/** A unit indicating inches.
*/
public static final int INCH = 5;
/** A unit indicating percent.
*/
public static final int PERCENT = 6;
/** A unit indicating points.
*/
public static final int PT = 7;
/** A unit indicating screen percentage width.
*/
public static final int SPX = 8;
/** A unit indicating screen percentage height.
*/
public static final int SPY = 9;
/** A unit indicating alignment.
*/
public static final int ALIGN = 12;
/** A unit indicating minimum size.
*/
public static final int MIN_SIZE = 13;
/** A unit indicating preferred size.
*/
public static final int PREF_SIZE = 14;
/** A unit indicating maximum size.
*/
public static final int MAX_SIZE = 15;
/** A unit indicating button size.
*/
public static final int BUTTON = 16;
/** A unit indicating linking to x.
*/
public static final int LINK_X = 18; // First link
/** A unit indicating linking to y.
*/
public static final int LINK_Y = 19;
/** A unit indicating linking to width.
*/
public static final int LINK_W = 20;
/** A unit indicating linking to height.
*/
public static final int LINK_H = 21;
/** A unit indicating linking to x2.
*/
public static final int LINK_X2 = 22;
/** A unit indicating linking to y2.
*/
public static final int LINK_Y2 = 23;
/** A unit indicating linking to x position on screen.
*/
public static final int LINK_XPOS = 24;
/** A unit indicating linking to y position on screen.
*/
public static final int LINK_YPOS = 25; // Last link
/** A unit indicating a lookup.
*/
public static final int LOOKUP = 26;
/** A unit indicating label alignment.
*/
public static final int LABEL_ALIGN = 27;
private static final int IDENTITY = -1;
static {
UNIT_MAP.put("px", PIXEL);
UNIT_MAP.put("lpx", LPX);
UNIT_MAP.put("lpy", LPY);
UNIT_MAP.put("%", PERCENT);
UNIT_MAP.put("cm", CM);
UNIT_MAP.put("in", INCH);
UNIT_MAP.put("spx", SPX);
UNIT_MAP.put("spy", SPY);
UNIT_MAP.put("al", ALIGN);
UNIT_MAP.put("mm", MM);
UNIT_MAP.put("pt", PT);
UNIT_MAP.put("min", MIN_SIZE);
UNIT_MAP.put("minimum", MIN_SIZE);
UNIT_MAP.put("p", PREF_SIZE);
UNIT_MAP.put("pref", PREF_SIZE);
UNIT_MAP.put("max", MAX_SIZE);
UNIT_MAP.put("maximum", MAX_SIZE);
UNIT_MAP.put("button", BUTTON);
UNIT_MAP.put("label", LABEL_ALIGN);
}
static final UnitValue ZERO = new UnitValue(0, null, PIXEL, true, STATIC, null, null, "0px");
static final UnitValue TOP = new UnitValue(0, null, PERCENT, false, STATIC, null, null, "top");
static final UnitValue LEADING = new UnitValue(0, null, PERCENT, true, STATIC, null, null, "leading");
static final UnitValue LEFT = new UnitValue(0, null, PERCENT, true, STATIC, null, null, "left");
static final UnitValue CENTER = new UnitValue(50, null, PERCENT, true, STATIC, null, null, "center");
static final UnitValue TRAILING = new UnitValue(100, null, PERCENT, true, STATIC, null, null, "trailing");
static final UnitValue RIGHT = new UnitValue(100, null, PERCENT, true, STATIC, null, null, "right");
static final UnitValue BOTTOM = new UnitValue(100, null, PERCENT, false, STATIC, null, null, "bottom");
static final UnitValue LABEL = new UnitValue(0, null, LABEL_ALIGN, false, STATIC, null, null, "label");
static final UnitValue INF = new UnitValue(LayoutUtil.INF, null, PIXEL, true, STATIC, null, null, "inf");
static final UnitValue BASELINE_IDENTITY = new UnitValue(0, null, IDENTITY, false, STATIC, null, null, "baseline");
private final transient float value;
private final transient int unit;
private final transient int oper;
private final transient String unitStr;
private transient String linkId = null; // Should be final, but initializes in a sub method.
private final transient boolean isHor;
private final transient UnitValue[] subUnits;
// Pixel
public UnitValue(float value) // If hor/ver does not matter.
{
this(value, null, PIXEL, true, STATIC, null, null, value + "px");
}
public UnitValue(float value, int unit, String createString) // If hor/ver does not matter.
{
this(value, null, unit, true, STATIC, null, null, createString);
}
public UnitValue(float value, String unitStr, boolean isHor, int oper, String createString)
{
this(value, unitStr, -1, isHor, oper, null, null, createString);
}
UnitValue(boolean isHor, int oper, UnitValue sub1, UnitValue sub2, String createString)
{
this(0, "", -1, isHor, oper, sub1, sub2, createString);
if (sub1 == null || sub2 == null)
throw new IllegalArgumentException("Sub units is null!");
}
private UnitValue(float value, String unitStr, int unit, boolean isHor, int oper, UnitValue sub1, UnitValue sub2, String createString)
{
if (oper < STATIC || oper > MID)
throw new IllegalArgumentException("Unknown Operation: " + oper);
if (oper >= ADD && oper <= MID && (sub1 == null || sub2 == null))
throw new IllegalArgumentException(oper + " Operation may not have null sub-UnitValues.");
this.value = value;
this.oper = oper;
this.isHor = isHor;
this.unitStr = unitStr;
this.unit = unitStr != null ? parseUnitString() : unit;
this.subUnits = sub1 != null && sub2 != null ? new UnitValue[] {sub1, sub2} : null;
LayoutUtil.putCCString(this, createString); // "this" escapes!! Safe though.
}
/** Returns the size in pixels rounded.
* @param refValue The reference value. Normally the size of the parent. For unit {@link #ALIGN} the current size of the component should be sent in.
* @param parent The parent. May be null
for testing the validity of the value, but should normally not and are not
* required to return any usable value if null
.
* @param comp The component, if any, that the value is for. Might be null
if the value is not
* connected to any component.
* @return The size in pixels.
*/
public final int getPixels(float refValue, ContainerWrapper parent, ComponentWrapper comp)
{
return Math.round(getPixelsExact(refValue, parent, comp));
}
private static final float[] SCALE = new float[] {25.4f, 2.54f, 1f, 0f, 72f};
/** Returns the size in pixels.
* @param refValue The reference value. Normally the size of the parent. For unit {@link #ALIGN} the current size of the component should be sent in.
* @param parent The parent. May be null
for testing the validity of the value, but should normally not and are not
* required to return any usable value if null
.
* @param comp The component, if any, that the value is for. Might be null
if the value is not
* connected to any component.
* @return The size in pixels.
*/
public final float getPixelsExact(float refValue, ContainerWrapper parent, ComponentWrapper comp)
{
if (parent == null)
return 1;
if (oper == STATIC) {
switch (unit) {
case PIXEL:
return value;
case LPX:
case LPY:
return parent.getPixelUnitFactor(unit == LPX) * value;
case MM:
case CM:
case INCH:
case PT:
float f = SCALE[unit - MM];
Float s = isHor ? PlatformDefaults.getHorizontalScaleFactor() : PlatformDefaults.getVerticalScaleFactor();
if (s != null)
f *= s;
return (isHor ? parent.getHorizontalScreenDPI() : parent.getVerticalScreenDPI()) * value / f;
case PERCENT:
return value * refValue * 0.01f;
case SPX:
case SPY:
return (unit == SPX ? parent.getScreenWidth() : parent.getScreenHeight()) * value * 0.01f;
case ALIGN:
Integer st = LinkHandler.getValue(parent.getLayout(), "visual", isHor ? LinkHandler.X : LinkHandler.Y);
Integer sz = LinkHandler.getValue(parent.getLayout(), "visual", isHor ? LinkHandler.WIDTH : LinkHandler.HEIGHT);
if (st == null || sz == null)
return 0;
return value * (Math.max(0, sz.intValue()) - refValue) + st;
case MIN_SIZE:
if (comp == null)
return 0;
return isHor ? comp.getMinimumWidth(comp.getHeight()) : comp.getMinimumHeight(comp.getWidth());
case PREF_SIZE:
if (comp == null)
return 0;
return isHor ? comp.getPreferredWidth(comp.getHeight()) : comp.getPreferredHeight(comp.getWidth());
case MAX_SIZE:
if (comp == null)
return 0;
return isHor ? comp.getMaximumWidth(comp.getHeight()) : comp.getMaximumHeight(comp.getWidth());
case BUTTON:
return PlatformDefaults.getMinimumButtonWidthIncludingPadding(refValue, parent, comp);
case LINK_X:
case LINK_Y:
case LINK_W:
case LINK_H:
case LINK_X2:
case LINK_Y2:
case LINK_XPOS:
case LINK_YPOS:
Integer v = LinkHandler.getValue(parent.getLayout(), getLinkTargetId(), unit - (unit >= LINK_XPOS ? LINK_XPOS : LINK_X));
if (v == null)
return 0;
if (unit == LINK_XPOS)
return parent.getScreenLocationX() + v;
if (unit == LINK_YPOS)
return parent.getScreenLocationY() + v;
return v;
case LOOKUP:
float res = lookup(refValue, parent, comp);
if (res != UnitConverter.UNABLE)
return res;
case LABEL_ALIGN:
return PlatformDefaults.getLabelAlignPercentage() * refValue;
case IDENTITY:
}
throw new IllegalArgumentException("Unknown/illegal unit: " + unit + ", unitStr: " + unitStr);
}
if (subUnits != null && subUnits.length == 2) {
float r1 = subUnits[0].getPixelsExact(refValue, parent, comp);
float r2 = subUnits[1].getPixelsExact(refValue, parent, comp);
switch (oper) {
case ADD:
return r1 + r2;
case SUB:
return r1 - r2;
case MUL:
return r1 * r2;
case DIV:
return r1 / r2;
case MIN:
return r1 < r2 ? r1 : r2;
case MAX:
return r1 > r2 ? r1 : r2;
case MID:
return (r1 + r2) * 0.5f;
}
}
throw new IllegalArgumentException("Internal: Unknown Oper: " + oper);
}
private float lookup(float refValue, ContainerWrapper parent, ComponentWrapper comp)
{
float res = UnitConverter.UNABLE;
for (int i = CONVERTERS.size() - 1; i >= 0; i--) {
res = CONVERTERS.get(i).convertToPixels(value, unitStr, isHor, refValue, parent, comp);
if (res != UnitConverter.UNABLE)
return res;
}
return PlatformDefaults.convertToPixels(value, unitStr, isHor, refValue, parent, comp);
}
private int parseUnitString()
{
int len = unitStr.length();
if (len == 0)
return isHor ? PlatformDefaults.getDefaultHorizontalUnit() : PlatformDefaults.getDefaultVerticalUnit();
Integer u = UNIT_MAP.get(unitStr);
if (u != null) {
if (!isHor && (u == BUTTON || u == LABEL_ALIGN))
throw new IllegalArgumentException("Not valid in vertical contexts: '" + unitStr + "'");
return u;
}
if (unitStr.equals("lp"))
return isHor ? LPX : LPY;
if (unitStr.equals("sp"))
return isHor ? SPX : SPY;
if (lookup(0, null, null) != UnitConverter.UNABLE) // To test so we can fail fast
return LOOKUP;
// Only link left. E.g. "otherID.width"
int pIx = unitStr.indexOf('.');
if (pIx != -1) {
linkId = unitStr.substring(0, pIx);
String e = unitStr.substring(pIx + 1);
if (e.equals("x"))
return LINK_X;
if (e.equals("y"))
return LINK_Y;
if (e.equals("w") || e.equals("width"))
return LINK_W;
if (e.equals("h") || e.equals("height"))
return LINK_H;
if (e.equals("x2"))
return LINK_X2;
if (e.equals("y2"))
return LINK_Y2;
if (e.equals("xpos"))
return LINK_XPOS;
if (e.equals("ypos"))
return LINK_YPOS;
}
throw new IllegalArgumentException("Unknown keyword: " + unitStr);
}
final boolean isAbsolute()
{
switch (unit) {
case PIXEL:
case LPX:
case LPY:
case MM:
case CM:
case INCH:
case PT:
return true;
case SPX:
case SPY:
case PERCENT:
case ALIGN:
case MIN_SIZE:
case PREF_SIZE:
case MAX_SIZE:
case BUTTON:
case LINK_X:
case LINK_Y:
case LINK_W:
case LINK_H:
case LINK_X2:
case LINK_Y2:
case LINK_XPOS:
case LINK_YPOS:
case LOOKUP:
case LABEL_ALIGN:
return false;
case IDENTITY:
}
throw new IllegalArgumentException("Unknown/illegal unit: " + unit + ", unitStr: " + unitStr);
}
final boolean isAbsoluteDeep()
{
if (subUnits != null) {
for (UnitValue subUnit : subUnits) {
if (subUnit.isAbsoluteDeep())
return true;
}
}
return isAbsolute();
}
final boolean isLinked()
{
return linkId != null;
}
final boolean isLinkedDeep()
{
if (subUnits != null) {
for (UnitValue subUnit : subUnits) {
if (subUnit.isLinkedDeep())
return true;
}
}
return isLinked();
}
final String getLinkTargetId()
{
return linkId;
}
final UnitValue getSubUnitValue(int i)
{
return subUnits[i];
}
final int getSubUnitCount()
{
return subUnits != null ? subUnits.length : 0;
}
public final UnitValue[] getSubUnits()
{
return subUnits != null ? subUnits.clone() : null;
}
public final int getUnit()
{
return unit;
}
public final String getUnitString()
{
return unitStr;
}
public final int getOperation()
{
return oper;
}
public final float getValue()
{
return value;
}
public final boolean isHorizontal()
{
return isHor;
}
@Override
final public String toString()
{
return getClass().getName() + ". Value=" + value + ", unit=" + unit + ", unitString: " + unitStr + ", oper=" + oper + ", isHor: " + isHor;
}
/** Returns the creation string for this object. Note that {@link LayoutUtil#setDesignTime(ContainerWrapper, boolean)} must be
* set to true
for the creation strings to be stored.
* @return The constraint string or null
if none is registered.
*/
public final String getConstraintString()
{
return LayoutUtil.getCCString(this);
}
@Override
public final int hashCode()
{
return (int) (value * 12345) + (oper >>> 5) + unit >>> 17;
}
/** Adds a global unit converter that can convert from some unit
to pixels.
*
* This converter will be asked before the platform converter so the values for it (e.g. "related" and "unrelated")
* can be overridden. It is however not possible to override the built in ones (e.g. "mm", "pixel" or "lp").
* @param conv The converter. Not null
.
*/
public synchronized static void addGlobalUnitConverter(UnitConverter conv)
{
if (conv == null)
throw new NullPointerException();
CONVERTERS.add(conv);
}
/** Removed the converter.
* @param unit The converter.
* @return If there was a converter found and thus removed.
*/
public synchronized static boolean removeGlobalUnitConverter(UnitConverter unit)
{
return CONVERTERS.remove(unit);
}
/** Returns the global converters currently registered. The platform converter will not be in this list.
* @return The converters. Never null
.
*/
public synchronized static UnitConverter[] getGlobalUnitConverters()
{
return CONVERTERS.toArray(new UnitConverter[CONVERTERS.size()]);
}
/** Returns the current default unit. The default unit is the unit used if no unit is set. E.g. "width 10".
* @return The current default unit.
* @see #PIXEL
* @see #LPX
* @deprecated Use {@link PlatformDefaults#getDefaultHorizontalUnit()} and {@link PlatformDefaults#getDefaultVerticalUnit()} instead.
*/
public static int getDefaultUnit()
{
return PlatformDefaults.getDefaultHorizontalUnit();
}
/** Sets the default unit. The default unit is the unit used if no unit is set. E.g. "width 10".
* @param unit The new default unit.
* @see #PIXEL
* @see #LPX
* @deprecated Use {@link PlatformDefaults#setDefaultHorizontalUnit(int)} and {@link PlatformDefaults#setDefaultVerticalUnit(int)} instead.
*/
public static void setDefaultUnit(int unit)
{
PlatformDefaults.setDefaultHorizontalUnit(unit);
PlatformDefaults.setDefaultVerticalUnit(unit);
}
static {
if(LayoutUtil.HAS_BEANS){
LayoutUtil.setDelegate(UnitValue.class, new PersistenceDelegate() {
@Override
protected Expression instantiate(Object oldInstance, Encoder out)
{
UnitValue uv = (UnitValue) oldInstance;
String cs = uv.getConstraintString();
if (cs == null)
throw new IllegalStateException("Design time must be on to use XML persistence. See LayoutUtil.");
return new Expression(oldInstance, ConstraintParser.class, "parseUnitValueOrAlign", new Object[] {
uv.getConstraintString(), (uv.isHorizontal() ? Boolean.TRUE : Boolean.FALSE), null
});
}
});
}
}
// ************************************************
// Persistence Delegate and Serializable combined.
// ************************************************
private static final long serialVersionUID = 1L;
private Object readResolve() throws ObjectStreamException
{
return LayoutUtil.getSerializedObject(this);
}
private void writeObject(ObjectOutputStream out) throws IOException
{
if (getClass() == UnitValue.class)
LayoutUtil.writeAsXML(out, this);
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
{
LayoutUtil.setSerializedObject(this, LayoutUtil.readAsXML(in));
}
}
miglayout-5.1/demo/000077500000000000000000000000001324101563200143125ustar00rootroot00000000000000miglayout-5.1/demo/pom.xml000077500000000000000000000044271324101563200156410ustar00rootroot00000000000000
4.0.0
com.miglayout
miglayout-parent
5.1-SNAPSHOT
../pom.xml
miglayout-demo
jar
MiGLayout Demo
MiGLayout - Demo's for Swing and SWT
org.apache.maven.plugins
maven-compiler-plugin
3.7.0
1.8
1.8
true
none
-g:none
${project.groupId}
miglayout-swing
${project.version}
${project.groupId}
miglayout-swt
${project.version}
${project.groupId}
miglayout-javafx
${project.version}
${project.groupId}
miglayout-ideutil
${project.version}
org.java.net.substance
substance
5.3
true
miglayout-5.1/demo/src/000077500000000000000000000000001324101563200151015ustar00rootroot00000000000000miglayout-5.1/demo/src/main/000077500000000000000000000000001324101563200160255ustar00rootroot00000000000000miglayout-5.1/demo/src/main/java/000077500000000000000000000000001324101563200167465ustar00rootroot00000000000000miglayout-5.1/demo/src/main/java/net/000077500000000000000000000000001324101563200175345ustar00rootroot00000000000000miglayout-5.1/demo/src/main/java/net/miginfocom/000077500000000000000000000000001324101563200216635ustar00rootroot00000000000000miglayout-5.1/demo/src/main/java/net/miginfocom/demo/000077500000000000000000000000001324101563200226075ustar00rootroot00000000000000miglayout-5.1/demo/src/main/java/net/miginfocom/demo/CallbackDemo.java000077500000000000000000000146541324101563200257700ustar00rootroot00000000000000package net.miginfocom.demo;
import net.miginfocom.layout.BoundSize;
import net.miginfocom.layout.ComponentWrapper;
import net.miginfocom.layout.LayoutCallback;
import net.miginfocom.layout.UnitValue;
import net.miginfocom.swing.MigLayout;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.IdentityHashMap;
/*
* License (BSD):
* ==============
*
* Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
* 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 the MiG InfoCom AB nor 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.
*
* @version 1.0
* @author Mikael Grev, MiG InfoCom AB
* Date: 2006-sep-08
*/
public class CallbackDemo extends JFrame implements ActionListener, MouseMotionListener, MouseListener
{
private final Timer repaintTimer = new Timer(20, new ActionListener() {
public void actionPerformed(ActionEvent e) {
((JPanel) getContentPane()).revalidate();
}
});
private final IdentityHashMap pressMap = new IdentityHashMap();
private Point mousePos = null;
public CallbackDemo()
{
super("MiG Layout Callback Demo");
MigLayout migLayout = new MigLayout("align center bottom, insets 30");
final JPanel panel = new JPanel(migLayout) {
protected void paintComponent(Graphics g)
{
((Graphics2D) g).setPaint(new GradientPaint(0, getHeight() / 2, Color.WHITE, 0, getHeight(), new Color(240, 238, 235)));
g.fillRect(0, 0, getWidth(), getHeight());
}
};
setContentPane(panel);
// This callback methods will be called for every layout cycle and let you make correction before and after the calculations.
migLayout.addLayoutCallback(new LayoutCallback() {
// This is the size change part
public BoundSize[] getSize(ComponentWrapper comp)
{
if (comp.getComponent() instanceof JButton) {
Component c = (Component) comp.getComponent();
Point p = mousePos != null ? SwingUtilities.convertPoint(panel, mousePos, c) : new Point(-1000, -1000);
float fact = (float) Math.sqrt(Math.pow(Math.abs(p.x - c.getWidth() / 2f), 2) + Math.pow(Math.abs(p.y - c.getHeight() / 2f), 2));
fact = Math.max(2 - (fact / 200), 1);
return new BoundSize[] {new BoundSize(new UnitValue(70 * fact), ""), new BoundSize(new UnitValue(70 * fact), "")};
}
return null;
}
// This is the jumping part
public void correctBounds(ComponentWrapper c)
{
Long pressedNanos = pressMap.get(c.getComponent());
if (pressedNanos != null) {
long duration = System.nanoTime() - pressedNanos;
double maxHeight = 100.0 - (duration / 100000000.0);
int deltaY = (int) Math.round(Math.abs(Math.sin((duration) / 300000000.0) * maxHeight));
c.setBounds(c.getX(), c.getY() - deltaY, c.getWidth(), c.getHeight());
if (maxHeight < 0.5) {
pressMap.remove(c.getComponent());
if (pressMap.size() == 0)
repaintTimer.stop();
}
}
}
});
for (int j = 0; j < 10; j++)
panel.add(createButton(j), "aligny 0.8al");
JLabel label = new JLabel("Press one of those Swing JButtons!");
label.setFont(new Font("verdana", Font.PLAIN, 24));
label.setForeground(new Color(150, 150, 150));
panel.add(label, "pos 0.5al 0.2al");
panel.addMouseMotionListener(this);
panel.addMouseListener(this);
}
private static Font[] FONTS = new Font[120];
private JButton createButton(int i)
{
JButton button = new JButton(String.valueOf("MIG LAYOUT".charAt(i))) {
public Font getFont()
{
if (FONTS[0] == null) {
for (int i = 0; i < FONTS.length; i++)
FONTS[i] = new Font("tahoma", Font.PLAIN, i);
}
return FONTS[getWidth() >> 1];
}
};
button.setForeground(new Color(100, 100, 100));
button.setFocusPainted(false);
button.addMouseMotionListener(this);
button.addActionListener(this);
button.setMargin(new Insets(0, 0, 0, 0));
return button;
}
public void mouseDragged(MouseEvent e) {}
public void mouseMoved(MouseEvent e)
{
if (e.getSource() instanceof JButton) {
mousePos = SwingUtilities.convertPoint((Component) e.getSource(), e.getPoint(), getContentPane());
} else {
mousePos = e.getPoint();
}
((JPanel) getContentPane()).revalidate();
}
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e)
{
mousePos = null;
((JPanel) getContentPane()).revalidate();
}
public void actionPerformed(ActionEvent e)
{
pressMap.put(e.getSource(), System.nanoTime());
repaintTimer.start();
}
public static void main(String args[])
{
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {}
CallbackDemo demoFrame = new CallbackDemo();
demoFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
demoFrame.setSize(970, 500);
demoFrame.setLocationRelativeTo(null);
demoFrame.setVisible(true);
}
}miglayout-5.1/demo/src/main/java/net/miginfocom/demo/HiDPISimulator.java000077500000000000000000000437671324101563200262730ustar00rootroot00000000000000package net.miginfocom.demo;
//import org.jvnet.substance.SubstanceLookAndFeel;
//import org.jvnet.substance.fonts.SubstanceFontUtilities;
//import org.jvnet.substance.skin.SubstanceBusinessBlackSteelLookAndFeel;
/*
* License (BSD):
* ==============
*
* Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
* 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 the MiG InfoCom AB nor 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.
*
* @version 1.0
* @author Mikael Grev, MiG InfoCom AB
* Date: 2006-sep-08
*/
// Since Substance Look & Fell is discontinued, so is this HiDPI Simulator.
/** A demo application that shows some components in a GUI and how they will look on a HiDPI screen.
*/
public class HiDPISimulator
{
// static final String SYSTEM_LAF_NAME = "System";
// static final String SUBSTANCE_LAF_NAME = "Substance";
// static final String OCEAN_LAF_NAME = "Ocean";
// static final String NUMBUS_LAF_NAME = "Nimbus (Soon..)";
//
// static JFrame APP_GUI_FRAME;
// static HiDPIDemoPanel HiDPIDEMO_PANEL;
// static JPanel SIM_PANEL;
// static JPanel MIRROR_PANEL;
// static JScrollPane MAIN_SCROLL;
// static JTextArea TEXT_AREA;
//
// static boolean SCALE_LAF = false;
// static boolean SCALE_FONTS = true;
// static boolean SCALE_LAYOUT = true;
//
// static boolean PAINT_GHOSTED = false;
//
// static BufferedImage GUI_BUF = null;
// static BufferedImage ORIG_GUI_BUF = null;
//
// static int CUR_DPI = PlatformDefaults.getDefaultDPI();
// static HashMap ORIG_DEFAULTS;
//
// private static JPanel createScaleMirror()
// {
// return new JPanel(new MigLayout()) {
// protected void paintComponent(Graphics g)
// {
// super.paintComponent(g);
//
// if (GUI_BUF != null) {
// Graphics2D g2 = (Graphics2D) g.create();
//
// double dpi = getToolkit().getScreenResolution();
//
// AffineTransform oldTrans = g2.getTransform();
// g2.scale(dpi / CUR_DPI, dpi / CUR_DPI);
//
// g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
//
// g2.drawImage(GUI_BUF, 0, 0, null);
//
// g2.setTransform(oldTrans);
//
// if (ORIG_GUI_BUF != null && PAINT_GHOSTED) {
// g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.2f));
// g2.drawImage(ORIG_GUI_BUF, 0, 0, null);
// }
//
// g2.dispose();
// }
// }
//
// public Dimension getPreferredSize()
// {
// return ORIG_GUI_BUF != null ? new Dimension(ORIG_GUI_BUF.getWidth(), ORIG_GUI_BUF.getHeight()) : new Dimension(100, 100);
// }
//
// public Dimension getMinimumSize()
// {
// return getPreferredSize();
// }
// };
// }
//
// private static JPanel createSimulator()
// {
// final JRadioButton scaleCompsFonts = new JRadioButton("UIManager Font Substitution", true);
// final JRadioButton scaleCompsLaf = new JRadioButton("Native Look&Feel Scaling", false);
// final JRadioButton scaleCompsNone = new JRadioButton("No Scaling", false);
// final JRadioButton scaleLayoutMig = new JRadioButton("Native MigLayout Gap Scaling", true);
// final JRadioButton scaleLayoutNone = new JRadioButton("No Gap Scaling", false);
// final JComboBox lafCombo = new JComboBox(new String[] {SYSTEM_LAF_NAME, SUBSTANCE_LAF_NAME, OCEAN_LAF_NAME, NUMBUS_LAF_NAME});
//
// final ButtonGroup bg1 = new ButtonGroup();
// final ButtonGroup bg2 = new ButtonGroup();
// final JCheckBox ghostCheck = new JCheckBox("Overlay \"Optimal\" HiDPI Result");
//
// scaleCompsLaf.setEnabled(false);
//
// bg1.add(scaleCompsFonts);
// bg1.add(scaleCompsLaf);
// bg1.add(scaleCompsNone);
//
// bg2.add(scaleLayoutMig);
// bg2.add(scaleLayoutNone);
//
// Vector dpiStrings = new Vector();
//
// for (float f = 0.5f; f < 2.01f; f += 0.1f)
// dpiStrings.add(Math.round(PlatformDefaults.getDefaultDPI() * f) + " DPI (" + Math.round(f * 100f + 0.499f) + "%)");
//
// final JComboBox dpiCombo = new JComboBox(dpiStrings);
// dpiCombo.setSelectedIndex(5);
//
// JPanel panel = new JPanel(new MigLayout("alignx center, insets 10px, flowy", "[]", "[]3px[]0px[]"));
//
// JLabel lafLabel = new JLabel("Look & Feel:");
// JLabel sliderLabel = new JLabel("Simulated DPI:");
// JLabel scaleLabel = new JLabel("Component/Text Scaling:");
// JLabel layoutLabel = new JLabel("LayoutManager Scaling:");
// JLabel visualsLabel = new JLabel("Visual Aids:");
//
// panel.add(lafLabel, "");
// panel.add(lafCombo, "wrap");
//
// panel.add(sliderLabel, "");
// panel.add(dpiCombo, "wrap");
//
// panel.add(scaleLabel, "");
// panel.add(scaleCompsFonts, "");
// panel.add(scaleCompsLaf, "");
// panel.add(scaleCompsNone, "wrap");
//
// panel.add(layoutLabel, "");
// panel.add(scaleLayoutMig, "");
// panel.add(scaleLayoutNone, "wrap");
//
// panel.add(visualsLabel, "");
// panel.add(ghostCheck, "");
//
// lockFont(dpiCombo, scaleCompsFonts, scaleCompsLaf, scaleLayoutMig, scaleCompsNone, lafCombo, ghostCheck, panel, lafLabel, sliderLabel, scaleLayoutNone, scaleLabel, layoutLabel, visualsLabel);
//
// lafCombo.addActionListener(new ActionListener() {
// public void actionPerformed(ActionEvent e)
// {
// GUI_BUF = null;
// try {
// Object s = lafCombo.getSelectedItem();
//
// dpiCombo.setSelectedIndex(5);
//
// if (s.equals(SYSTEM_LAF_NAME)) {
// UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
// } else if (s.equals(SUBSTANCE_LAF_NAME)) {
// UIManager.setLookAndFeel(new SubstanceBusinessBlackSteelLookAndFeel());
// } else if (s.equals(OCEAN_LAF_NAME)) {
// UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
// } else {
// JOptionPane.showMessageDialog(APP_GUI_FRAME, "Nimbus will be included as soon as it is ready!");
// }
//
// if (ORIG_DEFAULTS != null) {
// for (String key : ORIG_DEFAULTS.keySet())
// UIManager.put(key, null);
// }
// ORIG_DEFAULTS = null;
//
// if (UIManager.getLookAndFeel().getName().toLowerCase().contains("windows")) {
// UIManager.put("TextArea.font", UIManager.getFont("TextField.font"));
// } else {
// UIManager.put("TextArea.font", null);
// }
//
// SwingUtilities.updateComponentTreeUI(APP_GUI_FRAME);
// MAIN_SCROLL.setBorder(null);
//
// if (s.equals(SYSTEM_LAF_NAME)) {
// if (scaleCompsLaf.isSelected())
// scaleCompsFonts.setSelected(true);
//
// scaleCompsLaf.setEnabled(false);
//
// } else if (s.equals(SUBSTANCE_LAF_NAME)) {
// scaleCompsLaf.setEnabled(true);
//
// } else if (s.equals(OCEAN_LAF_NAME)) {
// if (scaleCompsLaf.isSelected())
// scaleCompsFonts.setSelected(true);
// scaleCompsLaf.setEnabled(false);
// }
//
// setDPI(CUR_DPI);
//
// } catch (Exception ex) {
// ex.printStackTrace();
// }
// }
// });
//
// ghostCheck.addActionListener(new ActionListener() {
// public void actionPerformed(ActionEvent actionEvent)
// {
// GUI_BUF = null;
// PAINT_GHOSTED = ghostCheck.isSelected();
// APP_GUI_FRAME.repaint();
// }
// });
//
// scaleLayoutMig.addItemListener(new ItemListener() {
// public void itemStateChanged(ItemEvent e)
// {
// GUI_BUF = null;
// SCALE_LAYOUT = scaleLayoutMig.isSelected();
// setDPI(CUR_DPI);
// }
// });
//
// ItemListener il = new ItemListener() {
// public void itemStateChanged(ItemEvent e)
// {
// if (e.getStateChange() == ItemEvent.SELECTED) {
// GUI_BUF = null;
// SCALE_LAF = scaleCompsLaf.isSelected();
// SCALE_FONTS = scaleCompsFonts.isSelected();
// setDPI(CUR_DPI);
// }
// }
// };
//
// scaleCompsLaf.addItemListener(il);
// scaleCompsFonts.addItemListener(il);
// scaleCompsNone.addItemListener(il);
//
// dpiCombo.addItemListener(new ItemListener() {
// public void itemStateChanged(ItemEvent e)
// {
// if (e.getStateChange() == ItemEvent.SELECTED) {
// GUI_BUF = null;
// CUR_DPI = Integer.parseInt(dpiCombo.getSelectedItem().toString().substring(0, 3).trim());
// setDPI(CUR_DPI);
// }
// }
// });
//
// return panel;
// }
//
// private static void lockFont(Component ... comps)
// {
// for (Component c : comps) {
// Font f = c.getFont();
// c.setFont(f.deriveFont((float) f.getSize()));
// }
// }
//
// private static void revalidateGUI()
// {
// APP_GUI_FRAME.getContentPane().invalidate();
// APP_GUI_FRAME.repaint();
// }
//
// private synchronized static void setDPI(int dpi)
// {
// float scaleFactor = dpi / (float) Toolkit.getDefaultToolkit().getScreenResolution();
// TEXT_AREA.setSize(0, 0); // To reset for Swing TextArea horizontal size bug...
// PlatformDefaults.setHorizontalScaleFactor(.1f);// Only so that the cache will be invalidated for sure
// PlatformDefaults.setHorizontalScaleFactor(SCALE_LAYOUT ? scaleFactor : null);
// PlatformDefaults.setVerticalScaleFactor(SCALE_LAYOUT ? scaleFactor : null);
//
// float fontScale = SCALE_FONTS ? dpi / (float) Toolkit.getDefaultToolkit().getScreenResolution() : 1f;
//
// if (ORIG_DEFAULTS == null) {
// ORIG_DEFAULTS = new HashMap();
//
// Set entries = new HashSet(UIManager.getLookAndFeelDefaults().keySet());
// for (Iterator it = entries.iterator(); it.hasNext();) {
// String key = it.next().toString();
// Object value = UIManager.get(key);
//
// if (value instanceof Font)
// ORIG_DEFAULTS.put(key, (Font) value);
// }
// }
//
// Set entries = ORIG_DEFAULTS.entrySet();
// for (Iterator> it = entries.iterator(); it.hasNext();) {
// Map.Entry e = it.next();
// Font origFont = e.getValue();
//
// if (SCALE_LAF == false) {
// UIManager.put(e.getKey(), new FontUIResource(origFont.deriveFont(origFont.getSize() * fontScale)));
// } else {
// UIManager.put(e.getKey(), null);
// }
// }
//
// if (SCALE_LAF) {
// scaleSubstanceLAF(scaleFactor);
// } else if (UIManager.getLookAndFeel().getName().toLowerCase().contains("substance")) {
// scaleSubstanceLAF(1);
// }
//
// SwingUtilities.updateComponentTreeUI(HiDPIDEMO_PANEL);
// revalidateGUI();
// }
//
// private static void scaleSubstanceLAF(float factor)
// {
// SubstanceLookAndFeel.setFontPolicy(SubstanceFontUtilities.getScaledFontPolicy(factor));
//
// try {
// UIManager.setLookAndFeel(new SubstanceBusinessBlackSteelLookAndFeel());
// } catch (Exception exc) {
// }
//
// SwingUtilities.updateComponentTreeUI(APP_GUI_FRAME);
// MAIN_SCROLL.setBorder(null);
// }
//
// public static void main(String[] args)
// {
// try {
// System.setProperty("apple.laf.useScreenMenuBar", "true");
// System.setProperty("com.apple.mrj.application.apple.menu.about.name", "HiDPI Simulator");
// } catch(Exception ex) {}
//
// PlatformDefaults.setDefaultHorizontalUnit(UnitValue.LPX);
// PlatformDefaults.setDefaultVerticalUnit(UnitValue.LPY);
//
// SwingUtilities.invokeLater(new Runnable() {
// public void run() {
// try {
//// UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
// UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
// } catch (Exception ex) {
// ex.printStackTrace();
// }
//
// if (UIManager.getLookAndFeel().getName().toLowerCase().contains("windows"))
// UIManager.put("TextArea.font", UIManager.getFont("TextField.font"));
//
// APP_GUI_FRAME = new JFrame("Resolution Independence Simulator");
//
//// RepaintManager.currentManager(APP_GUI_FRAME).setDoubleBufferingEnabled(false);
//
// JPanel uberPanel = new JPanel(new MigLayout("fill, insets 0px, nocache"));
//
// JPanel mainPanel = new JPanel(new MigLayout("fill, insets 0px, nocache")) {
// public void paintComponent(Graphics g)
// {
// Graphics2D g2 = (Graphics2D) g.create();
//
// g2.setPaint(new GradientPaint(0, 0, new Color(20, 20, 30), 0, getHeight(), new Color(90, 90, 110), false));
// g2.fillRect(0, 0, getWidth(), getHeight());
//
// g2.setFont(g2.getFont().deriveFont(Font.BOLD, 13));
// g2.setPaint(Color.WHITE);
// g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
//
// g2.drawString("Left panel shows the scaled version. Right side shows how this would look on a HiDPI screen. It should look the same as the original panel!", 10, 19);
//
// g2.dispose();
// }
// };
//
// HiDPIDEMO_PANEL = new HiDPIDemoPanel();
// SIM_PANEL = createSimulator();
// MIRROR_PANEL = createScaleMirror();
//
// MAIN_SCROLL = new JScrollPane(mainPanel);
// MAIN_SCROLL.setBorder(null);
//
// mainPanel.add(HiDPIDEMO_PANEL, "align center center, split, span, width pref!");
// mainPanel.add(MIRROR_PANEL, "id mirror, gap 20px!, width pref!");
//
// uberPanel.add(SIM_PANEL, "dock south");
// uberPanel.add(MAIN_SCROLL, "dock center");
//
// Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
// APP_GUI_FRAME.setContentPane(uberPanel);
// APP_GUI_FRAME.setSize(Math.min(1240, screenSize.width), Math.min(950, screenSize.height - 30));
// APP_GUI_FRAME.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
// APP_GUI_FRAME.setLocationRelativeTo(null);
// APP_GUI_FRAME.setVisible(true);
// }
// });
// }
//}
//
//class HiDPIDemoPanel extends JPanel {
// public HiDPIDemoPanel()
// {
// super(new MigLayout());
//
// JLabel jLabel1 = new JLabel("A Small Label:");
// JTextField jTextField1 = new JTextField(10);
// JButton jButton1 = new JButton("Cancel");
// JButton jButton2 = new JButton("OK");
// JButton jButton4 = new JButton("Help");
// JList jList1 = new JList();
// JLabel jLabel2 = new JLabel("Label:");
// JTextField jTextField2 = new JTextField(10);
// JLabel jLabel3 = new JLabel("This is another section");
// JSeparator jSeparator1 = new JSeparator();
// JTextArea jTextArea1 = new JTextArea("Some general text that takes place, doesn't offend anyone and fills some pixels.", 3, 30); // colums set always!
// JLabel jLabel4 = new JLabel("Some Text Area");
// JLabel jLabel6 = new JLabel("Some List:");
// JComboBox jComboBox1 = new JComboBox();
// JCheckBox jCheckBox1 = new JCheckBox("Orange");
//
// JScrollBar scroll1 = new JScrollBar(JScrollBar.VERTICAL);
// JScrollBar scroll2 = new JScrollBar(JScrollBar.HORIZONTAL, 30, 40, 0, 100);
// JRadioButton radio = new JRadioButton("Apple");
// JProgressBar prog = new JProgressBar();
// prog.setValue(50);
// JSpinner spinner = new JSpinner(new SpinnerNumberModel(50, 0, 100, 1));
// JTree tree = new JTree();
// tree.setOpaque(false);
// tree.setEnabled(false);
//
// jList1.setModel(new AbstractListModel() {
// String[] strings = { "Donald Duck", "Mickey Mouse", "Pluto", "Cartman" };
// public int getSize() { return strings.length; }
// public Object getElementAt(int i) { return strings[i]; }
// });
//
// jList1.setVisibleRowCount(4);
// jList1.setBorder(new LineBorder(Color.GRAY));
// jTextArea1.setLineWrap(true);
// jTextArea1.setWrapStyleWord(true);
// jTextArea1.setBorder(new LineBorder(Color.GRAY));
// jComboBox1.setModel(new DefaultComboBoxModel(new String[] {"Text in ComboBox"}));
// jCheckBox1.setMargin(new java.awt.Insets(0, 0, 0, 0));
//
// add(jLabel1, "split, span");
// add(jTextField1, "");
// add(jLabel2, "gap unrelated");
// add(jTextField2, "wrap");
// add(jLabel3, "split, span");
// add(jSeparator1, "growx, span, gap 2, wrap unrelated");
// add(jLabel4, "wrap 2");
// add(jTextArea1, "span, wmin 150, wrap unrelated");
// add(jLabel6, "wrap 2");
// add(jList1, "split, span");
// add(scroll1, "growy");
// add(prog, "width 80!");
// add(tree, "wrap unrelated");
//
// add(scroll2, "split, span, growx");
// add(spinner, "wrap unrelated");
// add(jComboBox1, "span, split");
// add(radio, "");
// add(jCheckBox1, "wrap unrelated");
// add(jButton4, "split, span, tag help2");
// add(jButton2, "tag ok");
// add(jButton1, "tag cancel");
//
// HiDPISimulator.TEXT_AREA = jTextArea1;
// }
//
// public void paint(Graphics g)
// {
// if (HiDPISimulator.GUI_BUF == null) {
// BufferedImage bi = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
//
// Graphics2D g2 = bi.createGraphics();
//
// super.paint(g2);
//
// g2.dispose();
//
// g.drawImage(bi, 0, 0, null);
//
// HiDPISimulator.GUI_BUF = bi;
//
// if (HiDPISimulator.CUR_DPI == PlatformDefaults.getDefaultDPI())
// HiDPISimulator.ORIG_GUI_BUF = bi;
//
// SwingUtilities.invokeLater(new Runnable() {
// public void run() {
// HiDPISimulator.MIRROR_PANEL.revalidate();
// HiDPISimulator.MIRROR_PANEL.repaint();
// }
// });
// } else {
// super.paint(g);
// }
// }
}
miglayout-5.1/demo/src/main/java/net/miginfocom/demo/JavaFXCallbackDemo.java000066400000000000000000000134751324101563200270250ustar00rootroot00000000000000package net.miginfocom.demo;
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.geometry.Point2D;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.scene.paint.CycleMethod;
import javafx.scene.paint.LinearGradient;
import javafx.scene.paint.Stop;
import javafx.scene.text.Font;
import javafx.stage.Stage;
import net.miginfocom.layout.BoundSize;
import net.miginfocom.layout.ComponentWrapper;
import net.miginfocom.layout.LayoutCallback;
import net.miginfocom.layout.UnitValue;
import org.tbee.javafx.scene.layout.MigPane;
import java.util.IdentityHashMap;
/*
* License (BSD):
* ==============
*
* Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
* 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 the MiG InfoCom AB nor 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.
*
* @version 1.0
* @author Mikael Grev, MiG InfoCom AB
* Date: 2006-sep-08
*/
public class JavaFXCallbackDemo extends Application
{
private AnimationTimer layoutTimer;
private final IdentityHashMap jumpingMap = new IdentityHashMap<>();
private Point2D mousePos = null;
private MigPane migPane = null;
private Button createButton(int i)
{
Button button = new Button(String.valueOf("MIG LAYOUT".charAt(i)));
button.setOnAction(event -> {
jumpingMap.put(button, System.nanoTime());
layoutTimer.start();
});
button.addEventHandler(MouseEvent.MOUSE_MOVED, (MouseEvent event) -> {
mousePos = button.localToParent(event.getX(), event.getY());
migPane.requestLayout();
});
button.widthProperty().addListener((observable, oldValue, newValue) -> {
button.setFont(new Font(newValue.doubleValue() / 4));
});
button.setTextFill(Color.rgb(100, 100, 100));
button.setFont(new Font(24));
return button;
}
public void start(Stage stage) {
migPane = new MigPane("align center bottom, insets 80");
// This callback methods will be called for every layout cycle and let you make correction before and after the calculations.
migPane.addLayoutCallback(new LayoutCallback() {
// This is the size change part
public BoundSize[] getSize(ComponentWrapper wrapper)
{
if (wrapper.getComponent() instanceof Button) {
Button c = (Button) wrapper.getComponent();
Point2D p = mousePos != null ? c.parentToLocal(mousePos) : new Point2D(-1000, -1000);
double fact = Math.sqrt(Math.pow(Math.abs(p.getX() - c.getWidth() / 2f), 2) + Math.pow(Math.abs(p.getY() - c.getHeight() / 2f), 2));
fact = Math.max(2 - (fact / 200), 1);
return new BoundSize[] {new BoundSize(new UnitValue((float) (70 * fact)), ""), new BoundSize(new UnitValue((float) (70 * fact)), "")};
}
return null;
}
// This is the jumping part
public void correctBounds(ComponentWrapper wrapper)
{
Long pressedNanos = jumpingMap.get(wrapper.getComponent());
if (pressedNanos != null) {
long duration = System.nanoTime() - pressedNanos;
double maxHeight = 100.0 - (duration / 70000000.0);
int deltaY = (int) Math.round(Math.abs(Math.sin((duration) / 300000000.0) * maxHeight));
wrapper.setBounds(wrapper.getX(), wrapper.getY() - deltaY, wrapper.getWidth(), wrapper.getHeight());
if (maxHeight < 0.5) {
jumpingMap.remove(wrapper.getComponent());
if (jumpingMap.isEmpty())
layoutTimer.stop();
}
}
}
});
for (int j = 0; j < 10; j++)
migPane.add(createButton(j), "aligny 0.8al");
Label label = new Label("Press one of those Buttons!");
label.setFont(new Font(24));
label.setTextFill(Color.rgb(150, 150, 150));
migPane.add(label, "pos 0.5al 0al");
migPane.addEventHandler(MouseEvent.MOUSE_MOVED, (MouseEvent event) -> {
mousePos = new Point2D(event.getX(), event.getY());
migPane.requestLayout();
});
migPane.addEventHandler(MouseEvent.MOUSE_EXITED, event -> {
mousePos = null;
migPane.requestLayout();
});
// create scene
Scene scene = new Scene(migPane, -1, 450);
scene.setFill(new LinearGradient(0, 0, 0, 500, true, CycleMethod.NO_CYCLE, new Stop(0, Color.WHITE), new Stop(1, Color.rgb(240, 238, 235))));
// create stage
stage.setTitle("Callback Demo");
stage.setScene(scene);
stage.sizeToScene();
stage.show();
layoutTimer = new AnimationTimer() {
public void handle(long now) {
migPane.requestLayout();
}
};
}
public static void main(String[] args) {
launch(args);
}
}miglayout-5.1/demo/src/main/java/net/miginfocom/demo/SwingDemo.java000077500000000000000000005157331324101563200253670ustar00rootroot00000000000000package net.miginfocom.demo;
import net.miginfocom.layout.*;
import net.miginfocom.swing.MigLayout;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.border.EtchedBorder;
import javax.swing.border.LineBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
import java.awt.event.*;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Random;
/*
* License (BSD):
* ==============
*
* Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
* 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 the MiG InfoCom AB nor 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.
*
* @version 1.0
* @author Mikael Grev, MiG InfoCom AB
* Date: 2006-sep-08
*/
public class SwingDemo extends JFrame
{
public static final int INITIAL_INDEX = 0;
private static final boolean DEBUG = false;
private static final boolean OPAQUE = false;
private static final String[][] panels = new String[][] {
// {"Test", "BugTestApp, disregard"},
{"Welcome", "\n\n \"MigLayout makes complex layouts easy and normal layouts one-liners.\""},
{"Quick Start", "This is an example of how to build a common dialog type. Note that there are no special components, nested panels or absolute references to cell positions. If you look at the source code you will see that the layout code is very simple to understand."},
{"Plain", "A simple example on how simple it is to create normal forms. No builders needed since the whole layout manager works like a builder."},
{"Alignments", "Shows how the alignment of components are specified. At the top/left is the alignment for the column/row. The components have no alignments specified.\n\nNote that baseline alignment will be interpreted as 'center' before JDK 6."},
{"Cell Alignments", "Shows how components are aligned when both column/row alignments and component constraints are specified. At the top/left are the alignment for the column/row and the text on the buttons is the component constraint that will override the column/row alignment if it is an alignment.\n\nNote that baseline alignment will be interpreted as 'center' before JDK 6."},
{"Basic Sizes", "A simple example that shows how to use the column or row min/preferred/max size to set the sizes of the contained components and also an example that shows how to do this directly in the component constraints."},
{"Growing", "A simple example that shows how to use the growx and growy constraint to set the sizes and how they should grow to fit the available size. Both the column/row and the component grow/shrink constraints can be set, but the components will always be confined to the space given by its column/row."},
{"Grow Shrink", "Demonstrates the very flexible grow and shrink constraints that can be set on a component.\nComponents can be divided into grow/shrink groups and also have grow/shrink weight within each of those groups.\n\nBy default " +
"components shrink to their inherent (or specified) minimum size, but they don't grow."},
{"Span", "This example shows the powerful spanning and splitting that can be specified in the component constraints. With spanning any number of cells can be merged with the additional option to split that space for more than one component. This makes layouts very flexible and reduces the number of times you will need nested panels to very few."},
{"Flow Direction", "Shows the different flow directions. Flow direction for the layout specifies if the next cell will be in the x or y dimension. Note that it can be a different flow direction in the slit cell (the middle cell is slit in two). Wrap is set to 3 for all panels."},
{"Grouping", "Sizes for both components and columns/rows can be grouped so they get the same size. For instance buttons in a button bar can be given a size-group so that they will all get " +
"the same minimum and preferred size (the largest within the group). Size-groups can be set for the width, height or both."},
{"Units", "Demonstrates the basic units that are understood by MigLayout. These units can be extended by the user by adding one or more UnitConverter(s)."},
{"Component Sizes", "Minimum, preferred and maximum component sizes can be overridden in the component constraints using any unit type. The format to do this is short and simple to understand. You simply specify the " +
"min, preferred and max sizes with a colon between.\n\nAbove are some examples of this. An exclamation mark means that the value will be used for all sizes."},
{"Bound Sizes", "Shows how to create columns that are stable between tabs using minimum sizes."},
{"Cell Position", "Even though MigLayout has automatic grid flow you can still specify the cell position explicitly. You can even combine absolute (x, y) and flow (skip, wrap and newline) constraints to build your layout."},
{"Orientation", "MigLayout supports not only right-to-left orientation, but also bottom-to-top. You can even set the flow direction so that the flow is vertical instead of horizontal. It will automatically " +
"pick up if right-to-left is to be used depending on the ComponentWrapper, but it can also be manually set for every layout."},
{"Absolute Position", "Demonstrates the option to place any number of components using absolute coordinates. This can be just the position (if min/preferred size) using \"x y p p\" format or" +
"the bounds using the \"x1 y1 x2 y2\" format. Any unit can be used and percent is relative to the parent.\nAbsolute components will not disturb the flow or occupy cells in the grid. " +
"Absolute positioned components will be taken into account when calculating the container's preferred size."},
{"Component Links", "Components can be linked to any side of any other component. It can be a forward, backward or cyclic link references, as long as it is stable and won't continue to change value over many iterations." +
"Links are referencing the ID of another component. The ID can be overridden by the component's constrains or is provided by the ComponentWrapper. For instance it will use the component's 'name' on Swing.\n" +
"Since the links can be combined with any expression (such as 'butt1.x+10' or 'max(button.x, 200)' the links are very customizable."},
{"Docking", "Docking components can be added around the grid. The docked component will get the whole width/height on the docked side by default, however this can be overridden. When all docked components are laid out, whatever space " +
"is left will be available for the normal grid laid out components. Docked components does not in any way affect the flow in the grid.\n\nSince the docking runs in the same code path " +
"as the normal layout code the same properties can be specified for the docking components. You can for instance set the sizes and alignment or link other components to their docked component's bounds."},
{"Button Bars", "Button order is very customizable and are by default different on the supported platforms. E.g. Gaps, button order and minimum button size are properties that are 'per platform'. MigLayout picks up the current platform automatically and adjusts the button order and minimum button size accordingly, all without using a button builder or any other special code construct."},
{"Visual Bounds", "Human perceptible bounds may not be the same as the mathematical bounds for the component. This is for instance the case if there is a drop shadow painted by the component's border. MigLayout can compensate " +
"for this in a simple way. Note the top middle tab-component, it is not aligned visually correct on Windows XP. For the second tab the bounds are corrected automatically on Windows XP."},
{"Debug", "Demonstrates the non-intrusive way to get visual debugging aid. There is no need to use a special DebugPanel or anything that will need code changes. The user can simply turn on debug on the layout manager by using the \"debug\" constraint and it will " +
"continuously repaint the panel with debug information on top. This means you don't have to change your code to debug!"},
{"Layout Showdown", "This is an implementation of the Layout Showdown posted on java.net by John O'Conner. The first tab is a pure implementation of the showdown that follows all the rules. The second tab is a slightly fixed version that follows some improved layout guidelines." +
"The source code is for both the first and for the fixed version. Note the simplification of the code for the fixed version. Writing better layouts with MiG Layout is easier that writing bad.\n\nReference: http://weblogs.java.net/blog/joconner/archive/2006/10/more_informatio.html"},
{"API Constraints1", "This dialog shows the constraint API added to v2.0. It works the same way as the string constraints but with chained method calls. See the source code for details."},
{"API Constraints2", "This dialog shows the constraint API added to v2.0. It works the same way as the string constraints but with chained method calls. See the source code for details."}
};
private int lastIndex = -10;
private JPanel contentPanel = DEBUG ? new JPanel(new BorderLayout()) : new JPanel(new MigLayout("wrap", "[]unrel[grow]", "[grow][pref]"));
private JTabbedPane layoutPickerTabPane = new JTabbedPane();
private JList pickerList = new JList(new DefaultListModel());
private JTabbedPane southTabPane = new JTabbedPane();
private JScrollPane descrTextAreaScroll = createTextAreaScroll("", 5, 80, true);
private JTextArea descrTextArea = (JTextArea) descrTextAreaScroll.getViewport().getView();
private JScrollPane sourceTextAreaScroll = null;
private JTextArea sourceTextArea = null;
private JPanel layoutDisplayPanel = new JPanel(new BorderLayout(0, 0));
private static boolean buttonOpaque = true;
private static boolean contentAreaFilled = true;
private JFrame sourceFrame = null;
private JTextArea sourceFrameTextArea = null;
private static int benchRuns = 0;
private static long startupMillis = 0;
private static long timeToShowMillis = 0;
private static long benchRunTime = 0;
private static String benchOutFileName = null;
private static boolean append = false;
private static long lastRunTimeStart = 0;
private static StringBuffer runTimeSB = null;
public static void main(String args[])
{
try {
System.setProperty("apple.laf.useScreenMenuBar", "true");
System.setProperty("com.apple.mrj.application.apple.menu.about.name", "MiGLayout Swing Demo");
} catch(Throwable ex) {
// Beacuse we did not have permissions.
}
startupMillis = System.currentTimeMillis();
String laf = UIManager.getSystemLookAndFeelClassName();
if (args.length > 0) {
for (int i = 0; i 0)
// RepaintManager.currentManager(this).setDoubleBufferingEnabled(false);
if (benchRuns == 0) {
sourceTextAreaScroll = createTextAreaScroll("", 5, 80, true);
sourceTextArea = (JTextArea) sourceTextAreaScroll.getViewport().getView();
}
if (DEBUG) {
contentPanel.add(layoutDisplayPanel, BorderLayout.CENTER);
// contentPanel.add(layoutPickerTabPane, BorderLayout.WEST);
// contentPanel.add(descriptionTabPane, BorderLayout.SOUTH);
} else {
contentPanel.add(layoutPickerTabPane, "spany,grow");
contentPanel.add(layoutDisplayPanel, "grow");
contentPanel.add(southTabPane, "growx");
}
setContentPane(contentPanel);
pickerList.setOpaque(OPAQUE);
((DefaultListCellRenderer) pickerList.getCellRenderer()).setOpaque(OPAQUE);
pickerList.setSelectionForeground(new Color(0, 0, 220));
pickerList.setBackground(null);
pickerList.setBorder(new EmptyBorder(2, 5, 0, 4));
pickerList.setFont(pickerList.getFont().deriveFont(Font.BOLD));
layoutPickerTabPane.addTab("Example Browser", pickerList);
descrTextAreaScroll.setBorder(null);
descrTextAreaScroll.setOpaque(OPAQUE);
descrTextAreaScroll.getViewport().setOpaque(OPAQUE);
descrTextArea.setOpaque(OPAQUE);
descrTextArea.setEditable(false);
descrTextArea.setBorder(new EmptyBorder(0, 4, 0, 4));
southTabPane.addTab("Description", descrTextAreaScroll);
if (sourceTextArea != null) {
sourceTextAreaScroll.setBorder(null);
sourceTextAreaScroll.setOpaque(OPAQUE);
sourceTextAreaScroll.getViewport().setOpaque(OPAQUE);
sourceTextAreaScroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
sourceTextArea.setOpaque(OPAQUE);
sourceTextArea.setLineWrap(false);
sourceTextArea.setWrapStyleWord(false);
sourceTextArea.setEditable(false);
sourceTextArea.setBorder(new EmptyBorder(0, 4, 0, 4));
sourceTextArea.setFont(new Font("monospaced", Font.PLAIN, 11));
southTabPane.addTab("Source Code", sourceTextAreaScroll);
southTabPane.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e)
{
if (e.getClickCount() == 2)
showSourceInFrame();
}
});
}
for (int i = 0; i < panels.length; i++)
((DefaultListModel) pickerList.getModel()).addElement(panels[i][0]);
try {
if (UIManager.getLookAndFeel().getID().equals("Aqua")) {
setSize(1000, 750);
} else {
setSize(900, 650);
}
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
} catch(Throwable t) {
t.printStackTrace();
System.exit(1);
}
pickerList.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e)
{
int ix = pickerList.getSelectedIndex();
if (ix == -1 || lastIndex == ix)
return;
lastIndex = ix;
String methodName = "create" + panels[ix][0].replace(' ', '_');
layoutDisplayPanel.removeAll();
try {
pickerList.requestFocusInWindow();
final JComponent panel = (JComponent) SwingDemo.class.getMethod(methodName, new Class[0]).invoke(SwingDemo.this, new Object[0]);
layoutDisplayPanel.add(panel);
descrTextArea.setText(panels[ix][1]);
descrTextArea.setCaretPosition(0);
contentPanel.revalidate();
} catch (Exception e1) {
e1.printStackTrace(); // Should never happen...
}
southTabPane.setSelectedIndex(0);
}
});
pickerList.requestFocusInWindow();
Toolkit.getDefaultToolkit().setDynamicLayout(true);
if (benchRuns > 0) {
doBenchmark();
} else {
pickerList.setSelectedIndex(INITIAL_INDEX);
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new KeyEventDispatcher() {
public boolean dispatchKeyEvent(KeyEvent e)
{
if (e.getID() == KeyEvent.KEY_PRESSED && e.getKeyCode() == KeyEvent.VK_B && (e.getModifiersEx() & KeyEvent.CTRL_DOWN_MASK) > 0) {
startupMillis = System.currentTimeMillis();
timeToShowMillis = System.currentTimeMillis() - startupMillis;
benchRuns = 1;
doBenchmark();
return true;
}
return false;
}
});
}
}
private void doBenchmark()
{
Thread benchThread = new Thread() {
public void run()
{
for (int j = 0; j < benchRuns; j++) {
lastRunTimeStart = System.currentTimeMillis();
for (int i = 0, iCnt = pickerList.getModel().getSize(); i < iCnt; i++) {
if (benchRuns > 0 && panels[i][0].equals("Visual Bounds"))
continue; // the SWT version does not have Visual bounds...
final int ii = i;
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
pickerList.setSelectedIndex(ii);
Toolkit.getDefaultToolkit().sync();
}
});
} catch (Exception e) {
e.printStackTrace();
}
Component[] comps = layoutDisplayPanel.getComponents();
for (int cIx = 0; cIx < comps.length; cIx++) {
if (comps[cIx] instanceof JTabbedPane) {
final JTabbedPane tp = (JTabbedPane) comps[cIx];
for (int k = 0, kCnt = tp.getTabCount(); k < kCnt; k++) {
final int kk = k;
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
tp.setSelectedIndex(kk);
Toolkit.getDefaultToolkit().sync();
if (timeToShowMillis == 0)
timeToShowMillis = System.currentTimeMillis() - startupMillis;
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
if (runTimeSB != null) {
runTimeSB.append("Run ").append(j).append(": ");
runTimeSB.append(System.currentTimeMillis() - lastRunTimeStart).append(" millis.\n");
}
}
benchRunTime = System.currentTimeMillis() - startupMillis - timeToShowMillis;
final String message = "Java Version: " + System.getProperty("java.version") + "\n" +
"Look & Feel: " + UIManager.getLookAndFeel().getDescription() + "\n" +
"Time to Show: " + timeToShowMillis + " millis.\n" +
(runTimeSB != null ? runTimeSB.toString() : "") +
"Benchmark Run Time: " + benchRunTime + " millis.\n" +
"Average Run Time: " + (benchRunTime / benchRuns) + " millis (" + benchRuns + " runs).\n\n";
if (benchOutFileName == null) {
JOptionPane.showMessageDialog(SwingDemo.this, message, "Results", JOptionPane.INFORMATION_MESSAGE);
} else {
FileWriter fw = null;
try {
fw = new FileWriter(benchOutFileName, append);
fw.write(message);
} catch(IOException ex) {
ex.printStackTrace();
} finally {
if (fw != null)
try {fw.close();} catch(IOException ex) {}
}
}
System.out.println(message);
}
};
benchThread.start();
}
private void setSource(String source)
{
if (benchRuns > 0 || sourceTextArea == null)
return;
if (source.length() > 0) {
source = source.replaceAll("\t\t", "");
source = "DOUBLE CLICK TAB TO SHOW SOURCE IN SEPARATE WINDOW!\n===================================================\n\n" + source;
}
sourceTextArea.setText(source);
sourceTextArea.setCaretPosition(0);
if (sourceFrame != null && sourceFrame.isVisible()) {
sourceFrameTextArea.setText(source.length() > 105 ? source.substring(105) : "No Source Code Available!");
sourceFrameTextArea.setCaretPosition(0);
}
}
private void showSourceInFrame()
{
if (sourceTextArea == null)
return;
JScrollPane sourceFrameTextAreaScroll = createTextAreaScroll("", 5, 80, true);
sourceFrameTextArea = (JTextArea) sourceFrameTextAreaScroll.getViewport().getView();
sourceFrameTextAreaScroll.setBorder(null);
sourceFrameTextAreaScroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
sourceFrameTextArea.setLineWrap(false);
sourceFrameTextArea.setWrapStyleWord(false);
sourceFrameTextArea.setEditable(false);
sourceFrameTextArea.setBorder(new EmptyBorder(10, 10, 10, 10));
sourceFrameTextArea.setFont(new Font("monospaced", Font.PLAIN, 12));
String source = this.sourceTextArea.getText();
sourceFrameTextArea.setText(source.length() > 105 ? source.substring(105) : "No Source Code Available!");
sourceFrameTextArea.setCaretPosition(0);
sourceFrame = new JFrame("Source Code");
sourceFrame.getContentPane().add(sourceFrameTextAreaScroll, BorderLayout.CENTER);
sourceFrame.setSize(700, 800);
sourceFrame.setLocationRelativeTo(this);
sourceFrame.setVisible(true);
}
public JComponent createTest()
{
JPanel thisp = new JPanel();
MigLayout layout = new MigLayout();
thisp.setLayout(layout);
// thisp.add("wrap, span", new JButton());
// thisp.add("newline, span", new JButton());
// thisp.add("newline, span", new JButton());
// thisp.add("newline, span", new JButton());
// thisp.add("newline 100", new JButton("should have 40 pixels before"));
// thisp.add("newline", new JButton());
// thisp.add("newline", new JButton());
// thisp.add("newline", new JButton());
return thisp;
}
public JComponent createAPI_Constraints1()
{
JTabbedPane tabbedPane = new JTabbedPane();
LC layC = new LC().fill().wrap();
AC colC = new AC().align("right", 1).fill(2, 4).grow(100, 2, 4).align("right", 3).gap("15", 2);
AC rowC = new AC().align("top", 7).gap("15!", 6).grow(100, 8);
JPanel panel = createTabPanel(new MigLayout(layC, colC, rowC)); // Makes the background gradient
// References to text fields not stored to reduce code clutter.
JScrollPane list2 = new JScrollPane(new JList(new String[] {"Mouse, Mickey"}));
panel.add(list2, new CC().spanY().growY().minWidth("150").gapX(null, "10"));
panel.add(new JLabel("Last Name"));
panel.add(new JTextField());
panel.add(new JLabel("First Name"));
panel.add(new JTextField(), new CC().wrap().alignX("right"));
panel.add(new JLabel("Phone"));
panel.add(new JTextField());
panel.add(new JLabel("Email"));
panel.add(new JTextField());
panel.add(new JLabel("Address 1"));
panel.add(new JTextField(), new CC().spanX().growX());
panel.add(new JLabel("Address 2"));
panel.add(new JTextField(), new CC().spanX().growX());
panel.add(new JLabel("City"));
panel.add(new JTextField(), new CC().wrap());
panel.add(new JLabel("State"));
panel.add(new JTextField());
panel.add(new JLabel("Postal Code"));
panel.add(new JTextField(10), new CC().spanX(2).growX(0));
panel.add(new JLabel("Country"));
panel.add(new JTextField(), new CC().wrap());
panel.add(new JButton("New"), new CC().spanX(5).split(5).tag("other"));
panel.add(new JButton("Delete"), new CC().tag("other"));
panel.add(new JButton("Edit"), new CC().tag("other"));
panel.add(new JButton("Save"), new CC().tag("other"));
panel.add(new JButton("Cancel"), new CC().tag("cancel"));
tabbedPane.addTab("Layout Showdown (improved)", panel);
setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" +
"\n" +
"LC layC = new LC().fill().wrap();\n" +
"AC colC = new AC().align(\"right\", 1).fill(2, 4).grow(100, 2, 4).align(\"right\", 3).gap(\"15\", 2);\n" +
"AC rowC = new AC().align(\"top\", 7).gap(\"15!\", 6).grow(100, 8);\n" +
"\n" +
"JPanel panel = createTabPanel(new MigLayout(layC, colC, rowC)); // Makes the background gradient\n" +
"\n" +
"// References to text fields not stored to reduce code clutter.\n" +
"\n" +
"JScrollPane list2 = new JScrollPane(new JList(new String[] {\"Mouse, Mickey\"}));\n" +
"panel.add(list2, new CC().spanY().growY().minWidth(\"150\").gapX(null, \"10\"));\n" +
"\n" +
"panel.add(new JLabel(\"Last Name\"));\n" +
"panel.add(new JTextField());\n" +
"panel.add(new JLabel(\"First Name\"));\n" +
"panel.add(new JTextField(), new CC().wrap().alignX(\"right\"));\n" +
"panel.add(new JLabel(\"Phone\"));\n" +
"panel.add(new JTextField());\n" +
"panel.add(new JLabel(\"Email\"));\n" +
"panel.add(new JTextField());\n" +
"panel.add(new JLabel(\"Address 1\"));\n" +
"panel.add(new JTextField(), new CC().spanX().growX());\n" +
"panel.add(new JLabel(\"Address 2\"));\n" +
"panel.add(new JTextField(), new CC().spanX().growX());\n" +
"panel.add(new JLabel(\"City\"));\n" +
"panel.add(new JTextField(), new CC().wrap());\n" +
"panel.add(new JLabel(\"State\"));\n" +
"panel.add(new JTextField());\n" +
"panel.add(new JLabel(\"Postal Code\"));\n" +
"panel.add(new JTextField(10), new CC().spanX(2).growX(0));\n" +
"panel.add(new JLabel(\"Country\"));\n" +
"panel.add(new JTextField(), new CC().wrap());\n" +
"\n" +
"panel.add(new JButton(\"New\"), new CC().spanX(5).split(5).tag(\"other\"));\n" +
"panel.add(new JButton(\"Delete\"), new CC().tag(\"other\"));\n" +
"panel.add(new JButton(\"Edit\"), new CC().tag(\"other\"));\n" +
"panel.add(new JButton(\"Save\"), new CC().tag(\"other\"));\n" +
"panel.add(new JButton(\"Cancel\"), new CC().tag(\"cancel\"));\n" +
"\n" +
"tabbedPane.addTab(\"Layout Showdown (improved)\", panel);");
return tabbedPane;
}
public JComponent createAPI_Constraints2()
{
JTabbedPane tabbedPane = new JTabbedPane();
LC layC = new LC().fill().wrap();
AC colC = new AC().align("right", 0).fill(1, 3).grow(100, 1, 3).align("right", 2).gap("15", 1);
AC rowC = new AC().index(6).gap("15!").align("top").grow(100, 8);
JPanel panel = createTabPanel(new MigLayout(layC, colC, rowC)); // Makes the background gradient
// References to text fields not stored to reduce code clutter.
panel.add(new JLabel("Last Name"));
panel.add(new JTextField());
panel.add(new JLabel("First Name"));
panel.add(new JTextField(), new CC().wrap());
panel.add(new JLabel("Phone"));
panel.add(new JTextField());
panel.add(new JLabel("Email"));
panel.add(new JTextField());
panel.add(new JLabel("Address 1"));
panel.add(new JTextField(), new CC().spanX().growX());
panel.add(new JLabel("Address 2"));
panel.add(new JTextField(), new CC().spanX().growX());
panel.add(new JLabel("City"));
panel.add(new JTextField(), new CC().wrap());
panel.add(new JLabel("State"));
panel.add(new JTextField());
panel.add(new JLabel("Postal Code"));
panel.add(new JTextField(10), new CC().spanX(2).growX(0));
panel.add(new JLabel("Country"));
panel.add(new JTextField(), new CC().wrap());
panel.add(createButton("New"), new CC().spanX(5).split(5).tag("other"));
panel.add(createButton("Delete"), new CC().tag("other"));
panel.add(createButton("Edit"), new CC().tag("other"));
panel.add(createButton("Save"), new CC().tag("other"));
panel.add(createButton("Cancel"), new CC().tag("cancel"));
tabbedPane.addTab("Layout Showdown (improved)", panel);
setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" +
"\n" +
"LC layC = new LC().fill().wrap();\n" +
"AC colC = new AC().align(\"right\", 0).fill(1, 3).grow(100, 1, 3).align(\"right\", 2).gap(\"15\", 1);\n" +
"AC rowC = new AC().index(6).gap(\"15!\").align(\"top\").grow(100, 8);\n" +
"\n" +
"JPanel panel = createTabPanel(new MigLayout(layC, colC, rowC)); // Makes the background gradient\n" +
"\n" +
"// References to text fields not stored to reduce code clutter.\n" +
"\n" +
"panel.add(new JLabel(\"Last Name\"));\n" +
"panel.add(new JTextField());\n" +
"panel.add(new JLabel(\"First Name\"));\n" +
"panel.add(new JTextField(), new CC().wrap());\n" +
"panel.add(new JLabel(\"Phone\"));\n" +
"panel.add(new JTextField());\n" +
"panel.add(new JLabel(\"Email\"));\n" +
"panel.add(new JTextField());\n" +
"panel.add(new JLabel(\"Address 1\"));\n" +
"panel.add(new JTextField(), new CC().spanX().growX());\n" +
"panel.add(new JLabel(\"Address 2\"));\n" +
"panel.add(new JTextField(), new CC().spanX().growX());\n" +
"panel.add(new JLabel(\"City\"));\n" +
"panel.add(new JTextField(), new CC().wrap());\n" +
"panel.add(new JLabel(\"State\"));\n" +
"panel.add(new JTextField());\n" +
"panel.add(new JLabel(\"Postal Code\"));\n" +
"panel.add(new JTextField(10), new CC().spanX(2).growX(0));\n" +
"panel.add(new JLabel(\"Country\"));\n" +
"panel.add(new JTextField(), new CC().wrap());\n" +
"\n" +
"panel.add(createButton(\"New\"), new CC().spanX(5).split(5).tag(\"other\"));\n" +
"panel.add(createButton(\"Delete\"), new CC().tag(\"other\"));\n" +
"panel.add(createButton(\"Edit\"), new CC().tag(\"other\"));\n" +
"panel.add(createButton(\"Save\"), new CC().tag(\"other\"));\n" +
"panel.add(createButton(\"Cancel\"), new CC().tag(\"cancel\"));\n" +
"\n" +
"tabbedPane.addTab(\"Layout Showdown (improved)\", panel);");
return tabbedPane;
}
public JComponent createLayout_Showdown()
{
JTabbedPane tabbedPane = new JTabbedPane();
JPanel p = createTabPanel(new MigLayout("", "[]15[][grow,fill]15[grow]"));
JScrollPane list1 = new JScrollPane(new JList(new String[] {"Mouse, Mickey"}));
p.add(list1, "spany, growy, wmin 150");
p.add(new JLabel("Last Name"));
p.add(new JTextField());
p.add(new JLabel("First Name"), "split"); // split divides the cell
p.add(new JTextField(), "growx, wrap");
p.add(new JLabel("Phone"));
p.add(new JTextField());
p.add(new JLabel("Email"), "split");
p.add(new JTextField(), "growx, wrap");
p.add(new JLabel("Address 1"));
p.add(new JTextField(), "span, growx"); // span merges cells
p.add(new JLabel("Address 2"));
p.add(new JTextField(), "span, growx");
p.add(new JLabel("City"));
p.add(new JTextField(), "wrap"); // wrap continues on next line
p.add(new JLabel("State"));
p.add(new JTextField());
p.add(new JLabel("Postal Code"), "split");
p.add(new JTextField(), "growx, wrap");
p.add(new JLabel("Country"));
p.add(new JTextField(), "wrap 15");
p.add(createButton("New"), "span, split, align left");
p.add(createButton("Delete"), "");
p.add(createButton("Edit"), "");
p.add(createButton("Save"), "");
p.add(createButton("Cancel"), "wrap push");
tabbedPane.addTab("Layout Showdown (pure)", p);
// Fixed version *******************************************
JPanel p2 = createTabPanel(new MigLayout("", "[]15[][grow,fill]15[][grow,fill]")); // Makes the background gradient
// References to text fields not stored to reduce code clutter.
JScrollPane list2 = new JScrollPane(new JList(new String[] {"Mouse, Mickey"}));
p2.add(list2, "spany, growy, wmin 150");
p2.add(new JLabel("Last Name"));
p2.add(new JTextField());
p2.add(new JLabel("First Name"));
p2.add(new JTextField(), "wrap");
p2.add(new JLabel("Phone"));
p2.add(new JTextField());
p2.add(new JLabel("Email"));
p2.add(new JTextField(), "wrap");
p2.add(new JLabel("Address 1"));
p2.add(new JTextField(), "span");
p2.add(new JLabel("Address 2"));
p2.add(new JTextField(), "span");
p2.add(new JLabel("City"));
p2.add(new JTextField(), "wrap");
p2.add(new JLabel("State"));
p2.add(new JTextField());
p2.add(new JLabel("Postal Code"));
p2.add(new JTextField(10), "growx 0, wrap");
p2.add(new JLabel("Country"));
p2.add(new JTextField(), "wrap 15");
p2.add(createButton("New"), "tag other, span, split");
p2.add(createButton("Delete"), "tag other");
p2.add(createButton("Edit"), "tag other");
p2.add(createButton("Save"), "tag other");
p2.add(createButton("Cancel"), "tag cancel, wrap push");
tabbedPane.addTab("Layout Showdown (improved)", p2);
setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" +
"\n" +
"JPanel p = createTabPanel(new MigLayout(\"\", \"[]15[][grow,fill]15[grow]\"));\n" +
"\n" +
"JScrollPane list1 = new JScrollPane(new JList(new String[] {\"Mouse, Mickey\"}));\n" +
"\n" +
"p.add(list1, \"spany, growy, wmin 150\");\n" +
"p.add(new JLabel(\"Last Name\"));\n" +
"p.add(new JTextField());\n" +
"p.add(new JLabel(\"First Name\"), \"split\"); // split divides the cell\n" +
"p.add(new JTextField(), \"growx, wrap\");\n" +
"p.add(new JLabel(\"Phone\"));\n" +
"p.add(new JTextField());\n" +
"p.add(new JLabel(\"Email\"), \"split\");\n" +
"p.add(new JTextField(), \"growx, wrap\");\n" +
"p.add(new JLabel(\"Address 1\"));\n" +
"p.add(new JTextField(), \"span, growx\"); // span merges cells\n" +
"p.add(new JLabel(\"Address 2\"));\n" +
"p.add(new JTextField(), \"span, growx\");\n" +
"p.add(new JLabel(\"City\"));\n" +
"p.add(new JTextField(), \"wrap\"); // wrap continues on next line\n" +
"p.add(new JLabel(\"State\"));\n" +
"p.add(new JTextField());\n" +
"p.add(new JLabel(\"Postal Code\"), \"split\");\n" +
"p.add(new JTextField(), \"growx, wrap\");\n" +
"p.add(new JLabel(\"Country\"));\n" +
"p.add(new JTextField(), \"wrap 15\");\n" +
"\n" +
"p.add(createButton(\"New\"), \"span, split, align left\");\n" +
"p.add(createButton(\"Delete\"), \"\");\n" +
"p.add(createButton(\"Edit\"), \"\");\n" +
"p.add(createButton(\"Save\"), \"\");\n" +
"p.add(createButton(\"Cancel\"), \"wrap push\");\n" +
"\n" +
"tabbedPane.addTab(\"Layout Showdown (pure)\", p);" +
"\n" +
"\t\t// Fixed version *******************************************\n" +
"JPanel p2 = createTabPanel(new MigLayout(\"\", \"[]15[][grow,fill]15[][grow,fill]\")); // Makes the background gradient\n" +
"\n" +
"// References to text fields not stored to reduce code clutter.\n" +
"\n" +
"JScrollPane list2 = new JScrollPane(new JList(new String[] {\"Mouse, Mickey\"}));\n" +
"p2.add(list2, \"spany, growy, wmin 150\");\n" +
"p2.add(new JLabel(\"Last Name\"));\n" +
"p2.add(new JTextField());\n" +
"p2.add(new JLabel(\"First Name\"));\n" +
"p2.add(new JTextField(), \"wrap\");\n" +
"p2.add(new JLabel(\"Phone\"));\n" +
"p2.add(new JTextField());\n" +
"p2.add(new JLabel(\"Email\"));\n" +
"p2.add(new JTextField(), \"wrap\");\n" +
"p2.add(new JLabel(\"Address 1\"));\n" +
"p2.add(new JTextField(), \"span\");\n" +
"p2.add(new JLabel(\"Address 2\"));\n" +
"p2.add(new JTextField(), \"span\");\n" +
"p2.add(new JLabel(\"City\"));\n" +
"p2.add(new JTextField(), \"wrap\");\n" +
"p2.add(new JLabel(\"State\"));\n" +
"p2.add(new JTextField());\n" +
"p2.add(new JLabel(\"Postal Code\"));\n" +
"p2.add(new JTextField(10), \"growx 0, wrap\");\n" +
"p2.add(new JLabel(\"Country\"));\n" +
"p2.add(new JTextField(), \"wrap 15\");\n" +
"\n" +
"p2.add(createButton(\"New\"), \"tag other, span, split\");\n" +
"p2.add(createButton(\"Delete\"), \"tag other\");\n" +
"p2.add(createButton(\"Edit\"), \"tag other\");\n" +
"p2.add(createButton(\"Save\"), \"tag other\");\n" +
"p2.add(createButton(\"Cancel\"), \"tag cancel, wrap push\");\n" +
"\n" +
"tabbedPane.addTab(\"Layout Showdown (improved)\", p2);");
return tabbedPane;
}
public JComponent createWelcome()
{
JTabbedPane tabbedPane = new JTabbedPane();
MigLayout lm = new MigLayout("ins 20, fill", "", "[grow]unrel[]");
JPanel mainPanel = createTabPanel(lm);
String s = "MigLayout's main purpose is to make layouts for SWT and Swing, and possibly other frameworks, much more powerful and a lot easier to create, especially for manual coding.\n\n" +
"The motto is: \"MigLayout makes complex layouts easy and normal layouts one-liners.\"\n\n" +
"The layout engine is very flexible and advanced, something that is needed to make it simple to use yet handle almost all layout use-cases.\n\n" +
"MigLayout can handle all layouts that the commonly used Swing Layout Managers can handle and this with a lot of extra features. " +
"It also incorporates most, if not all, of the open source alternatives FormLayout's and TableLayout's functionality." +
"\n\n\nThanks to Karsten Lentzsch of JGoodies.com for allowing the reuse of the main demo application layout and for his inspiring talks that led to this layout manager." +
"\n\n\nMikael Grev\n" +
"MiG InfoCom AB\n" +
"miglayout@miginfocom.com";
JTextArea textArea = new JTextArea(s);
textArea.setEditable(false);
textArea.setSize(400, 400);
if (PlatformDefaults.getCurrentPlatform() == PlatformDefaults.WINDOWS_XP)
textArea.setFont(new Font("tahoma", Font.BOLD, 11));
textArea.setOpaque(OPAQUE);
textArea.setWrapStyleWord(true);
textArea.setLineWrap(true);
JLabel label = new JLabel("You can Right Click any Component or Container to change the constraints for it!");
label.setForeground(new Color(200, 0, 0));
mainPanel.add(textArea, "wmin 500, ay top, grow, push, wrap");
mainPanel.add(label, "growx");
label.setFont(label.getFont().deriveFont(Font.BOLD));
tabbedPane.addTab("Welcome", mainPanel);
setSource("");
return tabbedPane;
}
public JComponent createVisual_Bounds()
{
JTabbedPane tabbedPane = new JTabbedPane();
// "NON"-corrected bounds
JPanel p1 = createTabPanel(new MigLayout("fill, ins 3, novisualpadding"));
p1.setBorder(new LineBorder(Color.BLACK));
JTabbedPane demoPane2 = new JTabbedPane();
JPanel demoPanel2 = new JPanel();
demoPanel2.setBackground(Color.WHITE);
demoPane2.addTab("Demo Tab", demoPanel2);
p1.add(createTextArea("A JTextArea", 1, 100), "grow, aligny bottom, wmin 100");
p1.add(demoPane2, "grow, aligny bottom");
p1.add(createTextField("A JTextField", 100), "grow, aligny bottom, wmin 100");
p1.add(createTextArea("A JTextArea", 1, 100), "newline,grow, aligny bottom, wmin 100");
p1.add(createTextArea("A JTextArea", 1, 100), "grow, aligny bottom, wmin 100");
p1.add(createTextArea("A JTextArea", 1, 100), "grow, aligny bottom, wmin 100");
JPanel p2 = createTabPanel(new MigLayout("center,center,fill,ins 3"));
p2.setBorder(new LineBorder(Color.BLACK));
JTabbedPane demoPane = new JTabbedPane();
JPanel demoPanel = new JPanel();
demoPanel.setBackground(Color.WHITE);
demoPane.addTab("Demo Tab", demoPanel);
p2.add(createTextArea("A JTextArea", 1, 100), "grow, aligny bottom, wmin 100");
p2.add(demoPane, "grow, aligny bottom");
p2.add(createTextField("A JTextField", 100), "grow, aligny bottom, wmin 100");
p2.add(createTextArea("A JTextArea", 1, 100), "newline,grow, aligny bottom, wmin 100");
p2.add(createTextArea("A JTextArea", 1, 100), "grow, aligny bottom, wmin 100");
p2.add(createTextArea("A JTextArea", 1, 100), "grow, aligny bottom, wmin 100");
tabbedPane.addTab("Visual Bounds (Not Corrected)", p1);
tabbedPane.addTab("Visual Bounds (Corrected)", p2);
// Disregard. Just forgetting the source code text close to the source code.
setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" +
"\n" +
"// \"NON\"-corrected bounds\n" +
"JPanel p1 = createTabPanel(new MigLayout(\"fill, ins 3, novisualpadding\"));\n" +
"p1.setBorder(new LineBorder(Color.BLACK));\n" +
"\n" +
"JTabbedPane demoPane2 = new JTabbedPane();\n" +
"JPanel demoPanel2 = new JPanel();\n" +
"demoPanel2.setBackground(Color.WHITE);\n" +
"demoPane2.addTab(\"Demo Tab\", demoPanel2);\n" +
"\n" +
"p1.add(createTextArea(\"A JTextArea\", 1, 100), \"grow, aligny bottom, wmin 100\");\n" +
"p1.add(demoPane2, \"grow, aligny bottom\");\n" +
"p1.add(createTextField(\"A JTextField\", 100), \"grow, aligny bottom, wmin 100\");\n" +
"p1.add(createTextArea(\"A JTextArea\", 1, 100), \"newline,grow, aligny bottom, wmin 100\");\n" +
"p1.add(createTextArea(\"A JTextArea\", 1, 100), \"grow, aligny bottom, wmin 100\");\n" +
"p1.add(createTextArea(\"A JTextArea\", 1, 100), \"grow, aligny bottom, wmin 100\");\n" +
"\n" +
"JPanel p2 = createTabPanel(new MigLayout(\"center,center,fill,ins 3\"));\n" +
"p2.setBorder(new LineBorder(Color.BLACK));\n" +
"\n" +
"JTabbedPane demoPane = new JTabbedPane();\n" +
"JPanel demoPanel = new JPanel();\n" +
"demoPanel.setBackground(Color.WHITE);\n" +
"demoPane.addTab(\"Demo Tab\", demoPanel);\n" +
"\n" +
"p2.add(createTextArea(\"A JTextArea\", 1, 100), \"grow, aligny bottom, wmin 100\");\n" +
"p2.add(demoPane, \"grow, aligny bottom\");\n" +
"p2.add(createTextField(\"A JTextField\", 100), \"grow, aligny bottom, wmin 100\");\n" +
"p2.add(createTextArea(\"A JTextArea\", 1, 100), \"newline,grow, aligny bottom, wmin 100\");\n" +
"p2.add(createTextArea(\"A JTextArea\", 1, 100), \"grow, aligny bottom, wmin 100\");\n" +
"p2.add(createTextArea(\"A JTextArea\", 1, 100), \"grow, aligny bottom, wmin 100\");\n" +
"\n" +
"tabbedPane.addTab(\"Visual Bounds (Not Corrected)\", p1);\n" +
"tabbedPane.addTab(\"Visual Bounds (Corrected)\", p2);");
return tabbedPane;
}
public JComponent createDocking()
{
JTabbedPane tabbedPane = new JTabbedPane();
JPanel p1 = createTabPanel(new MigLayout("fill"));
p1.add(createPanel("1. North"), "north");
p1.add(createPanel("2. West"), "west");
p1.add(createPanel("3. East"), "east");
p1.add(createPanel("4. South"), "south");
String[][] data = new String[20][6];
for (int r = 0; r < data.length; r++) {
data[r] = new String[6];
for (int c = 0; c < data[r].length; c++)
data[r][c] = "Cell " + (r + 1) + ", " + (c + 1);
}
JTable table = new JTable(data, new String[] {"Column 1", "Column 2", "Column 3", "Column 4", "Column 5", "Column 6"});
p1.add(new JScrollPane(table), "grow");
JPanel p2 = createTabPanel(new MigLayout("fill", "[c]", ""));
p2.add(createPanel("1. North"), "north");
p2.add(createPanel("2. North"), "north");
p2.add(createPanel("3. West"), "west");
p2.add(createPanel("4. West"), "west");
p2.add(createPanel("5. South"), "south");
p2.add(createPanel("6. East"), "east");
p2.add(createButton("7. Normal"));
p2.add(createButton("8. Normal"));
p2.add(createButton("9. Normal"));
JPanel p3 = createTabPanel(new MigLayout());
p3.add(createPanel("1. North"), "north");
p3.add(createPanel("2. South"), "south");
p3.add(createPanel("3. West"), "west");
p3.add(createPanel("4. East"), "east");
p3.add(createButton("5. Normal"));
JPanel p4 = createTabPanel(new MigLayout());
p4.add(createPanel("1. North"), "north");
p4.add(createPanel("2. North"), "north");
p4.add(createPanel("3. West"), "west");
p4.add(createPanel("4. West"), "west");
p4.add(createPanel("5. South"), "south");
p4.add(createPanel("6. East"), "east");
p4.add(createButton("7. Normal"));
p4.add(createButton("8. Normal"));
p4.add(createButton("9. Normal"));
JPanel p5 = createTabPanel(new MigLayout("fillx", "[c]", ""));
p5.add(createPanel("1. North"), "north");
p5.add(createPanel("2. North"), "north");
p5.add(createPanel("3. West"), "west");
p5.add(createPanel("4. West"), "west");
p5.add(createPanel("5. South"), "south");
p5.add(createPanel("6. East"), "east");
p5.add(createButton("7. Normal"));
p5.add(createButton("8. Normal"));
p5.add(createButton("9. Normal"));
JPanel p6 = createTabPanel(new MigLayout("fill", "", ""));
Random rand = new Random();
String[] sides = {"north", "east", "south", "west"};
for (int i = 0; i < 20; i++) {
int side = rand.nextInt(4);
p6.add(createPanel((i + 1) + " " + sides[side]), sides[side]);
}
p6.add(createPanel("I'm in the Center!"), "dock center");
tabbedPane.addTab("Docking 1 (fill)", p1);
tabbedPane.addTab("Docking 2 (fill)", p2);
tabbedPane.addTab("Docking 3", p3);
tabbedPane.addTab("Docking 4", p4);
tabbedPane.addTab("Docking 5 (fillx)", p5);
tabbedPane.addTab("Random Docking", new JScrollPane(p6));
// Disregard. Just forgetting the source code text close to the source code.
setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" +
"\n" +
"JPanel p1 = createTabPanel(new MigLayout(\"fill\"));\n" +
"\n" +
"p1.add(createPanel(\"1. North\"), \"north\");\n" +
"p1.add(createPanel(\"2. West\"), \"west\");\n" +
"p1.add(createPanel(\"3. East\"), \"east\");\n" +
"p1.add(createPanel(\"4. South\"), \"south\");\n" +
"\n" +
"String[][] data = new String[20][6];\n" +
"for (int r = 0; r < data.length; r++) {\n" +
"\tdata[r] = new String[6];\n" +
"\tfor (int c = 0; c < data[r].length; c++)\n" +
"\t\tdata[r][c] = \"Cell \" + (r + 1) + \", \" + (c + 1);\n" +
"}\n" +
"JTable table = new JTable(data, new String[] {\"Column 1\", \"Column 2\", \"Column 3\", \"Column 4\", \"Column 5\", \"Column 6\"});\n" +
"p1.add(new JScrollPane(table), \"grow\");\n" +
"\n" +
"JPanel p2 = createTabPanel(new MigLayout(\"fill\", \"[c]\", \"\"));\n" +
"\n" +
"p2.add(createPanel(\"1. North\"), \"north\");\n" +
"p2.add(createPanel(\"2. North\"), \"north\");\n" +
"p2.add(createPanel(\"3. West\"), \"west\");\n" +
"p2.add(createPanel(\"4. West\"), \"west\");\n" +
"p2.add(createPanel(\"5. South\"), \"south\");\n" +
"p2.add(createPanel(\"6. East\"), \"east\");\n" +
"p2.add(createButton(\"7. Normal\"));\n" +
"p2.add(createButton(\"8. Normal\"));\n" +
"p2.add(createButton(\"9. Normal\"));\n" +
"\n" +
"JPanel p3 = createTabPanel(new MigLayout());\n" +
"\n" +
"p3.add(createPanel(\"1. North\"), \"north\");\n" +
"p3.add(createPanel(\"2. South\"), \"south\");\n" +
"p3.add(createPanel(\"3. West\"), \"west\");\n" +
"p3.add(createPanel(\"4. East\"), \"east\");\n" +
"p3.add(createButton(\"5. Normal\"));\n" +
"\n" +
"JPanel p4 = createTabPanel(new MigLayout());\n" +
"\n" +
"p4.add(createPanel(\"1. North\"), \"north\");\n" +
"p4.add(createPanel(\"2. North\"), \"north\");\n" +
"p4.add(createPanel(\"3. West\"), \"west\");\n" +
"p4.add(createPanel(\"4. West\"), \"west\");\n" +
"p4.add(createPanel(\"5. South\"), \"south\");\n" +
"p4.add(createPanel(\"6. East\"), \"east\");\n" +
"p4.add(createButton(\"7. Normal\"));\n" +
"p4.add(createButton(\"8. Normal\"));\n" +
"p4.add(createButton(\"9. Normal\"));\n" +
"\n" +
"JPanel p5 = createTabPanel(new MigLayout(\"fillx\", \"[c]\", \"\"));\n" +
"\n" +
"p5.add(createPanel(\"1. North\"), \"north\");\n" +
"p5.add(createPanel(\"2. North\"), \"north\");\n" +
"p5.add(createPanel(\"3. West\"), \"west\");\n" +
"p5.add(createPanel(\"4. West\"), \"west\");\n" +
"p5.add(createPanel(\"5. South\"), \"south\");\n" +
"p5.add(createPanel(\"6. East\"), \"east\");\n" +
"p5.add(createButton(\"7. Normal\"));\n" +
"p5.add(createButton(\"8. Normal\"));\n" +
"p5.add(createButton(\"9. Normal\"));\n" +
"\n" +
"JPanel p6 = createTabPanel(new MigLayout(\"fill\", \"\", \"\"));\n" +
"\n" +
"Random rand = new Random();\n" +
"String[] sides = {\"north\", \"east\", \"south\", \"west\"};\n" +
"for (int i = 0; i < 20; i++) {\n" +
"\tint side = rand.nextInt(4);\n" +
"\tp6.add(createPanel((i + 1) + \" \" + sides[side]), sides[side]);\n" +
"}\n" +
"p6.add(createButton(\"I'm in the middle!\"), \"grow\");\n" +
"\n" +
"tabbedPane.addTab(\"Docking 1 (fill)\", p1);\n" +
"tabbedPane.addTab(\"Docking 2 (fill)\", p2);\n" +
"tabbedPane.addTab(\"Docking 3\", p3);\n" +
"tabbedPane.addTab(\"Docking 4\", p4);\n" +
"tabbedPane.addTab(\"Docking 5 (fillx)\", p5);\n" +
"tabbedPane.addTab(\"Docking Spiral\", new JScrollPane(p6));");
return tabbedPane;
}
public JComponent createAbsolute_Position()
{
JTabbedPane tabbedPane = new JTabbedPane();
// Pos tab
final JPanel posPanel = createTabPanel(new MigLayout());
posPanel.add(createButton(), "pos 0.5al 0al");
posPanel.add(createButton(), "pos 1al 0al");
posPanel.add(createButton(), "pos 0.5al 0.5al");
posPanel.add(createButton(), "pos 5in 45lp");
posPanel.add(createButton(), "pos 0.5al 0.5al");
posPanel.add(createButton(), "pos 0.5al 1.0al");
posPanel.add(createButton(), "pos 1al .25al");
posPanel.add(createButton(), "pos visual.x2-pref visual.y2-pref");
posPanel.add(createButton(), "pos 1al -1in");
posPanel.add(createButton(), "pos 100 100");
posPanel.add(createButton(), "pos (10+(20*3lp)) 200");
posPanel.add(createButton("Drag Window! (pos 500-container.xpos 500-container.ypos)"),
"pos 500-container.xpos 500-container.ypos");
// Bounds tab
JPanel boundsPanel = createTabPanel(new MigLayout());
String constr = "pos (visual.x+visual.w*0.1) visual.y2-40 (visual.x2-visual.w*0.1) visual.y2";
JLabel southLabel = createLabel(constr, SwingConstants.CENTER);
southLabel.setBorder(new LineBorder(Color.LIGHT_GRAY, 1));
southLabel.setBackground(new Color(200, 200, 255, benchRuns == 0 ? 70 : 255));
southLabel.setOpaque(true);
southLabel.setFont(southLabel.getFont().deriveFont(Font.BOLD));
boundsPanel.add(southLabel, constr);
boundsPanel.add(createButton(), "pos 0 0 container.x2 n");
boundsPanel.add(createButton(), "pos visual.x 40 visual.x2 70");
boundsPanel.add(createButton(), "pos visual.x 100 visual.x2 p");
boundsPanel.add(createButton(), "pos 0.1al 0.4al n (visual.y2 - 10)");
boundsPanel.add(createButton(), "pos 0.9al 0.4al n visual.y2-10");
boundsPanel.add(createButton(), "pos 0.5al 0.5al, pad 3 0 -3 0");
boundsPanel.add(createButton(), "pos n n 50% 50%");
boundsPanel.add(createButton(), "pos 50% 50% n n");
boundsPanel.add(createButton(), "pos 50% n n 50%");
boundsPanel.add(createButton(), "pos n 50% 50% n");
tabbedPane.addTab("X Y Positions", posPanel);
tabbedPane.addTab("X1 Y1 X2 Y2 Bounds", boundsPanel);
// Glass pane tab
if (benchRuns == 0) {
final JPanel glassPanel = createTabPanel(new MigLayout("align c c, ins 0"));
final JButton butt = createButton("Press me!!");
glassPanel.add(butt);
butt.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
butt.setEnabled(false);
final JPanel bg = new JPanel(new MigLayout("align c c,fill")) {
public void paint(Graphics g)
{
g.setColor(getBackground());
g.fillRect(0, 0, getWidth(), getHeight());
super.paint(g);
}
};
bg.setOpaque(OPAQUE);
configureActiveComponet(bg);
final JLabel label = createLabel("You don't need a GlassPane to be cool!");
label.setFont(label.getFont().deriveFont(30f));
label.setForeground(new Color(255, 255, 255, 0));
bg.add(label, "align 50% 30%");
glassPanel.add(bg, "pos visual.x visual.y visual.x2 visual.y2", 0);
final long startTime = System.nanoTime();
final long endTime = startTime + 500000000L;
glassPanel.revalidate();
final javax.swing.Timer timer = new Timer(25, null);
timer.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
long now = System.nanoTime();
int alpha = (int) (((now - startTime) / (double) (endTime - startTime)) * 300);
if (alpha < 150)
bg.setBackground(new Color(100, 100, 100, alpha));
if (alpha > 150 && alpha < 405) {
label.setForeground(new Color(255, 255, 255, (alpha - 150)));
bg.repaint();
}
if (alpha > 405)
timer.stop();
}
});
timer.start();
}
});
tabbedPane.addTab("GlassPane Substitute", glassPanel);
addComponentListener(new ComponentAdapter() {
public void componentMoved(ComponentEvent e) {
if (posPanel.isDisplayable()) {
posPanel.revalidate();
} else {
removeComponentListener(this);
}
}
});
}
// Disregard. Just forgetting the source code text close to the source code.
setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" +
"\n" +
"// Pos tab\n" +
"final JPanel posPanel = createTabPanel(new MigLayout());\n" +
"\n" +
"posPanel.add(createButton(), \"pos 0.5al 0al\");\n" +
"posPanel.add(createButton(), \"pos 1al 0al\");\n" +
"posPanel.add(createButton(), \"pos 0.5al 0.5al\");\n" +
"posPanel.add(createButton(), \"pos 5in 45lp\");\n" +
"posPanel.add(createButton(), \"pos 0.5al 0.5al\");\n" +
"posPanel.add(createButton(), \"pos 0.5al 1.0al\");\n" +
"posPanel.add(createButton(), \"pos 1al .25al\");\n" +
"posPanel.add(createButton(), \"pos visual.x2-pref visual.y2-pref\");\n" +
"posPanel.add(createButton(), \"pos 1al -1in\");\n" +
"posPanel.add(createButton(), \"pos 100 100\");\n" +
"posPanel.add(createButton(), \"pos (10+(20*3lp)) 200\");\n" +
"posPanel.add(createButton(\"Drag Window! (pos 500-container.xpos 500-container.ypos)\"),\n" +
" \"pos 500-container.xpos 500-container.ypos\");\n" +
"\n" +
"// Bounds tab\n" +
"JPanel boundsPanel = createTabPanel(new MigLayout());\n" +
"\n" +
"String constr = \"pos (visual.x+visual.w*0.1) visual.y2-40 (visual.x2-visual.w*0.1) visual.y2\";\n" +
"JLabel southLabel = createLabel(constr, SwingConstants.CENTER);\n" +
"southLabel.setBorder(new LineBorder(Color.LIGHT_GRAY, 1));\n" +
"southLabel.setBackground(new Color(200, 200, 255, 70));\n" +
"southLabel.setOpaque(true);\n" +
"southLabel.setFont(southLabel.getFont().deriveFont(Font.BOLD));\n" +
"boundsPanel.add(southLabel, constr);\n" +
"\n" +
"boundsPanel.add(createButton(), \"pos 0 0 container.x2 n\");\n" +
"boundsPanel.add(createButton(), \"pos visual.x 40 visual.x2 70\");\n" +
"boundsPanel.add(createButton(), \"pos visual.x 100 visual.x2 p\");\n" +
"boundsPanel.add(createButton(), \"pos 0.1al 0.4al n visual.y2-10\");\n" +
"boundsPanel.add(createButton(), \"pos 0.9al 0.4al n visual.y2-10\");\n" +
"boundsPanel.add(createButton(), \"pos 0.5al 0.5al, pad 3 0 -3 0\");\n" +
"boundsPanel.add(createButton(), \"pos n n 50% 50%\");\n" +
"boundsPanel.add(createButton(), \"pos 50% 50% n n\");\n" +
"boundsPanel.add(createButton(), \"pos 50% n n 50%\");\n" +
"boundsPanel.add(createButton(), \"pos n 50% 50% n\");\n" +
"\n" +
"// Glass pane tab\n" +
"final JPanel glassPanel = createTabPanel(new MigLayout(\"align c c, ins 0\"));\n" +
"final JButton butt = createButton(\"Press me!!\");\n" +
"glassPanel.add(butt);\n" +
"\n" +
"butt.addActionListener(new ActionListener()\t\t{\n" +
"\tpublic void actionPerformed(ActionEvent e)\n" +
"\t{\n" +
"\t\tbutt.setEnabled(false);\n" +
"\t\tfinal JPanel bg = new JPanel(new MigLayout(\"align c c,fill\")) {\n" +
"\t\t\tpublic void paint(Graphics g)\n" +
"\t\t\t{\n" +
"\t\t\t\tg.setColor(getBackground());\n" +
"\t\t\t\tg.fillRect(0, 0, getWidth(), getHeight());\n" +
"\t\t\t\tsuper.paint(g);\n" +
"\t\t\t}\n" +
"\t\t};\n" +
"\t\tbg.setOpaque(OPAQUE);\n" +
"\t\tconfigureActiveComponet(bg);\n" +
"\n" +
"\t\tfinal JLabel label = createLabel(\"You don't need a GlassPane to be cool!\");\n" +
"\t\tlabel.setFont(label.getFont().deriveFont(30f));\n" +
"\t\tlabel.setForeground(new Color(255, 255, 255, 0));\n" +
"\t\tbg.add(label, \"align 50% 30%\");\n" +
"\n" +
"\t\tglassPanel.add(bg, \"pos visual.x visual.y visual.x2 visual.y2\", 0);\n" +
"\t\tfinal long startTime = System.nanoTime();\n" +
"\t\tfinal long endTime = startTime + 500000000L;\n" +
"\n" +
"\t\tglassPanel.revalidate();\n" +
"\n" +
"\t\tfinal javax.swing.Timer timer = new Timer(25, null);\n" +
"\n" +
"\t\ttimer.addActionListener(new ActionListener() {\n" +
"\t\t\tpublic void actionPerformed(ActionEvent e)\n" +
"\t\t\t{\n" +
"\t\t\t\tlong now = System.nanoTime();\n" +
"\t\t\t\tint alpha = (int) (((now - startTime) / (double) (endTime - startTime)) * 300);\n" +
"\t\t\t\tif (alpha < 150)\n" +
"\t\t\t\t\tbg.setBackground(new Color(100, 100, 100, alpha));\n" +
"\n" +
"\t\t\t\tif (alpha > 150 && alpha < 405) {\n" +
"\t\t\t\t\tlabel.setForeground(new Color(255, 255, 255, (alpha - 150)));\n" +
"\t\t\t\t\tbg.repaint();\n" +
"\t\t\t\t}\n" +
"\t\t\t\tif (alpha > 405)\n" +
"\t\t\t\t\ttimer.stop();\n" +
"\t\t\t}\n" +
"\t\t});\n" +
"\t\ttimer.start();\n" +
"\t}\n" +
"});\n" +
"\n" +
"tabbedPane.addTab(\"X Y Positions\", posPanel);\n" +
"tabbedPane.addTab(\"X1 Y1 X2 Y2 Bounds\", boundsPanel);\n" +
"tabbedPane.addTab(\"GlassPane Substitute\", glassPanel);\n" +
"\n" +
"addComponentListener(new ComponentAdapter() {\n" +
"\tpublic void componentMoved(ComponentEvent e) {\n" +
"\t\tif (posPanel.isDisplayable()) {\n" +
"\t\t\tposPanel.revalidate();\n" +
"\t\t} else {\n" +
"\t\t\tremoveComponentListener(this);\n" +
"\t\t}\n" +
"\t}\n" +
"});");
return tabbedPane;
}
public JComponent createComponent_Links()
{
JTabbedPane tabbedPane = new JTabbedPane();
JPanel linksPanel = createTabPanel(new MigLayout());
// Links tab
JButton mini = createButton("Mini");
mini.setMargin(new Insets(0, 1, 0, 1));
linksPanel.add(mini, "pos null ta.y ta.x2 null");
linksPanel.add(createTextArea("Components, Please Link to Me!\nMy ID is: 'ta'", 3, 30), "id ta, pos 0.5al 0.5al");
linksPanel.add(createButton(), "id b1,pos ta.x2 ta.y2");
linksPanel.add(createButton(), "pos b1.x2+rel b1.y visual.x2 null");
linksPanel.add(createButton(), "pos ta.x2+rel ta.y visual.x2 null");
linksPanel.add(createButton(), "pos null ta.y+(ta.h-pref)/2 ta.x-rel null");
linksPanel.add(createButton(), "pos ta.x ta.y2+100 ta.x2 null");
linksPanel.add(createCheck("pos (ta.x+indent) (ta.y2+rel)"),
"pos (ta.x+indent) (ta.y2+rel)");
// External tab
JPanel externalPanel = createTabPanel(new MigLayout());
JButton extButt = createButton("Bounds Externally Set!");
extButt.setBounds(250, 130, 200, 40);
externalPanel.add(extButt, "id ext, external");
externalPanel.add(createButton(), "pos ext.x2 ext.y2");
externalPanel.add(createButton(), "pos null null ext.x ext.y");
// Start/End Group tab
JPanel egPanel = createTabPanel(new MigLayout());
egPanel.add(createButton(), "id b1, endgroupx g1, pos 200 200");
egPanel.add(createButton(), "id b2, endgroupx g1, pos (b1.x+2ind) (b1.y2+rel)");
egPanel.add(createButton(), "id b3, endgroupx g1, pos (b1.x+4ind) (b2.y2+rel)");
egPanel.add(createButton(), "id b4, endgroupx g1, pos (b1.x+6ind) (b3.y2+rel)");
// Group Bounds tab
JPanel gpPanel = createTabPanel(new MigLayout());
gpPanel.add(createButton(), "id grp1.b1, pos n 0.5al 50% n");
gpPanel.add(createButton(), "id grp1.b2, pos 50% 0.5al n n");
gpPanel.add(createButton(), "id grp1.b3, pos 0.5al n n b1.y");
gpPanel.add(createButton(), "id grp1.b4, pos 0.5al b1.y2 n n");
gpPanel.add(createButton(), "pos n grp1.y2 grp1.x n");
gpPanel.add(createButton(), "pos n n grp1.x grp1.y");
gpPanel.add(createButton(), "pos grp1.x2 n n grp1.y");
gpPanel.add(createButton(), "pos grp1.x2 grp1.y2");
JPanel boundsPanel = new JPanel(null);
boundsPanel.setBackground(new Color(200, 200, 255));
gpPanel.add(boundsPanel, "pos grp1.x grp1.y grp1.x2 grp1.y2");
tabbedPane.addTab("Component Links", linksPanel);
tabbedPane.addTab("External Components", externalPanel);
tabbedPane.addTab("End Grouping", egPanel);
tabbedPane.addTab("Group Bounds", gpPanel);
// Disregard. Just forgetting the source code text close to the source code.
setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" +
"\n" +
"JPanel linksPanel = createTabPanel(new MigLayout());\n" +
"\n" +
"// Links tab\n" +
"JButton mini = createButton(\"Mini\");\n" +
"mini.setMargin(new Insets(0, 1, 0, 1));\n" +
"linksPanel.add(mini, \"pos null ta.y ta.x2 null\");\n" +
"linksPanel.add(createTextArea(\"Components, Please Link to Me!\\nMy ID is: 'ta'\", 3, 30), \"id ta, pos 0.5al 0.5al\");\n" +
"linksPanel.add(createButton(), \"id b1,pos ta.x2 ta.y2\");\n" +
"linksPanel.add(createButton(), \"pos b1.x2+rel b1.y visual.x2 null\");\n" +
"linksPanel.add(createButton(), \"pos ta.x2+rel ta.y visual.x2 null\");\n" +
"linksPanel.add(createButton(), \"pos null ta.y+(ta.h-pref)/2 ta.x-rel null\");\n" +
"linksPanel.add(createButton(), \"pos ta.x ta.y2+100 ta.x2 null\");\n" +
"linksPanel.add(createCheck(\"pos (ta.x+indent) (ta.y2+rel)\"),\n" +
" \"pos (ta.x+indent) (ta.y2+rel)\");\n" +
"\n" +
"// External tab\n" +
"JPanel externalPanel = createTabPanel(new MigLayout());\n" +
"\n" +
"JButton extButt = createButton(\"Bounds Externally Set!\");\n" +
"extButt.setBounds(250, 130, 200, 40);\n" +
"externalPanel.add(extButt, \"id ext, external\");\n" +
"externalPanel.add(createButton(), \"pos ext.x2 ext.y2\");\n" +
"externalPanel.add(createButton(), \"pos null null ext.x ext.y\");\n" +
"\n" +
"// Start/End Group tab\n" +
"JPanel egPanel = createTabPanel(new MigLayout());\n" +
"\n" +
"egPanel.add(createButton(), \"id b1, endgroupx g1, pos 200 200\");\n" +
"egPanel.add(createButton(), \"id b2, endgroupx g1, pos (b1.x+2ind) (b1.y2+rel)\");\n" +
"egPanel.add(createButton(), \"id b3, endgroupx g1, pos (b1.x+4ind) (b2.y2+rel)\");\n" +
"egPanel.add(createButton(), \"id b4, endgroupx g1, pos (b1.x+6ind) (b3.y2+rel)\");\n" +
"\n" +
"// Group Bounds tab\n" +
"JPanel gpPanel = createTabPanel(new MigLayout());\n" +
"\n" +
"gpPanel.add(createButton(), \"id grp1.b1, pos n 0.5al 50% n\");\n" +
"gpPanel.add(createButton(), \"id grp1.b2, pos 50% 0.5al n n\");\n" +
"gpPanel.add(createButton(), \"id grp1.b3, pos 0.5al n n b1.y\");\n" +
"gpPanel.add(createButton(), \"id grp1.b4, pos 0.5al b1.y2 n n\");\n" +
"\n" +
"gpPanel.add(createButton(), \"pos n grp1.y2 grp1.x n\");\n" +
"gpPanel.add(createButton(), \"pos n n grp1.x grp1.y\");\n" +
"gpPanel.add(createButton(), \"pos grp1.x2 n n grp1.y\");\n" +
"gpPanel.add(createButton(), \"pos grp1.x2 grp1.y2\");\n" +
"\n" +
"JPanel boundsPanel = new JPanel(null);\n" +
"boundsPanel.setBackground(new Color(200, 200, 255));\n" +
"gpPanel.add(boundsPanel, \"pos grp1.x grp1.y grp1.x2 grp1.y2\");\n" +
"\n" +
"\n" +
"tabbedPane.addTab(\"Component Links\", linksPanel);\n" +
"tabbedPane.addTab(\"External Components\", externalPanel);\n" +
"tabbedPane.addTab(\"End Grouping\", egPanel);\n" +
"tabbedPane.addTab(\"Group Bounds\", gpPanel);");
return tabbedPane;
}
public JComponent createFlow_Direction()
{
JTabbedPane tabbedPane = new JTabbedPane();
tabbedPane.addTab("Layout: flowx, Cell: flowx", createFlowPanel("", "flowx"));
tabbedPane.addTab("Layout: flowx, Cell: flowy", createFlowPanel("", "flowy"));
tabbedPane.addTab("Layout: flowy, Cell: flowx", createFlowPanel("flowy", "flowx"));
tabbedPane.addTab("Layout: flowy, Cell: flowy", createFlowPanel("flowy", "flowy"));
// Disregard. Just forgetting the source code text close to the source code.
setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" +
"\n" +
"tabbedPane.addTab(\"Layout: flowx, Cell: flowx\", createFlowPanel(\"\", \"flowx\"));\n" +
"tabbedPane.addTab(\"Layout: flowx, Cell: flowy\", createFlowPanel(\"\", \"flowy\"));\n" +
"tabbedPane.addTab(\"Layout: flowy, Cell: flowx\", createFlowPanel(\"flowy\", \"flowx\"));\n" +
"tabbedPane.addTab(\"Layout: flowy, Cell: flowy\", createFlowPanel(\"flowy\", \"flowy\"));" +
"\n\tpublic JPanel createFlowPanel(String gridFlow, String cellFlow)\n" +
"\t{\n" +
"MigLayout lm = new MigLayout(\"center, wrap 3,\" + gridFlow,\n" +
" \"[110,fill]\",\n" +
" \"[110,fill]\");\n" +
"JPanel panel = createTabPanel(lm);\n" +
"\n" +
"for (int i = 0; i < 9; i++) {\n" +
"\tJButton b = createButton(\"\" + (i + 1));\n" +
"\tb.setFont(b.getFont().deriveFont(20f));\n" +
"\tpanel.add(b, cellFlow);\n" +
"}\n" +
"\n" +
"JButton b = createButton(\"5:2\");\n" +
"b.setFont(b.getFont().deriveFont(20f));\n" +
"panel.add(b, cellFlow + \",cell 1 1\");\n" +
"\n" +
"return panel;\n" +
"\t}");
return tabbedPane;
}
public JPanel createFlowPanel(String gridFlow, String cellFlow)
{
MigLayout lm = new MigLayout("center, wrap 3," + gridFlow,
"[110,fill]",
"[110,fill]");
JPanel panel = createTabPanel(lm);
Font f = panel.getFont().deriveFont(20f);
for (int i = 0; i < 9; i++) {
JComponent b = createPanel("" + (i + 1));
b.setFont(f);
panel.add(b, cellFlow);
}
JComponent b = createPanel("5:2");
b.setFont(f);
panel.add(b, cellFlow + ",cell 1 1");
return panel;
}
public JComponent createDebug()
{
return createPlainImpl(true);
}
public JComponent createButton_Bars()
{
MigLayout lm = new MigLayout("ins 0 0 15lp 0",
"[grow]",
"[grow][baseline,nogrid]");
final JPanel mainPanel = new JPanel(lm);
final JLabel formatLabel = createLabel("");
formatLabel.setFont(formatLabel.getFont().deriveFont(Font.BOLD));
JTabbedPane tabbedPane = new JTabbedPane();
JToggleButton winButt = createToggleButton("Windows");
JToggleButton macButt = createToggleButton("Mac OS X");
JButton helpButt = createButton("Help");
if (benchRuns == 0) {
winButt.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
PlatformDefaults.setPlatform(PlatformDefaults.WINDOWS_XP);
formatLabel.setText("'" + PlatformDefaults.getButtonOrder() + "'");
((JPanel) ((JFrame) Frame.getFrames()[0]).getContentPane()).revalidate();
}
});
macButt.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
PlatformDefaults.setPlatform(PlatformDefaults.MAC_OSX);
formatLabel.setText(PlatformDefaults.getButtonOrder());
((JPanel) ((JFrame) Frame.getFrames()[0]).getContentPane()).revalidate();
}
});
helpButt.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(mainPanel, "See JavaDoc for PlatformDefaults.setButtonOrder(..) for details on the format string.");
}
});
}
ButtonGroup bg = new ButtonGroup();
bg.add(winButt);
bg.add(macButt);
if (benchRuns == 0) {
if (PlatformDefaults.getCurrentPlatform() == PlatformDefaults.MAC_OSX) {
macButt.doClick();
} else {
winButt.doClick();
}
}
tabbedPane.addTab("Buttons", createButtonBarsPanel("help", false));
tabbedPane.addTab("Buttons with Help2", createButtonBarsPanel("help2", false));
tabbedPane.addTab("Buttons (Same width)", createButtonBarsPanel("help", true));
mainPanel.add(tabbedPane, "grow,wrap");
mainPanel.add(createLabel("Button Order:"));
mainPanel.add(formatLabel, "growx");
mainPanel.add(winButt);
mainPanel.add(macButt);
mainPanel.add(helpButt, "gapbefore unrel");
// Disregard. Just forgetting the source code text close to the source code.
setSource("MigLayout lm = new MigLayout(\"ins 0 0 15lp 0\",\n" +
" \"[grow]\",\n" +
" \"[grow][baseline,nogrid,gap unrelated]\");\n" +
"\n" +
"final JPanel mainPanel = new JPanel(lm);\n" +
"final JLabel formatLabel = createLabel(\"\");\n" +
"formatLabel.setFont(formatLabel.getFont().deriveFont(Font.BOLD));\n" +
"JTabbedPane tabbedPane = new JTabbedPane();\n" +
"\n" +
"JToggleButton winButt = createToggleButton(\"Windows\");\n" +
"\n" +
"winButt.addActionListener(new ActionListener() {\n" +
"\tpublic void actionPerformed(ActionEvent e) {\n" +
"\t\tPlatformDefaults.setPlatform(PlatformDefaults.WINDOWS_XP);\n" +
"\t\tformatLabel.setText(\"'\" + PlatformDefaults.getButtonOrder() + \"'\");\n" +
"\t\tSwingUtilities.updateComponentTreeUI(mainPanel);\n" +
"\t}\n" +
"});\n" +
"\n" +
"JToggleButton macButt = createToggleButton(\"Mac OS X\");\n" +
"macButt.addActionListener(new ActionListener() {\n" +
"\tpublic void actionPerformed(ActionEvent e) {\n" +
"\t\tPlatformDefaults.setPlatform(PlatformDefaults.MAC_OSX);\n" +
"\t\tformatLabel.setText(PlatformDefaults.getButtonOrder());\n" +
"\t\tSwingUtilities.updateComponentTreeUI(mainPanel);\n" +
"\t}\n" +
"});\n" +
"\n" +
"JButton helpButt = createButton(\"Help\");\n" +
"helpButt.addActionListener(new ActionListener() {\n" +
"\tpublic void actionPerformed(ActionEvent e) {\n" +
"\t\tJOptionPane.showMessageDialog(mainPanel, \"See JavaDoc for PlatformDefaults.setButtonOrder(..) for details on the format string.\");\n" +
"\t}\n" +
"});\n" +
"\n" +
"ButtonGroup bg = new ButtonGroup();\n" +
"bg.add(winButt);\n" +
"bg.add(macButt);\n" +
"winButt.doClick();\n" +
"\n" +
"tabbedPane.addTab(\"Buttons\", createButtonBarsPanel(\"help\", false));\n" +
"tabbedPane.addTab(\"Buttons with Help2\", createButtonBarsPanel(\"help2\", false));\n" +
"tabbedPane.addTab(\"Buttons (Same width)\", createButtonBarsPanel(\"help\", true));\n" +
"\n" +
"mainPanel.add(tabbedPane, \"grow,wrap\");\n" +
"\n" +
"mainPanel.add(createLabel(\"Button Order:\"));\n" +
"mainPanel.add(formatLabel, \"growx\");\n" +
"mainPanel.add(winButt);\n" +
"mainPanel.add(macButt);\n" +
"mainPanel.add(helpButt, \"gapbefore unrel\");");
return mainPanel;
}
private JComponent createButtonBarsPanel(String helpTag, boolean sizeLocked)
{
MigLayout lm = new MigLayout("nogrid, fillx, aligny 100%, gapy unrel");
JPanel panel = createTabPanel(lm);
// Notice that the order in the rows below does not matter...
String[][] buttons = new String[][] {
{"OK"},
{"No", "Yes"},
{"Help", "Close"},
{"OK", "Help"},
{"OK", "Cancel", "Help"},
{"OK", "Cancel", "Apply", "Help"},
{"No", "Yes", "Cancel"},
{"Help", "< Back", "Forward >", "Cancel"},
{"Print...", "Cancel", "Help"}
};
for (int r = 0; r < buttons.length; r++) {
for (int i = 0; i < buttons[r].length; i++) {
String txt = buttons[r][i];
String tag = txt;
if (txt.equals("Help")) {
tag = helpTag;
} else if (txt.equals("< Back")) {
tag = "back";
} else if (txt.equals("Close")) {
tag = "cancel";
} else if (txt.equals("Forward >")) {
tag = "next";
} else if (txt.equals("Print...")) {
tag = "other";
}
String wrap = (i == buttons[r].length - 1) ? ",wrap" : "";
String sizeGroup = sizeLocked ? ("sgx " + r + ",") : "";
panel.add(createButton(txt), sizeGroup + "tag " + tag + wrap);
}
}
return panel;
}
public JComponent createOrientation()
{
JTabbedPane tabbedPane = new JTabbedPane();
MigLayout lm = new MigLayout("flowy", "[grow,fill]", "[]20[]20[]20[]");
JPanel mainPanel = createTabPanel(lm);
// Default orientation
MigLayout defLM = new MigLayout("", "[trailing][grow,fill]", "");
JPanel defPanel = createTabPanel(defLM);
addSeparator(defPanel, "Default Orientation");
defPanel.add(createLabel("Level of Trust"));
defPanel.add(createTextField(""), "span,growx");
defPanel.add(createLabel("Radar Presentation"));
defPanel.add(createTextField(""));
defPanel.add(createTextField(""));
// Right-to-left, Top-to-bottom
MigLayout rtlLM = new MigLayout("rtl,ttb",
"[trailing][grow,fill]",
"");
JPanel rtlPanel = createTabPanel(rtlLM);
addSeparator(rtlPanel, "Right to Left");
rtlPanel.add(createLabel("Level of Trust"));
rtlPanel.add(createTextField(""), "span,growx");
rtlPanel.add(createLabel("Radar Presentation"));
rtlPanel.add(createTextField(""));
rtlPanel.add(createTextField(""));
// Right-to-left, Bottom-to-top
MigLayout rtlbLM = new MigLayout("rtl,btt",
"[trailing][grow,fill]",
"");
JPanel rtlbPanel = createTabPanel(rtlbLM);
addSeparator(rtlbPanel, "Right to Left, Bottom to Top");
rtlbPanel.add(createLabel("Level of Trust"));
rtlbPanel.add(createTextField(""), "span,growx");
rtlbPanel.add(createLabel("Radar Presentation"));
rtlbPanel.add(createTextField(""));
rtlbPanel.add(createTextField(""));
// Left-to-right, Bottom-to-top
MigLayout ltrbLM = new MigLayout("ltr,btt",
"[trailing][grow,fill]",
"");
JPanel ltrbPanel = createTabPanel(ltrbLM);
addSeparator(ltrbPanel, "Left to Right, Bottom to Top");
ltrbPanel.add(createLabel("Level of Trust"));
ltrbPanel.add(createTextField(""), "span,growx");
ltrbPanel.add(createLabel("Radar Presentation"));
ltrbPanel.add(createTextField(""));
ltrbPanel.add(createTextField(""));
mainPanel.add(defPanel);
mainPanel.add(rtlPanel);
mainPanel.add(rtlbPanel);
mainPanel.add(ltrbPanel);
tabbedPane.addTab("Orientation", mainPanel);
// Disregard. Just forgetting the source code text close to the source code.
setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" +
"\n" +
"MigLayout lm = new MigLayout(\"flowy\", \"[grow,fill]\", \"[]0[]15lp[]0[]\");\n" +
"JPanel mainPanel = createTabPanel(lm);\n" +
"\n" +
"// Default orientation\n" +
"MigLayout defLM = new MigLayout(\"\", \"[][grow,fill]\", \"\");\n" +
"\n" +
"JPanel defPanel = createTabPanel(defLM);\n" +
"addSeparator(defPanel, \"Default Orientation\");\n" +
"defPanel.add(createLabel(\"Level\"));\n" +
"defPanel.add(createTextField(\"\"), \"span,growx\");\n" +
"defPanel.add(createLabel(\"Radar\"));\n" +
"defPanel.add(createTextField(\"\"));\n" +
"defPanel.add(createTextField(\"\"));\n" +
"\n" +
"// Right-to-left, Top-to-bottom\n" +
"MigLayout rtlLM = new MigLayout(\"rtl,ttb\",\n" +
" \"[][grow,fill]\",\n" +
" \"\");\n" +
"JPanel rtlPanel = createTabPanel(rtlLM);\n" +
"addSeparator(rtlPanel, \"Right to Left\");\n" +
"rtlPanel.add(createLabel(\"Level\"));\n" +
"rtlPanel.add(createTextField(\"\"), \"span,growx\");\n" +
"rtlPanel.add(createLabel(\"Radar\"));\n" +
"rtlPanel.add(createTextField(\"\"));\n" +
"rtlPanel.add(createTextField(\"\"));\n" +
"\n" +
"// Right-to-left, Bottom-to-top\n" +
"MigLayout rtlbLM = new MigLayout(\"rtl,btt\",\n" +
" \"[][grow,fill]\",\n" +
" \"\");\n" +
"JPanel rtlbPanel = createTabPanel(rtlbLM);\n" +
"addSeparator(rtlbPanel, \"Right to Left, Bottom to Top\");\n" +
"rtlbPanel.add(createLabel(\"Level\"));\n" +
"rtlbPanel.add(createTextField(\"\"), \"span,growx\");\n" +
"rtlbPanel.add(createLabel(\"Radar\"));\n" +
"rtlbPanel.add(createTextField(\"\"));\n" +
"rtlbPanel.add(createTextField(\"\"));\n" +
"\n" +
"// Left-to-right, Bottom-to-top\n" +
"MigLayout ltrbLM = new MigLayout(\"ltr,btt\",\n" +
" \"[][grow,fill]\",\n" +
" \"\");\n" +
"JPanel ltrbPanel = createTabPanel(ltrbLM);\n" +
"addSeparator(ltrbPanel, \"Left to Right, Bottom to Top\");\n" +
"ltrbPanel.add(createLabel(\"Level\"));\n" +
"ltrbPanel.add(createTextField(\"\"), \"span,growx\");\n" +
"ltrbPanel.add(createLabel(\"Radar\"));\n" +
"ltrbPanel.add(createTextField(\"\"));\n" +
"ltrbPanel.add(createTextField(\"\"));\n" +
"\n" +
"mainPanel.add(defPanel);\n" +
"mainPanel.add(rtlPanel);\n" +
"mainPanel.add(rtlbPanel);\n" +
"mainPanel.add(ltrbPanel);\n" +
"\n" +
"tabbedPane.addTab(\"Orientation\", mainPanel);");
return tabbedPane;
}
public JComponent createCell_Position()
{
JTabbedPane tabbedPane = new JTabbedPane();
// Absolute grid position
MigLayout absLM = new MigLayout("",
"[100:pref,fill]",
"[100:pref,fill]");
JPanel absPanel = createTabPanel(absLM);
absPanel.add(createButton(), "cell 0 0");
absPanel.add(createButton(), "cell 2 0");
absPanel.add(createButton(), "cell 3 0");
absPanel.add(createButton(), "cell 1 1");
absPanel.add(createButton(), "cell 0 2");
absPanel.add(createButton(), "cell 2 2");
absPanel.add(createButton(), "cell 2 2");
// Relative grid position with wrap
MigLayout relAwLM = new MigLayout("wrap",
"[100:pref,fill][100:pref,fill][100:pref,fill][100:pref,fill]",
"[100:pref,fill]");
JPanel relAwPanel = createTabPanel(relAwLM);
relAwPanel.add(createButton());
relAwPanel.add(createButton(), "skip");
relAwPanel.add(createButton());
relAwPanel.add(createButton(), "skip,wrap");
relAwPanel.add(createButton());
relAwPanel.add(createButton(), "skip,split");
relAwPanel.add(createButton());
// Relative grid position with manual wrap
MigLayout relWLM = new MigLayout("",
"[100:pref,fill]",
"[100:pref,fill]");
JPanel relWPanel = createTabPanel(relWLM);
relWPanel.add(createButton());
relWPanel.add(createButton(), "skip");
relWPanel.add(createButton(), "wrap");
relWPanel.add(createButton(), "skip,wrap");
relWPanel.add(createButton());
relWPanel.add(createButton(), "skip,split");
relWPanel.add(createButton());
// Mixed relative and absolute grid position
MigLayout mixLM = new MigLayout("",
"[100:pref,fill]",
"[100:pref,fill]");
JPanel mixPanel = createTabPanel(mixLM);
mixPanel.add(createButton());
mixPanel.add(createButton(), "cell 2 0");
mixPanel.add(createButton());
mixPanel.add(createButton(), "cell 1 1,wrap");
mixPanel.add(createButton());
mixPanel.add(createButton(), "cell 2 2,split");
mixPanel.add(createButton());
tabbedPane.addTab("Absolute", absPanel);
tabbedPane.addTab("Relative + Wrap", relAwPanel);
tabbedPane.addTab("Relative", relWPanel);
tabbedPane.addTab("Mixed", mixPanel);
// Disregard. Just forgetting the source code text close to the source code.
setSource("\t\tJTabbedPane tabbedPane = new JTabbedPane();\n" +
"\n" +
"\t\t// Absolute grid position\n" +
"\t\tMigLayout absLM = new MigLayout(\"\",\n" +
"\t\t \"[100:pref,fill]\",\n" +
"\t\t \"[100:pref,fill]\");\n" +
"\t\tJPanel absPanel = createTabPanel(absLM);\n" +
"\t\tabsPanel.add(createPanel(), \"cell 0 0\");\n" +
"\t\tabsPanel.add(createPanel(), \"cell 2 0\");\n" +
"\t\tabsPanel.add(createPanel(), \"cell 3 0\");\n" +
"\t\tabsPanel.add(createPanel(), \"cell 1 1\");\n" +
"\t\tabsPanel.add(createPanel(), \"cell 0 2\");\n" +
"\t\tabsPanel.add(createPanel(), \"cell 2 2\");\n" +
"\t\tabsPanel.add(createPanel(), \"cell 2 2\");\n" +
"\n" +
"\n" +
"\t\t// Relative grid position with wrap\n" +
"\t\tMigLayout relAwLM = new MigLayout(\"wrap\",\n" +
"\t\t \"[100:pref,fill][100:pref,fill][100:pref,fill][100:pref,fill]\",\n" +
"\t\t \"[100:pref,fill]\");\n" +
"\t\tJPanel relAwPanel = createTabPanel(relAwLM);\n" +
"\t\trelAwPanel.add(createPanel());\n" +
"\t\trelAwPanel.add(createPanel(), \"skip\");\n" +
"\t\trelAwPanel.add(createPanel());\n" +
"\t\trelAwPanel.add(createPanel(), \"skip,wrap\");\n" +
"\t\trelAwPanel.add(createPanel());\n" +
"\t\trelAwPanel.add(createPanel(), \"skip,split\");\n" +
"\t\trelAwPanel.add(createPanel());\n" +
"\n" +
"\n" +
"\t\t// Relative grid position with manual wrap\n" +
"\t\tMigLayout relWLM = new MigLayout(\"\",\n" +
"\t\t \"[100:pref,fill]\",\n" +
"\t\t \"[100:pref,fill]\");\n" +
"\t\tJPanel relWPanel = createTabPanel(relWLM);\n" +
"\t\trelWPanel.add(createPanel());\n" +
"\t\trelWPanel.add(createPanel(), \"skip\");\n" +
"\t\trelWPanel.add(createPanel(), \"wrap\");\n" +
"\t\trelWPanel.add(createPanel(), \"skip,wrap\");\n" +
"\t\trelWPanel.add(createPanel());\n" +
"\t\trelWPanel.add(createPanel(), \"skip,split\");\n" +
"\n" +
"\t\trelWPanel.add(createPanel());\n" +
"\n" +
"\n" +
"\t\t// Mixed relative and absolute grid position\n" +
"\t\tMigLayout mixLM = new MigLayout(\"\",\n" +
"\t\t \"[100:pref,fill]\",\n" +
"\t\t \"[100:pref,fill]\");\n" +
"\t\tJPanel mixPanel = createTabPanel(mixLM);\n" +
"\t\tmixPanel.add(createPanel());\n" +
"\t\tmixPanel.add(createPanel(), \"cell 2 0\");\n" +
"\t\tmixPanel.add(createPanel());\n" +
"\t\tmixPanel.add(createPanel(), \"cell 1 1,wrap\");\n" +
"\t\tmixPanel.add(createPanel());\n" +
"\t\tmixPanel.add(createPanel(), \"cell 2 2,split\");\n" +
"\t\tmixPanel.add(createPanel());\n" +
"\n" +
"\t\ttabbedPane.addTab(\"Absolute\", absPanel);\n" +
"\t\ttabbedPane.addTab(\"Relative + Wrap\", relAwPanel);\n" +
"\t\ttabbedPane.addTab(\"Relative\", relWPanel);\n" +
"\t\ttabbedPane.addTab(\"Mixed\", mixPanel);");
return tabbedPane;
}
public JComponent createPlain()
{
return createPlainImpl(false);
}
private JComponent createPlainImpl(boolean debug)
{
JTabbedPane tabbedPane = new JTabbedPane();
MigLayout lm = new MigLayout((debug && benchRuns == 0 ? "debug, inset 20" : "ins 20"), "[para]0[][100lp, fill][60lp][95lp, fill]", "");
JPanel panel = createTabPanel(lm);
addSeparator(panel, "Manufacturer");
panel.add(createLabel("Company"), "skip");
panel.add(createTextField(""), "span, growx");
panel.add(createLabel("Contact"), "skip");
panel.add(createTextField(""), "span, growx");
panel.add(createLabel("Order No"), "skip");
panel.add(createTextField(15), "wrap para");
addSeparator(panel, "Inspector");
panel.add(createLabel("Name"), "skip");
panel.add(createTextField(""), "span, growx");
panel.add(createLabel("Reference No"), "skip");
panel.add(createTextField(""), "wrap");
panel.add(createLabel("Status"), "skip");
panel.add(createCombo(new String[] {"In Progress", "Finnished", "Released"}), "wrap para");
addSeparator(panel, "Ship");
panel.add(createLabel("Shipyard"), "skip");
panel.add(createTextField(""), "span, growx");
panel.add(createLabel("Register No"), "skip");
panel.add(createTextField(""));
panel.add(createLabel("Hull No"), "right");
panel.add(createTextField(15), "wrap");
panel.add(createLabel("Project StructureType"), "skip");
panel.add(createCombo(new String[] {"New Building", "Convention", "Repair"}));
if (debug)
panel.add(createLabel("Red is cell bounds. Blue is component bounds."), "newline,ax left,span,gaptop 40,");
tabbedPane.addTab("Plain", panel);
// Disregard. Just forgetting the source code text close to the source code.
setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" +
"\n" +
"MigLayout lm = new MigLayout((debug && benchRuns == 0 ? \"debug, inset 20\" : \"ins 20\"), \"[para]0[][100lp, fill][60lp][95lp, fill]\", \"\");\n" +
"JPanel panel = createTabPanel(lm);\n" +
"\n" +
"addSeparator(panel, \"Manufacturer\");\n" +
"\n" +
"panel.add(createLabel(\"Company\"), \"skip\");\n" +
"panel.add(createTextField(\"\"), \"span, growx\");\n" +
"panel.add(createLabel(\"Contact\"), \"skip\");\n" +
"panel.add(createTextField(\"\"), \"span, growx\");\n" +
"panel.add(createLabel(\"Order No\"), \"skip\");\n" +
"panel.add(createTextField(15), \"wrap para\");\n" +
"\n" +
"addSeparator(panel, \"Inspector\");\n" +
"\n" +
"panel.add(createLabel(\"Name\"), \"skip\");\n" +
"panel.add(createTextField(\"\"), \"span, growx\");\n" +
"panel.add(createLabel(\"Reference No\"), \"skip\");\n" +
"panel.add(createTextField(\"\"), \"wrap\");\n" +
"panel.add(createLabel(\"Status\"), \"skip\");\n" +
"panel.add(createCombo(new String[] {\"In Progress\", \"Finnished\", \"Released\"}), \"wrap para\");\n" +
"\n" +
"addSeparator(panel, \"Ship\");\n" +
"\n" +
"panel.add(createLabel(\"Shipyard\"), \"skip\");\n" +
"panel.add(createTextField(\"\"), \"span, growx\");\n" +
"panel.add(createLabel(\"Register No\"), \"skip\");\n" +
"panel.add(createTextField(\"\"));\n" +
"panel.add(createLabel(\"Hull No\"), \"right\");\n" +
"panel.add(createTextField(15), \"wrap\");\n" +
"panel.add(createLabel(\"Project StructureType\"), \"skip\");\n" +
"panel.add(createCombo(new String[] {\"New Building\", \"Convention\", \"Repair\"}));\n" +
"\n" +
"if (debug)\n" +
"\tpanel.add(createLabel(\"Red is cell bounds. Blue is component bounds.\"), \"newline,ax left,span,gaptop 40,\");\n" +
"\n" +
"tabbedPane.addTab(\"Plain\", panel);");
return tabbedPane;
}
public JComponent createBound_Sizes()
{
JTabbedPane tabbedPane = new JTabbedPane();
for (int i = 0; i < 2; i++) { // Jumping for 0 and Stable for 1
String colConstr = i == 0 ? "[right][300]" : "[right, 100lp:pref][300]";
MigLayout LM1 = new MigLayout("wrap", colConstr, "");
JPanel panel1 = createTabPanel(LM1);
panel1.add(createLabel("File Number:"));
panel1.add(createTextField(""), "growx");
panel1.add(createLabel("RFQ Number:"));
panel1.add(createTextField(""), "growx");
panel1.add(createLabel("Entry Date:"));
panel1.add(createTextField(6));
panel1.add(createLabel("Sales Person:"));
panel1.add(createTextField(""), "growx");
MigLayout LM2 = new MigLayout("wrap", colConstr, "");
JPanel panel2 = createTabPanel(LM2);
panel2.add(createLabel("Shipper:"));
panel2.add(createTextField(6), "split 2");
panel2.add(createTextField(""), "growx");
panel2.add(createLabel("Consignee:"));
panel2.add(createTextField(6), "split 2");
panel2.add(createTextField(""), "growx");
panel2.add(createLabel("Departure:"));
panel2.add(createTextField(6), "split 2");
panel2.add(createTextField(""), "growx");
panel2.add(createLabel("Destination:"));
panel2.add(createTextField(6), "split 2");
panel2.add(createTextField(""), "growx");
tabbedPane.addTab(i == 0 ? "Jumping 1" : "Stable 1", panel1);
tabbedPane.addTab(i == 0 ? "Jumping 2" : "Stable 2", panel2);
}
// Disregard. Just forgetting the source code text close to the source code.
setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" +
"\n" +
"for (int i = 0; i < 2; i++) { // Jumping for 0 and Stable for 1\n" +
"\tString colConstr = i == 0 ? \"[right][300]\" : \"[right, 100lp:pref][300]\";\n" +
"\n" +
"\tMigLayout LM1 = new MigLayout(\"wrap\", colConstr, \"\");\n" +
"\tJPanel panel1 = createTabPanel(LM1);\n" +
"\tpanel1.add(createLabel(\"File Number:\"));\n" +
"\tpanel1.add(createTextField(\"\"), \"growx\");\n" +
"\tpanel1.add(createLabel(\"RFQ Number:\"));\n" +
"\tpanel1.add(createTextField(\"\"), \"growx\");\n" +
"\tpanel1.add(createLabel(\"Entry Date:\"));\n" +
"\tpanel1.add(createTextField(6));\n" +
"\tpanel1.add(createLabel(\"Sales Person:\"));\n" +
"\tpanel1.add(createTextField(\"\"), \"growx\");\n" +
"\n" +
"\tMigLayout LM2 = new MigLayout(\"wrap\", colConstr, \"\");\n" +
"\tJPanel panel2 = createTabPanel(LM2);\n" +
"\tpanel2.add(createLabel(\"Shipper:\"));\n" +
"\tpanel2.add(createTextField(6), \"split 2\");\n" +
"\tpanel2.add(createTextField(\"\"), \"growx\");\n" +
"\tpanel2.add(createLabel(\"Consignee:\"));\n" +
"\tpanel2.add(createTextField(6), \"split 2\");\n" +
"\tpanel2.add(createTextField(\"\"), \"growx\");\n" +
"\tpanel2.add(createLabel(\"Departure:\"));\n" +
"\tpanel2.add(createTextField(6), \"split 2\");\n" +
"\tpanel2.add(createTextField(\"\"), \"growx\");\n" +
"\tpanel2.add(createLabel(\"Destination:\"));\n" +
"\tpanel2.add(createTextField(6), \"split 2\");\n" +
"\tpanel2.add(createTextField(\"\"), \"growx\");\n" +
"\n" +
"\ttabbedPane.addTab(i == 0 ? \"Jumping 1\" : \"Stable 2\", panel1);\n" +
"\ttabbedPane.addTab(i == 0 ? \"Jumping 2\" : \"Stable 2\", panel2);\n" +
"}");
return tabbedPane;
}
public JComponent createComponent_Sizes()
{
JTabbedPane tabbedPane = new JTabbedPane();
MigLayout LM = new MigLayout("wrap", "[right][0:pref,grow]", "");
JPanel panel = createTabPanel(LM);
JScrollPane descrText = createTextAreaScroll("Use slider to see how the components grow and shrink depending on the constraints set on them.", 0, 0, false);
descrText.setOpaque(OPAQUE);
descrText.setBorder(new EmptyBorder(10, 10, 10, 10));
((JTextArea) descrText.getViewport().getView()).setOpaque(OPAQUE);
descrText.getViewport().setOpaque(OPAQUE);
JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, panel, descrText);
splitPane.setOpaque(OPAQUE);
splitPane.setBorder(null);
panel.add(createLabel("\"\""));
panel.add(createTextField(""));
panel.add(createLabel("\"min!\""));
panel.add(createTextField("3", 3), "width min!");
panel.add(createLabel("\"pref!\""));
panel.add(createTextField("3", 3), "width pref!");
panel.add(createLabel("\"min:pref\""));
panel.add(createTextField("8", 8), "width min:pref");
panel.add(createLabel("\"min:100:150\""));
panel.add(createTextField("8", 8), "width min:100:150");
panel.add(createLabel("\"min:100:150, growx\""));
panel.add(createTextField("8", 8), "width min:100:150, growx");
panel.add(createLabel("\"min:100, growx\""));
panel.add(createTextField("8", 8), "width min:100, growx");
panel.add(createLabel("\"40!\""));
panel.add(createTextField("8", 8), "width 40!");
panel.add(createLabel("\"40:40:40\""));
panel.add(createTextField("8", 8), "width 40:40:40");
tabbedPane.addTab("Component Sizes", splitPane);
// Disregard. Just forgetting the source code text close to the source code.
setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" +
"\n" +
"\t\tMigLayout LM = new MigLayout(\"wrap\", \"[right][0:pref,grow]\", \"\");\n" +
"\n" +
"\t\tJPanel panel = createTabPanel(LM);\n" +
"\t\tJScrollPane descrText = createTextAreaScroll(\"Use slider to see how the components grow and shrink depending on the constraints set on them.\", 0, 0, false);\n" +
"\n" +
"\t\tdescrText.setOpaque(OPAQUE);\n" +
"\t\tdescrText.setBorder(new EmptyBorder(10, 10, 10, 10));\n" +
"\t\t((JTextArea) descrText.getViewport().getView()).setOpaque(OPAQUE);\n" +
"\t\tdescrText.getViewport().setOpaque(OPAQUE);\n" +
"\n" +
"\t\tJSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, panel, descrText);\n" +
"\t\tsplitPane.setOpaque(OPAQUE);\n" +
"\t\tsplitPane.setBorder(null);\n" +
"\n" +
"\t\tpanel.add(createLabel(\"\\\"\\\"\"));\n" +
"\t\tpanel.add(createTextField(\"\"));\n" +
"\t\tpanel.add(createLabel(\"\\\"min!\\\"\"));\n" +
"\t\tpanel.add(createTextField(\"3\", 3), \"width min!\");\n" +
"\t\tpanel.add(createLabel(\"\\\"pref!\\\"\"));\n" +
"\t\tpanel.add(createTextField(\"3\", 3), \"width pref!\");\n" +
"\t\tpanel.add(createLabel(\"\\\"min:pref\\\"\"));\n" +
"\t\tpanel.add(createTextField(\"8\", 8), \"width min:pref\");\n" +
"\t\tpanel.add(createLabel(\"\\\"min:100:150\\\"\"));\n" +
"\t\tpanel.add(createTextField(\"8\", 8), \"width min:100:150\");\n" +
"\t\tpanel.add(createLabel(\"\\\"min:100:150, growx\\\"\"));\n" +
"\t\tpanel.add(createTextField(\"8\", 8), \"width min:100:150, growx\");\n" +
"\t\tpanel.add(createLabel(\"\\\"min:100, growx\\\"\"));\n" +
"\t\tpanel.add(createTextField(\"8\", 8), \"width min:100, growx\");\n" +
"\t\tpanel.add(createLabel(\"\\\"40!\\\"\"));\n" +
"\t\tpanel.add(createTextField(\"8\", 8), \"width 40!\");\n" +
"\t\tpanel.add(createLabel(\"\\\"40:40:40\\\"\"));\n" +
"\t\tpanel.add(createTextField(\"8\", 8), \"width 40:40:40\");\n" +
"\n" +
"\t\ttabbedPane.addTab(\"Component Sizes\", splitPane);");
return tabbedPane;
}
public JComponent createCell_Alignments()
{
JTabbedPane tabbedPane = new JTabbedPane();
// Horizontal
MigLayout hLM = new MigLayout("wrap",
"[grow,left][grow,center][grow,right][grow,fill,center]",
"[]unrel[][]");
JPanel hPanel = createTabPanel(hLM);
String[] sizes = new String[] {"", "growx", "growx 0", "left", "center", "right", "leading", "trailing"};
hPanel.add(createLabel("[left]"), "c");
hPanel.add(createLabel("[center]"), "c");
hPanel.add(createLabel("[right]"), "c");
hPanel.add(createLabel("[fill,center]"), "c, growx 0");
for (int r = 0; r < sizes.length; r++) {
for (int c = 0; c < 4; c++) {
String text = sizes[r].length() > 0 ? sizes[r] : "default";
hPanel.add(createButton(text), sizes[r]);
}
}
// Vertical
MigLayout vLM = new MigLayout("wrap,flowy",
"[right][]",
"[grow,top][grow,center][grow,bottom][grow,fill,bottom][grow,fill,baseline]");
JPanel vPanel = createTabPanel(vLM);
String[] vSizes = new String[] {"", "growy", "growy 0", "top", "aligny center", "bottom"};
vPanel.add(createLabel("[top]"), "aligny center");
vPanel.add(createLabel("[center]"), "aligny center");
vPanel.add(createLabel("[bottom]"), "aligny center");
vPanel.add(createLabel("[fill, bottom]"), "aligny center, growy 0");
vPanel.add(createLabel("[fill, baseline]"), "aligny center");
for (int c = 0; c < vSizes.length; c++) {
for (int r = 0; r < 5; r++) {
String text = vSizes[c].length() > 0 ? vSizes[c] : "default";
JButton b = createButton(text);
if (r == 4 && c <= 1)
b.setFont(new Font("sansserif", Font.PLAIN, 16 + c * 5));
vPanel.add(b, vSizes[c]);
}
}
tabbedPane.addTab("Horizontal", hPanel);
tabbedPane.addTab("Vertical", vPanel);
// Disregard. Just forgetting the source code text close to the source code.
setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" +
"\n" +
"// Horizontal\n" +
"MigLayout hLM = new MigLayout(\"wrap\",\n" +
" \"[grow,left][grow,center][grow,right][grow,fill,center]\",\n" +
" \"[]unrel[][]\");\n" +
"JPanel hPanel = createTabPanel(hLM);\n" +
"String[] sizes = new String[] {\"\", \"growx\", \"growx 0\", \"left\", \"center\", \"right\", \"leading\", \"trailing\"};\n" +
"hPanel.add(createLabel(\"[left]\"), \"c\");\n" +
"hPanel.add(createLabel(\"[center]\"), \"c\");\n" +
"hPanel.add(createLabel(\"[right]\"), \"c\");\n" +
"hPanel.add(createLabel(\"[fill,center]\"), \"c, growx 0\");\n" +
"\n" +
"for (int r = 0; r < sizes.length; r++) {\n" +
"\tfor (int c = 0; c < 4; c++) {\n" +
"\t\tString text = sizes[r].length() > 0 ? sizes[r] : \"default\";\n" +
"\t\thPanel.add(createButton(text), sizes[r]);\n" +
"\t}\n" +
"}\n" +
"\n" +
"// Vertical\n" +
"MigLayout vLM = new MigLayout(\"wrap,flowy\",\n" +
" \"[right][]\",\n" +
" \"[grow,top][grow,center][grow,bottom][grow,fill,bottom][grow,fill,baseline]\");\n" +
"JPanel vPanel = createTabPanel(vLM);\n" +
"String[] vSizes = new String[] {\"\", \"growy\", \"growy 0\", \"top\", \"center\", \"bottom\"};\n" +
"vPanel.add(createLabel(\"[top]\"), \"center\");\n" +
"vPanel.add(createLabel(\"[center]\"), \"center\");\n" +
"vPanel.add(createLabel(\"[bottom]\"), \"center\");\n" +
"vPanel.add(createLabel(\"[fill, bottom]\"), \"center, growy 0\");\n" +
"vPanel.add(createLabel(\"[fill, baseline]\"), \"center\");\n" +
"\n" +
"for (int c = 0; c < vSizes.length; c++) {\n" +
"\tfor (int r = 0; r < 5; r++) {\n" +
"\t\tString text = vSizes[c].length() > 0 ? vSizes[c] : \"default\";\n" +
"\t\tJButton b = createButton(text);\n" +
"\t\tif (r == 4 && c <= 1)\n" +
"\t\t\tb.setFont(new Font(\"sansserif\", Font.PLAIN, 16 + c * 5));\n" +
"\t\tvPanel.add(b, vSizes[c]);\n" +
"\t}\n" +
"}\n" +
"\n" +
"tabbedPane.addTab(\"Horizontal\", hPanel);\n" +
"tabbedPane.addTab(\"Vertical\", vPanel);");
return tabbedPane;
}
public JComponent createUnits()
{
JTabbedPane tabbedPane = new JTabbedPane();
// Horizontal
MigLayout hLM = new MigLayout("wrap,nocache",
"[right][]",
"");
JPanel hPanel = createTabPanel(hLM);
String[] sizes = new String[] {"72pt", "25.4mm", "2.54cm", "1in", "72px", "96px", "120px", "25%", "20sp"};
for (int i = 0; i < sizes.length; i++) {
hPanel.add(createLabel(sizes[i]));
hPanel.add(createTextField(""), "width " + sizes[i] + "!");
}
// Horizontal lp
MigLayout hlpLM = new MigLayout("nocache", "[right][][]", "");
JPanel hlpPanel = createTabPanel(hlpLM);
hlpPanel.add(createLabel("9 cols"));
hlpPanel.add(createTextField(9));
String[] lpSizes = new String[] {"75lp", "75px", "88px", "100px"};
hlpPanel.add(createLabel("Width of createTextField(9)"), "wrap");
for (int i = 0; i < lpSizes.length; i++) {
hlpPanel.add(createLabel(lpSizes[i]));
hlpPanel.add(createTextField(""), "width " + lpSizes[i] + "!, wrap");
}
// Vertical
MigLayout vLM = new MigLayout("wrap,flowy,nocache",
"[c]",
"[top][top]");
JPanel vPanel = createTabPanel(vLM);
String[] vSizes = new String[] {"72pt", "25.4mm", "2.54cm", "1in", "72px", "96px", "120px", "25%", "20sp"};
for (int i = 0; i < sizes.length; i++) {
vPanel.add(createLabel(vSizes[i]));
vPanel.add(createTextArea("", 0, 5), "width 50!, height " + vSizes[i] + "!");
}
// Vertical lp
MigLayout vlpLM = new MigLayout("wrap,flowy,nocache",
"[c]",
"[top][top]40px[top][top]");
JPanel vlpPanel = createTabPanel(vlpLM);
vlpPanel.add(createLabel("4 rows"));
vlpPanel.add(createTextArea("", 4, 5), "width 50!");
vlpPanel.add(createLabel("field"));
vlpPanel.add(createTextField(5));
String[] vlpSizes1 = new String[] {"63lp", "57px", "63px", "68px", "25%"};
String[] vlpSizes2 = new String[] {"21lp", "21px", "23px", "24px", "10%"};
for (int i = 0; i < vlpSizes1.length; i++) {
vlpPanel.add(createLabel(vlpSizes1[i]));
vlpPanel.add(createTextArea("", 1, 5), "width 50!, height " + vlpSizes1[i] + "!");
vlpPanel.add(createLabel(vlpSizes2[i]));
vlpPanel.add(createTextField(5), "height " + vlpSizes2[i] + "!");
}
vlpPanel.add(createLabel("button"), "skip 2");
vlpPanel.add(createButton("..."));
tabbedPane.addTab("Horizontal", hPanel);
tabbedPane.addTab("Horizontal LP", hlpPanel);
tabbedPane.addTab("Vertical", vPanel);
tabbedPane.addTab("Vertical LP", vlpPanel);
// Disregard. Just forgetting the source code text close to the source code.
setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" +
"\n" +
"// Horizontal\n" +
"MigLayout hLM = new MigLayout(\"wrap,nocache\",\n" +
"\t\t\t\t\t\t\t \"[right][]\",\n" +
"\t\t\t\t\t\t\t \"\");\n" +
"JPanel hPanel = createTabPanel(hLM);\n" +
"String[] sizes = new String[] {\"72pt\", \"25.4mm\", \"2.54cm\", \"1in\", \"72px\", \"96px\", \"120px\", \"25%\", \"20sp\"};\n" +
"for (int i = 0; i < sizes.length; i++) {\n" +
"\thPanel.add(createLabel(sizes[i]));\n" +
"\thPanel.add(createTextField(\"\"), \"width \" + sizes[i] + \"!\");\n" +
"}\n" +
"\n" +
"// Horizontal lp\n" +
"MigLayout hlpLM = new MigLayout(\"nocache\", \"[right][][]\", \"\");\n" +
"JPanel hlpPanel = createTabPanel(hlpLM);\n" +
"hlpPanel.add(createLabel(\"9 cols\"));\n" +
"hlpPanel.add(createTextField(9));\n" +
"String[] lpSizes = new String[] {\"75lp\", \"75px\", \"88px\", \"100px\"};\n" +
"hlpPanel.add(createLabel(\"Width of createTextField(9)\"), \"wrap\");\n" +
"for (int i = 0; i < lpSizes.length; i++) {\n" +
"\thlpPanel.add(createLabel(lpSizes[i]));\n" +
"\thlpPanel.add(createTextField(\"\"), \"width \" + lpSizes[i] + \"!, wrap\");\n" +
"}\n" +
"\n" +
"// Vertical\n" +
"MigLayout vLM = new MigLayout(\"wrap,flowy,nocache\",\n" +
"\t\t\t\t\t\t\t \"[c]\",\n" +
"\t\t\t\t\t\t\t \"[top][top]\");\n" +
"JPanel vPanel = createTabPanel(vLM);\n" +
"String[] vSizes = new String[] {\"72pt\", \"25.4mm\", \"2.54cm\", \"1in\", \"72px\", \"96px\", \"120px\", \"25%\", \"20sp\"};\n" +
"for (int i = 0; i < sizes.length; i++) {\n" +
"\tvPanel.add(createLabel(vSizes[i]));\n" +
"\tvPanel.add(createTextArea(\"\", 0, 5), \"width 50!, height \" + vSizes[i] + \"!\");\n" +
"}\n" +
"\n" +
"// Vertical lp\n" +
"MigLayout vlpLM = new MigLayout(\"wrap,flowy,nocache\",\n" +
"\t\t\t\t\t\t\t\t\"[c]\",\n" +
"\t\t\t\t\t\t\t\t\"[top][top]40px[top][top]\");\n" +
"JPanel vlpPanel = createTabPanel(vlpLM);\n" +
"vlpPanel.add(createLabel(\"4 rows\"));\n" +
"vlpPanel.add(createTextArea(\"\", 4, 5), \"width 50!\");\n" +
"vlpPanel.add(createLabel(\"field\"));\n" +
"vlpPanel.add(createTextField(5));\n" +
"\n" +
"String[] vlpSizes1 = new String[] {\"63lp\", \"57px\", \"63px\", \"68px\", \"25%\"};\n" +
"String[] vlpSizes2 = new String[] {\"21lp\", \"21px\", \"23px\", \"24px\", \"10%\"};\n" +
"for (int i = 0; i < vlpSizes1.length; i++) {\n" +
"\tvlpPanel.add(createLabel(vlpSizes1[i]));\n" +
"\tvlpPanel.add(createTextArea(\"\", 1, 5), \"width 50!, height \" + vlpSizes1[i] + \"!\");\n" +
"\tvlpPanel.add(createLabel(vlpSizes2[i]));\n" +
"\tvlpPanel.add(createTextField(5), \"height \" + vlpSizes2[i] + \"!\");\n" +
"}\n" +
"\n" +
"vlpPanel.add(createLabel(\"button\"), \"skip 2\");\n" +
"vlpPanel.add(createButton(\"...\"));\n" +
"\n" +
"tabbedPane.addTab(\"Horizontal\", hPanel);\n" +
"tabbedPane.addTab(\"Horizontal LP\", hlpPanel);\n" +
"tabbedPane.addTab(\"Vertical\", vPanel);\n" +
"tabbedPane.addTab(\"Vertical LP\", vlpPanel);");
return tabbedPane;
}
public JComponent createGrouping()
{
JTabbedPane tabbedPane = new JTabbedPane();
// Ungrouped
MigLayout ugM = new MigLayout("", "[]push[][][]", "");
JPanel ugPanel = createTabPanel(ugM);
ugPanel.add(createButton("Help"));
ugPanel.add(createButton("< Back"), "");
ugPanel.add(createButton("Forward >"), "gap push");
ugPanel.add(createButton("Apply"), "gap unrel");
ugPanel.add(createButton("Cancel"), "gap unrel");
// Grouped Components
MigLayout gM = new MigLayout("nogrid, fillx");
JPanel gPanel = createTabPanel(gM);
gPanel.add(createButton("Help"), "sg");
gPanel.add(createButton("< Back"), "sg,gap push");
gPanel.add(createButton("Forward >"), "sg");
gPanel.add(createButton("Apply"), "sg,gap unrel");
gPanel.add(createButton("Cancel"), "sg,gap unrel");
// Grouped Columns
MigLayout gcM = new MigLayout("", "[sg,fill]push[sg,fill][sg,fill]unrel[sg,fill]unrel[sg,fill]", "");
JPanel gcPanel = createTabPanel(gcM);
gcPanel.add(createButton("Help"));
gcPanel.add(createButton("< Back"));
gcPanel.add(createButton("Forward >"));
gcPanel.add(createButton("Apply"));
gcPanel.add(createButton("Cancel"));
// Ungrouped Rows
MigLayout ugrM = new MigLayout(); // no "sg" is the only difference to next panel
JPanel ugrPanel = createTabPanel(ugrM);
ugrPanel.add(createLabel("File Number:"));
ugrPanel.add(createTextField(30), "wrap");
ugrPanel.add(createLabel("BL/MBL number:"));
ugrPanel.add(createTextField(7), "split 2");
ugrPanel.add(createTextField(7), "wrap");
ugrPanel.add(createLabel("Entry Date:"));
ugrPanel.add(createTextField(7), "wrap");
ugrPanel.add(createLabel("RFQ Number:"));
ugrPanel.add(createTextField(30), "wrap");
ugrPanel.add(createLabel("Goods:"));
ugrPanel.add(createCheck("Dangerous"), "wrap");
ugrPanel.add(createLabel("Shipper:"));
ugrPanel.add(createTextField(30), "wrap");
ugrPanel.add(createLabel("Customer:"));
ugrPanel.add(createTextField(""), "split 2,growx");
ugrPanel.add(createButton("..."), "width 60px:pref,wrap");
ugrPanel.add(createLabel("Port of Loading:"));
ugrPanel.add(createTextField(30), "wrap");
ugrPanel.add(createLabel("Destination:"));
ugrPanel.add(createTextField(30), "wrap");
// Grouped Rows
MigLayout grM = new MigLayout("", "[]", "[sg]"); // "sg" is the only difference to previous panel
JPanel grPanel = createTabPanel(grM);
grPanel.add(createLabel("File Number:"));
grPanel.add(createTextField(30),"wrap");
grPanel.add(createLabel("BL/MBL number:"));
grPanel.add(createTextField(7),"split 2");
grPanel.add(createTextField(7), "wrap");
grPanel.add(createLabel("Entry Date:"));
grPanel.add(createTextField(7), "wrap");
grPanel.add(createLabel("RFQ Number:"));
grPanel.add(createTextField(30), "wrap");
grPanel.add(createLabel("Goods:"));
grPanel.add(createCheck("Dangerous"), "wrap");
grPanel.add(createLabel("Shipper:"));
grPanel.add(createTextField(30), "wrap");
grPanel.add(createLabel("Customer:"));
grPanel.add(createTextField(""), "split 2,growx");
grPanel.add(createButton("..."), "width 50px:pref,wrap");
grPanel.add(createLabel("Port of Loading:"));
grPanel.add(createTextField(30), "wrap");
grPanel.add(createLabel("Destination:"));
grPanel.add(createTextField(30), "wrap");
tabbedPane.addTab("Ungrouped", ugPanel);
tabbedPane.addTab("Grouped (Components)", gPanel);
tabbedPane.addTab("Grouped (Columns)", gcPanel);
tabbedPane.addTab("Ungrouped Rows", ugrPanel);
tabbedPane.addTab("Grouped Rows", grPanel);
// Disregard. Just forgetting the source code text close to the source code.
setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" +
"\n" +
"// Ungrouped\n" +
"MigLayout ugM = new MigLayout(\"\", \"[]push[][][]\", \"\");\n" +
"JPanel ugPanel = createTabPanel(ugM);\n" +
"ugPanel.add(createButton(\"Help\"));\n" +
"ugPanel.add(createButton(\"< Back\"), \"\");\n" +
"ugPanel.add(createButton(\"Forward >\"), \"gap push\");\n" +
"ugPanel.add(createButton(\"Apply\"), \"gap unrel\");\n" +
"ugPanel.add(createButton(\"Cancel\"), \"gap unrel\");\n" +
"\n" +
"// Grouped Components\n" +
"MigLayout gM = new MigLayout(\"nogrid, fillx\");\n" +
"JPanel gPanel = createTabPanel(gM);\n" +
"gPanel.add(createButton(\"Help\"), \"sg\");\n" +
"gPanel.add(createButton(\"< Back\"), \"sg,gap push\");\n" +
"gPanel.add(createButton(\"Forward >\"), \"sg\");\n" +
"gPanel.add(createButton(\"Apply\"), \"sg,gap unrel\");\n" +
"gPanel.add(createButton(\"Cancel\"), \"sg,gap unrel\");\n" +
"\n" +
"// Grouped Columns\n" +
"MigLayout gcM = new MigLayout(\"\", \"[sg,fill]push[sg,fill][sg,fill]unrel[sg,fill]unrel[sg,fill]\", \"\");\n" +
"JPanel gcPanel = createTabPanel(gcM);\n" +
"gcPanel.add(createButton(\"Help\"));\n" +
"gcPanel.add(createButton(\"< Back\"));\n" +
"gcPanel.add(createButton(\"Forward >\"));\n" +
"gcPanel.add(createButton(\"Apply\"));\n" +
"gcPanel.add(createButton(\"Cancel\"));\n" +
"\n" +
"// Ungrouped Rows\n" +
"MigLayout ugrM = new MigLayout(); // no \"sg\" is the only difference to next panel\n" +
"JPanel ugrPanel = createTabPanel(ugrM);\n" +
"ugrPanel.add(createLabel(\"File Number:\"));\n" +
"ugrPanel.add(createTextField(30), \"wrap\");\n" +
"ugrPanel.add(createLabel(\"BL/MBL number:\"));\n" +
"ugrPanel.add(createTextField(7), \"split 2\");\n" +
"ugrPanel.add(createTextField(7), \"wrap\");\n" +
"ugrPanel.add(createLabel(\"Entry Date:\"));\n" +
"ugrPanel.add(createTextField(7), \"wrap\");\n" +
"ugrPanel.add(createLabel(\"RFQ Number:\"));\n" +
"ugrPanel.add(createTextField(30), \"wrap\");\n" +
"ugrPanel.add(createLabel(\"Goods:\"));\n" +
"ugrPanel.add(createCheck(\"Dangerous\"), \"wrap\");\n" +
"ugrPanel.add(createLabel(\"Shipper:\"));\n" +
"ugrPanel.add(createTextField(30), \"wrap\");\n" +
"ugrPanel.add(createLabel(\"Customer:\"));\n" +
"ugrPanel.add(createTextField(\"\"), \"split 2,growx\");\n" +
"ugrPanel.add(createButton(\"...\"), \"width 60px:pref,wrap\");\n" +
"ugrPanel.add(createLabel(\"Port of Loading:\"));\n" +
"ugrPanel.add(createTextField(30), \"wrap\");\n" +
"ugrPanel.add(createLabel(\"Destination:\"));\n" +
"ugrPanel.add(createTextField(30), \"wrap\");\n" +
"\n" +
"// Grouped Rows\n" +
"MigLayout grM = new MigLayout(\"\", \"[]\", \"[sg]\"); // \"sg\" is the only difference to previous panel\n" +
"JPanel grPanel = createTabPanel(grM);\n" +
"grPanel.add(createLabel(\"File Number:\"));\n" +
"grPanel.add(createTextField(30),\"wrap\");\n" +
"grPanel.add(createLabel(\"BL/MBL number:\"));\n" +
"grPanel.add(createTextField(7),\"split 2\");\n" +
"grPanel.add(createTextField(7), \"wrap\");\n" +
"grPanel.add(createLabel(\"Entry Date:\"));\n" +
"grPanel.add(createTextField(7), \"wrap\");\n" +
"grPanel.add(createLabel(\"RFQ Number:\"));\n" +
"grPanel.add(createTextField(30), \"wrap\");\n" +
"grPanel.add(createLabel(\"Goods:\"));\n" +
"grPanel.add(createCheck(\"Dangerous\"), \"wrap\");\n" +
"grPanel.add(createLabel(\"Shipper:\"));\n" +
"grPanel.add(createTextField(30), \"wrap\");\n" +
"grPanel.add(createLabel(\"Customer:\"));\n" +
"grPanel.add(createTextField(\"\"), \"split 2,growx\");\n" +
"grPanel.add(createButton(\"...\"), \"width 50px:pref,wrap\");\n" +
"grPanel.add(createLabel(\"Port of Loading:\"));\n" +
"grPanel.add(createTextField(30), \"wrap\");\n" +
"grPanel.add(createLabel(\"Destination:\"));\n" +
"grPanel.add(createTextField(30), \"wrap\");\n" +
"\n" +
"tabbedPane.addTab(\"Ungrouped\", ugPanel);\n" +
"tabbedPane.addTab(\"Grouped (Components)\", gPanel);\n" +
"tabbedPane.addTab(\"Grouped (Columns)\", gcPanel);\n" +
"tabbedPane.addTab(\"Ungrouped Rows\", ugrPanel);\n" +
"tabbedPane.addTab(\"Grouped Rows\", grPanel);");
return tabbedPane;
}
public JComponent createSpan()
{
JTabbedPane tabbedPane = new JTabbedPane();
// Horizontal span
MigLayout colLM = new MigLayout("nocache",
"[fill][25%!,fill][105lp!,fill][100px!,fill]",
"[]15[][]");
JPanel colPanel = createTabPanel(colLM);
colPanel.add(createTextField("Col1 [ ]"));
colPanel.add(createTextField("Col2 [25%!]"));
colPanel.add(createTextField("Col3 [105lp!]"));
colPanel.add(createTextField("Col4 [100px!]"), "wrap");
colPanel.add(createLabel("Full Name:"));
colPanel.add(createTextField("span, growx", 40), "span,growx");
colPanel.add(createLabel("Phone:"));
colPanel.add(createTextField(5), "span 3, split 5");
colPanel.add(createTextField(7));
colPanel.add(createTextField(7));
colPanel.add(createTextField(9));
colPanel.add(createLabel("(span 3, split 4)"), "wrap");
colPanel.add(createLabel("Zip/City:"));
colPanel.add(createTextField(5));
colPanel.add(createTextField("span 2, growx", 5), "span 2,growx");
// Vertical span
MigLayout rowLM = new MigLayout("wrap",
"[225lp]para[225lp]",
"[]3[]unrel[]3[]unrel[]3[]");
JPanel rowPanel = createTabPanel(rowLM);
rowPanel.add(createLabel("Name"));
rowPanel.add(createLabel("Notes"));
rowPanel.add(createTextField("growx"), "growx");
rowPanel.add(createTextArea("spany,grow", 5, 20), "spany,grow");
rowPanel.add(createLabel("Phone"));
rowPanel.add(createTextField("growx"), "growx");
rowPanel.add(createLabel("Fax"));
rowPanel.add(createTextField("growx"), "growx");
tabbedPane.addTab("Column Span/Split", colPanel);
tabbedPane.addTab("Row Span", rowPanel);
// Disregard. Just forgetting the source code text close to the source code.
setSource("\t\tJTabbedPane tabbedPane = new JTabbedPane();\n" +
"\n" +
"\t\t// Horizontal span\n" +
"\t\tMigLayout colLM = new MigLayout(\"\",\n" +
"\t\t \"[fill][25%!,fill][105lp!,fill][100px!,fill]\",\n" +
"\t\t \"[]15[][]\");\n" +
"\t\tJPanel colPanel = createTabPanel(colLM);\n" +
"\t\tcolPanel.add(createTextField(\"Col1 [ ]\"));\n" +
"\t\tcolPanel.add(createTextField(\"Col2 [25%!]\"));\n" +
"\t\tcolPanel.add(createTextField(\"Col3 [105lp!]\"));\n" +
"\t\tcolPanel.add(createTextField(\"Col4 [100px!]\"), \"wrap\");\n" +
"\n" +
"\t\tcolPanel.add(createLabel(\"Full Name:\"));\n" +
"\t\tcolPanel.add(createTextField(\"span, growx\", 40), \"span,growx\");\n" +
"\n" +
"\t\tcolPanel.add(createLabel(\"Phone:\"));\n" +
"\t\tcolPanel.add(createTextField(5), \"span 3, split 5\");\n" +
"\t\tcolPanel.add(createTextField(7));\n" +
"\t\tcolPanel.add(createTextField(7));\n" +
"\t\tcolPanel.add(createTextField(9));\n" +
"\t\tcolPanel.add(createLabel(\"(span 3, split 4)\"), \"wrap\");\n" +
"\n" +
"\t\tcolPanel.add(createLabel(\"Zip/City:\"));\n" +
"\t\tcolPanel.add(createTextField(5));\n" +
"\t\tcolPanel.add(createTextField(\"span 2, growx\", 5), \"span 2,growx\");\n" +
"\n" +
"\t\t// Vertical span\n" +
"\t\tMigLayout rowLM = new MigLayout(\"wrap\",\n" +
"\t\t \"[225lp]para[225lp]\",\n" +
"\t\t \"[]3[]unrel[]3[]unrel[]3[]\");\n" +
"\t\tJPanel rowPanel = createTabPanel(rowLM);\n" +
"\t\trowPanel.add(createLabel(\"Name\"));\n" +
"\t\trowPanel.add(createLabel(\"Notes\"));\n" +
"\t\trowPanel.add(createTextField(\"growx\"), \"growx\");\n" +
"\t\trowPanel.add(createTextArea(\"spany,grow\", 5, 20), \"spany,grow\");\n" +
"\t\trowPanel.add(createLabel(\"Phone\"));\n" +
"\t\trowPanel.add(createTextField(\"growx\"), \"growx\");\n" +
"\t\trowPanel.add(createLabel(\"Fax\"));\n" +
"\t\trowPanel.add(createTextField(\"growx\"), \"growx\");\n" +
"\n" +
"\t\ttabbedPane.addTab(\"Column Span/Split\", colPanel);\n" +
"\t\ttabbedPane.addTab(\"Row Span\", rowPanel);");
return tabbedPane;
}
public JComponent createGrowing()
{
JTabbedPane tabbedPane = new JTabbedPane();
// All tab
MigLayout allLM = new MigLayout("",
"[pref!][grow,fill]",
"[]15[]");
JPanel allTab = createTabPanel(allLM);
allTab.add(createLabel("Fixed"));
allTab.add(createLabel("Gets all extra space"), "wrap");
allTab.add(createTextField(5));
allTab.add(createTextField(5));
// Half tab
MigLayout halfLM = new MigLayout("",
"[pref!][grow,fill]",
"[]15[]");
JPanel halfTab = createTabPanel(halfLM);
halfTab.add(createLabel("Fixed"));
halfTab.add(createLabel("Gets half of extra space"));
halfTab.add(createLabel("Gets half of extra space"), "wrap");
halfTab.add(createTextField(5));
halfTab.add(createTextField(5));
halfTab.add(createTextField(5));
// Percent 1 tab
MigLayout p1LM = new MigLayout("",
"[pref!][0:0,grow 25,fill][0:0,grow 75,fill]",
"[]15[]");
JPanel p1Tab = createTabPanel(p1LM);
p1Tab.add(createLabel("Fixed"));
p1Tab.add(createLabel("Gets 25% of extra space"), "");
p1Tab.add(createLabel("Gets 75% of extra space"), "wrap");
p1Tab.add(createTextField(5));
p1Tab.add(createTextField(5));
p1Tab.add(createTextField(5));
// Percent 2 tab
MigLayout p2LM = new MigLayout("",
"[0:0,grow 33,fill][0:0,grow 67,fill]",
"[]15[]");
JPanel p2Tab = createTabPanel(p2LM);
p2Tab.add(createLabel("Gets 33% of extra space"), "");
p2Tab.add(createLabel("Gets 67% of extra space"), "wrap");
p2Tab.add(createTextField(5));
p2Tab.add(createTextField(5));
// Vertical 1 tab
MigLayout v1LM = new MigLayout("flowy",
"[]15[]",
"[][c,pref!][c,grow 25,fill][c,grow 75,fill]");
JPanel v1Tab = createTabPanel(v1LM);
v1Tab.add(createLabel("Fixed"), "skip");
v1Tab.add(createLabel("Gets 25% of extra space"));
v1Tab.add(createLabel("Gets 75% of extra space"), "wrap");
v1Tab.add(createLabel("new JTextArea(4, 30)"));
v1Tab.add(createTextAreaScroll("", 4, 30, false));
v1Tab.add(createTextAreaScroll("", 4, 30, false));
v1Tab.add(createTextAreaScroll("", 4, 30, false));
// Vertical 2 tab
MigLayout v2LM = new MigLayout("flowy",
"[]15[]",
"[][c,grow 33,fill][c,grow 67,fill]");
JPanel v2Tab = createTabPanel(v2LM);
v2Tab.add(createLabel("Gets 33% of extra space"), "skip");
v2Tab.add(createLabel("Gets 67% of extra space"), "wrap");
v2Tab.add(createLabel("new JTextArea(4, 30)"));
v2Tab.add(createTextAreaScroll("", 4, 30, false));
v2Tab.add(createTextAreaScroll("", 4, 30, false));
tabbedPane.addTab("All", allTab);
tabbedPane.addTab("Half", halfTab);
tabbedPane.addTab("Percent 1", p1Tab);
tabbedPane.addTab("Percent 2", p2Tab);
tabbedPane.addTab("Vertical 1", v1Tab);
tabbedPane.addTab("Vertical 2", v2Tab);
// Disregard. Just forgetting the source code text close to the source code.
setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" +
"\n" +
"// All tab\n" +
"MigLayout allLM = new MigLayout(\"\",\n" +
" \"[pref!][grow,fill]\",\n" +
" \"[]15[]\");\n" +
"JPanel allTab = createTabPanel(allLM);\n" +
"allTab.add(createLabel(\"Fixed\"));\n" +
"allTab.add(createLabel(\"Gets all extra space\"), \"wrap\");\n" +
"allTab.add(createTextField(5));\n" +
"allTab.add(createTextField(5));\n" +
"\n" +
"// Half tab\n" +
"MigLayout halfLM = new MigLayout(\"\",\n" +
" \"[pref!][grow,fill]\",\n" +
" \"[]15[]\");\n" +
"JPanel halfTab = createTabPanel(halfLM);\n" +
"halfTab.add(createLabel(\"Fixed\"));\n" +
"halfTab.add(createLabel(\"Gets half of extra space\"));\n" +
"halfTab.add(createLabel(\"Gets half of extra space\"), \"wrap\");\n" +
"halfTab.add(createTextField(5));\n" +
"halfTab.add(createTextField(5));\n" +
"halfTab.add(createTextField(5));\n" +
"\n" +
"// Percent 1 tab\n" +
"MigLayout p1LM = new MigLayout(\"\",\n" +
" \"[pref!][0:0,grow 25,fill][0:0,grow 75,fill]\",\n" +
" \"[]15[]\");\n" +
"JPanel p1Tab = createTabPanel(p1LM);\n" +
"p1Tab.add(createLabel(\"Fixed\"));\n" +
"p1Tab.add(createLabel(\"Gets 25% of extra space\"), \"\");\n" +
"p1Tab.add(createLabel(\"Gets 75% of extra space\"), \"wrap\");\n" +
"p1Tab.add(createTextField(5));\n" +
"p1Tab.add(createTextField(5));\n" +
"p1Tab.add(createTextField(5));\n" +
"\n" +
"// Percent 2 tab\n" +
"MigLayout p2LM = new MigLayout(\"\",\n" +
" \"[0:0,grow 33,fill][0:0,grow 67,fill]\",\n" +
" \"[]15[]\");\n" +
"JPanel p2Tab = createTabPanel(p2LM);\n" +
"p2Tab.add(createLabel(\"Gets 33% of extra space\"), \"\");\n" +
"p2Tab.add(createLabel(\"Gets 67% of extra space\"), \"wrap\");\n" +
"p2Tab.add(createTextField(5));\n" +
"p2Tab.add(createTextField(5));\n" +
"\n" +
"// Vertical 1 tab\n" +
"MigLayout v1LM = new MigLayout(\"flowy\",\n" +
" \"[]15[]\",\n" +
" \"[][c,pref!][c,grow 25,fill][c,grow 75,fill]\");\n" +
"JPanel v1Tab = createTabPanel(v1LM);\n" +
"v1Tab.add(createLabel(\"Fixed\"), \"skip\");\n" +
"v1Tab.add(createLabel(\"Gets 25% of extra space\"));\n" +
"v1Tab.add(createLabel(\"Gets 75% of extra space\"), \"wrap\");\n" +
"v1Tab.add(createLabel(\"new JTextArea(4, 30)\"));\n" +
"v1Tab.add(createTextAreaScroll(\"\", 4, 30, false));\n" +
"v1Tab.add(createTextAreaScroll(\"\", 4, 30, false));\n" +
"v1Tab.add(createTextAreaScroll(\"\", 4, 30, false));\n" +
"\n" +
"// Vertical 2 tab\n" +
"MigLayout v2LM = new MigLayout(\"flowy\",\n" +
" \"[]15[]\",\n" +
" \"[][c,grow 33,fill][c,grow 67,fill]\");\n" +
"JPanel v2Tab = createTabPanel(v2LM);\n" +
"v2Tab.add(createLabel(\"Gets 33% of extra space\"), \"skip\");\n" +
"v2Tab.add(createLabel(\"Gets 67% of extra space\"), \"wrap\");\n" +
"v2Tab.add(createLabel(\"new JTextArea(4, 30)\"));\n" +
"v2Tab.add(createTextAreaScroll(\"\", 4, 30, false));\n" +
"v2Tab.add(createTextAreaScroll(\"\", 4, 30, false));\n" +
"\n" +
"tabbedPane.addTab(\"All\", allTab);\n" +
"tabbedPane.addTab(\"Half\", halfTab);\n" +
"tabbedPane.addTab(\"Percent 1\", p1Tab);\n" +
"tabbedPane.addTab(\"Percent 2\", p2Tab);\n" +
"tabbedPane.addTab(\"Vertical 1\", v1Tab);\n" +
"tabbedPane.addTab(\"Vertical 2\", v2Tab);");
return tabbedPane;
}
public JComponent createBasic_Sizes()
{
JTabbedPane tabbedPane = new JTabbedPane();
// Horizontal tab
MigLayout horLM = new MigLayout("",
"[]15[75px]25[min]25[]",
"[]15");
JPanel horTab = createTabPanel(horLM);
horTab.add(createLabel("75px"), "skip");
horTab.add(createLabel("Min"));
horTab.add(createLabel("Pref"), "wrap");
horTab.add(createLabel("new TextField(15)"));
horTab.add(createTextField(15));
horTab.add(createTextField(15));
horTab.add(createTextField(15));
// Vertical tab 1
MigLayout verLM = new MigLayout("flowy,wrap",
"[]15[]",
"[]15[c,45px]15[c,min]15[c,pref]");
JPanel verTab = createTabPanel(verLM);
verTab.add(createLabel("45px"), "skip");
verTab.add(createLabel("Min"));
verTab.add(createLabel("Pref"));
verTab.add(createLabel("new JTextArea(10, 40)"));
verTab.add(createTextArea("", 10, 40));
verTab.add(createTextArea("", 10, 40));
verTab.add(createTextArea("", 10, 40));
// Componentsized/Baseline 2
MigLayout verLM2 = new MigLayout("flowy,wrap",
"[]15[]",
"[]15[baseline]15[baseline]15[baseline]");
JPanel verTab2 = createTabPanel(verLM2);
verTab2.add(createLabel("45px"), "skip");
verTab2.add(createLabel("Min"));
verTab2.add(createLabel("Pref"));
verTab2.add(createLabel("new JTextArea(10, 40)"));
verTab2.add(createTextArea("", 10, 40), "height 45");
verTab2.add(createTextArea("", 10, 40), "height min");
verTab2.add(createTextArea("", 10, 40), "height pref");
tabbedPane.addTab("Horizontal - Column size set", horTab);
tabbedPane.addTab("Vertical - Row sized", verTab);
tabbedPane.addTab("Vertical - Component sized + Baseline", verTab2);
// Disregard. Just forgetting the source code text close to the source code.
setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" +
"\n" +
"// Horizontal tab\n" +
"MigLayout horLM = new MigLayout(\"\",\n" +
" \"[]15[75px]25[min]25[]\",\n" +
" \"[]15\");\n" +
"JPanel horTab = createTabPanel(horLM);\n" +
"horTab.add(createLabel(\"75px\"), \"skip\");\n" +
"horTab.add(createLabel(\"Min\"));\n" +
"horTab.add(createLabel(\"Pref\"), \"wrap\");\n" +
"\n" +
"horTab.add(createLabel(\"new TextField(15)\"));\n" +
"horTab.add(createTextField(15));\n" +
"horTab.add(createTextField(15));\n" +
"horTab.add(createTextField(15));\n" +
"\n" +
"// Vertical tab 1\n" +
"MigLayout verLM = new MigLayout(\"flowy,wrap\",\n" +
" \"[]15[]\",\n" +
" \"[]15[c,45px]15[c,min]15[c,pref]\");\n" +
"JPanel verTab = createTabPanel(verLM);\n" +
"verTab.add(createLabel(\"45px\"), \"skip\");\n" +
"verTab.add(createLabel(\"Min\"));\n" +
"verTab.add(createLabel(\"Pref\"));\n" +
"\n" +
"verTab.add(createLabel(\"new JTextArea(10, 40)\"));\n" +
"verTab.add(createTextArea(\"\", 10, 40));\n" +
"verTab.add(createTextArea(\"\", 10, 40));\n" +
"verTab.add(createTextArea(\"\", 10, 40));\n" +
"\n" +
"// Componentsized/Baseline 2\n" +
"MigLayout verLM2 = new MigLayout(\"flowy,wrap\",\n" +
" \"[]15[]\",\n" +
" \"[]15[baseline]15[baseline]15[baseline]\");\n" +
"JPanel verTab2 = createTabPanel(verLM2);\n" +
"verTab2.add(createLabel(\"45px\"), \"skip\");\n" +
"verTab2.add(createLabel(\"Min\"));\n" +
"verTab2.add(createLabel(\"Pref\"));\n" +
"\n" +
"verTab2.add(createLabel(\"new JTextArea(10, 40)\"));\n" +
"verTab2.add(createTextArea(\"\", 10, 40), \"height 45\");\n" +
"verTab2.add(createTextArea(\"\", 10, 40), \"height min\");\n" +
"verTab2.add(createTextArea(\"\", 10, 40), \"height pref\");\n" +
"\n" +
"tabbedPane.addTab(\"Horizontal - Column size set\", horTab);\n" +
"tabbedPane.addTab(\"Vertical - Row sized\", verTab);\n" +
"tabbedPane.addTab(\"Vertical - Component sized + Baseline\", verTab2);");
return tabbedPane;
}
public JComponent createAlignments()
{
JTabbedPane tabbedPane = new JTabbedPane();
// Horizontal tab
MigLayout horLM = new MigLayout("wrap",
"[label]15[left]15[center]15[right]15[fill]15[]",
"[]15[]");
String[] horLabels = new String[] {"[label]", "[left]", "[center]", "[right]", "[fill]", "[] (Default)"};
JPanel horTab = createTabPanel(horLM);
String[] horNames = new String[] {"First Name", "Phone Number", "Facsmile", "Email", "Address", "Other"};
for (int c = 0; c < horLabels.length; c++)
horTab.add(createLabel(horLabels[c]));
for (int r = 0; r < horLabels.length; r++) {
for (int c = 0; c < horNames.length; c++)
horTab.add(c == 0 ? createLabel(horNames[r] + ":") : createButton(horNames[r]));
}
// Vertical tab
MigLayout verLM = new MigLayout("wrap,flowy",
"[]unrel[]rel[]",
"[top]15[center]15[bottom]15[fill]15[fill,baseline]15[baseline]15[]");
String[] verLabels = new String[] {"[top]", "[center]", "[bottom]", "[fill]", "[fill,baseline]", "[baseline]", "[] (Default)"};
JPanel verTab = createTabPanel(verLM);
String[] verNames = benchRuns == 0 ? new String[] {"One", "One Two"} : new String[] {"One", "One/Two"};
for (int c = 0; c < verLabels.length; c++)
verTab.add(createLabel(verLabels[c]));
for (int r = 0; r < verNames.length; r++) {
for (int c = 0; c < verLabels.length; c++)
verTab.add(createButton(verNames[r]));
}
for (int c = 0; c < verLabels.length; c++)
verTab.add(createTextField("JTextFied"));
for (int c = 0; c < verLabels.length; c++)
verTab.add(createTextArea("JTextArea", 1, 8));
for (int c = 0; c < verLabels.length; c++)
verTab.add(createTextArea("JTextArea\nwith two lines", 1, 10));
for (int c = 0; c < verLabels.length; c++)
verTab.add(createTextAreaScroll("Scrolling JTextArea\nwith two lines", 1, 15, true));
tabbedPane.addTab("Horizontal", horTab);
tabbedPane.addTab("Vertical", verTab);
// Disregard. Just forgetting the source code text close to the source code.
setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" +
"\n" +
"// Horizontal tab\n" +
"MigLayout horLM = new MigLayout(\"wrap\",\n" +
" \"[left]15[center]15[right]15[fill]15[]\",\n" +
" \"rel[]rel\");\n" +
"\n" +
"String[] horLabels = new String[] {\"[left]\", \"[center]\", \"[right]\", \"[fill]\", \"[] (Default)\"};\n" +
"JPanel horTab = createTabPanel(horLM);\n" +
"String[] horNames = new String[] {\"First Name\", \"Phone Number\", \"Facsmile\", \"Email\", \"Address\"};\n" +
"for (int c = 0; c < horLabels.length; c++)\n" +
"\thorTab.add(createLabel(horLabels[c]));\n" +
"\n" +
"for (int r = 0; r < horLabels.length; r++) {\n" +
"\tfor (int c = 0; c < horNames.length; c++)\n" +
"\t\thorTab.add(createButton(horNames[r]));\n" +
"}\n" +
"\n" +
"// Vertical tab\n" +
"MigLayout verLM = new MigLayout(\"wrap,flowy\",\n" +
" \"[]unrel[]rel[]\",\n" +
" \"[top]15[center]15[bottom]15[fill]15[fill,baseline]15[baseline]15[]\");\n" +
"\n" +
"String[] verLabels = new String[] {\"[top]\", \"[center]\", \"[bottom]\", \"[fill]\", \"[fill,baseline]\", \"[baseline]\", \"[] (Default)\"};\n" +
"JPanel verTab = createTabPanel(verLM);\n" +
"\n" +
"String[] verNames = new String[] {\"One\", \"One Two\"};\n" +
"for (int c = 0; c < verLabels.length; c++)\n" +
"\tverTab.add(createLabel(verLabels[c]));\n" +
"\n" +
"for (int r = 0; r < verNames.length; r++) {\n" +
"\tfor (int c = 0; c < verLabels.length; c++)\n" +
"\t\tverTab.add(createButton(verNames[r]));\n" +
"}\n" +
"\n" +
"for (int c = 0; c < verLabels.length; c++)\n" +
"\tverTab.add(createTextField(\"JTextFied\"));\n" +
"\n" +
"for (int c = 0; c < verLabels.length; c++)\n" +
"\tverTab.add(createTextArea(\"JTextArea\", 1, 8));\n" +
"\n" +
"for (int c = 0; c < verLabels.length; c++)\n" +
"\tverTab.add(createTextArea(\"JTextArea\\nwith two lines\", 1, 10));\n" +
"\n" +
"for (int c = 0; c < verLabels.length; c++)\n" +
"\tverTab.add(createTextAreaScroll(\"Scrolling JTextArea\\nwith two lines\", 1, 15, true));\n" +
"\n" +
"tabbedPane.addTab(\"Horizontal\", horTab);\n" +
"tabbedPane.addTab(\"Vertical\", verTab);");
return tabbedPane;
}
public JComponent createQuick_Start()
{
JTabbedPane tabbedPane = new JTabbedPane();
JPanel p = createTabPanel(new MigLayout("inset 20"));
addSeparator(p, "General");
p.add(createLabel("Company"), "gap para");
p.add(createTextField(""), "span, growx");
p.add(createLabel("Contact"), "gap para");
p.add(createTextField(""), "span, growx, wrap para");
addSeparator(p, "Propeller");
p.add(createLabel("PTI/kW"), "gap para");
p.add(createTextField(10));
p.add(createLabel("Power/kW"),"gap para");
p.add(createTextField(10), "wrap");
p.add(createLabel("R/mm"), "gap para");
p.add(createTextField(10));
p.add(createLabel("D/mm"), "gap para");
p.add(createTextField(10));
tabbedPane.addTab("Quick Start", p);
// Disregard. Just forgetting the source code text close to the source code.
setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" +
"\n" +
"JPanel p = createTabPanel(new MigLayout());\n" +
"\n" +
"addSeparator(p, \"General\");\n" +
"\n" +
"p.add(createLabel(\"Company\"), \"gap para\");\n" +
"p.add(createTextField(\"\"), \"span, growx, wrap\");\n" +
"p.add(createLabel(\"Contact\"), \"gap para\");\n" +
"p.add(createTextField(\"\"), \"span, growx, wrap para\");\n" +
"\n" +
"addSeparator(p, \"Propeller\");\n" +
"\n" +
"p.add(createLabel(\"PTI/kW\"), \"gap para\");\n" +
"p.add(createTextField(10));\n" +
"p.add(createLabel(\"Power/kW\"),\"gap para\");\n" +
"p.add(createTextField(10), \"wrap\");\n" +
"p.add(createLabel(\"R/mm\"), \"gap para\");\n" +
"p.add(createTextField(10));\n" +
"p.add(createLabel(\"D/mm\"), \"gap para\");\n" +
"p.add(createTextField(10));\n" +
"\n" +
"tabbedPane.addTab(\"Quick Start\", p);");
return tabbedPane;
}
public JComponent createGrow_Shrink()
{
JTabbedPane tabbedPane = new JTabbedPane();
// shrink tab
MigLayout slm = new MigLayout("nogrid");
JPanel sPanel = createTabPanel(slm);
JScrollPane sDescrText = createTextAreaScroll("Use the slider to see how the components shrink depending on the constraints set on them.\n\n'shp' means Shrink Priority. " +
"Lower values will be shrunk before higer ones and the default value is 100.\n\n'shrink' means Shrink Weight. " +
"Lower values relative to other's means they will shrink less when space is scarse. " +
"Shrink Weight is only relative to components with the same Shrink Priority. Default Shrink Weight is 100.\n\n" +
"The component's minimum size will always be honored.", 0, 0, true);
sDescrText.setOpaque(OPAQUE);
sDescrText.setBorder(new EmptyBorder(10, 10, 10, 10));
((JTextArea) sDescrText.getViewport().getView()).setOpaque(OPAQUE);
sDescrText.getViewport().setOpaque(OPAQUE);
JSplitPane sSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, sPanel, sDescrText);
sSplitPane.setOpaque(OPAQUE);
sSplitPane.setBorder(null);
sPanel.add(createTextField("shp 110", 12), "shp 110");
sPanel.add(createTextField("Default (100)", 12), "");
sPanel.add(createTextField("shp 90", 12), "shp 90");
sPanel.add(createTextField("shrink 25", 20), "newline,shrink 25");
sPanel.add(createTextField("shrink 75", 20), "shrink 75");
sPanel.add(createTextField("Default", 20), "newline");
sPanel.add(createTextField("Default", 20), "");
sPanel.add(createTextField("shrink 0", 40), "newline,shrink 0");
sPanel.add(createTextField("shp 110", 12), "newline,shp 110");
sPanel.add(createTextField("shp 100,shrink 25", 12), "shp 100,shrink 25");
sPanel.add(createTextField("shp 100,shrink 75", 12), "shp 100,shrink 75");
tabbedPane.addTab("Shrink", sSplitPane);
// Grow tab
MigLayout glm = new MigLayout("nogrid", "[grow]", "");
JPanel gPanel = createTabPanel(glm);
JScrollPane gDescrText = createTextAreaScroll("'gp' means Grow Priority. " +
"Higher values will be grown before lower ones and the default value is 100.\n\n'grow' means Grow Weight. " +
"Higher values relative to other's means they will grow more when space is up for takes. " +
"Grow Weight is only relative to components with the same Grow Priority. Default Grow Weight is 0 which means " +
"components will normally not grow. \n\nNote that the buttons in the first and last row have max width set to 170 to " +
"emphasize Grow Priority.\n\nThe component's maximum size will always be honored.", 0, 0, true);
gDescrText.setOpaque(OPAQUE);
gDescrText.setBorder(new EmptyBorder(10, 10, 10, 10));
((JTextArea) gDescrText.getViewport().getView()).setOpaque(OPAQUE);
gDescrText.getViewport().setOpaque(OPAQUE);
JSplitPane gSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, gPanel, gDescrText);
gSplitPane.setOpaque(OPAQUE);
gSplitPane.setBorder(null);
gPanel.add(createButton("gp 110,grow"), "gp 110,grow,wmax 170");
gPanel.add(createButton("Default (100),grow"), "grow,wmax 170");
gPanel.add(createButton("gp 90,grow"), "gp 90,grow,wmax 170");
gPanel.add(createButton("Default Button"), "newline");
gPanel.add(createButton("growx"), "newline,growx,wrap");
gPanel.add(createButton("gp 110,grow"), "gp 110,grow,wmax 170");
gPanel.add(createButton("gp 100,grow 25"), "gp 100,grow 25,wmax 170");
gPanel.add(createButton("gp 100,grow 75"), "gp 100,grow 75,wmax 170");
tabbedPane.addTab("Grow", gSplitPane);
// Disregard. Just forgetting the source code text close to the source code.
setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" +
"\n" +
"// shrink tab\n" +
"MigLayout slm = new MigLayout(\"nogrid\");\n" +
"JPanel sPanel = createTabPanel(slm);\n" +
"\n" +
"JScrollPane sDescrText = createTextAreaScroll(\"Use the slider to see how the components shrink depending on the constraints set on them.\\n\\n'shp' means Shrink Priority. \" +\n" +
" \"Lower values will be shrunk before higer ones and the default value is 100.\\n\\n'shrink' means Shrink Weight. \" +\n" +
" \"Lower values relative to other's means they will shrink less when space is scarse. \" +\n" +
" \"Shrink Weight is only relative to components with the same Shrink Priority. Default Shrink Weight is 100.\\n\\n\" +\n" +
" \"The component's minimum size will always be honored.\", 0, 0, true);\n" +
"\n" +
"sDescrText.setOpaque(OPAQUE);\n" +
"sDescrText.setBorder(new EmptyBorder(10, 10, 10, 10));\n" +
"((JTextArea) sDescrText.getViewport().getView()).setOpaque(OPAQUE);\n" +
"sDescrText.getViewport().setOpaque(OPAQUE);\n" +
"\n" +
"JSplitPane sSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, sPanel, sDescrText);\n" +
"sSplitPane.setOpaque(OPAQUE);\n" +
"sSplitPane.setBorder(null);\n" +
"\n" +
"sPanel.add(createTextField(\"shp 110\", 12), \"shp 110\");\n" +
"sPanel.add(createTextField(\"Default (100)\", 12), \"\");\n" +
"sPanel.add(createTextField(\"shp 90\", 12), \"shp 90\");\n" +
"\n" +
"sPanel.add(createTextField(\"shrink 25\", 20), \"newline,shrink 25\");\n" +
"sPanel.add(createTextField(\"shrink 75\", 20), \"shrink 75\");\n" +
"\n" +
"sPanel.add(createTextField(\"Default\", 20), \"newline\");\n" +
"sPanel.add(createTextField(\"Default\", 20), \"\");\n" +
"\n" +
"sPanel.add(createTextField(\"shrink 0\", 40), \"newline,shrink 0\");\n" +
"\n" +
"sPanel.add(createTextField(\"shp 110\", 12), \"newline,shp 110\");\n" +
"sPanel.add(createTextField(\"shp 100,shrink 25\", 12), \"shp 100,shrink 25\");\n" +
"sPanel.add(createTextField(\"shp 100,shrink 75\", 12), \"shp 100,shrink 75\");\n" +
"tabbedPane.addTab(\"Shrink\", sSplitPane);\n" +
"\n" +
"// Grow tab\n" +
"MigLayout glm = new MigLayout(\"nogrid\", \"[grow]\", \"\");\n" +
"JPanel gPanel = createTabPanel(glm);\n" +
"\n" +
"JScrollPane gDescrText = createTextAreaScroll(\"'gp' means Grow Priority. \" +\n" +
" \"Higher values will be grown before lower ones and the default value is 100.\\n\\n'grow' means Grow Weight. \" +\n" +
" \"Higher values relative to other's means they will grow more when space is up for takes. \" +\n" +
" \"Grow Weight is only relative to components with the same Grow Priority. Default Grow Weight is 0 which means \" +\n" +
" \"components will normally not grow. \\n\\nNote that the buttons in the first and last row have max width set to 170 to \" +\n" +
" \"emphasize Grow Priority.\\n\\nThe component's maximum size will always be honored.\", 0, 0, true);\n" +
"\n" +
"gDescrText.setOpaque(OPAQUE);\n" +
"gDescrText.setBorder(new EmptyBorder(10, 10, 10, 10));\n" +
"((JTextArea) gDescrText.getViewport().getView()).setOpaque(OPAQUE);\n" +
"gDescrText.getViewport().setOpaque(OPAQUE);\n" +
"\n" +
"JSplitPane gSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, gPanel, gDescrText);\n" +
"gSplitPane.setOpaque(OPAQUE);\n" +
"gSplitPane.setBorder(null);\n" +
"\n" +
"gPanel.add(createButton(\"gp 110,grow\"), \"gp 110,grow,wmax 170\");\n" +
"gPanel.add(createButton(\"Default (100),grow\"), \"grow,wmax 170\");\n" +
"gPanel.add(createButton(\"gp 90,grow\"), \"gp 90,grow,wmax 170\");\n" +
"\n" +
"gPanel.add(createButton(\"Default Button\"), \"newline\");\n" +
"\n" +
"gPanel.add(createButton(\"growx\"), \"newline,growx,wrap\");\n" +
"\n" +
"gPanel.add(createButton(\"gp 110,grow\"), \"gp 110,grow,wmax 170\");\n" +
"gPanel.add(createButton(\"gp 100,grow 25\"), \"gp 100,grow 25,wmax 170\");\n" +
"gPanel.add(createButton(\"gp 100,grow 75\"), \"gp 100,grow 75,wmax 170\");\n" +
"tabbedPane.addTab(\"Grow\", gSplitPane);");
return tabbedPane;
}
public JComponent createPlainApi()
{
JTabbedPane tabbedPane = new JTabbedPane();
MigLayout lm = new MigLayout(new LC(), null, null);
JPanel panel = createTabPanel(lm);
addSeparator(panel, "Manufacturer");
panel.add(createLabel("Company"));
panel.add(createTextField(""), "span,growx");
panel.add(createLabel("Contact"));
panel.add(createTextField(""), "span,growx");
panel.add(createLabel("Order No"));
panel.add(createTextField(15), "wrap");
addSeparator(panel, "Inspector");
panel.add(createLabel("Name"));
panel.add(createTextField(""), "span,growx");
panel.add(createLabel("Reference No"));
panel.add(createTextField(""), "wrap");
panel.add(createLabel("Status"));
panel.add(createCombo(new String[] {"In Progress", "Finnished", "Released"}), "wrap");
addSeparator(panel, "Ship");
panel.add(createLabel("Shipyard"));
panel.add(createTextField(""), "span,growx");
panel.add(createLabel("Register No"));
panel.add(createTextField(""));
panel.add(createLabel("Hull No"), "right");
panel.add(createTextField(15), "wrap");
panel.add(createLabel("Project StructureType"));
panel.add(createCombo(new String[] {"New Building", "Convention", "Repair"}));
tabbedPane.addTab("Plain", panel);
return tabbedPane;
}
// **********************************************************
// * Helper Methods
// **********************************************************
private final ToolTipListener toolTipListener = new ToolTipListener();
private final ConstraintListener constraintListener = new ConstraintListener();
private JLabel createLabel(String text)
{
return createLabel(text, SwingConstants.LEADING);
}
private JLabel createLabel(String text, int align)
{
final JLabel b = new JLabel(text, align);
configureActiveComponet(b);
return b;
}
public JComboBox createCombo(String[] items)
{
JComboBox combo = new JComboBox(items);
if (PlatformDefaults.getCurrentPlatform() == PlatformDefaults.MAC_OSX)
combo.setOpaque(false);
return combo;
}
private JTextField createTextField(int cols)
{
return createTextField("", cols);
}
private JTextField createTextField(String text)
{
return createTextField(text, 0);
}
private JTextField createTextField(String text, int cols)
{
final JTextField b = new JTextField(text, cols);
configureActiveComponet(b);
return b;
}
private static final Font BUTT_FONT = new Font("monospaced", Font.PLAIN, 12);
private JButton createButton()
{
return createButton("");
}
private JButton createButton(String text)
{
return createButton(text, false);
}
private JButton createButton(String text, boolean bold)
{
JButton b = new JButton(text) {
public void addNotify()
{
super.addNotify();
if (benchRuns == 0) { // Since this does not exist in the SWT version
if (getText().length() == 0) {
String lText = (String) ((MigLayout) getParent().getLayout()).getComponentConstraints(this);
setText(lText != null && lText.length() > 0 ? lText : "");
}
} else {
setText("Benchmark Version");
}
}
};
if (bold)
b.setFont(b.getFont().deriveFont(Font.BOLD));
configureActiveComponet(b);
b.setOpaque(buttonOpaque); // Or window's buttons will have strange border
b.setContentAreaFilled(contentAreaFilled);
return b;
}
private JToggleButton createToggleButton(String text)
{
JToggleButton b = new JToggleButton(text);
// configureActiveComponet(b);
b.setOpaque(buttonOpaque); // Or window's buttons will have strange border
return b;
}
private JCheckBox createCheck(String text)
{
JCheckBox b = new JCheckBox(text);
configureActiveComponet(b);
b.setOpaque(OPAQUE); // Or window's checkboxes will have strange border
return b;
}
private JPanel createTabPanel(LayoutManager lm)
{
JPanel panel = new JPanel(lm);
configureActiveComponet(panel);
panel.setOpaque(OPAQUE);
return panel;
}
private JComponent createPanel()
{
return createPanel("");
}
private JComponent createPanel(String s)
{
JLabel panel = new JLabel(s, SwingConstants.CENTER) {
public void addNotify()
{
super.addNotify();
if (benchRuns == 0) { // Since this does not exist in the SWT version
if (getText().length() == 0) {
String lText = (String) ((MigLayout) getParent().getLayout()).getComponentConstraints(this);
setText(lText != null && lText.length() > 0 ? lText : "");
}
}
}
};
panel.setBorder(new EtchedBorder());
panel.setOpaque(true);
configureActiveComponet(panel);
return panel;
}
private JTextArea createTextArea(String text, int rows, int cols)
{
JTextArea ta = new JTextArea(text, rows, cols);
ta.setBorder(UIManager.getBorder("TextField.border"));
ta.setFont(UIManager.getFont("TextField.font"));
ta.setWrapStyleWord(true);
ta.setLineWrap(true);
configureActiveComponet(ta);
return ta;
}
private JScrollPane createTextAreaScroll(String text, int rows, int cols, boolean hasVerScroll)
{
JTextArea ta = new JTextArea(text, rows, cols);
ta.setFont(UIManager.getFont("TextField.font"));
ta.setWrapStyleWord(true);
ta.setLineWrap(true);
JScrollPane scroll = new JScrollPane(
ta,
hasVerScroll ? ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED : ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
return scroll;
}
private JComponent configureActiveComponet(JComponent c)
{
if (benchRuns == 0) {
c.addMouseMotionListener(toolTipListener);
c.addMouseListener(constraintListener);
}
return c;
}
static final Color LABEL_COLOR = new Color(0, 70, 213);
private void addSeparator(JPanel panel, String text)
{
JLabel l = createLabel(text);
l.setForeground(LABEL_COLOR);
panel.add(l, "gapbottom 1, span, split 2, aligny center");
panel.add(configureActiveComponet(new JSeparator()), "gapleft rel, growx");
}
private class ConstraintListener extends MouseAdapter
{
public void mousePressed(MouseEvent e)
{
if (e.isPopupTrigger())
react(e);
}
public void mouseReleased(MouseEvent e)
{
if (e.isPopupTrigger())
react(e);
}
public void react(MouseEvent e)
{
JComponent c = (JComponent) e.getSource();
LayoutManager lm = c.getParent().getLayout();
if (lm instanceof MigLayout == false)
lm = c.getLayout();
if (lm instanceof MigLayout) {
MigLayout layout = (MigLayout) lm;
boolean isComp = layout.isManagingComponent(c);
Object compConstr = isComp ? layout.getComponentConstraints(c) : null;
if (isComp && compConstr == null)
compConstr = "";
Object rowsConstr = isComp ? null : layout.getRowConstraints();
Object colsConstr = isComp ? null : layout.getColumnConstraints();
Object layoutConstr = isComp ? null : layout.getLayoutConstraints();
ConstraintsDialog cDlg = new ConstraintsDialog(SwingDemo.this,
layoutConstr instanceof LC ? IDEUtil.getConstraintString((LC) layoutConstr, false) : (String) layoutConstr,
rowsConstr instanceof AC ? IDEUtil.getConstraintString((AC) rowsConstr, false, false) : (String) rowsConstr,
colsConstr instanceof AC ? IDEUtil.getConstraintString((AC) colsConstr, false, false) : (String) colsConstr,
compConstr instanceof CC ? IDEUtil.getConstraintString((CC) compConstr, false) : (String) compConstr);
cDlg.pack();
cDlg.setLocationRelativeTo(c);
if (cDlg.showDialog()) {
try {
if (isComp) {
String constrStr = cDlg.componentConstrTF.getText().trim();
layout.setComponentConstraints(c, constrStr);
if (c instanceof JButton) {
c.setFont(BUTT_FONT);
((JButton) c).setText(constrStr.length() == 0 ? "" : constrStr);
}
} else {
layout.setLayoutConstraints(cDlg.layoutConstrTF.getText());
layout.setRowConstraints(cDlg.rowsConstrTF.getText());
layout.setColumnConstraints(cDlg.colsConstrTF.getText());
}
} catch(Exception ex) {
StringWriter sw = new StringWriter();
ex.printStackTrace(new PrintWriter(sw));
JOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(c), sw.toString(), "Error parsing Constraint!", JOptionPane.ERROR_MESSAGE);
return;
}
c.invalidate();
c.getParent().validate();
}
}
}
}
private static class ToolTipListener extends MouseMotionAdapter
{
public void mouseMoved(MouseEvent e)
{
JComponent c = (JComponent) e.getSource();
LayoutManager lm = c.getParent().getLayout();
if (lm instanceof MigLayout) {
Object constr = ((MigLayout) lm).getComponentConstraints(c);
if (constr instanceof String)
c.setToolTipText((constr != null ? ("\"" + constr + "\"") : "null"));
}
}
}
private static class ConstraintsDialog extends JDialog implements ActionListener, KeyEventDispatcher
{
private static final Color ERROR_COLOR = new Color(255, 180, 180);
private final JPanel mainPanel = new JPanel(new MigLayout("fillx,flowy,ins dialog",
"[fill]",
"2[]2"));
final JTextField layoutConstrTF;
final JTextField rowsConstrTF;
final JTextField colsConstrTF;
final JTextField componentConstrTF;
private final JButton okButt = new JButton("OK");
private final JButton cancelButt = new JButton("Cancel");
private boolean okPressed = false;
public ConstraintsDialog(Frame owner, String layoutConstr, String rowsConstr, String colsConstr, String compConstr)
{
super(owner, (compConstr != null ? "Edit Component Constraints" : "Edit Container Constraints"), true);
layoutConstrTF = createConstraintField(layoutConstr);
rowsConstrTF = createConstraintField(rowsConstr);
colsConstrTF = createConstraintField(colsConstr);
componentConstrTF = createConstraintField(compConstr);
if (componentConstrTF != null) {
mainPanel.add(new JLabel("Component Constraints"));
mainPanel.add(componentConstrTF);
}
if (layoutConstrTF != null) {
mainPanel.add(new JLabel("Layout Constraints"));
mainPanel.add(layoutConstrTF);
}
if (colsConstrTF != null) {
mainPanel.add(new JLabel("Column Constraints"), "gaptop unrel");
mainPanel.add(colsConstrTF);
}
if (rowsConstrTF != null) {
mainPanel.add(new JLabel("Row Constraints"), "gaptop unrel");
mainPanel.add(rowsConstrTF);
}
mainPanel.add(okButt, "tag ok,split,flowx,gaptop 15");
mainPanel.add(cancelButt, "tag cancel,gaptop 15");
setContentPane(mainPanel);
okButt.addActionListener(this);
cancelButt.addActionListener(this);
}
public void addNotify()
{
super.addNotify();
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(this);
}
public void removeNotify()
{
KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(this);
super.removeNotify();
}
public boolean dispatchKeyEvent(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_ESCAPE)
dispose();
return false;
}
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == okButt)
okPressed = true;
dispose();
}
private JTextField createConstraintField(String text)
{
if (text == null)
return null;
final JTextField tf = new JTextField(text, 50);
tf.setFont(new Font("monospaced", Font.PLAIN, 12));
tf.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
okButt.doClick();
return;
}
javax.swing.Timer timer = new Timer(50, new ActionListener() {
public void actionPerformed(ActionEvent e)
{
String constr = tf.getText();
try {
if (tf == layoutConstrTF) {
ConstraintParser.parseLayoutConstraint(constr);
} else if (tf == rowsConstrTF) {
ConstraintParser.parseRowConstraints(constr);
} else if (tf == colsConstrTF) {
ConstraintParser.parseColumnConstraints(constr);
} else if (tf == componentConstrTF) {
ConstraintParser.parseComponentConstraint(constr);
}
tf.setBackground(Color.WHITE);
okButt.setEnabled(true);
} catch(Exception ex) {
tf.setBackground(ERROR_COLOR);
okButt.setEnabled(false);
}
}
});
timer.setRepeats(false);
timer.start();
}
});
return tf;
}
private boolean showDialog()
{
setVisible(true);
return okPressed;
}
}
}miglayout-5.1/demo/src/main/java/net/miginfocom/demo/SwtDemo.java000077500000000000000000002510771324101563200250530ustar00rootroot00000000000000package net.miginfocom.demo;
import net.miginfocom.layout.*;
import net.miginfocom.swt.MigLayout;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.*;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Random;
/*
* License (BSD):
* ==============
*
* Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
* 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 the MiG InfoCom AB nor 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.
*
* @version 1.0
* @author Mikael Grev, MiG InfoCom AB
* Date: 2006-sep-08
*/
public class SwtDemo
{
public static final int SELECTED_INDEX = 0;
private static final String[][] panels = new String[][] {
// {"BugTestApp", "BugTestApp, Disregard"},
{"Welcome", "\n\n \"MigLayout makes complex layouts easy and normal layouts one-liners.\""},
{"Quick Start", "This is an example of how to build a common dialog type. Note that there are no special components, nested panels or absolute references to cell positions. If you look at the source code you will see that the layout code is very simple to understand."},
{"Plain", "A simple example on how simple it is to create normal forms. No builders needed since the whole layout manager works like a builder."},
{"Alignments", "Shows how the alignment of components are specified. At the top/left is the alignment for the column/row. The components have no alignments specified.\n\nNote that baseline alignment will be interpreted as 'center' before JDK 6."},
{"Cell Alignments", "Shows how components are aligned when both column/row alignments and component constraints are specified. At the top/left are the alignment for the column/row and the text on the buttons is the component constraint that will override the column/row alignment if it is an alignment.\n\nNote that baseline alignment will be interpreted as 'center' before JDK 6."},
{"Basic Sizes", "A simple example that shows how to use the column or row min/preferred/max size to set the sizes of the contained components and also an example that shows how to do this directly in the component constraints."},
{"Growing", "A simple example that shows how to use the growx and growy constraint to set the sizes and how they should grow to fit the available size. Both the column/row and the component grow/shrink constraints can be set, but the components will always be confined to the space given by its column/row."},
{"Grow Shrink", "Demonstrates the very flexible grow and shrink constraints that can be set on a component.\nComponents can be divided into grow/shrink groups and also have grow/shrink weight within each of those groups.\n\nBy default " +
"components shrink to their inherent (or specified) minimum size, but they don't grow."},
{"Span", "This example shows the powerful spanning and splitting that can be specified in the component constraints. With spanning any number of cells can be merged with the additional option to split that space for more than one component. This makes layouts very flexible and reduces the number of times you will need nested panels to very few."},
{"Flow Direction", "Shows the different flow directions. Flow direction for the layout specifies if the next cell will be in the x or y dimension. Note that it can be a different flow direction in the slit cell (the middle cell is slit in two). Wrap is set to 3 for all panels."},
{"Grouping", "Sizes for both components and columns/rows can be grouped so they get the same size. For instance buttons in a button bar can be given a size-group so that they will all get " +
"the same minimum and preferred size (the largest within the group). Size-groups can be set for the width, height or both."},
{"Units", "Demonstrates the basic units that are understood by MigLayout. These units can be extended by the user by adding one or more UnitConverter(s)."},
{"Component Sizes", "Minimum, preferred and maximum component sizes can be overridden in the component constraints using any unit type. The format to do this is short and simple to understand. You simply specify the " +
"min, preferred and max sizes with a colon between.\n\nAbove are some examples of this. An exclamation mark means that the value will be used for all sizes."},
{"Bound Sizes", "Shows how to create columns that are stable between tabs using minimum sizes."},
{"Cell Position", "Even though MigLayout has automatic grid flow you can still specify the cell position explicitly. You can even combine absolute (x, y) and flow (skip, wrap and newline) constraints to build your layout."},
{"Orientation", "MigLayout supports not only right-to-left orientation, but also bottom-to-top. You can even set the flow direction so that the flow is vertical instead of horizontal. It will automatically " +
"pick up if right-to-left is to be used depending on the ComponentWrapper, but it can also be manually set for every layout."},
{"Absolute Position", "Demonstrates the option to place any number of components using absolute coordinates. This can be just the position (if min/preferred size) using \"x y p p\" format or" +
"the bounds using the \"x1 y1 x2 y2\" format. Any unit can be used and percent is relative to the parent.\nAbsolute components will not disturb the flow or occupy cells in the grid. " +
"Absolute positioned components will be taken into account when calculating the container's preferred size."},
{"Component Links", "Components can be linked to any side of any other component. It can be a forward, backward or cyclic link references, as long as it is stable and won't continue to change value over many iterations." +
"Links are referencing the ID of another component. The ID can be overridden by the component's constrains or is provided by the ComponentWrapper. For instance it will use the component's 'name' on Swing.\n" +
"Since the links can be combined with any expression (such as 'butt1.x+10' or 'max(button.x, 200)' the links are very customizable."},
{"Docking", "Docking components can be added around the grid. The docked component will get the whole width/height on the docked side by default, however this can be overridden. When all docked components are laid out, whatever space " +
"is left will be available for the normal grid laid out components. Docked components does not in any way affect the flow in the grid.\n\nSince the docking runs in the same code path " +
"as the normal layout code the same properties can be specified for the docking components. You can for instance set the sizes and alignment or link other components to their docked component's bounds."},
{"Button Bars", "Button order is very customizable and are by default different on the supported platforms. E.g. Gaps, button order and minimum button size are properties that are 'per platform'. MigLayout picks up the current platform automatically and adjusts the button order and minimum button size accordingly, all without using a button builder or any other special code construct."},
{"Debug", "Demonstrates the non-intrusive way to get visual debugging aid. There is no need to use a special DebugPanel or anything that will need code changes. The user can simply turn on debug on the layout manager by using the �debug� constraint and it will " +
"continuously repaint the panel with debug information on top. This means you don't have to change your code to debug!"},
{"Layout Showdown", "This is an implementation of the Layout Showdown posted on java.net by John O'Conner. The first tab is a pure implemenetation of the showdown that follows all the rules. The second tab is a slightly fixed version that follows some improved layout guidelines." +
"The source code is for bothe the first and for the fixed version. Note the simplification of the code for the fixed version. Writing better layouts with MiG Layout is reasier that writing bad.\n\nReference: http://weblogs.java.net/blog/joconner/archive/2006/10/more_informatio.html"},
{"API Constraints1", "This dialog shows the constraint API added to v2.0. It works the same way as the string constraints but with chained method calls. See the source code for details."},
{"API Constraints2", "This dialog shows the constraint API added to v2.0. It works the same way as the string constraints but with chained method calls. See the source code for details."},
};
private static int DOUBLE_BUFFER = 0;//SWT.DOUBLE_BUFFERED;
private static int benchRuns = 0;
private static long startupMillis = 0;
private static long timeToShowMillis = 0;
private static long benchRunTime = 0;
private static String benchOutFileName = null;
private static boolean append = false;
private static long lastRunTimeStart = 0;
private static StringBuffer runTimeSB = null;
private static Display display = null;
public static void main(String[] args)
{
startupMillis = System.currentTimeMillis();
if (args.length > 0) {
for (int i = 0; i < args.length; i++) {
String arg = args[i].trim();
if (arg.startsWith("-bench")) {
benchRuns = 10;
try {
if (arg.length() > 6)
benchRuns = Integer.parseInt(arg.substring(6));
} catch (Exception ex) {}
} else if (arg.startsWith("-bout")) {
benchOutFileName = arg.substring(5);
} else if (arg.startsWith("-append")) {
append = true;
} else if (arg.startsWith("-verbose")) {
runTimeSB = new StringBuffer(256);
} else {
System.out.println("Usage: [-bench[#_of_runs]] [-bout[benchmark_results_filename]] [-append]\n" +
" -bench Run demo as benchmark. Run count can be appended. 10 is default.\n" +
" -bout Benchmark results output filename.\n" +
" -append Appends the result to the \"-bout\" file.\n" +
" -verbose Print the times of every run.\n" +
"\nExamples:\n" +
" java -jar swtdemoapp.jar -bench -boutC:/bench.txt -append\n" +
" java -jar swtdemoapp.jar -bench20\n" +
"NOTE! swt-win32-3232.dll must be in the current directory!");
System.exit(0);
}
}
}
if (benchRuns == 0)
LayoutUtil.setDesignTime(null, true);
new SwtDemo();
}
final List pickerList;
final Composite layoutDisplayPanel;
final StyledText descrTextArea;
public SwtDemo()
{
display = new Display();
final Shell shell = new Shell();
shell.setLayout(new MigLayout("wrap", "[]u[grow,fill]", "[grow,fill][pref!]"));
shell.setText("MigLayout SWT Demo v2.5 - MigLayout v" + LayoutUtil.getVersion());
TabFolder layoutPickerTabPane = new TabFolder(shell, DOUBLE_BUFFER);
layoutPickerTabPane.setLayoutData("spany,grow");
pickerList = new List(layoutPickerTabPane, SWT.SINGLE | DOUBLE_BUFFER);
pickerList.setBackground(layoutPickerTabPane.getBackground());
deriveFont(pickerList, SWT.BOLD, -1);
TabItem tab = new TabItem(layoutPickerTabPane, DOUBLE_BUFFER);
tab.setControl(pickerList);
tab.setText("Example Browser");
for (int i = 0; i < panels.length; i++)
pickerList.add(panels[i][0]);
layoutDisplayPanel = new Composite(shell, DOUBLE_BUFFER);
layoutDisplayPanel.setLayout(new MigLayout("fill, insets 0"));
TabFolder descriptionTabPane = new TabFolder(shell, DOUBLE_BUFFER);
descriptionTabPane.setLayoutData("growx,hmin 120,w 500:500");
descrTextArea = createTextArea(descriptionTabPane, "", "", SWT.MULTI | SWT.WRAP);
descrTextArea.setBackground(descriptionTabPane.getBackground());
tab = new TabItem(descriptionTabPane, DOUBLE_BUFFER);
tab.setControl(descrTextArea);
tab.setText("Description");
pickerList.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
dispatchSelection();
}
});
shell.setSize(900, 650);
shell.open();
shell.layout();
if (benchRuns > 0) {
doBenchmark();
} else {
pickerList.select(SELECTED_INDEX);
dispatchSelection();
display.addFilter(SWT.KeyDown, new Listener() {
public void handleEvent(Event e)
{
if (e.character == 'b') {
startupMillis = System.currentTimeMillis();
timeToShowMillis = System.currentTimeMillis() - startupMillis;
benchRuns = 1;
doBenchmark();
}
}
});
}
System.out.println(Display.getCurrent().getDPI());
while(!shell.isDisposed()){
if(!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
private static Control[] comps = null; // thread hack...
private static Control[] tabs = null; // thread hack...
private void doBenchmark()
{
final int pCnt = pickerList.getItemCount();
Thread benchThread = new Thread() {
public void run()
{
for (int j = 0; j < benchRuns; j++) {
lastRunTimeStart = System.currentTimeMillis();
final int jj = j;
for (int i = 0; i < pCnt; i++) {
final int ii = i;
try {
display.syncExec(new Runnable() {
public void run () {
pickerList.setSelection(ii);
dispatchSelection();
}
});
} catch (Exception e) {
e.printStackTrace();
}
display.syncExec(new Runnable() {
public void run() {
comps = layoutDisplayPanel.getChildren();
}
});
for (int cIx = 0; cIx < comps.length; cIx++) {
if (comps[cIx] instanceof TabFolder) {
final TabFolder tp = (TabFolder) comps[cIx];
display.syncExec(new Runnable() {
public void run() {
tabs = tp.getTabList();
}
});
for (int k = 0; k < tabs.length; k++) {
final int kk = k;
try {
display.syncExec(new Runnable() {
public void run() {
tp.setSelection(kk);
if (timeToShowMillis == 0)
timeToShowMillis = System.currentTimeMillis() - startupMillis;
}
});
} catch (Exception e) {
e.printStackTrace();
};
}
}
}
}
if (runTimeSB != null) {
runTimeSB.append("Run ").append(jj).append(": ");
runTimeSB.append(System.currentTimeMillis() - lastRunTimeStart).append(" millis.\n");
}
}
benchRunTime = System.currentTimeMillis() - startupMillis - timeToShowMillis;
final String message = "Java Version: " + System.getProperty("java.version") + "\n" +
"Time to Show: " + timeToShowMillis + " millis.\n" +
(runTimeSB != null ? runTimeSB.toString() : "") +
"Benchmark Run Time: " + benchRunTime + " millis.\n" +
"Average Run Time: " + (benchRunTime / benchRuns) + " millis (" + benchRuns + " runs).\n\n";
display.syncExec(new Runnable() {
public void run() {
if (benchOutFileName == null) {
MessageBox messageBox = new MessageBox(display.getActiveShell(), SWT.OK | SWT.ICON_INFORMATION);
messageBox.setText("Results");
messageBox.setMessage(message);
messageBox.open();
} else {
FileWriter fw = null;
try {
fw = new FileWriter(benchOutFileName, append);
fw.write(message);
} catch(IOException ex) {
ex.printStackTrace();
} finally {
if (fw != null)
try {fw.close();} catch(IOException ex) {}
}
}
}
});
System.out.println(message);
if (benchOutFileName != null)
System.exit(0);
}
};
benchThread.start();
}
private void dispatchSelection()
{
int ix = pickerList.getSelectionIndex();
if (ix == -1)
return;
String methodName = "create" + panels[ix][0].replace(' ', '_');
Control[] children = layoutDisplayPanel.getChildren();
for (int i = 0; i < children.length; i++)
children[i].dispose();
try {
Control child = (Control) SwtDemo.class.getMethod(methodName, new Class[] {Composite.class}).invoke(SwtDemo.this, new Object[] {layoutDisplayPanel});
child.setLayoutData("grow, wmin 500");
descrTextArea.setText(panels[ix][1]);
layoutDisplayPanel.layout();
} catch (Exception e1) {
e1.printStackTrace(); // Should never happpen...
}
}
public Control createTest(Composite parent)
{
// TabFolder tabFolder = new TabFolder(parent2, DOUBLE_BUFFER);
Button button;
Composite composite = new Composite(parent, SWT.NONE);
composite.setLayout(new MigLayout("debug", "[right][grow]", ""));
button = new Button(composite, SWT.PUSH);
button.setText("New");
button.setLayoutData("span 2, align left, split, sgx button");
button = new Button(composite, SWT.PUSH);
button.setText("Edit");
button.setLayoutData("sgx button");
button = new Button(composite, SWT.PUSH);
button.setText("Cancel");
button.setLayoutData("sgx button");
button = new Button(composite, SWT.PUSH);
button.setText("Save");
button.setLayoutData("sgx button, wrap");
new Label(composite, SWT.NONE).setText("Name");
Text text = new Text(composite, SWT.BORDER);
text.setLayoutData("sgy control, pushx, growx, wrap");
new Label(composite, SWT.NONE).setText("Sex");
Combo combo = new Combo(composite, SWT.DROP_DOWN);
combo.setLayoutData("sgy control, w 50!, wrap");
combo.setItems(new String[]
{ "M", "F", "-" });
return composite;
}
public Control createWelcome(Composite parent)
{
TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
TabItem tabPanel = createTabPanel(tabbedPane, "Welcome", new MigLayout());
MigLayout lm = new MigLayout("ins 20, fill");
Composite panel = createPanel(tabbedPane, lm);
tabPanel.setControl(panel);
String s = "MigLayout's main purpose is to make layouts for SWT and Swing, and possibly other frameworks, much more powerful and a lot easier to create, especially for manual coding.\n\n" +
"The motto is: \"MigLayout makes complex layouts easy and normal layouts one-liners.\"\n\n" +
"The layout engine is very flexible and advanced, something that is needed to make it simple to use yet handle almost all layout use-cases.\n\n" +
"MigLayout can handle all layouts that the commonly used Swing Layout Managers can handle and this with a lot of extra features. " +
"It also incorporates most, if not all, of the open source alternatives FormLayout's and TableLayout's functionality." +
"\n\n\nThanks to Karsten Lentzsch from JGoodies.com for allowing the reuse of the main demo application layout and for his inspiring talks that led to this layout Manager." +
"\n\n\nMikael Grev\n" +
"MiG InfoCom AB\n" +
"miglayout@miginfocom.com";
// One needs to set both min and pref for SWT wrapping text areas since it always returns the unwrapped size otherwise.
StyledText textArea = createTextArea(panel, s, "w 500:500, ay top, grow, push", 0);
textArea.setBackground(panel.getBackground());
textArea.setBackgroundMode(SWT.INHERIT_NONE);
// deriveFont(textArea, SWT.PATH_LINE_TO, -1);
return tabbedPane;
}
public Composite createAPI_Constraints1(Composite parent)
{
TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
LC layC = new LC().fill().wrap();
AC colC = new AC().align("right", 0).fill(1, 3).grow(100, 1, 3).align("right", 2).gap("15", 1);
AC rowC = new AC().align("top", 7).gap("15!", 6).grow(100, 8);
TabItem p1 = createTabPanel(tabbedPane, "Layout Showdown (improved)", new MigLayout(layC, colC, rowC));
// References to text fields not stored to reduce code clutter.
createList(p1, "Mouse, Mickey", new CC().dockWest().minWidth("150").gapX(null, "10"));
createLabel(p1, "Last Name", "");
createTextField(p1, "", "");
createLabel(p1, "First Name", "");
createTextField(p1, "", new CC().wrap());
createLabel(p1, "Phone", "");
createTextField(p1, "", "");
createLabel(p1, "Email", "");
createTextField(p1, "", "");
createLabel(p1, "Address 1", "");
createTextField(p1, "", new CC().spanX().growX());
createLabel(p1, "Address 2", "");
createTextField(p1, "", new CC().spanX().growX());
createLabel(p1, "City", "");
createTextField(p1, "", new CC().wrap());
createLabel(p1, "State", "");
createTextField(p1, "", "");
createLabel(p1, "Postal Code", "");
createTextField(p1, "", new CC().spanX(2).growX(0));
createLabel(p1, "Country", "");
createTextField(p1, "", new CC().wrap());
createButton(p1, "New", new CC().spanX(5).split(5).tag("other"));
createButton(p1, "Delete", new CC().tag("other"));
createButton(p1, "Edit", new CC().tag("other"));
createButton(p1, "Save", new CC().tag("other"));
createButton(p1, "Cancel", new CC().tag("cancel"));
return tabbedPane;
}
public Composite createAPI_Constraints2(Composite parent)
{
TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
LC layC = new LC().fill().wrap();
AC colC = new AC().align("right", 0).fill(1, 3).grow(100, 1, 3).align("right", 2).gap("15", 1);
AC rowC = new AC().index(6).gap("15!").align("top").grow(100, 8);
TabItem p1 = createTabPanel(tabbedPane, "Layout Showdown (improved)", new MigLayout(layC, colC, rowC));
// References to text fields not stored to reduce code clutter.
createLabel(p1, "Last Name", "");
createTextField(p1, "", "");
createLabel(p1, "First Name", "");
createTextField(p1, "", new CC().wrap());
createLabel(p1, "Phone", "");
createTextField(p1, "", "");
createLabel(p1, "Email", "");
createTextField(p1, "", "");
createLabel(p1, "Address 1", "");
createTextField(p1, "", new CC().spanX().growX());
createLabel(p1, "Address 2", "");
createTextField(p1, "", new CC().spanX().growX());
createLabel(p1, "City", "");
createTextField(p1, "", new CC().wrap());
createLabel(p1, "State", "");
createTextField(p1, "", "");
createLabel(p1, "Postal Code", "");
createTextField(p1, "", new CC().spanX(2).growX(0));
createLabel(p1, "Country", "");
createTextField(p1, "", new CC().wrap());
createButton(p1, "New", new CC().spanX(5).split(5).tag("other"));
createButton(p1, "Delete", new CC().tag("other"));
createButton(p1, "Edit", new CC().tag("other"));
createButton(p1, "Save", new CC().tag("other"));
createButton(p1, "Cancel", new CC().tag("cancel"));
return tabbedPane;
}
public Composite createLayout_Showdown(Composite parent)
{
TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
TabItem p1 = createTabPanel(tabbedPane, "Layout Showdown (pure)", new MigLayout("", "[]15[][grow,fill]15[grow]"));
// References to text fields not stored to reduce code clutter.
createList(p1, "Mouse, Mickey", "spany, growy, wmin 150");
createLabel(p1, "Last Name", "");
createTextField(p1, "", "");
createLabel(p1, "First Name", "split"); // split divides the cell
createTextField(p1, "", "growx, wrap");
createLabel(p1, "Phone", "");
createTextField(p1, "", "");
createLabel(p1, "Email", "split");
createTextField(p1, "", "growx, wrap");
createLabel(p1, "Address 1", "");
createTextField(p1, "", "span, growx"); // span merges cells
createLabel(p1, "Address 2", "");
createTextField(p1, "", "span, growx");
createLabel(p1, "City", "");
createTextField(p1, "", "wrap"); // wrap continues on next line
createLabel(p1, "State", "");
createTextField(p1, "", "");
createLabel(p1, "Postal Code", "split");
createTextField(p1, "", "growx, wrap");
createLabel(p1, "Country", "");
createTextField(p1, "", "wrap 15");
createButton(p1, "New", "span, split, align right");
createButton(p1, "Delete", "");
createButton(p1, "Edit", "");
createButton(p1, "Save", "");
createButton(p1, "Cancel", "wrap push");
// Fixed version *******************************************
TabItem p2 = createTabPanel(tabbedPane, "Layout Showdown (improved)", new MigLayout("", "[]15[][grow,fill]15[][grow,fill]"));
// References to text fields not stored to reduce code clutter.
createList(p2, "Mouse, Mickey", "spany, growy, wmin 150");
createLabel(p2, "Last Name", "");
createTextField(p2, "", "");
createLabel(p2, "First Name", "");
createTextField(p2, "", "wrap");
createLabel(p2, "Phone", "");
createTextField(p2, "", "");
createLabel(p2, "Email", "");
createTextField(p2, "", "wrap");
createLabel(p2, "Address 1", "");
createTextField(p2, "", "span");
createLabel(p2, "Address 2", "");
createTextField(p2, "", "span");
createLabel(p2, "City", "");
createTextField(p2, "", "wrap");
createLabel(p2, "State", "");
createTextField(p2, "", "");
createLabel(p2, "Postal Code", "");
createTextField(p2, "", "width 50, grow 0, wrap");
createLabel(p2, "Country", "");
createTextField(p2, "", "wrap 15");
createButton(p2, "New", "tag other, span, split");
createButton(p2, "Delete", "tag other");
createButton(p2, "Edit", "tag other");
createButton(p2, "Save", "tag other");
createButton(p2, "Cancel", "tag cancel, wrap push");
return tabbedPane;
}
public Composite createDocking(Composite parent)
{
TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
tabbedPane.setLayoutData("grow");
TabItem p1 = createTabPanel(tabbedPane, "Docking 1", new MigLayout("fill"));
createPanel(p1, "1. North", "north");
createPanel(p1, "2. West", "west");
createPanel(p1, "3. East", "east");
createPanel(p1, "4. South", "south");
Table table = new Table(getComposite(p1), DOUBLE_BUFFER);
for (int i = 0; i < 5; i++) {
TableColumn tc = new TableColumn(table, SWT.LEFT | SWT.V_SCROLL | SWT.SCROLL_LINE);
tc.setText("Column " + (i + 1));
tc.setWidth(100);
}
for (int r = 0; r < 15; r++) {
TableItem item1 = new TableItem(table,0);
String[] data = new String[6];
for (int c = 0; c < data.length; c++)
data[c] = "Cell " + (r + 1) + ", " + (c + 1);
item1.setText(data);
}
table.setHeaderVisible(true);
table.setLinesVisible(true);
table.setLayoutData("grow");
TabItem p2 = createTabPanel(tabbedPane, "Docking 2 (fill)", new MigLayout("fill", "[c]", ""));
createPanel(p2, "1. North", "north");
createPanel(p2, "2. North", "north");
createPanel(p2, "3. West", "west");
createPanel(p2, "4. West", "west");
createPanel(p2, "5. South", "south");
createPanel(p2, "6. East", "east");
createButton(p2, "7. Normal", "");
createButton(p2, "8. Normal", "");
createButton(p2, "9. Normal", "");
TabItem p3 = createTabPanel(tabbedPane, "Docking 3", new MigLayout());
createPanel(p3, "1. North", "north");
createPanel(p3, "2. South", "south");
createPanel(p3, "3. West", "west");
createPanel(p3, "4. East", "east");
createButton(p3, "5. Normal", "");
TabItem p4 = createTabPanel(tabbedPane, "Docking 4", new MigLayout());
createPanel(p4, "1. North", "north");
createPanel(p4, "2. North", "north");
createPanel(p4, "3. West", "west");
createPanel(p4, "4. West", "west");
createPanel(p4, "5. South", "south");
createPanel(p4, "6. East", "east");
createButton(p4, "7. Normal", "");
createButton(p4, "8. Normal", "");
createButton(p4, "9. Normal", "");
TabItem p5 = createTabPanel(tabbedPane, "Docking 5 (fillx)", new MigLayout("fillx", "[c]", ""));
createPanel(p5, "1. North", "north");
createPanel(p5, "2. North", "north");
createPanel(p5, "3. West", "west");
createPanel(p5, "4. West", "west");
createPanel(p5, "5. South", "south");
createPanel(p5, "6. East", "east");
createButton(p5, "7. Normal", "");
createButton(p5, "8. Normal", "");
createButton(p5, "9. Normal", "");
TabItem p6 = createTabPanel(tabbedPane, "Random Docking", new MigLayout("fill"));
String[] sides = {"north", "east", "south", "west"};
Random rand = new Random();
for (int i = 0; i < 20; i++) {
int side = rand.nextInt(4);
createPanel(p6, ((i + 1) + " " + sides[side]), sides[side]);
}
createPanel(p6, "I'm in the Center!", "grow");
return tabbedPane;
}
public Control createAbsolute_Position(final Composite parent)
{
TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
// Pos tab
TabItem posTabPanel = createTabPanel(tabbedPane, "X Y Positions", new FillLayout());
final Composite posPanel = createPanel(posTabPanel, new MigLayout());
createButton(posPanel, "pos 0.5al 0al", null);
createButton(posPanel, "pos 1al 0al", null);
createButton(posPanel, "pos 0.5al 0.5al", null);
createButton(posPanel, "pos 5in 45lp", null);
createButton(posPanel, "pos 0.5al 0.5al", null);
createButton(posPanel, "pos 0.5al 1al", null);
createButton(posPanel, "pos 1al .25al", null);
createButton(posPanel, "pos visual.x2-pref visual.y2-pref", null);
createButton(posPanel, "pos 1al -1in", null);
createButton(posPanel, "pos 100 100", null);
createButton(posPanel, "pos (10+(20*3lp)) 200", null);
createButton(posPanel, "Drag Window! (pos 500-container.xpos 500-container.ypos)",
"pos 500-container.xpos 500-container.ypos");
// Bounds tab
TabItem boundsTabPanel = createTabPanel(tabbedPane, "X1 Y1 X2 Y2 Bounds", new FillLayout());
Composite boundsPanel = createPanel(boundsTabPanel, new MigLayout());
Label southLabel = createLabel(boundsPanel, "pos (visual.x+visual.w*0.1) visual.y2-40 (visual.x2-visual.w*0.1) visual.y2", null, SWT.CENTER | SWT.BORDER);
southLabel.setBackground(new Color(display, 200, 200, 255));
deriveFont(southLabel, SWT.BOLD, 10);
createButton(boundsPanel, "pos 0 0 container.x2 n", null);
createButton(boundsPanel, "pos visual.x 40 visual.x2 70", null);
createButton(boundsPanel, "pos visual.x 100 visual.x2 p", null);
createButton(boundsPanel, "pos 0.1al 0.4al n visual.y2-10", null);
createButton(boundsPanel, "pos 0.9al 0.4al n visual.y2-10", null);
createButton(boundsPanel, "pos 0.5al 0.5al, pad 3 0 -3 0", null);
createButton(boundsPanel, "pos n n 50% 50%", null);
createButton(boundsPanel, "pos 50% 50% n n", null);
createButton(boundsPanel, "pos 50% n n 50%", null);
createButton(boundsPanel, "pos n 50% 50% n", null);
// Glass pane tab
// final TabItem glassPanel = createTabPanel(tabbedPane, "GlassPane Substitute", parent, new SwtMigLayout("align c c"));
// final Button butt = new Button("Press me!!");
// glassPanel.add(butt);
//
// butt.addActionListener(new ActionListener() {
// public void actionPerformed(ActionEvent e)
// {
// butt.setEnabled(false);
// final JPanel bg = new JPanel(parent, new SwtMigLayout("align c c,fill")) {
// public void paint(Graphics g)
// {
// g.setColor(getBackground());
// g.fillRect(0, 0, getWidth(), getHeight());
// super.paint(g);
// }
// };
// bg.setOpaque(false);
// configureActiveComponet(bg);
//
// final Label label = createLabel("You don't need a GlassPane to be cool!");
// label.setFont(label.getFont().deriveFont(30f));
// label.setForeground(new Color(255, 255, 255, 0));
// bg.add(label, "align 50% 30%");
//
// glassPanel.add(bg, "pos 0 0 visual.x2 visual.y2", 0);
// final long startTime = System.nanoTime();
// final long endTime = startTime + 500000000L;
//
// glassPanel.revalidate();
//
// final javax.swing.Timer timer = new Timer(25, null);
//
// timer.addActionListener(new ActionListener() {
// public void actionPerformed(ActionEvent e)
// {
// long now = System.nanoTime();
// int alpha = (int) (((now - startTime) / (double) (endTime - startTime)) * 300);
// if (alpha < 150)
// bg.setBackground(new Color(100, 100, 100, alpha));
//
// if (alpha > 150 && alpha < 405) {
// label.setForeground(new Color(255, 255, 255, (alpha - 150)));
// bg.repaint();
// }
// if (alpha > 405)
// timer.stop();
// }
// });
// timer.start();
// }
// });
//
parent.getShell().addControlListener(new ControlAdapter() {
public void controlMoved(ControlEvent e)
{
if (!posPanel.isDisposed()) {
posPanel.layout();
} else {
parent.getShell().removeControlListener(this);
}
}
});
return tabbedPane;
}
public Control createComponent_Links(Composite parent)
{
TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
TabItem linksPanel = createTabPanel(tabbedPane, "Component Links", new MigLayout());
// Links tab
createButton(linksPanel, "Mini", "pos null ta.y ta.x2 null, pad 3 0 -3 0");
createTextArea(linksPanel, "Components, Please Link to Me!\nMy ID is: 'ta'", "id ta, pos 0.5al 0.5al, w 300");
createButton(linksPanel, "id b1,pos ta.x2 ta.y2", null);
createButton(linksPanel, "pos b1.x2+rel b1.y visual.x2 null", null);
createCheck(linksPanel, "pos (ta.x+indent) (ta.y2+rel)", null);
createButton(linksPanel, "pos ta.x2+rel ta.y visual.x2 null", null);
createButton(linksPanel, "pos null ta.y+(ta.h-pref)/2 ta.x-rel null", null);
createButton(linksPanel, "pos ta.x ta.y2+100 ta.x2 null", null);
// External tab
TabItem externalPanel = createTabPanel(tabbedPane, "External Components", new MigLayout());
Button extButt = createButton(externalPanel, "Bounds Externally Set!", "id ext, external");
extButt.setBounds(250, 130, 200, 40);
createButton(externalPanel, "pos ext.x2 ext.y2", "pos ext.x2 ext.y2");
createButton(externalPanel, "pos null null ext.x ext.y", "pos null null ext.x ext.y");
TabItem egTabPanel = createTabPanel(tabbedPane, "End Grouping", new FillLayout());
final Composite egPanel = createPanel(egTabPanel, new MigLayout());
createButton(egPanel, "id b1, endgroupx g1, pos 200 200", null);
createButton(egPanel, "id b2, endgroupx g1, pos (b1.x+2ind) (b1.y2+rel)", null);
createButton(egPanel, "id b3, endgroupx g1, pos (b1.x+4ind) (b2.y2+rel)", null);
createButton(egPanel, "id b4, endgroupx g1, pos (b1.x+6ind) (b3.y2+rel)", null);
// Group Bounds tab
TabItem gpTabPanel = createTabPanel(tabbedPane, "Group Bounds", new FillLayout());
final Composite gpPanel = createPanel(gpTabPanel, new MigLayout());
createButton(gpPanel, "id grp1.b1, pos n 0.5al 50% n", null);
createButton(gpPanel, "id grp1.b2, pos 50% 0.5al n n", null);
createButton(gpPanel, "id grp1.b3, pos 0.5al n n b1.y", null);
createButton(gpPanel, "id grp1.b4, pos 0.5al b1.y2 n n", null);
createButton(gpPanel, "pos n grp1.y2 grp1.x n", null);
createButton(gpPanel, "pos n n grp1.x grp1.y", null);
createButton(gpPanel, "pos grp1.x2 n n grp1.y", null);
createButton(gpPanel, "pos grp1.x2 grp1.y2", null);
Composite boundsPanel = createPanel(gpPanel, (Layout) null);
boundsPanel.setLayoutData("pos grp1.x grp1.y grp1.x2 grp1.y2");
boundsPanel.setBackground(new Color(display, 200, 200, 255));
return tabbedPane;
}
public Control createFlow_Direction(Composite parent)
{
TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
createFlowPanel(tabbedPane, "Layout: flowx, Cell: flowx", "", "flowx");
createFlowPanel(tabbedPane, "Layout: flowx, Cell: flowy", "", "flowy");
createFlowPanel(tabbedPane, "Layout: flowy, Cell: flowx", "flowy", "flowx");
createFlowPanel(tabbedPane, "Layout: flowy, Cell: flowy", "flowy", "flowy");
return tabbedPane;
}
private TabItem createFlowPanel(TabFolder parent, String text, String gridFlow, String cellFlow)
{
MigLayout lm = new MigLayout("center, wrap 3," + gridFlow,
"[110,fill]",
"[110,fill]");
TabItem panel = createTabPanel(parent, text, lm);
for (int i = 0; i < 9; i++) {
Composite b = createPanel(panel, "" + (i + 1), cellFlow);
Font f = deriveFont(b, SWT.DEFAULT, 20);
b.getChildren()[0].setFont(f);
}
Composite b = createPanel(panel, "5:2", cellFlow + ",cell 1 1");
Font f = deriveFont(b, SWT.DEFAULT, 20);
b.getChildren()[0].setFont(f);
return panel;
}
public Control createDebug(Composite parent)
{
return createPlainImpl(parent, true);
}
public Control createButton_Bars(final Composite parent)
{
MigLayout lm = new MigLayout("ins 0 0 15lp 0",
"[grow]",
"[grow]u[baseline,nogrid]");
final Composite mainPanel = new Composite(parent, DOUBLE_BUFFER);
mainPanel.setLayout(lm);
TabFolder tabbedPane = new TabFolder(mainPanel, DOUBLE_BUFFER);
tabbedPane.setLayoutData("grow, wrap");
createButtonBarsPanel(tabbedPane, "Buttons", "help", false);
createButtonBarsPanel(tabbedPane, "Buttons with Help2", "help2", false);
createButtonBarsPanel(tabbedPane, "Buttons (Same width)", "help", true);
createLabel(mainPanel, "Button Order:", "");
final Label formatLabel = createLabel(mainPanel, "", "growx");
deriveFont(formatLabel, SWT.BOLD , -1);
final Button winButt = createToggleButton(mainPanel, "Windows", "wmin button");
final Button macButt = createToggleButton(mainPanel, "Mac OS X", "wmin button");
winButt.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e)
{
if (winButt.getSelection()) {
PlatformDefaults.setPlatform(PlatformDefaults.WINDOWS_XP);
formatLabel.setText("'" + PlatformDefaults.getButtonOrder() + "'");
macButt.setSelection(false);
mainPanel.layout();
}
}
});
macButt.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e)
{
if (macButt.getSelection()) {
PlatformDefaults.setPlatform(PlatformDefaults.MAC_OSX);
formatLabel.setText("'" + PlatformDefaults.getButtonOrder() + "'");
winButt.setSelection(false);
mainPanel.layout();
}
}
});
Button helpButt = createButton(mainPanel, "Help", "gap unrel,wmin button");
helpButt.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e)
{
MessageBox msgBox = new MessageBox(parent.getShell());
msgBox.setMessage("See JavaDoc for PlatformDefaults.setButtonOrder(..) for details on the format string.");
msgBox.open();
}
});
(PlatformDefaults.getPlatform() == PlatformDefaults.WINDOWS_XP ? winButt : macButt).setSelection(true);
return mainPanel;
}
private TabItem createButtonBarsPanel(TabFolder parent, String text, String helpTag, boolean sizeLocked)
{
MigLayout lm = new MigLayout("nogrid, fillx, aligny 100%, gapy unrel");
TabItem panel = createTabPanel(parent, text, lm);
// Notice that the order in the rows below does not matter...
String[][] buttons = new String[][] {
{"No", "Yes"},
{"Help", "Close"},
{"OK", "Help"},
{"OK", "Cancel", "Help"},
{"OK", "Cancel", "Apply", "Help"},
{"No", "Yes", "Cancel"},
{"Help", "< Move Back", "Move Forward >", "Cancel"},
{"Print...", "Cancel", "Help"},
};
for (int r = 0; r < buttons.length; r++) {
for (int i = 0; i < buttons[r].length; i++) {
String txt = buttons[r][i];
String tag = txt;
if (txt.equals("Help")) {
tag = helpTag;
} else if (txt.equals("< Move Back")) {
tag = "back";
} else if (txt.equals("Close")) {
tag = "cancel";
} else if (txt.equals("Move Forward >")) {
tag = "next";
} else if (txt.equals("Print...")) {
tag = "other";
}
String wrap = (i == buttons[r].length - 1) ? ",wrap" : "";
String sizeGroup = sizeLocked ? ("sgx " + r + ",") : "";
createButton(panel, txt, sizeGroup + "tag " + tag + wrap);
}
}
return panel;
}
public Control createOrientation(Composite parent)
{
TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
MigLayout lm = new MigLayout("flowy", "[grow,fill]", "[]0[]15lp[]0[]");
TabItem mainPanel = createTabPanel(tabbedPane, "Orientation", lm);
// Default orientation
MigLayout defLM = new MigLayout("", "[][grow,fill]", "");
Composite defPanel = createPanel(mainPanel, defLM);
addSeparator(defPanel, "Default Orientation");
createLabel(defPanel, "Level", "");
createTextField(defPanel, "", "span,growx");
createLabel(defPanel, "Radar", "");
createTextField(defPanel, "", "");
createTextField(defPanel, "", "");
// Right-to-left, Top-to-bottom
MigLayout rtlLM = new MigLayout("rtl,ttb",
"[][grow,fill]",
"");
Composite rtlPanel = createPanel(mainPanel, rtlLM);
addSeparator(rtlPanel, "Right to Left");
createLabel(rtlPanel, "Level", "");
createTextField(rtlPanel, "", "span,growx");
createLabel(rtlPanel, "Radar", "");
createTextField(rtlPanel, "", "");
createTextField(rtlPanel, "", "");
// Right-to-left, Bottom-to-top
MigLayout rtlbLM = new MigLayout("rtl,btt",
"[][grow,fill]",
"");
Composite rtlbPanel = createPanel(mainPanel, rtlbLM);
addSeparator(rtlbPanel, "Right to Left, Bottom to Top");
createLabel(rtlbPanel, "Level", "");
createTextField(rtlbPanel, "", "span,growx");
createLabel(rtlbPanel, "Radar", "");
createTextField(rtlbPanel, "", "");
createTextField(rtlbPanel, "", "");
// Left-to-right, Bottom-to-top
MigLayout ltrbLM = new MigLayout("ltr,btt",
"[][grow,fill]",
"");
Composite ltrbPanel = createPanel(mainPanel, ltrbLM);
addSeparator(ltrbPanel, "Left to Right, Bottom to Top");
createLabel(ltrbPanel, "Level", "");
createTextField(ltrbPanel, "", "span,growx");
createLabel(ltrbPanel, "Radar", "");
createTextField(ltrbPanel, "", "");
createTextField(ltrbPanel, "", "");
return tabbedPane;
}
public Control createCell_Position(Composite parent)
{
TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
// Absolute grid position
MigLayout absLM = new MigLayout("",
"[100:pref,fill]",
"[100:pref,fill]");
TabItem absPanel = createTabPanel(tabbedPane, "Absolute", absLM);
createPanel(absPanel, "cell 0 0", null);
createPanel(absPanel, "cell 2 0", null);
createPanel(absPanel, "cell 3 0", null);
createPanel(absPanel, "cell 1 1", null);
createPanel(absPanel, "cell 0 2", null);
createPanel(absPanel, "cell 2 2", null);
createPanel(absPanel, "cell 2 2", null);
// Relative grid position with wrap
MigLayout relAwLM = new MigLayout("wrap",
"[100:pref,fill][100:pref,fill][100:pref,fill][100:pref,fill]",
"[100:pref,fill]");
TabItem relAwPanel = createTabPanel(tabbedPane, "Relative + Wrap", relAwLM);
createPanel(relAwPanel, "", null);
createPanel(relAwPanel, "skip", null);
createPanel(relAwPanel, "", null);
createPanel(relAwPanel, "skip,wrap", null);
createPanel(relAwPanel, "", null);
createPanel(relAwPanel, "skip,split", null);
createPanel(relAwPanel, "", null);
// Relative grid position with manual wrap
MigLayout relWLM = new MigLayout("",
"[100:pref,fill]",
"[100:pref,fill]");
TabItem relWPanel = createTabPanel(tabbedPane, "Relative", relWLM);
createPanel(relWPanel, "", null);
createPanel(relWPanel, "skip", null);
createPanel(relWPanel, "wrap", null);
createPanel(relWPanel, "skip,wrap", null);
createPanel(relWPanel, "", null);
createPanel(relWPanel, "skip,split", null);
createPanel(relWPanel, "", null);
// Mixed relative and absolute grid position
MigLayout mixLM = new MigLayout("",
"[100:pref,fill]",
"[100:pref,fill]");
TabItem mixPanel = createTabPanel(tabbedPane, "Mixed", mixLM);
createPanel(mixPanel, "", null);
createPanel(mixPanel, "cell 2 0", null);
createPanel(mixPanel, "", null);
createPanel(mixPanel, "cell 1 1,wrap", null);
createPanel(mixPanel, "", null);
createPanel(mixPanel, "cell 2 2,split", null);
createPanel(mixPanel, "", null);
return tabbedPane;
}
public Control createPlain(Composite parent)
{
return createPlainImpl(parent, false);
}
private Control createPlainImpl(Composite parent, boolean debug)
{
TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
MigLayout lm = new MigLayout((debug && benchRuns == 0 ? "debug" : ""), "[r][100lp, fill][60lp][95lp, fill]", "");
TabItem panel = createTabPanel(tabbedPane, "Plain", lm);
addSeparator(panel, "Manufacturer");
createLabel(panel, "Company", "");
createTextField(panel, "", "span,growx");
createLabel(panel, "Contact", "");
createTextField(panel, "", "span,growx");
createLabel(panel, "Order No", "");
createTextField(panel, "", "wmin 15*6,wrap");
addSeparator(panel, "Inspector");
createLabel(panel, "Name", "");
createTextField(panel, "", "span,growx");
createLabel(panel, "Reference No", "");
createTextField(panel, "", "wrap");
createLabel(panel, "Status", "");
createCombo(panel, new String[] {"In Progress", "Finnished", "Released"}, "wrap");
addSeparator(panel, "Ship");
createLabel(panel, "Shipyard", "");
createTextField(panel, "", "span,growx");
createLabel(panel, "Register No", "");
createTextField(panel, "", "");
createLabel(panel, "Hull No", "right");
createTextField(panel, "", "wmin 15*6,wrap");
createLabel(panel, "Project StructureType", "");
createCombo(panel, new String[] {"New Building", "Convention", "Repair"}, "wrap");
if (debug)
createLabel(panel, "Blue is component bounds. Cell bounds (red) can not be shown in SWT", "newline,ax left,span,gaptop 40");
return tabbedPane;
}
public Control createBound_Sizes(Composite parent)
{
TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
for (int i = 0; i < 2; i++) { // Jumping for 0 and Stable for 1
String colConstr = i == 0 ? "[right][300]" : "[right, 150lp:pref][300]";
MigLayout LM1 = new MigLayout("wrap", colConstr, "");
TabItem panel1 = createTabPanel(tabbedPane, i == 0 ? "Jumping 1" : "Stable 1", LM1);
createLabel(panel1, "File Number:", "");
createTextField(panel1, "", "growx");
createLabel(panel1, "RFQ Number:", "");
createTextField(panel1, "", "growx");
createLabel(panel1, "Entry Date:", "");
createTextField(panel1, " ", "wmin 6*6");
createLabel(panel1, "Sales Person:", "");
createTextField(panel1, "", "growx");
MigLayout LM2 = new MigLayout("wrap", colConstr, "");
TabItem panel2 = createTabPanel(tabbedPane, i == 0 ? "Jumping 2" : "Stable 2", LM2);
createLabel(panel2, "Shipper:", "");
createTextField(panel2, " ", "split 2");
createTextField(panel2, "", "growx");
createLabel(panel2, "Consignee:", "");
createTextField(panel2, " ", "split 2");
createTextField(panel2, "", "growx");
createLabel(panel2, "Departure:", "");
createTextField(panel2, " ", "split 2");
createTextField(panel2, "", "growx");
createLabel(panel2, "Destination:", "");
createTextField(panel2, " ", "split 2");
createTextField(panel2, "", "growx");
}
return tabbedPane;
}
public Control createComponent_Sizes(Composite parent)
{
TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
MigLayout lm = new MigLayout("wrap", "[right][0:pref,grow]", "");
TabItem tabPanel = createTabPanel(tabbedPane, "Component Sizes", new FillLayout());
SashForm sashForm = new SashForm(getComposite(tabPanel), SWT.HORIZONTAL | SWT.SMOOTH);
sashForm.setBackground(new Color(display, 255, 255, 255));
sashForm.setBackgroundMode(SWT.INHERIT_FORCE);
Composite panel = createPanel(sashForm, lm, SWT.BORDER);
createTextArea(sashForm, "Use slider to see how the components grow and shrink depending on the constraints set on them.", "");
createLabel(panel, "", "");
createTextField(panel, "8 ", "");
createLabel(panel, "width min!", null);
createTextField(panel, "3 ", "width min!");
createLabel(panel, "width pref!", "");
createTextField(panel, "3 ", "width pref!");
createLabel(panel, "width min:pref", null);
createTextField(panel, "8 ", "width min:pref");
createLabel(panel, "width min:100:150", null);
createTextField(panel, "8 ", "width min:100:150");
createLabel(panel, "width min:100:150, growx", null);
createTextField(panel, "8 ", "width min:100:150, growx");
createLabel(panel, "width min:100, growx", null);
createTextField(panel, "8 ", "width min:100, growx");
createLabel(panel, "width 40!", null);
createTextField(panel, "8 ", "width 40!");
createLabel(panel, "width 40:40:40", null);
createTextField(panel, "8 ", "width 40:40:40");
return tabbedPane;
}
public Control createCell_Alignments(Composite parent)
{
TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
// Horizontal
MigLayout hLM = new MigLayout("wrap",
"[grow,left][grow,center][grow,right][grow,fill,center]",
"[]unrel[][]");
TabItem hPanel = createTabPanel(tabbedPane, "Horizontal", hLM);
String[] sizes = new String[] {"", "growx", "growx 0", "left", "center", "right", "leading", "trailing"};
createLabel(hPanel, "[left]", "c");
createLabel(hPanel, "[center]", "c");
createLabel(hPanel, "[right]", "c");
createLabel(hPanel, "[fill,center]", "c, growx 0");
for (int r = 0; r < sizes.length; r++) {
for (int c = 0; c < 4; c++) {
String text = sizes[r].length() > 0 ? sizes[r] : "default";
createButton(hPanel, text, sizes[r]);
}
}
// Vertical
MigLayout vLM = new MigLayout("wrap,flowy",
"[right][]",
"[grow,top][grow,center][grow,bottom][grow,fill,bottom][grow,fill,baseline]");
TabItem vPanel = createTabPanel(tabbedPane, "Vertical", vLM);
String[] vSizes = new String[] {"", "growy", "growy 0", "top", "center", "bottom"};
createLabel(vPanel, "[top]", "center");
createLabel(vPanel, "[center]", "center");
createLabel(vPanel, "[bottom]", "center");
createLabel(vPanel, "[fill, bottom]", "center, growy 0");
createLabel(vPanel, "[fill, baseline]", "center");
for (int c = 0; c < vSizes.length; c++) {
for (int r = 0; r < 5; r++) {
String text = vSizes[c].length() > 0 ? vSizes[c] : "default";
createButton(vPanel, text, vSizes[c]);
}
}
return tabbedPane;
}
public Control createUnits(Composite parent)
{
TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
// Horizontal
MigLayout hLM = new MigLayout("wrap",
"[right][]",
"");
TabItem hPanel = createTabPanel(tabbedPane, "Horizontal", hLM);
String[] sizes = new String[] {"72pt", "25.4mm", "2.54cm", "1in", "72px", "96px", "120px", "25%", "30sp"};
for (int i = 0; i < sizes.length; i++) {
createLabel(hPanel, sizes[i], "");
createTextField(hPanel, "", "width " + sizes[i] + "");
}
// Horizontal lp
MigLayout hlpLM = new MigLayout("", "[right][][]", "");
TabItem hlpPanel = createTabPanel(tabbedPane, "Horizontal LP", hlpLM);
createLabel(hlpPanel, "9 cols", "");
createTextField(hlpPanel, "", "wmin 9*6");
String[] lpSizes = new String[] {"75lp", "75px", "88px", "100px"};
createLabel(hlpPanel, "", "wrap");
for (int i = 0; i < lpSizes.length; i++) {
createLabel(hlpPanel, lpSizes[i], "");
createTextField(hlpPanel, "", "width " + lpSizes[i] + ", wrap");
}
// Vertical
MigLayout vLM = new MigLayout("wrap,flowy",
"[c]",
"[top][top]");
TabItem vPanel = createTabPanel(tabbedPane, "Vertical", vLM);
String[] vSizes = new String[] {"72pt", "25.4mm", "2.54cm", "1in", "72px", "96px", "120px", "25%", "30sp"};
for (int i = 0; i < sizes.length; i++) {
createLabel(vPanel, vSizes[i], "");
createTextArea(vPanel, "", "width 50!, height " + vSizes[i] + "");
}
// Vertical lp
MigLayout vlpLM = new MigLayout("wrap,flowy",
"[c]",
"[top][top]40px[top][top]");
TabItem vlpPanel = createTabPanel(tabbedPane, "Vertical LP", vlpLM);
createLabel(vlpPanel, "4 rows", "");
createTextArea(vlpPanel, "\n\n\n\n", "width 50!");
createLabel(vlpPanel, "field", "");
createTextField(vlpPanel, "", "wmin 5*9");
String[] vlpSizes1 = new String[] {"63lp", "57px", "63px", "68px", "25%"};
String[] vlpSizes2 = new String[] {"21lp", "21px", "23px", "24px", "10%"};
for (int i = 0; i < vlpSizes1.length; i++) {
createLabel(vlpPanel, vlpSizes1[i], "");
createTextArea(vlpPanel, "", "width 50!, height " + vlpSizes1[i] + "");
createLabel(vlpPanel, vlpSizes2[i], "");
createTextField(vlpPanel, "", "height " + vlpSizes2[i] + "!,wmin 5*6");
}
createLabel(vlpPanel, "button", "skip 2");
createButton(vlpPanel, "...", "");
return tabbedPane;
}
public Control createGrouping(Composite parent)
{
TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
// Ungrouped
MigLayout ugM = new MigLayout("", "[]push[][][]", "");
TabItem ugPanel = createTabPanel(tabbedPane, "Ungrouped", ugM);
createButton(ugPanel, "Help", "");
createButton(ugPanel, "< Back", "gap push");
createButton(ugPanel, "Forward >", "");
createButton(ugPanel, "Apply", "gap unrel");
createButton(ugPanel, "Cancel", "gap unrel");
// Grouped Components
MigLayout gM = new MigLayout("nogrid, fillx");
TabItem gPanel = createTabPanel(tabbedPane, "Grouped (Components)", gM);
createButton(gPanel, "Help", "sg");
createButton(gPanel, "< Back", "sg, gap push");
createButton(gPanel, "Forward >", "sg");
createButton(gPanel, "Apply", "sg, gap unrel");
createButton(gPanel, "Cancel", "sg, gap unrel");
// Grouped Columns
MigLayout gcM = new MigLayout("", "[sg,fill]push[sg,fill][sg,fill]unrel[sg,fill]unrel[sg,fill]", "");
TabItem gcPanel = createTabPanel(tabbedPane, "Grouped (Columns)", gcM);
createButton(gcPanel, "Help", "");
createButton(gcPanel, "< Back", "");
createButton(gcPanel, "Forward >", "");
createButton(gcPanel, "Apply", "");
createButton(gcPanel, "Cancel", "");
// Ungrouped Rows
MigLayout ugrM = new MigLayout(); // no "sg" is the only difference to next panel
TabItem ugrPanel = createTabPanel(tabbedPane, "Ungrouped Rows", ugrM);
createLabel(ugrPanel, "File Number:", "");
createTextField(ugrPanel, "30 ", "wrap");
createLabel(ugrPanel, "BL/MBL number:", "");
createTextField(ugrPanel, "7 ", "split 2");
createTextField(ugrPanel, "7 ", "wrap");
createLabel(ugrPanel, "Entry Date:", "");
createTextField(ugrPanel, "7 ", "wrap");
createLabel(ugrPanel, "RFQ Number:", "");
createTextField(ugrPanel, "30 ", "wrap");
createLabel(ugrPanel, "Goods:", "");
createCheck(ugrPanel, "Dangerous", "wrap");
createLabel(ugrPanel, "Shipper:", "");
createTextField(ugrPanel, "30 ", "wrap");
createLabel(ugrPanel, "Customer:", "");
createTextField(ugrPanel, "", "split 2,growx");
createButton(ugrPanel, "...", "width 60px:pref,wrap");
createLabel(ugrPanel, "Port of Loading:", "");
createTextField(ugrPanel, "30 ", "wrap");
createLabel(ugrPanel, "Destination:", "");
createTextField(ugrPanel, "30 ", "wrap");
// Grouped Rows
MigLayout grM = new MigLayout("", "[]", "[sg]"); // "sg" is the only difference to previous panel
TabItem grPanel = createTabPanel(tabbedPane, "Grouped Rows", grM);
createLabel(grPanel, "File Number:", "");
createTextField(grPanel, "30 ","wrap");
createLabel(grPanel, "BL/MBL number:", "");
createTextField(grPanel, "7 ","split 2");
createTextField(grPanel, "7 ", "wrap");
createLabel(grPanel, "Entry Date:", "");
createTextField(grPanel, "7 ", "wrap");
createLabel(grPanel, "RFQ Number:", "");
createTextField(grPanel, "30 ", "wrap");
createLabel(grPanel, "Goods:", "");
createCheck(grPanel, "Dangerous", "wrap");
createLabel(grPanel, "Shipper:", "");
createTextField(grPanel, "30 ", "wrap");
createLabel(grPanel, "Customer:", "");
createTextField(grPanel, "", "split 2,growx");
createButton(grPanel, "...", "width 50px:pref,wrap");
createLabel(grPanel, "Port of Loading:", "");
createTextField(grPanel, "30 ", "wrap");
createLabel(grPanel, "Destination:", "");
createTextField(grPanel, "30 ", "wrap");
return tabbedPane;
}
public Control createSpan(Composite parent)
{
TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
// Horizontal span
MigLayout colLM = new MigLayout("",
"[fill][25%,fill][105lp!,fill][150px!,fill]",
"[]15[][]");
TabItem colPanel = createTabPanel(tabbedPane, "Column Span/Split", colLM);
createTextField(colPanel, "Col1 [ ]", "");
createTextField(colPanel, "Col2 [25%]", "");
createTextField(colPanel, "Col3 [105lp!]", "");
createTextField(colPanel, "Col4 [150px!]", "wrap");
createLabel(colPanel, "Full Name:", "");
createTextField(colPanel, "span, growx ", "span,growx");
createLabel(colPanel, "Phone:", "");
createTextField(colPanel, " ", "span 3, split 5");
createTextField(colPanel, " ", null);
createTextField(colPanel, " ", null);
createTextField(colPanel, " ", null);
createLabel(colPanel, "(span 3, split 4)", "wrap");
createLabel(colPanel, "Zip/City:", "");
createTextField(colPanel, " ", "");
createTextField(colPanel, "span 2, growx", null);
// Vertical span
MigLayout rowLM = new MigLayout("wrap",
"[225lp]para[225lp]",
"[]3[]unrel[]3[]unrel[]3[]");
TabItem rowPanel = createTabPanel(tabbedPane, "Row Span", rowLM);
createLabel(rowPanel, "Name", "");
createLabel(rowPanel, "Notes", "");
createTextField(rowPanel, "growx", null);
createTextArea(rowPanel, "spany,grow ", "spany,grow,hmin 13*5");
createLabel(rowPanel, "Phone", "");
createTextField(rowPanel, "growx", null);
createLabel(rowPanel, "Fax", "");
createTextField(rowPanel, "growx", null);
return tabbedPane;
}
public Control createGrowing(Composite parent)
{
TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
// All tab
MigLayout allLM = new MigLayout("",
"[pref!][grow,fill]",
"[]15[]");
TabItem allTab = createTabPanel(tabbedPane, "All", allLM);
createLabel(allTab, "Fixed", "");
createLabel(allTab, "Gets all extra space", "wrap");
createTextField(allTab, " ", "");
createTextField(allTab, " ", "");
// Half tab
MigLayout halfLM = new MigLayout("",
"[pref!][grow,fill]",
"[]15[]");
TabItem halfTab = createTabPanel(tabbedPane, "Half", halfLM);
createLabel(halfTab, "Fixed", "");
createLabel(halfTab, "Gets half of extra space", "");
createLabel(halfTab, "Gets half of extra space", "wrap");
createTextField(halfTab, " ", "");
createTextField(halfTab, " ", "");
createTextField(halfTab, " ", "");
// Percent 1 tab
MigLayout p1LM = new MigLayout("",
"[pref!][0:0,grow 25,fill][0:0,grow 75,fill]",
"[]15[]");
TabItem p1Tab = createTabPanel(tabbedPane, "Percent 1", p1LM);
createLabel(p1Tab, "Fixed", "");
createLabel(p1Tab, "Gets 25% of extra space", "");
createLabel(p1Tab, "Gets 75% of extra space", "wrap");
createTextField(p1Tab, " ", "");
createTextField(p1Tab, " ", "");
createTextField(p1Tab, " ", "");
// Percent 2 tab
MigLayout p2LM = new MigLayout("",
"[0:0,grow 33,fill][0:0,grow 67,fill]",
"[]15[]");
TabItem p2Tab = createTabPanel(tabbedPane, "Percent 2", p2LM);
createLabel(p2Tab, "Gets 33% of extra space", "");
createLabel(p2Tab, "Gets 67% of extra space", "wrap");
createTextField(p2Tab, " ", "");
createTextField(p2Tab, " ", "");
// Vertical 1 tab
MigLayout v1LM = new MigLayout("flowy",
"[]15[]",
"[][c,pref!][c,grow 25,fill][c,grow 75,fill]");
TabItem v1Tab = createTabPanel(tabbedPane, "Vertical 1", v1LM);
createLabel(v1Tab, "Fixed", "skip");
createLabel(v1Tab, "Gets 25% of extra space", "");
createLabel(v1Tab, "Gets 75% of extra space", "wrap");
createLabel(v1Tab, "new Text(SWT.MULTI | SWT.WRAP | SWT.BORDER)", "");
createTextArea(v1Tab, "", "hmin 4*13");
createTextArea(v1Tab, "", "hmin 4*13");
createTextArea(v1Tab, "", "hmin 4*13");
// Vertical 2 tab
MigLayout v2LM = new MigLayout("flowy",
"[]15[]",
"[][c,grow 33,fill][c,grow 67,fill]");
TabItem v2Tab = createTabPanel(tabbedPane, "Vertical 2", v2LM);
createLabel(v2Tab, "Gets 33% of extra space", "skip");
createLabel(v2Tab, "Gets 67% of extra space", "wrap");
createLabel(v2Tab, "new Text(SWT.MULTI | SWT.WRAP | SWT.BORDER)", "");
createTextArea(v2Tab, "", "hmin 4*13");
createTextArea(v2Tab, "", "hmin 4*13");
return tabbedPane;
}
public Control createBasic_Sizes(Composite parent)
{
TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
// Horizontal tab
MigLayout horLM = new MigLayout("",
"[]15[75px]25[min]25[]",
"[]15");
TabItem horTab = createTabPanel(tabbedPane, "Horizontal - Column size set", horLM);
createLabel(horTab, "75px", "skip");
createLabel(horTab, "Min", "");
createLabel(horTab, "Pref", "wrap");
createLabel(horTab, "new Text(15)", "");
createTextField(horTab, " ", "wmin 10");
createTextField(horTab, " ", "wmin 10");
createTextField(horTab, " ", "wmin 10");
// Vertical tab 1
MigLayout verLM = new MigLayout("flowy,wrap",
"[]15[]",
"[]15[c,45:45]15[c,min]15[c,pref]");
TabItem verTab = createTabPanel(tabbedPane, "\"Vertical - Row sized\"", verLM);
createLabel(verTab, "45px", "skip");
createLabel(verTab, "Min", "");
createLabel(verTab, "Pref", "");
createLabel(verTab, "new Text(SWT.MULTI)", "");
createTextArea(verTab, "", "");
createTextArea(verTab, "", "");
createTextArea(verTab, "", "");
// Componentsized/Baseline 2
MigLayout verLM2 = new MigLayout("flowy,wrap",
"[]15[]",
"[]15[baseline]15[baseline]15[baseline]");
TabItem verTab2 = createTabPanel(tabbedPane, "\"Vertical - Component sized + Baseline\"", verLM2);
createLabel(verTab2, "45px", "skip");
createLabel(verTab2, "Min", "");
createLabel(verTab2, "Pref", "");
createLabel(verTab2, "new Text(SWT.MULTI)", "");
createTextArea(verTab2, "", "height 45");
createTextArea(verTab2, "", "height min");
createTextArea(verTab2, "", "height pref");
return tabbedPane;
}
public Control createAlignments(Composite parent)
{
TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
// Horizontal tab
MigLayout horLM = new MigLayout("wrap",
"[label]15[left]15[center]15[right]15[fill]15[]",
"[]15[]");
String[] horLabels = new String[] {"[label]", "[left]", "[center]", "[right]", "[fill]", "[] (Default)"};
TabItem horTab = createTabPanel(tabbedPane, "Horizontal", horLM);
String[] horNames = new String[] {"First Name", "Phone Number", "Facsmile", "Email", "Address", "Other"};
for (int c = 0; c < horLabels.length; c++)
createLabel(horTab, horLabels[c], "");
for (int r = 0; r < horLabels.length; r++) {
for (int c = 0; c < horNames.length; c++) {
if (c == 0) {
createLabel(horTab, horNames[r] + ":", "");
} else {
createButton(horTab, horNames[r], "");
}
}
}
// Vertical tab
MigLayout verLM = new MigLayout("wrap,flowy",
"[]unrel[]rel[]",
"[top]15[center]15[bottom]15[fill]15[fill,baseline]15[baseline]15[]");
String[] verLabels = new String[] {"[top]", "[center]", "[bottom]", "[fill]", "[fill,baseline]", "[baseline]", "[] (Default)"};
TabItem verTab = createTabPanel(tabbedPane, "Vertical", verLM);
for (int c = 0; c < verLabels.length; c++)
createLabel(verTab, verLabels[c], "");
for (int c = 0; c < verLabels.length; c++)
createButton(verTab, "A Button", "");
for (int c = 0; c < verLabels.length; c++)
createTextField(verTab, "JTextFied", "");
for (int c = 0; c < verLabels.length; c++)
createTextArea(verTab, "Text ", "");
for (int c = 0; c < verLabels.length; c++)
createTextArea(verTab, "Text\nwith two lines", "");
for (int c = 0; c < verLabels.length; c++)
createTextArea(verTab, "Scrolling Text\nwith two lines", "");
return tabbedPane;
}
public Control createQuick_Start(Composite parent)
{
TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
MigLayout lm = new MigLayout("wrap",
"[right][fill,sizegroup]unrel[right][fill,sizegroup]",
"");
TabItem p = createTabPanel(tabbedPane, "Quick Start", lm);
addSeparator(p, "General");
createLabel(p, "Company", "gap indent");
createTextField(p, "", "span,growx");
createLabel(p, "Contact", "gap indent");
createTextField(p, "", "span,growx");
addSeparator(p, "Propeller");
createLabel(p, "PTI/kW", "gap indent");
createTextField(p, "", "wmin 130");
createLabel(p, "Power/kW", "gap indent");
createTextField(p, "", "wmin 130");
createLabel(p, "R/mm", "gap indent");
createTextField(p, "", "wmin 130");
createLabel(p, "D/mm", "gap indent");
createTextField(p, "", "wmin 130");
return tabbedPane;
}
public Control createGrow_Shrink(Composite parent)
{
TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
// shrink tab
MigLayout slm = new MigLayout("nogrid");
TabItem shrinkTabPanel = createTabPanel(tabbedPane, "Shrink", new FillLayout());
SashForm shrinkSash = new SashForm(getComposite(shrinkTabPanel), SWT.HORIZONTAL | SWT.SMOOTH);
shrinkSash.setBackground(new Color(display, 255, 255, 255));
shrinkSash.setBackgroundMode(SWT.INHERIT_FORCE);
Composite shrinkPanel = createPanel(shrinkSash, slm, SWT.BORDER);
shrinkPanel.setLayoutData("wmin 100");
createTextField(shrinkPanel, "shp 110", "shp 110,w 10:130");
createTextField(shrinkPanel, "Default (100)", "w 10:130");
createTextField(shrinkPanel, "shp 90", "shp 90,w 10:130");
createTextField(shrinkPanel, "shrink 25", "newline,shrink 25,w 10:130");
createTextField(shrinkPanel, "shrink 75", "shrink 75,w 10:130");
createTextField(shrinkPanel, "Default", "newline, w 10:130");
createTextField(shrinkPanel, "Default", "w 10:130");
createTextField(shrinkPanel, "shrink 0", "newline,shrink 0,w 10:130");
createTextField(shrinkPanel, "shp 110", "newline,shp 110,w 10:130");
createTextField(shrinkPanel, "shp 100,shrink 25", "shp 100,shrink 25,w 10:130");
createTextField(shrinkPanel, "shp 100,shrink 75", "shp 100,shrink 75,w 10:130");
createTextArea(shrinkSash, "Use the slider to see how the components shrink depending on the constraints set on them.\n\n'shp' means Shrink Priority. " +
"Lower values will be shrunk before higer ones and the default value is 100.\n\n'shrink' means Shrink Weight. " +
"Lower values relative to other's means they will shrink less when space is scarse. " +
"Shrink Weight is only relative to components with the same Shrink Priority. Default Shrink Weight is 100.\n\n" +
"The component's minimum size will always be honored.\n\nFor SWT, which doesn't have a component notion of minimum, " +
"preferred or maximum size, those sizes are set explicitly to minimum 10 and preferred 130 pixels.", "");
// Grow tab
TabItem growTabPanel = createTabPanel(tabbedPane, "Grow", new FillLayout());
SashForm growSash = new SashForm(getComposite(growTabPanel), SWT.HORIZONTAL | SWT.SMOOTH);
growSash.setBackground(new Color(display, 255, 255, 255));
growSash.setBackgroundMode(SWT.INHERIT_FORCE);
Composite growPanel = createPanel(growSash, new MigLayout("nogrid", "[grow]"), SWT.BORDER);
growPanel.setLayoutData("wmin 100");
createButton(growPanel, "gp 110, grow", "gp 110, grow, wmax 170");
createButton(growPanel, "Default (100), grow", "grow, wmax 170");
createButton(growPanel, "gp 90, grow", "gp 90, grow, wmax 170");
createButton(growPanel, "Default Button", "newline");
createButton(growPanel, "growx", "newline,growx,wrap");
createButton(growPanel, "gp 110, grow", "gp 110, grow, wmax 170");
createButton(growPanel, "gp 100, grow 25", "gp 100, grow 25, wmax 170");
createButton(growPanel, "gp 100, grow 75", "gp 100, grow 75, wmax 170");
createTextArea(growSash, "'gp' means Grow Priority. " +
"Lower values will be grown before higher ones and the default value is 100.\n\n'grow' means Grow Weight. " +
"Higher values relative to other's means they will grow more when space is up for takes. " +
"Grow Weight is only relative to components with the same Grow Priority. Default Grow Weight is 0 which means " +
"components will normally not grow. \n\nNote that the buttons in the first and last row have max width set to 170 to " +
"emphasize Grow Priority.\n\nThe component's maximum size will always be honored.", "");
return tabbedPane;
}
// **********************************************************
// * Helper Methods
// **********************************************************
// private final ToolTipListener toolTipListener = new ToolTipListener();
// private final ConstraintListener constraintListener = new ConstraintListener();
private Combo createCombo(Object parent, String[] texts, Object layout)
{
Combo b = new Combo(getComposite(parent), SWT.DROP_DOWN);
for (int i = 0; i < texts.length; i++)
b.add(texts[i]);
b.setLayoutData(layout);
// configureActiveComponet(b);
return b;
}
private Label createLabel(Object parent, String text, Object layout)
{
return createLabel(parent, text, layout, SWT.LEFT);
}
private Label createLabel(Object parent, String text, Object layout, int style)
{
final Label b = new Label(getComposite(parent), style | DOUBLE_BUFFER);
b.setText(text);
b.setLayoutData(layout != null ? layout : text);
// b.setAlignment();
// configureActiveComponet(b);
return b;
}
private Text createTextField(Object parent, String text, Object layout)
{
final Text b = new Text(getComposite(parent), SWT.SINGLE | SWT.BORDER | DOUBLE_BUFFER);
b.setText(text);
b.setLayoutData(layout != null ? layout : text);
// configureActiveComponet(b);
return b;
}
private Button createButton(Object parent, String text, Object layout)
{
return createButton(getComposite(parent), text, layout, false);
}
private Button createButton(Object parent, String text, Object layout, boolean bold)
{
Button b = new Button(getComposite(parent), SWT.PUSH | SWT.NO_BACKGROUND | DOUBLE_BUFFER);
b.setText(text.length() == 0 ? "\"\"" : text);
b.setLayoutData(layout != null ? layout : text);
// configureActiveComponet(b);
return b;
}
private Composite createPanel(Object parent, String text, Object layout)
{
Color bg = new Color(display.getActiveShell().getDisplay(), 255, 255, 255);
Composite panel = new Composite(getComposite(parent), DOUBLE_BUFFER | SWT.BORDER);
panel.setLayout(new MigLayout("fill"));
panel.setBackground(bg);
panel.setLayoutData(layout != null ? layout : text);
text = text.length() == 0 ? "\"\"" : text;
Label label = createLabel(panel, text, "grow", SWT.NO_BACKGROUND | SWT.CENTER);
label.setBackground(bg);
// configureActiveComponet(panel);
return panel;
}
private TabItem createTabPanel(TabFolder parent, String text, Layout lm)
{
Composite panel = new Composite(parent, DOUBLE_BUFFER);
// panel.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WHITE));
TabItem tab = new TabItem(parent, DOUBLE_BUFFER);
tab.setControl(panel);
tab.setText(text);
if (lm != null)
panel.setLayout(lm);
// configureActiveComponet(panel);
return tab;
}
private Composite createPanel(Object parent, Layout lm)
{
return createPanel(parent, lm, 0);
}
private Composite createPanel(Object parent, Layout lm, int style)
{
Composite panel = new Composite(getComposite(parent), DOUBLE_BUFFER | style);
panel.setLayout(lm);
return panel;
}
private Button createToggleButton(Object parent, String text, Object layout)
{
Button b = new Button(getComposite(parent), SWT.TOGGLE | DOUBLE_BUFFER);
b.setText(text.length() == 0 ? "\"\"" : text);
b.setLayoutData(layout != null ? layout : text);
// configureActiveComponet(b);
return b;
}
private Button createCheck(Object parent, String text, Object layout)
{
Button b = new Button(getComposite(parent), SWT.CHECK | DOUBLE_BUFFER);
b.setText(text);
b.setLayoutData(layout != null ? layout : text);
// configureActiveComponet(b);
return b;
}
private List createList(Object parent, String text, Object layout)
{
List list = new List(getComposite(parent), DOUBLE_BUFFER | SWT.BORDER);
list.add(text);
list.setLayoutData(layout);
return list;
}
private StyledText createTextArea(Object parent, String text, String layout)
{
return createTextArea(parent, text, layout, SWT.MULTI | SWT.WRAP | SWT.BORDER | DOUBLE_BUFFER);
}
private StyledText createTextArea(Object parent, String text, String layout, int style)
{
StyledText ta = new StyledText(getComposite(parent), SWT.MULTI | SWT.WRAP | style | DOUBLE_BUFFER);
ta.setText(text);
// ta.setMargins(5, 5, 5, 5);
ta.setLayoutData(layout != null ? layout : text);
// configureActiveComponet(ta);
return ta;
}
public Composite getComposite(Object c)
{
if (c instanceof Control)
return (Composite) c;
return (Composite) ((TabItem) c).getControl();
}
private Font deriveFont(Control cont, int style, int height)
{
Font f = cont.getFont();
FontData fd = f.getFontData()[0];
if (style != SWT.DEFAULT)
fd.setStyle(style);
if (height != -1)
fd.setHeight(height);
Font font = new Font(display, fd);
cont.setFont(font);
return font;
}
// private Control configureActiveComponet(Control c)
// {
// c.addMouseMotionListener(toolTipListener);
// c.addMouseListener(constraintListener);
// return c;
// }
private void addSeparator(Object panel, String text)
{
Label l = createLabel(panel, text, "gaptop para, span, split 2");
l.setForeground(new Color(display, 0, 70, 213));
Label s = new Label(getComposite(panel), SWT.SEPARATOR | SWT.HORIZONTAL | DOUBLE_BUFFER);
s.setLayoutData("gapleft rel, gaptop para, growx");
// configureActiveComponet(s);
}
// private class ConstraintListener extends MouseAdapter
// {
// public void mousePressed(MouseEvent e)
// {
// if (e.isPopupTrigger())
// react(e);
// }
//
// public void mouseReleased(MouseEvent e)
// {
// if (e.isPopupTrigger())
// react(e);
// }
//
// public void react(MouseEvent e)
// {
// Control c = (Control) e.getSource();
// LayoutManager lm = c.getParent().getLayout();
// if (lm instanceof SwtMigLayout == false)
// lm = c.getLayout();
//
// if (lm instanceof SwtMigLayout) {
// MigLayout ffl = (MigLayout) lm;
// boolean isComp = ffl.isManagingComponent(c);
// String compConstr = isComp ? ffl.getComponentConstraints(c) : null;
// String rowsConstr = isComp ? null : ffl.getRowConstraints();
// String colsConstr = isComp ? null : ffl.getColumnConstraints();
// String layoutConstr = isComp ? null : ffl.getLayoutConstraints();
//
// ConstraintsDialog cDlg = new ConstraintsDialog(SwingDemo.this, layoutConstr, rowsConstr, colsConstr, compConstr);
// cDlg.pack();
// cDlg.setLocationRelativeTo(c);
//
// if (cDlg.showDialog()) {
// try {
// if (isComp) {
// String constrStr = cDlg.componentConstrTF.getText().trim();
// ffl.setComponentConstraints(c, constrStr);
// if (c instanceof Button) {
// c.setFont(BUTT_FONT);
// ((Button) c).setText(constrStr.length() == 0 ? "" : constrStr);
// }
// } else {
// ffl.setLayoutConstraints(cDlg.layoutConstrTF.getText());
// ffl.setRowConstraints(cDlg.rowsConstrTF.getText());
// ffl.setColumnConstraints(cDlg.colsConstrTF.getText());
// }
// } catch(Exception ex) {
// StringWriter sw = new StringWriter();
// ex.printStackTrace(new PrintWriter(sw));
// JOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(c), sw.toString(), "Error parsing Constraint!", JOptionPane.ERROR_MESSAGE);
// return;
// }
//
// c.invalidate();
// c.getParent().validate();
// }
// }
// }
// }
//
// private static class ToolTipListener extends MouseMotionAdapter
// {
// public void mouseMoved(MouseEvent e)
// {
// Control c = (Control) e.getSource();
// LayoutManager lm = c.getParent().getLayout();
// if (lm instanceof SwtMigLayout) {
// String constr = ((MigLayout) lm).getComponentConstraints(c);
// c.setToolTipText((constr != null ? ("\"" + constr + "\"") : "null"));
// }
// }
// }
//
// private static class ConstraintsDialog extends JDialog implements ActionListener, KeyEventDispatcher
// {
// private static final Color ERROR_COLOR = new Color(255, 180, 180);
// private final JPanel mainPanel = new JPanel(parent, new SwtMigLayout("fillx,flowy,ins dialog",
// "[fill]",
// "2[]2"));
// final Text layoutConstrTF;
// final Text rowsConstrTF;
// final Text colsConstrTF;
// final Text componentConstrTF;
//
// private final Button okButt = new Button("OK");
// private final Button cancelButt = new Button("Cancel");
//
// private boolean okPressed = false;
//
// public ConstraintsDialog(Frame owner, String layoutConstr, String rowsConstr, String colsConstr, String compConstr)
// {
// super(owner, (compConstr != null ? "Edit Component Constraints" : "Edit Container Constraints"), true);
//
// layoutConstrTF = createConstraintField(layoutConstr);
// rowsConstrTF = createConstraintField(rowsConstr);
// colsConstrTF = createConstraintField(colsConstr);
// componentConstrTF = createConstraintField(compConstr);
//
// if (componentConstrTF != null) {
// mainPanel.add(new Label("Component Constraints"));
// mainPanel.add(componentConstrTF);
// }
//
// if (layoutConstrTF != null) {
// mainPanel.add(new Label("Container Layout Constraints"));
// mainPanel.add(layoutConstrTF);
// }
//
// if (rowsConstrTF != null) {
// mainPanel.add(new Label("Container Row Constraints"), "gaptop unrel");
// mainPanel.add(rowsConstrTF);
// }
//
// if (colsConstrTF != null) {
// mainPanel.add(new Label("Container Column Constraints"), "gaptop unrel");
// mainPanel.add(colsConstrTF);
// }
//
// mainPanel.add(okButt, "tag ok,split,flowx,gaptop 15");
// mainPanel.add(cancelButt, "tag cancel,gaptop 15");
//
// setContentPane(mainPanel);
//
// okButt.addActionListener(this);
// cancelButt.addActionListener(this);
// }
//
// public void addNotify()
// {
// super.addNotify();
// KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(this);
// }
//
// public void removeNotify()
// {
// KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(this);
// super.removeNotify();
// }
//
// public boolean dispatchKeyEvent(KeyEvent e)
// {
// if (e.getKeyCode() == KeyEvent.VK_ESCAPE)
// dispose();
// return false;
// }
//
// public void actionPerformed(ActionEvent e)
// {
// if (e.getSource() == okButt)
// okPressed = true;
// dispose();
// }
//
// private Text createConstraintField(String text)
// {
// if (text == null)
// return null;
//
// final Text tf = new Text(text, 50);
// tf.setFont(new Font("monospaced", Font.PLAIN, 12));
//
// tf.addKeyListener(new KeyAdapter() {
// public void keyPressed(KeyEvent e)
// {
// if (e.getKeyCode() == KeyEvent.VK_ENTER) {
// okButt.doClick();
// return;
// }
//
// javax.swing.Timer timer = new Timer(50, new ActionListener() {
// public void actionPerformed(ActionEvent e)
// {
// String constr = tf.getText();
// try {
// if (tf == layoutConstrTF) {
// MigLayout.validateLayoutConstraint(constr);
// } else if (tf == rowsConstrTF) {
// MigLayout.validateRowConstraints(constr);
// } else if (tf == colsConstrTF) {
// MigLayout.validateColumnConstraints(constr);
// } else if (tf == componentConstrTF) {
// MigLayout.validateComponentConstraint(constr);
// }
// tf.setBackground(Color.WHITE);
// okButt.setEnabled(true);
// } catch(Exception ex) {
// tf.setBackground(ERROR_COLOR);
// okButt.setEnabled(false);
// }
// }
// });
// timer.setRepeats(false);
// timer.start();
// }
// });
//
// return tf;
// }
//
// private boolean showDialog()
// {
// setVisible(true);
// return okPressed;
// }
// }
}
miglayout-5.1/demo/src/main/java/net/miginfocom/demo/SwtTest.java000077500000000000000000000050361324101563200250760ustar00rootroot00000000000000package net.miginfocom.demo;
import net.miginfocom.swt.MigLayout;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
public class SwtTest extends Composite
{
private Combo combo;
private Control control;
public SwtTest(Composite parent, int style, Layout layout)
{
super(parent, style);
setLayout(layout);
createControls();
}
private void createControls()
{
Label label = new Label(this, SWT.None);
label.setText("Select Control: ");
combo = new Combo(this, SWT.READ_ONLY | SWT.DROP_DOWN);
combo.setLayoutData("wrap");
combo.add("Text Box");
combo.add("Combo");
combo.add("Radio Button");
combo.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
if (control != null)
control.dispose();
switch (combo.getSelectionIndex()) {
case 0:
control = new Text(SwtTest.this, SWT.BORDER);
break;
case 1:
control = new Combo(SwtTest.this, SWT.DROP_DOWN);
break;
case 2:
control = new Button(SwtTest.this, SWT.RADIO);
break;
}
if (SwtTest.this.getLayout() instanceof GridLayout) {
GridData data = new GridData(SWT.FILL, SWT.NONE, false, false);
data.horizontalSpan = 2;
control.setLayoutData(data);
} else if (SwtTest.this.getLayout() instanceof MigLayout) {
control.setLayoutData("spanx 2, grow");
}
SwtTest.this.layout(true);
}
});
}
public static void main(String[] args)
{
Display display = new Display();
Shell shell = new Shell(display);
shell.setText("SWT");
shell.setLayout(new FillLayout());
/**
* Swap out GridLayout for MigLayout to profile and see resources cleaned up.
*/
// GridLayout layout = new GridLayout(2, false);
MigLayout layout = new MigLayout();
new SwtTest(shell, SWT.NONE, layout);
shell.open();
// Set up the event loop.
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
// If no more entries in event queue
display.sleep();
}
}
display.dispose();
}
}miglayout-5.1/demo/src/main/java/net/miginfocom/demo/Test.java000077500000000000000000000011121324101563200243670ustar00rootroot00000000000000package net.miginfocom.demo;
import net.miginfocom.swing.MigLayout;
import javax.swing.*;
import java.awt.Color;
import java.awt.HeadlessException;
import java.awt.Toolkit;
public class Test extends JFrame
{
public Test() throws HeadlessException
{
System.out.println("res " + Toolkit.getDefaultToolkit().getScreenResolution());
JPanel panel = new JPanel();
panel.setBackground(Color.BLACK);
setLayout(new MigLayout());
add(panel, "w 100mm");
pack();
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String[] argv) {
new Test();
}
}
miglayout-5.1/examples/000077500000000000000000000000001324101563200152045ustar00rootroot00000000000000miglayout-5.1/examples/pom.xml000077500000000000000000000020451324101563200165250ustar00rootroot00000000000000
4.0.0
com.miglayout
miglayout-parent
5.1-SNAPSHOT
../pom.xml
miglayout-examples
jar
MiGLayout Examples
MiGLayout - Examples for Swing and SWT
${project.groupId}
miglayout-swing
${project.version}
${project.groupId}
miglayout-swt
${project.version}
miglayout-5.1/examples/src/000077500000000000000000000000001324101563200157735ustar00rootroot00000000000000miglayout-5.1/examples/src/main/000077500000000000000000000000001324101563200167175ustar00rootroot00000000000000miglayout-5.1/examples/src/main/java/000077500000000000000000000000001324101563200176405ustar00rootroot00000000000000miglayout-5.1/examples/src/main/java/net/000077500000000000000000000000001324101563200204265ustar00rootroot00000000000000miglayout-5.1/examples/src/main/java/net/miginfocom/000077500000000000000000000000001324101563200225555ustar00rootroot00000000000000miglayout-5.1/examples/src/main/java/net/miginfocom/examples/000077500000000000000000000000001324101563200243735ustar00rootroot00000000000000miglayout-5.1/examples/src/main/java/net/miginfocom/examples/BugTestApp.java000077500000000000000000000100741324101563200272610ustar00rootroot00000000000000package net.miginfocom.examples;
import javax.swing.*;
import net.miginfocom.swing.MigLayout;
import java.awt.Color;
import java.awt.LayoutManager;
/*
* License (BSD):
* ==============
*
* Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
* 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 the MiG InfoCom AB nor 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.
*
* @version 1.0
* @author Mikael Grev, MiG InfoCom AB
* Date: 2006-sep-08
*/
/**
* @author Mikael Grev, MiG InfoCom AB
* Date: Dec 15, 2008
* Time: 7:04:50 PM
*/
public class BugTestApp
{
private static JPanel createPanel()
{
JPanel c = new JPanel();
c.setBackground(new Color(200, 255, 200));
c.setLayout(new MigLayout("debug"));
JLabel lab = new JLabel("Qwerty");
lab.setFont(lab.getFont().deriveFont(30f));
c.add(lab, "pos 0%+5 0%+5 50%-5 50%-5");
c.add(new JTextField("Qwerty"));
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLayout(new MigLayout());
f.add(c, "w 400, h 100");
f.setLocationRelativeTo(null);
f.pack();
f.setVisible(true);
return null;
}
private static JPanel createPanel2()
{
JFrame tst = new JFrame();
tst.setLayout(new MigLayout("debug, fillx","",""));
tst.add(new JTextField(),"span 2, grow, wrap");
tst.add(new JTextField(10));
tst.add(new JLabel("End"));
tst.setSize(600, 400);
tst.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
tst.setVisible(true);
return null;
}
public static void main2(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
ex.printStackTrace();
}
createPanel();
// JFrame frame = new JFrame("Bug Test App");
// frame.getContentPane().add(createPanel2());
// frame.pack();
// frame.setLocationRelativeTo(null);
// frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
// frame.setVisible(true);
}
});
}
public static void main(String[] args) throws Exception
{
// createFrame(new GridLayout(1,1));
createFrame(new MigLayout());
}
private static void createFrame(LayoutManager outerPanelLayout)
{
JPanel innerPanel = new JPanel(new MigLayout());
for (int i = 0; i < 2000; i++)
innerPanel.add(new JLabel("label nr "+i), "wrap");
JPanel outerPanel = new JPanel(outerPanelLayout);
outerPanel.add(innerPanel);
JFrame f1 = new JFrame(outerPanelLayout.getClass().getSimpleName());
f1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f1.getContentPane().add(new JScrollPane(outerPanel));
f1.pack();
f1.setLocation((int)(Math.random() * 800.0), 0);
f1.setVisible(true);
}
}
miglayout-5.1/examples/src/main/java/net/miginfocom/examples/Example.java000077500000000000000000000060141324101563200266350ustar00rootroot00000000000000package net.miginfocom.examples;
import net.miginfocom.swt.MigLayout;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
/*
* License (BSD):
* ==============
*
* Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
* 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 the MiG InfoCom AB nor 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.
*
* @version 1.0
* @author Mikael Grev, MiG InfoCom AB
* Date: 2006-sep-08
*/
public class Example
{
protected void buildControls(Composite parent)
{
parent.setLayout(new MigLayout("inset 0", "[fill, grow]", "[fill, grow]"));
Table table = new Table(parent, SWT.BORDER|SWT.H_SCROLL|SWT.V_SCROLL);
table.setLayoutData("id table, hmin 100, wmin 300");
table.setHeaderVisible(true);
table.setLinesVisible(true);
Label statusLabel = new Label(parent, SWT.BORDER);
statusLabel.setText("Label Text");
statusLabel.moveAbove(null);
statusLabel.setLayoutData("pos table.x table.y");
for (int i = 0; i < 10; i++) {
TableItem ti = new TableItem(table, SWT.NONE);
ti.setText("item #" + i);
}
}
public static void main(String[] args)
{
final Display display = new Display();
final Shell shell = new Shell(display);
new Example().buildControls(shell);
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
}
miglayout-5.1/examples/src/main/java/net/miginfocom/examples/Example01.java000077500000000000000000000055231324101563200270020ustar00rootroot00000000000000package net.miginfocom.examples;
import javax.swing.*;
import net.miginfocom.swing.MigLayout;
/*
* License (BSD):
* ==============
*
* Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
* 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 the MiG InfoCom AB nor 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.
*
* @version 1.0
* @author Mikael Grev, MiG InfoCom AB
* Date: 2006-sep-08
*/
/**
*/
public class Example01
{
private static JPanel createPanel()
{
JPanel panel = new JPanel(new MigLayout());
panel.add(new JLabel("First Name"));
panel.add(new JTextField(10));
panel.add(new JLabel("Surname"), "gap unrelated"); // Unrelated size is resolved per platform
panel.add(new JTextField(10), "wrap"); // Wraps to the next row
panel.add(new JLabel("Address"));
panel.add(new JTextField(), "span, grow"); // Spans cells in row and grows to fit that
return panel;
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Example 01");
frame.getContentPane().add(createPanel());
frame.pack();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
}
miglayout-5.1/examples/src/main/java/net/miginfocom/examples/Example02.java000077500000000000000000000061351324101563200270030ustar00rootroot00000000000000package net.miginfocom.examples;
import javax.swing.*;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.EtchedBorder;
import net.miginfocom.swing.MigLayout;
/*
* License (BSD):
* ==============
*
* Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
* 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 the MiG InfoCom AB nor 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.
*
* @version 1.0
* @author Mikael Grev, MiG InfoCom AB
* Date: 2006-sep-08
*/
public class Example02
{
private static JPanel createPanel()
{
JPanel panel = new JPanel(new MigLayout());
panel.add(createLabel("West Panel"), "dock west");
panel.add(createLabel("North 1 Panel"), "dock north");
panel.add(createLabel("North 2 Panel"), "dock north");
panel.add(createLabel("South Panel"), "dock south");
panel.add(createLabel("East Panel"), "dock east");
panel.add(createLabel("Center Panel"), "grow, push"); // "dock center" from v3.0
return panel;
}
private static JLabel createLabel(String text)
{
JLabel label = new JLabel(text);
label.setHorizontalAlignment(JLabel.CENTER);
label.setBorder(new CompoundBorder(new EtchedBorder(), new EmptyBorder(5, 10, 5, 10)));
return label;
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Example 02");
frame.getContentPane().add(createPanel());
frame.pack();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
}
miglayout-5.1/examples/src/main/java/net/miginfocom/examples/ExampleGood.java000077500000000000000000000060111324101563200274430ustar00rootroot00000000000000package net.miginfocom.examples;
import net.miginfocom.swt.MigLayout;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
/*
* License (BSD):
* ==============
*
* Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
* 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 the MiG InfoCom AB nor 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.
*
* @version 1.0
* @author Mikael Grev, MiG InfoCom AB
* Date: 2006-sep-08
*/
public class ExampleGood
{
protected void buildControls(Composite parent)
{
parent.setLayout(new MigLayout("inset 0", "[fill, grow]", "[fill, grow]"));
Table table = new Table(parent, SWT.BORDER|SWT.H_SCROLL|SWT.V_SCROLL);
table.setLayoutData("id table, hmin 100, wmin 300");
table.setHeaderVisible(true);
table.setLinesVisible(true);
Label statusLabel = new Label(parent, SWT.BORDER);
statusLabel.setText("Label Text");
statusLabel.moveAbove(null);
statusLabel.setLayoutData("pos 0 0");
for (int i = 0; i < 10; i++)
{
TableItem ti = new TableItem(table, SWT.NONE);
ti.setText("item #" + i);
}
}
public static void main(String[] args)
{
final Display display = new Display();
final Shell shell = new Shell(display);
new ExampleGood().buildControls(shell);
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
}
miglayout-5.1/examples/src/main/java/net/miginfocom/examples/JavaOneShrink.java000077500000000000000000000075511324101563200277530ustar00rootroot00000000000000package net.miginfocom.examples;
import javax.swing.*;
import javax.swing.border.LineBorder;
import net.miginfocom.swing.MigLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
/*
* License (BSD):
* ==============
*
* Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
* 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 the MiG InfoCom AB nor 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.
*
* @version 1.0
* @author Mikael Grev, MiG InfoCom AB
* Date: 2006-sep-08
*/
/**
* @author Mikael Grev, MiG InfoCom AB
* Date: Apr 20, 2008
* Time: 10:32:58 PM
*/
public class JavaOneShrink
{
private static JComponent createPanel(String ... args)
{
JPanel panel = new JPanel(new MigLayout("nogrid"));
panel.add(createTextArea(args[0].replace(", ", "\n ")), args[0] + ", w 200");
panel.add(createTextArea(args[1].replace(", ", "\n ")), args[1] + ", w 200");
panel.add(createTextArea(args[2].replace(", ", "\n ")), args[2] + ", w 200");
panel.add(createTextArea(args[3].replace(", ", "\n ")), args[3] + ", w 200");
JSplitPane gSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, panel, new JPanel());
gSplitPane.setOpaque(true);
gSplitPane.setBorder(null);
return gSplitPane;
}
private static JComponent createTextArea(String s)
{
JTextArea ta = new JTextArea("\n\n " + s, 6, 20);
ta.setBorder(new LineBorder(new Color(200, 200, 200)));
ta.setFont(new Font("Helvetica", Font.BOLD, 20));
ta.setMinimumSize(new Dimension(20, 20));
ta.setFocusable(false);
return ta;
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("JavaOne Shrink Demo");
Container cp = frame.getContentPane();
cp.setLayout(new MigLayout("wrap 1"));
cp.add(createPanel("", "", "", ""));
cp.add(createPanel("shrinkprio 1", "shrinkprio 1", "shrinkprio 2", "shrinkprio 3"));
cp.add(createPanel("shrink 25", "shrink 50", "shrink 75", "shrink 100"));
cp.add(createPanel("shrinkprio 1, shrink 50", "shrinkprio 1, shrink 100", "shrinkprio 2, shrink 50", "shrinkprio 2, shrink 100"));
frame.pack();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
miglayout-5.1/examples/src/main/java/net/miginfocom/examples/MigLayoutBug.java000066400000000000000000000016711324101563200276130ustar00rootroot00000000000000package net.miginfocom.examples;
import net.miginfocom.swing.MigLayout;
import javax.swing.*;
import java.awt.Color;
/**
* @author Mikael Grev, MiG InfoCom AB
* Date: 14-06-03
* Time: 21:31
*/
public class MigLayoutBug
{
public static void main(String[] args)
{
JFrame frame = new JFrame();
frame.setSize(500, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
JPanel mainPanel = new JPanel(new MigLayout("debug", "", ""));
JPanel greyPanel = new JPanel();
greyPanel.setBackground(Color.GRAY);
JTextArea label = new JTextArea("text \n" +
"over \n" +
"two \n" +
"rows");
mainPanel.add(label, "spany 2");
mainPanel.add(new JLabel("First row"), "wrap");
mainPanel.add(new JLabel("Second row"), "wrap");
mainPanel.add(greyPanel, "spanx 2, pushy, grow");
frame.setContentPane(mainPanel);
frame.setVisible(true);
}
}
miglayout-5.1/examples/src/main/java/net/miginfocom/examples/SwtTest.java000077500000000000000000000071701324101563200266630ustar00rootroot00000000000000package net.miginfocom.examples;
import net.miginfocom.swt.MigLayout;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
/*
* License (BSD):
* ==============
*
* Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
* 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 the MiG InfoCom AB nor 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.
*
* @version 1.0
* @author Mikael Grev, MiG InfoCom AB
* Date: 2006-sep-08
*/
public class SwtTest
{
public static void main(final String[] args)
{
final Display display = new Display();
final Shell shell = new Shell(display);
shell.setLayout(new FillLayout(SWT.VERTICAL));
final Composite cmpLabels = new Composite(shell, SWT.BORDER);
cmpLabels.setLayout(new MigLayout("wrap 5"));
final Label l0 = new Label(cmpLabels, SWT.NONE);
l0.setText("L 0");
final Label l1 = new Label(cmpLabels, SWT.NONE);
final Label l2 = new Label(cmpLabels, SWT.NONE);
l2.setText("L 2");
final Label l3 = new Label(cmpLabels, SWT.NONE);
final Label l4 = new Label(cmpLabels, SWT.NONE);
l4.setText("L 4");
final Composite cmpButtons = new Composite(shell, SWT.NONE);
cmpButtons.setLayout(new FillLayout());
final Button btn1 = new Button(cmpButtons, SWT.PUSH);
btn1.setText("Set 1");
btn1.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(final SelectionEvent e)
{
l3.setText("");
l1.setText("Some Text");
cmpLabels.layout();
cmpLabels.redraw();
}
});
final Button btn3 = new Button(cmpButtons, SWT.PUSH);
btn3.setText("Set 3");
btn3.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(final SelectionEvent e)
{
l1.setText("");
l3.setText("Some Text");
cmpLabels.layout();
cmpLabels.redraw();
}
});
shell.setSize(300, 100);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
}miglayout-5.1/examples/src/main/java/net/miginfocom/examples/VisualPaddingOSX.java000077500000000000000000000134301324101563200303660ustar00rootroot00000000000000package net.miginfocom.examples;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import javax.swing.border.MatteBorder;
import net.miginfocom.swing.MigLayout;
import java.awt.Color;
import java.awt.image.BufferedImage;
public class VisualPaddingOSX extends JFrame
{
public VisualPaddingOSX()
{
super("MigLayout Test");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new MigLayout("nogrid, debug"));
String cc = "";
add(createButton(null), cc);
add(createButton("square"), cc);
add(createButton("gradient"), cc);
add(createButton("bevel"), cc);
add(createButton("textured"), cc);
add(createButton("roundRect"), cc);
add(createButton("recessed"), cc);
add(createButton("help"), cc);
add(createIconButton(null), cc + ", newline");
add(createIconButton("square"), cc);
add(createIconButton("gradient"), cc);
add(createIconButton("bevel"), cc);
add(createIconButton("textured"), cc);
add(createIconButton("roundRect"), cc);
add(createIconButton("recessed"), cc);
add(createIconButton("help"), cc);
add(createToggleButton(null), cc + ", newline");
add(createToggleButton("square"), cc);
add(createToggleButton("gradient"), cc);
add(createToggleButton("bevel"), cc);
add(createToggleButton("textured"), cc);
add(createToggleButton("roundRect"), cc);
add(createToggleButton("recessed"), cc);
add(createToggleButton("help"), cc);
add(createBorderButton("button", null), cc + ", newline");
add(createBorderButton("button", new LineBorder(Color.BLACK)), cc);
add(createBorderButton("button", new MatteBorder(3, 3, 3, 3, Color.BLACK)), cc);
add(createCombo("JComboBox.isPopDown", false), cc + ", newline");
add(createCombo("JComboBox.isSquare", false), cc);
add(createCombo(null, false), "");
add(createCombo("JComboBox.isPopDown", true), cc + ", newline");
add(createCombo("JComboBox.isSquare", true), cc);
add(createCombo(null, true), cc);
JTextField ta = new JTextField("No Border");
ta.setBorder(new EmptyBorder(0, 0, 0, 0));
add(ta, cc + ", newline");
JTextField tfo = new JTextField("Opaque");
tfo.setOpaque(true);
add(tfo, cc);
add(new JTextArea("A text"), cc);
add(new JTextField("A text"), cc);
add(new JScrollPane(new JTextPane()), cc);
add(new JScrollPane(new JTextArea("A text", 1, 20)), cc);
JList list = new JList(new Object[] {"A text"});
list.setVisibleRowCount(1);
add(new JScrollPane(list), cc);
add(new JTextField("Compared to"), cc + ", newline");
add(new JSpinner(new SpinnerNumberModel(1, 1, 10000, 1)), cc);
add(new JSpinner(new SpinnerDateModel()), cc);
add(new JSpinner(new SpinnerListModel(new Object[]{"One", "Two", "Fifteen"})), cc);
JSpinner spinner = new JSpinner();
spinner.setEditor(new JTextField());
add(spinner, cc);
add(createToggle("toggle", null, true, new EmptyBorder(0, 0, 0, 0)), cc + ", newline");
add(createToggle("toggle", null, true, null), cc);
add(createToggle("toggle", "regular", true, null), cc);
add(createToggle("toggle", "small", true, null), cc);
add(createToggle("toggle", "mini", true, null), cc);
add(createToggle("toggle", null, false, new EmptyBorder(0, 0, 0, 0)), cc);
add(createToggle("toggle", null, false, null), cc);
add(createToggle("toggle", "regular", false, null), cc);
add(createToggle("toggle", "small", false, null), cc);
add(createToggle("toggle", "mini", false, null), cc);
add(createTabbedPane(), cc + ", newline, growx");
pack();
setLocationRelativeTo(null);
}
private JToggleButton createToggle(String name, String size, boolean radio, Border border)
{
JToggleButton button = radio ? new JRadioButton(name) : new JCheckBox(name);
if (size != null)
button.putClientProperty("JComponent.sizeVariant", size);
button.setFocusable(false);
if (border != null)
button.setBorder(border);
return button;
}
private JButton createButton(String type)
{
String name = String.valueOf(type);
if (name.equals("help"))
name = "";
JButton button = new JButton(name);
button.setDefaultCapable(false);
button.setFocusable(false);
if (type != null && type.equals("...") == false)
button.putClientProperty("JButton.buttonType", type);
return button;
}
private JButton createIconButton(String type)
{
String name = String.valueOf(type);
if (name.equals("help"))
name = "";
JButton button = new JButton(name);
button.setIcon(new ImageIcon(new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB)));
button.setDefaultCapable(false);
button.setFocusable(false);
if (type != null && type.equals("...") == false)
button.putClientProperty("JButton.buttonType", type);
return button;
}
private JToggleButton createToggleButton(String type)
{
String name = String.valueOf(type);
if (name.equals("help"))
name = "";
JToggleButton button = new JToggleButton(name);
button.setFocusable(false);
if (type != null)
button.putClientProperty("JButton.buttonType", type);
return button;
}
private JButton createBorderButton(String name, Border border)
{
JButton button = new JButton(name);
button.setDefaultCapable(false);
button.setFocusable(false);
button.setBorder(border);
return button;
}
private JComboBox createCombo(String key, boolean editable)
{
JComboBox comboBox = new JComboBox(new Object[]{ String.valueOf(key)});
comboBox.setFocusable(editable);
comboBox.setEditable(editable);
if (key != null)
comboBox.putClientProperty(key, Boolean.TRUE);
return comboBox;
}
private JTabbedPane createTabbedPane()
{
JTabbedPane tabbedPane = new JTabbedPane();
tabbedPane.addTab("tab1", new JLabel("tab1"));
tabbedPane.addTab("tab2", new JLabel("tab2"));
return tabbedPane;
}
public static void main(String args[])
{
VisualPaddingOSX migTest = new VisualPaddingOSX();
migTest.setVisible(true);
}
}miglayout-5.1/ideutil/000077500000000000000000000000001324101563200150255ustar00rootroot00000000000000miglayout-5.1/ideutil/pom.xml000077500000000000000000000015351324101563200163510ustar00rootroot00000000000000
4.0.0
com.miglayout
miglayout-parent
5.1-SNAPSHOT
../pom.xml
miglayout-ideutil
jar
MiGLayout IDEUtil
MiGLayout - IDEUtil class for EDI integration
${project.groupId}
miglayout-core
${project.version}
miglayout-5.1/ideutil/src/000077500000000000000000000000001324101563200156145ustar00rootroot00000000000000miglayout-5.1/ideutil/src/main/000077500000000000000000000000001324101563200165405ustar00rootroot00000000000000miglayout-5.1/ideutil/src/main/java/000077500000000000000000000000001324101563200174615ustar00rootroot00000000000000miglayout-5.1/ideutil/src/main/java/net/000077500000000000000000000000001324101563200202475ustar00rootroot00000000000000miglayout-5.1/ideutil/src/main/java/net/miginfocom/000077500000000000000000000000001324101563200223765ustar00rootroot00000000000000miglayout-5.1/ideutil/src/main/java/net/miginfocom/layout/000077500000000000000000000000001324101563200237135ustar00rootroot00000000000000miglayout-5.1/ideutil/src/main/java/net/miginfocom/layout/IDEUtil.java000077500000000000000000000717571324101563200260410ustar00rootroot00000000000000package net.miginfocom.layout;
import java.util.HashMap;
/*
* License (BSD):
* ==============
*
* Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
* 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 the MiG InfoCom AB nor 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.
*
* @version 1.0
* @author Mikael Grev, MiG InfoCom AB
* Date: 2006-sep-08
*/
/** This class contains static methods to be used by IDE vendors to convert to and from String/API constraints.
*
* Note that {@link LayoutUtil#setDesignTime(ContainerWrapper, boolean)} should be set to true
for this class'
* methods to work.
*/
public class IDEUtil
{
/** A direct reference to the corresponding value for predefined UnitValues in {@link UnitValue}.
*/
public static final UnitValue ZERO = UnitValue.ZERO;
/** A direct reference to the corresponding value for predefined UnitValues in {@link UnitValue}.
*/
public static final UnitValue TOP = UnitValue.TOP;
/** A direct reference to the corresponding value for predefined UnitValues in {@link UnitValue}.
*/
public static final UnitValue LEADING = UnitValue.LEADING;
/** A direct reference to the corresponding value for predefined UnitValues in {@link UnitValue}.
*/
public static final UnitValue LEFT = UnitValue.LEFT;
/** A direct reference to the corresponding value for predefined UnitValues in {@link UnitValue}.
*/
public static final UnitValue CENTER = UnitValue.CENTER;
/** A direct reference to the corresponding value for predefined UnitValues in {@link UnitValue}.
*/
public static final UnitValue TRAILING = UnitValue.TRAILING;
/** A direct reference to the corresponding value for predefined UnitValues in {@link UnitValue}.
*/
public static final UnitValue RIGHT = UnitValue.RIGHT;
/** A direct reference to the corresponding value for predefined UnitValues in {@link UnitValue}.
*/
public static final UnitValue BOTTOM = UnitValue.BOTTOM;
/** A direct reference to the corresponding value for predefined UnitValues in {@link UnitValue}.
*/
public static final UnitValue LABEL = UnitValue.LABEL;
/** A direct reference to the corresponding value for predefined UnitValues in {@link UnitValue}.
*/
public static final UnitValue INF = UnitValue.INF;
/** A direct reference to the corresponding value for predefined UnitValues in {@link UnitValue}.
*/
public static final UnitValue BASELINE_IDENTITY = UnitValue.BASELINE_IDENTITY;
private final static String[] X_Y_STRINGS = new String[] {"x", "y", "x2", "y2"};
/** Returns the version of IDEUtil
* @return The version.
*/
public String getIDEUtilVersion()
{
return "1.0";
}
/** Returns the grid cells that the components in parentContainer
has.
* @param parentContainer The parent container. It is an object since MigLayout is GUI toolkit
* independent.
* @return A new hashmap with the components mapped to an array [x, y, spanx, spany].
*
* Dock components will always have x and y less than -30000 or more than 30000. This is since they
* are actually part of the grid, but on the outer edges.
*
* Components that span the "rest of the row/column" have really large span values. Actually 30000-x or
* 30000-y.
*
* Generally, the grid does not need to have the upper left at 0, 0. Though it normally does if you
* don't set the cells explicitly to other values. Rows and columns that are completely empty and
* that does not have an explicit row/column constraint will be totally disregarded.
*/
public static HashMap getGridPositions(Object parentContainer)
{
return Grid.getGridPositions(parentContainer);
}
/** Returns the sizes of the rows and gaps for a container.
* There will be two arrays returned [0] and [1].
*
* The first array will be the indexes of the rows where indexes that
* are less than 30000 or larger than 30000 is docking rows. There might be extra docking rows that aren't
* visible but they always have size 0. Non docking indexes will probably always be 0, 1, 2, 3, etc..
*
* The second array is the sizes of the form:
* [left inset][row size 1][gap 1][row size 2][gap 2][row size n][right inset]
.
*
* The returned sizes will be the ones calculated in the last layout cycle.
* @param parentContainer The container to return the row sizes and gaps for. In Swing it will be a {@link java.awt.Container} and
* in SWT it will be a {@link org.eclipse.swt.widgets.Composite}.
* @return The sizes or null
if {@link LayoutUtil#isDesignTime(ContainerWrapper)} is false
or
* parentContainer
does not have a MigLayout layout manager.
* The returned sizes will be the ones calculated in the last layout cycle.
* @see LayoutUtil#isDesignTime(ContainerWrapper)
*/
public static int[][] getRowSizes(Object parentContainer)
{
return Grid.getSizesAndIndexes(parentContainer, true);
}
/** Returns the sizes of the columns and gaps for a container.
* There will be two arrays returned [0] and [1].
*
* The first array will be the indexes of the columns where indexes that
* are less than 30000 or larger than 30000 is docking columns. There might be extra docking columns that aren't
* visible but they always have size 0. Non docking indexes will probably always be 0, 1, 2, 3, etc..
*
* The second array is the sizes of the form:
* [top inset][column size 1][gap 1][column size 2][gap 2][column size n][bottom inset]
.
*
* The returned sizes will be the ones calculated in the last layout cycle.
* @param parentContainer The container to return the column sizes and gaps for. In Swing it will be a {@link java.awt.Container} and
* in SWT it will be a {@link org.eclipse.swt.widgets.Composite}.
* @return The sizes and indexes or null
if {@link LayoutUtil#isDesignTime(ContainerWrapper)} is false
or
* parentContainer
does not have a MigLayout layout manager.
* The returned sizes will be the ones calculated in the last layout cycle.
* @see LayoutUtil#isDesignTime(ContainerWrapper)
*/
public static int[][] getColumnSizes(Object parentContainer)
{
return Grid.getSizesAndIndexes(parentContainer, false);
}
/** Returns the a constraint string that can be re-parsed to be the exact same AxisConstraint.
* @param ac The axis constraint to return as a constraint string.
* @param asAPI If the returned string should be of API type (e.g. .flowX().gap("rel").align("right")) or
* as a String type (e.g. "flowx, gap rel, right").
* @param isCols The the constraint should be returned for columns rather than rows.
* @return A String. Never null
.
*/
public static String getConstraintString(AC ac, boolean asAPI, boolean isCols)
{
StringBuffer sb = new StringBuffer(32);
DimConstraint[] dims = ac.getConstaints();
BoundSize defGap = isCols ? PlatformDefaults.getGridGapX() : PlatformDefaults.getGridGapY();
for (int i = 0; i < dims.length; i++) {
DimConstraint dc = dims[i];
addRowDimConstraintString(dc, sb, asAPI);
if (i < dims.length - 1) {
BoundSize gap = dc.getGapAfter();
if (gap == defGap || gap == null)
gap = dims[i + 1].getGapBefore();
if (gap != null) {
String gapStr = getBS(gap);
if (asAPI) {
sb.append(".gap(\"").append(gapStr).append("\")");
} else {
sb.append(gapStr);
}
} else {
if (asAPI)
sb.append(".gap()");
}
}
}
return sb.toString();
}
/** Adds the a constraint string that can be re-parsed to be the exact same DimConstraint.
* @param dc The layout constraint to return as a constraint string.
* @param asAPI If the returned string should be of API type (e.g. .flowX().gap("rel").align("right")) or
* as a String type (e.g. "flowx, gap rel, right").
*/
private static void addRowDimConstraintString(DimConstraint dc, StringBuffer sb, boolean asAPI)
{
int gp = dc.getGrowPriority();
int firstComma = sb.length();
BoundSize size = dc.getSize();
if (size.isUnset() == false) {
if (asAPI) {
sb.append(".size(\"").append(getBS(size)).append("\")");
} else {
sb.append(',').append(getBS(size));
}
}
if (gp != 100) {
if (asAPI) {
sb.append(".growPrio(").append(gp).append(")");
} else {
sb.append(",growprio ").append(gp);
}
}
Float gw = dc.getGrow();
if (gw != null) {
String g = gw != 100f ? floatToString(gw, asAPI) : "";
if (asAPI) {
if (g.length() == 0) {
sb.append(".grow()");
} else {
sb.append(".grow(").append(g).append(")");
}
} else {
sb.append(",grow").append(g.length() > 0 ? (" " + g) : "");
}
}
int sp = dc.getShrinkPriority();
if (sp != 100) {
if (asAPI) {
sb.append(".shrinkPrio(").append(sp).append(")");
} else {
sb.append(",shrinkprio ").append(sp);
}
}
Float sw = dc.getShrink();
if (sw != null && sw.intValue() != 100) {
String s = floatToString(sw, asAPI);
if (asAPI) {
sb.append(".shrink(").append(s).append(")");
} else {
sb.append(",shrink ").append(s);
}
}
String eg = dc.getEndGroup();
if (eg != null) {
if (asAPI) {
sb.append(".endGroup(\"").append(eg).append("\")");
} else {
sb.append(",endgroup ").append(eg);
}
}
String sg = dc.getSizeGroup();
if (sg != null) {
if (asAPI) {
sb.append(".sizeGroup(\"").append(sg).append("\")");
} else {
sb.append(",sizegroup ").append(sg);
removeTrailingSpace(sb);
}
}
UnitValue al = dc.getAlign();
if (al != null) {
if (asAPI) {
sb.append(".align(\"").append(getUV(al)).append("\")");
} else {
String s = getUV(al);
String alKw = (s.equals("top") || s.equals("bottom") || s.equals("left") || s.equals("label") ||
s.equals("leading") || s.equals("center") || s.equals("trailing") ||
s.equals("right") || s.equals("baseline")) ? "" : "align ";
sb.append(',').append(alKw).append(s);
}
}
if (dc.isNoGrid()) {
if (asAPI) {
sb.append(".noGrid()");
} else {
sb.append(",nogrid");
}
}
if (dc.isFill()) {
if (asAPI) {
sb.append(".fill()");
} else {
sb.append(",fill");
}
}
if (asAPI == false) {
if (sb.length() > firstComma) {
sb.setCharAt(firstComma, '[');
sb.append(']');
} else {
sb.append("[]");
}
}
}
/** Returns the a constraint string that can be re-parsed to be the exact same DimConstraint.
* @param dc The layout constraint to return as a constraint string.
* @param asAPI If the returned string should be of API type (e.g. .flowX().gap("rel").align("right")) or
* as a String type (e.g. "flowx, gap rel, right").
* @param isHor The the DimConstraint is decoration something horizontal (column or x).
* @param noGrowAdd If true
no grow constraints will be added.
* @return A constraint string. Never null
.
*/
private static void addComponentDimConstraintString(DimConstraint dc, StringBuffer sb, boolean asAPI, boolean isHor, boolean noGrowAdd)
{
int gp = dc.getGrowPriority();
if (gp != 100) {
if (asAPI) {
sb.append(isHor ? ".growPrioX(" : ".growPrioY(").append(gp).append(')');
} else {
sb.append(isHor ? ",growpriox " : ",growprioy ").append(gp);
}
}
if (noGrowAdd == false) {
Float gw = dc.getGrow();
if (gw != null) {
String g = gw != 100f ? floatToString(gw, asAPI) : "";
if (asAPI) {
sb.append(isHor ? ".growX(" : ".growY(").append(g).append(')');
} else {
sb.append(isHor ? ",growx" : ",growy").append(g.length() > 0 ? (" " + g) : "");
}
}
}
int sp = dc.getShrinkPriority();
if (sp != 100) {
if (asAPI) {
sb.append(isHor ? ".shrinkPrioX(" : ".shrinkPrioY(").append(sp).append(')');
} else {
sb.append(isHor ? ",shrinkpriox " : ",shrinkprioy ").append(sp);
}
}
Float sw = dc.getShrink();
if (sw != null && sw.intValue() != 100) {
String s = floatToString(sw, asAPI);
if (asAPI) {
sb.append(isHor ? ".shrinkX(" : ".shrinkY(").append(s).append(')');
} else {
sb.append(isHor ? ",shrinkx " : ",shrinky ").append(s);
}
}
String eg = dc.getEndGroup();
if (eg != null) {
if (asAPI) {
sb.append(isHor ? ".endGroupX(\"" : ".endGroupY(\"").append(eg).append("\")");
} else {
sb.append(isHor ? ",endgroupx " : ",endgroupy ").append(eg);
removeTrailingSpace(sb);
}
}
String sg = dc.getSizeGroup();
if (sg != null) {
if (asAPI) {
sb.append(isHor ? ".sizeGroupX(\"" : ".sizeGroupY(\"").append(sg).append("\")");
} else {
sb.append(isHor ? ",sizegroupx " : ",sizegroupy ").append(sg);
removeTrailingSpace(sb);
}
}
appendBoundSize(dc.getSize(), sb, isHor, asAPI);
UnitValue al = dc.getAlign();
if (al != null) {
if (asAPI) {
sb.append(isHor ? ".alignX(\"" : ".alignY(\"").append(getUV(al)).append("\")");
} else {
sb.append(isHor ? ",alignx " : ",aligny ").append(getUV(al));
}
}
BoundSize gapBef = dc.getGapBefore();
BoundSize gapAft= dc.getGapAfter();
if (gapBef != null || gapAft != null) {
if (asAPI) {
sb.append(isHor ? ".gapX(" : ".gapY(").append(getBS(gapBef, asAPI)).append(", ").append(getBS(gapAft, asAPI)).append(")");
} else {
sb.append(isHor ? ",gapx " : ",gapy ").append(getBS(gapBef));
if (gapAft != null)
sb.append(' ').append(getBS(gapAft));
}
}
}
private static void appendBoundSize(BoundSize size, StringBuffer sb, boolean isHor, boolean asAPI)
{
if (size.isUnset() == false) {
if (size.getPreferred() == null) {
if (size.getMin() == null) {
if (asAPI) {
sb.append(isHor ? ".maxWidth(\"" : ".maxHeight(\"").append(getUV(size.getMax())).append("\")");
} else {
sb.append(isHor ? ",wmax " : ",hmax ").append(getUV(size.getMax()));
}
} else if (size.getMax() == null) {
if (asAPI) {
sb.append(isHor ? ".minWidth(\"" : ".minHeight(\"").append(getUV(size.getMin())).append("\")");
} else {
sb.append(isHor ? ",wmin " : ",hmin ").append(getUV(size.getMin()));
}
} else { // None are null
if (asAPI) {
sb.append(isHor ? ".width(\"" : ".height(\"").append(getUV(size.getMin())).append("::").append(getUV(size.getMax())).append("\")");
} else {
sb.append(isHor ? ",width " : ",height ").append(getUV(size.getMin())).append("::").append(getUV(size.getMax()));
}
}
} else {
if (asAPI) {
sb.append(isHor ? ".width(\"" : ".height(\"").append(getBS(size)).append("\")");
} else {
sb.append(isHor ? ",width " : ",height ").append(getBS(size));
}
}
}
}
/** Returns the a constraint string that can be re-parsed to be the exact same LayoutConstraint.
* @param cc The component constraint to return as a constraint string.
* @param asAPI If the returned string should be of API type (e.g. .flowX().gap("rel").align("right")) or
* as a String type (e.g. "flowx, gap rel, right").
* @return A String. Never null
.
*/
public static String getConstraintString(CC cc, boolean asAPI)
{
StringBuffer sb = new StringBuffer(16);
if (cc.isNewline()) {
sb.append(asAPI ? ".newline(" : ",newline");
BoundSize newlineGapSize = cc.getNewlineGapSize();
if (newlineGapSize != null)
sb.append(asAPI ? "" : " ").append(getBS(newlineGapSize, asAPI));
if (asAPI)
sb.append(')');
}
if (cc.isExternal())
sb.append(asAPI ? ".external()" : ",external");
Boolean flowX = cc.getFlowX();
if (flowX != null) {
if (asAPI) {
sb.append(flowX ? ".flowX()" : ".flowY()");
} else {
sb.append(flowX ? ",flowx" : ",flowy");
}
}
UnitValue[] pad = cc.getPadding();
if (pad != null) {
sb.append(asAPI ? ".pad(\"" : ",pad ");
for (int i = 0; i < pad.length; i++)
sb.append(getUV(pad[i])).append(i < pad.length - 1 ? " " : "");
if (asAPI)
sb.append("\")");
}
UnitValue[] pos = cc.getPos();
if (pos != null) {
if (cc.isBoundsInGrid()) {
for (int i = 0; i < 4; i++) {
if (pos[i] != null) {
if (asAPI) {
sb.append('.').append(X_Y_STRINGS[i]).append("(\"").append(getUV(pos[i])).append("\")");
} else {
sb.append(',').append(X_Y_STRINGS[i]).append(' ').append(getUV(pos[i]));
}
}
}
} else {
sb.append(asAPI ? ".pos(" : ",pos ");
int iSz = (pos[2] != null || pos[3] != null) ? 4 : 2; // "pos x y" vs "pos x1 y1 x2 y2".
for (int i = 0; i < iSz; i++)
sb.append(getUV(pos[i], asAPI)).append(i < iSz - 1 ? (asAPI ? ", " : " ") : "");
if (asAPI)
sb.append(")");
}
}
String id = cc.getId();
if (id != null) {
if (asAPI) {
sb.append(".id(\"").append(id).append("\")");
} else {
sb.append(",id ").append(id);
}
}
String tag = cc.getTag();
if (tag != null) {
if (asAPI) {
sb.append(".tag(\"").append(tag).append("\")");
} else {
sb.append(",tag ").append(tag);
}
}
int hideMode = cc.getHideMode();
if (hideMode >= 0) {
if (asAPI) {
sb.append(".hideMode(").append(hideMode).append(')');
} else {
sb.append(",hidemode ").append(hideMode);
}
}
int skip = cc.getSkip();
if (skip > 0) {
if (asAPI) {
sb.append(".skip(").append(skip).append(')');
} else {
sb.append(",skip ").append(skip);
}
}
int split = cc.getSplit();
if (split > 1) {
String s = split == LayoutUtil.INF ? "" : String.valueOf(split);
if (asAPI) {
sb.append(".split(").append(s).append(')');
} else {
sb.append(",split ").append(s);
removeTrailingSpace(sb);
}
}
int cx = cc.getCellX();
int cy = cc.getCellY();
int spanX = cc.getSpanX();
int spanY = cc.getSpanY();
if (cx >= 0 && cy >= 0) {
if (asAPI) {
sb.append(".cell(").append(cx).append(", ").append(cy);
if (spanX > 1 || spanY > 1)
sb.append(", ").append(spanX).append(", ").append(spanY);
sb.append(')');
} else {
sb.append(",cell ").append(cx).append(' ').append(cy);
if (spanX > 1 || spanY > 1)
sb.append(' ').append(spanX).append(' ').append(spanY);
}
} else if (spanX > 1 || spanY > 1) {
if (spanX > 1 && spanY > 1) {
sb.append(asAPI ? ".span(" : ",span ").append(spanX).append(asAPI ? ", " : " ").append(spanY);
} else if (spanX > 1) {
sb.append(asAPI ? ".spanX(" : ",spanx ").append(spanX == LayoutUtil.INF ? "" : (String.valueOf(spanX)));
} else if (spanY > 1) {
sb.append(asAPI ? ".spanY(" : ",spany ").append(spanY == LayoutUtil.INF ? "" : (String.valueOf(spanY)));
}
if (asAPI)
sb.append(')');
else
removeTrailingSpace(sb);
}
Float pushX = cc.getPushX();
Float pushY = cc.getPushY();
if (pushX != null || pushY != null) {
if (pushX != null && pushY != null) {
sb.append(asAPI ? ".push(" : ",push ");
if (pushX != 100.0 || pushY != 100.0)
sb.append(floatObjectToString(pushX, asAPI)).append(asAPI ? ", " : " ").append(floatObjectToString(pushY, asAPI));
} else if (pushX != null) {
sb.append(asAPI ? ".pushX(" : ",pushx ").append(pushX == 100 ? "" : (floatObjectToString(pushX, asAPI)));
} else if (pushY != null) {
sb.append(asAPI ? ".pushY(" : ",pushy ").append(pushY == 100 ? "" : (floatObjectToString(pushY, asAPI)));
}
if (asAPI)
sb.append(')');
else
removeTrailingSpace(sb);
}
int dock = cc.getDockSide();
if (dock >= 0) {
String ds = CC.DOCK_SIDES[dock];
if (asAPI) {
sb.append(".dock").append(Character.toUpperCase(ds.charAt(0))).append(ds.substring(1)).append("()");
} else {
sb.append(",").append(ds);
}
}
boolean noGrowAdd = cc.getHorizontal().getGrow() != null && cc.getHorizontal().getGrow().intValue() == 100 &&
cc.getVertical().getGrow() != null && cc.getVertical().getGrow().intValue() == 100;
addComponentDimConstraintString(cc.getHorizontal(), sb, asAPI, true, noGrowAdd);
addComponentDimConstraintString(cc.getVertical(), sb, asAPI, false, noGrowAdd);
if (noGrowAdd)
sb.append(asAPI ? ".grow()" : ",grow"); // Combine ".growX().growY()" into ".grow()".
if (cc.isWrap()) {
BoundSize wrap = cc.getWrapGapSize();
if (wrap != null)
sb.append(asAPI ? ".wrap(\"" : ",wrap ").append(getBS(wrap)).append(asAPI ? "\")" : "");
else
sb.append(asAPI ? ".wrap()" : ",wrap");
}
String s = sb.toString();
return s.length() == 0 || s.charAt(0) != ',' ? s : s.substring(1);
}
/** Returns the a constraint string that can be re-parsed to be the exact same LayoutConstraint.
* @param lc The layout constraint to return as a constraint string.
* @param asAPI If the returned string should be of API type (e.g. .flowX().gap("rel").align("right")) or
* as a String type (e.g. "flowx, gap rel, right").
* @return A String. Never null
.
*/
public static String getConstraintString(LC lc, boolean asAPI)
{
StringBuffer sb = new StringBuffer(16);
if (lc.isFlowX() == false)
sb.append(asAPI ? ".flowY()" : ",flowy");
boolean fillX = lc.isFillX();
boolean fillY = lc.isFillY();
if (fillX || fillY) {
if (fillX == fillY) {
sb.append(asAPI ? ".fill()" : ",fill");
} else {
sb.append(asAPI ? (fillX ? ".fillX()" : ".fillY()") : (fillX ? ",fillx" : ",filly"));
}
}
Boolean leftToRight = lc.getLeftToRight();
if (leftToRight != null) {
if (asAPI) {
sb.append(".leftToRight(").append(leftToRight).append(')');
} else {
sb.append(leftToRight ? ",ltr" : ",rtl");
}
}
if (!lc.getPackWidth().isUnset() || !lc.getPackHeight().isUnset()) {
if (asAPI) {
String w = getBS(lc.getPackWidth());
String h = getBS(lc.getPackHeight());
sb.append(".pack(");
if (w.equals("pref") && h.equals("pref")) {
sb.append(')');
} else {
sb.append('\"').append(w).append("\", \"").append(h).append("\")");
}
} else {
sb.append(",pack");
String size = getBS(lc.getPackWidth()) + " " + getBS(lc.getPackHeight());
if (size.equals("pref pref") == false)
sb.append(' ').append(size);
}
}
if (lc.getPackWidthAlign() != 0.5f || lc.getPackHeightAlign() != 1f) {
if (asAPI) {
sb.append(".packAlign(").append(floatToString(lc.getPackWidthAlign(), asAPI)).append(", ").append(floatToString(lc.getPackHeightAlign(), asAPI)).append(')');
} else {
sb.append(",packalign ").append(floatToString(lc.getPackWidthAlign(), asAPI)).append(' ').append(floatToString(lc.getPackHeightAlign(), asAPI));
}
}
if (lc.isTopToBottom() == false)
sb.append(asAPI ? ".bottomToTop()" : ",btt");
UnitValue[] insets = lc.getInsets();
if (insets != null) {
String cs = LayoutUtil.getCCString(insets);
if (cs != null) {
if (asAPI) {
sb.append(".insets(\"").append(cs).append("\")");
} else {
sb.append(",insets ").append(cs);
}
} else if (isDialogInsets(insets)) {
sb.append(asAPI ? ".insets(\"dialog\")" : ",insets dialog");
} else if (isPanelInsets(insets)) {
sb.append(asAPI ? ".insets(\"panel\")" : ",insets panel");
} else {
sb.append(asAPI ? ".insets(\"" : ",insets ");
for (int i = 0; i < insets.length; i++)
sb.append(getUV(insets[i])).append(i < insets.length - 1 ? " " : "");
if (asAPI)
sb.append("\")");
}
}
if (lc.isNoGrid())
sb.append(asAPI ? ".noGrid()" : ",nogrid");
if (lc.isVisualPadding() == false)
sb.append(asAPI ? ".noVisualPadding()" : ",novisualpadding");
int hideMode = lc.getHideMode();
if (hideMode > 0) {
if (asAPI) {
sb.append(".hideMode(").append(hideMode).append(')');
} else {
sb.append(",hidemode ").append(hideMode);
}
}
appendBoundSize(lc.getWidth(), sb, true, asAPI);
appendBoundSize(lc.getHeight(), sb, false, asAPI);
UnitValue alignX = lc.getAlignX();
UnitValue alignY = lc.getAlignY();
if (alignX != null || alignY != null) {
if (alignX != null && alignY != null) {
sb.append(asAPI ? ".align(\"" : ",align ").append(getUV(alignX)).append(asAPI ? "\", \"" : " ").append(getUV(alignY));
} else if (alignX != null) {
sb.append(asAPI ? ".alignX(\"" : ",alignx ").append(getUV(alignX));
} else if (alignY != null) {
sb.append(asAPI ? ".alignY(\"" : ",aligny ").append(getUV(alignY));
}
if (asAPI)
sb.append("\")");
}
BoundSize gridGapX = lc.getGridGapX();
BoundSize gridGapY = lc.getGridGapY();
if (gridGapX != null || gridGapY != null) {
if (gridGapX != null && gridGapY != null) {
sb.append(asAPI ? ".gridGap(\"" : ",gap ").append(getBS(gridGapX)).append(asAPI ? "\", \"" : " ").append(getBS(gridGapY));
} else if (gridGapX != null) {
sb.append(asAPI ? ".gridGapX(\"" : ",gapx ").append(getBS(gridGapX));
} else if (gridGapY != null) {
sb.append(asAPI ? ".gridGapY(\"" : ",gapy ").append(getBS(gridGapY));
}
if (asAPI)
sb.append("\")");
}
int wrapAfter = lc.getWrapAfter();
if (wrapAfter != LayoutUtil.INF) {
String ws = wrapAfter > 0 ? String.valueOf(wrapAfter) : "";
if (asAPI) {
if (ws.isEmpty())
sb.append(".wrap()");
else
sb.append(".wrapAfter(").append(ws).append(')');
} else {
sb.append(",wrap ").append(ws);
removeTrailingSpace(sb);
}
}
int debugMillis = lc.getDebugMillis();
if (debugMillis > 0) {
if (asAPI) {
sb.append(".debug(").append(debugMillis).append(')');
} else {
sb.append(",debug ").append(debugMillis);
}
}
if (lc.isNoCache())
sb.append(asAPI ? ".noCache()" : ",nocache");
String s = sb.toString();
return s.length() == 0 || s.charAt(0) != ',' ? s : s.substring(1);
}
private static String getUV(UnitValue uv)
{
return uv != null ? uv.getConstraintString() : "null";
}
private static String getUV(UnitValue uv, boolean asAPI)
{
return uv != null
? (asAPI ? ('"' + uv.getConstraintString() + '"') : uv.getConstraintString())
: "null";
}
private static String getBS(BoundSize bs)
{
return bs != null ? bs.getConstraintString() : "null";
}
private static String getBS(BoundSize bs, boolean asAPI)
{
return bs != null
? (asAPI ? ('"' + bs.getConstraintString() + '"') : bs.getConstraintString())
: "null";
}
private static boolean isDialogInsets(UnitValue[] insets)
{
for (int i = 0; i < 4; i++) {
if (PlatformDefaults.getDialogInsets(i) != insets[i])
return false;
}
return true;
}
private static boolean isPanelInsets(UnitValue[] insets)
{
for (int i = 0; i < 4; i++) {
if (PlatformDefaults.getPanelInsets(i) != insets[i])
return false;
}
return true;
}
/** Converts a float
to a string and is removing the ".0" if the float is an integer.
* @param f the float.
* @return f
as a string. Never null
.
*/
private static String floatToString(float f, boolean asAPI)
{
String valS = String.valueOf(f);
return valS.endsWith(".0") ? valS.substring(0, valS.length() - 2) : (valS + (asAPI ? "f" : ""));
}
private static String floatObjectToString(float f, boolean asAPI)
{
String valS = floatToString(f, asAPI);
// trailing 'f' is required if Java method parameter is of type java.lang.Float
if (asAPI && !valS.endsWith("f"))
valS = valS.concat("f");
return valS;
}
private static void removeTrailingSpace(StringBuffer sb)
{
int length = sb.length();
if (length > 0 && sb.charAt(length - 1) == ' ')
sb.setLength(length - 1);
}
}
miglayout-5.1/ideutil/src/test/000077500000000000000000000000001324101563200165735ustar00rootroot00000000000000miglayout-5.1/ideutil/src/test/java/000077500000000000000000000000001324101563200175145ustar00rootroot00000000000000miglayout-5.1/ideutil/src/test/java/net/000077500000000000000000000000001324101563200203025ustar00rootroot00000000000000miglayout-5.1/ideutil/src/test/java/net/miginfocom/000077500000000000000000000000001324101563200224315ustar00rootroot00000000000000miglayout-5.1/ideutil/src/test/java/net/miginfocom/layout/000077500000000000000000000000001324101563200237465ustar00rootroot00000000000000miglayout-5.1/ideutil/src/test/java/net/miginfocom/layout/IDEUtilTest.java000066400000000000000000000471231324101563200267170ustar00rootroot00000000000000/*
* License (BSD):
* ==============
*
* Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
* 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 the MiG InfoCom AB nor 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 net.miginfocom.layout;
import static org.junit.Assert.*;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ErrorCollector;
/**
* Unit tests for {@link IDEUtil}.
*
* @author Karl Tauber
*/
public class IDEUtilTest
{
@Rule
public ErrorCollector errorCollector = new ErrorCollector();
@BeforeClass
public static void initialize() {
// MigLayout: enable design time for LayoutUtil.putCCString()
LayoutUtil.setDesignTime( null, true );
}
@Test
public void testMigLayoutConstraints() {
// wrap
testLC( "wrap", null, new LC().wrap(), ".wrap()" );
testLC( "wrap 4", null, new LC().wrapAfter(4), ".wrapAfter(4)" );
// gap
testLC( "gap 5px", "gap 5px 5px", new LC().gridGap("5px", "5px"), ".gridGap(\"5px\", \"5px\")" );
testLC( "gap 5px 10px", null, new LC().gridGap("5px", "10px"), ".gridGap(\"5px\", \"10px\")" );
testLC( "gap null 10px", "gapy 10px", new LC().gridGap(null, "10px"), ".gridGapY(\"10px\")" );
testLC( "gapx 10::50", null, new LC().gridGapX("10::50"), ".gridGapX(\"10::50\")" );
testLC( "gapy 0:rel:null", null, new LC().gridGapY("0:rel:null"), ".gridGapY(\"0:rel:null\")" );
// debug
testLC( "debug", "debug 1000", new LC().debug(1000), ".debug(1000)" );
testLC( "debug 300", null, new LC().debug(), ".debug(300)" );
testLC( "debug 4000", null, new LC().debug(4000), ".debug(4000)" );
// nogrid
testLC( "nogrid", null, new LC().noGrid(), ".noGrid()" );
// novisualpadding
testLC( "novisualpadding", null, new LC().noVisualPadding(), ".noVisualPadding()" );
// fill
testLC( "fill", null, new LC().fill(), ".fill()" );
testLC( "fillx", null, new LC().fillX(), ".fillX()" );
testLC( "filly", null, new LC().fillY(), ".fillY()" );
// insets
testLC( "insets panel", null, new LC().insets("panel"), ".insets(\"panel\")" );
testLC( "insets dialog", null, new LC().insets("dialog"), ".insets(\"dialog\")" );
testLC( "insets", "insets dialog", new LC().insets(""), ".insets(\"dialog\")" );
testLC( "insets 0", "insets 0 0 0 0", new LC().insetsAll( "0" ), ".insets(\"0 0 0 0\")" );
testLC( "insets 0 1", "insets 0 1 1 1", new LC().insets( "0 1" ), ".insets(\"0 1 1 1\")" );
testLC( "insets 0 1 2", "insets 0 1 2 2", new LC().insets( "0 1 2" ), ".insets(\"0 1 2 2\")" );
testLC( "insets 0 1 2 3", null, new LC().insets("0 1 2 3"), ".insets(\"0 1 2 3\")" );
testLC( "insets 0 1 2 3", null, new LC().insets("0", "1", "2", "3"), ".insets(\"0 1 2 3\")" );
testLC( "insets 0 null 2 3", null, new LC().insets("0", null, "2", "3"), ".insets(\"0 null 2 3\")" );
// flowy
testLC( "flowy", null, new LC().flowY(), ".flowY()" );
// align
testLC( "align left", "alignx left", new LC().alignX("left"), ".alignX(\"left\")" );
testLC( "align null top", "aligny top", new LC().alignY("top"), ".alignY(\"top\")" );
testLC( "align left top", null, new LC().align("left", "top"), ".align(\"left\", \"top\")" );
testLC( "alignx left", null, new LC().alignX("left"), ".alignX(\"left\")" );
testLC( "aligny top", null, new LC().alignY("top"), ".alignY(\"top\")" );
// lefttoright, righttoleft
testLC( "ltr", null, new LC().leftToRight(true), ".leftToRight(true)" );
testLC( "rtl", null, new LC().rightToLeft(), ".leftToRight(false)" );
// toptobottom, bottomtotop
testLC( "ttb", "", new LC().topToBottom(), "" );
testLC( "btt", null, new LC().bottomToTop(), ".bottomToTop()" );
// hidemode
testLC( "hidemode 1", null, new LC().hideMode(1), ".hideMode(1)" );
// nocache
testLC( "nocache", null, new LC().noCache(), ".noCache()" );
}
@Test
public void testMigColumnRowConstraints() {
// gaps
testAC( "[]", null, new AC(), "" );
testAC( "[][]", null, new AC().gap(), ".gap()" );
testAC( "[][][]", null, new AC().gap().gap(), ".gap().gap()" );
testAC( "[]10[]", null, new AC().gap("10"), ".gap(\"10\")" );
testAC( "[]para[]unrel[]", null, new AC().gap("para").gap("unrel"), ".gap(\"para\").gap(\"unrel\")" );
// complex samples from white paper
testAC( false, "[fill]10[10:20,top]", null,
new AC().fill().gap("10").size("10:20").align("top"),
".fill().gap(\"10\").size(\"10:20\").align(\"top\")" );
testAC( "[fill]push[]", null,
new AC().fill().gap("push"),
".fill().gap(\"push\")" );
testAC( false, "[fill]10:10:100:push[10:20,top]", null,
new AC().fill().gap("10:10:100:push").size("10:20").align("top"),
".fill().gap(\"10:10:100:push\").size(\"10:20\").align(\"top\")" );
// size
testAC( "[100]", null, new AC().size("100"), ".size(\"100\")");
testAC( "[100][200]", null, new AC().size("100").gap().size("200"), ".size(\"100\").gap().size(\"200\")");
testAC( "[pref]", null, new AC().size("pref"), ".size(\"pref\")" );
testAC( "[pref,fill]", null, new AC().size("pref").fill(), ".size(\"pref\").fill()" );
// sizegroup
testAC( "[sizegroup]", null, new AC().sizeGroup(), ".sizeGroup(\"\")" );
testAC( "[sizegroup grp1]", null, new AC().sizeGroup("grp1"), ".sizeGroup(\"grp1\")" );
// fill
testAC( "[fill]", null, new AC().fill(), ".fill()" );
// nogrid
testAC( "[nogrid]", null, new AC().noGrid(), ".noGrid()" );
// grow
testAC( "[grow]", null, new AC().grow(), ".grow()" );
testAC( "[grow 50]", null, new AC().grow(50), ".grow(50)" );
// growprio
testAC( "[growprio 50]", null, new AC().growPrio(50), ".growPrio(50)" );
// shrink
testAC( "[shrink 50]", null, new AC().shrink(50), ".shrink(50)" );
// shrinkprio
testAC( "[shrinkprio 50]", null, new AC().shrinkPrio(50), ".shrinkPrio(50)" );
// align
testAC( "[align 50%]", null, null, null ); // no API because AC().align() does not support UnitValues
testAC( "[align 100px]", null, null, null ); // no API because AC().align() does not support UnitValues
testAC( true, "[align left]", "[left]", new AC().align("left"), ".align(\"left\")" );
testAC( false, "[align top]", "[top]", new AC().align("top"), ".align(\"top\")" );
}
@Test
public void testMigComponentConstraints() {
// wrap
testCC( "wrap", null, new CC().wrap(), ".wrap()" );
testCC( "wrap 15px", null, new CC().wrap("15px"), ".wrap(\"15px\")" );
testCC( "wrap push", null, new CC().wrap("push"), ".wrap(\"push\")" );
testCC( "wrap 15:push", null, new CC().wrap("15:push"), ".wrap(\"15:push\")" );
// newline
testCC( "newline", null, new CC().newline(), ".newline()" );
testCC( "newline 15px", null, new CC().newline("15px"), ".newline(\"15px\")" );
// push
testCC( "push", null, new CC().push(), ".push()" );
testCC( "push 200", "push 200 100", new CC().push(200f, 100f), ".push(200f, 100f)" );
testCC( "push 200 300", null, new CC().push(200f, 300f), ".push(200f, 300f)" );
testCC( "pushx", null, new CC().pushX(), ".pushX()" );
testCC( "pushx 200", null, new CC().pushX(200f), ".pushX(200f)" );
testCC( "pushy", null, new CC().pushY(), ".pushY()" );
testCC( "pushy 200", null, new CC().pushY(200f), ".pushY(200f)" );
// skip
testCC( "skip", "skip 1", new CC().skip(), ".skip(1)" );
testCC( "skip 3", null, new CC().skip(3), ".skip(3)" );
// span
testCC( "span", "spanx", new CC().span(), ".spanX()" );
testCC( "span 4", "spanx 4", new CC().span(4), ".spanX(4)" );
testCC( "span 2 3", null, new CC().span(2, 3), ".span(2, 3)" );
testCC( "spanx", null, new CC().spanX(), ".spanX()" );
testCC( "spanx 10", null, new CC().spanX(10), ".spanX(10)" );
testCC( "spany", null, new CC().spanY(), ".spanY()" );
testCC( "spany 2", null, new CC().spanY(2), ".spanY(2)" );
// split
testCC( "split", null, new CC().split(), ".split()" );
testCC( "split 4", null, new CC().split(4), ".split(4)" );
// cell
testCC( "cell 2 2", null, new CC().cell(2, 2), ".cell(2, 2)" );
testCC( "cell 0 1 2", "cell 0 1 2 1", new CC().cell(0, 1, 2), ".cell(0, 1, 2, 1)" );
testCC( "cell 0 1 2 3", null, new CC().cell(0, 1, 2, 3), ".cell(0, 1, 2, 3)" );
// flowx, flowy
testCC( "flowx", null, new CC().flowX(), ".flowX()" );
testCC( "flowy", null, new CC().flowY(), ".flowY()" );
// width, height
testCC( "width 10", null, new CC().width("10"), ".width(\"10\")" );
testCC( "height pref!", null, new CC().height("pref!"), ".height(\"pref!\")" );
// wmin, wmax, hmin, hmax
testCC( "wmin 10", null, new CC().minWidth("10"), ".minWidth(\"10\")" );
testCC( "wmax 10", null, new CC().maxWidth("10"), ".maxWidth(\"10\")" );
testCC( "hmin 10", null, new CC().minHeight("10"), ".minHeight(\"10\")" );
testCC( "hmax 10", null, new CC().maxHeight("10"), ".maxHeight(\"10\")" );
// grow
testCC( "grow", null, new CC().grow(), ".grow()" );
testCC( "grow 100", "grow", new CC().grow(100, 100), ".grow()" );
testCC( "grow 50", "growx 50,growy", new CC().grow(50, 100), ".growX(50).growY()" );
testCC( "grow 50 20", "growx 50,growy 20", new CC().grow(50, 20), ".growX(50).growY(20)" );
testCC( "grow 50 50", "growx 50,growy 50", new CC().grow(50, 50), ".growX(50).growY(50)" );
testCC( "grow 100 20", "growx,growy 20", new CC().grow(100, 20), ".growX().growY(20)" );
testCC( "grow 50 100", "growx 50,growy", new CC().grow(50, 100), ".growX(50).growY()" );
testCC( "growx", null, new CC().growX(), ".growX()" );
testCC( "growx 50", null, new CC().growX(50), ".growX(50)" );
testCC( "growy", null, new CC().growY(), ".growY()" );
testCC( "growy 0", null, new CC().growY(0), ".growY(0)" );
// growprio
testCC( "growprio 50", "growpriox 50", new CC().growPrio(50), ".growPrioX(50)" );
testCC( "growprio 50 80", "growpriox 50,growprioy 80", new CC().growPrio(50, 80), ".growPrioX(50).growPrioY(80)" );
testCC( "growpriox 50", null, new CC().growPrioX(50), ".growPrioX(50)" );
testCC( "growprioy 80", null, new CC().growPrioY(80), ".growPrioY(80)" );
// shrink
testCC( "shrink 50", "shrinkx 50", new CC().shrink(50, 100), ".shrinkX(50)" );
testCC( "shrink 50 20", "shrinkx 50,shrinky 20", new CC().shrink(50, 20), ".shrinkX(50).shrinkY(20)" );
testCC( "shrink 100 20", "shrinky 20", new CC().shrink(100, 20), ".shrinkY(20)" );
testCC( "shrinkx 50", null, new CC().shrinkX(50), ".shrinkX(50)" );
testCC( "shrinky 20", null, new CC().shrinkY(20), ".shrinkY(20)" );
// shrinkprio
testCC( "shrinkprio 50", "shrinkpriox 50", new CC().shrinkPrio(50), ".shrinkPrioX(50)" );
testCC( "shrinkprio 50 80", "shrinkpriox 50,shrinkprioy 80", new CC().shrinkPrio(50, 80), ".shrinkPrioX(50).shrinkPrioY(80)" );
testCC( "shrinkpriox 50", null, new CC().shrinkPrioX(50), ".shrinkPrioX(50)" );
testCC( "shrinkprioy 80", null, new CC().shrinkPrioY(80), ".shrinkPrioY(80)" );
// sizegroup
testCC( "sizegroup", "sizegroupx,sizegroupy", new CC().sizeGroup("", ""), ".sizeGroupX(\"\").sizeGroupY(\"\")" );
testCC( "sizegroup g1", "sizegroupx g1,sizegroupy g1", new CC().sizeGroup("g1", "g1"), ".sizeGroupX(\"g1\").sizeGroupY(\"g1\")" );
testCC( "sizegroupx", null, new CC().sizeGroupX(""), ".sizeGroupX(\"\")" );
testCC( "sizegroupx g1", null, new CC().sizeGroupX("g1"), ".sizeGroupX(\"g1\")" );
testCC( "sizegroupy", null, new CC().sizeGroupY(""), ".sizeGroupY(\"\")" );
testCC( "sizegroupy g1", null, new CC().sizeGroupY("g1"), ".sizeGroupY(\"g1\")" );
// endgroup
testCC( "endgroupx", null, new CC().endGroupX(""), ".endGroupX(\"\")" );
testCC( "endgroupx g1", null, new CC().endGroupX("g1"), ".endGroupX(\"g1\")" );
testCC( "endgroupy", null, new CC().endGroupY(""), ".endGroupY(\"\")" );
testCC( "endgroupy g1", null, new CC().endGroupY("g1"), ".endGroupY(\"g1\")" );
// gap, gaptop, gapleft, gapbottom, gapright, gapbefore, gapafter
testCC( "gap 5", "gapx 5", new CC().gap("5"), ".gapX(\"5\", null)" );
testCC( "gap 5 6", "gapx 5 6", new CC().gap("5", "6"), ".gapX(\"5\", \"6\")" );
testCC( "gap 5 6 7", "gapx 5 6,gapy 7", new CC().gap("5", "6", "7"), ".gapX(\"5\", \"6\").gapY(\"7\", null)" );
testCC( "gap 5 6 7 8", "gapx 5 6,gapy 7 8", new CC().gap("5", "6", "7", "8"), ".gapX(\"5\", \"6\").gapY(\"7\", \"8\")" );
testCC( "gaptop 5", "gapy 5", new CC().gapTop("5"), ".gapY(\"5\", null)" );
testCC( "gapleft 5", "gapx 5", new CC().gapLeft("5"), ".gapX(\"5\", null)" );
testCC( "gapbottom 5", "gapy null 5", new CC().gapBottom("5"), ".gapY(null, \"5\")" );
testCC( "gapright 5", "gapx null 5", new CC().gapRight("5"), ".gapX(null, \"5\")" );
testCC( "gapbefore 5", "gapx 5", new CC().gapBefore("5"), ".gapX(\"5\", null)" );
testCC( "gapafter 5", "gapx null 5", new CC().gapAfter("5"), ".gapX(null, \"5\")" );
// gapx, gapy
testCC( "gapx 5", null, new CC().gapX("5", null), ".gapX(\"5\", null)" );
testCC( "gapx 5 10", null, new CC().gapX("5", "10"), ".gapX(\"5\", \"10\")" );
testCC( "gapy unrel", null, new CC().gapY("unrel", null), ".gapY(\"unrel\", null)" );
testCC( "gapy unrel rel", null, new CC().gapY("unrel", "rel"), ".gapY(\"unrel\", \"rel\")" );
// id
testCC( "id button1", null, new CC().id("button1"), ".id(\"button1\")" );
// pos
testCC( "pos 50% 80%", null, new CC().pos("50%", "80%"), ".pos(\"50%\", \"80%\")" );
testCC( "pos 50% 80%", null, new CC().pos("50%", "80%"), ".pos(\"50%\", \"80%\")" );
testCC( "pos 50% 80% 200 100", null, new CC().pos("50%", "80%", "200", "100"), ".pos(\"50%\", \"80%\", \"200\", \"100\")" );
testCC( "pos null null 200 100", null, new CC().pos(null, null, "200", "100"), ".pos(null, null, \"200\", \"100\")" );
testCC( "pos (b1.x+b1.w/2) (b1.y2+rel)", null, new CC().pos("(b1.x+b1.w/2)", "(b1.y2+rel)"), ".pos(\"(b1.x+b1.w/2)\", \"(b1.y2+rel)\")" );
testCC( "pos (visual.x2 - pref) 200", null, new CC().pos("(visual.x2 - pref)", "200"), ".pos(\"(visual.x2 - pref)\", \"200\")" );
testCC( "pos null b1.y b1.x-rel b1.y2", null, new CC().pos(null, "b1.y", "b1.x-rel", "b1.y2"), ".pos(null, \"b1.y\", \"b1.x-rel\", \"b1.y2\")" );
// x, x2, y, y2
testCC( "x 10", null, new CC().x("10"), ".x(\"10\")" );
testCC( "x button1.x", null, new CC().x("button1.x"), ".x(\"button1.x\")" );
testCC( "x2 (visual.x2-50)", null, new CC().x2("(visual.x2-50)"), ".x2(\"(visual.x2-50)\")" );
testCC( "y 10", null, new CC().y("10"), ".y(\"10\")" );
testCC( "y2 10", null, new CC().y2("10"), ".y2(\"10\")" );
// dock
testCC( "dock north", "north", new CC().dockNorth(), ".dockNorth()" );
testCC( "dock west", "west", new CC().dockWest(), ".dockWest()" );
testCC( "dock south", "south", new CC().dockSouth(), ".dockSouth()" );
testCC( "dock east", "east", new CC().dockEast(), ".dockEast()" );
testCC( "dock center", "push,grow", new CC().push().grow(), ".push().grow()" );
testCC( "north", null, new CC().dockNorth(), ".dockNorth()" );
testCC( "west", null, new CC().dockWest(), ".dockWest()" );
testCC( "south", null, new CC().dockSouth(), ".dockSouth()" );
testCC( "east", null, new CC().dockEast(), ".dockEast()" );
// pad
testCC( "pad 5", "pad 5 5 5 5", new CC().pad("5"), ".pad(\"5 5 5 5\")" );
testCC( "pad 5 6", "pad 5 6 6 6", new CC().pad("5 6"), ".pad(\"5 6 6 6\")" );
testCC( "pad 5 6 7", "pad 5 6 7 7", new CC().pad("5 6 7"), ".pad(\"5 6 7 7\")" );
testCC( "pad 5 6 7 8", null, new CC().pad("5 6 7 8"), ".pad(\"5 6 7 8\")" );
testCC( "pad 5.0px 6.0px 7.0px 8.0px", null, new CC().pad(5, 6, 7, 8), ".pad(\"5.0px 6.0px 7.0px 8.0px\")" );
// align
testCC( "align left", "alignx left", new CC().alignX("left"), ".alignX(\"left\")" );
testCC( "align left top", "alignx left,aligny top", new CC().alignX("left").alignY("top"), ".alignX(\"left\").alignY(\"top\")" );
testCC( "align null top", "aligny top", new CC().alignY("top"), ".alignY(\"top\")" );
testCC( "alignx left", null, new CC().alignX("left"), ".alignX(\"left\")" );
testCC( "aligny top", null, new CC().alignY("top"), ".alignY(\"top\")" );
// external
testCC( "external", null, new CC().external(), ".external()" );
// hidemode
testCC( "hidemode 1", null, new CC().hideMode(1), ".hideMode(1)" );
// tag
testCC( "tag ok", null, new CC().tag("ok"), ".tag(\"ok\")" );
}
private void testLC( String input, String expected, LC inputAPI, String expectedAPI ) {
LC lc = ConstraintParser.parseLayoutConstraint( input );
String actual = IDEUtil.getConstraintString( lc, false );
String actualAPI = IDEUtil.getConstraintString( inputAPI, true );
String actualAPI2 = IDEUtil.getConstraintString( lc, true );
myAssertEquals( input, (expected != null) ? expected : input, actual );
myAssertEquals( input, expectedAPI, actualAPI );
myAssertEquals( input, actualAPI2, actualAPI );
}
private void testAC( String input, String expected, AC inputAPI, String expectedAPI ) {
testAC( true, input, expected, inputAPI, expectedAPI );
testAC( false, input, expected, inputAPI, expectedAPI );
}
private void testAC( boolean isCols, String input, String expected, AC inputAPI, String expectedAPI ) {
AC ac = isCols
? ConstraintParser.parseColumnConstraints( input )
: ConstraintParser.parseRowConstraints( input );
String actual = IDEUtil.getConstraintString( ac, false, isCols );
myAssertEquals( input, (expected != null) ? expected : input, actual );
if( inputAPI != null ) {
String actualAPI = IDEUtil.getConstraintString( inputAPI, true, isCols );
String actualAPI2 = IDEUtil.getConstraintString( ac, true, isCols );
myAssertEquals( input, expectedAPI, actualAPI );
myAssertEquals( input, actualAPI2, actualAPI );
}
}
private void testCC( String input, String expected, CC inputAPI, String expectedAPI ) {
CC cc = ConstraintParser.parseComponentConstraint( input );
String actual = IDEUtil.getConstraintString( cc, false );
String actualAPI = IDEUtil.getConstraintString( inputAPI, true );
String actualAPI2 = IDEUtil.getConstraintString( cc, true );
myAssertEquals( input, (expected != null) ? expected : input, actual );
myAssertEquals( input, expectedAPI, actualAPI );
myAssertEquals( input, actualAPI2, actualAPI );
}
private void myAssertEquals( String message, Object expected, Object actual ) {
try {
assertEquals( message, expected, actual );
} catch( Throwable ex ) {
errorCollector.addError( ex );
}
}
}
miglayout-5.1/javafx/000077500000000000000000000000001324101563200146455ustar00rootroot00000000000000miglayout-5.1/javafx/maven.txt000077500000000000000000000036401324101563200165220ustar00rootroot00000000000000The JavaFX runtime is not available in any public Maven repository, it has to be installed in the local repository manually using the command below:
mvn install:install-file -Dfile=/path-to/javafx-sdk2.0-beta/rt/lib/jfxrt.jar -DgroupId=com.oracle -DartifactId=javafx-runtime -Dversion=2.0 -Dpackaging=jar -DgeneratePom=true
Naturally the path-to must be your path to where the JavaFX SDK is installed and make sure that the specified version matches the actual JavaFX release version (and naturally that should be the one the miglayout-javafx artifact depends on).
This is enough to get the JavaFX plugin to compile, but the test classes cannot be run because the JavaFX binaries are missing.
To run the test classes in the IDE, the easiest way is to modify the classpath or java library path to include the libs directory of the corresponding JavaFX installation.
The easiest way to do this is to manually include the JavaFX runtime jar (C:\Program Files\Oracle\JavaFX Runtime 2.0\lib\jfxrt.jar) and make sure it is positioned before the maven dependency in your EDI.
Some IDE's may be stubborn when the project is created from the POM and do not allow additional classpath entries, in this case specifying it in the run configuration of each test class will help.
For example in Eclipse the run configuration of a test could be modified to include the following as "VM arguments":
-Djava.library.path=C:\Progra~1\Oracle\JAVAFX~1.0\bin
However, all this does not solve the actual problem, it just will get the test code to run in an EDI, and that is the reason why there are no unittest at this time.
The JFXtras project has a workaround where the binaries are uploaded as a separate Maven artifact and a prelaunch method is used to make sure they are on the classpath, but we do not want MigLayout-JavaFX depending on JFXtras.
So for now we have to live with this and wait for Oracle to improve the Maven support in JavaFX.
miglayout-5.1/javafx/pom.xml000077500000000000000000000051751324101563200161750ustar00rootroot00000000000000
4.0.0
com.miglayout
miglayout-parent
5.1-SNAPSHOT
../pom.xml
miglayout-javafx
jar
MiGLayout JavaFX
MiGLayout - Layout Manager for JavaFX
${project.groupId}
miglayout-core
${project.version}
org.loadui
testFx
3.1.2
test
org.jfxtras
jfxtras-test-support
8.0-r3
test
org.jfxtras
jfxtras-common
8.0-r3
test
org.apache.maven.plugins
maven-compiler-plugin
3.7.0
1.8
1.8
true
none
-g:none
tbee
Tom Eugelink
tbee@tbee.org
Developer
+1
http://www.tbee.org/
miglayout-5.1/javafx/src/000077500000000000000000000000001324101563200154345ustar00rootroot00000000000000miglayout-5.1/javafx/src/main/000077500000000000000000000000001324101563200163605ustar00rootroot00000000000000miglayout-5.1/javafx/src/main/java/000077500000000000000000000000001324101563200173015ustar00rootroot00000000000000miglayout-5.1/javafx/src/main/java/org/000077500000000000000000000000001324101563200200705ustar00rootroot00000000000000miglayout-5.1/javafx/src/main/java/org/tbee/000077500000000000000000000000001324101563200210075ustar00rootroot00000000000000miglayout-5.1/javafx/src/main/java/org/tbee/javafx/000077500000000000000000000000001324101563200222665ustar00rootroot00000000000000miglayout-5.1/javafx/src/main/java/org/tbee/javafx/scene/000077500000000000000000000000001324101563200233635ustar00rootroot00000000000000miglayout-5.1/javafx/src/main/java/org/tbee/javafx/scene/layout/000077500000000000000000000000001324101563200247005ustar00rootroot00000000000000miglayout-5.1/javafx/src/main/java/org/tbee/javafx/scene/layout/LayoutAnimator.java000066400000000000000000000137741324101563200305270ustar00rootroot00000000000000package org.tbee.javafx.scene.layout;
import javafx.animation.FadeTransition;
import javafx.animation.Interpolator;
import javafx.animation.Transition;
import javafx.application.Platform;
import javafx.geometry.Bounds;
import javafx.geometry.Rectangle2D;
import javafx.scene.Node;
import javafx.scene.SnapshotParameters;
import javafx.scene.image.ImageView;
import javafx.util.Duration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.IdentityHashMap;
/**
* @author Mikael Grev, MiG InfoCom AB
* Date: 14-09-24
* Time: 16:05
*/
public class LayoutAnimator
{
private static final String ANIM_REPLACE_ID = "mig-anim";
enum TransType {
BOUNDS, OPACITY
}
public static final Duration ANIM_DURATION = new Duration(2000);
private final MigPane pane;
private final ArrayList addedNodes = new ArrayList<>();
private final ArrayList removedNodes = new ArrayList<>();
private final IdentityHashMap> nodeAnimMap = new IdentityHashMap<>();
private final IdentityHashMap replacedNodeMap = new IdentityHashMap<>();
public LayoutAnimator(MigPane pane)
{
this.pane = pane;
}
/** Animates the node.
* @param node The node to animate. Not null.
* @param toBounds If != null the animation will be to these bounds.
*/
void animate(Node node, Rectangle2D toBounds)
{
nodeAnimMap.compute(node, (n, oldTrans) -> createOrUpdateAnimation(n, oldTrans, toBounds));
Node replNode = replacedNodeMap.get(node);
if (replNode != null)
nodeAnimMap.compute(replNode, (n, oldTrans) -> createOrUpdateAnimation(n, oldTrans, toBounds));
}
private HashMap createOrUpdateAnimation(Node node, HashMap transMap, Rectangle2D toBounds)
{
if (transMap == null)
transMap = new HashMap<>();
double toOpacity = extractOpacity(node);
transMap.compute(TransType.OPACITY, (transType, oldTrans) -> {
if (toOpacity != -1) {
if (oldTrans != null)
oldTrans.stop();
FadeTransition fadeTrans = new FadeTransition(ANIM_DURATION, node);
fadeTrans.setToValue(toOpacity);
if (isReplacement(node)) {
fadeTrans.setOnFinished(event -> {
Node realNode = (Node) node.getUserData();
if (realNode != null) {
Rectangle2D rb = getBounds(node);
realNode.resizeRelocate(rb.getMinX(), rb.getMinY(), rb.getWidth(), rb.getHeight());
realNode.setVisible(true);
}
pane.remove(node);
});
}
fadeTrans.play();
// System.out.println("fade to " + toOpacity);
return fadeTrans;
}
return oldTrans;
});
if (toBounds != null) {
transMap.compute(TransType.BOUNDS, (transType, oldTrans) -> {
Rectangle2D curBounds = getBounds(node);
if (!curBounds.equals(toBounds) && (oldTrans == null || !(((LayoutTrans) oldTrans).toBounds.equals(toBounds)))) {
if (oldTrans != null)
oldTrans.stop();
if (toOpacity == -1) {
LayoutTrans trans = new LayoutTrans(node, ANIM_DURATION, toBounds);
trans.play();
// System.out.println("layout to " + toBounds.toString());
return trans;
} else {
node.resizeRelocate(toBounds.getMinX(), toBounds.getMinY(), toBounds.getWidth(), toBounds.getHeight());
}
}
return oldTrans;
});
}
return transMap;
}
private double extractOpacity(Node node)
{
if (addedNodes.remove(node)) {
node.setOpacity(0);
return 1;
} else if (removedNodes.remove(node)) {
return 0;
}
return -1;
}
void nodeAdded(Node node)
{
if (isReplacement(node))
return;
Node replNode = createReplacement(node);
addedNodes.add(replNode);
removedNodes.remove(node);
node.setVisible(false);
Platform.runLater(() -> {
pane.add(0, replNode);
// animate(replNode, null);
});
}
void nodeRemoved(Node node)
{
if (isReplacement(node))
return;
Node replNode = createReplacement(node);
removedNodes.add(replNode);
addedNodes.remove(node);
Platform.runLater(() -> {
pane.add(0, replNode);
animate(replNode, null);
});
}
private static boolean isReplacement(Node node)
{
return ANIM_REPLACE_ID.equals(node.getId());
}
public Node createReplacement(Node node)
{
Rectangle2D b = getBounds(node);
Node replNode = new ImageView(node.snapshot(new SnapshotParameters(), null));
replacedNodeMap.put(node, replNode);
replNode.setUserData(node);
replNode.setManaged(false);
replNode.setId(ANIM_REPLACE_ID);
replNode.resizeRelocate(b.getMinX(), b.getMinY(), b.getWidth(), b.getHeight());
return replNode;
}
void start()
{
// if (status == PAUSED)
// nodeAnimMap.values().forEach(map -> map.values().forEach(Animation::play));
// status = RUNNING;
}
private static Rectangle2D getBounds(Node node)
{
Bounds lBounds = node.getLayoutBounds();
return new Rectangle2D(
node.getLayoutX(),
node.getLayoutY(),
lBounds.getWidth(),
lBounds.getHeight()
);
}
private class LayoutTrans extends Transition
{
private final Node node;
private final double fromX, fromY, fromW, fromH;
private final Rectangle2D toBounds;
/**
* @param node The node to animate
* @param toBounds Target bounds. Never null.
*/
LayoutTrans(Node node, Duration duration, Rectangle2D toBounds)
{
this.node = node;
this.fromX = node.getLayoutX();
this.fromY = node.getLayoutY();
Bounds bounds = node.getLayoutBounds();
this.fromW = bounds.getWidth();
this.fromH = bounds.getHeight();
this.toBounds = toBounds;
setCycleDuration(duration);
// setInterpolator(Interpolator.SPLINE(0.8, 0.2, 0.2, 0.8));
setInterpolator(Interpolator.SPLINE(0.0, 0.0, 0.2, 0.8));
// setInterpolator(Interpolator.EASE_OUT);
}
@Override
protected void interpolate(double frac)
{
double x = fromX + (toBounds.getMinX() - fromX) * frac;
double y = fromY + (toBounds.getMinY() - fromY) * frac;
double w = fromW + (toBounds.getWidth() - fromW) * frac;
double h = fromH + (toBounds.getHeight() - fromH) * frac;
pane.incLayoutInhibit();
node.resizeRelocate(x, y, w, h);
pane.decLayoutInhibit();
}
}
}
miglayout-5.1/javafx/src/main/java/org/tbee/javafx/scene/layout/MigPane.java000077500000000000000000000756331324101563200271040ustar00rootroot00000000000000package org.tbee.javafx.scene.layout;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.collections.ListChangeListener;
import javafx.geometry.*;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Control;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.layout.Region;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Screen;
import javafx.stage.Window;
import net.miginfocom.layout.*;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
/**
* Manages nodes with MigLayout added via add(node, CC)
*
* @author Tom Eugelink
*
*/
public class MigPane extends javafx.scene.layout.Pane
{
static {
// todo Made static to defeat JavaFX bug: https://bugs.openjdk.java.net/browse/JDK-8095013
PlatformDefaults.setDefaultDPI(96);
}
protected final static String FXML_CC_KEY = "MigPane.cc";
// We need to invalidate the grid since we can have a component with hidemode 3
// We need to request layout since JavaFX doesn't do this.
private final ChangeListener gridInvalidator = (observable, oldValue, newValue) -> {
invalidateGrid();
requestLayout();
};
// ============================================================================================================
// CONSTRUCTOR
/**
*
*/
public MigPane() {
super();
construct();
}
/**
* use the class layout constraints
*/
public MigPane(LC layoutConstraints) {
super();
setLayoutConstraints(layoutConstraints);
construct();
}
/**
* use the class layout constraints
*/
public MigPane(LC layoutConstraints, AC colConstraints) {
super();
setLayoutConstraints(layoutConstraints);
setColumnConstraints(colConstraints);
construct();
}
/**
* use the class layout constraints
*/
public MigPane(LC layoutConstraints, AC colConstraints, AC rowConstraints) {
super();
setLayoutConstraints(layoutConstraints);
setColumnConstraints(colConstraints);
setRowConstraints(rowConstraints);
construct();
}
/**
* use the string layout constraints
*/
public MigPane(String layoutConstraints) {
super();
setLayoutConstraints(ConstraintParser.parseLayoutConstraint(ConstraintParser.prepare(layoutConstraints)));
construct();
}
/**
* use the string layout constraints
*/
public MigPane(String layoutConstraints, String colConstraints) {
super();
setLayoutConstraints(ConstraintParser.parseLayoutConstraint(ConstraintParser.prepare(layoutConstraints)));
setColumnConstraints(ConstraintParser.parseColumnConstraints(ConstraintParser.prepare(colConstraints)));
construct();
}
/**
* use the string layout constraints
*/
public MigPane(String layoutConstraints, String colConstraints, String rowConstraints) {
super();
setLayoutConstraints(ConstraintParser.parseLayoutConstraint(ConstraintParser.prepare(layoutConstraints)));
setColumnConstraints(ConstraintParser.parseColumnConstraints(ConstraintParser.prepare(colConstraints)));
setRowConstraints(ConstraintParser.parseRowConstraints(ConstraintParser.prepare(rowConstraints)));
construct();
}
/*
*
*/
private void construct() {
// When Scene changes the grid needs to be cleared
sceneProperty().addListener(e -> invalidateGrid());
// invalidate grid and request layout when node orientation changes
nodeOrientationProperty().addListener(observable -> {
invalidateGrid();
requestLayout();
});
// defaults
if (layoutConstraints == null) setLayoutConstraints(new LC());
if (rowConstraints == null) setRowConstraints(new AC());
if (columnConstraints == null) setColumnConstraints(new AC());
// In case when someone sneakily removes a child the JavaFX way; prevent memory leaking
getChildren().addListener((ListChangeListener) c -> {
while (c.next()) {
for (Node node : c.getRemoved()) {
node.visibleProperty().removeListener(gridInvalidator);
animateRemoved(node);
int sizeBef = wrapperToCCMap.size();
wrapperToCCMap.remove(new FXComponentWrapper(node));
if (wrapperToCCMap.size() != sizeBef) // Can't use the return from wrapperToCCMap since it might be null anyway if no CC.
invalidateGrid();
}
for (Node node : c.getAddedSubList()) {
// debug rectangles are not handled by miglayout, neither are not managed ones
if (!node.isManaged())
continue;
// get cc or use default
CC cc = (CC) node.getProperties().remove(FXML_CC_KEY);
FXComponentWrapper wrapper = new FXComponentWrapper(node);
// Only put the value if this comes from FXML or from direct list manipulation (not in wrapperToCCMap yet)
if (cc != null || !wrapperToCCMap.containsKey(wrapper))
wrapperToCCMap.put(wrapper, cc);
animateAdded(node);
node.visibleProperty().addListener(gridInvalidator);
invalidateGrid();
}
}
});
}
// ============================================================================================================
// PANE
//
@Override
protected double computeMinWidth(double height) {
return computeWidth(height, LayoutUtil.MIN);
}
@Override
protected double computeMinHeight(double width) {
return computeHeight(width, LayoutUtil.MIN);
}
@Override
protected double computePrefWidth(double height) {
return computeWidth(height, LayoutUtil.PREF);
}
@Override
protected double computePrefHeight(double width) {
return computeHeight(width, LayoutUtil.PREF);
}
@Override
protected double computeMaxWidth(double height) {
return computeWidth(height, LayoutUtil.MAX);
}
@Override
protected double computeMaxHeight(double width) {
return computeHeight(width, LayoutUtil.MAX);
}
protected double computeWidth(double refHeight, int type) {
int ins = getHorIns();
int refSize = (int) Math.ceil(refHeight != -1 ? refHeight : getHeight()) - ins;
return ins + LayoutUtil.getSizeSafe(getGrid().getWidth(refSize), type);
}
protected double computeHeight(double refWidth, int type) {
int ins = getVerIns();
int refSize = (int) Math.ceil(refWidth != -1 ? refWidth : getWidth()) - ins;
return ins + LayoutUtil.getSizeSafe(getGrid().getHeight(refSize), type);
}
private int getHorIns()
{
Insets insets = getInsets();
return (int) Math.ceil(snapSpace(insets.getLeft()) + snapSpace(insets.getRight()));
}
private int getVerIns()
{
Insets insets = getInsets();
return (int) Math.ceil(snapSpace(insets.getTop()) + snapSpace(insets.getBottom()));
}
private Orientation bias = null;
private boolean biasDirty = true;
private boolean debug = false;
@Override
public Orientation getContentBias() {
if (biasDirty) {
bias = null;
for (Node child : getManagedChildren()) {
Orientation ori = child.getContentBias();
if (ori == Orientation.HORIZONTAL) {
bias = Orientation.HORIZONTAL;
break;
}
if (ori != null)
bias = ori;
}
biasDirty = false;
}
return bias;
}
// ============================================================================================================
// CONSTRAINTS
/** LayoutConstraints: */
public LC getLayoutConstraints() { return this.layoutConstraints; }
public void setLayoutConstraints(LC lc)
{
this.layoutConstraints = lc;
// Set debug. Clear it if LC is null.
debug = lc != null && lc.getDebugMillis() > 0;
invalidateGrid();
requestLayout();
}
public MigPane withLayoutConstraints(LC value) { setLayoutConstraints(value); return this; }
private LC layoutConstraints = null;
final static public String LAYOUTCONSTRAINTS_PROPERTY_ID = "layoutConstraints";
/** ColumnConstraints: */
public AC getColumnConstraints() { return this.columnConstraints; }
public void setColumnConstraints(AC value) { this.columnConstraints = value; invalidateGrid(); requestLayout();}
public MigPane withColumnConstraints(AC value) { setColumnConstraints(value); return this; }
private AC columnConstraints = null;
final static public String COLUMNCONSTRAINTS_PROPERTY_ID = "columnConstraints";
/** RowConstraints: */
public AC getRowConstraints() { return this.rowConstraints; }
public void setRowConstraints(AC value) { this.rowConstraints = value; invalidateGrid(); requestLayout();}
public MigPane withRowConstraints(AC value) { setRowConstraints(value); return this; }
private AC rowConstraints = null;
final static public String ROWCONSTRAINTS_PROPERTY_ID = "rowConstraints";
/** Returns the constraints for the node
* @return May be null which means all default constraints.
*/
public CC getComponentConstraints(Node node)
{
return wrapperToCCMap.get(new FXComponentWrapper(node));
}
/** Sets the constraints for the node
* @param node The node. Must already be in the pane.
* @param ccs The component constraints. Can be null.
*/
public void setComponentConstraints(Node node, String ccs)
{
FXComponentWrapper wrapper = new FXComponentWrapper(node);
if (!wrapperToCCMap.containsKey(wrapper))
throw new IllegalArgumentException("Node not in pane: " + node);
CC cc = ConstraintParser.parseComponentConstraint(ConstraintParser.prepare(ccs));
wrapperToCCMap.put(wrapper, cc);
invalidateGrid();
requestLayout();
}
private LayoutAnimator anim = null;
// ============================================================================================================
// Animation
private int animPrio = 0;
/**
* @return If there is a current animator, that is returned. Otherwise a new one is created and returned. Never null.
*/
private LayoutAnimator getAnimator()
{
if (anim == null)
anim = new LayoutAnimator(this);
return anim;
}
/** Starts animation if there is one.
*/
private void startQueuedAnimations()
{
if (anim != null)
anim.start();
}
public void animateAdded(Node node)
{
if (isNodeAnimated(node))
getAnimator().nodeAdded(node);
}
public void animateRemoved(Node node)
{
if (isNodeAnimated(node))
getAnimator().nodeRemoved(node);
}
public boolean animateBoundsChange(Node node, int x, int y, int width, int height)
{
if (!isNodeAnimated(node))
return false;
getAnimator().animate(node, new Rectangle2D(x, y, width, height));
return true;
}
private boolean isNodeAnimated(Node node)
{
if (!isVisible())
return false;
CC cc = wrapperToCCMap.get(new FXComponentWrapper(node));
int compPrio = cc != null ? cc.getAnimSpec().getPriority() : 0;
return compPrio + (long) animPrio > 0;
}
// ============================================================================================================
// CALLBACK
private ArrayList callbackList = null;
/** Adds the callback function that will be called at different stages of the layout cycle.
* @param callback The callback. Not null
.
*/
public void addLayoutCallback(LayoutCallback callback)
{
if (callback == null)
throw new NullPointerException();
if (callbackList == null)
callbackList = new ArrayList<>(1);
callbackList.add(callback);
invalidateGrid();
}
/** Removes the callback if it exists.
* @param callback The callback. May be null
.
*/
public void removeLayoutCallback(LayoutCallback callback)
{
if (callbackList != null)
callbackList.remove(callback);
}
// ============================================================================================================
// SCENE
public MigPane add(Node node, CC cc) {
if (node.isManaged())
wrapperToCCMap.put(new FXComponentWrapper(node), cc);
getChildren().add(node);
return this;
}
public MigPane add(Node node) {
add(node, (CC) null);
return this;
}
public MigPane add(Node node, String sCc) {
CC cc = ConstraintParser.parseComponentConstraint(ConstraintParser.prepare(sCc));
add(node, cc);
return this;
}
public MigPane add(int index, Node node) {
add(index, node, (CC) null);
return this;
}
public MigPane add(int index, Node node, String sCc) {
CC cc = ConstraintParser.parseComponentConstraint(ConstraintParser.prepare(sCc));
add(index, node, cc);
return this;
}
public MigPane add(int index, Node node, CC cc) {
if (node.isManaged())
wrapperToCCMap.put(new FXComponentWrapper(node), cc);
getChildren().add(index, node);
return this;
}
public boolean remove(Node node)
{
return getChildren().remove(node);
}
public Node remove(int ix)
{
return getChildren().remove(ix);
}
// ============================================================================================================
// LAYOUT
// Store constraints. Key order important. Can have null values but all components that MigPane handles must be a key.
final private LinkedHashMap wrapperToCCMap = new LinkedHashMap<>();
private long lastSize = 0;
/**
* This is where the actual layout happens
*/
@Override
protected void layoutChildren() {
incLayoutInhibit();
try {
if (layoutConstraints.isNoCache())
_grid = null;
// for debugging System.out.println("MigPane.layoutChildren");
Grid lGrid = getGrid();
// here the actual layout happens
// this will use FXComponentWrapper.setBounds to actually place the components
Insets ins = getInsets();
int[] lBounds = new int[]{(int) ins.getLeft(), (int) ins.getTop(), (int) Math.ceil(getWidth() - getHorIns()), (int) Math.ceil(getHeight() - getVerIns())};
lGrid.layout(lBounds, getLayoutConstraints().getAlignX(), getLayoutConstraints().getAlignY(), debug);
// paint debug
if (debug) {
clearDebug();
lGrid.paintDebug();
}
// Handle the "pack" keyword
long newSize = lGrid.getHeight()[1] + (((long) lGrid.getWidth()[1]) << 32);
if (lastSize != newSize) {
lastSize = newSize;
Platform.runLater(this::adjustWindowSize);
}
startQueuedAnimations();
} finally {
decLayoutInhibit();
}
}
@Override
protected void setWidth(double newWidth)
{
if (newWidth != getWidth()) {
super.setWidth(newWidth);
if (_grid != null)
_grid.invalidateContainerSize();
}
}
@Override
protected void setHeight(double newHeight)
{
if (newHeight != getHeight()) {
super.setHeight(newHeight);
if (_grid != null)
_grid.invalidateContainerSize();
}
}
@Override
public void requestLayout() {
if (layoutInhibits > 0)
return;
biasDirty = true;
if (_grid != null)
_grid.invalidateContainerSize();
super.requestLayout();
}
private Grid _grid;
private int layoutInhibits = 0; // When > 0 request layouts should be inhibited
void incLayoutInhibit()
{
layoutInhibits++;
}
void decLayoutInhibit()
{
layoutInhibits--;
}
/*
* the _grid is valid if all hash codes are unchanged
*/
private Grid getGrid() {
if (_grid == null)
_grid = new Grid(new FXContainerWrapper(this), getLayoutConstraints(), getRowConstraints(), getColumnConstraints(), wrapperToCCMap, callbackList);
return _grid;
}
/** Removes the grid so it is recreated as needed next time. Should only be needed when the grid structure, or the interpretation of it,
* has changed. Should normally don't have to be called by client code since this should be fully handled by MigPane.
*/
public void invalidateGrid()
{
_grid = null;
biasDirty = true;
}
/** Checks the parent window/popup if its size is within parameters as set by the LC.
*/
private void adjustWindowSize()
{
BoundSize wBounds = layoutConstraints.getPackWidth();
BoundSize hBounds = layoutConstraints.getPackHeight();
Scene scene = getScene();
Window window = scene != null ? scene.getWindow() : null;
if (window == null || wBounds == BoundSize.NULL_SIZE && hBounds == BoundSize.NULL_SIZE)
return;
Parent root = scene.getRoot();
double winWidth = window.getWidth();
double winHeight = window.getHeight();
double prefWidth = root.prefWidth(-1);
double prefHeight = root.prefHeight(-1);
FXContainerWrapper container = new FXContainerWrapper(root);
double horIns = winWidth - scene.getWidth();
double verIns = winHeight - scene.getHeight();
double targetW = constrain(container, winWidth, prefWidth, wBounds) + horIns;
double targetH = constrain(container, winHeight, prefHeight, hBounds) + verIns;
double x = window.getX() - ((targetW - winWidth) * (1 - layoutConstraints.getPackWidthAlign()));
double y = window.getY() - ((targetH - winHeight) * (1 - layoutConstraints.getPackHeightAlign()));
window.setX(x);
window.setY(y);
window.setWidth(targetW);
window.setHeight(targetH);
}
private double constrain(ContainerWrapper parent, double winSize, double prefSize, BoundSize constrain)
{
if (constrain == null)
return winSize;
double retSize = winSize;
UnitValue wUV = constrain.getPreferred();
if (wUV != null)
retSize = wUV.getPixels((float) prefSize, parent, parent);
retSize = constrain.constrain((int) Math.ceil(retSize), (float) prefSize, parent);
return constrain.getGapPush() ? Math.max(winSize, retSize) : retSize;
}
@Override
public boolean usesMirroring() {
// do not use mirroring transformation for right-to-left node orientation
return false;
}
// ============================================================================================================
// DEBUG
public void clearDebug() {
// for debugging System.out.println("clearDebug");
MigPane.this.getChildren().removeAll(this.debugRectangles);
this.debugRectangles.clear();
}
final private List debugRectangles = new ArrayList();
private void addDebugRectangle(double x, double y, double w, double h, DebugRectangleType type)
{
DebugRectangle lRectangle = new DebugRectangle( snap(x), snap(y), snap(x + w - 1) - snap(x), snap(y + h - 1) - snap(y) );
if (type == DebugRectangleType.CELL) {
//System.out.print(getId() + ": " + "paintDebugCell ");
lRectangle.setStroke(getDebugCellColor());
lRectangle.getStrokeDashArray().addAll(3d,3d);
}
else if (type == DebugRectangleType.EXTERNAL) {
//System.out.print(getId() + ": " + "paintDebugExternal ");
lRectangle.setStroke(getDebugExternalColor());
lRectangle.getStrokeDashArray().addAll(5d,5d);
}
else if (type == DebugRectangleType.OUTLINE) {
//System.out.print(getId() + ": " + "paintDebugOutline ");
lRectangle.setStroke(getDebugOutlineColor());
lRectangle.getStrokeDashArray().addAll(4d,4d);
}
else if (type == DebugRectangleType.CONTAINER_OUTLINE) {
//System.out.print(getId() + ": " + "paintDebugContainerOutline ");
lRectangle.setStroke(getDebugContainerOutlineColor());
lRectangle.getStrokeDashArray().addAll(7d,7d);
}
else {
throw new IllegalStateException("Unknown debug rectangle type");
}
// for debugging System.out.println(lRectangle.getX() + "," + lRectangle.getY() + "/" + lRectangle.getWidth() + "x" + lRectangle.getHeight());
//lRectangle.setStrokeWidth(0.5f);
lRectangle.setFill(null);
lRectangle.mouseTransparentProperty().set(true); // just to be sure
// add as child
MigPane.this.getChildren().add(lRectangle);
this.debugRectangles.add(lRectangle);
}
private enum DebugRectangleType { CELL, OUTLINE, CONTAINER_OUTLINE, EXTERNAL }
class DebugRectangle extends Rectangle
{
public DebugRectangle(double x, double y, double w, double h)
{
super(x,y,w,h);
setManaged(false);
}
}
private double snap(double v) {
return ((int) v) + .5;
}
/** debugCellColor */
public Color getDebugCellColor() { return this.debugCellColor; }
public void setDebugCellColor(Color value) { this.debugCellColor = value; }
private Color debugCellColor = Color.RED;
/** debugExternalColor */
public Color getDebugExternalColor() { return this.debugExternalColor; }
public void setDebugExternalColor(Color value) { this.debugExternalColor = value; }
private Color debugExternalColor = Color.BLUE;
/** debugOutlineColor */
public Color getDebugOutlineColor() { return this.debugOutlineColor; }
public void setDebugOutlineColor(Color value) { this.debugOutlineColor = value; }
private Color debugOutlineColor = Color.GREEN;
/** debugContainerOutlineColor */
public Color getDebugContainerOutlineColor() { return this.debugContainerOutlineColor; }
public void setDebugContainerOutlineColor(Color value) { this.debugContainerOutlineColor = value; }
private Color debugContainerOutlineColor = Color.PURPLE;
// ============================================================================================================
// ContainerWrapper
/*
* This class provides the data for MigLayout for the container
*/
class FXContainerWrapper extends FXComponentWrapper
implements net.miginfocom.layout.ContainerWrapper {
public FXContainerWrapper(Parent node) {
super(node);
}
@Override
public FXComponentWrapper[] getComponents() {
// for debugging System.out.println("MigPane.FXContainerWrapper.getComponents " + MigPane.this.componentWrapperList.size());
// return getManagedChildren().stream().map(node -> new FXComponentWrapper(node)).toArray(FXComponentWrapper[]::new);
List lFXComponentWrappers = new ArrayList<>();
for (Node node : getManagedChildren()) {
lFXComponentWrappers.add(new FXComponentWrapper(node));
}
return lFXComponentWrappers.toArray(new FXComponentWrapper[]{});
}
@Override
public int getComponentCount() {
// for debugging System.out.println("MigPane.FXContainerWrapper.getComponentCount " + MigPane.this.wrapperToCCMap.size());
return MigPane.this.wrapperToCCMap.size();
}
@Override
public Object getLayout() {
return MigPane.this;
}
@Override
public boolean isLeftToRight() {
return getEffectiveNodeOrientation() != NodeOrientation.RIGHT_TO_LEFT;
}
@Override
public void paintDebugCell(int x, int y, int w, int h) {
addDebugRectangle((double)x, (double)y, (double)w, (double)h, DebugRectangleType.CELL);
}
@Override
public void paintDebugOutline(boolean useVisualPadding) {
addDebugRectangle( 0, 0, getWidth(), getHeight(), DebugRectangleType.CONTAINER_OUTLINE);
}
}
// ============================================================================================================
// ComponentWrapper
/*
* This class provides the data for MigLayout for a single component
*/
class FXComponentWrapper implements net.miginfocom.layout.ComponentWrapper
{
final protected Node node;
// wrap this node
public FXComponentWrapper(Node node)
{
this.node = node;
}
// get the wrapped node
@Override
public Object getComponent()
{
return this.node;
}
// get the parent
@Override
public ContainerWrapper getParent()
{
Parent parent = node.getParent();
return parent != null ? new FXContainerWrapper(node.getParent()) : null;
}
// what type are we wrapping
@Override
public int getComponentType(boolean arg0)
{
if (node instanceof TextField || node instanceof TextArea) {
return TYPE_TEXT_FIELD;
} else if (node instanceof Group) {
return TYPE_CONTAINER;
} else {
return TYPE_UNKNOWN;
}
}
@Override
public int getX()
{
int v = (int) node.getLayoutX();
return v;
}
@Override
public int getY()
{
int v = (int) node.getLayoutY();
return v;
}
@Override
public int getWidth()
{
// for debugging if (getComponent() instanceof MigPane == false) System.out.println(getComponent() + " getWidth " + node.getLayoutBounds().getWidth());
int v = (int) Math.ceil(node.getLayoutBounds().getWidth());
return v;
}
@Override
public int getMinimumWidth(int height)
{
int v = (int) Math.ceil(this.node.minWidth(height));
// for debugging System.out.println(getComponent() + " getMinimumWidth " + v);
return v;
}
@Override
public int getPreferredWidth(int height)
{
int v = (int) Math.ceil(this.node.prefWidth(height));
// for debugging System.out.println(getComponent() + " getPreferredWidth " + v);
return v;
}
@Override
public int getMaximumWidth(int height)
{
// backwards compatibility with JavaFX2 (control does not extend Region there)
if (node instanceof Region || node instanceof Control) {
double prefWidth = node instanceof Region ? ((Region) node).getMaxWidth() : ((Control) node).getMaxWidth();
if (prefWidth == USE_COMPUTED_SIZE || prefWidth == USE_PREF_SIZE)
return LayoutUtil.INF;
}
return (int) Math.ceil(node.maxWidth(height));
}
@Override
public int getHeight()
{
int v = (int) Math.ceil(node.getLayoutBounds().getHeight());
return v;
}
@Override
public int getMinimumHeight(int width)
{
int v = (int) Math.ceil(this.node.minHeight(width));
return v;
}
@Override
public int getPreferredHeight(int width)
{
int v = (int) Math.ceil(this.node.prefHeight(width));
// for debugging System.out.println(getComponent() + " FXComponentWrapper.getPreferredHeight -> node.prefHeight(" + width + ")=" + this.node.prefHeight(width));
return v;
}
@Override
public int getMaximumHeight(int width)
{
// backwards compatibility with JavaFX2 (control does not extend Region there)
if (node instanceof Region || node instanceof Control) {
double prefWidth = node instanceof Region ? ((Region) node).getMaxHeight() : ((Control) node).getMaxHeight();
if (prefWidth == USE_COMPUTED_SIZE || prefWidth == USE_PREF_SIZE)
return LayoutUtil.INF;
}
return (int) Math.ceil(node.maxHeight(width));
}
@Override
public int getBaseline(int width, int height)
{
return (int) Math.round(node.getBaselineOffset());
}
@Override
public boolean hasBaseline()
{
// For some reason not resizable just return their height as the baseline, not BASELINE_OFFSET_SAME_AS_HEIGHT as logic would suggest.
// For more info : https://bugs.openjdk.java.net/browse/JDK-8091288
return node.isResizable() && node.getBaselineOffset() != BASELINE_OFFSET_SAME_AS_HEIGHT;
}
@Override
public int getScreenLocationX()
{
// this code is called when absolute layout is used
Bounds lBoundsInSceneNode = node.localToScene(node.getBoundsInLocal());
int v = (int) (node.getScene().getX() + node.getScene().getX() + lBoundsInSceneNode.getMinX());
// for debugging System.out.println(getComponent() + " getScreenLocationX =" + v);
return v;
}
@Override
public int getScreenLocationY()
{
// this code is called when absolute layout is used
Bounds lBoundsInSceneNode = node.localToScene(node.getBoundsInLocal());
int v = (int) (node.getScene().getY() + node.getScene().getY() + lBoundsInSceneNode.getMinY());
// for debugging System.out.println(getComponent() + " getScreenLocationX =" + v);
return v;
}
@Override
public int getScreenHeight()
{
// this code is never called?
int v = (int) Math.ceil(Screen.getPrimary().getBounds().getHeight());
// for debugging System.out.println(getComponent() + " getScreenHeight=" + v);
return v;
}
@Override
public int getScreenWidth()
{
// this code is never called?
int v = (int) Math.ceil(Screen.getPrimary().getBounds().getWidth());
// for debugging System.out.println(getComponent() + " getScreenWidth=" + v);
return v;
}
@Override
public int[] getVisualPadding()
{
return null;
}
@Override
public int getHorizontalScreenDPI()
{
// todo Made static to defeat JavaFX bug: https://bugs.openjdk.java.net/browse/JDK-8095013
// todo NOTE Also remove the static block at the top of this file that sets the default DPI on the platform to 96 DPI which makes LP and PX 1:1.
// todo All references to Screen.getPrimary() should be replaced with getting the actual screen the Node is on.
return 96; // E.g. 101 on a 30" and 109 on 27" Apple Cinema Display.
// return (int) Math.ceil(Screen.getPrimary().getDpi());
}
@Override
public int getVerticalScreenDPI()
{
// todo Made static to defeat JavaFX bug: https://bugs.openjdk.java.net/browse/JDK-8095013
return 96; // E.g. 101 on a 30" and 109 on 27" Apple Cinema Display.
// return (int) Math.ceil(Screen.getPrimary().getDpi());
}
@Override
public float getPixelUnitFactor(boolean isHor)
{
switch (PlatformDefaults.getLogicalPixelBase()) {
case PlatformDefaults.BASE_FONT_SIZE:
return 1.0f; // todo
case PlatformDefaults.BASE_SCALE_FACTOR:
Float s = isHor ? PlatformDefaults.getHorizontalScaleFactor() : PlatformDefaults.getVerticalScaleFactor();
if (s == null)
s = 1.0f;
return s * (isHor ? getHorizontalScreenDPI() : getVerticalScreenDPI()) / (float) PlatformDefaults.getDefaultDPI();
default:
return 1f;
}
}
@Override
public int getLayoutHashCode()
{
return 0; // Not used in MigPane.
}
@Override
public String getLinkId()
{
return node.getId();
}
@Override
public boolean isVisible()
{
return node.isVisible();
}
@Override
public int getContentBias()
{
Orientation bias = node.getContentBias();
return bias == null ? -1 : bias.ordinal(); // 0 == Orientation.HORIZONTAL and Orientation.HORIZONTAL, 1 = Orientation.VERTICAL and LayoutUtil.VERTICAL
}
@Override
public void paintDebugOutline(boolean useVisualPadding)
{
CC lCC = wrapperToCCMap.get(this);
DebugRectangleType type = lCC != null && lCC.isExternal() ? DebugRectangleType.EXTERNAL : DebugRectangleType.OUTLINE;
addDebugRectangle(this.node.getLayoutX() + this.node.getLayoutBounds().getMinX(), (double) this.node.getLayoutY() + this.node.getLayoutBounds().getMinY(), getWidth(), getHeight(), type); // always draws node size, even if less is used
}
@Override
public int hashCode()
{
return node.hashCode();
}
/**
* This needs to be overridden so that different wrappers that hold the same component compare
* as equal. Otherwise, Grid won't be able to layout the components correctly.
*/
@Override
public boolean equals(Object o)
{
if (!(o instanceof FXComponentWrapper))
return false;
return getComponent().equals(((FXComponentWrapper) o).getComponent());
}
@Override
public void setBounds(int x, int y, int width, int height)
{
// System.out.println(getComponent() + " FXComponentWrapper.setBound x=" + x + ",y=" + y + " / w=" + width + ",h=" + height + " / resizable=" + this.node.isResizable());
// System.out.println("x: " + x + ", y: " + y);
// CC cc = wrapperToCCMap.get(this);
if (!animateBoundsChange(node, x, y, width, height))
node.resizeRelocate((double) x, (double) y, (double) width, (double) height);
}
}
}
miglayout-5.1/javafx/src/main/java/org/tbee/javafx/scene/layout/fxml/000077500000000000000000000000001324101563200256465ustar00rootroot00000000000000miglayout-5.1/javafx/src/main/java/org/tbee/javafx/scene/layout/fxml/MigPane.java000077500000000000000000000037021324101563200300360ustar00rootroot00000000000000package org.tbee.javafx.scene.layout.fxml;
import javafx.beans.DefaultProperty;
import javafx.scene.Node;
import net.miginfocom.layout.CC;
import net.miginfocom.layout.ConstraintParser;
/**
* This class provides some API enhancements to implement FXML (and this keep the original's API clean)
* @author User
*
*/
@DefaultProperty(value = "children") // for FXML integration
public class MigPane extends org.tbee.javafx.scene.layout.MigPane
{
// The FXML simply is matching tag- and attributes names to classes and properties (getter/setter) in the imported Java files
// Many thanks to Michael Paus for the grunt work!
/** layout called in FXML on MigPane itself */
public void setLayout(String value)
{
this.fxmLayoutConstraints = value;
setLayoutConstraints( ConstraintParser.parseLayoutConstraint( ConstraintParser.prepare( value ) ) );
}
public String getLayout() { return fxmLayoutConstraints; }
private String fxmLayoutConstraints;
/** cols called in FXML on MigPane itself */
public void setCols(String value)
{
this.fxmlColumConstraints = value;
setColumnConstraints( ConstraintParser.parseColumnConstraints( ConstraintParser.prepare( value ) ) );
}
public String getCols() { return fxmlColumConstraints; }
private String fxmlColumConstraints;
/** rows called in FXML on MigPane itself */
public void setRows(String value)
{
this.fxmlRowConstraints = value;
setRowConstraints( ConstraintParser.parseRowConstraints( ConstraintParser.prepare( value ) ) );
}
public String getRows() { return fxmlRowConstraints; }
private String fxmlRowConstraints;
/** called from the subnodes in FXML via MigPane.cc="..." */
public static void setCc(Node node, CC cc)
{
node.getProperties().put(FXML_CC_KEY, cc);
}
public static void setCc(Node node, String cc)
{
CC lCC = ConstraintParser.parseComponentConstraint( ConstraintParser.prepare( cc ) );
setCc(node, lCC);
}
}
miglayout-5.1/javafx/src/test/000077500000000000000000000000001324101563200164135ustar00rootroot00000000000000miglayout-5.1/javafx/src/test/java/000077500000000000000000000000001324101563200173345ustar00rootroot00000000000000miglayout-5.1/javafx/src/test/java/org/000077500000000000000000000000001324101563200201235ustar00rootroot00000000000000miglayout-5.1/javafx/src/test/java/org/tbee/000077500000000000000000000000001324101563200210425ustar00rootroot00000000000000miglayout-5.1/javafx/src/test/java/org/tbee/javafx/000077500000000000000000000000001324101563200223215ustar00rootroot00000000000000miglayout-5.1/javafx/src/test/java/org/tbee/javafx/scene/000077500000000000000000000000001324101563200234165ustar00rootroot00000000000000miglayout-5.1/javafx/src/test/java/org/tbee/javafx/scene/layout/000077500000000000000000000000001324101563200247335ustar00rootroot00000000000000miglayout-5.1/javafx/src/test/java/org/tbee/javafx/scene/layout/test/000077500000000000000000000000001324101563200257125ustar00rootroot00000000000000miglayout-5.1/javafx/src/test/java/org/tbee/javafx/scene/layout/test/MigPaneInternalLayoutTest.java000066400000000000000000000412321324101563200336320ustar00rootroot00000000000000package org.tbee.javafx.scene.layout.test;
import java.util.List;
import javafx.scene.Parent;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.TextAlignment;
import javafx.stage.Stage;
import jfxtras.test.AssertNode;
import jfxtras.test.TestUtil;
import jfxtras.util.PlatformUtil;
import net.miginfocom.layout.AC;
import net.miginfocom.layout.CC;
import net.miginfocom.layout.LC;
import net.miginfocom.layout.PlatformDefaults;
import org.junit.Assert;
import org.junit.Test;
import org.tbee.javafx.scene.layout.MigPane;
/**
* TestFX is able to layout a single node per class.
* Because we would be creating MigPane only once, this would result in one class with one test method per to-be-tested layout, and thus is a LOT of classes.
* By placing MigPane in a presized Pane, it is possible to test different layouts each in a separate method, all in a single class.
* The drawback is that MigPane is never tested stand alone, as the root node, so for each test it must be decided if we can put it in here, or if it needs a test class on its own.
*
* @author Tom Eugelink
*
*/
public class MigPaneInternalLayoutTest extends org.loadui.testfx.GuiTest {
@Override
protected Parent getRootNode() {
PlatformDefaults.setDefaultDPI(96);
PlatformDefaults.setPlatform(PlatformDefaults.WINDOWS_XP);
// use a pane to force the scene large enough, migpane is placed top-left
pane = new Pane();
pane.setMinSize(1000, 600);
// just for readability; place a label
label = new Label();
label.layoutYProperty().bind(pane.minHeightProperty().subtract(20));
pane.getChildren().add(label);
// done
return pane;
}
private Pane pane = null;
private Label label = null;
@Test
public void twoChildBasicLayout() {
loadCSS();
setLabel("twoChildBasicLayout");
MigPane migPane = TestUtil.runThenWaitForPaintPulse( () -> {
MigPane constructMigPane = new MigPane(new LC().debug(1000), new AC(), new AC());
pane.getChildren().add(constructMigPane);
// add nodes
constructMigPane.add(new TextField(), new CC());
constructMigPane.add(new Rectangle(30,30, Color.YELLOW), new CC());
return constructMigPane;
});
//generateSource(migPane);
assertWH(migPane, 187.0, 45.0);
new AssertNode(migPane.getChildren().get(0)).assertXYWH(7.0, 7.0, 136.0, 31.0, 0.01).assertClass(javafx.scene.control.TextField.class);
new AssertNode(migPane.getChildren().get(1)).assertXYWH(150.0, 8.0, 30.0, 30.0, 0.01).assertClass(javafx.scene.shape.Rectangle.class); }
@Test
public void wrappingLabel() {
loadCSS();
setLabel("wrappingLabel");
MigPane migPane = TestUtil.runThenWaitForPaintPulse( () -> {
MigPane constructMigPane = new MigPane(new LC().width("400px").debug(1000), new AC(), new AC());
pane.getChildren().add(constructMigPane);
// add nodes
Label label = new Label("Test long label to see if the wrap works ok in a Migpane. I am going to have to keep writing because this may not be long enough yet!!");
label.setWrapText(true);
constructMigPane.add(label, new CC().grow());
return constructMigPane;
});
//generateSource(migPane);
assertWH(migPane, 400.0, 90.0);
new AssertNode(migPane.getChildren().get(0)).assertXYWH(7.0, 7.0, 386.0, 76.0, 0.01).assertClass(javafx.scene.control.Label.class);
}
@Test
public void size() {
loadCSS();
setLabel("size");
MigPane migPane = TestUtil.runThenWaitForPaintPulse( () -> {
MigPane constructMigPane = new MigPane(new LC().debug().fillX(), new AC(), new AC());
pane.getChildren().add(constructMigPane);
// add nodes
constructMigPane.add(new Button("500 logical pixels (def)"), "w 500, wrap");
constructMigPane.add(new Button("500 logical pixels"), "w 500lp, wrap");
constructMigPane.add(new Button("500 pixels"), "w 500px, wrap");
constructMigPane.add(new Button("10 centimeters"), "w 10cm, wrap");
constructMigPane.add(new Button("4 inches"), "w 4in, wrap");
constructMigPane.add(new Button("30% of screen"), "w 30sp, wrap");
constructMigPane.add(new Button("30% of container"), "w 30%, wrap");
return constructMigPane;
});
//generateSource(migPane);
assertWH(migPane, 781.0, 280.0);
new AssertNode(migPane.getChildren().get(0)).assertXYWH(7.0, 7.0, 500.0, 31.0, 0.01).assertClass(javafx.scene.control.Button.class);
new AssertNode(migPane.getChildren().get(1)).assertXYWH(7.0, 45.0, 500.0, 31.0, 0.01).assertClass(javafx.scene.control.Button.class);
new AssertNode(migPane.getChildren().get(2)).assertXYWH(7.0, 83.0, 500.0, 31.0, 0.01).assertClass(javafx.scene.control.Button.class);
new AssertNode(migPane.getChildren().get(3)).assertXYWH(7.0, 121.0, 378.0, 31.0, 0.01).assertClass(javafx.scene.control.Button.class);
new AssertNode(migPane.getChildren().get(4)).assertXYWH(7.0, 159.0, 384.0, 31.0, 0.01).assertClass(javafx.scene.control.Button.class);
new AssertNode(migPane.getChildren().get(5)).assertXYWH(7.0, 197.0, 767.0, 31.0, 0.01).assertClass(javafx.scene.control.Button.class);
new AssertNode(migPane.getChildren().get(6)).assertXYWH(7.0, 235.0, 234.0, 31.0, 0.01).assertClass(javafx.scene.control.Button.class);
}
@Test
public void pack() {
loadCSS();
setLabel("pack");
final Label label = new Label("Pack it up!");
final MigPane migPane = TestUtil.runThenWaitForPaintPulse( () -> {
MigPane constructMigPane = new MigPane(new LC().pack().packAlign(0.5f, 1f), new AC(), new AC());
pane.getChildren().add(constructMigPane);
// add nodes
constructMigPane.add(label, "alignx center, wrap unrel");
Label wrapLabel = new Label("The only thing changed\nis the font size");
wrapLabel.setTextAlignment(TextAlignment.CENTER);
constructMigPane.add(wrapLabel, "alignx center");
return constructMigPane;
});
//generateSource(migPane);
assertWH(migPane, 226.0, 82.0);
new AssertNode(migPane.getChildren().get(0)).assertXYWH(60.0, 7.0, 106.0, 19.0, 0.01).assertClass(javafx.scene.control.Label.class);
new AssertNode(migPane.getChildren().get(1)).assertXYWH(7.0, 37.0, 212.0, 38.0, 0.01).assertClass(javafx.scene.control.Label.class);
// increase font size
TestUtil.runThenWaitForPaintPulse( () -> {
label.setFont(new Font(50));
return null;
});
//generateSource(migPane);
assertWH(migPane, 244.0, 136.0);
new AssertNode(migPane.getChildren().get(0)).assertXYWH(7.0, 7.0, 230.0, 73.0, 0.01).assertClass(javafx.scene.control.Label.class);
new AssertNode(migPane.getChildren().get(1)).assertXYWH(16.0, 91.0, 212.0, 38.0, 0.01).assertClass(javafx.scene.control.Label.class);
// increase font size
TestUtil.runThenWaitForPaintPulse( () -> {
label.setFont(new Font(100));
return null;
});
//generateSource(migPane);
assertWH(migPane, 474.0, 209.0);
new AssertNode(migPane.getChildren().get(0)).assertXYWH(7.0, 7.0, 460.0, 146.0, 0.01).assertClass(javafx.scene.control.Label.class);
new AssertNode(migPane.getChildren().get(1)).assertXYWH(131.0, 164.0, 212.0, 38.0, 0.01).assertClass(javafx.scene.control.Label.class);
}
@Test
public void wrap() {
loadCSS();
setLabel("wrap");
MigPane migPane = TestUtil.runThenWaitForPaintPulse( () -> {
MigPane constructMigPane = new MigPane(new LC().debug().fillX(), new AC(), new AC());
pane.getChildren().add(constructMigPane);
// add nodes
for (int i = 0; i < 10; i++)
{
TextField lRectangle = new TextField();
CC lCC = new CC();
if ((i + 1) % 3 == 0) {
lCC = lCC.growX().wrap(); // wrap every 3rd
}
constructMigPane.add(lRectangle, lCC);
}
return constructMigPane;
});
//generateSource(migPane);
assertWH(migPane, 436.0, 159.0);
new AssertNode(migPane.getChildren().get(0)).assertXYWH(7.0, 7.0, 136.0, 31.0, 0.01).assertClass(javafx.scene.control.TextField.class);
new AssertNode(migPane.getChildren().get(1)).assertXYWH(150.0, 7.0, 136.0, 31.0, 0.01).assertClass(javafx.scene.control.TextField.class);
new AssertNode(migPane.getChildren().get(2)).assertXYWH(293.0, 7.0, 136.0, 31.0, 0.01).assertClass(javafx.scene.control.TextField.class);
new AssertNode(migPane.getChildren().get(3)).assertXYWH(7.0, 45.0, 136.0, 31.0, 0.01).assertClass(javafx.scene.control.TextField.class);
new AssertNode(migPane.getChildren().get(4)).assertXYWH(150.0, 45.0, 136.0, 31.0, 0.01).assertClass(javafx.scene.control.TextField.class);
new AssertNode(migPane.getChildren().get(5)).assertXYWH(293.0, 45.0, 136.0, 31.0, 0.01).assertClass(javafx.scene.control.TextField.class);
new AssertNode(migPane.getChildren().get(6)).assertXYWH(7.0, 83.0, 136.0, 31.0, 0.01).assertClass(javafx.scene.control.TextField.class);
new AssertNode(migPane.getChildren().get(7)).assertXYWH(150.0, 83.0, 136.0, 31.0, 0.01).assertClass(javafx.scene.control.TextField.class);
new AssertNode(migPane.getChildren().get(8)).assertXYWH(293.0, 83.0, 136.0, 31.0, 0.01).assertClass(javafx.scene.control.TextField.class);
new AssertNode(migPane.getChildren().get(9)).assertXYWH(7.0, 121.0, 136.0, 31.0, 0.01).assertClass(javafx.scene.control.TextField.class);
}
@Test
public void external() {
loadCSS();
setLabel("external");
MigPane migPane = TestUtil.runThenWaitForPaintPulse( () -> {
MigPane constructMigPane = new MigPane(new LC().debug().fillX(), new AC(), new AC());
pane.getChildren().add(constructMigPane);
// add managed nodes
constructMigPane.add(new TextField(), new CC());
constructMigPane.add(new Rectangle(30,30, Color.RED), new CC());
// add external (not unmanaged..) nodes
Rectangle rectangle = new Rectangle(100, 50, 30, 30);
constructMigPane.add(rectangle, new CC().external());
return constructMigPane;
});
//generateSource(migPane);
assertWH(migPane, 187.0, 45.0);
new AssertNode(migPane.getChildren().get(0)).assertXYWH(7.0, 7.0, 136.0, 31.0, 0.01).assertClass(javafx.scene.control.TextField.class);
new AssertNode(migPane.getChildren().get(1)).assertXYWH(150.0, 8.0, 30.0, 30.0, 0.01).assertClass(javafx.scene.shape.Rectangle.class);
new AssertNode(migPane.getChildren().get(2)).assertXYWH(0.0, 0.0, 130.0, 80.0, 0.01).assertClass(javafx.scene.shape.Rectangle.class);
}
@Test
public void defaultLayout() {
loadCSS();
setLabel("defaultLayout");
MigPane migPane = TestUtil.runThenWaitForPaintPulse( () -> {
MigPane constructMigPane = new MigPane(new LC().debug().fillX(), new AC(), new AC());
pane.getChildren().add(constructMigPane);
// add nodes
constructMigPane.add(new Label("First name"), "");
constructMigPane.add(new TextField(), "");
constructMigPane.add(new Label("Last name"), "gap unrelated");
constructMigPane.add(new TextField(), "wrap");
constructMigPane.add(new Label("Address"), "");
constructMigPane.add(new TextField(), "span, grow");
return constructMigPane;
});
//generateSource(migPane);
assertWH(migPane, 502.0, 83.0);
new AssertNode(migPane.getChildren().get(0)).assertXYWH(7.0, 13.0, 97.0, 19.0, 0.01).assertClass(javafx.scene.control.Label.class);
new AssertNode(migPane.getChildren().get(1)).assertXYWH(111.0, 7.0, 136.0, 31.0, 0.01).assertClass(javafx.scene.control.TextField.class);
new AssertNode(migPane.getChildren().get(2)).assertXYWH(265.0, 13.0, 87.0, 19.0, 0.01).assertClass(javafx.scene.control.Label.class);
new AssertNode(migPane.getChildren().get(3)).assertXYWH(359.0, 7.0, 136.0, 31.0, 0.01).assertClass(javafx.scene.control.TextField.class);
new AssertNode(migPane.getChildren().get(4)).assertXYWH(7.0, 51.0, 68.0, 19.0, 0.01).assertClass(javafx.scene.control.Label.class);
new AssertNode(migPane.getChildren().get(5)).assertXYWH(111.0, 45.0, 384.0, 31.0, 0.01).assertClass(javafx.scene.control.TextField.class);
}
@Test
public void span() {
loadCSS();
setLabel("span");
MigPane migPane = TestUtil.runThenWaitForPaintPulse( () -> {
MigPane constructMigPane = new MigPane(new LC().debug().fillX(), new AC(), new AC());
pane.getChildren().add(constructMigPane);
// add nodes
for (int i = 0; i < 10; i++)
{
constructMigPane.add(new Button("MMMMMMMMMMMMMMMMMMMMMMMMMMMM".substring(0, i + 1)), i < 9 ? new CC() : new CC().wrap());
}
for (int i = 1; i < 10; i++)
{
constructMigPane.add(new Button("MMMMMMMMMMMMMMMMMMMMMMMMMMMM".substring(0, i + 1)), new CC().wrap().spanX());
}
return constructMigPane;
});
//generateSource(migPane);
assertWH(migPane, 831.0, 394.0);
new AssertNode(migPane.getChildren().get(0)).assertXYWH(7.0, 7.0, 32.0, 31.0, 0.01).assertClass(javafx.scene.control.Button.class);
new AssertNode(migPane.getChildren().get(1)).assertXYWH(46.0, 7.0, 42.0, 31.0, 0.01).assertClass(javafx.scene.control.Button.class);
new AssertNode(migPane.getChildren().get(2)).assertXYWH(95.0, 7.0, 51.0, 31.0, 0.01).assertClass(javafx.scene.control.Button.class);
new AssertNode(migPane.getChildren().get(3)).assertXYWH(153.0, 7.0, 61.0, 31.0, 0.01).assertClass(javafx.scene.control.Button.class);
new AssertNode(migPane.getChildren().get(4)).assertXYWH(221.0, 7.0, 71.0, 31.0, 0.01).assertClass(javafx.scene.control.Button.class);
new AssertNode(migPane.getChildren().get(5)).assertXYWH(299.0, 7.0, 80.0, 31.0, 0.01).assertClass(javafx.scene.control.Button.class);
new AssertNode(migPane.getChildren().get(6)).assertXYWH(386.0, 7.0, 90.0, 31.0, 0.01).assertClass(javafx.scene.control.Button.class);
new AssertNode(migPane.getChildren().get(7)).assertXYWH(483.0, 7.0, 99.0, 31.0, 0.01).assertClass(javafx.scene.control.Button.class);
new AssertNode(migPane.getChildren().get(8)).assertXYWH(589.0, 7.0, 109.0, 31.0, 0.01).assertClass(javafx.scene.control.Button.class);
new AssertNode(migPane.getChildren().get(9)).assertXYWH(705.0, 7.0, 119.0, 31.0, 0.01).assertClass(javafx.scene.control.Button.class);
new AssertNode(migPane.getChildren().get(10)).assertXYWH(7.0, 45.0, 42.0, 31.0, 0.01).assertClass(javafx.scene.control.Button.class);
new AssertNode(migPane.getChildren().get(11)).assertXYWH(7.0, 83.0, 51.0, 31.0, 0.01).assertClass(javafx.scene.control.Button.class);
new AssertNode(migPane.getChildren().get(12)).assertXYWH(7.0, 121.0, 61.0, 31.0, 0.01).assertClass(javafx.scene.control.Button.class);
new AssertNode(migPane.getChildren().get(13)).assertXYWH(7.0, 159.0, 71.0, 31.0, 0.01).assertClass(javafx.scene.control.Button.class);
new AssertNode(migPane.getChildren().get(14)).assertXYWH(7.0, 197.0, 80.0, 31.0, 0.01).assertClass(javafx.scene.control.Button.class);
new AssertNode(migPane.getChildren().get(15)).assertXYWH(7.0, 235.0, 90.0, 31.0, 0.01).assertClass(javafx.scene.control.Button.class);
new AssertNode(migPane.getChildren().get(16)).assertXYWH(7.0, 273.0, 99.0, 31.0, 0.01).assertClass(javafx.scene.control.Button.class);
new AssertNode(migPane.getChildren().get(17)).assertXYWH(7.0, 311.0, 109.0, 31.0, 0.01).assertClass(javafx.scene.control.Button.class);
new AssertNode(migPane.getChildren().get(18)).assertXYWH(7.0, 349.0, 119.0, 31.0, 0.01).assertClass(javafx.scene.control.Button.class);
}
// =============================================================================================================================================================================================================================
// SUPPORT
List EXCLUDED_CLASSES = java.util.Arrays.asList(new String[]{"org.tbee.javafx.scene.layout.MigPane$DebugRectangle"});
private void assertWH(MigPane migPane, double w, double h) {
Assert.assertEquals(w, migPane.getWidth(), 0.01);
Assert.assertEquals(h, migPane.getHeight(), 0.01);
}
private void setLabel(String s) {
PlatformUtil.runAndWait( () -> {
label.setText(s);
});
}
private void generateSource(Pane pane) {
System.out.println(label.getText());
System.out.println("assertWH(migPane, " + pane.getWidth() + ", " + pane.getHeight() + ");");
AssertNode.generateSource("migPane", pane.getChildren(), EXCLUDED_CLASSES, false, AssertNode.A.XYWH, AssertNode.A.CLASS);
TestUtil.sleep(3000);
}
private void loadCSS() {
TestUtil.runThenWaitForPaintPulse( () -> {
Stage lStage = (Stage)getWindows().get(0);
lStage.getScene().getStylesheets().addAll(this.getClass().getResource("MigPaneInternalLayoutTest.css").toExternalForm());
});
}
}
miglayout-5.1/javafx/src/test/java/org/tbee/javafx/scene/layout/trial/000077500000000000000000000000001324101563200260465ustar00rootroot00000000000000miglayout-5.1/javafx/src/test/java/org/tbee/javafx/scene/layout/trial/AnimDemo.java000066400000000000000000000031651324101563200304070ustar00rootroot00000000000000package org.tbee.javafx.scene.layout.trial;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;
import org.tbee.javafx.scene.layout.LayoutAnimator;
import org.tbee.javafx.scene.layout.MigPane;
import java.util.Random;
import static javafx.animation.Timeline.INDEFINITE;
/**
* @author Mikael Grev, MiG InfoCom AB
* Date: 14-09-25
* Time: 20:43
*/
public class AnimDemo extends Application
{
private final Random random = new Random(1);
private MigPane pane;
public static void main(String[] args)
{
launch(args);
}
public void start(Stage stage)
{
pane = new MigPane("flowy, align center center");
stage.setScene(new Scene(pane, 600, 800));
stage.sizeToScene();
stage.show();
for (int i = 0; i++ < 3;)
pane.add(getIx(), createRect());
Timeline timer = new Timeline(new KeyFrame(new Duration(LayoutAnimator.ANIM_DURATION.toMillis() + 300), e -> {
if (Math.random() > 0.6 || pane.getChildren().size() < 3) {
pane.add(getIx(), createRect(), "");
} else {
pane.remove(getIx());
}
}));
timer.setCycleCount(INDEFINITE);
timer.play();
}
private int getIx()
{
int size = pane.getChildren().size();
return size == 0 ? 0 : random.nextInt(size);
}
private Rectangle createRect()
{
Rectangle rect = new Rectangle(500, 100);
rect.setFill(Color.color(Math.random(), Math.random(), Math.random()));
rect.setArcHeight(15);
rect.setArcWidth(15);
return rect;
}
}
miglayout-5.1/javafx/src/test/java/org/tbee/javafx/scene/layout/trial/MigPaneBaselineTrial.java000066400000000000000000000021141324101563200326660ustar00rootroot00000000000000package org.tbee.javafx.scene.layout.trial;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.text.Font;
import javafx.stage.Stage;
import net.miginfocom.layout.AC;
import net.miginfocom.layout.LC;
import org.tbee.javafx.scene.layout.MigPane;
/**
* Test miglayout managed and unmanaged nodes
* @author Tom Eugelink
*
*/
public class MigPaneBaselineTrial extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
// root
MigPane lRoot = new MigPane(new LC().debug(1000), new AC(), new AC());
// add managed nodes
Label label = new Label("We should");
label.setFont(new Font(40));
lRoot.add(label, "split 2");
lRoot.add(new TextField("have the same baseline"));
// lRoot.add(new Rectangle(30,30, Color.YELLOW), new CC());
// create scene
Scene scene = new Scene(lRoot, -1, -1);
// create stage
stage.setTitle("Test");
stage.setScene(scene);
stage.sizeToScene();
stage.show();
}
}miglayout-5.1/javafx/src/test/java/org/tbee/javafx/scene/layout/trial/MigPaneHidemodeTrial.java000066400000000000000000000044611324101563200326710ustar00rootroot00000000000000package org.tbee.javafx.scene.layout.trial;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Separator;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
import net.miginfocom.layout.AC;
import net.miginfocom.layout.LC;
import org.tbee.javafx.scene.layout.MigPane;
/**
* @author Mikael Grev, MiG InfoCom AB
* Date: 14-04-29
* Time: 14:22
*/
public class MigPaneHidemodeTrial extends Application
{
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
// add managed nodes
Button button = new Button("Change Visibility");
TextField textField0 = new TextField("hidemode 0");
TextField textField1 = new TextField("hidemode 1");
TextField textField2 = new TextField("hidemode 2");
TextField textField3 = new TextField("hidemode 3");
MigPane pane = new MigPane(new LC().debug().pack(), new AC(), new AC());
pane.add(button, "wrap");
pane.add(new Separator(), "growx, wrap");
pane.add(textField0, "hidemode 0, gap 10 10 10 10, wrap");
pane.add(new Separator(), "growx, wrap");
pane.add(textField1, "hidemode 1, gap 10 10 10 10, wrap");
pane.add(new Separator(), "growx, wrap");
pane.add(textField2, "hidemode 2, gap 10 10 10 10, wrap");
pane.add(new Separator(), "growx, wrap");
pane.add(textField3, "hidemode 3, gap 10 10 10 10, wrap");
pane.add(new Separator(), "growx, wrap");
// VBox pane = new VBox();
// pane.getChildren().add(button);
// pane.getChildren().add(new Separator());
// pane.getChildren().add(textField0);
// pane.getChildren().add(new Separator());
// pane.getChildren().add(textField1);
// pane.getChildren().add(new Separator());
// pane.getChildren().add(textField2);q
// pane.getChildren().add(new Separator());
// pane.getChildren().add(textField3);
// pane.getChildren().add(new Separator());
button.setOnAction(event -> {
textField0.setVisible(!textField0.isVisible());
textField1.setVisible(!textField1.isVisible());
textField2.setVisible(!textField2.isVisible());
textField3.setVisible(!textField3.isVisible());
});
// create scene
Scene scene = new Scene(pane, -1, -1);
// create stage
stage.setTitle("Test");
stage.setScene(scene);
stage.sizeToScene();
stage.show();
}
}
miglayout-5.1/javafx/src/test/java/org/tbee/javafx/scene/layout/trial/MigPanePackTrial.java000066400000000000000000000032121324101563200320220ustar00rootroot00000000000000package org.tbee.javafx.scene.layout.trial;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.text.Font;
import javafx.scene.text.TextAlignment;
import javafx.stage.Stage;
import javafx.util.Duration;
import net.miginfocom.layout.LC;
import org.tbee.javafx.scene.layout.MigPane;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* Test miglayout managed and unmanaged nodes
* @author Tom Eugelink
*
*/
public class MigPanePackTrial extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
// root
MigPane rootMP = new MigPane(new LC().pack().packAlign(0.5f, 1f));
// add managed nodes
Label label = new Label("Pack it up!");
rootMP.add(label, "alignx center, wrap unrel");
Label wrapLabel = new Label("The only thing changed\nis the font size");
wrapLabel.setTextAlignment(TextAlignment.CENTER);
rootMP.add(wrapLabel, "alignx center");
// create scene
Scene scene = new Scene(rootMP);
// create stage
stage.setTitle("Pack Trial");
stage.setScene(scene);
stage.sizeToScene();
stage.show();
AtomicBoolean up = new AtomicBoolean(true);
Timeline timeline = new Timeline(new KeyFrame(Duration.millis(40), event -> {
double oldSize = label.getFont().getSize();
if (oldSize > 100) {
up.set(false);
} else if (oldSize < 10) {
up.set(true);
stage.centerOnScreen();
}
label.setFont(new Font(oldSize + (up.get() ? 2 : -2)));
}));
timeline.setCycleCount(-1);
timeline.play();
}
}miglayout-5.1/javafx/src/test/java/org/tbee/javafx/scene/layout/trial/MigPanePosTrial.java000066400000000000000000000017701324101563200317140ustar00rootroot00000000000000package org.tbee.javafx.scene.layout.trial;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.FlowPane;
import javafx.stage.Stage;
import org.tbee.javafx.scene.layout.MigPane;
/**
* Created by user mikaelgrev on 18-01-16.
*/
public class MigPanePosTrial extends Application
{
public static void main(String[] args)
{
launch(args);
}
@Override
public void start(Stage stage)
{
MigPane migPane = new MigPane("debug");
FlowPane flowPane = new FlowPane();
flowPane.getChildren().add(new Label("1"));
flowPane.getChildren().add(new Label("2"));
flowPane.getChildren().add(new Label("3"));
migPane.add(new Label("3"), "pos container.x 0");
// migPane.add(new Label("3"), "pos 0 0"); // This instead of above made it always work.
migPane.add(flowPane, "");
// Before fix to Grid.java in 2018-01-16 the flowpane became too large.
Scene scene = new Scene(migPane);
stage.setScene(scene);
stage.show();
}
}
miglayout-5.1/javafx/src/test/java/org/tbee/javafx/scene/layout/trial/MigPaneSizeGroupTrial18.java000066400000000000000000000021621324101563200332470ustar00rootroot00000000000000package org.tbee.javafx.scene.layout.trial;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.stage.Stage;
import org.tbee.javafx.scene.layout.MigPane;
/**
* @author Mikael Grev, MiG InfoCom AB
* Date: 15-10-07
* Time: 21:11
*/
public class MigPaneSizeGroupTrial18 extends Application
{
public static void main(String[] args)
{
launch(args);
}
@Override
public void start(Stage stage)
{
// root
MigPane pane = new MigPane("debug");
// add managed nodes
pane.add(new Label("Should have same sizes as ->"), "sgx");
pane.add(new Label("Short"), "sgx");
// With this line the layout will not be correct pre 2015-10-07 fix since the Grid is created
// with the Scene set to null
pane.prefHeight(-1);
// Add this and it till work again since it clears the grid. Adding "nocache"
// to the LC in the constructor also works.
// pane.invalidateGrid();
// create scene
Scene scene = new Scene(pane, -1, -1);
// create stage
stage.setTitle("Test");
stage.setScene(scene);
stage.sizeToScene();
stage.show();
}
}
miglayout-5.1/javafx/src/test/java/org/tbee/javafx/scene/layout/trial/MigPaneSizeTrial.java000066400000000000000000000025011324101563200320560ustar00rootroot00000000000000package org.tbee.javafx.scene.layout.trial;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.stage.Stage;
import net.miginfocom.layout.LC;
import org.tbee.javafx.scene.layout.MigPane;
/**
* @author Mikael Grev, MiG InfoCom AB
* Date: 14-04-24
* Time: 16:33
*/
public class MigPaneSizeTrial extends Application
{
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
// root
MigPane lRoot = new MigPane(new LC().debug().fillX());
// System.out.println(Screen.getPrimary().getDpi());
// System.out.println(Toolkit.getDefaultToolkit().getScreenResolution());
// add nodes
lRoot.add(new Button("500 logical pixels (def)"), "w 500, wrap");
lRoot.add(new Button("500 logical pixels"), "w 500lp, wrap");
lRoot.add(new Button("500 pixels"), "w 500px, wrap");
lRoot.add(new Button("10 centimeters"), "w 10cm, wrap");
lRoot.add(new Button("4 inches"), "w 4in, wrap");
lRoot.add(new Button("30% of screen"), "w 30sp, wrap");
lRoot.add(new Button("30% of container"), "w 30%, wrap");
// create scene
Scene scene = new Scene(lRoot);
// create stage
stage.setTitle("Test - resize to check container percentage");
stage.setScene(scene);
stage.sizeToScene();
stage.show();
}
}
miglayout-5.1/javafx/src/test/java/org/tbee/javafx/scene/layout/trial/MigPaneTest11.java000066400000000000000000000062061324101563200312370ustar00rootroot00000000000000package org.tbee.javafx.scene.layout.trial;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import org.tbee.javafx.scene.layout.fxml.MigPane;
import java.util.Date;
/**
* This test is ran out of memory because of a memory leak.
*
*/
public class MigPaneTest11 extends Application
{
public static class ListElement extends MigPane
{
public ListElement(int i, Date date)
{
Label title = new Label("Element " + i);
Label info = new Label("element created at: " + date);
getChildren().
add(new VBox(title, info));
Button b1 = new Button("button-1");
Button b2 = new Button("button-2");
Button b3 = new Button("button-3");
b1.setMnemonicParsing(false);
b2.setMnemonicParsing(false);
b3.setMnemonicParsing(false);
getChildren().
add(new HBox(b1, b2, b3));
}
}
public MigPaneTest11()
{
super();
// this.items = FXCollections.observableArrayList();
}
// private ObservableList items;
private Parent createRoot()
{
final ListView listView = new ListView();
// listView.setItems(this.items);
Button testButton = new Button("Start test");
testButton.maxWidth(Double.MAX_VALUE);
testButton.setOnAction(new EventHandler()
{
public void handle(final ActionEvent ev)
{
final Thread t = new Thread()
{
@Override
public void run()
{
for (int loop = 0; loop < Integer.MAX_VALUE; loop++)
{
System.out.println("loop " + loop);
Platform.runLater(new Runnable()
{
public void run()
{
// for (ListElement le : items)
// {
// le.getChildren().clear();
// }
// items.clear();
ObservableList items = FXCollections.observableArrayList();
for (int i = 0; i < 10; i++)
{
items.add(new ListElement(i, new Date()));
}
listView.setItems(items);
}
});
try
{
Thread.sleep(10);
}
catch (final InterruptedException e)
{
// do nothing
}
}
System.out.println("done");
}
};
t.setDaemon(true);
t.start();
}
});
BorderPane borderPane = new BorderPane();
borderPane.setCenter(listView);
borderPane.setBottom(testButton);
return borderPane;
}
@Override
public void start(Stage stage) throws Exception
{
Parent root = createRoot();
scene = new Scene(root);
stage.setScene(scene);
stage.setWidth(800);
stage.setHeight(600);
stage.show();
}
static Scene scene = null;
public static void main(String[] args)
{
launch(args);
}
}
miglayout-5.1/javafx/src/test/java/org/tbee/javafx/scene/layout/trial/MigPaneTest14.java000066400000000000000000000023071324101563200312400ustar00rootroot00000000000000package org.tbee.javafx.scene.layout.trial;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import net.miginfocom.layout.AC;
import net.miginfocom.layout.CC;
import net.miginfocom.layout.LC;
import org.tbee.javafx.scene.layout.MigPane;
/**
* Test miglayout managed and unmanaged nodes
* @author Tom Eugelink
*
*/
public class MigPaneTest14 extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
// root
MigPane lRoot = new MigPane(new LC().debug(1000), new AC(), new AC());
// add managed nodes
lRoot.add(new TextField(), new CC());
lRoot.add(new Rectangle(30,30, Color.YELLOW), new CC());
// add unmanaged (not external..) nodes
Rectangle rectangle = new Rectangle(100, 50, 30, 30); // should not affect bounds or preferred size of MigPane
rectangle.setManaged(false);
lRoot.add(rectangle);
// create scene
Scene scene = new Scene(lRoot, -1, -1);
// create stage
stage.setTitle("Test");
stage.setScene(scene);
stage.sizeToScene();
stage.show();
}
}miglayout-5.1/javafx/src/test/java/org/tbee/javafx/scene/layout/trial/MigPaneTest15.java000066400000000000000000000026031324101563200312400ustar00rootroot00000000000000package org.tbee.javafx.scene.layout.trial;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.stage.Stage;
import org.tbee.javafx.scene.layout.MigPane;
public class MigPaneTest15 extends Application {
public static void main(String[] arguments) {
launch();
}
@Override
public void start(Stage stage) throws Exception {
Scene scene = createScene();
stage.setScene(scene);
showStage(stage);
}
private Scene createScene() {
final MigPane container = new MigPane();
Button control = new Button("Add Content");
control.setOnAction(new EventHandler() {
@Override
public void handle(ActionEvent actionEvent) {
showContent(container);
}
});
MigPane parent = new MigPane("");
parent.add(control);
parent.add(container);
return new Scene(parent);
}
private void showContent(MigPane container) {
container.getChildren().clear();
ComboBox comboBox = new ComboBox<>();
comboBox.getItems().add("There is a label to my left!");
Label label = new Label("I should be visible!");
container.add(label);
container.add(comboBox);
}
private void showStage(Stage stage) {
stage.setHeight(400);
stage.setWidth(800);
stage.show();
}
}miglayout-5.1/javafx/src/test/java/org/tbee/javafx/scene/layout/trial/MigPaneTest3.java000077500000000000000000000035571324101563200311710ustar00rootroot00000000000000package org.tbee.javafx.scene.layout.trial;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.stage.Stage;
import net.miginfocom.layout.AC;
import net.miginfocom.layout.CC;
import net.miginfocom.layout.LC;
import org.tbee.javafx.scene.layout.MigPane;
/**
* Testing if grow and push actually grow stuff
* @author Tom Eugelink
*
*/
public class MigPaneTest3 extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
// root
MigPane lRoot = new MigPane(new LC().debug(1000), new AC(), new AC());
// create 10 buttons
for (int i = 0; i < 5*3; i++)
{
int lRow = (int)(i / 3);
int lCol = (i + 1) % 3;
String lText = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX".substring(0, i + 1);
// add a node
Control lControl = null;
if ( lRow == 0) lControl = new CheckBox(lText);
else if ( lRow == 1) { lControl = new TextField(); ((TextField)lControl).setText(lText); }
else if ( lRow == 2) { lControl = new ChoiceBox(FXCollections.observableArrayList("X", lText, "XX")); ((ChoiceBox)lControl).getSelectionModel().select(1); }
else if ( lRow == 3) { lControl = new ToggleButton(lText); }
else lControl = new Button(lText); // wrong
CC lCC = new CC();
if (lCol == 2) lCC = lCC.grow().push();
if (lCol == 0) lCC = lCC.wrap();
lRoot.add(lControl, lCC);
}
// create scene
Scene scene = new Scene(lRoot, -1, -1);
// create stage
stage.setTitle("Test");
stage.setScene(scene);
stage.sizeToScene();
stage.show();
}
}
miglayout-5.1/javafx/src/test/java/org/tbee/javafx/scene/layout/trial/MigPaneTest5.java000077500000000000000000000020351324101563200311610ustar00rootroot00000000000000package org.tbee.javafx.scene.layout.trial;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import net.miginfocom.layout.CC;
import org.tbee.javafx.scene.layout.MigPane;
/**
* Using string constraints
* @author Tom Eugelink
*
*/
public class MigPaneTest5 extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
// root
MigPane lRoot = new MigPane("debug", "[grow,fill]", "");
// add managed nodes
lRoot.add(new TextField(), "");
// add external (not unmanaged..) nodes
lRoot.add(new Rectangle(100, 50, 30, 30), new CC().external());
// create scene
Scene scene = new Scene(lRoot, -1, -1);
// create stage
stage.setTitle("Test");
stage.setScene(scene);
stage.sizeToScene();
stage.show();
}
}
miglayout-5.1/javafx/src/test/java/org/tbee/javafx/scene/layout/trial/MigPaneTest8.java000077500000000000000000000020071324101563200311630ustar00rootroot00000000000000package org.tbee.javafx.scene.layout.trial;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
import org.tbee.javafx.scene.layout.MigPane;
import java.io.IOException;
import java.net.URL;
/**
* Load a layout from FXML
*
* @author Michael Paus and Tom Eugelink
*
*/
public class MigPaneTest8 extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage)
throws IOException
{
// load FXML
String lName = getClass().getSimpleName() + ".xml";
URL lURL = getClass().getResource("/" + lName);
System.out.println("loading FXML " + lName + " -> " + lURL);
MigPane lRoot = (MigPane)FXMLLoader.load(lURL);
// create scene
Scene scene = new Scene(lRoot, 800, 300);
// create stage
stage.setTitle(this.getClass().getSimpleName());
stage.setScene(scene);
stage.show();
}
}
miglayout-5.1/javafx/src/test/java/org/tbee/javafx/scene/layout/trial/MigPaneTest8Controller.java000077500000000000000000000017161324101563200332350ustar00rootroot00000000000000package org.tbee.javafx.scene.layout.trial;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import org.tbee.javafx.scene.layout.MigPane;
/**
* Handler class for the FXML
*
* @author Michael Paus
* @author Tom Eugelink
*
*/
public class MigPaneTest8Controller extends MigPane
{
@FXML private TextField firstNameField;
@FXML private TextField lastNameField;
@FXML private Label messageLabel;
@SuppressWarnings("unused")
@FXML private void handleButtonAction(ActionEvent event)
{
String fullName = firstNameField.getText() + " " + lastNameField.getText();
if (fullName.length() > 1)
{
messageLabel.setText("Your name '" + fullName + "' was successfully entered into our spam database :-(");
}
else
{
messageLabel.setText("Sorry, but you have to provide your name!");
}
}
}miglayout-5.1/javafx/src/test/java/org/tbee/javafx/scene/layout/trial/MigPaneTest9.java000077500000000000000000000034151324101563200311700ustar00rootroot00000000000000package org.tbee.javafx.scene.layout.trial;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.ButtonBase;
import javafx.scene.control.ToggleButton;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import net.miginfocom.layout.AC;
import net.miginfocom.layout.CC;
import net.miginfocom.layout.LC;
import org.tbee.javafx.scene.layout.MigPane;
/**
* Wrap MigPane in a number of other containers and set a padding.
*
* @author Tom Eugelink
*
*/
public class MigPaneTest9 extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
// root
MigPane lMigPane = new MigPane(new LC().debug(1000).align("center", "center").gridGap("0px", "0px"), new AC(), new AC());
for (int i = 0; i < 9; i++)
{
CC lCC = new CC();
if ((i + 1) % 3 == 0)
{
lCC = lCC.wrap();
}
final ButtonBase btn = new ToggleButton("MMMMMMMMMMMMMMMMMMMMMMMMMMMM".substring(0, i + 1));
if (i == 0)
{
btn.setStyle("-fx-padding: 10; ");
}
lMigPane.add(btn, lCC);
}
// include in stackpane and set a padding
StackPane lStackPane = new StackPane();
lStackPane.getChildren().add(lMigPane);
lStackPane.setStyle("-fx-background-color: yellow; -fx-padding: 10; ");
// create scene
Scene scene = new Scene(new Group(lStackPane), -1, -1);
// create stage
stage.setTitle("ButtonTest");
stage.setScene(scene);
stage.sizeToScene();
stage.show();
}
}miglayout-5.1/javafx/src/test/java/org/tbee/javafx/scene/layout/trial/MigPaneTrial1.java000066400000000000000000000017001324101563200313040ustar00rootroot00000000000000package org.tbee.javafx.scene.layout.trial;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.Button;
import javafx.stage.Stage;
import net.miginfocom.layout.CC;
import net.miginfocom.layout.LC;
import org.tbee.javafx.scene.layout.MigPane;
public class MigPaneTrial1 extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) throws Exception {
MigPane migPane = new MigPane(new LC());
migPane.add(new Label("Label"), new CC().wrap());
migPane.add(new Label("Label"), new CC().wrap().push().grow());
migPane.add(new Label("Label"), new CC().wrap());
Button button = new Button("Button");
// migPane.add(button, new CC().dockWest().grow());
migPane.add(button, new CC().wrap().grow().push());
button.setRotate(90);
Scene scene = new Scene(migPane);
stage.setScene(scene);
stage.show();
}
}miglayout-5.1/javafx/src/test/java/org/tbee/javafx/scene/layout/trial/MigPaneTrial16.java000066400000000000000000000036121324101563200313760ustar00rootroot00000000000000package org.tbee.javafx.scene.layout.trial;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonBase;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.stage.Stage;
import net.miginfocom.layout.CC;
import net.miginfocom.layout.LC;
import org.tbee.javafx.scene.layout.MigPane;
public class MigPaneTrial16 extends Application
{
public static final String PATH_TO_IMAGE = "/MigPaneTrial16.png";
public static void main(String[] arguments) {
// URL url = new MigPaneTrial16().getClass().getResource(PATH_TO_IMAGE);
// System.out.println(url);
launch();
}
@Override
public void start(Stage stage) throws Exception {
Scene scene = createScene();
stage.setScene(scene);
stage.sizeToScene();
stage.show();
}
private Scene createScene() {
MigPane parent = new MigPane(new LC().debug(300));
addRowTo(parent);
return new Scene(parent, 300, 100);
}
boolean b = true;
private void addRowTo(MigPane parent) {
ImageView mainIcon = new ImageView();
Button toggle = new Button("Hello", mainIcon);
sizeUpButton(toggle);
toggle.setOnAction(new EventHandler() {
public void handle(ActionEvent event)
{
if (b) {
mainIcon.setImage(new Image(PATH_TO_IMAGE));
// toggle.getBaselineOffset();
System.out.println("baseline img: " + toggle.getBaselineOffset());
} else {
mainIcon.setImage(null);
System.out.println("baseline: " + toggle.getBaselineOffset());
}
b = !b;
}
});
parent.add(toggle, "");
parent.add(new Label("<-Click the Button"), new CC().growX().pushX());
}
private void sizeUpButton(ButtonBase button) {
// button.setMinSize(20, 20);
// button.setPrefSize(20, 20);
// button.setMaxSize(20, 20);
}
}miglayout-5.1/javafx/src/test/java/org/tbee/javafx/scene/layout/trial/MigPaneTrial17.java000066400000000000000000000011511324101563200313730ustar00rootroot00000000000000package org.tbee.javafx.scene.layout.trial;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.stage.Stage;
import net.miginfocom.layout.LC;
import org.tbee.javafx.scene.layout.MigPane;
public class MigPaneTrial17 extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) throws Exception {
MigPane migPane = new MigPane(new LC().wrapAfter(1));
migPane.getChildren().add(0, new Button("Test"));
Scene scene = new Scene(migPane);
stage.setScene(scene);
stage.show();
}
}miglayout-5.1/javafx/src/test/java/org/tbee/javafx/scene/layout/trial/MigTestTest10.java000066400000000000000000000025261324101563200312730ustar00rootroot00000000000000package org.tbee.javafx.scene.layout.trial;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import org.tbee.javafx.scene.layout.MigPane;
/**
* Test a nested MigPane
*
*/
public class MigTestTest10 extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(final Stage stage) throws InterruptedException {
MigPane lOuterMigPane = new MigPane("debug");
lOuterMigPane.setId("outer");
lOuterMigPane.setDebugCellColor(null);
lOuterMigPane.setDebugOutlineColor(Color.BLUE);
lOuterMigPane.setDebugContainerOutlineColor(Color.BLUE);
lOuterMigPane.add(new Button("In outer MigPane"));
MigPane lNestedMigPane = new MigPane("debug");
lNestedMigPane.setId("nested");
lNestedMigPane.setDebugCellColor(null);
lNestedMigPane.setDebugOutlineColor(Color.RED);
lNestedMigPane.setDebugContainerOutlineColor(Color.RED);
lNestedMigPane.add(new Button("In nested MigPane"));
lOuterMigPane.add(lNestedMigPane);
Scene scene = new Scene(lOuterMigPane);
stage.setScene(scene);
stage.sizeToScene();
stage.show();
}
}
miglayout-5.1/javafx/src/test/resources/000077500000000000000000000000001324101563200204255ustar00rootroot00000000000000miglayout-5.1/javafx/src/test/resources/MigPaneTest8.xml000077500000000000000000000013521324101563200234230ustar00rootroot00000000000000
miglayout-5.1/javafx/src/test/resources/MigPaneTrial16.png000066400000000000000000000017451324101563200236250ustar00rootroot00000000000000�PNG
IHDR��agAMA��|�Q� cHRMz%������u0�`:�o����pIDATx�bd�V��QFz�V
�R�@>��'ϟ��t������G�#�����#?5<5>ęMV�����P�?ï�lO��aX�v�� �W����KP�H@����[�xR����8Ï�~}}����o�-L�l\���G.�a��k������!����ٻjjI�������z�����@r�O������3�)K2�+��qB���[d�YA����`u�OONm�����7���e`b�4�/����T����d1�/���,@��1]�4�h+����~00��4�?�?`x���� /�,
@,?20�{��/#;P� ��&�l��������W`����##а�ρA� �X����73�(��?Va�f) ��
5�`L������=0����a���#�×ߟ���_�=y��PIB����(3/�.�P�~f`�-���~��ɓ3g�}9@L���[�1������
5q����f"k FtS��ZP�7��X�RA^N��>zr����Z�?�� ���b�+��IEND�B`�miglayout-5.1/javafx/src/test/resources/org/000077500000000000000000000000001324101563200212145ustar00rootroot00000000000000miglayout-5.1/javafx/src/test/resources/org/tbee/000077500000000000000000000000001324101563200221335ustar00rootroot00000000000000miglayout-5.1/javafx/src/test/resources/org/tbee/javafx/000077500000000000000000000000001324101563200234125ustar00rootroot00000000000000miglayout-5.1/javafx/src/test/resources/org/tbee/javafx/scene/000077500000000000000000000000001324101563200245075ustar00rootroot00000000000000miglayout-5.1/javafx/src/test/resources/org/tbee/javafx/scene/layout/000077500000000000000000000000001324101563200260245ustar00rootroot00000000000000miglayout-5.1/javafx/src/test/resources/org/tbee/javafx/scene/layout/test/000077500000000000000000000000001324101563200270035ustar00rootroot00000000000000MigPaneInternalLayoutTest.css000066400000000000000000000001101324101563200345010ustar00rootroot00000000000000miglayout-5.1/javafx/src/test/resources/org/tbee/javafx/scene/layout/test.root{
-fx-font-size: 12pt;
-fx-font-family: "Courier New";
}miglayout-5.1/nbm/000077500000000000000000000000001324101563200141425ustar00rootroot00000000000000miglayout-5.1/nbm/pom.xml000066400000000000000000000066321324101563200154660ustar00rootroot00000000000000
4.0.0
com.miglayout
miglayout-parent
5.1-SNAPSHOT
../pom.xml
lib-miglayout-NB80
nbm
MiGLayout NetBeans platform library wrapper
UTF-8
netbeans
NetBeans
http://bits.netbeans.org/maven2/
false
org.netbeans.api
org-netbeans-api-annotations-common
RELEASE80
com.miglayout
miglayout-javafx
${project.parent.version}
com.miglayout
miglayout-swing
${project.parent.version}
org.codehaus.mojo
nbm-maven-plugin
3.14
true
com.miglayout
org.tbee.javafx.scene.layout
org.tbee.javafx.scene.layout.fxml
net.miginfocom.layout
net.miginfocom.swing
org.apache.maven.plugins
maven-compiler-plugin
3.7.0
1.8
1.8
org.apache.maven.plugins
maven-jar-plugin
2.4
true
miglayout-5.1/pom.xml000077500000000000000000000205341324101563200147120ustar00rootroot00000000000000
4.0.0
org.sonatype.oss
oss-parent
7
com.miglayout
miglayout-parent
5.1-SNAPSHOT
pom
MiGLayout
MiGLayout - Java Layout Manager for Swing, SWT and JavaFX
2007
http://www.miglayout.com/
core
swing
swt
javafx
ideutil
demo
examples
nbm
junit
junit
4.12
test
doclint-java8-disable
[1.8,)
-Xdoclint:none
org.apache.maven.plugins
maven-compiler-plugin
3.7.0
1.8
1.8
true
none
-g:none
org.apache.maven.plugins
maven-surefire-plugin
2.8.1
org.apache.maven.plugins
maven-javadoc-plugin
2.8
attach-javadocs
jar
${javadoc.opts}
org.apache.maven.plugins
maven-source-plugin
2.1.2
attach-sources
jar-no-fork
org.apache.maven.plugins
maven-release-plugin
2.2.1
true
org.apache.maven.plugins
maven-site-plugin
3.0
org.apache.maven.plugins
maven-javadoc-plugin
2.8
org.apache.maven.plugins
maven-project-info-reports-plugin
org.apache.maven.plugins
maven-changes-plugin
changes-report
maven-jar-plugin
2.3.1
${project.build.outputDirectory}/META-INF/MANIFEST.MF
org.apache.felix
maven-bundle-plugin
2.5.3
true
bundle-manifest
process-classes
manifest
BSD
http://www.debian.org/misc/bsd.license
repo
scm:git:https://github.com/mikaelgrev/miglayout.git
scm:git:https://github.com/mikaelgrev/miglayout.git
https://github.com/mikaelgrev/miglayout
mikaelgrev
Mikael Grev
mikael.grev@miginfocom.com
Project Lead
+1
http://www.miglayout.com/
joeluckelman
Joel Uckelman
uckelman@nomic.net
Developer
+1
http://www.nomic.net/
anavarro
Alexandre Navarro
navarroa@free.fr
Developer
+1
http://javageek.free.fr/
tuomashuhtanen
Tuomas Huhtanen
unknown@foo.com
Developer
+1
http://unknown.foo.com/
tbee
Tom Eugelink
tbee@tbee.org
Developer
+1
http://www.tbee.org/
miglayout-5.1/src/000077500000000000000000000000001324101563200141555ustar00rootroot00000000000000miglayout-5.1/src/changes/000077500000000000000000000000001324101563200155655ustar00rootroot00000000000000miglayout-5.1/src/changes/changes.xml000077500000000000000000000530171324101563200177300ustar00rootroot00000000000000
MiGLayout
mikael
JavaFX: Added layout callbacks.
JavaFX: Added two test panels and made the old ones startup with sizeToScene bounds to catch initial prefSize problems.
JavaFX: MigPane now works with right-to-left layout (untested) and it picks the default from JavaFX.
JavaFX: MigPane now revalidates correctly when PlatformDefaults is changed or constraints on MigPane is changed (LayoutConstraints, Column/RowConstraints).
JavaFX: MigPane now asks its children for layout orientation and behaves appropriately. For instance this makes wrapped labels get the correct height.
JavaFX: debug graphics are now crisp (width 1).
JavaFX: MigPane now disregards unmanaged nodes (external was needed to be set explicitly before).
JavaFX: MigPane now adheres to insets (padding) from the MigPane itself.
JavaFX: Made some optimizations and small adjustments to MigPane. Now it only revalidates the Grid if a child needs layout.
JavaFX: Added baseline layout.
A MigLayout Swing panel could never exceed size Short.MAX_VALUE (32768) in any dimension. Now it's the standard Integer.MAX_VALUE which should be sufficient.
Now handles all size variants in Swing on OS X.
Now compensates for the extra white space around components in Swing on OS X. Bad Apple.
Generally better resolution handling, especially on OS X.
Added better exceptions when parsing.
SwingComponentWrapper must query Toolkit-provided screen resolution for dpi scaling. Thanks to Kleopatra for the patch.
Fixed a NullPointerException that happened when a ancestor was a BoxLayout or an OverlayLayout. Thanks to "uckelman" for the patch.
A memory leak in the Swing version when components where removed from the layout.
Baseline of an empty JComboBox was interpreted as not valid.
Fixed a memory leak in SWT where a disposed widget could be referenced from the MigLayout instance.
Cache wasn't flushed even if flushCache was true in MigLayout.layout(..) for SWT.
Fixed the gaps on Windows to adhere to Windows 7 style guide.
Some parsing errors didn't throw an exception.
MigLayout now requires at least Java 6.
Also made JPopupMenu, not only Window, work with the 'pack' keyword in Swing.
Added JavaFX2 code into the main MigLayout project.
Guarded the beans check with a catch since it has been reported that it doesn't work with a null class loader.
Updated the Maven poms and moved the releases to the Sonatype Central Repo.
If using design time (in IDEUtil.java) is turned on (normally just by IDEs with MigLayout support) there was a memory leak.
SWT had a memory leak. When disposing Controls they were held strongly by MigLayout.
In SWT after setting a new LayoutData on a control it sometime wasn't picked up. And when it was all constraints were recreated which was slow.
Introduced a fail safe for buggy Swing applications/containers so that there's less risk for memory leaks.
Reduced heap memory consumption for components that doesn't have a constraint. Now a CC is reused instead of recreated with Grid.
MigLayout now requires at least Java 5 and the code base has been updated to for-each loops and no explicit value unboxing or boxing.
Made Beans package load only if it exist. It doesn't on Android for instance and there might be other places where it doesn't exist.
Layout Constraint "align" with only one argument used that for the vertical dimension also which wasn't correct.
Fixed a Negative Array Exception that could happen in rare circumstances.
Fixed a bug where some layout changes didn't re-layout the container.
IDEUtil did output "hideMode" instead of "hidemode".
Fixed most FindBugs warnings in the library.
"debug" mode had a javax.swing.Timer going and it seems it hinders shutdown without explicit exit.
Fixed a NPE in DimConstraint. Thanks to Stephan for the test code.
Made IDEUtil drop the trailing null if possible for "gapx" recreation.
Fixed IDEUtil's reparsing of "height xxx!" type values. Thanks to Konstantin Scheglov from Instantiations, Inc for the bug report.
Fixed a regression that the performance fix in 3.7.1 introduced. Thanks to Ingo Kegel ej-technologies for the fix.
Added a fix that makes spanning components in multiple rows works more consistent.
Made it clear in the White Paper that sizes can't contain links.
Removed a debug print statement from 3.7.2
Made the documentation concerning docking clearer in the White Paper.
"pos" pointing to "visual" or "container" didn't work in SWT and possibly Swing if the container was resized during layout.
Changed so that two or more consecutive spaces in an expression is the same as one.
Added some API to the API version (e.g. new CC().slit()) which made it more complete. Thanks tbee.
DPI in SWT on Mac OS X in Java 6 was wrong. DPI was changed in Swing from 72 to 96 DPI in Java 6 by Apple. I have now forced it to be 72 when at least one
SWT MigLayout is created. It is not possible to have correct DPI in both Swing and SWT on OS X with Java 6 and above.
'aligny baseline' for the Layout Constraint was accepted by the parser but failed for layout. Now the parser correctly throws an IllegalArgumentException.
Baseline alignment broken, at least on Mac, since 3.7.1.
There was a problem to serialize a layout for a container that wasn't a part of a component hierarchy.
If "skip" during a "span" then an extra cell was skipped.
Fixed a race condition regression introduced in 3.6.1.
Made IDEUtil design time empty row/column gap override default to 0 instead of 15. This is so that design time is always the same as
normal unless IDE vendors opt in to have special empty row size. See LayoutUtil.setDesignTimeEmptySize(int pixels).
Fixed a performance bug that made deeply nested MigLayout containers really slow in some circumstances. Now an invalid parent for a layout
will only re-check the sizes for all children once. Please post a bug report with a runnable demo that shows this regression and I will try
to make a version that doesn't suffer from this performance bug and which are without regressions. Thanks to Jermo from the forums which
posted the bug report. Note that this might also be a performance problem in the SWT version, which is unpatched.
Turned off baseline alignment support for components that has BaselineResizeBehavior == OTHER. This means that for instance JLabel with HTML
content will now be aligned vertically as CENTER rather than BASELINE. This is because the HTML implementation in Swing doesn't return
a reasonable baseline value anyway. For instance, it quite often returns different values for the same arguments when called twice in
sequence and every now and again returns a negative value indicating it doesn't support baseline alignment.
Improved SWT text components having the Swt.WRAP property set. They should now get a more correct height that is dependant on the width.
Component constraints "push", "pushx" and "pushy" was still affecting the layout even if the component was invisible in hidemode
2 and 3. Now that will happen only in hidemode 0 and 1.
There was still a case when "skip" did not skip the correct number of cells.
A cell spanning many columns did not transfer its minimum size in an optimal way. Now a column will get more pixels if its preferred size
is larger than its minimum size. Before, the last column was increased to a size more than its preferred while another column could get
somewhere between its minimum size and preferred size. Basically all columns will now be pushed to their preferred size before the last
column will be increased. Still, if there is a "push" component/column it will be increased before any other column. Rows and columns are
interchangeable in this context.
If a component had a 'grow' constraint it would affect the column and/or row to take up more space if the whole layout was set
to 'fill' the bounds. This was a legacy from the time when 'push' did not exist. 'push' now does that so it is not logical that
'grow' should do it as well. 'grow' now only affects the component so that it will take up as much space as it can without
affecting the grid. It should be noted that everything now works as the documentation has stated the whole time.
If your layouts change to not grow in some way due to this then look for 'grow' (or growx/growy) and add a similar 'push' next
to it.
If there were more than 512 rows or columns in the grid the preferred size was sometimes wrong (negative).
Made the persistence delegate for UnitValue and BoundsSize not look for the BeanInfo classes, since they will never exist and it
delays startup as an Applet. Thanks Anthony.
Added Linux/Gnome platform defaults. This means that Gnome Human Interface Guidelines' gaps and sizes are now correct on Linux.
MigLayout in a Serialized component throws a NPE.
"skip" skipped cells before they where checked if there was a spanning component. This meant that "skip" did sometimes not skip a cell,
instead it skipped the cell that would be skipped anyway since there was another component (spanning) there already. This is unlikely
to affect many and if it does you are probably overusing the "skip" keyword anyway. :)
"skip" did not take automatic layout wrapping (wrap in the Layout Constraints) into account. So if you skipped the last cells on a row the component did not end
up in the next row as expected but on the same row. "skip" now alwats skips the correct number of cells and move to new rows as
needed.
If "newline size" or "wrap size" was used with "span" the size was attached to the wrong row. Also, if there was a wrap
on one line and a newline on the next the extra row was removed, which was also a bug.
Fixed a strange shrinkage of some components due to calling Window.getPreferedSize() within the layout loop. This seem to be a workaround
for a Swing bug rather than a big in MigLayout but it is hard to know.
The parser now throws an IllegalArgmentException if links to other components are in the min/pref/max width or height keywords.
Prior to this the link was silently evaluated to 0.
Made "sg" and "sizegroup" set the size group for both width and height. This might break old code but this way is more compliant
with for instance "grow", which is also a short for both dimensions. It was not documented either way so I thought I would make it
the most logical choice. If you have bugs because of this make sure you don't have "sg" or "sizegroup" without the trailing "x" or "y".
Fixed a bug that linked sizegroupx and sizegroupy in certain circumstances.
Fixed a memory leak that pegged the layout instance in memory when debug mode was used. Thanks Dieter Krachtus.
Added a compensation for a probable Swing bug introduced in java 6.0. In Swing when calling component.getBaseline(width, height) on a component that has
embedded HTML and at least one BR or P section, Swing always revalidates the layout. This leads to a new call to component.getBaseline(width, height) and the loop
goes on forever. It is unclear how to get out of this loop, if there even exist a simple all-working solution. In the mean time you can set "aligny center" or
"aligny top" to make it not call that method from this version.
IDEUtil: Fixed a formatting error in IDEUtil where gaps was not recreated correctly.
IDEUtil: Fixed a formatting error in IDEUtil where width/height was used together with maxWidth/maxHeight.
If there was an active "split" in progress a docking component would be in that split instead of docked.
Converted MigLayout project to Maven 2 for build and deploy management. See the Maven part of the site for information on how to use MigLayout though Maven.
IDEUtil: Added option to get which cells in the layout
grid the components end up in. Good for IDE
Integrators..
If aligny baseline was specified for a textfield
component it might get x and w that were wrong. Thanks
Konstantin Scheglov - Instantiations, SwingDesigner.
TextFields in a baseline does not align the first layout
if it has size 0, 0 before. Thanks Konstantin Scheglov -
Instantiations, SwingDesigner
miglayout-5.1/src/site/000077500000000000000000000000001324101563200151215ustar00rootroot00000000000000miglayout-5.1/src/site/apt/000077500000000000000000000000001324101563200157055ustar00rootroot00000000000000miglayout-5.1/src/site/apt/index.apt000077500000000000000000000014761324101563200175350ustar00rootroot00000000000000Maven Users Site
This site is for Maven users. Please go to the main site for generic information about the project {{http://www.miglayout.com}}.
Usage:
+-------------+
Each environment in which MigLayout is used has its own artifact:
* miglayout-swing
* miglayout-swt
* miglayout-javafx
And there also are supporting artifacts like:
* miglayout-ideutil
* miglayout-demo
* miglayout-examples
All directly or indirectly use the central artifact:
* miglayout-core
All artifacts share the same group:
* com.miglayout
All artifacts have related sources and javadoc artifacts using the similarly named classifier.
+-------------+
miglayout-5.1/src/site/resources/000077500000000000000000000000001324101563200171335ustar00rootroot00000000000000miglayout-5.1/src/site/resources/docs/000077500000000000000000000000001324101563200200635ustar00rootroot00000000000000miglayout-5.1/src/site/resources/docs/MiGLayout.html000077500000000000000000000350661324101563200226400ustar00rootroot00000000000000Introducing MigLayout. The One Layout Manager to Rule Them All!?
MigLayout is a the most versatile SWT/Swing layout manager written, yet incredibly simple to use. It is use-case optimized for manually coded layouts and is using string constraints to format the layout. And for many the most important thing: It's free to use and will be Open Source .
Quick Start
We are all impatient and pressed for time. To see a demo application showing off what MigLayout can do, launch the sand boxed Swing version here and the SWT version here . They both need Java v1.5 to be installed. The Swing demo application even works as a very poor man's IDE, right click any component or container and you can change its constraints! You can view the source code for the demo applications here: Swing source code and SWT source code .
To read a more technical paper about how MigLayout works you can find that here . If printable Cheat Sheets are your thing you can find a very printable PDF with all currently supported layout constrains and also a HTML version .
Problems to Solve
For manually coded GUIs the layout managers delivered with Swing are all reasonably good at exactly what they do. They lack options, but they do their job for simple layouts. The problem starts when you want to change the layout slightly or need to tweak the layout to for instance follow platform defaults. Since all layout managers, except GridBagLayout, have very few options to tweak you'd better like what they do or you need to switch layout manager. The problem is that since all layout managers have quite different use-cases, moving from one type to another is .. hmm .. interesting..
Another problem is that there are layout managers for Swing and others for SWT. If you work with both toolkits, like many do, you need to learn two sets of layout managers. MigLayout works for both Swing and SWT. The GUI toolkit has been completely abstracted away and to make it work for yet another GUI toolkit all that is needed is to create three simple wrapper implementations. As a comparison, converting the Swing version to SWT took four hours, and I had never seen SWT code before that. It took another four hours to convert the demo application from Swing to SWT since I didn't use any of the SWT widget wrapper frameworks available.
To preempt the mandatory reply that JGoodies FormLayout
has many things figured out already I can only concur with this estimation, it is a good layout manager. I set out to make things even simpler, and especially more flexible and powerful. As you'll note, should you run the web-started the demos linked at the top, it partly looks a lot like the JGoodies' demo application. It was intentionally done this way (with Karsten Lentzsch's permission of course) to be sure that it'd cover everything FormLayout
can do, and much more.
Design Choices
There are always design choices that have to be weighed against each other, and sometimes what you gain in one place you lose in another. With a clear definition of these choices one knows what corners to cut and why something was done the way it was. Here are the major design choices for MigLayout.
Layout Constraint Proximity
All constraints for making layouts should be settable in the layout manager's constructor or in the constraint used when adding a component to the container. Most other advanced layout managers, if not all, use extra lines of code to specify constraints. This scatters the layout choices over many places and they can be hard to find or easy to forget. GUI creation code is usually quite verbose in that there are many SLOC (Source Lines Of Code) and if layout affecting code is scattered, it gets bad quickly.
String Constraints
The lowdown is that string constraints are short to type and easy to understand, but they lacks type safety. Normally I prefer type safety but when it comes to things like this, where for instance there is no refactoring happening, I think it is a reasonable trade of. I'm not so comfortable in that decision that the layout is reading directly form the string into the layout engine though. There is type safety in the background. The constraints are parsed directly and a currently package private struct-class is holding the information. It would be a simple thing to make it public and thus allow for full type safety, maybe with a builder. Another reason that makes type unsafe strings work here is that the constraint is parsed and any errors in the string is reported directly and without mercy (i.e. RuntimeExeption).
An added advantage with both paragraphs above is that implementing basic support for MigLayout in RAD IDEs is trivial.
Toolkit Agnostic
MigLayout currently exist for the SWT and Swing GUI toolkits. It would be quite easy to convert it to for instance .NET. As long as a widget has a preferred size and the parent container holds a number of widgets there should be no major problems converting it to any platform or GUI toolkit. The code is free of javax.swing.* code which makes everything easier.
Flexibility and Extensibility
For a layout manager to be successful it is important that it can be used in many contexts and that the user isn't constrained by lack of features. This is why you can do almost anything with MigLayout. It is a docking layout manager, a grid layout manager, an absolute positioning layout manager, a flowing layout manager, a panel factory. And.. there's more.
No Panels in Panels
Nested layouts (a.k.a. panels in panels) is an abomination if you want to create exact and clean layouts with predictable results. The built in layout managers in Swing forces you by design to use nested panels. The problem is that since the different layout managers behaves differently regarding the interpretation and adherence to minimum, preferred and maximum sizes they get hard to handle when nested, and you must figure out for instance why the minimum size is disregarded, and at which panel level...
The flexibility of MigLayout should get rid of almost any panel-in-panel urges. In fact, when I was doing the mandatory research for how general layouts looked like (using Windows XP's and Mac OS X's standard dialogs as examples) the goal was to create a layout manager that was so flexible that every dialog could be done with one layout for every tab.
Units, Platform Defaults and Visual Bounds
You can use any units that are normally used in layouts. Pixels, font size compensated pixels, millimeters, inches, percentage of container size, percentage of screen size, and more, works out of the box. If you want more units it is easy to install converters. There are also logical gap sizes, such as �related�, �unrelated�, �paragraph� and �indent� that will be interpreted on a platform basis. For instance Mac OS X has larger spacing between components compared to Windows XP. Further, button order in button bars are supported natively without the use of button bar builders or the like. They are configurable and more platforms can be added or the built in defaults can be changed by the developer.
Visual vs Actual bounds are compensated for on a Component by Component basis. For instance Windows XP's JTabbedPane
has a three pixel drop shadow that makes the bounds not the same as the human interpretation of the bounds. This is compensated for with on-the-fly padding. Currently only that component is padded but the support is there and can be extended to include more compensations. It is of course also possible to turn this feature off with a simple constraint.
Component Sizes
The min/preferred/max size of a component is usually delivered by the UI delegate, and that for a good reason; the delegate has intricate knowledge of the component and how it will look its best. Now, that is true for the component, but it is you that want to say how it should look, taking these sizes into account. Changing these component sizes directly on the component/widget, for the sake of making the layout look right, is the wrong way to go since the interpretation of these sizes is different for different layout managers. This is especially true for text components, where you can't change the preferred size in one dimension without changing the other as well.
In MigLayout you can override these sizes directly in the layout constraints, where that information belongs. This also helps with narrowing the Layout Constraint Proximity to zero. All layout information in one place and if you for instance want to swap that JTextArea
for a JEditorPane
you just do it and the layout stays in place! And when the layout doesn't do as you expect, you have only one place (or maybe two) to look. If you don't agree on this design choice, don't worry, you can still do it the component centric way. MigLayout honors all component sizes the intended way.
Baseline Support
Nothing that doesn't support baseline alignment would be cool in Mustang and later, yet nothing that requires baseline support will work in anything before Mustang. MiGLayout supports baseline alignment through reflection, which means it will use baseline alignment, if so selected, in Mustang and above but will fall back to centered alignment for 1.5 and 1.4.
Smaller is Better
I like small stuff since it is easy to carry around. A small .jar size was a major design goal. The .jar has just turned 60k. Compared to other advanced layout managers this is small enough. FormLayout is 85k, GroupLayout (Matisse's layout manager) is 70k. With Pack200 (as is used for the JRE downloads) all of these will be even smaller, about a third of that.
XUL Friendly
Since all constraints are string based, the layout manager should be a dream come true for XUL implementations. There is no need to synthesize a XML to Java code bridge in the XML since constraint can be set in MigLayout's constructor or as a single string when adding a component to a container. This means that component layout in XML might even be readable!
How MigLayout Works
I'm actually going to be quite brief here. There is a white paper (linked at the top) on how it works and this article would be too long if that information was re-iterated here. But let's list the main features.
Grid Based
The layout engine is in its core grid based, with all the advantages that mean regarding the aligning of components. The problem with grids are that they are square and sometimes the layout isn't. This isn't a problem with this grid though since all cells can be merged and/or split in any dimension (as long as we stick to two dimensions). There is even a �nogrid� mode where the layout manager behaves like FlowLayout
, but with oodles of options and without the annoying auto-wrapping that my doctor has forbidden me to mention.
Component Docking
First I actually set out to fix the Swing layout problem by creating two layout managers. MiGLayout and a docking one. But when the layout engine was done I realized that docking components actually fitted nicely with it. This was an unexpected but pleasant discovery. If you have done GUIs on the �unmentionable� platform (�.NET�. Oops..) you know that a docking layout is an excellent way to layout panels. It can be used to do almost anything though. Swing has a poor excuse for a docking layout manager called BorderLayout
. It lacks any kind of features and of you aren't happy with having the �north� panel over the �west� one, here's a present for you: �Panels in panels�. And if you want to change that later, here's another present: �Gray hair�.
MigLayout supports docking the proper way, with options to tweak it the way you want. And since it is the same layout engine as for the grid layout you can use all the gaps, insets and alignment constraints. This does however mean that if you actually like putting the intended decorating border in a CompoundBorder
to make the spacing with an EmptyBorder
you will have less fun in the future. But you will be more productive and can spend more time at the golf court as a poor compensation (or whatever you do when you don't do GUIs).
Gaps and White Space
MigLayout has extensive support for gaps and white space. You don't need surrogate rows and columns to accommodate them as with other layout managers, you just specify their size and it works. And they even work they way humans think they should! This requires an explanation, I know. Example. If person A want a 2 meter space around him (for reasons unknown) and person B requires 1 meter, how close could/would you put them in a confined space? Also for reasons unknown they will have 3(!) meters between them if current gap-supporting layout managers would decide. Why? It's easier to code it that way... As mentioned MigLayout does it the human understandable way, where the components are spaced to the other component's bounds and not to where their gap ends.
Gaps in MigLayout can even have min, preferred and max size set. This means you can create glues (pushing, expanding spaces) with gaps and don't have to resort to using �glue components� that take up memory and complicates the layout.
Free like Lotto Coupons or Free Like a Bird?
MigLayout will be free to use for just about any purpose. It will be Open Source, though I'm not sure which license to use. There was a sizable amount of resources used for the creation of this layout manager and I would not like it if it was immediately forked, renamed, and re-released under a different name/vendor.
One question is whether we should push for MigLayout to be included in JDK 7. It would be good if everyone had a powerful layout manager at their disposal, both for Swing and for SWT.
Now, please use it. Test it. See what you think and post your constructive criticism either here or at www.miginfocom.com/forum under the MiG Layout section. There might still be room for improvements and the API can be changed if need arises.
miglayout-5.1/src/site/resources/docs/QuickStart.odt000077500000000000000000000475211324101563200227010ustar00rootroot00000000000000PK��0<^�2''mimetypeapplication/vnd.oasis.opendocument.textPK��0<�Configurations2/statusbar/PK��0<�'Configurations2/accelerator/current.xmlPKPK��0<�Configurations2/floater/PK��0<�Configurations2/popupmenu/PK��0<�Configurations2/progressbar/PK��0<�Configurations2/menubar/PK��0<�Configurations2/toolbar/PK��0<�Configurations2/images/Bitmaps/PK��0<�layout-cachecd`d(�g``�d``Ʌ1��^��@�L�:#���e�PKH�1�*CPK��0<�content.xml�}ے۸���~�&�Q��J��>a�/�g�ޮ���p8& �ئH5A�J��a�v_���K63�DJ"EQb�k⌻D@"�Hd&��=,,ힻ�t�W�f�B���={u��݇����^���:ө��k���������W�ֶ��o_]��}�0a�k�-����kg����u��kK>���ݜ>�������1~�h�&�G���
���6�o���S'o�a5�`}�d��Ńe��_]�=oy�j�V���t�Y�3�[�6X�[��E_z�[�N��
�]p�����d�� ws��y,���~��"�g[P�ϙ��6���������3�m̛oY���gxI�|�т��;~�@����Ӕ_��;���
�%p��v�%Ǿ^��|�wc��;?י��wYH��:-����LC�GD�-
�-�:�X[����O���/X�����i��f\\��3�\�t\/D�4?Ä�ꆣS_�&����4V����6�א�Lnd���K�ؐY�r���Y�j:��XkI<�e���^�N
Ie�>�ј2�7�[��_�k�7�����c��z1q�
vw��´։����ܱ��`��>�}�o�5����WY���-�S�#��BK��6f���FX8w��'K�ӁWL�n��@���6q�W��aV���1 �D�
�mo�y��tU)��k�A��7�YyϷ-V��������4h�|�4�v�l��n� �m��k��E?�j�M[�;[!�8 <��l�2�Gomc��9�=�3��rW�wV���%��"hE�K`���Lؗ���4P��6;�����'�af�3���zjl�}`4�d�/�
x��4X깂������((o+�=h��
���ʻJ��=���2j���&{5tnY����8S�z��^*zW]�I�t�p�6pћ6��&�4���ſs��>���{�2O��y(jo����T�����͆�uV4���9�(���C��jB5��M#������G62r��W�^�'p��x8������݊N��!X��u��R� <�����懺�%���*���P�咍���\�=�\�������̾rI�rI��d�k?kz�%�f�ݽ:�*��h\\��4�q�r֛aq)��ٶ�ˉ�ي�zp��ŻV�tg�Z��p�ӟw���K����j(��0
Ò?=����˵��!�.7��s���1�p����
y ��wz�C�����SJ�h�h�n���[�lY�$n��C�N\�[��G���_NiR���JS�>��~}���
�&8Q�6ש�J���~�Zy6[n,M݅���U��m��?_�&�1��CӸ>M������84��s����4~>�7���'���'���>���'p���]���N�>Z0�R�C`��S�R�&��6nMKm����86�~P6��
�xv �6�������M �J� �W�c�(��� ��P�1*�O:��!X��P�+.�
��͕��<8�-�������>��V�>����Ug|�xX��>𰚛��U�Pjc�Vr_�;���� ��4u?���W��?� <|>���9�{�Ѱ��>��nL\ξ7&�[qn#]�WSf ^֊����M��
��^���wUx
��~h�3�Ʊ�<�r�ql����!���L\jgw�C�j��BT���aQ��$D�������+����W!㪤�!-٥���
�n����D�"?\U�{�`uUM�.l�v����9rwN~`yN��r�%��62KQmd��*d��հ�UȾU;��rU&
�r��lK沙˖��<�*��![�z�6�k�Ї�6��A"����?|��uC�Ġ�L&f�P����(#�0� ���$|�`�d��w�����m~���� �l�%�l�L~��j��c��/������M1�3̶�k��/�ٶ�6JZ�lU��M3œ�L�f����Nc��6u�y��n�,f�GN�F��ع�m�<����EJ���,�K�K��.\�a�O��]���>u�yf�3i9p�u������.LP�'@C+�l}bH}�_�J�~��ݽ���l<�.�g�h�8��K+#�[������O�M�RJ�ı�,�E��!��A~`�7��8DE�M�"&�X]���sK1��oY���K|�_ȟqf��>ÓG� K����!�������쳁e�^]����B��F�aF���>u\��^W�M㫅i7,6�F���U�ɜԝ,��څ�x�O��<�M�����C�4�?����v��#ip�=�y�ix�M�y�iT�=�x����]��H��uo�s����S��[[���h�`s �/xC8S��t����>zD����*�"������uR�\.�u���
���I��?}nG��%P�)�[7߳L�7Ԣk.��e��s���@gd+�*oe;y'k1GT���y����^|!����@��}6?j��^h��7��ҝ�}�M�k�t������鑒��)4������9Z4VS����w�9w5�Fr���,���1O�c1�*B_{�%#L�V/Գ�˧���s���c�� �.^g>Wb�5�z�ʴ,m�5i0��ۛk8�@�D��+�ن�r���8�M��27~�ͤ1�h��?`8��6�#���-��ǒX����i��e"`�k���h�-&�Sy�v����7�锣�3��NZ�ER�>o��]j
�\k+�����{֚�0��?\kK8��/���o�k �Qg�{z�i����>,�y��sX����Nc��z��g.sg"���kM�K,R���������b�-�Н�v�M@ ]�(�!Tgz�3������.!�"o��Rcbˈ��cY�J���&L�:,2�� ����S�4�k� BY��C��Љ��u��p�US�2�D0�
����Ϟq�����#z-�\7�r�u �&4�˟����r�R�E��
�� �;L�t-��N�z�>�up��[M����2�luZ�6�����w���ˀ %:fZ�[-�|Gξ��/c�"A�Wy��� 2�oM���֯�o��)��m�7E�+���f@�F(j;:Q�of����œt�����X^�Ek�ڄ�DP��7tN�u���W��^n��v�d�[���d.���=p�W9&�:Ue�m�=��ڻMN�����_�<�m�<;��8rF��F����C��V�o^����@�t��4FP '�
I
��3�o���$E�6��6Y�iGs�~R!��&+�lt�ɥ&}�`6�q����2���^5�3ґ��HE"`�����zr�PJ�q��q�6uЃ& rf9?/��[��.�@U�P��m��^���N��7��f;.]�2��ƍ�CgJ� m�O3e�P��L-��z��R�~��[�Goq�ڿx��u�}�9H�aKG�$����H�0]NF�RlA�}�k�vkj�4ل�uj�9�����w�h�커m�g4��4��o��M����S��@�����f�9��"��fD� ���z�)봇h���F0+9L�=�X���S��Bc��2=b47�O#�Q�i`��B�����L������Llq���F�N�A�/��ߕ/�i3 �)�vm�C8�Ơ�uM����M����QS�����������-��4�[��mO�5y ��Vsǒƻ����V�RJ��i���,u�Z��E-Kݢ��nڲ�����
>��]u�����g9��z1�Z!����� w�z�t�x�шr���:||
&�n!�X�QX|JAYzw>u=CYb��4̋r"�ϴQ�쏇�i�yu� ���BH��@��������������m�m�I9��lHk��S�i�Iڽ)��*�!�$�Zy�/�OU�P��)��L�Կ�C����SJE�����8����3���K�!�+E�vG���ɍ�H�s��)����f����+�l��*�����ɣ�&l�'�ńΑ�&�y{
�K��ʨ��0a�cS/KC�-W�$��(<�G ����@T��3�������BZ9�R-�����������h��P?\\
Mj��ڤ���(�}��⨜A��WEt�N�pB�v����)�ۅs���n�s�@�r�[ُPc,vɼ����-�Y�'���Q(�q�Qh[��,�G�<�����=�L.j&����T.�H�r��m���#[������%����:<�5`š�&�Zj���x5Hize1�%w���Z:��.-��o���̈́�qw�[_^���t�?n�$��H{�3P2'�l�] .�Ŷ�Ŵ
̘c|2m��ۙ�V��&���ҕ8�nR� ���i��/�p��2ߢWYM�M!�Qp�T��"7sgk��;T���K������r��O\!�Q�f3V�L(ŝ���Hb�d�]�"� kM!�'�[q.;e�J}AX3]
�9��+��Rx����bo�l�,2���Yo� ��<�+ o���Dߛ�9�fg�ő����2�Pޖ>�j��h�������n��m�(���l��Q�12��{r��`�G؋�$q��Z��{��9ۊ�մ�b��@1(d�5O�Z'E�����A�{����T����S���Wҥ�.'{�ƕ���`p>]�y�]����V�s��P��,x�P�U��l�3^!˃o���U�m�{�a�zRPqHhݶ���OG��k�5�6�͢@���ڹ�B��yYu�EJ��j�sǟ�_n��R+����8��a�mm�M�湋��FJ.}�e�b�,�啍���bH��ō#�靆������M��i�J�������AK7� M]��~?q���{��#�_�G��u�����f�e�F0ķ��ǔ~K!�;b��o�#M�v |}�� �2g�ߒ��}S�츪�/c����$�4���:9��=_V��`nP=>���Pa�V8��9l��2Z�
��<"�������X�7�ļx��&�5�:~|]D������*U�[���pn��%��5�� �܄?��>T�� 2^܂�_�zq��䕃v̆�ܛ�=4������M]h�r��;��}��M�v�����,�_.�#RY������˧�u��Z�|X#LP?o��I �U��:zO1Q�#0��p � �yrY�\���.�e�ޚ|�hN��Cv���DNN/A�.��s#�ݡ�s�- �:��5L>c� �c��:��n���Nw�X�b��dˍ�=%�>Ar��<#�P/�ʄI����V�0��`!2brw���Osf�zm��˸��,��3Ś�.&�X���Ah��S���d� V�Q��3���hqBl����KCU�p�B��:D�GIjȓRb{�2�I��u��K��u�WUC\Ϡ�A�B�Ii�d>����(��Q&���j+W-Q���Nt�-��ܶ�i�;C�kʔ*۶����է���4�܄d>u���ꞵ�̰��Tl`Ի��c(Yrܜ�)aA�s���^�r䪺�MPՏ'>�?�;��`wtg�N��W��=��߾�~���l�ރ��a$��]v����΄�� ����4��C��6��/���-G�˰�tyjk�Vxr�i�-"�=��-c�ý��pҙH�h�<³UJU�N��9��w;��A���d�S �7���$.5n�
���������9�f�"k�}M��_�p�~�a����ۘ:�;��AI��M��m������8&`�A�K��L2F�����%�
��P�El��1`�SX5�$���G��/�ZS���
��UP����9�K�_Di͂C"��3)�H��4~��8L��v�v$�q�h6��b�W����?���eX��R�t����~� �G
����@%T��x�[�$�9A1A�
�����2�9�nܥ�]ɢ��\$��"-3%�0�����&��Hhk)���aƤ���)���e�
0��L(>�0s�~�ꢎ��+.˷�z(�d
(��I���s����&�e�Q���5f��Ȁ�Z�Pp6(�r�P�("��<��V@�IG�{��9��3G�E�9H�I���!����<�ل�S�*�-��Ӊ��)a�*I�C�&����Z�0��g�i/�㸖)�$�ł>50�ȡFZ5��O�J���-��>�!C�d)�g��NM7�d�� .P�H7��m��T<S���Gy�l�uK�� ��U����] �:�2�7O��B�(\��.�Ą�����r �l���(���B/�z���t�E�܀�QF��e�����yX�~jߒ@*�����L�dh�Sb� `)p��NM<�U\2'��~C�Mm|�]��tǵ��Dܴ�K�x�7�7T)�ʢ�L�܌���|Pْ`�>cl�����~ѻ�<1��3��E��"��{�~ss��h����ٲw�h)`���4�lcC��#�d=s9�'�3�~��N���&��C�U���w�2;�����m5�ue���p/�uI��"��q�*;��ar:� "?F7�x��q� �apruPv�lӥ�@�Z�XG�4�fc6O�2�{��s��Fȱy����j��� �1�����U,��%�
����1m��j�*��_��]崃U`�X!�M>���ak�djg�S���,x�����xa�����]A{X�����NEǷ���#��'ۀ�8~
6�G8��Oh5y���sB�%���Ξ�3�焴�M(?ئ�
�u��*0W�"����rV���]�O����f�#��8�F�r�'o.Y����kP�i"o?t�Rv�"l2r��JB�����G�7��n���z��~�š���n�@*��;��2`ӱ�7�̴p�[��(�^z�/l�s�z�΄��A@#AP'��~�hU�qĵZnRk�G�|������s�?i��������"�0�{�(��%00znIP��cc�x�/ť&i�E/Vt
�/�Z �� g�)���x/���)�T�J�﹌�`\2�zҫF\:BF�Ţ�W2�;0W9D�@�<�7���IΫ�ݪhL�>:��T�S��7w\�-�]Z̖��~�p6������}O�)�_�G+$&3�((W�
���Gy|�0-N�__`���-�Y�����obDA�O��_��E���ۛ�Ȟb����=��lnӪ�d���*H�驂��ڴ��H'ʚ6S)\1��0�%sr�����^�ܝ�q��߾~�����WE����)F�oTږF!��9��Y�����t����hn亠N�N;���d��:< �x��
����L?�Y` ǁ$ ��?� �Y�\���(I����X��v� ѐ bc�Ĺ�g���G��� ��Vki�Q�&q�F�n^�lbX��|�{�q�_�<�q�7��q�I��\�.�/��n^��갺�\v3 (+���"�/3ā`���,�c���c�A��`�/_�x�te�zh�|�rY�&?.�c�
�=Q�;Y6@w��Ϲ46ߝ2�1�Fp�hCG���<`U^P�@F,{��Ϲ!�+I��p�{�Է�bڤ� �u`+����f�;���GvILQe��I�Z��.��R(��N�+�.hS3���N��{�:��`Y�_+�����B=��|��b�y��V+3�ck�,W�G�7��Sz�8���k;k,R���j2ۍ�d�"�{"vjPPl���*�"n�"t�(�)���Oa����
l.-�S��p������1,���C��aa]�ƫ�ѿ
z���s��S�"֬Y�`Qci����Lx�mXzG��0j�[;�Z�.������n�oE��>/��pB6�����PSQ%�
Y�d� �D4�)<�L�}�|v0�W^�j�\n� 3�Aވ�Ǔ'5�F��]�����SW* s�D����{T,2��Ps�|�
�CV���>k���1�+'�R���e<ЛHO%l��+��H��<p0;'��&;�������D�d�_ʜH�'5w�=ȧ>���~��8�:�X(8�_�PK�:�'�hPK��0<�
styles.xml�[�r���)X�Jn�DI�%e��Im2U�M*�9oA$$!K,��}��F�,�?�H����a��n4���?���&�f��l퇣���,�1�vk��_������>��DxӨHq&.� �L��J�~��E��U�R�W"Z�gv���^���6t�bvg�,�N����h3|e��Ύ:�,y����-:��'��Ms$HC��d�����j<>��lD�n.�˱��
G%_^�Dq��'X.���([�4T?�몔����A�x�?�G�Ӯ�4�����������;�ݹ)��,�@T�=|�b��Cג�5SE�䃷������RU9A'�Rw:������}�e?0"0sأ^�%Qiq��
��1p�I���frӝ�o�甉R��p��L�U�-*�N>R9Q��J�L�)?��:\���E�-ݢ1�~�Ag@9���Rϵ�({<���D��JIr���b��=MQ�"CS^����`���mB��r���0�߫ɔ��g���Ƙe5���rgK�q|�F*�b�2�~k�WH,����_�����7�;�Թ�7����;�� 1"��T� ���ˎw/���n��ӵ�t�ժ}."#�e���(�p��Zx8����5:>���I5J`;"�����(��sĐ��k)M��*��@8�S͊�|_�_�aA��8_X�, �rk�~����b,�\ه���JZ�^�Ӝˈ�V�d�z���̐I��#�P�l+�Tk���i8ͅKP�+��p�"Zd�AT|}��D���@��mlcX.�b$YB��)y)r`�,
���B�z�y��4e��VSϭ�1P���;S���przo��*RN�zQ��fC��`����oG��_Og2>�:���"
�#d'&#�#�T�f��b�<��k�;(����m������
�/����x2b�SpA��@6�����}α\?w��y�}D�L�os']�ӹuvu�l��5[���U�L�,B۱|��X�97�ǟ�?�����������W��� e���X�y�鲶�f����?�[qr��44�Qe&��D̠-o������^�j�wM�Đ�8n��c��͎W^ҝ�E��G�a�N��{TY-�����N�w�!9<��Z�O���S�p�����\e3*0��/ے]��+�WSMo)�w�ޡ�/�'UO()�Rf�N�AU��:�9�)�~Hy�K_����,�R��+h�K�T�-��R�ќ��)�d�ah$��� ���wJZ�ѝ,b@&�K�*L�uQ#U���\ހ����hV�}U��V��¿n�<
���z�b���hz{73-�"��R6ڷF�U �D@���2�@�`����nq7ﺢ9��.��b[ْ����P�m���r���>L5�N֘h2�L��j�T��9��4[.Z��V����2�t�����`ά=�+�b�^��;��k�t�cw�v��hH�k�yi��l9]�z����� F
_�#����g���
�n���SL1��RDi3(%�2�yi�ڸ%״zs��I������d��4�?��{��-�HS履͑�7�\�tT�v��Ը�����PK�_��� �7PK��0<�&����meta.xml
OpenOffice.org/3.1$Unix OpenOffice.org_project/310m19$Build-9420 Mikael Grev 2006-10-28T20:38:47 Mikael Grev 2010-01-16T23:20:19 en-US 16 PT20H19M46S PK��0<�Thumbnails/thumbnail.png��{8��'e�#�d���%�K.�R�FΦ�ͥ��6���5�\2�_�)���N�.�̬lGb�����Q��y���~���;�?���<�?>���~�~�d+�Ga���`
�R* ��ت��̸��;볗Ê��2x�26����%�gǴN"�u����]���KhNq/'u�R��mSKS�#��"��,Kf�����/���(��R��T��o8�.&b$���x5Æ���f{ύ�#l�ٔ�ڕӁU�=l+7��'xI�}N8�u�������u'H���;��MyP�Bzƹ�C�O2=���� �'b�kh�d�^��d�R^��O�R��ۥ
���rC+�`�Sg#ȗ������3��Q�7�Ïg9��u�������ׇ�3���ؤ�6�xC��015u�m�=���$y��4Û�j�}�/�C���s�Ԡ
߈"��
-E���4H��T3��<�Η���Q�+,���kf�Sį.}�h��&r^�y�p�+&k���(�����dL��a?�oM��;�;��u��Z�3sZ읮����Q��8V�/��IO.��Uŋb�A�������ZBM(բ2����a�� �u�(��Ay�&��r���Ə�JNJ=Wh>}�DzG�?��?1�3�=]r��{G�,��F-Әǩ�:��,�ꆊ�^�!�c+�d�2�g���5'2_[[�������MvL��>�]�{��1��z0D���{_���GL�ߐ��ڔ�r4$�d�4�;+��u;������!����\��tWG�Bg�z��. ����@��QUH�aI�Ys7�!]3�ݥ���2��nn'��ka��ʁ8E��j�� �����4���x7r�EN�T1������ih�}*�v�q7yu��ȷw�,I� ���cS���WXtu�=��?�\
�h��V@�{�Bݔ{܂M�.�R�3Q���}��6�k}Ro�-s��������Twr�c�O�?v�Ϡ�*��#�;�rU��{Ͽ$��.��㵗�w]xנ�M���Pu����9`SR�O
�"!�}M���c��:��� @��B[���~\���:DŢ�{�r��\h3+�[�d,9�N0�]s������,;��O1dK%>z_,B�d����aY��;�F����V4Z�v��9�3*�LK�ڈ�r5�K7g�����Q�;�E>T.8�C4�.�L�i�3�3H�7H.�ۣ����>;z[�bʥ��Q��Y��#�x����s�8%c����ӹJ�<�vw�n\Ea8Eq�eRH��K��&j1I��m��Va�������lXC�d��B��xV�F��z�]�_��\���,�
D��˱�4*���丘G�eJ6�-OGs�=);���1�#��A���mi*���i�ղ,����X0��ޚ����j~~�>�[�Y��\�&��H���R�9ߍJ�t�x�B᧨12����TF����$���1���(��)�~�9+<4S|p�_G��O j{b{<}�~վ��G���C�w�k�r���B�="N;X��#�c`g8���Q�p3�9$�>׃H�n;p2� *����*��۪��L�>��F C��`ۺ���S��0%�&�����O���2;�j1{��ï$��s�I�g%N���g��yLɅ��[v|�3�.���-�V��!�h�PV����a�]���J@/��6����
���Q�/�e��wJ1f�����ǡ�'�/B-�����x{��B7�7P|>m|����jg��O�R��Lo��� �4�t��E�E�*�m���� �ǎ��h}[.˄{�+Q�� �^�}�J���p{�� �WUy�Y��IDKr����a+ƈ��Gɯ��C�j�w�@+�e���>��="���f��]s��a����͢2h�;~�~M�!��!T�x�on��(�F�����W�9��V�D�(����ѥ����?]��4rgC�O�v�ʋ�'$�7�QӞ.�k}B�C�\O^�&P�ҡ������q֯��g��5��U��tˮ��M�?7�-e����e ��Sp�)�AuQB��z���h@8(��_��im��F�R�A���?�
�hq~Fy�%�'�ZB���$d���w���2Ӛ�
���2s�������!���#�7�/}�����6�*�W@a�l����9�(�>��J�h���
s�Ӑ�t�������N����m5>'W�.T|Q���J�#+�Xe{�_í8���u�w�PK����PK��0<�settings.xml�Y[s�:~?�"�w
�4�0 CJ
�fN߄��Od�G����d�I��Pl=���������u�/^A�ŭW�P�.@Fbq�=M{�O���_78�G�B���(К���.T+{}�R���H��A�t���v[���U�=Y�H��zK��V��Z�>�P.��f�Y�o�K�hq��l�{U����lȌ��.k��j��w��.4�^{����\A�S�4�&6�ccڭG*[��ޢ�����ޗ���x�7z�ЛHh�]���l^�T�Ŝ.zs}Hv����(��Cr/��������э��U�<�%��R�Aw��Ԏ�"&���)���/:W
0�c�猫��Wb�T"���X�0��jCnN�x?�1UiI��M2_����^��] ���J���xu�X�8�^)V��Ҷ��ǪĔ`���j��Aٵz�q��?�)��ͷ%�b�4`Luy�ݲ.KzޏK��a��3�� p4�=I�0�����r�uY�P<��fR�4��?i�~��dSF�KZ*{|c���8vS)�LR`4�Le��5��� xI��m�Θ a����d�R�� R��sn��#�.Kt*�N��p��
C(�P6��=�.��������C�2zl]H�g� ����t~CAa�pA�y�{�db����W�������@�����t]�{���}=�D
�ڛK�0�2ޑ�^ܴ53���N�r�)Ƕ��M���l|1�
��׳G�a, f+���T�-��JʯG�a��Bb*��&���Ś�a9�B�M��A7x1��ۋ5�m?@"
ng�lG︫{ߑ�Ǿ��PK� ���PK��0<�META-INF/manifest.xml���n� @����{���5��I���\�H6U��#��f[5�[�A�ن���a0�ig�X=��r��}#�7o�x^/VX�!q}i���1��i�-H5��y��Sq@�����dZ/���˴0��E����G���V�)N��mutUsE�x`q�=�j9��EcJ�k���S^��t�16ZJb�H[y�LS��!L���fwet�c&�w>�t3b&|p}@�w�S�������H�E���:ndm#���TQWj.�]��o��0^�]�R��ፊ�ʩ\��o��g.�h����n�m���ւ6$�4����
�oa�9=��Ү䷗x�PKybU�PK��0<^�2''mimetypePK��0<�MConfigurations2/statusbar/PK��0<�'�Configurations2/accelerator/current.xmlPK��0<��Configurations2/floater/PK��0<�Configurations2/popupmenu/PK��0<�JConfigurations2/progressbar/PK��0<��Configurations2/menubar/PK��0<��Configurations2/toolbar/PK��0<��Configurations2/images/Bitmaps/PK��0>
stream
x��[I�,����ȳ��
������=����'�3`��e����КY���yE*�dD�P,z�˯/�_���Im�$�U�i[~����?-��}����/�O�b�z2�ǿ�?��'~����3�1~~oL�G��}��Ѹ�վ�������kz�W����#y�_��=�ED�0|�k�-ܯ���|������˵0'��������_�D0�
��U��H36v ]%����N$^~���N�z����8�؎p����{�,�0V�~�1"�0���x��*F�����$��`Ή�k�D$�����R�-ʠޘ�b��=Bjlo`�$��#L�\�W�@�}�LL`N�=A22O$�#J�??_���ׂ����W��>@=����o
��f]Rq$�q"���'���#��b�N���XY����������������0���D�ȡ�� �k��ݒD����k?� �?>��Bg����1b�R�3�|���YYj���ژB�5����64 h������o2m����3������[xO���ጠz��y%�Qs:�'ob���_�=A�]3�vG!�x�1z]��Fĉ�)�TOxP��Z�t�㩐��w�v���[��=e{���,��Xβ�h�~&���tNO��@ �Lb^ }������`�s�@�u>Hճ[��M�Pv=D"_�j���D��d����M�n�[Ex�:����n���'��Զ�=�
}d�&^��� �DEe�S�>�3Y��9
&�?9�(�J��N%�Q炸p�W�Ȯ�y��D���y,�(��ܫ��G>f��єXa{����X�ֆ=�Q�7�U�V�!�n)�P�
�d����)%�]o�߫[r���
9�A���G��S'�Sv^*I��� y �g�
P��7j�� 2(��o��1����;�ڳ�hADm�ߓ{�\]*�{-��qh2Jv��n����H�Qkҿs��F�ٰ�3�ďA��(ziq���b�s�PD��t�`g#DW09��q��{�a���-�v��6��[��]3O�A�\��YR#�3P\cp �����-ރ������>
�
۽\U���7L�8eX<��7��1lu�9ή�wcw�`�L��t�{|9����f��r$(�`�7�� �m�V�S���
.�[�\�O�fJ
_�mFʍp�m�J��H��"m�8�����|i"ʺ}H:~�?�³͐��Yq<��m�%���rUms���?�#��Cn�z��s$(�Xh_nG�H/iG�H/iG�ro �. �ϙ��� �}�� J��� J��� ��~�I�B�!���C�0��`
��!�{WI�r�p�oIE������U�k^m�����2Ll�}tͷ��=�����$��Q�jM�-�h��}oj��4nk��d���X;6��G3
L��<$T�<�ۚi��ݖ�ʼnMɪ8�/��_�}�9�Gə�k Ck�[j��d�Y*f6����X@�G"�V�QеH�GR��P���:����y�2s3I�?�#9�jݠlǛ�BGϦ�ԍ������\�O���f
m�s;����s��rke��N�t�#�>�Gy�|�D����h\���IQ����:X��ڃ!MB�Xp6k�z�Hd�
H�G���9���U���4p��*�;Fi�h�E�h�1�}.�F�CI*�vf���>Rl�w/D7�L ą�ʰ�Z�Yo3�N�����0B/6m��ȸ7Fo�*��HfO��OmD9������Nb^�M�w4T��=Ѝ�q�F[���`�܌f7i+��1��#��D(h|14����z��E_̫�7�.D鯅���cG�Ek��x@�F����KL����`��-T����N�H����32
]oi�2� �*3�ő�$�C�@?�:���+R�^K�6L�Ԑ�UM�^���:I��������ytG����� rlS������K����N��
҇.?q��d�Gz0oj�muj��(>��&��Vy`s��5��X_@
%OW���n��_!�oY~���WxD�Xa���i�|���;�4�@sR��j���t6��#��Y��
d�O�8Z m�����-|��Cg�F�h��a�IZ4��-b��))����Tل����B�j������Ͻ�IOe�wJ ���NH�OH��(|�n�j\s�����d��~����#�/h�n��ކ=�)���e�?��2����ֆN�,��*b�IRAI�%<[�s��N�H,����B��ΰZ�'���V���YԱap�l���[>ϝ�1�M{s�s��n_�m۫��i{ՆG\��[ YH�;"\��z�7�}
��%m��re�N�^�N�^M�z�R�gH|�r-�P�u���N�^�N�^�N�^�N�^M�z�R��
BN�N�ʝao}�J�$1�F�h�"�B����`���Z� -]�'��D��I�������-#j�b���
��vG�*�(G�n��n9G�tި��au������0I�M+:o��t������5����biAc��KY#��ӕ�S�AS�q����$�6�������|�.M1�Ͷ�ϥ���k�rT�B'������:�Hԁ�q�D�:�%�A�lN,B���Ʒ��}��ܶq�X�F������;C)wW!Y�o�o��B
endstream
endobj
3 0 obj
2745
endobj
5 0 obj
<>
stream
x��ZK��4ޟ_�5��<��F#�� �����!!@�
'Nb�i��ht��5���q������5�A�/���f�e�����/�? ��߿��>��x��������w3�>~9�Qi5�Y-ꊿn����z�w5����������Muf���j��`T����:����r0���Q;���q��5Np�;&x��Q���5����ȵK[��t��!�0)��(�O�
K�\��>$������.)��;@��q�N���k��3����Wt�Ny��Q/���n�
h���õ�z�=#:qV��]6��L溻:���u��B�7�W�{�ֳ�>�^�y
/��o�*D���'���hڏ&���7){t�m-Q���2�/�R��T`lS�R+-�Uh8
� ��04�ޤ�h0"��W�#�f�d��Ɍ���&#�lbĕ��$L�l2H�dF�P����Әe*�씌J9��Ĉ+mF�Ê�zI�M(
e�e��Q!{tD�e�'�P)��061�JF!��v��dH��0�J��4�
9MF�,��0*e��Ę/M��b�� 㚃���$Hos(D�X���b%�t����o��~��ڟ1�l�)�[[ʻ����(�{��-����%�F���ۥȎ �c��D"���F#�#{ʌ���8�9��������*�K�N�R�����4#�z��C��jy�cm�j�\7��
��xo��+��V�i��#5�;d[�P�f�mw�JU%k.�Zӄ���^��ME���?�q�'sV��·�賲$`��ɞ����=�o��&���*��ƻ��06B��mRl���gT�K���-ӑ� ]h4�����Ǐ��Kdܑ�v��s��:��-�1�;�I�������as+�"�.15j?M�Ѹ���%5����@��QGA��>g�~i�E|���!�!l}���d/��]B�|�����]��q~� �]=�-�b��aβGg#Q�]V�"Q���Q)#��g�Ң�%V��D���3e9�bt�h$�Q)gR���z1)/IR %3��̤2�H4�H���TB�}ZP�!-�肌TtAD� �- D?� Wl����x�U�Et����P�H
H�7}��UKz��w}�
�"v?V�AS�Rl�:ʥ\���בp��s�1��t��u����H����kOK�<$�FW��J���[j���u�9�K(^DqC�L���'�?w�_�����#�(w�Q���f�ܐ*��H��A�:�گ�˸=6W��B���⌏�6���Pr-�)V�X{�5]̖S���z�T�t6�2��"Rl������!Z���F�r�RR�AUi/B��d����j��6#�ܯ��<��̎j5�J_Χ��j�f�lM6\�%#*;���l�u'���v��1���6��_ �wS
�F8k.Ӎ���]-q;y&P�,^o�@7���1K��~}� ��/>ʡ�?h�ʥ���̞�NV�&Fǃ��h�uZe�uHH������UЏK���y"�
�&��}�*zר4���z�1����W�'֛�U'.��Á
�l岍�%O`�c
�0��i@�4-Nk��:�v��^`���#��r�.�7�h.Z��ܔ���}�'8�ΫxҐr�c�@C�u↥�Km-
�\jp�+ C��=����5cT�ڄ���(;7촘��Tե������u��лnS�/�Ku��KR8�}Cؙ��3.`�Z��u�
;�!ɼQ -�z�RI��:>�B�j�x8ў6�<�7u�{�2�>*�5z`�X?�7�c�M�hza~�WY��o��z���Ĉ�4�s�d [T��� 1�N����L #���X�4r�¨�3��!l��z�ߙPF��� 1*�L�Q!gB��6���;��(Pb,gB��Z��B΄�8
L^^�{��%(V`�&��oY�1�v��g��u#�����ƩG�����z�������/y�ձ.�:�\G��w�hd>��`
ɡ=���&�k=�>
stream
x��[K���ϯ��3��
�IR����E�]@�S����z��,?2h˴$��H��G����˟�ޙټ�a��6�<�������~}�~��6
���O�W5��rVH1�I��wW�������� @��mG��ț�g�:��r�x�vqm�"YO�S�ɐ����xg`�_�f�
%j��a��+��A�f�H��&�*p4{�.��M�wF�f*GOR�]U����ZT��S�0���/-�[�d�� �ܔ�:����'�+�N��!���뢉,"�| _�5���[�߿�N؇S��e�U|���ێj��y�fFk!�W��&�&�B��"�c�S��T���6R-�#�v�����T��z��2�kȵ�@� *�I�Lem(SY�JT�&��jy�(P�z�Xk������5�ŵ0f�F9`�-�^�P�@C��Q���Z�+���XYR<�_�@R�,�ɻ��zј!�(��vIy�^��b�ml臐�Y��J������D���Ov�I��Wz��3h�"���1{�5�n��}G@c�N�~�'��_� ��
'ܴ�U�_�I�u#=�ѿ9����P�j�;q������@D.d`�x��p7vݭ��{dF����2^@��ſ���Q��g�s�=������8���`�����И����梥V����Ӡ�% �Q�S�߹у1�_cq��a���c�����{��g�o�(%�k~A�=|)����`�.�,k<���jŕ`��Ǡ�'��sy\���3ڐ:� �=Q���,1�����x��� Ý�/��w�����������$�Ȥ������V�(��0�w;R1;�3q�W�H��>�_���#����M]Z9�"���D�zȖ��k��[�ǴQT�6��3���O���r����Y1��\ْ�z�"|֔�Y��l�/�l�&rBl�xϝ��pr��[�3��
�H4����t���>k̨���Dn4@�߸��S]�y7��hwV�<5�.��;��5����F��bp�[t�����ќ��|�^�N��Ccz�+�d0i�����T�ީ�A�����r��g+y���:�V��q!���+ےg��.fo�Qx�_�
sj�SXR��m����u�&��>�x�R$F�-��,��R��n4��ay�IǸI��炣)�[Ĩ����خ��U��eƌ�qw��/�1��q�=7@�m�ݹ�g�e�C,u͚(�taa�f���XD��4���'�*@�W��F�,c��L �o� L��%dڂ(n\ߎ���b�
�
!�w �V�6pjI�OF1��}�[S{};�,�t�~��]0&�⎬�V ���x�
u�d@>p$�R���Đg�O9K����1d��}��ƟP ���ԘB�:�a�>��'빖���Ș[6���jçn�@� ȡ��K�C��J�jv�*Wm4�>T"
��:$�Q;�!GN-GE�Ҝ��_�F���T�7�>�3�?�Q;�CT�����#;cQ�W��J�����L��3�3;De��QY;��i����&o�}f'S��F��Q�Q��De��N��\�Py��B���:�X��R�V�<�*j���i���Z�<`���גL��9�j�Q�^�C�wTݤ���_|�������Y�ڳW~w�Y�I�j��@��9��5+��M�?݀}O�ϋ�
A5�e��۴i�"�Q�<����IS`Klƞ^IJ���n5�{@9�z1)�<�^�:V\6�����)u#~w�آl#�W�Nt��lG�r���>X������N��_0 ���/�Y�R2�~����Yv,�](�o#��<����=&�^�.��4��ϻ�����ZH�O+}�nLI�Ecω��R/���IiS���"���1�T�������]4L���L�C�q�ۮQ�#$��kpW���Z�������j12�.W��Īqsv4T��hY*�}9iY>�_�I=�}��"�҈ �}�wAlt�\�0��Řr��qkw�(՜��k�.:�O���z��;�l����3�J�O���)*K2��j���]���;�fS誯����[�Q�qF/:i?�H(2jkgL�l{�v��$ž�t��#]�<��p�|�F�֚����'}#re;����N{[0������c�C�E!Hg�W7�Dz���=�0��+���Mm_�4��>}uփ8w��j�̀頙����&�)��,/i�+9���>��d&S~����t"��s���I�j��f�����(-������H����\ZXm�P��k�O��fhB���H
��f���2܃���������T|����Te�,�fdžD�G��s5�4��5>�����L܅�-ζ��d
0���)��I��Y|��T��ZC�%��
�y�+������y���O�t,L:����U��d3�=���Oi�ếf�<���\(��P/��Y��(�
�2�pR�,��Њ�;&kj;����g7�|��a�I�~���h��*��
endstream
endobj
9 0 obj
2569
endobj
11 0 obj
<>
stream
x��ZK��6ޟ_�����i�ph�n��ݙ���a��d3?�w�i��Mh��%YR���T�I�B����o"�7������e������������oo��79_�����?~��{����w2F�d!7x���AV��'�)��J:SE8���F!m~~�.>_�٨4��;�����~���}�}n�2�yP�<���K������8lr������$t}�II:}�nh˼�g��[J�
_������Ĕ)Y@�TR_&&U�wC�
�6�D���[T��Q�T��QT��^�X�Db�H6�D��VT��Q�T��Q$T��^�X�& �I$�B"�R+*M�(R*E�(*Mi/R,C�q�X*��%���1�Qa�x�ca<-��`C�C���Ԯ�oy�c8�3�Lhy��1��Y
˯�}J��K���3����
+,�GJg踪�ͮ��VX�F�UX�wީ焦DhW|�l��9Xc[���?�J�����'y\yx�'��̆�#�Q����f?ryw��B��5�ns�¯,��2������}���fQ��&��,Q�>~hN�����v:ghvN� �3�-��s��s�y5�+K��:��K3<����f���"�+֒�mR���U�A�:�%�=�ȫ1B������i��;B�CO6�uH��1uG0��r*\���g�s)=#6K/���d���tg=W�-@�j����1tq��)�O�I7�7�4�I(��=P��
��Z4�y�`%�
t���n�R�
0I-z�/Ҳ�R����mH�zԡ���Tx�1R1p%
�i�қ}��:j�?����h�ۑ�2;_1���7;h��T�6T�66v��Q�WF�ա�B3xb�M�OoIk� c��R�.+q`-7�������=J6�=}��rHh۩�ѳ6~|���oy2�3��:��a�3�66�+ҵ��)��[�� w����aT;�"��סH�����z@d�;�q�D!k�teb��KG͠!��h�s��}��
~����F��$�~.O�-��
�ɐ�q��s���f|�2�|����E�VgA���r��д�h'����A{�_�}� ������$.��n @����j�����+'�,ص@S4�Z�֔�D��Y&I�y;�c��Y{�;�7�ă����v�̫���v}��~F�fm;�|�Y�o�yG{�7�n�jZ4&l�T�#���p2�N�p�
l�Qcd�$U�9�X[� Wm�-�)7�C�5Z��
!8�Z1�5�u��,,���P��x�:����`Sx�Mt��,������
�c�P�� ���9�.���IK3ې7J���q�?u��No�P��s@)둸�KY���]2I��s�K�ɴ'��"�l���������u.�tu�m('�!����?w.i�܌XD�X��X�Ֆz��E����&@C ��l9$�$͉a��г����쇋��y��wS�%*�YaU�?ٕ�iFʮ���&���Z{ucK��
:��*��"�UG�l��ԣc`p`
^9{o�{.��Պ�h��\Ś�����v,&���ꢍHip�r��
�@�!�AUr�#ס�9~U�q��Ag�c9�W�#�]ռS6\�g����=�QU��,�z���\DBGҢ��"K���s�T�a�;�^!��v�ͪ#V�ڏ�D��"9=GÀ�����R\#��q`(�"���Q{i�)��M%�%T_�� 7S���ysEJ4�#?�d��͞��V��͝�
E����=�7I��'y�*m����[p�8A�rΟja|3�/#�&�Pa��D�ԝ$�,�]?Mi��"rj.����ڱ�1���m��:8j-�M�̹��b3��!��=���L��UD�@ƨ-��H�e����~������^��sHsR�,�g��j�gm�����?魜
Z^C���������o�2U�cdz�C���j��2��;���}���a4����I���דD�Ϋ3�4�y��=u��$���W\�]XK�J�;���n��v�;Q1�#�*��f[f��Ţ9~یD�b���"d�n���t�kv@QZpUSL�ZJ���dHPJ-u�q��v�#s��ܨ�����)�gtB�\_�@��Eb�e�Po�V����
X�#��M�q�U�
�V�h��ĊmB���^v/�yy��p�;���j�{ ]s(^5���!a�ͺ�V��2
G����|�Q�w�n�xCm_x@*/<�o#b�v��T�t�9����4`����Ѻk����e�ݎ�n���鱑g�4 ��Y�kN
Z����x^O�\[2Q3:�q��>�0�Ϋe��$=$�!�Nvhq{�����~ʥ�������Kͱ��y+{���R��5��D�<� `��
endstream
endobj
12 0 obj
2557
endobj
14 0 obj
<>
stream
x��ZK�$7�ϯ�s`:��U�4�3��&9,��!H.���߲]vu�Άfk�e[�,}�d{��_�����M-j'�Y�n���u���/_��~9��(��'�������ML�o���W&��8g�����BK���f0�������ő)l�����?^�o/�V���_
�p�Gh�>�Oq
�o�)�{;��k�w�� $����{6^�����}
�{���;�{&�k� ��+�3n�@;9Yeϟ߾�CS�q���{~>��K����=U~g'�)��/qWC�}��r�B����WF MV��(��@V��ɤ-��dt7ʱ���_b�b�
�����Z'L�DX@ި�!�F��d~��6�C��%�;z�_�
;Dd`�BfZy��AY���I�W(i%���0��J7�I�Y�������}�͵�f�J;�b����-k����Hp�+ɷ��JR;g�M�u����p�������O"���8G
U�!zL�b�z[\�n�����<�NVNЇ[�s��bf]���:pe�C+'���OsV�)��&h�[~�{p��7���;�L�?����x�1�Ywa$�QU��p�#���wv�1�!�U�֟��v�,gtN�n)���s��}���=�ER"�kvf�ň9e �)d�.$��9J�LJ���|���i#$�h!�IՈR/;S��D4շ�Z��|ks(����%{9�ë�R���1Ԁ�D1�K�|��d^jɵ��~���c�w7"zc0ܞ��ԃ�m��]�h(���Ÿif�|��=+0�!�Elƺ�\8���6B R��J��O��u�@b��/8��
�`��i�_��4��Ɏ?�p9*��ns�_L1\���E���0h�P�'�(�ԗ��~��3��}B�mU.a�[����m�=K�����TVE_Z~wD�Em.c���.��D(Zk����ו�T���\NxS--'��6��,7`�˘l�b��C���)��rƔks9bJr=&\�&cr%�)�:�6��TK� ���)ץR�k�s�u`'�Dj�o�u�Z�=H1�Q�;D�S�eƸw��l7��5�J%\�r�iR,.5�$��b���2�;Ř�5Q���5�vM�� �Y��T/�\�iI}e�ph��--W4�����~#Q<��&���߉QޞB6����ޑ�aO��g��Gc�*��tԳ�+�Nv������1"&���a��f���Ja���|#��3(�ܰ 4��/���n�l��ao��ǟ�q�c��P��Y)sN�?M��ܕ�
endstream
endobj
15 0 obj
2170
endobj
17 0 obj
<>
stream
x��ZI�,7�ϯ�s�uly�2
�TrK2�C�-��@r�ߏ��[U��#4�Ӷ��g��,��N|����M)�NbZ$?��_�����m������ۋҧe�����~��~������O��8�+��?�Wv=�\�����5\��τV���~�m�ŏj��Ʒ����_���
:4����F\H�#����g��>=���ogQ6+�S؟&|�ïr��Yi-}OH��B��f1!]�.~�ۃ�{3��
��߾}Y�^���&�Iu�fgz�����S*�.��w
�!���
�
H/YI9�d�nw��}��>�B-n�J�<�%���Wtc q��T�"J��V�`���<��`�웅���-�Í�����w;$Ju'���6��݃���;�P�
����kd��䥰䩩X������'���l�����{�k^�w�]�p�����a'=ſ�)��j\�<�\��>O���+�9��B˟'��`ju��F��牣��o۔K��!m�l[G[sqU��e�jp�5��b
L(=+�N�\��J�i��*��rBEZs9��#T@0A�(�� 8�@P
�;I\��H�nfҚ� Kj�儇��rZ/-�u$����ZB��Fˑ��� ��!уc[9#6�ݾL�H=��,�TjV��:��(��Eu�wi=&Y��Y
��0&hM������]�,�0�1
P�Z9��z�6@�^�
��9J�h�Qo͏��43k���ep��-]�tŦ͞l�ov�5�'�^O��U-��m=�Q?m�lA�惑��mm����G*�q��H�/������
���7�xq�;�u=ub�����ƹ�7l.�]�ڼ��v�(ebF�ְDx�����8#a!.ʴ�48"�\��.�g��U��T�,�n3� ˩_�l���ҝN���ٟ%@G��K�9ᖴ��8�=�j\;$�T*�f�$nd�V�nI��`H����8�O\�@�X�Qb�]�o\����걕�zF����H��GDs�#�.Y�K�W�4'�ĝ�?���k�x�8Z�k��F������w͋�E��y�E�4�[Z}r�6����'�Dzs5�L��p���`��S�16탡8���I��>��2KΛ��nЬ_�]�SJ�LU�"�7��pn&)Q��� @�������
O\z)�<�I�Vbkd��J�\E��;'�4:�W9I���w܄w��)g�=��$����N��\���I4�IqV)�[�����yK*��9��q$ω��N���k�.����X�捅U�������ܠ��o���MEVt�.���uE
UE,��9;�N�����0?���0�(���Q���^Z���S��W2��7ez��v�yG�4y87Ʌ�F�列tQ��\�ҥ�/�r��ښ2��HP��Z2_�����{����0�K�,c �S��>��!�ԀY#������-\��^��F��!WF�-����d� �;�"��2/ol�ɉ�x�Rd�z]��du�QZ�<:��wb�l�;���l�����{���$��w�Z��� �ҕ�*D�c�q"҆��z�"'���ť ��*MS��"�����~,5۠y@{���T���\+��������`+���cd˳]��L�0���ѵ�J��^>W�X��&-
�<6����2lEPZ��<�:�x���/U���[%�W�8���s�dV�9��.Ѷ=�p�F�7��$@r��νl[��lU�>�Q[k��hǚmZ'uh�,F7����K�.Eoz��1�79��Wԗ`lΑ��\���-|�}��n���\�WG8H�h�Ȣ��Y�J���a)� ��_����w`%xX#�V>������7��'V�>�90��L�q(&�B�w��[HFp�]0k_�4}g�?o�wh
5M�f`I�W�]�sK��vct�*~��䳄6+���S�8�AVYF�Xz ��W�3��ױ%M������8�!��+�>�;�/�\
�6��J���/(�m�F����t���J�loV��L����iv�#�U��{V��"J��D�7L�T���}�]�l߯k}�&��2�yپ�|�U���Ȟ%&������Uf�ӗ+���CoT
w��øq�
��x�j�̾�ц�k�X�)E�j�(WwG��s�C)g�q���d��Nm
endstream
endobj
18 0 obj
2277
endobj
20 0 obj
<>
stream
x��\I�#�
��_�s�vDI�0���m��0�)dd.���]�(����h�]VI$��#�jq��o�;����3��i�p6�_�q���N�
��ׯ��X>?��<�&5��?��'Ч��|��
9]�E���"�{c���U]�?��ѿ߮?�EH?Ύ���{�'\��ǠY�@��i��q^?c���h����Ϗ����l�=#��3"��]���_�X�,����y����:�/Kb�K��@�V��*�����P����翻�β�7s�0���!��Y
��
�d���g��03�[�q�k��_�d���<'2�9\��"q���#�5��j4��֒kC�k!by�+�BD5AY�9ݔ�Yv��M�����B����[gF)ɭn��mr����#�a��TPƪuz^�½�������*rAW���%��;m_^�ytG5�\8�Yר�
#�\fX�Y��"���7���a�� x3ۘ+��WО�m��8��ت�e��Le,/�!&n�g�Wnnt\zj-��K���0���7�q
)~�&^zek�Æ"���<�e;,����л�TH�;&^��ih�HT���o�C�ᚍ�X�]`�Rѡ�K��˭w7#��2��FT����t�9*�4vUݪȨ��҃]>:7���<���QW���Th�@��*"��क़�
��+�V�S�8�Bmi�^7Q��-��%ѝ/�.�uٷU���$��*v�D����ړ�����a���j�0*�2���a=����R����`WFߤ�W&1�m�YS0m`'ɯ<�K>��F��x,��MI;�l��AY��}+�پ��;��8�{��i]�Ő��ٖ�%���xZ�� ,���
�+�e��
n1�b?i?J"�<ٞP#A�,��x%{0�,y'ٓx��gdK$�^�ꈴ8��"xʞ$,F���P��7�iq���_��-3!�Ie��9f�&/s�e��`9��<��#�O�*�B7��b�5�l�V _��˾ -⩪ �ch���Z3f=�N8���EϜ��\\�%�4��ZA���%z.�A�Y�snDِa`��
Jf��Ml��v�'q� (bQ'-v70��� K�S35����:�c�tS)����h"��@Ⱦ��pl�!��1�d�# ���
��y�
@�\f��\�)�Q������)T%:�F���E2a��R[��y�� ��ٖ^��7̷��L�; ~[�e��]5���
�cZ��M�T�ᆶ�&��
,�h�h��<0c�k��5��
�/3S�/aZ�7�~~8�9��ˇ8O�ߪ���q����/'�c���ӟ GZ�}��Zt��MJ*�-���,$X�)![f�)'�+d�!��4�6ᷭD�B���� ]���^�f~�r�_���Ϊ_O�/�y)�z��ڬt�V)��m��ϺU͍ۢ��MƋ�;h�o�i$41r�X���� az���x^�٢�Ƈ�J���������z���ߋ�]���L�+�XT�#g�ؿ�E{�aL_�u+W�|D�*��d�8�%�uT�}!�jB,���v5sw�0�.@�t}R�N ��R�M[K�Ω��N�t$
��T#B�x��`�d=�nU��Nom bڻ�U+�]���l�Fu���SPQ�)�Z�苫�+���ˁ%BT(��įC�-(�Ȫ�T>� V�X̻����ع����w������륻~�
�G��hy�G�M_v�U2�"�c���"�4A�s��L�i��*bR�U-vTmvԩ[�ӭV�3��������h���IX��!Z�W-J�J��U=���$'�Vj�e]PGh��M�ѭ��܁B�t!R���I�q�W�(J
�x�w��*���q��kX|9�-w�Gq��0ڤe�JUm�T[h�E-�����4%�H�B�]�WeZ���[auw�:�N��"D�c+��v�xͭ��R�週����KcwG���|@��y�g��(}��,�X*��L��S !#�g�5g��N���?�uH%�K�ݑ.^�"|������J㎵�L�iA�jӜ+���i���Po�����'b���Y�@�۩��@�{ rx�̩��U(ؾ���Ȁ���.�jk;&HE�}�Q�����JP����Q憽��9'��w0o��
zG,����������8@W'��/�����/�K� ]�μ� 4�!�J��G��(��\'Q��p,m�H�b]�iњB2�Z'�Y����E�����-�}�p%Y��M�E!�"���a�-�����9���=��(ۭ�U7�Uj^�sSe|���k�� �贱Dw�]-�_'d@�r=X~4
m�4G�#�.1���}?Ҿ��wp�����I(jF�+v���V�[�P��;�C+5~��t$�|�) j aV��a\�I�L�m��*�V�M���v�)���A~�8��~4��mE"� 4!o�~�g|�����r�F̘�-O#����)�Q��jw�v���z���E�'�n��<`�Q5}�%�Q�|狫�˱���;�t�mz��I��}%;�c����ذ���C
�ԕ�GLz�p<`SWR����M}��+������Q�Tˌd�@�u��{篺�HRvdY����5��<�ޢ�������Ï�I���C||�ܖOW �����s��G�V�)9v��qJ�:�
wi��w=��X��B����َ�>OMز�a���ȹ��sަ�|��~��s���� 7�t�B{@@
U��:�j�35�{>�F��f��!%���a��Ij�c���2�y�����RI�xkum'x��#H�P�%��TO�7��OW�j�����Œ|�f06b/��u:D&T���O�@��5�o��i�W���.�!T�!���a���d~:�-��
endstream
endobj
21 0 obj
3209
endobj
25 0 obj
<>
stream
x��|y|U���������z�^����t���V@T"��� �}�qu�e�ˌ�6
��*�.��:�":j}��F��wnu'�8�������Iߺ�VUW�=���{n���-GRN_�)B�Ei���3�)����}�N?<ޜ3�ߡ�"t�^�����qW�-B癡������r�2@�ڿ[���9�$S,�7���9/}S;�A��&h���Y<���_|�iqmK��w>��Co����;o�Ƶ���Aȸ�0��\ki�0�F���&��j�x�.:�.�������
G��x�*�Jg�k��u�
�|㰦�#�[Z��������7#/l�\@������xEy�P*����ɕo�3�nU��xBy��@{�bt�=�5����HA6�ߋ�i��E�wДҷ�B��oP
G�KEģe�����8� ���5��I�_�R��Y����W&�ې�_L����D��Κ�^af�3���wx'�ri.��B�e���a�*�*�U�Y�!�_�s���Κ�f���p�ѽ�5<���������=,CO�Wp�E�l$����ߡ��V�,ڃ�G�b�m�
/�o�T�U�U:�4���F'�Ih9���INeNec�+�gq)�=]�.F���h
Z��CEb��d2�yyQ+:ͅ�\��0z��z��#������Y��؝E����߄�1}=�v�7Л��2X�i<�Ŀ�W��-�A�(~I4�}�a�d_d�,�[2��,=��"�Q(ӄ�z�����K�n�o�4�0�5�ņұ�e�J�J���h<�4��tڎ^�s_C���0J6b�B�|>_w�����D��d/�f^c���6ō�o����Rw�ϥWU�6�u:��h):O������}��� ��X<��v��}�0���\A%%��Yü�J�������7�r� �[� ��op�4~��0���G�2��{�E_c7�Z|>Oó�|�/�]�2|9���x3ގ��� K���&��ߒ�d3�E�%�bNf�1]�e�Zf3��9˱�����f/a/�
�u�_=�:��0�pg������U���?)�J;J�"-��{��{�
<�5�Ft��#p���З@��`,l���J��� p�S�t|&���a����x#~�����+�-���`���k)�B΄g���'����=�o&�d�z��icf�Ӭ`����=��)KX[Ǟ�.c_�0�34�i������|��3*:b�`�üJ�cۘEh�D��i��!?�??~��g&1�HiFo._�D�]ڐ6DD��f�� w�jf*g��|�7DN%א��!�4���N��y��#���؛�6�Z�DĂ@#�H��{u���'���/j��a�bb)�`?��-Ѓ�`*��O�}xq�h5�Q���q ��ߊ��&v?s=G>��Eh-~�q;ZD����4�<��'ộ:t����[P�,%a��)��o�$�'�M���X�BNG{�t��X 5�
���h^�2��w�W�M��c�=,�>܇70c���2�2aᗞ�Ѭ����:b
Hf���4!
��w�<��{|9Y��ۙ��H4�c�#c�m��ّL��6�&��z�i���P�3��xB���>�oi�y�9T�^
gi�ŏХ0:cA��Y�>�N|>�-��l�t
ZO�`?*���Л%���܂�%w�L�D��Ӵ�`W�W����m� ��5�ft'z��`�0���h�ݳlD-�Gyx�6th��`�$t
��٠%�D�.м��G��P�a4 �v��Y�P�xU���B�{����m��nDJ6=��̦{v��qL�{���8}v8y��X8���紏�?�;e�����'GƟx�4y��ٕ�?��Vy���J���1��J�xu/0�́�ic������Ve�3ztz�J��c���c��tc(��<��t���n��V������G���=�Jn����O]��xԾ1��V��Ǭ��rNOi�܈�EVn_�t��~������v��~:<�|<���c6D�'nP�'�:m+��mh�1���ӫK��b��P�Q��l��z�y3�P
K+2j5Py�a�Ǡ�}Ob$�'^�N��j�Ph9���eWhA�-����m�C|,ć�b�a��yXѠ�����7S?<���ԭ��G�l�M�Y��V�&s#P3nF��$g���'�G��F��<�8,��Y��ro�p|���0��QgF��p$� C{�Z�L��2$l ��]�n�;�&�D��!����'�/
��� �E�nӂ�1���9��^���4
�H�*&;i����<�o���"�Za��NxC`�g�(
O��W��C�]u�q��`�������%�]��I��ͮ5n�q#=Wh�gݘ��3{h������ݴ]W��:Qg(�#�x>���3��D��C�o,����ʹ\�s1\s��������n�-K���\�5�}�)�r�ۍx�r�#����0q],�̞o��s�w�x��f�V�z�:����-����͞��W���FP)�����!�լ��������ީ��N_�R�ˆb�p(\%���dc5&1�`6d{�~�T|m26��!�2\fi��$���*�n.���$�!��l��p6����/�DhGh_H�4�V׆�t��}��}ZV+
Kmw���Ք�;qzB��xgNSvG�}�}}0�}�N������k8��pa8?
��{J4�[:y|w��+��r��(_�th����7��騳5��"��{i'��Չ;Cym�x�NW>��u�a��h��o(��������q3��7~����F\;q��d�2ZO�{�}�=��Ϳ;N�����O���;�\����v��Ín�7�<�{N/�u�����擎�?u��)>����C/��a�q�p�p�p����,����(z��� �b�H\:F��XuB��*
�MVQp��h��X3Jk��\�Ձ�Q)�m��:��T#Q��"�"�#k"�"#ڈ�)ܨ��βN:� B6�1jQ�ԡ�UJ
?�H��ؠ%��mE��s�7��=��yO���U���n��V��S��ΰ���B�p={zå�˓]
�'�7ܓ��a}r]ö���)9�"
�d
��&(��s˜K�y�X[���Z�雉kq�_Ʋ����
��0�0���a�Ac��kBe�tG��=��@!6"�Rs��Uׄ>U�(�
- U J�@���J4J�#t�ȑ�2�ۑ�tyJ�6���=�7��Z}-�$�
��ڙ�)}�4�S�$���&:+�T��ii�S)#���Po�2V#���N슺�Μ�5�~;s�;����c�x���nx�쾓������dN�r��n|�q����b�eF�����[^{
$hOiSz���*���D8MGF=*?:�M��_>���w��}x̗��������x�`�k��6�1A���h��*|kn��4�~jӂ��͗6]�|]�u��E��[��D}:��)�-9��f�9��Q��6��4ڬfƈ^jnmk�a���͌\�kz�m�/�
�fݔᡉ�Y�%&�S79Ҝt����N�i�ڕ�K�8)���1ڸ1d:my��@��vL =�N�q�^J� �B��턢��-�N��>�*U�u��(MÎd_�s�9���;<���P�@���"���u��%���斦`c�#� ��Z��r�����+I��f1g�=]��J_�Q��6���zJ_m
;[|G��F���5��R`%�E(��P��9��(�&Ba�0��}�w`d�AO���H|@�cU�;��C���]N�WV Q�j�����(�s�x4^6��n��t���7��<���'F͙��K/-�;,���ܱ�u'�T|�����}�I�A�� x�RK�ix:�R��ݑ�Ǟ��ya�� <��Q�m�t� ٬��߲h��ՠ_���P�V�댶� ��O�SH��<��Ӟm9_�:���g�N�_u5|��k���F��d��t�3w0�2Z�O5R�/I>�鰩ma�Ulְ#���l �1lIfm�_3�52�!��ա`sL��X�i� ���'�g���Y�TڍG�
5 -*��kQͿ�3�f �R@�̵�@U�mN�-2�V�Օ��!9�=�3�+������Vz����
N����:�Xx���_�ڦ�DU?]�d�y��;����{��w̘y��s�KO��I��]l3�A�7�yc�Mo�]��5�]^�{G������ғ����L�n����;C�������\܄7�\$���R��9��#9n),$�*�23k3�lm8ɛT����:�h���a���8�b$6���i�%?�.����77i�6���t��s���n4e�> K=�~���\��v]-���;爩������^8���$�����]�j�A5�^�F��k�D��x@���T��tJ�3�~6 �p��7xŲ������2OPa��H??��`��d��Ϟ�4�X�
S�0淋O��k��&�i���c�.�>*Xu\���,\��~Y�Յo�[���r��Y� ��
e��y��ԓc�I�t�"y�����#��?
��i�|)_�4�y����\�]��{�����4���|��]�˾�Z��G�Ƽ?�ұ!�d��i^��R�����
�y����;�=�>��P�ѣ�B�
}�*�*�����)j� ����wR��!Uy�Q�����s����Ȍ�>�'����H��ss��_�~q��~�J�]�׃�����X�~*�������U�?zE��A�D�3�F�Jn��<�UD�i.�^3
�0H��V���AoDX�9n"��c8I:q�f6n���f�-8u�x�
@ț�82�U�m�w�'�~���~J�meJc�Z��o��#ި7��$��8���P5d]m�(�$S�M�NF�o'6�8�~�k��YOgLQ
}��q��)�'e@�$�hWA��ng�c6Y�����&ڊRd1�
��x�M}T�������*��4YRv�n���7/����>�Mm/}������[��'�w_�����]������>�h�}�¤�x�y�&)��9���j7
N�Vù�vG�]3�`���F���/۰�,�,5
����,E�����QN��8D�U�q'�-�$�VAҝs�i��$�j��I�ߝ� >)br�F�_�=�h��Φ&0�ԼW �C{����cܯo�(d�.�=q����}d�+'98�5��ݯ¦W�c,>�*�=.�˿���{�N]|���1��+�L��M0�-0�&��c�&��: 2/�M�5ӽcҞ�[��d���B�"~��L��bl!c2��!�vR��n�.u�X�n�9T�f#���[i8L��1K�;�{����m�d�;�X�Lұ�+tvQ�
��Nѕ��MN�������"&{�M�8�u�� �br���]�O��n��D(�F(t��)��v�h`'N�w����SXG�R������ �-Ӄy�c
����`Yn)�=���5v=��S>^��c��O�,�����/|������@`vmƐ��bfk������Zm���6� �͍��ލ6�1�⛫��;_w�OӨ���֍�M�ij��ZU=�o1�mĈֶ�2J��$�!�
,8Aa�Q��Ca.L�c*蹱����5��1ن��l�q�B;����c�;:��puV��TW�}Z�K
S��m*�xB����9���r*�|�s��8��9���r���PVno��4Զ�mO�&R �U�Z�e`��T$���7�G�+�6����K0N�Ta�P8W�srU�-ͬ�K�� �h%�+��4� v�=�K����~$ ���A o�K_#���p�6��o�]����w�i�����N6�V��iw�Q�2&< �`�r[7�c8���E#熚�1��X�uBC͙#ǨՉuՙ���Z[A�S�=f����O-l�&��^�翄���������*d�<�{����o�f��h����ެ^{;�f�@��c�56�B��j0s3P�7��(�o��~8�Ae{
��K�r��Lt�n_0*��19��d��
`LQ�B�t9BD��b��Ц���P>:����¨�P�?���!]�\�·�}�59��e�<"i
f���ι�����o��,u���^2bբ���t�.����>X9b�y�?��%�\����_�ߴ� <$�E
��y~D���XGӹH�,tMӭ���mM�j�j��z������C��\_���*eyz�1��w����fJW�Lnč4�rU<#�7ɲ���7l��6Xa�Eh�FZ{�E1:Z�o8���$�+�2I�4Z�W���2!P9�7��������(5
�B%�Щ�O��{�\>���&��(خq(8��+Xd�
Wն�i��jBM]�9Q�����?��O�~�)�����=�>���8N�뱛_��dg�#Ic���y�ԛ3o��S/��W���-s���ZN�ܶ�Z:~�������iɉW�:e��&��.�%o�`�����6�?2ϱo!=h����r
xmFhd|ϰ�<�2�b���~�
��a'"��Mz�������irзxR�&@f
�?U�I��!�`��2�=R�k��ʒ$k�Yj��5�[EO<���-�KS�����EULFy�ʙp]�<�|��C�:7��pd�s�� ��}S��t�=�ѳz��u;�H��r$\Ml�c,;�1��*NsL��U���f�;�r�%�Uu{��v�m���z�O�u�-d;���v=%=U���%ׇν�8{]i���L��3�Z!��zԹ����E�#���s�'�.�bW��eE���a��%hWfi��U��AZ[}#�,�.�.:)J��;���DU8T��ZzBr�a�a5� &�o� ��>ځ
�;4�V6kX٣�P��Y���HaYr�J�.��4N�w��,jXVv���!V!$�%��&��.��C0#;�p�����A+��N�_��h2��d֘hy�e{�E�lɲ�b�.qc��%n�Gk%�6/)U霤�P�PH(l|NjVfW����`�\x��rN!J����zQ8>Gz��F����?��Z�YCAMm�n65
ϩ�t� �Q����W��ct�NWN�8��4�5i&jX�OPr�����`��W�z;=\�6
�W�����;�;��.)�T�%xý�R裳���p�`�>R����{:����l'ͮ����S��?��l��Kz�;2���
�&��ø
�����!}̵����0�p��B|��:�u�����Æ'ѓ�%���]|������2������C��h���,�����}��n��P�R�r]��x@�U�&��0����o�����kZL���?�����?��fTE�-#��p��h�,f�UQ���%�d��9�5ԡ"��%�%�%�%�k�vjv��;
����la���C0��\�Sq�n�u��?P�t5�Fg�k�階g8���u���2����%R���s���U����茥Q��TM�����Q5���)��Ħ��o%�ưFU��zx@���؟W5�4R5D�_J�_C4D`����������P �A=c�gX}"��Y��-ڸ�hg�D0H�R�G�A KJ
D�1'-�B%�MWlU��YU˪VW�W���*}�vr��(2�(�4���/��To|��k�\h��z��!닦wMZ��h.��Uz���Ø
��5�9ك�W�@s4�k�i�!�$^����1���x�E��|�o�o�O��!�n��A���s��0��U�+�ݨK4ė�h�x�&��DF�9����x:�Ȫ������<��.7T>ކw��'MtMyq�h����]k�Ku�i̎����7��� [��������?҃�v�k!`�r�rk�
Dh���K�i��l�XXZ���g�g�u��Ы�W��=�a�#7�=̠z,t�BG�G�P���r���2�1��u� �rb(�#���5��Bs�Yn��5�7G�#ͩc�;���f������=I��$ڧkr=�f��qg;Gs��k̡��l� ' k?�ӦY��3��o�ܙ��Bw&�����Ԫ�/�2=Ɣ�Y{`�
8�����!w��AA}[iB�����J��)�����^�I;*[rs}�RhVԤ��P��&��]�)��䪦�G7�Ut��&!B���8&l�����V��U��hH1�5��\N�8�3�i\��g;8K=�����»-�\CO��-��9v��NC�� ����Ih��>Q�A�7:]m���:F�vL��a>�Ӣc����dkǴ�r[�E�(y�8�]PO� `+T�=�]�8�F�v)�DZ����A)��yԄ"�G�06BGyNcs`|�F�:|e\�y���fYU�Zܮ�
� xl�8���H��?���g`/��Aʧto�P\�sZ�!<��R9�bq�p�W��y�o0_�,f'8�]�`?C~Bo*� �B������~��N�8u�"X��:�P�,la((�k�ð�P���Fd�軍~����}N�C�RlXc=��"[�l#����X
�����m�-�����5�@S�@i]"03�T������V�=tF�VWۅCy�p$�7tҗ�`�)���~b�:ӫ��ݴ�'S��g�a�_�Y��?:�g�}��#�|�N��M$���� @ƠqM;��m���M�����C "o:�7������^����?�[��Y���~�
�lA�%�6�`���1�ϡ�0 '��p,�f��T��X_�o�gM��o`�z
�7��[�cn\N�M�ɀ~oM����$pے�t�*��)�R|~�d���DĴ4��D�B�S h ���1m����M��/��&�٬�df�q�>�hj��a������`bVbI�Ď�&�$���"�m�Չ7����|�8�A<��x&�>K��8�2Êl`�}�}��;k��?���@�>�����]������\A{��e���䅖�2���{.���z�``"�(������_=
�ٹj�J��#Cƿ9��;������_��r����6<�uʭ�2�B��]e���~�e��@��!{U�2���u=\��� �>�LI��zpUO�N�Η~'��n���l��?��nu8�>�pOoyҧ���odz�|��ʲ@'ܔ����a�˓�?�q�2�����8���eG��O�V�����7(�x����d�@>Ch��ě�yA�B�@!��1h?$�o=���������!&=�*x"�~�AI�4ᵒ��0ׇʛ�����2��Ҹ�d�R��3g��حb#�)-ٶ�N|MH-�v�tyk�
�v�?��i�ݍ܂;���\y��'Z�O������q��x>�����k�[�g���/��[�Z�z������Kv ��,�|G8���H��\S��*�@����Շ��vC9A����~`��#��W���p��=�ק��wq"��$�H8 ����HX�D�<�-�E$�����>�t9��+6{<��]mN�5��)+
L
������4S27��3�F�,����h5RCj��P�{;��d]IʃTf�A�U�_Q�R~-&�]$�����s-�Ԅp|����С!D/���y@MS�S�Ij�ڧA'���J�>��t���à�dC�����6*3�+�ܔ��ld�8I�{��՜3sVo6�a[9���=��\��v5���9
��v�D9ԌF��l�Moh�lZ1Ęd!����/��谮����9���te�:?��S�\^����)�\1b�N?ʃS�8��j51;����~L9]�^��A��W�Y� �'��&u9@b�3�z:Î4�W\���˔�Ur�0���֫Z�u�ﲻ;�]@*%n8i���jYWQ�;�d0fdA^4l�.
&�G���L���N0�ۄ��.0��, �@��Ђ���h�'4X�0G�غ��<s-��S�a�����R�A��6�~��
���~�?�����t.{~dS- ��Q����_�sNp=��Ŕ��e7� i+�N�����p�n}P-Ϻ5�ʄp�\�k�8i'�����w�Zf�a�'�o��bmX8�vʿ��<����6y
��!)�pk���'g%�Iޞ|Y����[/�I'���C�+G�"'G�A�C���1:OX�W1�[Yֈ�1x��T�V����Q��j�$����gŢ=�oOqRu�5�O�A���s������l_��;��E�K�ۧ1�4�
Px�~Kzב����.�Y�:3ӿH��h�e�m�����/:�%��x��7����-���S����y��߷��1r
�p����ќ�I�+��S�v.��m��*�wx~� ����5��S �x1>�}H�Y�E���}�>�Σ�]�.y��x���"s��o�o�����}}�|K}�}O������(��Q�C_�]5�h�ut�b��#�Ŋ@�WȚԌ������1����m��p�ot��E���-`@�l��>�F��Tk��މ
�
9�q��\�~����nj$7�#���?���{���S�a���HU����lm��m�a���S�+g�I��0�bkV%r�PÒ�>d���������cJ]<WF.I.K�Nޗ|"�IJ��ن��P��h,g`
U�e*�@�,����E4UCe��yxqp�]�Z,Q�UY,ѿTB]YQ�G�ڲ\Xs��V=Ps��3�:���?���:�����Ԙѵ��9s�ۏu�m*`y7�q{'_�zN�I
A��O��O�+H|�C5&}~�I�
�ʎ�b5i=�%Y�[�kT=�RxB&4[d�"@)�
o�o�~'�Siv@=z�(h"�&�ƚz���H�Y*-
��w��E}xr�i���߫��p��[8�����^ST��]`2@��G��[�Q�5a1�ҁP ���}}�bͳ��v�~
{�^�C�\ن�m$�)�U�4OΎ�-4���eY�Ȋ�8ק�#�{�a_h��~����v�����/-v��u�6.٢r,4O>=tI蒪�Kk7����5b<`N�Gl!�d�t�~�Ĺ-a��c���fIM���'u�ƥ�Z�u��<����a��w�l5�V����������M��g�k��:�Lz*�Zk�V�n;n�WҀ4K��Y�=�|��KR˪����!���x�`c�f��B�6�`����*7F�V�3��Vp��{L8fI((�K��?[1�J��.5�I
���������nۈ�{XFq�0:��L��x� λ�g����Ǝ��u�\>����-B����R��%K�[7oΩ-�~�9�����Y��[�^��ya�$��bq�g�7�����z��a�#�.�w�9��
���i�l%�.��`�X�r ��@�f��aF��Y&#o�,g6mL�ɟ6��`�v����&��X����R~�
kM�J=�!b8�7 !��g�,<��b����i�ZvQ\��]��n��]6x*<��wtC9��4�V�sҶ]�:$���:�丹�ԃO��� R�!Fg0�C6�>-�zR���,;D��n���DF�����3j{��������OP�R�������Q�Q�g��
��T=�ꔪ3�?}
o5=x2�K�~/���W�w�u�^�j��M�N�S4��N��L�"��2�e�K���� o�9o�h�zJ_l(�Gujn:�džzT^���z�*�������?�|���A������?�_��o�X���]Ń/>x�}���v]EAЧ�O��5��fY��&�#�J�!tn�>9��*����?���'x��|�g5X�VBW�p��6����T�;%����AkXX��T�K8b
�
�V���X<��0^}�.�j�j�0�%M�i����2a�ue�?��pq�䒜�C%����{ޠ��&�U�d<g�&��l0��:�F����m^�~���^[0㴱�]W�g+�`��{F�A�������f�����◧�r8yWvfg�;v�MS�_��U��[��VЯ<��y��;��M��}�q��d���Qg�5N22FI�����t��.����������o���������\K�@nQ�M���g�(n^�������f����I�+�L��t��f$���������ij�IT�a�[Q��K9A��E��mF�̺�]zDݸ�S=��Η��\��!�`ꑺ=�w�o����T�mqC�����ř��+3�\��-�:�����3 �-�i5U�o�����iPC�~�[�lv�y�C���LPN�C�pu&�A�qI�nR���$�Cak��ѻ��x*eW;��\���:ł�A\Ċ�8ރ;�,<\��xRx]����0��y6^�p�;pZj�h�R-�ή��^�=`�vU=��!Z�~���X0�0�A��A�LazH]�w��뎼X�Wz�K�~��(3���?�H���
�BxJ�Yw������w�ݧ.�A���w�_R���s6���%�W��8�h��ߜz_��n5p�]��'OZ�4�v����{Z�ss�%��'i�k�2_Y�μѼ9�|zo������t�j����>�P�ػ+���]�V�Q�3�#$�RM�[k��4���N��٣.ѼU�d�c��
��lůV�� j���;��MZ(q
*�~�4[�`a�>��ח�e�(�M�T�f���茞����%�R����ԥ�������l$R3/�nmKт��p�����!�)\S1ַ�3-����������A��P��3�g�H�O�h|���Q�:�2}�|W���1�e�e���T�6�WEW��S�y�2�Rn)�TXj�'����O_c��ۚ����Tsz��XNo�J�/�yS�lĖJ�/ណ��e����.���W��*?(o����)��;���4TX+[�H��^N��qg"��u��N=q�#1�9hΚ��ͳ�K��du�Ol�~'���?�kyO.Q���܃�<4���h�RY����_�~��jC@,ь M�x:���q���!Y���xuy������
��q�3v�2�9�Sy ���U��VcyQE#Ubw�^u���t�pr���Q�\T܄>�����*�5����\z��ݧM^5W�ƈoᰉWv�]8\��
a�~-h�<�ي�t5��=IS�E��U&n<������ᔘ��$S����h{�5ٞ[(.��δ㈽�N����_c�}�*�S짜~DlDnata~��>���#T~��i�Fꛩ6����E�\;�*X�A/��nPgjk��jkr��\��r�5[y�E�Er�r"�����e���drf,���X4����x)"���""Bd�GEMW^/��7g���3bjx�o��(�<Ò���N�o��Pz,Ks�sD���f��a���nƲq�a��p�P�f&�Aj�A�ˉ���.���a�C���*���Wf�#w��+�JwS���N��|��[���uU�ۍbU�E7��
�ov��]�Z��t����������:+8��S���M�hN쁭����l+�<����Ģ>F��\釁��#�I��~��r�J�����nk��W�
�#o���AN�x^Z5�j��{�}sTp��6�/,����g�o��ů��r����1�4��3+�D�L�HM�t��/��� �A]yj�ӭ���O�䗤i~I����.���k�4�ER�x�_�����qS$��Q<@�D�Q�q��+��đO�{ð�pР1���T�U��ܦ8c�(��I����p�N7�[����*�`�I���a��UPq<�]�0P<�N�:C|T��R���9rL�O!ר�Hs��SӔ��$���j�oq�(V�G{^+�<�E�}�����W����I�k�&r�q�1�SL��S���>��f6�W$nND��ƨ�
_�(��Y
�l������>[����Wm���nL������3�y��Yo^�Ȣh'�k�YSS�y�q�>�'z�uŒ!N�P��S�۩I��q6�s5���Q��-7�]G��#���@�)}��TU�bK�vF���9�)��!7�UYqy�+��g�Rϔ�b�f����1k�k7N����_�^G�wn�wa훗����F�>>��S˔·<��7o�7NZ��;Wb��%u��x6(��Sͻ���;��A�����&�E��|
�υ�����Xo5�gJ? 8UF�R��˪8a�SMje���v�vZ1�l����b&V�3��d��2D6����m�ۍK���H��%fl��,D�J��w�ݫÏ�㯨IcUu���&T��V���a��F���?������5Jc�](��̻�U�I�"�~('͏/���損'ϟK+/�O��7$��J����n���m��>V8�s|fL�$a�s�gVfR��)[�R�LH5�
{@qZV[}lI��a~#/D���Y<ސ�Ǔ)$���~}����A
)�
�ZR��X��S��.�%��h��
.� 2o.Hz�A���z<�T*���^�G����.���ѠU���kHM�A���=��G"�mx�Cm���{i����
z�{zY�̓�$�WDžm�
�@�H�P��yy����7|�gy8vSv���,�1�̹\-T� [���TI��&�Y���յ*�WM�l�Y�-/\e���~�:��ѕ,�e�������i9���M�G|�H��%j�֭�<�1^Q|m�|���n9�p��MZ<�A�[�<j��;�D�Ě�M'�g9;kNl�c>�yN͜�{k�4�1�#�zr=��ݡݹ�rߴ�u�}����4���,�P]ʋ.����b�q.n��q!��q�1�x.��7����r�X�E�)�ޣo&)�M���2jj4�!���pq�ì���t��m���]3Q�ڻ�ඊ����dI�d�?dK�~S^�!ڭm���j1�3��u�,�Y���g�,�ˬ��.,��Cy%}��֦��a�)ȖN�N��:�M�l�D�>��.Zl��k�s�r�w���GbFzF'�`/�\Deu��y�r�9����!����N0"����,�|�>h-�l�l�iڣe�N�-��i�"��4����?a���L�����P���;�9�EΝ����d�!) �oܘkկO��|vA� �_;\��A�?��YM.�|��W}�v�!~�@ZiK���V�QB��ʟC�W�tsk�y��N�5��v%�M֫V�jW5�τ��
⌱A�o0����6dL�_Mm�5�5�
�JZ9���vJ��W�t�:k��>����*��U�^g�Zl+m�l[SH7�{#�AP ����`��wUN��G=�'H��co��'�{�|r��'��6%�u�,[���Q犙��L0�{�'�tb������SO���81ҝLv��P��3332:m9��=LiK"ٽy<�3Սq䟢竡%��
����N����*������s痒.KPe��,��'32�V�l��d�u|+G{nE�<��V�HUU
�W�d���g��Y��SW��^v_�������,��LOn�`�вąqe�L�H��t_Tk-rh�ls�_(��Y���!�'.��j���|����re�s�`�����Y�
���u���o�"������P��([�g��|���G�O�+*�I�7Z��n�Ͼ#��+Ӑ����u�r��|x����O{�6
�Xj�:�Z�������/,_�3_ /�=�ؓm2ՙM�|�]o.(�`"�y��̀�G��
~�U��%~��7����&b1}�F�aN�@]Vy��^g�ۭ��Rh(u��f\���-���Ǖ�ы���K��n'��<5�����w���|�*<��~�e�hF��L!-�H�e{�|%��
�?������n(M���&��� ,Z_����?Q����lW��LK���f������P!����t�%ϐ�W�<}(����%m�iP�Fg���:��@�Mz��?>����8�N�^��ZP����%s��ڱF]��ɯ17ۚԭ�`~��i�w9�:#���˕7-V'ۖ��I���7/��y)7/W8=�\��"���ެ` ��e�&�t�ڂm$�|�UܵK�5�`�[x⦝���+�/f��,��Εz��~�͎a�>�z,s�{$��y�9!=�:^��o�B���lJ����A���?q ��B;�M��ى�P�U�ڧ�*'`t:0�rj��Nph�R��-\����(P�@1�- �Zu���æ����G�|��`_��no�I��l���7fU���2o��L�����+d��*2KT2����В\g@�@�^�+��!�?�e�������Yu��,����?������g]>{������x_E�����Z�Rzl����#ٞ������>�����G�z�SV�n����EM�/�y���S-~װ��m
��l�^��>0:囑�����ϗQ�����$�d��ߟ��I!G�%�&�W���L��*pK�!�L�H>$e�$B�%���G�&�H� [qG�@�e�K~[���j�Dz�{�M��d;��~�����%ҍ����H� E�/�K�<��5��y�k��Е��)��"�i�g��e?��V�[�ӧ9�y$�/�]��v��Rj�,2m-�q�]���_�/:�s:�U�i�hɄ��������,;Uvͳ������|�)c�]U�ޫ~��e˗MsτH�3�DJV�f����ۉ
aBV
��s���?�=Z�C"O��V�q^$w��^��^MdZ�3���^C��6*���Y� �7�k��a���S���*�@4�R�I�گ�*��(��Ճ
�A��q�אA���U���������,S�����m�W3�ivq>����p����r�1��5�*<|�R��C�C��Cm��Çڇ>ԞRx�P{Q��C��
�fu�C�?*<|�����9��ʦ�˦�r�lٜ������W8�>W������7�p�'���Ӝ/f:=��L�`㼓�^Η2}�m���|��w��a#㵼�
��2�1^/��p��Ő$/�Ԓ�ඐ=�~%����( I�1.iE(��0�Q�@L=��fȆ�>I<�@{?�4��q��\*�
���0�#�_���[�ZɭƑ�\��#V�xa%JC|��5�-�l���|���)6�ob߈]ڞ�0�}���|��=���|s/3��ܢ�n+BQ��_%�'�u#JΣ�Vs��G)� /�(/W�k�qI�>�k�r�f�ϡ�ۗxm����/�Z��nn#�K��c<�>^�����igkڎ��C����b���B.�ܢ�<�A���Lw��gg��ƀ�x�o��|)�U,*�"��/-�9���|��
��k�r�.����4o}�[�,�ϰ|����ҵ�o]˵*��&r]�<�ٖ���u�m��<����5�=^�Ո�Von�̫I��ym"sv��4���(���4J[�D����X��XDj���b�p2
H��istxO2!m�$"����@kl<�ĥ
��#��#��lڕiQ+�G� ؐ�55�w}t0K�v'}i:��T��Qb��{��4=)���R2����b�oYd):*%�u4��I��p2�ģCձ�CL\���&a:���;b��!�3�L�D⽱qi_��4���4��;6��� i,�M�lv䙶o]Bl��ⱡ��$+Ё=��=iiA���#�CH��IC���2@)�*
�AhEF�I��<6:rP�F}Rd�.�j�����E��C��a)I�փ�~i�sw)�V�x��%�ǜ�"סёX8=S:,��sll<96���"�����'22vS�p7��k6̯\�Ԁָ�������nv��>U|F<'�&^\/�/}{w�������ۻ����r�g��q��@����^Tn�K������ʡZ��Tu�V�X��(������܋�U�����������,��>7���E�e�xerk]p
d%'�Kk�0�e�tRW����1�Y���>�HD�n0��N�DR�+��&��EH.Br�fq�P�U��R'�~������P�x��� �(q��N��+t��q��N�rC:�(�|<P�S�]�8������!q���)��Ju
�:�R}La�$�'!? �I.?ɖ�Ô˧�R�S��E&�)���pq�=
�.n��u^
�[a�,�ω[��t��9���0�=���c�o�|��3\���7�ݸ^��&q-��vRڅ0��;9]/vp�rh'�rA�����ށ0���mΚ��������m(S��$����0�m��5�؆�GH!E6�� Q�hƱF\����]
�x��Մ���&Xn��i��i"� X�I
��a��*Q�J�P)V�R�r �H>��P�p�8@��I�3� /��������:�ʇӭt���gZ�,���f�Y��DZ��|SS-�u�ej��T_Tk�E��#�"��C�}��l� �t��e�ۀk��r8��(Gˑ��kep��3����yj'�:�
�z!�"�E/t��^�<���\V�Jxc.፳�JP�j�f���bɤ��q��+�����H�8�y~;�Z��.�j�4+��5F�D�r^%8\8$8��g�q8�q�1Gq6���/����X�������g�/�k. a�@0��K����L������p�8�qa���p����>��}���z������StW��o�g��q�a�߰�o������ʡ�t;1��9nḖ���t����~ʶtѢ���]�9?pM���ה�~9t�LV1�+�װ�R�xdR�zMd+}�h�?X��{M�&�Y� h�4^M�ƭqj�Z�6[��fj���J+h��͑
�G�$?��H��a�MÂ�`_�Z��%�<�S��n���+��s�����=E37ݕR�[h*��tni����S��ͩFgJ���s�>PJxx��-=St��,N嶲�Ih�Nj������S���{I��fKs��-���pВ����Ğz���'�#{o��13��Nx�[�� 4
���.
���\�<"4�of��#m��zD���q1�����t��Ch`ze��z��X�wn�����5����^�3�Pg��+:���J�ѼO\\ǥy���k�-����H�5������{��P{��>�n�RG�ﱤ�쒤���ˢ��������}�iK��ۤsk-�Ob�k�m�ȡ�-=�#m�k�k������3�{d6�s�%����
�WǙ%�ϰ������WG����[=�������������ZL$z�����8a֒����a�&,�M���g�`.1N�,0J�IPD�a�T��f�i�
endstream
endobj
26 0 obj
23101
endobj
27 0 obj
<>
endobj
28 0 obj
<>
stream
x�]�ˎ�@E��
/'���������$y(L>��
�l˘��u;���\U}\�(���a���<�ǰ��~��p�s�S��Cf$��vIW��^�)+b��q[��0���*+��{�e~�O�n<�OY�u�����������i��aX�2[��.�c�������B��]��/��X�/��1�\��P��p��6��p ٪,��j�_ga���W9�����f��&��e]�#�re��q;�k�g܂+r ���~!{�+y�(��1��[�_�;Ƶ�;yޓw�M�l�i�/�`�[8�[�1�8��
�E��_�
���{�ӿ���
gC�q�;�L��F�����cV��Q+��
L�9��p����\����
��,i�0�-��⹄�� ������iO�{�X�{xZ�{����A��q�M�����w�O�J{���m�}���=�`��Gk�����'�3w�wN$mV��g��>�q�t�u�q���'L�*��-(=
endstream
endobj
29 0 obj
<>
endobj
30 0 obj
<>
stream
x��|y`�յ���2���d&�$3��L6f�����` � ��$@X����+��Z�uyb�UQ��
ȫ�Uk��T��Z[���PZ�@�J2�s�LB�bm��u����{����_z�7��v��
�]9�T~@�-�{����Y�O(�XյzC�{���A����[Wm�8b�npխikn-��O�Yo�Ek���� ۂ��5z�ܭ��^�u��Ζ�O�� ����74_�5,�尾�rG��G�O��>kSWgO/�B*��wu�uMޒ�#���G��
Z�xAT(Uj�V�7����p
�m����_ n���xz{d{�}d8�~�ċ�)�Y�O�TǠd)��u�s��W�R~nǖ6�NY���;�
��DH��`��$p9�L2����H�qk�~x��m��W� �?����;NF�d�\F2����u�W���F���ۣ�A�U��Sx���#�~
4�UD�=\�
���?p��Hم#z�>8��~��{z�� C>̃;�)��M"D��L�]p����m���>WG=��@ N��b�����u�O�I ����6r��[���S�08p�T�d����*N�y&Zb&�H���r�Z��_�?.x��B��J�@4�3���[��F�3��� �£0HD� �ȍd����B.�2�:�V�*�g��_��^�Y&���+��Ž�7
�0Cx.:;�:�&�p]A�i�T���[ka|�#�G��C�H�T�yd�&=���D��[���
pO�
�
��G�-��ı��Zg�HM�=����!x
��ռ�ZaG�בF�D~H$�?�|?����#3F���ot��.�P�c���A3�m\
����c�-��/��O`�x�d����� �rA��]\���ܯ������{���p瞑�G[������?
�9V����6�u��w��_ds�އ��9&+�(�W_NjP{Vd5� 7�[��3�s�7�'p
N�,\��[͵skq�p�>��4~:�t��
���*Lf M�6�N���["�
1OܮHT�f��Ȃ�Ƒ{q��ѭ`�`�0y2.C�^��ݍ�|-��p�q
�
gq�Jb!A�y)@���5d;�I�#���6�C�A�?N�Q�,y����I���\���q~.�+����,n6>s��\=��]�m�E���翸����'����p/s��s��y>J^�[�T>�������L~6?���g������o��
� �B�p�������W|F<����YK�{.R�\&��f.@nCn�H5%�"Ʉ?A����U���/�Q\����L0�;@~L֒�d@P�A�#����\>�+2�P���_㎓�Q��eA�B��
��2�,@��Q��"�Q�4j�{0�8�Q~�����$WAw��H4@#���o@�<ג+��B���o�#3�T���sY�������
܍��kH�L�Ž�v�F�E/i>>Pe���
�f�-Y�������}�u�*(�G8� ���G�(Zо��a�o���>Aہ>f$ԡ<8M�d
چ �K*zV)F���+\=j�
mc>��y��4�UR�ڥf�'�����u$7z�p���ed-<
������#��n�~�E~T�7��ă|�D��`g�z��u�S�{�|�f����V�� �LE9��'�����B�^���v���9��fL/�6��xJaA~��ܜ��``RFzZj���=nWr��a�%Z- f�d4�uZ�Z�T��Ȭ�W5ɑ�����3'���͈h�h�Ȉ��H���<�2���.��(Cc�D�K�4+S��ˑ�*�� Y�����9r��,���+^/��+�k*�i�+#U���U6U�xZM���M�� -�Z�"6��� �l�S8P�qU���2��W�%D�����H͢�ʊ$��!+3B�[�+#��1 ��i"��M#����-�@汾[%X�Ե�[���G��:�)��VDl�N�/Tqpsy���I|_��]�վ�]rdߢ��^�74�ؗK�j�©o�\���B���Vb�j�WRL�Z9�����[ۄq�E`�V�A�3t8z��r_]��)K�74W$X�o��C���ؒ�9 �b�0�N?hkc#�P��1v�"�\T���"�J����b��C_K1�ᧁ`�H+��=�.oꓦR<�S%���1���g>��i�c���@A�c
���p$�T/��(H\�V/���<����d,�}PS���� Ͻ^*�[C�+����cuV&�PN�!�5іc�-�%�e�h�X�&?��,L�FTic_���P�fj�$~Ms[����_�hY�\���mu݄Z��x�-E���$.qIFL+�����_���A�
U�a�\��������
;
F?��Xq�[|������i�����q�BW]���O3q�B�?�JE%C%��JF���Ғ�9vVS��Z�S��\�Wj�z���z��Q_��A�SD�F��ֈ!5bd�>5�f0~m��/����F>�3��q���)������9"
Ɨ��:6��M!�ol�:4�H8�_4��kb&�u���4"͝���G$����Mr�Oj_q���0�6Qwؔ�.�kJ�is_��Hm����Ih�Mi
؍����#��*�T�8���Qn��9K�_M�6 �J��QΜ�F͒����(;qs���rU�G1���HM���`I�X[L�k��T��l�K�Řz�tUx���U�媾�����Ε~Y�������*�F]�`��-I��[q_Mk�Tt���
��M���cX&�TWo�M��0�x]-�� ��5�zM�����c�C"|�p=����¯��PD�O:%����*r����,��`�����>�}�'�CS�GO�x��5do��&��@)�5pV5H�5D�eH�2i��C8k�`�ء$�˝�Dg!����pzc����b��8ٛ�$!�@��Åss���rS6�e.�έ�\pf�� ��YpnŹ3�(;ÞsgV'�ꈶ�:��������?�3�aqqqٸhWR4�(?C�R����
����}
�Ւ��7֮X���:��d5$�.�1�#��[��q�noz��a2�-�G��䅶���潼�DkJЩM?�8�:�A���EL�o��no��`�>�s���O��/h�^���-ӄ5]���Q�t;�a�8�����b���}A���Y=��i�GOLHL:����b�i@�S�w��D�Ks
c-'��!ב���-��}Ķ燯�=rj��S;~����k�~�}�������}�ȹ���V����>���P��Ap���
�3L��9&^��%� �姞�j���*��݊q,�!;VqK&�$��*�Frd�$���ja"j,Ha�K�'��D��l�Cs��3w���Tʸ\p�L�4(��Ҳ�]bv�j�l�����^�S��K�]��M�����ȼd��;l�9�w�,-���$Y�f��f`��u�Q7n�WB��j%;��e{!X:r1�#Ęd���vS�:͔�/��Wī�n}�x�x��{~s��̱�q�c�C�k'$T0/�����N�p�4����Ƙ?ή@:^b�I�c�OY��3��'&�٭R[T*���w���$�@c��Z�d�fx}
�/�T;� �� j�?�IIe�eK4b���1P@�B�L��V��*��V�T�TE���DRI%�rU��S�>�竉k�a��6�#f����\*%��W���$��1(6�㩊Z]z2.�]�l{PDwZB��B��s�t@����?AdGJ&�B0�q�瀍A/s>�&��1��ot��b�&U�F*�go���s7���G�iq�==
r
Gu�3�ۚ8+|4V9�TE�[j���5��!�Z�ҩj�.K���L2$9�rR0)ӓ����wTJf%z�C]�~��X�a8'*K%�oI�$����r�a�}N������y���S���,�����B��.�%��!O��T�B��
��JI�H�L �ƄI�}�F�_=�uH�4)�K�������o��[�.eM%P"�p%��%%EE�B_i!T��Ӧ��sk+�έ��T��WV�
>/?��F��n���^���s��@ XYQ�.�q>(
�w�$gy�Y� �
�s�<�
���pb���O�(J+¥�5�2�`
%�Yչ$�9[�`z�-�[h%�H6ٖk�al��U}g�dJ@�#ȁ����@�Pba���]�±�f�
m�4GH)�c܉�nd���H�g��>1�rF�_�E���L�so�̘�م������@�-�ʋ�h�t��$�N���>0+��DJIUj��a �
q���>�?�1�p�v�yi�Y�*i���2%��oPݴ�K_����xY�eȋ�]2k˼4ҬP2��*hV)�Kp��ZJ��`��}9�����(~ԏڦ?!v*)_��[��i�}��:J/K�}��y+ߪrY|w%����-̤�U���5y��ͬ�/Wuk�W.驪��l��؇���}�d*����z�w��KB~(iҪX����� ����L%3��,<�|��1T�%��`�D��
Aư��[��.^�Jv�H���Lw����=��#n��l��R �1{�WJ)PT)�|7���2��m��V��3��v�3v��ٓ��c��d�j�����)�N���:� ?�x�x��FJ wx���a��kL&�4��8 �����A�݃�p5d���ߙߟ��|gl=4m3���97|n~1@a�Sv�)A��<����:���
؈TKP!.օQ)��A�ދ���:�^����F&Ϸi6{���q��}]��6�W�7~7.��Ϻ����ۘ8y�uncյ��H�(�C(������`AQ6�2m�`Q�8R�)�)u���NU��Ax��~�A��J��13��$!a)�MXE>!*��rs�~��[��[���?3�h�$$�Y`IJ���)1��;IN�[- qq33RS������̼I4:�FI�bq�S,~Jj�C�+���)J�N5�̌��KJҤ$Jg�SR,a�o�gj$��� ?�wdb���@�=���\�n��.a���!G�㙲�+P�g���m��+���xR3�� bzT���d꽄L�d��PE�9Q�3&�؋?���R�ސl��/�qwL���]������ё*?���⎚�R��NE�b������с6�'��85�\f۹��X�\�
������S�A�+Uv�S|=���#�pd��i�s�ch�ӛ,�Ę���'b��l�N���ō�t�j�[b���,<���p�!�p8 ǹ������$�|�����m6A7)�K
��^�%�W��:E �79t�N���u��S�!G!Ɓ����0������\�d��|��&�IBHo��6��ڈ�R����n!�����X��V@˃�BZ�,8�(���+���ĈxBT�G���(\��`'��3x��s:����[�o)��78��v����X�a�Sz��乓�T��]������%" ��A
c>�SHm(H�1ã����ꈄsU�\���������?�eH��@���]@?���D��%����c'گ#�LL�G�6��$!
3�Nt�4s�l�a�%���B!%��B)%��F�i;�6�9��<�c��š�c��R��{����5o�o���5����FN=8�����H���'oRE�b~�Ց��4�ޡ�Bޒ��q�C�
�
dJƒ<=ɔ��j�H�?�����|
T[���/�j��,���=!y���A�*
���HP�/���KB3�%;gwN�x6�5�.��))~uaa8K�Ն��,��O�׀������0b���H�qT���@g�z�M�?�-�8i� ��a�tê�N�Y�4\*�ĸj�!��(E�����Ve{�g�����90�W~T@A�n%�7�U��oI��F��f�+��ѻF���-�
/ϰ�
f���:��Y���[w*� ��_)�J�����p�W� Y͙)���N�C��ӬW��%v�O���TRZ��B��KN�ц�H�Ixձ�R�@���Y�+ίRW9����R�r�#?qRIW��5��1ALy����h%����w )���-�G��nAB�����BΰQM�4�v:��=GӨ��+�MT��8K٥h
�[g�|"���7��c�"�ؽh#�i2�9���A/��b'ܑ&X����~\�$z�`o�1nٸ�4���K�o|]����
��Vt��mW��}뎍�q�u�ތQ_u��$��.L��yW��0��E�L9x-s/ވ=x��~�x�]X3+��%���#3���6��hhMKkW#�5P�t�Z�J:Y#�d�,��?K� ��i�9`:2Ӿo���jY+�yQP�
_j/M[`�v-H[��5��������;Ru�'|,HK����2}�GR�m�7I)�!Ӏ�s�[�������n�휔N#to8�1�x"���{E?|�${I�{M?l
���,� �'��EM�ӫ�=�j���'�N}o�L�B�� DO?��yu>_�h�����(����ou�I.�
�5�!ޯ���Ւ^���n<�0�o.�0����ۃǛ�}i�c/K����Tr�G����4\�4��͇;�ݳ��{�}�K��A��6�]�A�������A��DO����P�d��������{S֍ſ(���'W�مm�r��m{���&{r�r���z"��<��#�7 �$x��l|6zy��X0}I�� sD�p��n3�ρ���NR�K2��{�6v���ɽ�}�-����5����-�v~����E�E;�>*�ɧ!u���.�L}+��٥x�$-Μ���Lٙ3�,Q�f�;vkY1v̎��;�ASj�HuD7�Yɓ��gѷA�+��G��3��Ð=wp�%�g�O �� ��(%s�Ʃ$W�k�u�����[��A�x�1����Bi�Fߴب�L��TG&�߂��l�Z��v2����2���7�Ȇ�o|�X뷟\����K�^Y}��F>��{�.��?�hVvS:���9�������=����骞�l�{�����~E!|��2�h,�X�V�_�=P�w���١�U`|ϡ7 �?�P<2��q?��ҿɎ�q������x3��!8��ga�T���:���,�.����Aď��^T���AsL{�n��&���\ ���~8�s`�W�����i���`-�y�/��x��=�n�����nb��
���8���HSVA.��Ր�]���]\�w
E]&�g�a��8�C��8`o��"�;���CqX -��8�����`PL��z�@Q�#�ǹ���i�}��8L�2XA���<#OT
+)^��_�`�/�����j�U_F����a�Wk�0�_����z{F������cq��>����HF�kN�a��<�5t���q���!�����_��d���`�(�&�ap2x�aV@6�c�D�7���8��J'0��a����w�+q�k��k��F.#�Qbp"��a��`���c\�q�f'1���0���.F�?q�ҿ�`Ï�a�K����q��8��H�0��8L�]�H{㰀&�d�b��)=����Kz=S�I
��I�o�3���4#�\L��!r�/�e�C;n�rtB�^؊~�bʱ֍0͛��(��e&��G�ň[��{���ڰlC�͘�"%a��V��Xn��Hߌ�ۡ�K�N�DyB��l�n�-�&
ٯ�s��1)M7��`Z��&}�Q/�Ę�0��h�X������Swɹ���1�2��"~�ݰqt���4�l�X�%Xk�忌��e�m�;��F���k�+la+�`�jg����J�`����\�����g34��e�ۭXnbz[u�+���l�����m`{��J�wt�����������Z���[q�6b�C[�\-����:�m�Uob�ie������.l�� ���\��Z�c���ډ���S����~���:�rl��ZWǗ���\�0z+i5⺙�c�n��W���vM\״q<�;�����7�t��^[�nНw2����8�<��mq]�Xc)W{�n�IW����mlJ�)�VF��y���rݚ6yAgGg�֮6�����������#[��~���}���yq[O[������M��m��¶-s{���v�:�E�5M���݃#Ʌٹ�rƂ���Ξ�U���Lz�8���W� ���6+>O��^�=r�����ڶ��{�ܹ�ې�;�^l[�����*��6��a�֜�n�[���M�8tO���ӹ���U�n��]���йI�мU��ӆC�RVuv���=rW[���^:�ʭl��%�gbk7�tuw�nj�ڲ��e�X�w���Ԋ]{;������8�{�#AR�u�f��������
+i�cu�R�yk{�j���w�B�7nzƮ�X��
2�q�
���8kk疎����'�E7ǖ��cl�ޮM�rk����6J��m}�E;B��)~�lF����1�j�m�3_�g"պq#|}�M�7�G��������K�O��O$�H�?��"��D"��0�?w2�o�&~z����؈��o��btd�z/I?�����D��u��D�9(տxN��[���g=bT����K�e��ʅ�0S(�.�cM�7:�'R��{'�c�\w)� 45�I��Vw|;'Ru���N3�R}&RU�ۘ%7�[��o��ߞ�߱��s��l���[�@�e�x0bބ��1Lx�UH%a^�iO���WR�B����ƫ��������Z �!��[=C�!�o(e(g(<�|�j(q�=��
���� )
�TC���^�Z4�x�n�]i�Y�/��.�i�b�v.o)�B(��L�a:��9�\�lY��j����� SS
�і���1����B:MWƇ�0/�sfN�ŗajĴ�ӘDh�v�NL��`�c�N` ��;0q`Ĝ����N`R���xkS+r�������渺l�
��*��P�f�*4���r��ez�Ls2��n�;C�����Z�?o��n��k[�[�� �<�\��~�R�ܥ������¥��������&�@�A�`�<�Of���RP�A�����=G�r��=J�i9�!E��O�O�� �����4x8��Ce��P��QzSz*=s���JO�ғ�{��^��W?��Q�?��_�쟣쟮�/P���ewE�V��G��"y���#'k�帯�\me�a�:,�sU0�r1�WU44T�(�$FW�ӄ�%��[� ��7�+����l<�Et.��ҥ�"F�bt�8���
�x++�^Fc�a45V`4|��;�Fy��ƫ<�%�7�I�J�q�k�u����T�j�T0��|y�L��f0-҇gܕt^�O�6���gE��YPVfg��Q�"
D)1Q�i^���#�����xS�̬�� m�6��o�o��M:B�7I�6�����"������ۃ�<����z���!����{�����s�Ho#�?�D#�
endstream
endobj
31 0 obj
10860
endobj
32 0 obj
<>
endobj
33 0 obj
<>
stream
x�]�Ko�0�{~E�ݡ�����:(�=4��a�F�Bz��/��M��9�!q����\�jgт����2߬�è4KR.�p�(�����v]L���ܺ�-���8���Y�b:��#�<���u�@���@-� >;�K_��]ᝒk�\����}��
}$_�դ�9C���}��3���G�T\�� }%����,�{<��gl\ܬ�#�f�SR~������
�
endstream
endobj
34 0 obj
<>
endobj
35 0 obj
<>
stream
x�Լy�T��?ZUgߺ��}����鞥�``t���Ⱦ� ��� �"(�"*7�(.Q4*0�F�D�B qIԨ$�GyB�0����nL~���s����Sg�����>K�%����t�qȞ6��[gM\�z!욶tIL�k���/���p���� Br-B�w��\>��9�r�"4ל=c����DhG}fÎ{37H�}%l�Ξ�d�gQ�ۛ���+L�z�_�t ��Y8�i��eob}����p�y���4x���G؇�� O� �B��_��+����~E��5�N���ڊ��s�s�e�
>WmC{Q;�-�A�!�ݍ�!M�=����`��8�mG��Q ѣ� �{ ��C>�~�V���wછ��J��h4Z�n�g�FSЧ���/�]����I�۳we�@�@{��f���Bh|f����3�W܃6�O�]�.d�SVÙ?G��\3����?B
����F��x?I��g�/q���]϶e�YԌf��>\����0%;"{�������%�!օc�'��PU�aОv�;���t��4Ҏ�^�@�pd�z� �k�@Ѕނ-\�}yP/4j�\��������!����N���7�/8���(<�T��an�ች�;́���� N��D'����_�'Ţ̑�(�B���_cZË�
�}�H.'��rw�O���B�/C��m��_��1�R<����x3>����d<�G��fs��K���/�o�
��_e&ed~��W�wv-��jzZ�B��S�W,`
;��q<_���m�1�?���)��_�������$A�I��I |d���M"��{�|K����.��q
\�j����]�_���B?���
�^���t���O=�U��Ie�g���ȴg���@��B1j��O��\����q��;X���J|�z�r<��eГ7��/Xݟ�/B/�u6H���RG. ��{�AZ�&ri'�9��8'��*��\37�[�-���ڸ�����r'�S���*_̗�)>��/�����o ���8_\+v��#��ΓFKc�f�i������*څ�t������B��>H~G~�|9� ��d+^OV�vR*,�x$:Ƨ��_#��d7���\�+w7��?��U�ɿm��y��������v`D�ᙿ�z�i�-�!�)��G�G�����<ō.x�?O����C�y��D��`�ԓ�F�����qo��E \ԗ�݈�?�N���}x:?ݎj�
�%zFE�p�X)z�d���q;"��кz\�9��n������t5:ī��Y��!�<7�?&�ųa�DkQkv
Z.L���g!ODI�H�\o>�U U��L�
�{ȁ��'�s1�����~� ����t;1vL����-���}N[���;�LΜ��3�ܙ��3�k@
=�b������uʤ6nj}����j�_{4pfn�8i]��an�����ܰa]�m˘Iݏ�鲩 �ג䐖
C����������M������m mU�}3�鞖��6%qAb���-@�І64vy|G(d��A���
�'%�m��D��A���a��A;<�H��������g���3Nc%v:-
{�g1�Qb0D[lZj2)m�G3��
���i�i�pU�t�Ȝ6e`��?�O�o�f"��8 ����{����I�)��f58^(���m���E��@S��yl��G���H,4c���C��o�6�����)�o����Ѷz̤�v]ށ��tSi�G��x'�#�GN_ޒNng��&�N����=xv�6���9<#w|����1�'�oh�����gm��;},_js�ąI�D�;
L9���tc���'�'2���!���l�
i3[.�-��x�yQG�����\��f[������>�z�*�r���6�gV�=pX~��O���� 02������G�M�6�l =�/�+�y։�|� >�;{T
A�aÐDlȆ�
S;���H��Ć���ʆ��[
�ӑ�wk�m��&�ٸ?
�.؞���l���q�'�5�~Z?~������hG���'u�M=�fW��Xsq+n%a�A靊q�O�:�b�~j�m��
�!�({Ą��A����x�ä���wa��:�_ٚi� Hv:aّ�{����_�
�N��2������́�y"�>�
�q�wm��l0PccCWC��P�7nw��ߐ �s���Z�u�$jy�Խȗݿ���:�Gl}@�����ٮ��`�_�t�� 9#���T=��5}j�
ޯ`��id�Ϧ�P����p��#��m�F(WQ�N�}b7m�2�l`�k�Զ����B�_�/��}ē�=��6���ȍ���Х#�c;�M(�~Z ��d�h��Dzc>�(DX�֫#�CG��R���4�� ���n��D�
���V�U�]��z\n;D��t�z�3�Q��kP��5V�է����Vm*Q"�^k]����>?���y�ok�u����'꺜<��q���ẑ�@(8�x�}�҇�`��I٢�)��O�c���be��Zy$�눒U�b#���SD�z�DA�UQJ
���·���#���?����ð��@�o��~�Y��*}*��Ǿi����S�J��)���A�QNl�Ė����{��͋Z��/�������ۡC'�|�䇔/�_q���PO�o_ǗxJ�+)�J'��(Y�ܮ�T����U�p���=�W���d!fo���S�)�m�>Ř+�U�s���\�=�^�,K���V�)��6i�S�˗$���.����~W�}U��|B}Z���ߤ|��㬁%�B�P(-�9��%�B�P(-�:��خh�d�,��|(����9E��]��][l�
^�<������A�8xG�_���za�u=��6&&X�a�`��W��`pX��3���"R�J<�#_G��ᾰݔ���9Zq�J��;Pۛ^^M�O0�[�A�Q����*h�V}���r���.��?\�+�S�P���ކ�P�f7��2�/��m齿7i콺7�mb�K{&2�X��z�L`ZZ����R�I[�d�s��iNʶ1�L��>Щ��8K>E�`>A�^�}� &[G�s'�MX-I�8c����3��sj�'5v���K���]l�?`ln��e=� �S��L��69�Ĉ��R.���Ql��0*I�\��qy���i>���"*1�Tt��>�2�f
��3���fw_���w��ڲT�}��a��/��h�z�>�F��#���T��-XV���k�G�߯��q+_�l��笘��U�oz���s^[y�|ndޢ��M����9tyyq���f�N�7)r��5篘2��K��De��#0N�Q_�îR�2h�*+���z���o���f��r�1����cm��CO�r�T��Q���'�ϔ��P~ x��ޏ��A>��()].�t����h-�����z��ja�D�)=S��^������m�;m��u`ެ.����{�W,� �jG���#��Cxı��s�m9��
�m/�8�!�Hy��p~���x" ѓBLw.S{G8�b�9����q�߲��UmPb����Y��LT���(���})/�Qf�����z����z:�T4�:���f�^t�mD�=��ד-���O�v>��?(�.}Y<$�b�Q$���T�i}������Х8Ad�_d#\���$on�<ޙ���3ã�+���0@�����p~knt�j��q+�Pk��%�-0.�RF����#��}^���O�8QrS^�����{�n{q����}8�^�jyQ[�÷�f���K^���8�`J��sf?�*�q_���I���2�,��FocpxpStKT�u׆��܃���������-���w��\_�_���
R�����NF�����Q�3���/§��'�$���r�5(i����t���j'�5 M�fr�E����n"%�ӗ�y8��@%�� m��L.�J_�I�JY�/��Q'�R�K!z�TBo$��UR�^!��Kⵠ��#���9���;��y�*�N�Y�.F`�܊Z�Ei��Z*��u5��D%0WUy߄�2�/x��ߴ>�v��'�-����"���Җ̍O���@_}���_�x�F�G���ڋB��
Us�j������6�ƥ�ۧc�O�j�`D5�d�O�i�aR?ä~�;��!�gC�
�F���O�Q�N���U�vP֏���d�9/��c!�0�%�ʆ�@�Ӑ�S��b8�b�8��U����UUUFςSt�!�3����t66���SD!�tN���,ʂ̉&���![aDAie��\���0U�� J�R�-s�+��Q�֮YW�s�����/�?�n1��k�m���w�zRp
��@�N3!
?:�@�6a~T���?��)����E�?�a�_����?o�����'n�{;�ٿ�.�곘���hxޕ����+7�V�X�j�E��$q�8Y��?�"��Y��%�BA)8��L��]��s�ke�;]e�pֱvX��#�v�7���^�兤�C��^�]�~�}&JO�8!���\/�S�QF�$N�����ra����}����/�߲ץ���D%E�aC��$z$I�x>)�APU0}x@2����T����"�M��t+ct3s�o��
-�H�M�HEl/fE�9t�lIf!�%�cԍ�ć�<#;��av��#���f�.��HAF
��~�pN�_i�u 퀂d�
rǖ�E6���
.Vn�0�Z�*[���8e��*UE��\T��dGQ=���c���zV��f�ڌ[I�{��ݿ#^Dܿ�GW��0��܊m�l�]�]�n�>��1�e����4�\ubG�^���p�t�ܔ��Pje�/��8�%���3_g��?�<�J�w�EܖY�5�_����ei��R،��O{�
VM"U����PX�Q�*��T�NU�w�%������2�Q��3���@��G�N�08J�c'��P�h�ԘoP�7�N��ȭ���Z5ބ�r�������ꦛv���N�G}��|f�J���O[AZ�ᮌ�)WW(<�����r�%rw�v����7a�u���L������y�č�n_��K���݀��x���������!� :�$Gs�a/��O��Jv�@蘥P#��崤��a��s
�DV4��j"eZ��g
�nz�f���#���y�꩜C�⍃l���y��~j����|؋�y�[,ŘaĖ[�l)�%���� Z"̀��x ���0sU�����^�#���R�c������!�А
K�
�wcv��D䂾�h�=(?�
�E���x5��lh�5�9���y��*D����e~)���BW���aN��OU�Iܥ�Rc�c�!kD���w�"ùA�-�0.p����ܽҽ�V�)It���S �m�0�� CQ��:�R�i��h�ätjq�v�>���!�������U��A#X�#�k���(�\hb��L�Z��'t��;�M�t�<�|��!Ҷ34;�:�q�3%[����N�i<���:&~��iㆷE�����I���ɾ߯_�&<�M�c����;T��)P#���x��*^o���ݷ�ѻ/+��{{��V�w���j�8�����q+a�2��ǥ�Ҟ�`�/d&n�L������~�;�����u���4:0?���Wx%���=a/i)×�n��JKQ��'Ie^@;�`)�Q��
Ʃ�di��b$V�B8B}t ���@�L�*�Ì{�.�eE���U��`jڥ�qF���9�aԀz�Z���U~�'V��E�p$ F`h�̤7U���|*�Eq�s��p���`�DH�qD�DZǂET��Q)ƻ8�+|*��f�c꒖�'JJI]����7��B�G<.��,�b2����-�<Ҿ�����Jm�_�{�ͯ\��;�?vi|wY�x/��O�����:��p��17�Z�ȁ�������^0*Ar h��c�sQ�,�C����b,��K��s�����9Q���`�l7��t��;ь(�h�Փ"����W��}?��9xD<3��,��W��*R=NN�"A�K�D��r�4[�9�G��N�>��+���w&���Nꨞ�/�LtnS9۰��+�Yk҅�+.�p�iez��G�c�96[Z���}�����n��q�q��.�˭k=�zo66X]ݷx�W�j/�/X�<ߨ_z�it���d#QW^���Z$�;9oK-x��9��of�!l�u:u�r�T�=nwҥz`é;-=��MS��Q���(bFHu���t��]N���A��Z��v��]/�,���v�48��C��`��G��h=���Y
6!ܣ=[x:���xsk(�$M�<~4h�.0;Y DOg�Sq#w�Z��a64���9@�@����+�e�� _�~/�d?����l<��[o�x�sX��:њ)�v��c��5n*`�58��*π���VJ�2�_�8]R���=s���=WL���z�,/
�s��]��^�b)�w��.hG1�>X�C�vO�ҀT�p9Z�V�m��Ƿ�����D3���u5�}��n��q3��f�E!*�wHX�ǃ���Ї@i��4^�(98��x4��/�
�E��
���0*6�h.� R��D��QP���}|�s��5Z��\��s]3�n��A���aG=
�������Or�(7ڂ��|����Pqm�lp�3�b/I{�< ��d�6�O�#wa��w��W��v:R\Fe�f�۠����^�^��vU��Ϸݓo�7�����w���x<|�Cqt���3��G:�`F볳�vI�%��Ùp����H�,�T\ad��0��5kptעj����=�ν^j��x�w�ƥO ��=vСC�[�����suH�O��90z0��q��E�d�,4+���qn2���4�pD�о\���\���#�6������g�pÛ�h��6�[����Uֶ�Sb&S���"����j�R�.��-xVc�3ϺaV@�%a0З�F��Ft p<}�y�F�Q��;��*���&],xʌkܺ��2 r�#ř��S̙�]��껽_g�Ǟ?����Wꎛ�m������M�e��x���v\�9����'���m�f�{���d>;������'��V������}�;�y:4�v���7��>&{�+"���3Tá;J��`��|���N�h���J��=������s�X��h�S��-K=�0���J�u������@[`�p���c��v��+�����$5����.����#��Y�X]���I�K�h`Vp!_�'Z�*��ʉf�a�T]��
nZ��������`��Z����<:�T�+�]��)>u߶�G�^ٵ���j��w���b>�CL�u
Z�l�\A����DL�G���_��DŽ��1�c %�)��FD/X�ԍ���N�M�-I���C��&[<�Q�A�y�i�Zگ5���o-B��b֩��\V ��y��m=���.�]�����vaj Z�vaF�0s��Y�� ����B�,L��C�&�ć�>_B��Q���5E���c�0�˳A7o���Ks�����d^�3>ttw__.�Ƴ�mO�xr��k����h]��0��\���;fv�wʣ[a�2��D���/�J@�â;KtK,y���s��W|��?�31弅w�O�~��|ꞑ�_1i߶�]e��W^���'��#;�-���]�X,��|��v,�D�R�o�Z���˭{�ʭK�lm'�~0a��G�O~,� \������pQ �s9�;��������1�����c�:݇gN�y����,�硠���y(,j�Υ�P J�ҹ��nl4=��]DH�h��<.scB<�eK���m�
�R�hi(Y1=w`�#�@�߮�%�f۪�a�.âSE����U�փ�[j~��ܐX���4�e� ��C��Jcf���\�W��"�R�v��b�3�G
I9G
j����k�HQ�3o�).��E]q�a%�xċ��9d��ܜG��a��Q��R��vԢ:��<�1�*��y�6�9Ժ�u�s�k�4]��Z.^+-������]�O*�U�ʍ2G���U���������s��O�d������9~˿/~�|����u\�Q�h"��Ζ���3[����p�.dɒ���I�+��C��'A_�o��Lb�$�d�{ܢ�Y)5m��ǪS�+��K�T�C��#G�3]��7����G�ͣ���l��=� Q�EUe�i�iY`=
�) W�#;̞�:�W-I�I`���#��4�pȠ^Ҫ�ˑ@���`,�x�����2t]�%�,��N�����[������F�x��J%`�L��Q^`���E�4S�-lr���p��ɐGp����@Ws+�B�.(q:&Qp��rB������\7�����p%6$0n蟖�x[�I�FL���G�A���v��s��œ�4
o��|���K=1����y_���R,�ו���7���{�F;�C�I��#�rO:}�����uV��N5��P����#��nW=��?
�����tFz0������b���O��W����=���<����swo˴��t��T׃G�7�U]��u��<�!Y���!�w���
h�(���M�b|||�iZ|ZEK��˾�������Do��^qK,j�PO]���ԕPYi�"�:�$��>oM�FM�������j?_������������,������������O��E,��ĉ�����e�!�ά�/v6:G��ϐ���$8YN��B˴q�Ugg&�Ԅ��O������G��&�Qs���F1���3u�r�R�]�3�i�.Y�>��K�>:v��o{��'g|��W�l~r劭�]�l�Иd����݊>����>5��C�~�U�~��o��ګ4Z�.3���](���o����p�o���Hq�BO���.��halSL�����Q�I�T���+��������c�x>|z'z�s4z$���|�L{�����"s��������Y0�X��qh�,=�bS��u�����ym��qA)�����=�>�lN���.��RCE�~�7�-�
�|1nģ����f�3l���,��-�) g�tz*�$a�'�CC���}��a��Uf��gH�����)(�P���|^�D-��nd]�D��f�?<��O��|�9֓K���%��g�/m3fc���3'o���I�z�7�Hi���b�kv�� tg�P'���bR\\��\YX��X��n�5�.�]j���I�f�e����l�U��B��?�?����[���ϊ�g��1��Y��)4:m�b�ha��a�?�M��:x��0%��bJkЗ�֢���bFD��i�|�#�Vר.��b�$3�ߌ�z�7��[��+���K���e��}x����܆1�ǏC���7�ڇo�x=D�/^W�7y�_��*�S���&B)� �:��A��VM
y�R�=uF%V�J�ކU��\�Z�.谝����J�d%�E�`2P��`[�ח�S�b�p��\I���N�
U'≤I����3�y��]��!��e�5�:����n��������;�g�c�Kh��]}�F���~�>SO��j4G
�Z�Rj_u�UE�]�Z���<,V�=�鈊k�ɬ��G���c���
�KA�h���4�
���Q5E��쾪$�IE�(����UP0+�L!��*���j�%�m��j�(8���Ip�m%Fl\�}�j�uR���
tm���ӘӪ?;4����/z�r�+����g����dq ����U�n��`�R���" ��2cpfɺ�{�`^H
�a� �e���3(p_6�h���km{fvI��}�kοo������6;���O9�����t�L�~��Mx�$^�l7�_�-��dYW�
�..\<�tH�8�I�RtI�-nG��̹B�PH
e�B���s'�
�B!U(�Q/�Z*7R���+K�q�&%WO�MLLH^��5�9fzf�k��:W�W�.N��6h����7�ޘ�˸�y�7�g��+�
)�
�B�"��{�J� ڍ�÷�I8�3zD˒8)�:��=�h�DZf�ƚr6^s>�䯯��}�v�d��Єx�(�%�爈��%�O��!�r�!�����̲Lãq^U���v������_��P��.g�Y�j��"�ڄS.�HN�
���Nz�k<
�{�ó�#�RW#�4�y���)��٤��9k�s��Plb�ghWw�(ai��):]&�Ҵ2���ShE�rij���߮\�̸�Sd�3g�������9�{����~��I��]{��g���Ѽ�K.X�ah�5�540 ]bMr]0��w�<3Ԙ8L{k�Z}�0H�/��/�N���K�%�u^��.�N"���O����xf�˲�����S��].����#��~ Fˢk{�WVbԢ��e@��7��z.]Q�^]���iyL�r)��
N���* \�t:���%�˲�Yd���1(�tXz�o#���a���|���9Gt�]] j���_�����Y������
��<�� �����ͥN$ag%3��p�'Z8`�N��彨� �a����N���g�{���P?���èD���f�z!�V���d���j��r�t�2����v�����c3��|���'�Ft�h�.�C�/�<�Na�zV�4����I�G�\xs���6�7�T>괧K
m:s��4����>}��>8����}��[oM�N���T�?�JL��<*�:�&�D�h�����ӌ�,~��tagI��`ڣ�������ʛ8�����[N�i��C�[�!������5��u �$5i�������=�C�����m�C�=���G�窫�8�t䲜4�HQ����""RU"��!� r`�(r��(X��8�M�a`��05�bh�n���8U�5��B�$R<)1^3���A�Ꜫ(KЙ���Q.�f\���Ω�r��N�c����"'v���#�]OJFA_�V�����9�����<��r"�p5E�y�m����u2���V��7�>�@Q�F�[+��K������x�I����%�zŎ��cɰW�5~ʷ}in+W������<~N�*��;��?�5)Ǚ�yA�Ɍ��;|QS���7�%7�YO��2K\B���-Qay<���:p���(H����)�0;��^�`�}U��26K�Ӛcns����7����Br������8�p�ÜN1�9���L7R-��s���U2`��pڰ��4���_�[[W\|=��S��7�~B%�c�t���,�t"��D5$���"�U+��.��1��!��Phȏ�������r:���t.�&��Ӝ���1����\��{�M4/��ٌ�mç&O
�A�l�c�
���U��Y�层D�p��u��TYdC�'j{����#�pF>1EX�����fD,�*?�1�����U�^� 6�頶7��m�Q�����
�B=�� 1ɢ(Ձ��!'��g�}�^�_wފ�燾y9m���q�I�:��`V}ġF�ވ���`kN��FFR��mJ�����>x:
��y MM�
W�uǖ�Cˋ6��~������QXV�Ge�Sz
=5��Glӭz]n������8�Fy�vӊ؎-�p8m/�Wj����ش�q����Y���U�&o��l�yP�f�@e���l��^�uȉ�A�ñ������58?���M�������eD��6�����
(�R��y������Iy�ӫ's;3˥��D���67��˟�h=5�%��+ohn�%˟��|еg�Mw���ێ���67�z�v�j���y6�tJ���_�s��ۗ7ad�Ј���5I��?�?���sw�� ��p[�x��=�s����HFo�U��p
zS�;��=���Eŵj����=�̥H���k�]���V��MNB�U3<���$�R
�2��y�d��od��-Mz����i���ɸ�<�p���"�.7'��t<�g˲����=�9���!'�Q3�X��V��]��)��X�1��p
˸�,L������g��֞�×���}�_d%<��kX�] M�M�k���/d������USn�T���5����.�R�����ͅ�kjs�=s���:���,��ցPN�TfmL�$l8,t �6�W��s��cHp�`�&� �QO�&��o}�]��Nع�
�1���o��
�v�j`��&�����\���_~��1���RX*����;����E*�`{���C��ih!ZR��T� = ������k7^7��E�(��"����˭�H�x�1�s�wbp�0��:�8�ݑ�� ��z��F2=f�'��3��Gy��D���:��r^�R��S1ˌ?�`tڔӉ��Lr��1���Q�l��Y�yk�E5��ʹ�W?�����mx�+�U^�y�gO6e�k�+!��?�k|�>��y�ǖ��|���7�H��e�Nr
�X���� �!���]����DU�� ��w`{ZG�ܠ:s=���D�s|����T�ey�]����w�G:����>j�rS�=>�u�'����|�[�zB��Z����N��N�()Dl�,�*i��sY�}T�[i���YT���^,���<����p�C �i�F�+��4���Z9����$���I2[�H'+��<��d�]����k��1c��bUS��0}�I�jjS�@@��;�
�V�
Q5ݜ�/��1P���3�(dʦL��L���1j!p*Jt��Nl/�gުm�������w��;g��=����ޜ7s�
�2_���,�1�y]�
+�k���:'����3��:�t�����Q�4n7K�=�nY��P7��Q�?HO�F��h�G�̢�R�D'��+6-BbŴ���˃����%���r��5�J��Ų}�ۊ�"��-]n2!���w��s&��f�����Yd�y�i�av����e��u���4Lo��;����u��z��y�������M�f�,2���+F�B2����jʢ�f$�DBr$��E8#jRfea��]��u�]]���)�Y�b���l���H.'�*��H)*�w���qO�I5�g<��1�:�9l�B����iC4���)鍧���x��?�9,���N�%���|�u�u7<�����;'.|�ǦD�{���i��?���y?{h����<7��X?�p�dPeLc�l/8,|G�&�7a��T�@�)�㜎�)���0����?3��3���]t�mն{{��z��Q��{5��q,�c�;��J���9��HJ�~�
�U���JW�~_ʗ�-�JߑΦ���(�;dͤ+�U��9�����_�D�@ed:�Q��٥켖>dGt��0��0QF�`����([��雬��)Wґ"�hʗR�b*����+F}�����8�H�(%(Ֆ�.�}R����0㸈��W�QX��Y���g͚5���]`G�F����f���jI����C?}�9�+<���3��l��[x�ɼ��S����qՓOg�0��諷��y��knn�]�z��{n[8y��Ϋ�{~�j���_dz_�
�����3����{O=�ӏ?���2KW�s�͛^��j~�E��ؼ��)֥�7t!�'��WNj(���a�������,��D�,���gMc>���]��|֝r�?JΉ�
��^������G���gF���.ƂfL�$��
ԓ�.�;a�]����zm��
��HZ�v_�(80<�=�;%86����9b�Hʨ7A%t<&�ʣ��Sgn�>�3�Jh2��V�x�G��l���*P��J.�N��e[�ڔ~�;
����GۙwȲ7�4��y ��\�'qY�ER���LX��o��q+G��}^����^���k��g?$o�bɲO�X�(g^{�ū��PL���?}��2�e���2������wxh�m�ݱt��3��^����'�ILL�L,VnR�9�����b�F�FM,�)\��2�+R�+ZYYQ�"EԗUpɁ�XxQ�v
Ӌ��"�^ 2]&2������ɔ�W������ѳ�PUQ��C�%��y�,�ۛ;}��9��I�0��
�
;cy8H�{�e*�c})�h�^����♳n��տޘ�>wM�������Gx�e������gc�9a_���=YS���Y�[zqc-���T��"���
��E��6��
U���d!GF������4
�_x[.�P�z�j��7q���w��E�R$~�O!�f��L\�wh��V��ϋ2l��}*H�Rm��zuB��ÔQ�<���'+��+�42M��\����)���[���$�S�BN+��/�?b��)���ZR�W�[<J�+*�U5��Z�ne2UHW�(g��9i�
��.˒ �@.E���6��$�[9lG�c��C`�D,��K�z=����,�^(�4��i��f:��y�EG�l��E_��`~\�9#~>��g����L���U�S2���zO�} [�졽H�2�J��&�H��Ov8i'�W_� �+�/|.���_�^�����!ߙ�nM��X�S���'Oʌ�w�z���owq�x�5]�]����]������q��Bz3�?���k���w~�;��͜9�:s�;Ա�X�
|�s���m�����
-���G���#�+9��8��Ðs9H:��'IU����-0�{P� (�^��I�U��+; AtB#R��$r�坄�#�,O���Ib<���ugfq��8�,�.��p�Hz=-���?d��j@�3��m�3ώ���`���.� �M��>2i�}e��#jm��df���0���C2N�[ �S�a��b#��㸍����NR��fT�iFuC
�l������>]g.^L��I�P�����r��A 3-�/]�g�:~������B����>�o/�W����f��on�����g�c��{�P��I
�'-���o%s�>)�f7� 7�=�n3b���������텆��c3�:0�u�mŀ�|�U.=�k��t�S�?_�О��0�{���B�L�k��u��C\/ly-�
�Ԙ������!s�\V�3�
�k^��6W0��B��S�̊mRl+���d�7+6�\�ظȽHZ�_�����ȸŴUw�i�a�)e�����l�ʒ`�b��,�,��E�y6��Jg�T��f�sz��εݎ�l���0����g�C��֫3��
\�㚽����E\Q�㻮E�/:c\Xw�7�GP�����N�cOe?��c����?�����CʪM@'L5&s��ZKR�C�5��y�K���
d�k�9@"�Ĕp�����f�.�J�_a![csIɶ'����O]���_�w�o�;����M�\5���-w��_\�d0�C\��s�������-{�WVUP�L��z?P&�x� ��,f� v����z-S2=zL��^˺Fli7O�7��7���#]�Pn�..��\�q������<Q�u�O�q�\[�-�Ʃ]��F0��m:ӷ��w�A�t��bo�23�V��;�i�E�\��緦��_�[Ѵxw�ϩFs��.}��H��+�]���}|9�z��<�*@?�AO�E~��cY�r����Fґ�j$���F�E���<�bA��쁞�ÁBo��^ԉ�R���A�=}����E�Ւ[6����N�聦�-/�eᄄg�����N��Nxx�)���Ĝ#O뒑h�< ~{lE��v(��q����1��i��<�z�������]W�y����>�o�=�%����w?O��'Ǜ������@K� �sr\v����|�ޮw�{���O9���"R~��4{�=�צj�^i^aY��a_�X�w����ۉ���8�G���I�NT�"�k���O3'~�9+���Yq_����|�o�ъ��t�ӝYc�;3Um�y#cx~d��w�I�|pD%�.|#��,���G��ǎ�G����|�����Q� �����o����ѧq��_���*���[��˧"���Y<�x���A[;E7K=[�Pw%w=w��lֽʽ
ՙ�Z�&����oS=�"�t<�ſ�������Vq5�Y4�Uc�\z�������|f��(���%N����A�t^BO�i���yI>T+�|F�N�T��D�����$)R0���]���ꄊW-(O_���&�Ih8M�\��K��(�s������Yz�6�4�v��^>�;}�3��]0�ɬ�qs±�9�b�j��W�g�xx�eY��>
���w��\��Hg6������sg��V���r�;kxJ�]����Q��p>�SC��h1��v��XO|��J$�����z���5go'?Gg��T5z��?��3��>I�F-Ԛˡ�d�G%>+vb���XK���jn�0G;�Pk�e���Y�i��Rè��bO��^Z=�L�Cz��K4S�ӌ>�l�V���/Z�Na����j݀C�F�*}���W���!�P���6�6ݿ�)�1��3�q��U��������X��پ�,Ya�QS/P���6B��}��9f�Β�wK����t�|s�m�Z�u��ܚ��&���l6X����n�uz�6�l�.;[��uk�&o�%�l˭P��s��<)+�N�Z�۩;��t)��!�l�!Щ �[���h�tr��*�
K>�;�;�;Ov���6�}�y��6\�W>�j�%��}��u'���Ĝ.�F�i�s�`څp�j�t`�ɖ-z��~TK�N�k�I=��&���h��g[mvh
q< �ٷF��}V�����zE���l;�����:�y�3�w�]�ۀ3����ZR����V,�S�|�,���!z+r�;����Z��[�.>s��g�j�1�����Q�0d����.Tӱ���S�F�y����^t�O��t#���h+�����5h�]���Q�~����L��OUO!5��S��@��5y���{T+�*��� �=<P5�����V�V��ޝ 3a�'��j���+���
�d�����}�)�.Hs�;�S���A�n�Oj� ���.*���!�]6ԋ�������]uX�C�.��=�0���-����Lw��ղں��yn��k��9�s����u��z��S���g\�$-���+XV�Da����w�R���F}oNIL�Y⟦��OM��Pϸt��3�(�+����x��[+_U5K`�����ѯ�!3*C+��z�|����Uf��od&�J]�\�ʈb
��j�� sB�*�w�`5�2��5h�,�r����h��e �m�l��J�t�WX�iT}
�P�jP�<��V�*dR�U��S
֠N��P��EM�L\�B�B�<qei^`�jȬy�a5�°��`X�XP3��:l
q��m
�)t(|�`С)t��(t���`С��u��@�����t1��i3�d8���3ldx�a3M����[
��a2w2���y�a�2�d�>ɰ�ɼ�p>�y�a��O.b�g�F�Q���,�F�,.c%�Y2.�4/ȸ�E�D��7P+�A!�����-��q�k05��3�R�i@��'�e����P��B`�@z3�� �8��2�
hPx_��v���5�Z��h�Q%~ ͂��Q��Ru�o�#h=�X2)��]Y
���$�Š��)���b,���&����G����FC�c!�W\TSZ(�\r�}�-c!H,�� ����t��t�?��oʵN�F&9�Һ�K!�뙎��V:�N����ZVQ4x-,��f:\� ˑ\�@
�e��r#1�n{��YGr�gi�1^�n��g�m�Д������>�K�d!���71�g�����)�^%�}���Ȥc`�l?�sݐ�.���!�n���AvS�.�m�i���Q_������ _6���t_8��G�υ�=Q��~e�2S{.���u��t�M*#�9/1_�^���vg��<��o� ��J=��)_�_�Vc 7Ȯ���x�0� �=���ꁄL��p_W�`7���ID��w�45\"�6���'I�}k�L���~ ����9��m%�:���a�%�Du9�X�#C}��`��J�Y��(��`�0&u�6S5�LO���|
�Ba�v��5pWc�ڍPo?f�|�O~��;��q��n����n�������{��
��|�+����s8��̅��9O��*�v�"a��̖�n��W���B�0k�½X(K��̴(��=8���+[��
(�H�[B8�9������:�s�/�J� $���n
���)�pĚ[ij��ѩ�2fJ`F����|3��ŁzH
��"@�@'��Ϲ��hn��9�Z:�6qvt
h�C"�e@K���R39ʉ]4�)� p��/gB��ɟ3kdco%se�N���]�_!ۍ��b��XE��.�/�S�˶��2Nm���p���A&鐾LL�@&�����rQ�pj��#E���1�G�#�B�s8i�T6��89��H$%'err�h�nXD����_�������:s�0��1�S@jr�ކ���[�D�De@��
��Ґ7�4�7�3)�D�`��됭��4���F^���9Y]Sy���b�]
��*S�O��%P�|P�P�rh.��$�+��Hև�ywD�w5���P�@J^��_BP�Z�~ 5�����@;��JA-�$��@���ʁ@-@y1 Ѥȱ�o��`#/���4�V4E�^z�Ld�4Z-
!��?t��i�Ur�4��~�K���Q?���p���58~����j���=8��x�"���� 8p�(�?��Q��x1�Ḅ�)�M^>�YM�i�7ؗ̅��D��Q/�y/� c`g�I���C킑i�dwime��2r.<�p�
�C�jt9�����0�)�qB7нM
�;�i�h��k�N�YrNQ��0KX����E��_�y�7�ov���˸nl�फ़q�F6:�l��6����_��AKn!;P>�N�ޑ<�/��mI�A�!�Fj�A>\�e�Y�-P�
�Ƀ`W&�+�2S�7]�Fz�~��=�cw���}P<.�x��8�_r�$>S��sȗ�`�JL�{���Q&zx�I��Pk��o��Un��=VG�0��|�e^�{��B���y��b�,5�^�_,�$�e8
[�f�zX�+�S�'0]�KӦY�����L�x5�&_���V�,�,A'�Z�" !�.H��|{��̎���3l&�$�B�A�P"�k&�������.ԼNJ|��0�uWt$T��q�ڌ�[�'���S��e�jsB��/m�0��� rc
�ֶ�����u=�[����ԭ7��#�m�<�<�\Kͥ�0�*��N�y8?��yy[���D%���͉[�K�����M��ߨ��v���?kZF�������^�䐄�rPc���x0S9$ Yn�,W׃\�@N�E�L�X�er<�r��EM������]BQ&�K�e��Lq1����Q&s��2��L������<�f"n��DV�)SDn������s2nY�p"#c82�������H]{ת�Pa��¦����7�8�u�����zH ηv]W���D{a�1�U�(��[u�UԻ��qZ��ڶoU Ԙ��5�G�TU��MqU�\ �X�ka�����BW5���Ƶ0��ŅXoi�'���V���렾�uy�����sY��:�q�Bo�~���'�
�'@�kFÌ���2ۤx9���F����ؖ����"GS�Q���X�A�p��G/���D ��!Ԝ���91�}
p��,%j3<��)5~Xf���29nB���)O�U�Y���wC�������s Os+����m�R��m�F�G3a(��|�яh�3T����b�W�%ьJ&~TY� �� @�`�5Y
endstream
endobj
36 0 obj
24983
endobj
37 0 obj
<>
endobj
38 0 obj
<>
stream
x�]�͎�0�=O�r���
�HQ�L2��菚�pR��Cy����R�pm\0���;��R|Sw�K~�>��t��O�2�����%�wm笈c���⯇�<�VY�=^�-�?m���?e����0���������y��~\�2[��ޟ�<���K{���z>���<�����dž�n��mn;���UY���~�����w�)9�t�~�!��XZ��[�,��d����47��,%r��ܰF�s����a~C~c���e�k����y���lJ�-2�
��~yG�����ך�a3ɯ���X��_���7�n�kN~���_�o��e�ot]��M�B��H�?��ǺB�g!�;K��_���o�<���i
��B�C߄~���"�[]7����[�[�-�m��^,��ɏ{��o�|��c�_���tN������c���~ѱ�[u�_�'�~�{�R�1��ߡW�~�5��ќ�xo��u��G���v�� �r��C��X?��s������ӌQ��
.�J
endstream
endobj
39 0 obj
<>
endobj
40 0 obj
<>
stream
x��{y|T���sνw��Y�,�%۽�$!d����@$Yb؉ IH& I�¦"��P�V���$����T���[��U�����E۪I��ܙ�Dm�����~���9�y�s�g?7COWoL�84mh�\q��y��7m�Q����=� 4�t��P%m��l�Y۶�e�Cc��@�m낍�2�V�)%8G�:D\?r���l���г�U�%��)�W�u45v--(��9l�nh������)�V�7�$� ��b���8�]\��;���o�.y�m�È#�e�:֦/�D�d0���l�;�1.���#����X>
<������GZG?a}#��D��'�yN��������[a7~����}�8t�68��c䗴V�&���
r 7�*<W3�����P�Fo&0�ʠ������T�v���>���^ x���,@�g�ez��1P�a!��=ݏ{}���e�oC`��n�����i/=�='��sW�����ЊTݰ��s|J�A�$�r����G�6��S��@��i���Mx�JV��˹N^��F�� �V@\W!��~z��3���_P9�fᮋ`&�%��e��/I%S�<�����k*�bz5=D�� \:~��� ��?���-�{:�h�h���-��GO��y�@:\�s��K�O���k`J�.��
��>x�0'���m�|!�Gf��B��r�� ��W�k��6�{�˜�[�k�/����k#02cd�H�ȯG-��ώ~<:��T����,�� �|�;pŇ���{�~B�I�����I
�J�H)$�����%=d+����%w��H��n� O�ߑ�g�s�����*4�f�,�Mҵt'�K�'���}��NK���K�L���8'~��4n��[�up[���v�!���;<����|&-������`nn~*�+�����@�X�Nw�.�{S��%b��]�J�����>��0��я'����w��EsN�YL�'������o�*������.��&� b��98�P�������x-i]O��Vr1�?Lz��x���������ߏ�mB����Fh-l��S'�H�6¯��:��E��itL'�l��Z����eh'���C�!۸� j�0}��z�E'��d�.�^$g��G}�"�h1Y�����GW@5��k���?Y(�C��n>�B���8�cp-�e��{V����L�0�v���/ɟ�8��_˭�]n�<�m�a���F�ǹ��9½A�p��B��-������0��
���F~O�#��������#k�]���
��.���w��8z�R�oB}�A�&��W��.%���\�\*$鰐&�z:GTuN�zS��Qf��0���?���d`��@��Jf�,�Q4� ?oZnNvV�?cj����_r��$&���z=nW��a��V��d4HzQ'�T dV�*�PZC�O�͛��ھFD4N@4�TDUN� �
�:�2��-ߢD(�DVK�$+S�𩡗�}j��\R����:5tV��5�O�fl$%��³�\
��"T�i]_EC9��o4��ʂ��L�74"r�:��{6�ꮘ�OAo�]�b}�!���m!ĥV46�/��(�KJ�����&ߚ�憬~�ʴeB����-�����n�?�tߞ�k��f_s���X�ְ�q��{���&Nn/��9�7���S
XR;�7��uu8����
}����EOn�m�%r����a.SC�o�o]�e
(�ؾ,ݚ4}b+Ծ嵾�Pi����<�� }K�z�wrOVf�l�p��b�&�D 8ާA9�����������&wR�Ã�`Ep�5�@2��jF1�����>y&ó�!!U��}_��w��ɘ�(F�*d�1�`�?���PF���{����gen
�B_��b��ŵ8�nf�<)�Iuw8k�ڱ�6�VaM�r�u!��zN��Ĭ`=;�zƇ7�P}�k)bLH�6��*��f���t#�U�|UKV֪}
Q�V-�Ԋ���B!GY-G���^��U�ĬQk
��O�irsXԣ*j�V��y��ΐ���G?c������6C3��۳&�'m�����4Z�|e_�aR_%����J�Z����ݱƧʾ�!z�����aL��ѓ��B�{����L�V
s�}dג�ٵle퐌�����в��uuY,�2���"~J#٘U��h>L��s`p��W�X?��
J�<���_��,�ϕT�@)��7XL�M�%�R� ��7*w���_�ʟ�5a��|!?����d`�%Y$Րj��R3g�D��/�_��6�/��0�9�if�
���t?�0�b���L��i0�])����:�X1͐�pFw��E\a�o��U�VhU�V�u��o41`�@��ؑ�%>N�`�I���_(�W�����|OR=���--=;\f�%�o�R~
l��b�,lvw1���K>U��%�M/(,,*L)*�^0%͗�����$r��ۗ���D�q���
9�ңM�_r}�dł��ҭ]����?COw�zgŻ�^�vq��4��q��k�T�bg�
��&Ki�)y�z��G.��\�9����.- �Ye�⿴��5�d����Mx/��H��J�1��G���t��zϭ⭆��t�)�"�&q������e���6���`du�\^�+ _�|uy%��'��\��KOS6�Kһu�V��������]�R8�zjK�D�.��vxyo�^9'�����@�I�ȫ�;�g�#�
T��k����K���9���Ϟ;+��߈"-�FM+=�/-))arA���Ji'?��i�PO�x4�9�4�����z��ۓw���>���&�N�u�����Rv���V䔔-�^S�G^��w����O菅#��-�M֝֟Z�p�/��O��0!x�`7f�L:/j��3[���=��d4n�Y+��4n��c|�Ɓi�t���Y�,�,qR��<7c��W��ܙsg�aV�aj��Uj+���3�K�xS�����E\�苞�|�8炶@n��7'�\�ʒ����ݩ%���6=�·���!#����t��h�ͨ3K�.-�!���Xf�ĩXL�HCrg2� q1�D�ι2�&�F�iPte�79/�ݖx��^�+F�U�@VN�%yUe����� 3�/뫙���5K;�d����萋�p�n(��K+bG�M�]�YYh�q����|z�/�?��cfך�e_��=��[H�KG>{�ё��\��}��,����.ٻ�]�0�؏~�D,� ���%�����T��͎���M?r\��{�����K>pX�ã��
X(3��cZl�e-1.�����ƺY©3����t�`q��v��ht7�����t��b��8I��I���ƻݱ�Z�I2F�=��x����O���#��i#��s���lҌ�[_���ǯG;fY��m���b.Aݲ¹��w�t�~����.�a������8]M�g�B:/�7�b��N�> xE �5tFE'�t�����P�j���EF�!D�˨���%���L��g|r�!�Fƛ2�_"%������&^�i&��C(jgR)0QKw)�.�5����D{��}�pt�������J�%��y��͜0�ĸ������� ���q�o�Zz���Erf�~�x%���囦I~}��H
��яFZ�y�/$�W��
���Ժ2f�U�3]�૭�c�T>��)�K���iH` j<��:���s�����z�L3�<�V^��铈�F�7�٢��eKB��n�b���ERc!vu,E]L
���̶�jAڅ�H$�erI���X
ɆgG6s��XƗzƤz��y&a�3��c�b尭8g�a�1�m�GO����#�1�����t��%أ� ��߯�߲��ϵ8Ts�uK���Uu��*6玴
��Ic����ȧ��j�7s���d��;o���5<�B�y�9>?a̰�
����Xsat^n5ߕtW2�����x��72��;�u�*G�:n���w�SJR�o��WMF.!Y��5O�)��H!dj��e�1A
�D�!�a��DjU 9���3 g���3�
�r*M���4Ӗ2�\�������'#�t���\��z�Ξ��m�8V{qƎ367�-��4���V:л���r��)i,�AV��2%Ť�ž1N��i+N�^]�eKJ����ʟ;��o�~~G���|����ٝ&��+��dd\��1o���M
�5yyi��+�m^��K.�X�J� �D� �h�"a����"���c�)aT)�E�����s\;HvM�p
^���B����:^����F��c�'M�<��}���}�N��,�E�r�ca�EL>�(R�Ӣ�g$L�`�71X�}t��E����n� <�$���<�Ʈ|�O
Iމ�_'���c\��I�8#����~��}����>.ʙQ�H�!�*q��#헎I��QI��:O84b \:EO�����tb:�X'���$GX��lBN����|�h-�{��>�]3{�}��$�@>P�]ʏ1�g�|аd��3Fj] ��:>'R�������� �B�sD�)�t�[���?�x�-�;O�3�b���k���
�{zg]5|%�gM�����ψ5s�����Ƚd�' C��.P�LG�<�
K��Ӝ�(�)�V��vLR���i�=5�J���t�
o�9����n�ɹI������7�(Nѓ��
�l�) V�G�zk%��\.�}��(���+n~��z�0M=.����W�T�9�$=-���0�*Hw������zB��=��+��}�1��x��W�j,vys���i$n���.�BT ���S�ȍ#�^�nz��<�iE�v���9eY��h+�c3�ɩ����n�q�=o>��٘r�
_������Ď�І}��^����6{�͵��T��g�$�w;2�\�|nG>I�0��7U������w
��+^=�1�k�� �J�r��^��~-[^H�d��� qz�� y�z3�f#���Hec-F70��k�_2�/a/#�w��=���?.��/Iz�A�8ވNL�x=5�R����� $�d��D�Su�*�s:� ��d+�:c�^D�I8�7�M9��jr��l?](Hy��2�k����\����Tk�zv���}��;s�7a{ޙ�ףh��(�q ���aE=�y}���.rYī"�O���\%�?��?�E�ϼ����o���Fz�[h�#w��N���C�8��ZbY��
>iQjoLj��M7Ֆ�Z�zaLMLK�n[��Θd�qڹ�N�8(�pb�2�����Q�FI����ω/�_�i�&�&�?;����&��?%��'݈�o��Sh9��c9����;�I�����O�ϜO/γ�]��{!��O�w��h����}�N�1��P��[�]�i������@~Ըz�ի�*��&pnќ�^�����s:��'Ǔw�t��|�On��y}�zF
/Ɗ�C���A���X�X��E�K���ݞ�^��0��p����K�2��cw���h!.8;�Y E&
��,F�'����L�^�;��yU1�n�7�Y�T�i��p�`���ַ��uvJ��H�쯎��;3�$׳7��_���D�y?s]�\٭�#N۞�I�7I$)�,�š��O���������|�9CS�����Z�s��گ�xë�%�����K�wo#��M����,}���_q�'`(�Z�k�n��ƩȆb�n]�*_!m���:��9U*#�/���2#IɅ�ˮ��]1�^�Ԫ$�P�ť�i�xY��j�J�Q5�L5{�6~[�gׅ�o���<���G��W�\҉���?����H��\����r���'�y�(Y|����`W���?ڵ�zԊ6<��h�VP��$D�;;�j����'x�VS���EtY� SE_̅��-:���$CfL��� �$y���*2װ F�ZMF�S2A�"�V���P��%K��%ٺ��a=����G�dUHSӆH����;��Zj��W�����.a����7{B�+���(N���?���-�����#���-����k��o�w��ۯ���9p�������cNJ~������`q��+�\�L�2�H��Tc����m��!i�B;ǣ��c8{��eC���%���\Xd!U"N��9��y��9z�\�L ����`΄����ˮ��ny�-��>������pQ9�z�s&�r�,#{6��Q�Y�HQ�'d�Z��+�/�M��s�"{Y�� �*��k�V͞^�����ܝ{n��<'���M]{�iaYM��t�1�_�w�@����47"�3�g ��\GQ��:������ll�n�P����F2��`�c�S������Ouw���uM>���[Wa�ѯ�\lo�\�����-����J�.��O��nj�Z���=Z��ST��*Q�j��N��!���p�*:�b2Eިd(�,`V��ZL[Y�
�(@��IՏ�A���`YQ$�<�� �p"��5���QQ���
;Ǯ
,�N��F~�����ߛ M���:��_�t]̒���s�|�ǎ�%K����N�&�)�~��V>��ƚ�K���wM�8��>Q�ZP�f�}�����JA`ͱ{G���fG�jk�z�^�����_�����G#�v��P���M�Ɖ�G2]�~�@��k ���Uݰ����n��ga?}���я0&/$�B!>`?�`�VTFۗ!�ƶ��z�Z����L���Fut��p/�;��y�f�%~�?,���3�0]h
���}��Ϡ���@9��RZ���%`�!D~�p�Vr�9
Z��F��'
s�;�0�8
�H�(��x��E8�~��z�%�����(l�ҁqOVEa��}Q��N�-
sP(��y0 �Ea��[QX�l�^�:
������T�:������ ��Z�!
���h����0�4X���_��'�
5��(��}����Fa�?�����(���r�0�K3�0�_���8V����(���>�������'�0���IF��h���ђ�����wZDa̜,�j��i�e{�!�r�[��<�y٧���Lf��
�If�o4���nuEa<�5��Fo����:O�]~Mf�N
�j��Ea6�m����q
N��߈���h���0�e���y��(��ș���+�0�/��,6����n�m�k���.
��%��>�`S���(���`M.��Q�b������-Dh9�� �������V��0e��B����o�(��g�~�K���@��
bD�MX6#��[ql�GV�B�wV�9�.2�Z�E��ꤑ�חl���^T��U�AB�8/��n|Zp��I3O����L�yG��3[&����ΗO��U;w#>=��q�
ھ�#����/��]�12n�Z��8��2m7=������fP���i�Rq���vm_�u�?����-��5���^�b{��E������k�gY���C�j7d"n��R��Ӫ�p��ډ"�QQ��0%R��F�x��^M�"<�ȠE�k�����Y�wj�m甊�.mO=Q�k�����:��7h<��m�1��E��>��Ȉ�}tM�����wܤ���fmߌ#��H��6�j�G�5��6'؈6
JG��X3
\������p��7�˾Kӯ1Y�i���`�nO� 2b'���G[oL/����6#f�v�����&4N�z0j)߶�����F��n���<��
)��e?��������������A�����������=[��֦.m]���[]�vm
6g��jml������46h��C���m�]j�sfM��gQ���խM]�-=S#��1��ٹ��y[������#���j�������ص^�h���U[���[���lV��4�qp{sNG�ځ=]jSGo{OWk�;��M2�[Ί��ͭ�k�E--�MA5K]ڱWY�ڴ����;S]܈�5�6��{ۛ�4��yu��ƭjoww�'h�h�Q{:�����6��M��]��l ֍�jg�kCk�����A��v6v�9�4lgWGsoS;��u�� +`�����یrR�6��UMo��7���'P����5�fv��`7;%c��"�5K;Qz+����x�Պ�6wlno�hl�̄���Q�r������Q�����f]��s2�����F��&����mr�z��
�~�nr�� ��K�W�� x���07�
q�i&��_�bƲ�e1��b����+�������0їwh���{>}���'ڈ����m��r�[=�h�pk�{�'���q���ga=? .��[Qn��K�a��C��:�s��>�/��~�7�j������=?`�$w���'�L�/�ҨiN���>��]����M���S�soӬ������?5��9�;��mҧy�c�A �G��azdP��c��Ț��yWͱ��p�S�|��X.�g5>?W����c"�$'vp06.�z�D��8Ńv�����9E�#��f��J+Wke�V�h�5��![]+Oi�1����R�\��Z�ѓ������C�a��"gY!�LP���q�@�&�@Q����)y��*�X+�\�1O��')�\)"��N(���F��m�@�<���N��N3HaR:�q�2G"3�$ϖ+��N|���.� �jM�>4�|�&5�WJXO��)aJ���/�c�������!��s@ +a�d��C��[Y��;�lQڔvU�jK�*`T�p�ʌ�J�f�,T�U.Tp�G�
�,��PnPyl�#�4�K�V��2#�M��-�U�(Sp�dm�
e�Y2KE{/�="�=,��.�#�%�-�N��{sĽ~qo��7At��zYoћ��^���z��������;u2�t<+y
�)+i�#��),�����U�撪��&�Z���\�Ò�!�7���UP�|�'4�_G����U!q�%����T���&��6L�u]�C(U�u7Ʊz��������Sj�m+�,���!ZN�ٟg�(�oB)���"6�as/k�eMOB趪e���ByM��
ݲL]U;D���+ʇ�/XUW;�e��K��,���B�ht��G�QV!��
(etP�C��I�Χѡ�E�\*�4:�K�D�H~��2X�t�w Q�Kt�3�����������Fs22W�D#Q$IR44E#Q�H*ϓdEI��I���8r�F�И�13[���>��~E+ӕŵ�z�[W�*R���ٚ�����ŝ����|sCF�\(-�h?\љB:D��0�YI��q'y G4j��Ѯ�9YsXj/벰����l��w��vɈ�����Ӌ�T�����~z�uT�2�U�J����ŊP���q�c8��">
endobj
43 0 obj
<>
stream
x�]�Kn�0�O�e���IB !%$}�� ��"c����xh+u�,Ϙ_c��**�MћT
o;����)�7�w�ɘ�NM�*�U�X��z'�+�iʢw�7Nn櫓n�ĢW��u��Wy�����/��L\�,�Z�sc_��е����y�[�
�����(j�0�F�k�X*D�Ӳ��o/���֪���R�K�Hd��w�
y��RM����P��'��9������g���/�μ��|����ߒK~�,)�ߒ�?��rɟ�����'E�2���Up�p�_C��0�|g��߰�Ů�|���
endstream
endobj
44 0 obj
<>
endobj
45 0 obj
<>
stream
x���y|TE�8^Uw��wz�$};�t�&d���@�`D�j�I�Q$!$,:B�X�W�㊎4 b�2�}t�<utƑ7��:���Sd�tOUwXf��|������S��ZN-�N�:�ꦻ�zڐ�"鋯j��������7��}�n
=2~�G�,�\v���<!�
!��e+�/��ζ�2?�P���m�K�����}PǸ�pu�z �!�����u���}?
�gVt,n}?4�=j��u]gw��P-D�������+z_����c]g��n��;i~gW[��_L���ޅ4_�1*�8�xA�dE5Mf��fOs8]n���O��h��PvN87/����#@�,<���0JG(qt4��Gi��`VF2�>���[��54��Cnt
{q ��x�-L�4��B4ݍ�(��<4�P&�n��'�$>G���#�����ݐ+z����Ǩ]��6�9�)jJ܇d��D4�P+���@�@w���'NA�t=�W�jPM���iT�n�w����m�,&'�Q&�B�H$�A�FM���S��P]�nB;��{��У(�����"�-MG��J�mC���؎���5�cHDi(�Ԏ>��xy�7&&%>B��!�/���O�ū&^AN�Bb�K�-/�7���#B8~$�}��7ȃ|�bt5���)@�п�ߠ���F'������8���/�B��L�I�&���q�p�q/���d�J�W�G�&a��*�O?�#�����'~
�c��è8zH�c�%���!�����?/��C+��|'�~��D�E&�Zh��t��'w�;��w�{�|D>&!�p�ō�Vqs1n�;�����a~,_���� ��R�Ba�����pB�����g��ҍ���!�����Ȯ�t5p�!���>������=>���Y�� ΅~W�:\�g�K�p�oƷ��~�~Fc �=Bj��J�ȍd3� ���-�9L�C��\��p%�tnw����m�n���������q�q�a��|&��_���?���-\,\�G���a���i�HD��.�W�O��Di�� m�ޗ�[���z���-��`&�M�F|20�,0���X����8̋��Cߜ�˧QJQ�c@ߍ_@��u�Q$hb��ǿ'G�W��7�{�'����$��m���H^���>RE�8�?�O�OA�ס;�x5z��oD�7߈��+x:>���:~ ��_kA\�~�>�?ě��~DwÌ>�>�O�ﰐ��ڨ��� �7!���a�m���
�B|��;�T!N�F'�������ɠI������?%*���`��'a�-G��� �i�G��U�%�����]Z�D,�@���D�%�~����p��A��B����C�����v��4�����Ka=�;���>��¯�����~��?�4�0������-�an�h�B�C��
��DS�u�=>95��P����`=��q�ď���aL�F�ڗ��z��B(�8��
xR���.@�q��x�
��P�ݠ���O�Gn'X�ƀ^���oѥh �05�0�Q%h�Z�߀��؊&�,�(е�
5�T)� 4&~Ibؽ���
za�q� '���㳡�a���wY/�%m�����
�K�̉ί��D�k��Փ.��8�r|Ey�����hl�HA~^n8';����~���v9iv��b6
�"K��s�1SCu-Z,��ái�
i<�
��$��4H�;�LLkaŴ�K�Pr�ߕԓ%�3%�U�BU�c��!-��ڐ6��j�'��&-v��3���&��A Цz��j1ܢM�խY�mjK-T�נN MiSǠ��P`1w�s/vO�!��$��S1_�vj���=�q9S[��f5N���M�cbx��Т
M�Y"����SbkFk��A۵�c����9���S7����M��k4�m�f-6<���� }65A@Kr�Z��A�7��h����1�o�&5::����BSiJ�ZL M-�vEL�o[�^������䛪m��
ƪ��������m����y��)��jK2v�ْB��s��3yc�)V?�g1�Qh:DL[�AOC0����6m[<��� Ul �H{L�Ҳ�:��S���c
i۾A ��_��ҚJs�� �R99#j�?��"�XAi
�)�q���Y3Hƅ:�`j6M(��t���hDb���q
-��#�(�#-4gx4�9����!o �$�c��3&���Y�����'İ�_d�%����g-hԦnkI�~�y�d��3y),�6���F����љ�4�h��9�'2�^�@(Y��b֖i�g��S�AI>�h0q�R1p�,���������q��ä~�m�����@m�V�궵lkL�.
i�ж!�yb[�Ԗ� L������X�'��4yoo��W�[�,h��w�enc?�dJ�䦦B0-����ZB���AR��!��sH��8F^Y�{���y"֓U#U�X���1R�����GIq����æZ�O��i�0�"o�����xt���a�s��A�J����M�UGRP4},��CTd�Oʗ*�+��F�y�PCd�)E�2��oS�Pגu���n�9�zR�Nu��w(��7���ߒ��ʇ�1����jZ��So 7�7(7�;��hh#W�˔�����jI=_�ԫ�ʗ*���Q��Q2��*�j��#/*��$>ޭH{E2en� <�*�Q�JE��Xj�� ���`�4LQY7�F
�I�V�d0�xL$��ꪪ�*��]a�f\t���q��LL�����������rP�pF���*�$��<�Mt_<@�#!1���@QdUs��Bƿ�6�X(~1~<�q�O�?N{�Ͼ���~
������ߵCH��U��j]iPH�S��C�W�PZ��J$�(�ps�ut,5�2Q�U"�1O٣���W���D@�#)1�ߑ�UU�`��Q���U�]�4�_w`o�X��1?��E|���@�%� �����u�3�3�Kk�5ƛ��7�o�+�[���v�-ϓ��˔�.��*W���W{�}����o�ް��z�j��E
�|��=�`�J/�n�G��3�p���D�q�^�*����5�BHε�'M�O�*�"Y��>[ԀZ�r� �y �an��/�6����~}|��^Y��:�|4R}���U�ʒb�s�˃6�ee��b\�ƻ�p8�%:����q�\5����ܟ㻟�ɻ؆���?
<��ʧ�������vdp�֗��>�KN���מ�k����ӣ`�����,��t_��/,�ɼ�����_�0H��%C�a��_b�ә��N0[�� �#G�g���-�@4=������/ū��ON2\����ҧ�����M��^^�]���{��qߐ�M�/�FQ49]�ו+�;��k�&�����h|)���dd���Ƙ����h���oF�#�t6ɮˠ�Xl�D/��(Ú��[��1�!R-(]���m�A�o���
���x�hR���1�B�1PB��̒���䙚�]Fk8�X7��F��(��Oo)�����'n<ӽ��������t�8˽��B$;J�(�,X����#GA:�WE�Z��(�j:������������%٤9�� 5��Nr��U8wܸ�R���9\�`87�+���pytܸ
�(�#,���t��J!i\9nKD�}���z��`��i�6?zp����~qCG�\|��/�+k/�Zf5�?������o����
�\We�O��s��YS'�ߵ�zr�&�/
Wd�W��Y�l��pt�=O�it#�-Q�e�D%��CpAI.� QAy��,Z J�4N�VIk�b� ޣ�
S�9i�bg��;��N:aY�(��==3�t�}|%�{�Q��q��a�1;x�z��hRԽ������1�'�yF.��V��H&���Q��梤F��J[%��+�``�Fpr���Y���&����[с� �'�rV<>M`
���n6٪Ӭi^x�=հ�����O�ՔLKb�̅�rs]t��q$~
��[��L�tcìK���]���#f���d�y�Y�ߛV7ѵ8��}�M�#ߣO���M��ɿI>��+x�d��6��乇�w���ߐ� �W~c<&?3Y��I�M|U~�(��[�e���_5���p�R��;��o"��1)�T�:9�8p��8pg��USu�ݺԾ����qs�wiQ;H,r:��p�qI9��m�����[_��v��^��V���d�m�7�����7&�|��'�x�Ij��;�ͅ�ݗږ��8E�U��VO�mLjd����R����i��Ӊq>,g]ˎ�q��|*I����O��tzNx�W�Q
aE�Y(�'���{ݩ�
�ޤ����I3�WY�fǶq�r��-�p9�O��xE�K&l�r����]=��{w�[t��I_�s�m�̞�x6Ag ��Mxf�Wz��4R�-���,�<�ˉ��4vۉ{8ER%�gc݂�}k0�i��N�� '�V�u��f`BEx!�PB��pa�}��ڱ˱���8z;�'rX����;��u}���>VK`",�!�H�o��A-Z�D�_{�"��r��QXD�2|�~���$C*܌A���PyYy��\=l�MϽȳ��_]iP��������#���
�fM-��s�G�[A�W��`%8Q���n�����x���[\g�ֽVۤn2o�nql��b����;2AoΕ܍p��\Z'����\�m��ڶ�6i�J��=%�w����e��7�ڥv�j�^9|1�Z��l,�l��8����`�$?��U�P�6`����st�����o.��S��4O1D�`9�Zq�^�R�Y�[�W j'
HA �ψ-ƀ����y����3������U3���5���>���a�aj�R5U�`3l��9.������lV��Csƥ��J�έp %W�^5E7?�cO���u�O�uxCy^�@e�����xF�\�<������#$]S�o���2|k|U�ޟ�X�O��5��O�� ���S�Tr��
���E���j�4ٛ\�-��v���{�=�7�ox~k������y���Sb�������[Y�[�4Q��"��L��}~)�8O��l�q<̦��rj�E�E�
x�SfSi]��=�%��l�v�
Ka�E�����`��W>%_�Ι{��\�Q��W0X�`���_0d�؟��^J���4��i���u�����M�<�r�R��`{1k36e�4�Cԃ�D)�ۼ�謬Y���^�V��˺.�Y�#j�);+;Ti����zSm֔����z��Y[M۲W�0=���4�YbȫzM�,)+��x��ѽZ�Ã;<�<�s��!?L��?�:84
�y��Ӣ�X�
���}8�������}�V��竄��4w�]/�}cAoXcVb��_�R�N�s��R?�q/��7�%�L�`�6lpG�%��]`��+�^%�]����I��C)�����,`���o��C��^i��*�F��L������O��4�\�u��<��8�4%�.���T������9-Ǖ�rٗڶg�$jغ]<��4t�|�6�z�G���e�Ư�°+J��i�^{���1�q읞�������mY?+:�o;q��g;_]�M��gUFs��^up���_ Z�k3B\�1+zRϻG����
=Wdo4/7w�yU����jLI�q����^��KF*GD5)V�X�TxŷѾ�N�7����y���ɚ�酉&�k���(ieTͰ�&͌���tCe�LRe)]3�'Ts�\{�^�t<�ZA�Q��?�%ц����\Y��t�L�]ćﹲ����5����2tu+�JG;�B{�ؤ6���{��wJ�*��3�7�L�� Ψ�"��x���{��P��_0��=a��`���7��bA�[3q�5({3��1�f��s�t�x�^Z�v��]lW��r\�iO���I#
*8�n[ô������5{<�+��c����-7.[���˚p.�3��I��;w_��G�x��ƛs�@���CȚ8��*�U�3�m}RxB}Ay�4�e�F.�ԙ�O����}o��0~�6���5��-�N�4�n�E-Η��89�X2�4����F���`n1��NW�~�?����8b C�2������$��3�[�����V��B���o�����6H(����M�(safG�L>��up���)�4�<��M�kj����=�Q��3-�7�C�e�6�G��C'�3W��=�.S�?Z�=[όA���v��MAl@Q'�hM�:�h��ԋmf͛u���6j�͛u`b�U��*�
�ʨ��B�L�T
�Sdj!-���;�����_njǎ��c�8�sN^�˭����*�g���s�}���?x��ix���LYM���I�_w
y���D"}������K��>��A�U��Qb�|�O�B��7
F� ���"��@^C*0D��f�$��>���.���)XD*��g��Lm8?��H�
���E��Jj������0�to�תV�3�1T�n�I�L��<� �����c9�l$����e��g��f�+�^���8[�t��W��[I7�U�f�{6�ALsӃpR���8�ܢ��6Ɓ{#|n����d&��G@g��a����r%��l'�A,�0H.^V��
z7�`cҬ��x���<�U�'p=���欃�}��3�p�T>.���Ǐ��땘�C;�&���D{��7�q([w��` ����y�嗭IV=cU��S�<�����d��������<�}C���7=�<���|����)���wyv�ˢOCyb�o?�3�;�'g{���>����[<�H cw���NO�����57f��� Cf�Y.�3�A�FK��Hh/u�:]sv(���F� ����"�`tH7>�&(�].<��X[�o�{�$���t�_UEw��#���#�VV��-�X��Jڇ~��Z���JA��U��a���4L߳��,gf���j<���!#q��0ۂ������k)g\6XŰeK"/J��t���˟G&�55.��y��Ƈ�.�Q?y��������V_:��+�I���/�]<����0=�w0/��%!�!)qXW**a��Cb��y�QQ���
�\ȃG>*��<��8U��+���[*,����q��DLds��xI�XC�!ITx^D� ����2&�l
�2�j��^V�Y���ê�����6��I�H�M���.�#�����e~��Q9j��k-�[�nQ6�l��]����j����]�f��&�����0b���/gL�� L����UTQD�o&:� 6E���7ŏeϪ���v����� �ϴ�o��?��웲��k��͍��[�w�D_�6cs�M�%�L�%��C$��2R��x
��]fir4��ϟٕ�S�Si���2�ļ�1�*���jǜ0���[`4��P`4�]ng��Ƭ'���1���~��m�c�$̓PN�D�f������5��\
�j!��S�xł|C8&����|���0�u�e���3���)�r�(Jg��v%�d�sC�s��~�e���C$�������-���e�K#�E"=t.���t9x���]�9�$����v��z\#g��_Y��f�0����0~��^,M�|���_�x���e�lY�vC]�xgf�U���g���7}?���/��j�3��~豾�Y��c���9���%������]h����>���N�Q�y�|G��G�Q6 28�np*������<�^��-�u�P�g��>�J_N>A�S�=6Or�TX��x����^7��Z�L��'�qʲ���+�|�bU���q�3�O�) K�D����wӔ���
Ӫ��S @�S�K�`6�g?nW�n�F�}���809��/㿏o�W�(6=��4�;�ck~��_���M����ߊ����]���n�"�]��/��B�NX�x���k���`�����@x��Z2U��
5�(�Ғߛ�+�Q� �q�s�s�X���#�f�_��/��/���h5�{Y� yɗ�b�����3y�j�����ù*F������-6�aöAR�[|�pF:�u���"��� �s�?ҏP.3ѕj
�q��\(���@������'\-�}'��\����P��[����s�y�=�L��)M:;v�IP���
3��l Q���?��88��ԑ���q�.����gt�Y��sۇ��]\�ȏz�ˈ�ȝ5q������q5�����mO͝7o����i"[5m��qB��_0���{GN�Hn����a~l:�O;>mZ�G�JSeZ�_�M7MO���ͯ����NJ���es�$���.��j1�����:[��l [���3t�^z�Q��;V%ŭGG/�ʤ*�b���K���PsZ�s�B�
�Rw�؎Ųg��$~z��֙��]�,]t���˶��nX�C|$~2�aݼ�Ϲ���x�] ����Ya��}X��!9�ms�v�w:�ɽ�@�ub�4d~3�i��d��o�gj3�e���DQ� �ٵ�eYK���n�V*�S�:�E������,)+;7\a,���lIT���r�YYY!);K�ڸα&��`��Ƃ��w���2��[�7{�-x� 6Ft]z0u��h��?qaW�lȹ5��螌h�o{
�a.����1��b+��� J�vR���ɽ���ȺA:'�A^��djߌ��1���(e㕋��Y�u���ɽ��Ob� �f��4������34���.M�i�?����U~z��K�g�0��e����@v2������J�U���tg�kY�g��,���}(�+�2�?��q��d�(;5��p�܌o�����S4��LsAI�����<�Cp�P��̭C�n*u��Q7�}v�9���z-������|:�,n�%|$5xv��>T��I���Rf�����*�4'-���[�b�W[��|�r����0VR��H�Ҿ�k�d�1xbM��&OŨE���f�bT�{(F���*��g_�����sz���6|��G��ſ�-l�(�����Ư��pEf��K/Ҝ[����n{��%�&\�Lg�ҋ�7��nV����{ۅ���p%5|���d��߰" .!�4ږ��I��fO��{�NRT��T]�0CP� +��D���y�tbz���/�μk�.� nva.�j[��;O����[�>0t�6낺�e�c�OwM��r��m���[7�| ��)�;3s��Oߘ�+Ąa�� �a�� �PT%\��wc����wcRoä\P��wu�-�M��-/ڦ��dI��n٥\(_�H�*�w[��t��z�����Oœ��d4bD��4�h�L�З��v=K�7�[�\���O4���?����L�[��r^��4���e�:ٜ��q�Qv�����-������8ϐv�7��p^�u��}��
�p�|p������,9��������m8I��͠��L�8>HO�N�%��
��~b�;Pr��V�����i���|��>m��N�^E5��DB��Ji�����5�n�[���������y�>)�Фx%Ε�,Bժj���t�8C�h���������$Úۇ0= *��+`R����*ER�2`z#՜���Ԕ�^�b����7M)�ٲ����?�o�%�O?��������� �����;��^��x"�8}�{���@a�����m�_��/P���ǥ��G
���K�M���N�>��>�NÓ�QN�a����R�/��m�)JO��W��"���X�L���Y��ߥ����PM�x��~�M�-�/�D
'�����" E�8�(�`А��މ��"+� ����E=���Iǀ�3q��������@�?��'#=�`��z�tГI%]tx��A�+i�<�j�\z�zd �~^�E�q�@�]���.��Jp���o��e c
_���/��r0��;2~����Yq�ad�3����1X ��
�`xHXVɷ��J*�q#i��d�]��?d��?b��"�a�ҍd��`e)�������b�"�V~Zx,G�)j�Ւ2�(�s��f�Z4K�E�l���n���Cvb��2�k�A���4R���1�����yF�_l���_��~
�$��4���.����7G�y�B�jԫljC�Y�Da���UI�>=�O^�"j��U�r!��j�4X�L�DiBe�x\�( �A'�ƕ�Y��EE%
����������:�8L>3>�~��IN��"�'
�S�����K�+Ww+O��B�͇U�E�@u���\g�d�bs��u�y��BK�y��=հNY�]��E��ݔ!*.�b���{�7��4��,�5��a2-F����I�:p���A�s&&�ىd3�\d����}n���C"/n�a-T"����w'�J��>��7���Q#U�]?��x��H��Z�kؖ��I}Ų��fJ.�;-ȍ%����6[z
�M:���W^n�����Ctͽ|i��~sE��i���n������6}������O7G�.�n�|�eF&�
���A�$W/��"�������d�6�'9�L�f4�#\D*�Jq7M�������1FUd�y�W*o�#��Wu�!���
�J��k,A�$�]H.�Iӕ�h�V��Q�7�-�f&H�l�}��F��������pT�B=j��R8%�T���4
���t�?!ʇ�&>b1�ƌ�y��D��ze3�<@��Ա���&��Y��ĠӘA7AⱨЋ��R��'oc��b�m01c@T��2j@����T��_�$A�yzg�^%Gj���L�n�O�Q�i����8lާa��!�Kn�>��gd���$/fμnM}Y�ث��l��T&��%�EԷ�g�M�0�S��J�)p,����ǂK���h�Ȩ��4,]��08�Zb��pS<�mo>�-{����}~�Fi��#�����O8�
~�g�`��9�[��x��E5
�M*���a��c6��J��� ,���j�;���
G���pB�{��5�d�}[}��1?L�����������2���^��!��
b�R�����N��|�u�-�Kgܰ�ё�p��?�����jŜI� �ïď��s7�-�/�.7�翾{���v3�S���#UP�^-�(�H�\,�$"�E���2�x*A
��jq�H��,D���` �ʹb��;&vh
�`s�Y�a���k�tY��;>2�,y@8p*�ة��ؿ�R���ZVwz�BK�7�Wf���ȟ���R��w�uK5.��_��I�KД���w�����F*�b%Z�B��tf�gC� ٍ��i� l棋����B���#��e���h>�R��v�+x;-�w���к�NO��wC\��]P�f�� �`��8܂������O㇅��x�T$�.�,S>Q?5�j8d����i��k�-�M��گ��V����t<��rq=�n�����;��3���+T��ۃ��y�o}G^AK��}��?�����1n�,�1*u�p5��p��
�pe��R��<��9(.�83�˨N�
�F�n"���g�\�J� ªN/�I�#\��y�
��pY�X
�Qx)�K�Y�e
�a>�R����z
7�y�MP3�A�Y�(���'}�p�-U&)�G.��p�E9+���.�1\�|�'�p��<��2���)�Gy��������pZ��p�|2�C��%)�����WzS8�_ٙ����W�O��Cr,*�i
���^c����?�pe�N0�H��O���]7SI3�p���|������S8�c^��4�C�<4��p����1?�p'�;�o�pi��|�X��R8�������-��sj���aN--Ϡ���I��ˏ`�oI�|���tN-Ϧp�S��P�X�M��K������LᴞS�������3���:.���Z���/O�4}�ټX7�pP<�[�S`+��/F�����6�3PZ ��G�,e
�VHog%�BN
Z_
͆�e@ߍV�X�6(��K�o�tA�V(;hW@�߷2�2ڙR�|V��T�*�ڊQ `yPG;Z��߁�B]�?X�?�c,�~�9���n�y5��q�B�fj�Z�\��\��}q�V���X�\ҾxyNJ��c��V�nq{�6��g��VR9����G��u�ֳ�
z#Xڱ�[��Ж���\�)���CN���Zg[�U�ݴ�ֳ���6W�* ����R;�:��,]�:rN�W.^ѳ�E�D��뵼�|���EP�9�W���Y�%t�]m��(){�6��v���lDy��Jw�U��]���+Wt�.9� �ɡ�t������ΞnmI��f(��mE��z�
V,]�t9w';?��`H���9�����s�)u�����T��;ȽƽϽ�柗�����Z�ky��������8�����nO�\p9�5@OSz�+���2�>��hZ�+@㜄�C��z���Q�թ=��k<�;�a�I�Lc�5l�9?���������ʫ�����s9��Oy���I�D~
?����|=_yn�̟��{��ԺO2���p �97�lj=[��鎿+q&�����9�g�.fZ���d�l���\�_�����Q��п���[c�A{ d������?:�̀d*����"�C�a@&����;K{_�FQ$?�?�&?=�ז2X61 �J엓ْ�4P��"YR�L�B��%"t�i� ��{�{��.5<Yj�cC/C�@H@����XC_�Rx��O#m�������,�B腰�;��]8���G����5*���p�!�?q0���2��;`I+�k��]�A1n�@��ۀ�6��W�_X�XX?��K�P~;tz;td;4�O��:Z~�@��VC�����/�&������a��[�B(�m� p1����%����X����^5�朠�\
�]:��r>�g�z���vz��
Ja�S8+b�L(
P��Ҁ��3�oP�[���҃�M��P�J����
3����PL�;j��\�\`K����+YE+���7�KG.Ȼ��@N�u\&�OpÒp���/pw0��i�����hM0�K�kn�Ƹ[`na���/E5a.C �㍀mdB�
�m0k�`���Lm�Nm�C�Vȡ��P�]�:��h�]�S�r�C���W:�y90���C�o@1Ӟy��i��g�h.�>ȭ9_
u�\���S��W��2f���� �9wrj��E�� ������2���XM�T����!�$��
�n���2������ar(�(Ȼ�I'���� �]��yL����^���x�K,x�?��� }���䢃%��G�RH '���)��*��!���Q:T�[��_&�(�K=�I7���H9X�/_#/R'ϓ�`c�@��v!�/Q��_���~��5^$ϒ�����?��'���P&�������F%�F�5�C�)Dv�H�dG��Z`�� ;tO����s�9ŅŏsZ����Z���
d��K�ói��a���W�jF`Lt\�³�a-��d���L� �U���L��a#�^�!�WC�!\�R�!�@Xڤ(:��(:E'PtE'Pt2�N�zJ�-@�-��(Z��(Z�oP�0��h��h`
@�
@��(��(�:P�@�3
(t�ЁBg:P�@�3�b�(�b�(f�@Q�@Q�(���(��Ph@�1
(4�ЀBcPh@�1
+PX��
VFa
+PX���(�l~z P�#@q(��Fq(���8�(���8B���ռ$����b$�����C����C��w3f�
6B�@i��vh��v��3��@ic@�P�E(b@���E(b��(���(�EP�EP�1�>&�=(��\(��SC�Í2쵤�3�}��t��k�^�g�t=�W�
ע0�P��( ��@���*`&��: 산�K$��� R�g�i��K�#�$ {�#��3�]��%Q�#�V�'&�GA��[�s#<���<�VM��n�l9|�$�ێk_�w
�KxO���(�B�3M��
Ǎ�1<)pBE8wh�[�����I��G~ a/��!\�B)�B9,��7�Y�*_��!A�M �D�Mև� ?>� ѷ'�s����b���3<ߟ�(P���(�ZE�9�������%�3��<��h�����_jLx
�tn
qS8�?0�������aZ�ʁ�|܈��IQe'[
�&��T��2ʥ�ETȺ'@���}5�y��w��cA<>�y���]V/>�k�5*-����Q�\���.��?po`l���A���ʚ�\�
����@o�8�]x4�:pQ�50;���^��DM��<�?�N�Q��.�d]����@��"�/�����E�T�l}� g�����Al����2i�4Q
IYR��!9d�l�ͲQVeYe^&2����}#�!�����'�p+�O�|�`���P,��'�s&����bT�H�����1!4����~����H�������Ǥ���b|K��ȖA��6�M��OWz/F7��?�0�����&�q���T�'�*�j�ђz��+-�sь���sc�3�b�Id4�Ǯ��:=D,�4�v��)hj�;�e�l��w�6A���H���\
��<i��ɴ�Q�\ȡ\�(��P���&V�Ǵ�����ڽ���� t��9���)��{�aV*��FZ
7�4ֱ|VQ E
���VQ��bEg�䤊��)R�����2�dG�hG���?~�&G�@IφW�y����Ah�m_���]�i{7��~�;ܲh�r
[�b=���؆P������~�f��j��W��m����V�_��L
��6
TW5֜���3m5V�@eU��F�Vu�d���j�V
m���U�W����S�oh�+���' d��l��vN�=41���?�#�$2D�b��� �*�)��Y��h���Z{*˳ab�?�ʲB�-4�̋���?�S�Y�HE%�����AS�k���,��ܒh�~����ӳ�>z"���̩���?�#I�TKm��M�8��WQ�&�!3��ݴ9�E0�)]�K"}b�D���=��(�8;�F�Ǒ��E�}&k�r���=PT���R����+��$�m�����Q���/������Q��qH>
endobj
48 0 obj
<>
stream
x�]�M��0���
���1�+EH�d#��5�@`�"59�_���V�!��xf�0L��awÜ�cw�ٜ��G���؉9�e�u��y9鳻�S�����6����z�����m���Ǔ|�8��y��=���>M��*a6E�4��s��Wɵ��Ч�a~<�� �I�ӳ�J7�r��Nb.����1����$���yǒӹ��ƔjSjQ�]��)W���5�+�\2�W̷�Z������W�K����oʥ�n����o�w�h|�Z���AK�
�-��
L�����L�������W�����-�=,�+��ҿ�L,�k�Y�_���0+K��n�[�����17G�}��
����ҿ��� G�o�����W��`E��V�t�����aӆ ��8�J�X��h
endstream
endobj
49 0 obj
<>
endobj
50 0 obj
<>
stream
x��|y|T������yo�̼�,3�m�0I&�d#! �H��EH�$M ��lJW0*�*Z��X�*C�@�T\�jݪТ��J+�ׅ�߹�=bp����������L�;��{��s���tw�h+��E��s=�2<@��Vv˷\��[�> ��_�����?0�6_�l�⸟ `�>�K�����2V�EK�b]��a,�-Y�͘:�IJ��mQ�O�υqX��qu�n)��QX�[�7?s����3�m]݀��Mf����ԃ�%�yXG��^V$V�oD��l�������˰�T���H��s"K�ﰶȲ�;�*+Y�u5�B�
�v�x�WI��� �_�4��p�l� �j�?�<���o<��q�s�ybC�́��t�=�#��j�%q���W��` �)�1�����p�D֚����y�p'q� ؠޅ�(_6E�ˡ��o���7�(���ws�(��p�z���YǒCt�� ��&�T���p?_������͆||O3�fx��Ӱ�p����v�������"K"+#����hj4/�=HE�5���Q'��w�
�a���?�to�-x%�� q$���D�з����jrZ�Nr7��K���I�9F�@^$���/�}�wr�r�C��OC��.���}3���n�Ϣ����+�4=�I�0.���RnW��p��c|<�BmW�+��Q��������j�d�5����[
�G�5���!�
77
;���"�z��n�g��qF�q���"�xH���Aj�S����Ԓ
d6�!=��h~�w�=t3
�]�S(�Y��A��j�{��ã������U�h�H;zWl�r:�`X ��Q�1wc�˨��d�S����
Gl�i�{�5�{��
~D�
|!OP�k0�o�n�"�;�ŝ�]�������p���>$�t�ed
�!��b���d}_�(�B��28L~L�r����!��'�.�L���t�Ѩ�5W��؉���m\?<:/� ����o�z�'�H["�*2��Í ]��|N�I&zгtG�}����o�C_�?���w{�-nWd}��E�h̠��G���_�W1�>���\+����@>�����0F��4@ޠ
�����6I�cL����B��0.z��;z4z�$�~ُq��'i��ů1�\�q��yX��6|������c�ڊ�t+���/^ƨq�߄�q��oP��=(�Y�-��3b�}��g�
���������G����b�0���0���h1��V[`/y�~���V��^V:ftɨ��#�rs��B�ᙁ��4�0��MMINJ��] �q�N�d��X-f�Q<��dU�'6�ጆ0��<9����X�8��!,c��Ky�r��&_ʩ ��p*�2�I$�J���
�~a�_ �g� }��>���T��P1X����\�^2A��"l���K �KF�I�w47k핳��3���=
�n+g_R��G
���P�a>55ŏ7s~
��?C�DEK�d�a(c8v|
�Dk5�&q�P�Gf�+�OT�o
s�j�'����ڳ���}k��8��@�,륢/��K
�]ZsI��=��g����{z̗�M���3�/O�i�i��_�%�>����W4\��@t��Iቷ��"����������{�q���}ު6ή��t|Cymm6e�ü�]�D(}���q��W�`���,���c����I�^(�.�+�v�ʐ���Lj<���H����C_(�d���==%L1�>2{��C}�%���!�#���eZJ�)\�eC����n����T*R"P���D%Ε(�J^I��������(�(��[M�H�ȶ�{������t�
}��Iu�;e�w%q��L
��n�
Ч�Q�jg�}N1L�N����!�g56��$TB�r%��T�6L��:����2����h5l&�0�g�� � ��8v�=�����`��$��i�n�;���0s�>�0�C!�5Y�qF:_��su��9J�:rO�-����ɺ��X�[Wz����,q�l��ߗ�F�:�u
'�~9��Y\��ː��&��������bw#���;�{w��������DHA~�T�����\�?o|~jv���_��r�5��W��������;#�}|ߞ�י��Q����'��t�ni:½a��U��ab X]�tȈ�u�T��,��6�]�@��#1G��9�����6~��E��r16����1�f��g���n6
��/Lt��|�vYa�@$�$�Z�8d�4��E*nڍj�̈́:��*;�o���tIPu�q��3R��u���N�{tܲ3e�9!T'))aE�6F�v�R;�O,*�w�L�����L��-��Nj
dM�knpb����S�l����cV67�/�{��J�l��������Κ�Ip�N�5�F��ww���G�? g�.p����~C��H(�� �M[�-�a�x��1R#��a�=��Ǹ釜��p�(5��ǩA!���r۹0�q��~�g$7��+6�~��D3���}���]T�
{ER��o2���o���:B'/����o��PǠ���Ri)�y��YG�5���ȍ�[9�J�oEN�G���=��)C-�̎���;ғ���֪���ɫ��1����I5�թ�S G���}q��mAsf�*g{*�ɩ4�b�I��Xu�p6v�l#q6��96`�$,�
�K�����9��z�m'aBE���xC�&�*��Q2�Ƴh�wR�k���3�ܫ��gB��� �ӥ���mR��yQG]��|ł��Q8��+�G�
��/z�����w��x��g^Y�E�_w͞�a������r܉7�䞝4��;�/}��kS�4jL���?�=�#I�r�\D6�nȥE��1�æ�Wf�( �ǞA�$ב��E\O����r�嫋Ve�ݘ�!�0:gR����Y5nC ��3*v��$dȎ�O�V��C`u[�ݜǒ��$[�|�1�3�Y�lq.�\���%�N_v��9��~��L[���HK�Rm"�`�hI Jbr^��ܞ|,�x�!هA�ˎͦg�I6�'��2��U�w�XIF�g�,^�v|�����E�Ҕ�>����S��O�v����@6��J�T�ѩ,�'Zg:
h�����a`��y���`�e����ivB�v'�0�ջH�Kqu���]���g�!�X0�M;s��L#;ϝ���Y��>�ĥ��=Ӂ��
i,�a8���P��b.��#����ҋ���ǡw�ǹ|}�3����`kU]��������w/vݑ�|�}�n���P�:eZ-!��W�s'��U�@?uoھcUw}��Y��N�|h�{c�Ҵ��e��E!1?�����E-@��#K�W�$H�ϕۧ�LvNL�H^�4��L�Wˋ���p��n��߾���|�؎H���m��$�fNK�F��̎g�3H�X���n�}�k�g�$ۥa�a�����=?����
u�jo%.�E�d;&����v��JT�p� 3˗I����E���@Z�hq���!#��wo{�V�
�M�[�����bl��n ��#���*��Wez6�8�)r�����)Y��W�<7���^�n����)��@f��y٘Y+�x�A���F�5|�7�$�Sr���(6�.�+d
�Cq�
U�I�����|�S^�lU�zL!�%ʼn���˅2P�ɋU�͛ ��$��ԓm�#��31�Q�sJ
9�B�%�:�!�OI�T�j�A�lU��(��%�n�Z�Q��B�&:YWv�\]�~��-e�/�c�3�k�
�j�W����G�?'���ȶ7�o&��3�����3o-�(v��B"<����9�����D�9ϳ�t8
3��$�Ou�b~�g��l�EbƗ�ݥ�Y��I+yX�
�,1i�F�2�PP*
wGZ/lvQ�g� Y��
㒒 '��4�0�9��}'i�4U/u����+DՂ��"��+�/��9,#�h�E�Hq�Z2��? ����[Nwr���W�[��{+�;�>�?��oD"����$����zcA��͛q�)�G��g�8Q���`�1�e��N۾�B�Ѝ�Vg7d���և���i}���817���>�mH��;ӓ�S2�g���D,�9����W�Y0�9)iR�\�<���
�&�-����������ߟ�S�ehw��������I{S��O�3�#�3�O%?���H�H�^�}=�Oɯ�o��<
����O% ��;���:�fr4��e��
��.I1�N�#N���p.Hb0�;��&)9YNI�KII%����P$�#9%%2��f�?��
��)�$�<3�uУx�O(�䙹)�z4���O`B�侠z?T��B�!D�B�!ڔ�p��B�eӄ�v��dG�9�b�qK�V�R O,��~�l�q�ltBK4�,�����QO81�$�?jгGO�I%q*��P�@�,�$D�J%�[*!!�UK�����z����X��/iAPK�X��{^}����m�6%o����),\:��Ps��ͮ��ܦ�$k�bv��nkSM�����.���\-et��}$�^���Z8-m]č9���#=d��Y�+�QE��w9���y(yXzS|O|O�O�i����t$��
���X���|�q��_�(�o�?�Ow��c���tH3g�p���dy�����_���qk�k�k$n�yR�<3G]n7^��V��l1���b���8� n��8�,V��cvbb��b��G�̴���^+���R�z�J��\k������:@��{f��x6%Z]�1��5�`�Ё�_s �C����s�A�^6�+�Uk���"2k�GO8�G���տjp��#���x����}?r���q�˶fəW0���TnY;���WlH,.�j���1Ʈ�ێ6t�L^U~����./q�j�s�팉�5J�3�lL4{-n�'>��k��i�� �^��7L5����>��x���o�l��8�jq�s���'�/L;bb�����u�{����O����<��7!����Wzn�d���L���>T\@$LOh5��"8S���y#��#V�=�#����H���^�1��������q�����n��&� � %� \��ar�
8d�v�8k�����k�ə�����87���i"�y���%�~�a����d��ɲ3,)�s)�%%)�pJaII�2��>���-�P�YJ�sU����)����f0�5��LZɤ�lji�M��|�2��c`Г������/��G��ی����W"��� �O���\U[{���w����ǡ��&��_���?^[� ּr��7`�=�Ɇ-�W>��6sos�G\<���ǖ7x��&�F�M��X�s1ܽ���S�k�I^���q=G��دKD�$�h��!8DIJp�6����o'''������m�k��pXz����:�#<�q��~�}�09
��~�o1n1m��j��za��^�y*�I���T/3f�d)͑���i:'��'�P��w'$p.D#o��[�@��m��lsH�����y�YХ�_���fx��;�Y��X���0K��#c���^�DE�x�.��ψ�U��<�
�x��5ޒ֛N8��i�z(�\�!a?�I<�(NM�N��<)��Z�/�w�s'1a�V�ɖ�O;��bw�I��G�=��ڠ�Q�.
E�^�!M�����t�@�s���ݵ8vk�m~2e��p�'X{y���w���r3^��T�����5_���}Œ{������b��g�������/f,������>�����.��862��D��%?y�v�,�G�(�%0��+�A�����G�m8�ź�b
LA<�Vѝ��( .r?U�k�5����^�qq��{����%��嗠�}��SJ ra��!��;��Ž����R���Ϭ�8�Wt�4��G�y�Y�F �8uZ�4���"f��u�yԦ�&�cu:��Oj��Щ��_�4��W:�A��1���ax_�
`7|��8�N�P'$����6A����!s�W؏�إ��X��_៤j�뒈<͗���\�4\���c�=UkMd�t�$�6��#w�g]�`�(�7����sՖ��kF��9&��+Փ����������V�1��@�3
z���W��zD���z�i�V��'����c��|?�W���J�d>k~���_����B'�2�o�������+Y����å���6�J5"�#զ��6Ҩ��֯h��Z�l���bq�_8?Ƣ�����r5ⷨѲ�ШZ���M^�o��U?���מ�y�@@��J
���_��G\�ou2<�?�@�}c�b��X���k��`=kLJ��8�4l�ɷ����:�8(�g�f�(v��r���aކ'�J,W�_sS�Ǐ�_w������g�6OjJa��sGh8��t�؊�e����
jwSl~�87���<��y�(��"P����P�Ѐ�m��m���M�>��7U_��~��_=N�&�����d�= v���NV�M�7I��}�C��>e\�F����[�����8�C��Ny�MP��!G8� �a;BG��{�
��a�^��E���S�<��UZ�yvAX�}�Ñ�J�S���EzP8(���n�n���J��]��u�qu\9*�T��,WMY�/�z������"X�@��O/�)C�B،�
� �v㓨|y���Q$Z��Bu�B�)D���YQ[��X7��\9-�w�i!j��>�HU��]$��H�b��f�O�3Y=�?���M�����F>Hc�lF��6��Gwi|^�b|�!�{xU>�{���Ʒ�E���G�U?@����!<�H=�!WZ�Ƶ��3.R��θ�!u�@Yr*I��:P�$�,�_��t��A�z��/Y���"�YB��WsyEˬrRY]����h8Aj�zF�g쎤��"�XB�a��d�`
�&"�����&��<��`���){\�8ք>Ϛl�Л��%�'�MV;p�oZBWWw�kh�7r�k/pW�L���:��+T���f��� ��
������k��bEXi�P�u9�8N��c2!n�Pۥ�B�+�C�ok�
f
�
�
&
f
�
�
��
�
��
�
���Ǚ�|n���mS�mx|�
S
tOs�Og��u%��t@}�
.Q�*ؐW-�pŬ��ִ"D�.V��C���
endstream
endobj
51 0 obj
11404
endobj
52 0 obj
<>
endobj
53 0 obj
<>
stream
x�]��n�0E��
/��A�"E�()�>����Zj�1��}=3����u&s�ľNͱ�&$o~T-��=L��+��+�\j�½�]
�I���`hl?��H�co
~���/� �W��{���C����`�LEUI
}��ܹ�n��\�FǶ �2Z��ف̩��(j�0�N���D���,�`��^�f˥W����,JӴ�V�s�m��"���yM����N�-s���sH�c^!��_�O����G�#� �ļF�yNA��������&���=e�)���F�.Z��u�o
endstream
endobj
54 0 obj
<>
endobj
55 0 obj
<>
stream
x���oTUǿ���iA��Z,R�BYP;� &$H����c�4��睙g߯���7��q�?�����Ą.X�Jw���.�`Q����3m���;��>��=��sߛI�Ta76`BڞN
�o1a_K�rfA�ȩ�tۍ�??�}��Ֆ�>�}���8L�d���7���D�p�K�_��n��G���&1G4>�T��a��'�[��滟h���A���Q�k�
A^�K��|,�@�}�l��z�R~�R�tLl�x�R���N��n=��.�y���'+r��y��_���[bL�s���^ט��z��?z�������w��`��?xa4��~�Q}{!�uV�sf=��u#���m����(��RV��F�0�O�008�k^_
�Ls
>�Ӛ
vaF�I�k��75���\��r�9��f�]X�l��5�&��i�+��s͙��f/��&&�[��8U�f��>��Ĕfe1���i�8�Y`T�4����ċ�˹���М��B�� �f��{�(�}Z��Y`���30i6�j.��k.‱��D��}L���;%R_^r�(��q��X^���ˡ���r�^Q�Ե�-��U;�/��������Z;���[�++I#_t�}�5��<�i�����&�e2̳�n�P�DŲ�:�^�*�ͷTQÉ��=�l���ZQN���?W�M�5Ř���؊7�<���n>��#k��ʤU?ZK�DI��A@�Η����γ%��{*Zy���0���)��P��G+�j�d�|O����)�R��^��X�1��&P�x�����Y�T!}>W�Y���z�����ڝ;���D������2{�����_����2�
endstream
endobj
56 0 obj
862
endobj
57 0 obj
<>
endobj
58 0 obj
<>
stream
x�]�Ak�0���s�=,Q�7�e�C���? &�
�I���1k[�!�����Mt�=u�~�`{L0zr�KX�"8yRe��t����D����%����Z�7���]���� Nm/�_c��)A���rϳ�/fF��K���i��x�"B�uy�b��%�lhBUE���($��;�a���%YJ�zh���t���~ڀ]��I�=W�����Cܩ����m�
endstream
endobj
59 0 obj
<>
endobj
60 0 obj
<>
endobj
61 0 obj
<>
endobj
1 0 obj
<>/Contents 2 0 R>>
endobj
4 0 obj
<>/Contents 5 0 R>>
endobj
7 0 obj
<>/Contents 8 0 R>>
endobj
10 0 obj
<>/Contents 11 0 R>>
endobj
13 0 obj
<>/Contents 14 0 R>>
endobj
16 0 obj
<>/Contents 17 0 R>>
endobj
19 0 obj
<>/Contents 20 0 R>>
endobj
62 0 obj
<>
endobj
63 0 obj
<
/Dest[1 0 R/XYZ 56.7 773.3 0]/Parent 62 0 R/Next 64 0 R>>
endobj
64 0 obj
<
/Dest[1 0 R/XYZ 56.7 654.5 0]/Parent 62 0 R/Prev 63 0 R/Next 65 0 R>>
endobj
65 0 obj
<
/Dest[1 0 R/XYZ 56.7 275 0]/Parent 62 0 R/Prev 64 0 R>>
endobj
66 0 obj
<
/Dest[4 0 R/XYZ 56.7 338.9 0]/Parent 65 0 R/Next 67 0 R>>
endobj
67 0 obj
<
/Dest[7 0 R/XYZ 56.7 639.9 0]/Parent 65 0 R/Prev 66 0 R/Next 70 0 R>>
endobj
68 0 obj
<
/Dest[7 0 R/XYZ 56.7 549.6 0]/Parent 67 0 R/Next 69 0 R>>
endobj
69 0 obj
<
/Dest[7 0 R/XYZ 56.7 207.3 0]/Parent 67 0 R/Prev 68 0 R>>
endobj
70 0 obj
<
/Dest[10 0 R/XYZ 56.7 620.4 0]/Parent 65 0 R/Prev 67 0 R/Next 71 0 R>>
endobj
71 0 obj
<
/Dest[10 0 R/XYZ 56.7 379.4 0]/Parent 65 0 R/Prev 70 0 R/Next 72 0 R>>
endobj
72 0 obj
<
/Dest[10 0 R/XYZ 56.7 150.5 0]/Parent 65 0 R/Prev 71 0 R/Next 73 0 R>>
endobj
73 0 obj
<
/Dest[13 0 R/XYZ 56.7 685.2 0]/Parent 65 0 R/Prev 72 0 R/Next 74 0 R>>
endobj
74 0 obj
<
/Dest[13 0 R/XYZ 56.7 365.4 0]/Parent 65 0 R/Prev 73 0 R/Next 75 0 R>>
endobj
75 0 obj
<
/Dest[16 0 R/XYZ 56.7 544.5 0]/Parent 65 0 R/Prev 74 0 R/Next 76 0 R>>
endobj
76 0 obj
<
/Dest[19 0 R/XYZ 56.7 751.7 0]/Parent 65 0 R/Prev 75 0 R/Next 77 0 R>>
endobj
77 0 obj
<
/Dest[19 0 R/XYZ 56.7 516.7 0]/Parent 65 0 R/Prev 76 0 R>>
endobj
24 0 obj
<>
endobj
22 0 obj
<>
>>
endobj
23 0 obj
<>
>>
endobj
78 0 obj
<>
endobj
79 0 obj
<
/Creator
/Producer
/CreationDate(D:20100126131554+01'00')>>
endobj
xref
0 80
0000000000 65535 f
0000124915 00000 n
0000000019 00000 n
0000002835 00000 n
0000125077 00000 n
0000002856 00000 n
0000005207 00000 n
0000125221 00000 n
0000005228 00000 n
0000007868 00000 n
0000125365 00000 n
0000007889 00000 n
0000010519 00000 n
0000125511 00000 n
0000010541 00000 n
0000012784 00000 n
0000125657 00000 n
0000012806 00000 n
0000015156 00000 n
0000125803 00000 n
0000015178 00000 n
0000018460 00000 n
0000129189 00000 n
0000129339 00000 n
0000129049 00000 n
0000018482 00000 n
0000041670 00000 n
0000041693 00000 n
0000041889 00000 n
0000042463 00000 n
0000042881 00000 n
0000053828 00000 n
0000053851 00000 n
0000054057 00000 n
0000054416 00000 n
0000054645 00000 n
0000079715 00000 n
0000079738 00000 n
0000079928 00000 n
0000080524 00000 n
0000080959 00000 n
0000091311 00000 n
0000091334 00000 n
0000091532 00000 n
0000091923 00000 n
0000092173 00000 n
0000109817 00000 n
0000109840 00000 n
0000110035 00000 n
0000110521 00000 n
0000110849 00000 n
0000122340 00000 n
0000122363 00000 n
0000122567 00000 n
0000122928 00000 n
0000123154 00000 n
0000124102 00000 n
0000124123 00000 n
0000124314 00000 n
0000124606 00000 n
0000124767 00000 n
0000124860 00000 n
0000125967 00000 n
0000126024 00000 n
0000126262 00000 n
0000126488 00000 n
0000126719 00000 n
0000126941 00000 n
0000127137 00000 n
0000127271 00000 n
0000127425 00000 n
0000127596 00000 n
0000127787 00000 n
0000127946 00000 n
0000128133 00000 n
0000128316 00000 n
0000128671 00000 n
0000128890 00000 n
0000129489 00000 n
0000129604 00000 n
trailer
<
]
/DocChecksum /2E62DB36A078CD319BDB4CFA61AE408B
>>
startxref
129849
%%EOF
miglayout-5.1/src/site/resources/docs/cheatsheet.html000077500000000000000000001655201324101563200231020ustar00rootroot00000000000000
MiG Layout Cheat Sheet
MiG Layout Cheat Sheet
Note! Italics is used to denote an
argument. Square brackets are used to indicate an optional
argument. UnitValue A value that
represents a size. Normally it consist of a value (integer or float)
and the unit type (e.g. "mm"
). MigLayout
support defining custom unit types and there are some special ones
built in. These are listed below and some have a context to which
they can appear. UnitValues can be quite rich expressions, like:
"(10px + 0.25*((pref/2)-10))"
.
The currently supported unit types are:
"" - No
unit specified. This is the default unit and pixels will be used by
default. Default unit can be set with
PlatformDefaults.setDefaultHorizontal/VerticalUnit(int)
. E.g. "10"
px - Pixels.
Normal pixels mapped directly to the screen. E.g. "10px"
or "10"
% - A percentage
of the container's size. May also be used for alignments where for
instance 50%
means "centered". E.g. "100%"
lp - Logical
Pixels. If the normal font is used on the platform this maps 1:1 to
pixels. If larger fonts are used the logical pixels gets
proportionally larger. Used instead of Dialog Units. E.g. "10lp"
pt - Points.
1/72:th of an inch. A unit normally used for printing. Will take the
screen DPI that the component is showing on into account. E.g.
"10pt"
mm - Millimeters.
Will take the screen DPI that the component is showing on into
account. E.g. "10mm"
cm - Centimeters.
Will take the screen that the component is showing on DPI into
account. E.g. "10cm"
in - Inches. Will
take the screen DPI that the component is showing on into account.
E.g. "10.4in"
sp - Percentage
of the screen. Will take the pixel screen size that the component is
showing on into account. 100.0
is the right/bottom edge
of the screen. E.g. "sp 70" or "sp 73.627123"
al - Visual
bounds alignment. "0al"
is left aligned,
"0.5al"
is centered and "1al"
is right aligned. This unit is used with absolute positioning. E.g.
"0.2al"
n/null - Null value. Denotes the absence of
a value. E.g. "n" or "null"
These are the unit values that are converted to pixels by the
default PlatformConverter
. The converted pixel sizes can
be different for the vertical and horizontal dimension.
r/rel/related -
Indicates that two components or columns/rows are considered
related. The exact pixel size is determined by the platform default.
E.g. "r" or "related"
u/unrel/unrelatedated
- Indicates that two components or columns/rows are considered
un related. The exact pixel size is determined by
the platform default. E.g. "u" or "unrelated"
p/para/paragraph
- A spacing that is considered appropriate for a paragraph is used.
The exact pixel size is determined by the platform default. E.g.
"para" or "paragraph"
i/ind/indent - A spacing that is considered
appropriate for indent. The exact pixel size is determined by the
platform default. E.g. "i" or "indent"
These are the unit values that can be specified as a reference to
component(s) sizes. These can be used on column/row
constraint's size and as a reference in component constraint
expressions.
min/minimum - A
reference to the largest minimum size of the
column/row. E.g. "min" or "minimum"
p/pref/preferred
- A reference to the largest preferred size of the
column/row. E.g. "p" or "pref" or
"preferred"
max/maximum - A reference to the smallest
maximum size of the column/row. E.g. "max" or
"maximum"
These are the unit values that can be specified for a component's
width. These can only be used on the width
component constraints size.
BoundSize A bound size is a size that optionally
has a lower and/or upper bound and consists of one to three Unit
Values. Practically it is a minimum/preferred/maximum size
combination but none of the sizes are actually mandatory. If a size
is missing (e.g. the preferred) it is null and will
be replaced by the most appropriate value. For components this value
is the corresponding size (E.g. Component.getPreferredSize()
on Swing) and for columns/rows it is the size of the components in
the row (see min /pref /max
in UnitValue above).
The format is "
min
:
preferred
:
max
"
,
however there are shorter versions since for instance it is seldom
needed to specify the maximum size.
A single value (E.g. "10"
) sets only the
preferred
size and is exactly the same as
"null:10:null"
and ":10:"
and "n:10:n"
. Two values (E.g. "10:20"
)
means minimum and preferred size and is exactly the same as
"10:20:null"
and "10:20:"
and "10:20:n"
The use a of an exclamation
mark (E.g. "20!"
) means that the value should
be used for all size types and no colon may then be used in the
string. It is the same as "20:20:20"
.
push can be appended to a gap to make that gap
"greedy" and take any left over space. This means that a
gap that has "push"
will be pushing the
components/rows/columns apart, taking as much space as possible for
the gap. The gap push is always an addition to a BoundSize .
E.g. "gap rel:push"
, "[][]push[][]"
,
"10cm!:push"
or "10:10:10:push"
.
Note! For row/column constraints the minimum ,
preferred and maximum keywords can
be used and they refer to the largest minimum, preferred and maximum
component in the column/row. A null
value is the same
thing as any of these constraints, for the indicated position, but
they can for instance be used to set the minimum size to the
preferred one or the other way around. E.g. "pref:pref"
or "min:min:pref"
.
AlignKeyword For alignment purposes these
keywords can be used: t/top , l/left ,
b/bottom , r/right , lead/leading ,
trail/trailing and base/baseline .
Leading/trailing is dependent on if component orientation is
"left-to-right" or "right-to-left". There is also
a keyword "align label"
or for columns/rows
one need only to use "label".
It will align
the component(s), which is normally labels, left, center or right
depending on the style guides for the platform. This currently means
left justified on all platforms except OS X which has right justified
labels.
Layout Constraints
Layout constraints and normally set in
the constructor of MigLayout and is constraints that will affect the
whole container.
wrap
[
count
]
Sets auto-wrap mode for the layout. This means that the grid
will wrap to a new column/row after a certain number of columns
(for horizontal flow) or rows (for vertical flow). The number is
either specified as an integer after the keyword or if not, the
number of column/row constraints specified will be used. A
wrapping layout means that after the count
:th
component has been added the layout will wrap and continue on the
next row/column. If wrap is turned off (default) the Component
Constraint's "wrap"
and "newline"
can be used to control wrapping.
"wrap" "wrap 4"
gap
gapx
[
gapy
]
gapx
gap
gapy
gap
Specifies the default gap between the cells in the grid and are
thus overriding the platform default value. The gaps are specified
as a BoundSize . See above.
"gap 5px 10px" "gap unrel rel" "gapx 10::50" "gapy
0:rel:null" "gap 10! 10!"
debug
[
millis
]
Turns on debug painting for the container. This will lead to an
active repaint every millis
milliseconds. Default
value is 1000 (once every second).
"debug" "debug 4000"
nogrid
Puts the layout in a flow-only mode. All components in the flow
direction will be put in the same cell and will thus not be
aligned with component in other rows/columns. For normal
horizontal flow this is the same as to say that all component will
be put in the first and only column.
"nogrid"
novisualpadding
Turns off padding of visual bounds (e.g. compensation for drop
shadows)
"novisualpadding"
fill fillx
filly
Claims all available space in the container for the columns and/or rows. At least one component need to have a "grow"
constraint for it to fill the container. The space will be divided equal, though honoring "growpriority"
. If no columns/rows has "grow"
set the grow weight of the components in the rows/columns will migrate to that row/column.
"fill" "fillx" "filly"
ins/insets
["dialog"] ["panel"] [
top/all
[
left
] [
bottom
]
[
right
]]
Specified the insets for the laid out container. The gaps
before/after the first/last column/row overrides these layout
insets. This is the same thing as setting an EmptyBorder
on the container but without removing any border already there.
Default value is "panel"
(or zero if there
are docking components). The size of "dialog"
and "panel"
insets is returned by the
current PlatformConverter
. The inset values all
around can also be set explicitly for one or more sides. Insets on
sides that are set to "null"
or "n"
will get the default values provided by the PlatformConverter
.
If less than four sides are specified the last value will be used
for the remaining side. The gaps are specified as a UnitValue .
See above. Note that the default insets is "panel
"
"insets dialog" "ins 0"
"insets
10px n n n" "insets 10 20 30 40"
flowy
Puts the layout in vertical flow mode. This means that the next
cell is normally below and the next component will be put there
instead of to the right. Default is horizontal flow.
"flowy"
al/align
alignx
[
aligny
]
aligny
/
ay
align
aligny
/
ax
align
Specifies the alignment for the laid out components as a group.
If the total bounds of all laid out components does not fill the
entire container the align value is used to position the
components within the container without changing their relative
positions. The alignment can be specified as a UnitValue
or AlignKeyword . See above. If an AlignKeyword
is used the "align"
keyword can be
omitted. Note that baseline alignment does not work since this
is not for single components.
"align 50% 50%" "aligny top" "alignx
leading" "align 100px" "top, left"
ltr
/
lefttoright
rtl
/
righttoleft
Overrides the container's ComponentOrientation
property for this layout. Normally this value is dependent on the
Locale
that the application is running. This
constraint overrides that value.
"ltr" "lefttoright" "rtl"
ttb
/
toptobottom
btt
/
bottomtotop
Specifies if the components should be added in the grid
bottom-to-top or top-to-bottom .
This value is not picked up from the container and is
top-to-bottom by default.
"ttb" "toptobottom" "btt"
hidemode
Sets the default hide mode for the layout. This hide mode can
be overridden by the component constraint. The hide mode specified
how the layout manager should handle a component that isn't
visible. The modes are:0
- Default. Means that
invisible components will be handled exactly as if they were
visible.1
- The size of an invisible component
will be set to 0, 0
.2
- The size of
an invisible component will be set to 0, 0
and the
gaps will also be set to 0
around it.3
- Invisible components will not participate in the layout at all
and it will for instance not take up a grid cell.
"hidemode 1"
nocache
Instructs the layout engine to not use caches. This should
normally only be needed if the "%"
unit is
used as it is a function of the parent size. If you are
experiencing revalidation problems you can try to set this
constraint.
"nocache"
Column/Row Constraints
Column and row constraints works the same and hence forth the term
row will be used for both columns and rows.
Every [] section denotes constraints for that row. The gap size
between is the gap size dividing the two rows. The format for the
constraint is:[constraint1, constraint2, ...]gap
size[constraint1, constraint2, ...]gap size[...]..."
Example:
"[fill]10[top,10:20]"
, "[fill]push[]"
,
"[fill]10:10:100:push[top,10:20]"
.
Tip! A vertical bar "|"
can be used instead of "]["
between rows if
the default gap should be used. E.g. "[100|200|300]"
is the same as "[100][200][300]"
.
Gaps are expressed as a BoundSize (see above) and
can thus have a min/preferred/max size. The size of the row is
expressed the same way, as a BoundSize . Leaving any
of the sizes out will make the size the default one. For gaps this is
"related"
(the pixel size for "related"
is determined by the PlatformConverter
) and for row size
this is the largest of the contained components for minimum and
preferred size and no maximum size. If there are fewer rows in the
format string than there are in the grid cells in that dimension the
last gap and row constraint will be used for the extra rows. For
instance "[10]"
is the same as "[10][10][10]"
(affects wrapping if wrap is turned on though) .
Gaps have only their size, however there are number of constraints
that can be used between the [ ]
and they will affect
that row.
":push"
(or "push"
if used with the default gap size) can be added to the gap size to
make that gap greedy and try to take as much space as possible
without making the layout bigger than the container.
Note! ""
is the same as
"[]"
which is the same as "[pref]"
and "[min:pref:n]"
.
sizegroup
[
name
]
sg
[
name
]
Gives the row a size group name. All rows that share a size
group name will get the same BoundSize as the row
with the largest min/preferred size. This is most usable when the
size of the row is not explicitly set and thus is determined by
the largest component is the row(s). An empty name ""
can be used unless there should be more than one group.
"sg" "sg group1" "sizegroup
props"
fill
Set the default value for components to "grow"
in the dimension of the row. So for columns the components in that
column will default to a "growx"
constraint
(which can be overridden by the individual component constraints).
Note that this property does not affect the size for the row, but
rather the sizes of the components in the row.
"fill"
nogrid
Puts the row in flow-only mode. All components in the flow
direction will be put in the same cell and will thus not be
aligned with component in other rows/columns. This property will
only be adhered to if the row is in the flow direction. So for the
normal horizontal flow ("flowx"
) it is only
used for rows and for "flowy"
it is only
used for columns.
"nogrid"
grow
[
weight
]
Sets how keen the row should be to grow in relation to other
rows. The weight (defaults to 100 if not specified) is purely a
relative value to other rows' weight. Twice the weight will get
double the extra space. If this constraint is not set, the grow
weight is set to zero and the column will not grow (unless "fill"
is set in the Layout Constraints and no other row has grow weight
above zero either). Grow weight will only be compared to the
weights for rows with the same grow priority. See below.
"grow 50" "grow"
growprio
prio
Sets the grow priority for the row (not for the components in
the row). When growing, all rows with higher priorities will be
grown to their maximum size before any row with lower priority are
considered. The default grow priority is 100. This can be used to
make certain rows grow to max before other rows even start to
grow.
"growprio 50"
shrink
weight
Sets how keen/reluctant the row should be to shrink in relation
to other rows. The weight is purely a relative value to other
rows' weights. Twice the weight will shrink twice as much when
space is scarce. If this constraint is not set the shrink weight
defaults to 100, which means that all rows by default can shrink
to their minimum size, but no less. Shrink weight will only be
compared against the weights in the same shrink priority group
(other rows with the same shrink priority). See below.
"shrink 50" "shrinkweight 0"
shrinkprio
prio
shp
prio
Sets the shrink priority for the row (not for the components in
the row). When space is scarce and rows needs to be shrunk, all
rows with higher priorities will be shrunk to their minimum size
before any row with lower priority are considered. The default
shrink priority is 100. This can be used to make certain rows
shrink to min before other rows even start to shrink.
"shrinkprio 50" "shp 110"
align
align
al
align
Specifies the default alignment for the components in the row.
This default alignment can be overridden by setting the alignment
for the component in the Component Constraint. The default row
alignment is "left"
for columns and
"center"
for rows. The alignment can be
specified as a UnitValue or AlignKeyword .
See above. If AlignKeyword is used the "align"
part can be omitted. Note that baseline alignement does not
work if the component can't get its preferred size in the vertical
dimension.
"align 50%" "align top" "al
leading" "align 100px" "top,
left" "align baseline"
gap
gapbefore
[
gap
]
gapbefore
gap
gapafter
gap
Specifies the gap before and/or after the row. The gap are
specified between the row constraints (between "]
["
). "gapleft", "gapright",
"gaptop", "gapbottom"
can also be used.
"gap 10 20" "gap 10:20:30
10px:20%:30in" "gapbefore 10px, gapafter
20px"
Component Constraints
Component constraints are used as an argument in the
Container.add(...)
for Swing and by setting it as
Control.setLayoutData(...)
in SWT. It can be used to
specify constraints that has to do with the component's size and/or
the grid cell flow. The constraints are specified one by one with
comma signs as separators. E.g. "width 100px!, grid 3
2, wrap"
.
wrap
[
gapsize
]
Wraps to a new column/row after the component
has been put in the next available cell. This means that the next
component will be put on the new row/column. Tip! Read wrap as
"wrap after". If specified "gapsize"
will override the size of the gap between the current and next row
(or column if "flowy"
). Note that the gaps
size is after the row that this component will
end up at.
"wrap" "wrap 15px" "wrap
push" "wrap 15:push"
newline
[
gapsize
]
Wraps to a new column/row before the component
is put in the next available cell. This means that the this
component will be put on a new row/column. Tip! Read wrap as "on
a newline". If specified "gapsize"
will override the size of the gap between the current and next row
(or column if "flowy"
). Note that the gaps
size is before the row that this component will
end up at.
"newline" "newline 15px" "newline
push" "newline 15:push"
push
[
weightx
][
weighty
]
pushx
[
weightx
]
pushy
[
weighty
]
Makes the row and/or column that the component is residing in
grow with "weight"
. This can be used
instead of having a "grow" keyword in the column/row
constraints.
"push" "pushx 200" "pushy"
skip
[
count
]
Skips a number of cells in the flow. This is used to jump over
a number of cells before the next free cell is looked for. The
skipping is done before this component is put in a cell and thus
this cells is affected by it. "count"
defaults to 1 if not specified.
"skip" "skip 3"
span
[
countx
]
[
county
]
spany
/
sy
[
count
]
spanx
/
sx
[
count
]
Spans the current cell (merges) over a number of cells.
Practically this means that this cell and the count
number of cells will be treated as one cell and the component can
use the space that all these cells have. count defaults
to a really high value which practically means span to the end
or the row/column . Note that a cell can be spanned and
split at the same time, so it can for instance be spanning 2 cells
and split that space for three components. "span"
for the first cell in a row is the same thing as setting "nogrid"
in the row constraint.
"span" "span 4" "span 2
2" "spanx 10" "spanx 2, spany 2"
split
[
count
]
Splits the cell in a number of sub cells. Basically this means
that the next count
number of components will be put
in the same cell, next to each other with defait gaps. Only the first
component in a cell can set the split, any subsequent "split"
keywords in the cell will be ignored. count
defaults
to infinite if not specified, which means that "split"
alone will put all subsequent components in the same cell. "skip"
,
"wrap"
and "newline"
will break out of the split cell. The latter two will move to a
new row/column as usual. "skip"
will skip
out if the splitting and continue in the next cell.
"split" "split 4"
cell
col
row
[span x [span y]]
Sets the grid cell that the component should be placed in. If
there are already components in the cell they will share the cell.
If there are two integers specified they will be interpreted as
absolute coordinates for the column and row. The flow will
continue after this cell. How many cells that will be spanned is
optional but may be specified. It is the same thing as using the
spanx
and spany
keywords.
"cell 2 2" "cell 1 1 2 2"
flowx
flowy
Sets the flow direction in the cell. By default the flow
direction in the cell is the same as the flow direction for the
layout. So if the components flows from left to right they will do
so for in-cell flow as well. The first component added to a cell
can change the cell flow. If flow direction is changed to flowy
the components in the cell will be positioned above/under each
other.
"flowy" "flowx"
w/width
size
h/height
size
Overrides the default size of the component that is set by the
UI delegate or by the developer explicitly on the component. The
size is specified as a BoundSize . See the Common
Argument Types section above for an explanation. Note that
expressions is supported and you can for instance set the size for
a component with "width pref+10px"
to make
it 10 pixels larger than normal or "width max(100,
10%)"
to make it 10% of the container's width, but a
maximum of 100 pixels.
"width 10!" "width 10" "h
10:20" "height pref!" "w
min:100:pref" "w100!,h100!" "width
visual.x2-pref"
wmin/wmax
x-size
hmin/hmax
y-size
Overrides the default size of the component for minimum or
maximum size that is set by the UI delegate or by the developer
explicitly on the component. The size is specified as a BoundSize .
See the Common Argument Types section above for an
explanation. Note that expressions is supported and you can for
instance set the size for a component with "wmin
pref-10px"
to make it no less than 10 pixels smaller
than normal. These keywords are syntactic shorts for "width
size
:pref"
or
"width min:pref:
size
"
with is exactly the same for minimum and maximum respectively.
"wmin 10" "hmax pref+100"
grow
[
weightx
]
[
weighty
]
growx
[
weightx
]
growy
[
weighty
]
Sets how keen the component should be to grow in relation to
other component in the same cell. The weight (defaults to 100 if
not specified) is purely a relative value to other components'
weight. Twice the weight will get double the extra space. If this
constraint is not set the grow weight is set to 0 and the
component will not grow (unless fill
is set in the
row/column in which case "grow 0"
can be
used to explicitly make it not grow). Grow weight will only be
compared against the weights in the same grow priority group and
for the same cell. See below.
"grow 50 20" "growx
50" "grow" "growx" "growy
0"
growprio
/
gp
prio
prowpriox
/
gpx
prio
growprioy
/
gpy
prio
Sets the grow priority for the component. When growing, all
components with higher priorities will be grown to their maximum
size before any component with lower priority are considered. The
default grow priority is 100. This constraint can be used to make
certain components grow to max before other components even start
to grow.
"growprio 50 50" "gp 110 90" "gpx
200" "growpriox 200"
shrink
weightx
[weighty]
Sets how keen/reluctant the component should be to shrink in
relation to other components. The weight is purely a relative
value to other components' weight. Twice the weight will shrink
twice as much when space is scarce. If this constraint is not set
the shrink weight defaults to 100, which means that all components
by default can shrink to their minimum size, but no less. Shrink
weight will only be compared against the weights in the same
shrink priority group (other components with the same shrink
priority). See below.
"shrink 50" "shrink 50 50 "
shrinkprio
/
shp
priox [prioy]
shrinkpriox
/
shpx
priox
shrinkprioy
/
shpy
prioy
Sets the shrink priority for the component. When space is
scarce and components needs be be shrunk, all components with
higher priorities will be shrunk to their minimum size before any
component with lower priority are considered. The default shrink
priority is 100. This can be used to make certain components
shrink to min before other even start to shrink.
"shrinkprio 50" "shp 200 200" "shpx
110"
sizegroup
/
sg
[
name
]
sizegroupx
/
sgx
[
name
]
sizegroupy
/
sgy
[
name
]
Gives the component a size group name. All components that
share a size group name will get the same BoundSize
(min/preferred/max). It is used to make sure that all components
in the same size group gets the same min/preferred/max size which
is that of the largest component in the group. An empty name ""
can be used.
"sg" "sg group1" "sizegroup
props" "sgx" "sizegroupy grp1"
endgroup
/
eg
[
name
]
endgroupx
/
egx
[
name
]
endgroupy
/
egy
[
name
]
Gives the component an end group name and association. All
components that share an end group name will get their
right/bottom component side aligned. The right/bottom side will be
that of the largest component in the group. If "eg"
or "endgroup"
is used and thus the
dimension is not specified the current flow dimension will be used
(see "flowx"
). So "eg"
will be the same as "egx"
in the normal
case. An empty name ""
can be used.
"eg" "eg group1" "endgroup
props" "egx" "endgroupy grp1"
gap
left
[
right
] [
top
]
[
bottom
]
gaptop
gap
gapleft
gap
gapbottom
gap
gapright
gap
gapbefore
gap
gapafter
gap
Specifies the gap between the components in the cell or to the
cell edge depending on what is around this component. If a gap
size is missing it is interpreted as 0px
. The gaps
are specified as a BoundSize . See above.
"gap 5px 10px" "gap unrel rel" "gapx 10:20:50" "gapy
0:rel:null" "gap 10! 10!"
gap
x
left
[
right
]
gapy
top [bottom]
Specifies the horizontal or vertical gap between the components
in the cell or to the cell edge depending on what is around this
component. If a gap size is missing it is interpreted as 0px
.
The gaps are specified as a BoundSize . See above.
"gapx 5px 10px" "gapy unrel rel"
id
[
groupid.
]
id
Sets the id (or name) for the component. If the id
is not specified the ComponentWrapper.getLinkId()
value is used. This value will give the component a way to be
referenced from other components. Two or more components may share
the group id
but the id
should be unique
within a layout. The value will be converted to lower case and are
thus not case sensitive. There must not be a dot
first or last in the value string.
"id button1" "id grp1.b1"
pos
x
y
[
x2
]
[
y2
]
Positions the component with absolute coordinates relative to
the container. If this keyword is used the component will not
be put in a grid cell and will thus not affect the flow in the
grid. One of eitherx
/x2
and one ofy
/y2
must not be null
. The coordinate that is set to null
will be placed so that the component get its preferred size in
that dimension. Non-specified values will be set to null
,
so for instance "abs 50% 50%"
is the same
as "abs 50% 50% null null"
. If the position
and size can be determined without references to the parent
containers size it will affect the preferred size of the
container. Example: "pos 50% 50% n n" or "pos
0.5al 0.5al" or "pos 100px 200px" or "position
n n 200 200"
.
Absolute positions can also links to other components' bounds
using their id
s or groupId
s. It can even
use expressions around these links. E.g. "pos
(butt.x+indent) butt1.y2"
will position the component
directly under the component with id "butt1", indented
slightly to the right. There are two special bounds that are
always set. "container"
are set to the
bounds if the container and "visual"
are
set to the bounds of the container minus the specified insets. The
coordinates that can be used for these links are:
.x or .y
- The top left coordinate of the referenced component's bounds
.x2 or .y2
- The lower right coordinate of the referenced component's bounds
.w or .h
- The current width and height of the referenced component.
.xpos or .ypos - The top
left coordinate of the referenced component in screen
coordinates .
"pos (b1.x+b1.w/2) (b1.y2+rel)" "pos
(visual.x2-pref) 200" "pos n b1.y
b1.x-rel b1.y2" "pos 100 100 200 200"
x
x
x2
x2
y
y
y2
y2
Used to position the start (x or y), end (x2 or y2) or both
edges of a component in absolute coordinates. This is used for
when a component is in a grid or dock and it for instance needs to
be adjusted to align with something else or in some other way be
positioned absolutely. The cell that the component is positioned
in will not change size, neither will the grid. The x, y, x2 and
y2 keywords are applied in the last stage and will therefore not
affect other components in the grid or dock, unless they are
explicitly linked to the bounds of the component. If the position
and size can be determined without references to the parent
containers size it will affect the preferred size of the
container.
"x button1.x" "x2 (visual.x2-50)1" "x
100, y 300"
dock
("
north
"
"
west
" "
south
"
"
east
"
) ornorth
/
west
/
south
/
east
Used for docking the component at an edge, or the center, of the container. Works much like BorderLayout
except that there can be an arbitrary number of docking components. They get the docked space in the order they are added to the container and "cuts that piece of". The "dock"
keyword can be omitted for all but "center "
and is only there to use for clarity. The component will be put in special surrounding cells that spans the rest of the rows which means that the docking constraint can be combined with many other constraints such as padding
, width
, height
and gap
.
"dock north" "north" "west,
gap 5"
pad
top
[left] [bottom] [right
]
Sets the padding for the component in absolute pixels. This is
an absolute adjustment of the bounds if the component and is done
at the last stage in the layout process. This means it will not
affect gaps or cell size or move other components. It can be used
to compensate for something that for some reason is hard to do
with the other constraints. For instance "ins -5 -5 5
5"
will enlarge the component five pixels in all
directions making it 10 pixels taller and wider. If values are
omitted they will be set to 0. Note! Padding
multi-line components derived from JTextComponent
(such as JTextArea
) without setting a explicit
minimum size may result in an continuous size escalation
(animated!). This is not a bug in the layout manager but a
"feature" derived from how these components calculates
their minimum size. If the size is padded so that it increases by
one pixel, the text component will automatically issue a
revalidation and the layout cycle will restart, now with a the
newly increased size as the new minimum size.
This will continue until the maximum size is reached. This only
happens for components that have "line wrap" set to
true
.
"padding 10 10" "pad 5 5 -5 -5" "pad
0 0 1 1"
al
/
align
alignx
[
aligny
]
alignx
/
ax
alignx
aligny
/
ay
aligny
Specifies the alignment for the component if the cell is larger
than the component plus its gaps. The alignment can be specified
as a UnitValue or AlignKeyword .
See above. If AlignKeyword is used the "align"
keyword can be omitted. In a cell where there is more than one
component, the first component can set the alignment for all the
components. It is not possible to for instance set the first
component to be left aligned and the second to be right aligned
and thus get a gap between them. That effect can better be
accomplished by setting a gap between the components that have a
minimum size and a large preferred size. Note that baseline
alignement does not work if the component can't get its preferred
size in the vertical dimension.
"align 50% 50%" "aligny top" "alignx
leading" "align 100px" "top,
left" "aligny baseline"
external
Inhibits MigLayout to change the bounds for the component. The
bounds should be handled/set from code outside this layout manager
by calling the setBounds(..)
(or equivalent depending
on the GUI toolkit used) directly on the component. This
component's bounds can still be linked to by other components if
it has an "id"
tag, or a link id is
provided by the ComponentWrapper
. This is a very
simple and powerful way to extend the usages for MigLayout and
reduce the number of times a custom layout manager has to be
written. Normal application code can be used to set the bounds,
something that can't be done with any other layout managers.
"external" "external,id butt"
hidemode
Sets the hide mode for the component. If the hide mode has been
specified in the This hide mode can be overridden by the component
constraint. The hide mode specified how the layout manager should
handle a component that isn't visible. The modes are:0
- Default. Means that invisible components will be handled exactly
as if they were visible.1
- The size of the
component (if invisible) will be set to 0, 0
.2
- The size of the component (if invisible) will be set to 0,
0
and the gaps will also be set to 0
around
it.3
- Invisible components will not participate
in the layout at all and it will for instance not take up a grid
cell.
"hidemode 1"
tag
[
name
]
Tags the component with metadata name that can be used by the
layout engine. The tag can be used to explain for the layout
manager what the components is showing, such as an OK
or Cancel button. Unknown tags will be
disregarded without error or any indication. Currently the
recognized tags are used for button reordering on a per platform
basis. See the JavaDoc for PlatformDefaults.setButtonOrder(String
order)
for a longer explanation. The supported tags are:
ok - An OK
button.
cancel - A
Cancel button.
help - Help
button that is normally on the right.
help2 - Help
button that on some platforms is placed to the left.
yes - A Yes
button.
no - A No
button.
apply - An
Apply button.
next - A Next
or Forward button.
back - A
Previous or Back button.
finish - A
Finished button.
left - A
button that should normally always be placed on the far left.
right - A button that should normally
always be placed on the far right.
other - An uncategorized button.
"tag ok" "tag help2"
miglayout-5.1/src/site/resources/docs/cheatsheet.pdf000066400000000000000000006004701324101563200227020ustar00rootroot00000000000000%PDF-1.3
%���������
4 0 obj
<< /Length 5 0 R /Filter /FlateDecode >>
stream
x�]]�ܶ�}�`tN���ڭ�G7���8�]�Ir�c9y��0���H��f'��{��A��ɖ���x�$Q
U�
��C���ڗmUn�����凛��m�������/+������������w���u��7@�m�������ܬ���3z�u�n7�C]�n]�¨o���P���^wح���*R��U�6?���fSU�������Ϥ;W��_����mݕ/�Ӄ�%z��]��ŋ���ߕ�߾���7�������ˇ��on.��[>��+���8R�!�]y�������ܜ�a0c��4���0|^o��:����7�����wP��z�6
D,��x�*W��ߖ���oU�.Í�6fx���,�*V��ў�����.�ru�w��P�k�r�����M6�/��?��/Z�F��(�tTI�$�%H�P�e�$}sQ���+>��W1I]� _a���<�g�����#:}�jNf��A��[$O���اY��s���k�y_��ZI�h�$� ! ����/d��"��oB0f6&תm�m]���n�&��Yh ����Ф�@�0�B����iq(�w�
ȕ^��P4I�^���r&Ku֡��hA�~GQam��cr�#u��"�E���\�([�s����w�"��B�/���7�%^��\TE�:6DJ��lf�Y����/Vl���ɨ�����|���)lk�ذ��Ql�2��}��P��r��p�_����T�he�����P��NDۥʼ��ɻwOfZ�P�@��oׇ
��+�^F�']sr��b���9à�M��C��(����=��ݽ7Z0 �#�G�Pm����T�+ҿ�E����"�2
��@,້��`�B��� �����B�������=��� �-��+�D��|����U�q-��8����"�^8͇P����Ol��}���U�0K>�+�Lo��?ҍ��c�Ec��}�>hZ��8}a�9}�@h}��[qUrϲ?Ҝ������WG47Jr��qV��R
��j+�V?�ǿ��HK�z�K��9/V�&��l�F����#5��b�72Nq�"��nE4Δ"����0f�.�.1�p��
k)W_$&p���a��v�C�mR�aYfU�4�o���� �#���js���?0����_�^��>�|��~y�y�yy����E1k��{��BS�;Wy��4�;����* w�*f�����E�P�/1�b� !ϵ�g4�ΐ�p@D
!Y�pD�����7����P? �Q�\��o����/O�ۛ'�t����n��o��ٺ�����i��.�ʦA��P�}L�[_�h�����l��&}?<��މ�q���]A:ߗ�:5D��I�R���v#a ��Փ�^[.�M4�=fS)��DP�>OТ?�q�N
������aׄ0ˌM8&|~f4�f�<��5��M�ص�m�<I���N�CEG�O���=�!����ɘv��ߐbީe��U�N̾� �(V2�*�wtA�d.Fx4�U^]��sq��8q�@4�~��l!&����d����7��ӯm�9�� Y�:i�@3
q�^z��
��D}84&`��8b:
\�}���o�.�~{�����ͭ͞ϳ�
v��
�F
�_���� ��?����m��ԓj3hi���wo��Mn���`Lp�%��
8���x���r��ߐΦg��>��
�(:�R=0J�;�Q���m�Ο��N�G�@=���lSp��9�Tf*Xn;�(���@�G�yz��"��9�q8/W�t�8MJVb�:����=��d/غb0�������^;��\|
U��dłN�Pc�PW{���K�=���ߞ��$4�,#�5M���-�����(�CG������zsȠ��*��v�@��_�,`���8�7�ޘ���f���Пu�;�e�� ��СPQ]a=5`>�3G#WD�E�m�>��♹0��?�/����Z�t�Jχ�������`��Y3pw8է���B-!��d��|0�"���~��-0D�o�8L/Ox�6���=7�m�s���=�s��_��I^�7/�T�����:�,���T#��!-�Jn�7k=Ҫ��&��P�wfi��Dd0�����0��d��(4vfc��y�+z+
u��c��k�v���L��{�b2�i�)� ���_((a~"&h��
_?Yy�*���ݶ�z���(L�����-�1 ��=�D���EjL�>H(���{�DI�#5^t�1��0&*c��7&����ѺAt0�+o�fJ��� ���#�'�~�a�M�Q��kih�)'���
)�
?t�mwȡIx[��W�Տ(�ο�`]��Fe�|P��ej�v��Z�?)�$!M��;)2'�CÐa%�;C�����f<�
�{2��6�w2v�s�NM�+����.x������n���^�6J[�m�*V��\����gs�u]��x��"8�gA�$�)7�,�f���,�0$��Nb_V�#��bV�����8��Z!bo�nj�,�K6�ij9���#�ȗ
� ��U����z\������+��� ��"Ω�����[��A]��1@(Z쳘�K+�x��6����(j�:_�!���7�)�Ȍ��5�zw����I�W���\�IJ����އ��|Bڵ���"�!�> H����}d�fR�1�C��hBj��C��][{���>Ą���/NM��3+R0T�u��Q['ԣ�R4>�X�FXi�1�ErE
���2鑩�a~df��4RO���$��:��9�����k�jCFd�D����3�Ϭ�d�Ns@��$O�����$��Zʮ�}]�&�&�<5f�yl�Bc�B�v]�c�Uu���f�ٺ?���b�`��������5!�R������D᯿��
M���&�-?�u�
� �FRN��M
��ӯ�)F�!�>`_%�Wv�J}�ؑ�`�k���-���1�ukH:�0ws-���������Oo �لU�H,����|7Kut���e��[\���[X/�Yha\XZ��g��^�0� �gYx��d0�P?����10I���<�e�BS_g���Om���g#�00sܗ`�
�*I�0�R�ŧ@(�L V��F������Typc+DS`r:T�YU���a��z�x�F�8}P�5X��X���]`�Q��)��<��~S3:S6Ck=�c����a�����R .K��4���c 06��:,�4�H1��#�
z:���0����]$��[X�)k�v�}�4&�^����%q? �(E����Ɨ�F��" 2_h����B�|��2X7�ɡO8F� ����S�c�ƁEZgl�Z�}�;��h��@�[ؾ�vg�w�h/�A2� }H��ܿ-*���)��}�/p���x�k��ފw�0�.R����}��|�X�h��@�H��~���݅m�)���0���)!�H��P��1�+��ë3Ml>��*L.��FƬ��F���Ǧ��"%��b�l�9��E32��M"^�i��Š�����.��o�����V�z��n��;�Dž����?u`�U���5JD/�����tf�8i���J�����ں=�Ơ
9,)��A�
ص�ӛ���Lfo̖��E
mv���l�,�.(���;�mf�,n*+g��s�_s(@^Oc��=�' ������8K&�wѲͧ0��� ��'�՜:�Q8Mm�hj����3y��c�$�E�A]���p�6���E1V��B���7��<߈o�2.`�y��S&3��bsDS�1>Ӱ5{��i��rq,��l�Yv'���<�8����g�����-��Lgh8Q" <� *��7�><3�~�y� ��SN'_Q�����5R�?!���
�����M#@c�N�z6�jS
�h
��l%0Sa�~��=��Ϗ1��v*�\��kD�6zWv�'�e��e��a��nR��=j�M&an���.�����ɷ����5��6��t��]��-�t:��w���]A:�g3
�b�Z(X>��1gOa6��Y�ԇZ;�`S�S^馶5z|��iV�e#�����|�Z�;AWV8���0�~s��ڟ
�+�y��D��(�$�������O�&����~ �����w��C>�d��xYF^���gq;ӆ��4jl�#�Ra��[o�3��UH�l!�`G���s
�����8C~��C[�NXu�D�)��ǰ<���c�FyU-�T<�ң�6M�N���Y���#�o|������N�IT�!��^�`s�0D0���KytgP
lL���0�1(���O�z����p�N���|�� &@�u�8*��钎��s�5�>lkL�ڦ������e�����Y@�_?>�Bw���E�,�}�C(��G�;ؙ�}�@bOx��U�>�
�Yt�;�m���-�3�'�>��QA����ͩ^Vjk$��C� ���%�n�C���IJʺ`����#�\W�:S~)�R)�����F�_)���N�y~*q�
�S��cDA��
Xΰ�G���ǧj{�"=��S�� �7y����6�e�����+���%+�Z�J�~$����F)�G,�ʆ��fɤ��o�pr��?H��C�ʓ�
�;��&�0HI�)�'����p�H�X���9\��a�z�0Aİ�8��ds��q�4�J�>0`��QCȿ�.�1��
�ulW�+��KqR�
K�8x�����I�Y����Ȑw ��]<0��`Q��H�*�!��NӔ�,s�w-�l��\�)�]o~��;�jq�F�7�P|XGq��Ⱦ�`�d���9�\/��lf<={����z[���f�}�yrz���m��c����N/A�ݷ6(A� �3m���<�L�#�VA=>�f���?��y� ��^�@���[G쪹=p���u�r��ֿf�4��E��J1;":$�a궐�!qp�s2����w��X�4>��Ŋd L�6~��ia4�]3VB襵��8��Ft=IL��^ ˖�
�gbiٱ�N��|v7c&�|D�Ϛ��
�l�JJ=bv�3����NY����Or�oa~FuĪ��p5��hՋթV^��^��^��m7-�Ȭ��$�܅0}#'���L>�
��K2�#�N{���B�ϸr`�-3���z?��#�oe�矰h6<6��,�����C�0�;����ށ ~�.;jk<�߃Mr��t��j�#c��L/!+�u��������6G�r� $�]�'�D�gQ���`<�_���>&Oүw�b#�����aZ�y#�$��QQ(��]w��B���0��!Ϙ�l^dm^���A�0��Ћ�HQ���#6�lc%�%8H��d�V�V��d�RE٠�'O`Ğ���&�3 ��������9��=���p鍈]��py����Τ�ik;s{{��q�'pv�w�.Y�V�=7t�Eoή
+�v�w�CY.]w�̟b�N
�ن��ў�1S�H�mDZ����������sun�ݮt-9}��YX蠐��rG_�vP��'�z��DBɤ�[*�s�2����F��A4>�ol��uH���w�u��E=���Q�=!ڻ�x�Xrv��Yԇ�bu�T#��>h�PuB֒�7� �,��]�; � ���4h�Z���CQ�Yx�F�u�yv�S��T �s�^�}����p��!��h~��C�����Egk��2�r7z~֤<'9 ��y�D�[dr�:%��g��$�� �@,��$�D/�l��i1���+��f{��3EB�ɚ��PM�
�o~�I�R�@�s��3Ȃ��ME~<�?7woG���0sl�S���1�{�9����L�iY��g���x:1k6��Ǽ�hiJ<���P�a�sI����p�o$
��5�Íe�$�d7����PƦ2qs�d��<�8��W���zKq?"������?�I��� �6;;7.d*Ⱥh�8"�kT6I��#'�iO�Rd��y=���}TN
�s�f!V�s
t�Sv�����P��$���|��
87���n>f���ݞn>.R7��[Xn~�3�͏�dcD�v����z���)����G��,��.�L�(��l����P#�*~��s?�(�AZ���c�r�cU�`"�f����ٌ�bF?�����[��Z�K��c�I�%��aF�сI�]�t&���)YO���C�A���B�@�u�oDx���*O-��=�����Ń�����,�ݶ�TY��"1Z~����V\M��¡�#j|α���N3��n�{���zђ�&���K;(�P��� &�&ή�L�*d���Qtw��
I=�������="�E���>>�]A:�tp�:��x�������Ç�͂������"��oC��$�L<U3F|l���I$P���O�F�v��^���t������7)'��`_iu�z�2�|P؟| ��7��~�?���;�ʨ9������b1���^�w!
lpW��7zu��,�F��h�l�j�E�OO9�3ڵ�)���>.܋{wm�=qуqKht��]�ؘ��x���)��}�A؞sO;������K��K7�@�[pdB�G���|g�U�
J!q'1�x�QS��Ue�~ہ��3�
�s��7�Px���P8�VY�Y0�n8#�t�h��b���wC�m��/���O��w��O��PߴUa(�N���1HL�1�3zꆍN��[Oӈn�/�a;�c�%Ǧ6N���8�ϼ�xd���/����Y3U�����
7��fI)Ӆ��.�<�~:xF�X��q$S�ټ;�s���^3{xq8�Cћ�h��7�AI�X^ �y6ԥ�S06.e
��u�f�&�D>��w�7ߠSJ~P1�'��>PY%��)���a�Q1L5�:���x�S�#����)@�H�Ur���c���
֍ߣ��^���Yi��=��;&�1T?n`��+@˱�p,�@/4~����ZD��礌3�G�=�u
��?�<+��l��n�$����1�c���(٨@{�
�F|�������=����D0��� ��U�v���$�>&C�~�����<�⣩������N���W��]�
��T!����0��>z����l{�9S���F��I��'sA�M.��Q��M��o�&�V7������Jr�
fH�}�l������L፝���t�����٢��lx�<��j�����>2�m�m�C8R�3������^���Deo���t��=�`�����6������o��7��U_�o�lh2�k���=S�͛u����ET��qI�4c�һ=�l+u�Y�)� ��ܮ�.J���ho[Uӊ�>�d�Ɓ�Dq|e��I����ι=j���U�^�3�fr;_�K��.Y�NR�5�ƽ����*Y�;�!���J
&{��K�DJ6u�%��}��s(<��>�]%};tR�%-��q��l���i"���U��R¿|�>�h��fʩ�#��a�G�)Vϝ�'��b�L�;2��C���[�Yȗ��ݽ�E�������\[��+K��$�>���G���?B&/ys[�.W��G��:G�賑��Q�VG���$�%!In��<�"�T�+A���IE3�R����ѹ���D��X�-dْ6�71@-~�=��x�I"ߢ�xr��أR��� _�XQ��W�˿x�\m��v��L��e.[g���=˗K�sy��2�����}�E;wnRZ;a�>�*R/j���"��S�"(Tl(i<$��Mme{ٰ��J�Q��K56��j���4��Ie��3&e��Z�8s����E��[��T���R��V��
s`���P�3q�N.�!�}_�L� ��C�%�V�mu8��v)��b�{q�:��[��A��gl�Ի���"wG�b���Ү�x�n�X�/RO�����aM��)�7,zN���o�>$ѫ"��n9��p�S;��'�{�2�P��N����k�� x�>kf5��ݥ����j"52�;�Ƶh0����M�P�{V��$Z�67���T���,�^vb(
��y2Կ[�����l�=֛�<�ԣ��ܙ9M��"x����iA�����I�Yh���Up嶇mף���/�g�J@\�bP�(�bbR�e^�����;䔤bB�3V�xa��ݺ���A>�pDv�I�~"N�(p�4[%�mZj�/j��g1ڃ�%�x��vY�3=-�� d���\7�]��'嚌���E��"=�|RP:ՙ�8�5NT� 5.�����NG{Z��Y��
�mPo���*m��sB�C�RȱNdl� #c��s�v������n@��3H�F�U�YoF��2fyly��}7,?H���)�A|�v���8�jH�n��\���8��Q��?��h��`b>�ơ刐��2(�b_�
��\=�o�Ј��1���T��+�����9�}h�q2���V������zڑhIh�q��=;Mf��gJ\�]�`�A{/��>q��uO
��6�So����d�)i;2��Z�(�
ȍ�k��e}=�v�:����,�}2Oj#��#�����S�G�'����ۍ��ٻ @�Ξ����E^n.X�M�@��}*�W��WQ���Q�+�n,@���Ǔ����dခ�)�g�vM{{U���ъt�&��su$���^ F�����`��&>�5=���� ���� � (�g��7�d/�蜔J:�*�Ћe<9K��.�Ɣ]�"� 7,~'ܑb �FΪy�j
+����7H�o&u��bN`��H�a7�Z��Ƅ`�ǐ��A�{P6U1�|e�u
������Sc�ȅGl|�c`���3�o���U#�>��e��xg� �"É\�G�N>��f�G�����%Lf�:����6��R@�I�J�G�dz�X��S�zO�'c�<�B�1�K:LjQL e��8`TR�ļ�;�IB�m4 Q-�.V�f�rٓ�xX�;����H�1�'lɩ�|��kP$��IAk/ � �U#�n�y`���(�$�?�ҺgaG��
U�L&���7��'������lؐ�����iXu��>r$��sR]zK�;�ع�V�d ,~�5uL3v���K���N֕�/�I�������ЧA��}�K���3��8��b�PF|E��'�}Y!Rf�£�P�*����s`��+�cSIT��z��!GnD!�h@LL��^H+T���,N�����y:�Ε䃨��zB!��]��D�MN呵���Kܡ �v<���qP��Lڤt����.���==,40)����J}�G_M{خ���Na�C��5�A�Ї&���?�DޛK]�E���^f�l��rS����+�/�a?}gjg�h,B0Į�g�%Ո뉯MaM�B8�G��ӟcE��?q@+�
endstream
endobj
5 0 obj
10781
endobj
2 0 obj
<< /Type /Page /Parent 3 0 R /Resources 6 0 R /Contents 4 0 R /MediaBox [0 0 595.28 841.89]
>>
endobj
6 0 obj
<< /ProcSet [ /PDF /Text ] /ColorSpace << /Cs1 7 0 R >> /Font << /TT4 11 0 R
/TT1 8 0 R /TT5 12 0 R /TT6 13 0 R /TT3 10 0 R /TT7 14 0 R /TT2 9 0 R >> >>
endobj
15 0 obj
<< /Length 16 0 R /N 3 /Alternate /DeviceRGB /Filter /FlateDecode >>
stream
x��wTS��Ͻ7��" %�z �;HQ�I�P��&vDF)VdT�G�"cE��b� �P��QDE�k �5�ޚ��Y�����g�}P���tX�4�X���\���X��ffG�D���=���HƳ��.�d��,�P&s���"7C$
E�6<~&��S��2����)2�12� ��"�įl���+�ɘ�&�Y��4���Pޚ%ᣌ�\�%�g�|e�TI���(����L0�_��&�l�2E����9�r��9h�x�g��Ib�טi���f��S�b1+��M�xL����0��o�E%Ym�h�����Y��h����~S�=�z�U�&�ϞA��Y�l�/��$Z����U�m@��O� ��ޜ��l^���'���ls�k.+�7���oʿ�9�����V;�?�#I3eE妧�KD����d�����9i���,�����UQ� ��h��<�X�.d
���6'~�khu_}�9P�I�o=C#$n?z}�[1
Ⱦ�h���s�2z���\�n�LA"S���dr%�,�߄l��t�
4�.0,`
�3p� ��H�.Hi@�A>�
A1�v�jpԁz�N�6p\W�
p�G@
��K0ށi���A����B�ZyCAP8�C���@��&�*���CP=�#t�]���� 4�}���a
���ٰ;G���Dx����J�>����,�_@��FX�DB�X$!k�"��E�����H�q���a���Y��bVa�bJ0c�VL�6f3����bձ�X'�?v 6��-�V`�`[����a�;���p~�\2n5������
�&�x�*���s�b|!�
ߏƿ'� Zk�!� $l$T����4Q��Ot"�y�\b)���A�I&N�I�$R$)���TIj"]&=&�!��:dGrY@^O�$� _%�?P�(&OJEB�N9J�@y@yC�R
�n�X����ZO�D}J}/G�3���ɭ���k��{%O�חw�_.�'_!J����Q�@�S���V�F��=�IE���b�b�b�b��5�Q%�����O�@��%�!BӥyҸ�M�:�e�0G7��ӓ����� e%e[�(����R�0`�3R��������4�����6�i^��)��*n*|�"�f����LUo�՝�m�O�0j&jaj�j��.��ϧ�w�ϝ_4����갺�z��j���=���U�4�5�n�ɚ��4ǴhZ�Z�Z�^0����Tf%��9�����-�>�ݫ=�c��Xg�N��]�.[7A�\�SwBOK/X/_�Q�>Q�����G�[��� �`�A�������a�a��c#����*�Z�;�8c�q��>�[&���I�I��MS���T`�ϴ�k�h&4�5�Ǣ��YY�F֠9�<�|�y��+=�X���_,�,S-�,Y)YXm�����Ěk]c}džj�c�Φ�浭�-�v��};�]���N����"�&�1=�x����tv(��}�������'{'��I�ߝY�)�
Σ��-r�q�r�.d.�_xp��Uە�Z���M�v�m���=����+K�G�ǔ����^���W�W����b�j�>:>�>�>�v��}/�a��v���������O8� �
�FV>2 u�����/�_$\�B�Cv�< 5]�s.,4�&�y�Ux~xw-bEDCĻH����G��KwF�G�E�GME{E�EK�X,Y��F�Z� �={$vr����K����
��.3\����r���Ϯ�_�Yq*���©�L��_�w�ד������+��]�e�������D��]�cI�II�OA��u�_�䩔���)3�ѩ�i�����B%a��+]3='�/�4�0C��i��U�@ёL(sYf����L�H�$�%�Y�j��gGe��Q�����n�����~5f5wug�v����5�k��֮\۹Nw]������m mH���Fˍe�n���Q�Q��`h����B�BQ�-�[l�ll��f��jۗ"^��b���O%ܒ��Y}W�����������w�vw����X�bY^�Ю�]�����W�Va[q`i�d��2���J�jGէ������{������m���>���Pk�Am�a�����꺿g_D�H��G�G��u�;��7�7�6�Ʊ�q�o���C{��P3���8!9�����<�y�}��'�����Z�Z���։��6i{L{��ӝ�-?��|������gKϑ���9�w~�Bƅ��:Wt>���ҝ����ˁ��^�r�۽��U��g�9];}�}��������_�~i��m��p���㭎�}��]�/���}������.�{�^�=�}����^?�z8�h�c��'
O*��?�����f�����`ϳ�g���C/����O�ϩ�+F�F�G�Gό���z����ˌ��ㅿ)����ѫ�~w��gb���k��?Jި�9���m�d���wi獵�ޫ�?�����c�Ǒ��O�O���?w| ��x&mf������
endstream
endobj
16 0 obj
2612
endobj
7 0 obj
[ /ICCBased 15 0 R ]
endobj
18 0 obj
<< /Length 19 0 R /Filter /FlateDecode >>
stream
x�}ےǑ�{}E fk�4#��u�ĕ�8���b/f@1�@C�(�����8�=2��2��36����̈�� �k�y�/�?/��r�,w���p�,?�]������o����e���mo7�j�l����a�q���P�m��v����zuh��C���j�^�6�*_���վ^�F4T��f�9m��yY�Y������_�W�usگ�h��[l|hW��z�D+���/��>�w��@�7��n{B��_B���^�7�6�(��e�V�M��
-�S��mv�ͺY��t\hˠ��b��ևS*d�*F5RhO6�u���W�u����j{Z����M�n�L��F|Z�C�,�m��J��=�p<���QҼх��>��9c�B��8��$-q�����C�b���%�i��6�f���nEs���(&i���<WǦ�����q���cM�&˱�s���rxAZ��� �V�J��p��<1+.�5O�վi��hM�M���?�*k:ͭIѣ��E\�Z�݊C`��<!��h�&�N����b��I#����i�d�QL�bMF;�Ul:��1*6w{X�pDe�.�4�搘�E\�&�
kW�#�5"-iz}����E9�6JL6�~��94�QѼQ$G����I��YH�P��MH
,8̺.r�%�D"��R�r�:�B�BZ���b_�1 �d�w�MFeE'$�R +��,��mRzQ�������������j/Y&�!�ʐ��!��>�ck�!�("۱&�bD��Æ�ܸ#$1R�*��+
%����
�B��p�Nb����.2HC �!Es�I�$6 ��,c@���}�O��h1�w��js�W�d�U��or�w;��NbE ����uK�l1�v�$$
\8���|P�b
]����.����mpٚfd��f�ɚ��h���ݚ�i_���BeMo��bj�k:�e&=�����Ǻ����
j8h�M�f�Y3��h�\(+�(kzAZ.�,idݚ��"��z)Z$¬����qֹpˎ�f�TY�i.��v�6Śn0�s����.�*�m��*�TU��FY���c�2�ii-ߟ�FmTlz�E$��N�U����Hk:�Rgi]$G�!Zit��nd���fE+���N����b&KZ�� ���f�Yqa�bN���S�M�f@�i]$��m�5��jz�f@�fUv�5� �/��
��6��4��FY�[t1��5-#�s�4��UeM��H����6Śn08�c�h��ٝ�2A3�ur���T!�M!d�D�m0�k���Q�b�
f�lR,�{���搘N�U��u��Qb:�R?i]$���mp9=p#k�ȗ5M�eE'�В:�HKZD� ���e����t�[ӑֹp�Dk:Һ5��"�n�hS��Fbz�{M�&˅�������"���6�)�u\vZo��9��d�e�u.�Ʋ#c3�jя�Y&fw.��v��6�,����d�����±`}\m��g�6ʖjrk����HՀhg�6K�o�)�H�jq'!EbE�ۅ 50!��������Q�� (�mF�%��Q�%�#�d���!I�%EeH��Ċ 6�M�%m��� *p!4
L�6ѐ�nH��<�^iv�6Ő<2���H2Z()�(C����U���QF�+i��i���i�%p
L�Ƣ##�q�
)������m�!b���nq�Р-�������|2�F��]oW�]��a[H��5��]S����F��s!��5 G� '��K�䳰Uʉ���b�hn�����m���Vd5"��� �ee�Q��2��/S�LJf�(Sz)�inJ!���I,:Ҕ��T�)�L��+tuS��n�˦�`ɨ��}��ʊ6ʔ^P���e�@�)C� ��R.��ܔF��*&�Ģ#M�X�t��mHJ�M1e��fu�u�u�U�z�I$�6ʔj�=��`Du��m
���Nڨ�T��"Z-�$<
\���#��K��e�I;Dc���P#kz��QSE+֬��(k��t�]��h��i�Ŭ�0_AM����hT,0J��%̒��C46:J̀6��G�[���Ue�XS���NJ�=��<���bV\k-m�B4*v�5�ʚ��}T&����(1nl'��X-B��fN����6�`��eE�^�ݢ�*�m)6�b�[���%�h��<�&a�3�$�gd`
f���.�+v��Ȋ���l�M��A_�&�9N�yG��ʔ^�LH2e()�r�&���IM)�
�t��mHJ�M1�
Y�p�59��BY�w�)��L��˔�$S��L�\H�y|-#��p���JS*,L�S*�u��n��p'Q�M5۶�Vl���-R��NeJoԲ�_�EKZ�X���C�h�M��"R��zM��΅�Xv�5c����.�c��mpٚjdMq�)�d�PV�Q���Yv�"�1�ʺ
��ȾbN�mѧD�h��E?1�u�\�C4��e1�Ț�^S��r��h���i�����/��Tv�5�EZ���hh������t���t�����
.[3�&m������
im�֫��^�����VY4�aiEHk�5p?�;i����6�$T
\�Fu��Qb:�R?i�(*����(1�Ț!�e͊V,W��bM��Ҋ�6�I�%m���+�D���hT�Xk:Һ5E#��L����Qb��5C�˚�X�*;Ś*(��- m��H�l1+.�5���6p!;֚Uv����2�v��FG�@}_�2)l-��*����my�
�ovվ�
i�ls�T;6�4W��B��������_���W �D��4�����(�І!�i�@�
CI�.J�V����WDW�"츈^4�~���;��-��B։6 ZTR��~����I���B� �
I�
%EeC/H{EL%-���(Hͤ�"�F�x�8mZ
NC:MҸVH�0�
�Ͷ��&�D��B�#���-�g��+�QVT���
Ⲏ���mN !@༡l����JQ����v�$�\���S�V�'@*�H�����3�����֬h�rU�)�TA�,�hW��V�f���_G�Q�0�(�up��p%�]�hlt��id���͊V,W��bM��6�I�%m���Y�h e�Q�c� �`W�Z�>*�n�hl����|6��g�^#���V�v@#^/�
�#sMW58ֆ���M>���w��?�R�g�\��f�K���Om�_�
��?,������v"�O�#6%�T�|�a��ŋ=.Uz�����w�~����w/�{���ſ.�"]�������hnc��#{�n���J'�+�~���h��h�
&?:mQ�g�����|mb&D\f�f�����fu�b�fY�qy�y����,�"گ٥��V�u�!�����3L)�A��"�˨(\i�f�/+�� �]�:���mq��{x����H
�E\(�\��:��vy�/�����������,�B�۟���J>O���k�壟R˛��]�|,�Q����4�V���+{տge|��~�nH���K}oS�I��/�n��=���f߮8�F�|x����� �ՠbcеC�Z��=
&jH�5]����J�����~���M����%`�9ܺ���ָb�]z�HH<��]��+fZ�[>`����y�E<���eᩯ�j�_�\pr{��O�٫��Tf�jh�����Š���_/o�¿�^*�����V߳2��|`�N!���R4�pl�1�$?��R��s��@AD����m2��w�����dd@���=��%�,�fM��
����6�+���.�N{�d��篥&A_(:��却"�} ���Խ�~PM�e^=�����q�����I�/�-�X����%�5�c����ō��C|u?��M
�!��p`� .�N��h"��O�GͳEv3����j�5����3�iz0��� {�_Z�:_ /|^;�b0YN,�@����7�bldM᎓�8��+�^��7+u�Y[�O�>���5�-<�����6G܋Ь�'��g��~m�� �Ÿ醒�!m�@=:�Mh��1X�uxsݑq�ݯv',�
Ɇ����o-�ub[��߬1�Z�Hf{ZiY�v�Q0���2+GW�r0�n��.=�/~d�������'�D�3iDm�G���70Й�]҆1�#�:M;�3�.}{H`�},���ﶈw� @���s�d��>�#%�����(�t{-)xv���\R�%�z�%��-����\S�SJ�aR�>V6���U���G����pf�>�o9�1���
r{8̙Ys����_T�-���� �,1��Zދ��y>��|�/�BOHPz0O�GH풸=v9���0sR>ĺ����^[�H%]v5@ƈަ�?�g6�QJ���"<|�O}XX�Mj�I_�o�8����m�B�Q����p��M�Y��|?[gdK/��r2GQ���o諉�V��a�̿����˹+
�ӧ
�ƕv��z��ۘ뗄������}�������oo}d9}��*��]'�B��_>��0�D/?�)�������S>�K��� �n*}4p�p�ܮ��sHJ�^6�D'���L�uZ��9���?��c"������&���u6~�������A�*f0K��)��df�7�^=�\8-
�n�찕+m'���R�
��Z�ɇ
V��zRA�t��*��;�*{5݁O�0$d,�qC��X��1+7�$���o�"7gzXJ�|i���8k�"8���z7�&�:�����'|w�ztf5,��I�_�##���v��'��j=k5�cIy(�cel�g:
��1��,
b�a�mu�>�>�:��bʬ�z ���?��t*q������ϯ�B�66�εF����7(���Tȷ���S��f��#m��͡h!���b��i�X�*���v�:iVa���UY��ÓG3-�-����hf��u1Ɋ�6�ֻ
VF]��#i���O�QR퓚�b/��y�uh��|7�r�>)�8��a��B���>D�T"N8����c��b�����AH�f�"wFf� �@(�]=%���jU��
��e�}��dW���OrH���wP d����$בu[���i�v�IJ��hj�M���y��X��S�j(��dA��`zA!2?g�K��Ozu� :T�fK�q�ȿ�����~&�v�Vn˪��s2���-2�6��oc��Ű$LlL�_y\��L�-�5�sŋ�
�L<��8�J�pd��3�rUn`�t.X)G�|�U��E�3>��2�&,zU(��a�u�@1(���ڔ ��oS$z��
���4���Ge�Z~��,�ۜ��K��#*K� ������/�F���*D����ʛ� �* Y9�qQUPk����rĪ2H��z�Şl���ZAg9�^a�PFe�>e�@`[�Q��z>��X�7�8$vA�ً��<8�R�KR)_�$K�=��ӑ��!���~���R��rڀ���� �$�E�����zE�A�\�:9rL5j�vK�"�-P�S��>^��ໜ���Bb�;; �'IF�jsx��b&Iy��P�pV�=�<�oh�K�1Lj�T��P&E�f}����d-�
n�¦R�6�@/1��9�f�OtG�8[�����&P�[Xc�nӘ������\�����x��Ś$gY�Q�!�3'o�k��BWԻ��`�d�Z�R ������"8�ۂj���L���m�0��ҹg{�E�a:N��^�f�F������� �RlzYuƜ��ߨ��7���V�m�{�U�e�M��(D����^��4�f������x6��'L���~~68�I(�L�:�%���j1?Ul;���x�vf��u������9�y��3���
2����iA�'���$ᓷv`3/nK��Kh�㍑>�*3��H��CI��ɐ���f�>�����Ƿ�E�f��,�)v�j�X�&���}�jq�n�r�w�G����y4B�'a|�7]#������!`(BY�#@�M�������%�01��X��Zw��d�\3;Sݲ�Be���C7�i�
���v8m�np־������?�8���&�+�ݣ�Hy�oeʏv���1?���
\��HCي�WEY&~��-�em
`�6�� ��DZ.\e}W4]��eqF�R'nnX�˗�j���ՐG���ެ�K����|��\냝�W~ť| h���8���#,�>MG�i�� VO�]�t���@dkA
��XGf&U� �}T�L'��Tu���"��<2c}_��W�T_E*�U%��1��!�1#}�`WM,[b� dk6j&��L�;����M������t��MZ�
�m6�c��@
��¨P�@
W�R����Q6fin�v���K�Pa$�������`[sj�|���Dž_Ҭ�Hc���j����J��������R�<+w�+;q�V;"�S{agG?>\�$�0��0Nc�wLG�������l�*�LVrv���8���� C� I��ѵ.���(
����8'@� ���������vl,-�(���0�Ŕ��fx��J=���{I���1��9��Y���_a#Kj�e�ΐ2N٩u'��k(�V��"u7���(��S-��u��S�1�|n*'e�$�J{�컈�9��#q���Ō�˰��pq@}\���f�;c��y�q��;X��"���E�l>���
&|�6��o�N�i��D�m/]��pdw(�P�~��ᓆ�����ݧ�b��^q��S�Ď25����oo��7��`}�z {���ӎ���L���ޭck�Q�=��=����/��Y���\7�=Lj�^[믡����%�k�n���1��*F����ؿ��ȼ��t
���BH��Y�7o�� G��C���%���#�ìcs�«��j4�����P����
����&7�#1OM]s/�]�O}�Z��a&������{�Ҽ!n�Ň[�/�@I�y��H���C/�D믑f�fb�N}�1N��^e�J묟���R�/(��b{ʘ�n�A�s��,�uk�/0/m�:�rH������<�K��)b�dMho�6�Q�{���%��w^b�����Co-�,��վ:��0�e��s�%E�G���պBV��_o�߳[��naO�"��%K��Q�� �"�z�Em1s�r��q�G�����{$ ���w����j�d�ȀVsOX���1��.;,��Z|�uP�����p&�V�/���'�}��<�_{�z��SM�g~�=,f�c���ƨ|u�+���G,�k�0�T��_n�iC�y���� ÅvZ\<�Y?I�,�.\�1�N���N>��{�z� &�և���b�p����]�! 4,��1=���B�|:}�-@n�b�5i i(h*ʊ69��d�p>��g�����9�����9f�����?!�!�.[
0��E"Í|�<@%B��&��,�,���i�������G6�$�u9��u��?� p�J���h�;�X�i���A�t�� v��,��;[HݶY0�)ѥP�B��֤uۛ:~��mg@�9�(���Bvvp�a!���/d� U�5E�¡ocQ��jiZz�Es��Υ�T��[��68��M-�Q\�o�Q-m�v�m!��}ʮ��P���<3�2�J�^v)�������7��~=��S�R�䫗����
�ٗY�͓��S���b}��#sm��Q����� ����_�i1�)ߐg)�����]jU����c{�*�V��C�H�ć�L
��4���q+*����J>IGy�˂U�Ɵ ��hผ{���5�ݘ�͆e��k~"h����M �#='!,��L%���g$�)����t�yGfK��䜦`�٠?0���vOp9N}�3�k'�8�[O�}������^�~z������ ���v�1�a�/��~'�5)�mM��J1���I���roGj7���
�lp`l���
+Z)Ͳ�=��ôyV�P���f���ک�13b �TtL���������p
z�������1S�����+:b�X�.M+�dc�9�̲�s]p��N��:q�H��k1���s���9�+l���sv�|����l�������%����M��ɂ{v�����I�
ѧrqiĬ�A^E�G�4���4l>bI.�/�z���k��;����-��w�q+|t��$!��qKg�����e�"���e\���%�`}(>�f�H�{R4�
_���<�L�m�Ƴ}��}�-�'���4����}��;h���e#
,b
i������Q$LQ`��UU�̥4�eE����qs�f�6�h���TF���#��*�_�x#ep�]ac�����E!���{A����'AP�{������p.iaDmKT�T1�*���{�����Wa|F<�rǿ���%��U�L��o���zeh⋜�8���⛬T2R�G�c�O19�Vɪ�'��B�0���'���!��M��S�@R7������7�\�-p�QڦKM,oW>sDy�b*lԹ�~�{mKW���W���*1���[��5��+�洈2]܂TA�.��P>qQ��Mo�Աh��bKM�}I�3���U�������2�YR��Q�����K� QABR��^/:�GL��2���U�|�������_*S���N��v�I���{DM�Iެ���[�1n�p"W��U���dC�p������.�u�-�����{`���鉡d�Z�S�%Q��r�����vd1�ā�=d�B/��$��C��SM�J��+�zrP��a%7֡d| +��O��t�ƭ\d���������Pp�\��]fD>%I1*�_(/�ԫ���4��ͳL��(���f���p|6�A�Y�=�2S�ݎ1������H��fr`���N8�>xҪ��Ю�T����gi x�v0+�ͷ��"�1����Ю,�Ƈ�?�?ǿoq��:�2�^l��`}r;յF���(;��%�k��b���cb�u����-�����K1�P����:���a��"�����#�u/��y����ݳ��膺2�c�O��O�>b#�܆���)��:�_QSX�GOl]���nF|p���8A4.�)f�~�ћ`ϵ�*�S����S��ՄW�c��C��z��:>t���!5C�|��p���i��=�[�p]���Q[�b�Wt|��1�f���|)k��]��t��(�ws=ɧl�r����|��'*�00┚ϴxt(����1/*�:F�J*�A3�f���\�%���P��1���F J~�X�OS�|����W��_
%�g�|�����(l����$����Rl�SjC�Ԥð^�쒲Z�Y@i�K�|,)��}��aZ�����$!���&)�����g6@kd©^<�t�V�[b�Q�4Ԥ��-$���;l1��u�N�b{nwo�Ng���۞�j2J2�:Q�g;7ܭ��T��Q˥��qt�Uȳ����7#�9�Uk��6�;�'�������}~��Wz�i�z2h۞0�e��x3����t�-P��X�*��B1b����2ĥ���ݩ:M"���l���Ab��0���p�/�\v8�>��x;-�p�-iR�:*=W��W��`�p�wv���=�gJ���v�X��T&�@���k�+�����~op֓ﺔ�d�Β�@@��C=�/�S4CY�H�y׳<T��\��F��ѶY
����W�1�U���>*�V���Iq���7u��X#^|����F6
a�Ɛ�����F�m�x��s/���x&Vk1 y�S`!D�zI� *�f�{��k��vj��͡����4g�8���ɑ���;E��P�QF
�{�.���1���qǠ�,���u���mbiBFh*���ޤ-R�q�װt���iەv�n�n�z'��Uz�r;���d��)Y}�����qz�,�87q$yu��J���-)��招��Le����>ټ:�w�e�):�?߾z����o�>���燐/��@�ެv8������r����.z�_����(g"����/3߅���k7v����`��gBp�!��g�fdM��-�EU��<������,�<�W�qBMuc���t��\f����r�(Y��Q�:#U\���z����7B����p��˽/Y����,�t5�����3͆|��z���ԯ�(:��Z�f�y1�Luq�1O"Oj�\�&�q�.h�s����R��+.F"S����
l���7Gܗ����Y�}�`����q�<��M�Od1�j�j��:-NV�(�w��5OOZL%��Z��їiK8!pЉ&z�>Y!����B����)��jEu���\�h���DoG�r���Ňp��F�8��\���#i}�>s��zh�Qs·ې��.�i57$��4qn�.7��o"���t�bm��ՇK�D��)�c]b���=�x7Y7�ГrYl==���c!��X��rn��3�㽜�=�~$+�JS�T
�
�7�:�1?ӽ�����|�7GԵuN���y�6�4P�B(zH��y^�B�u+��J�zd؝� K(�!�{>����(<���g!YH��Ze$̰~7/�>��6���t������J�N����q��.�
ё�7�`�K���7�3WĿ
A�I�n��?�i� �����v֊V��W�G����2�����4��ѳ�H`��(��(�R]��,R��w
ea�Ŧ���V�$���k@��b'��O��x%�t,��>m\���ר����Ƒ��K��ޭe
�u�ݙ4ʴ��7X�p�]��3l�w?�akO��#�|b0�W[�ΰ���}�
[)�aSa?�+��PZg�m�FEaIJ��^��V���kv�i�����/skBJ��΅��솔��M�h|A}L�'{��1�W�Z��6���{B\��N=Ό��u�?�4z�'_Ð� ���@���
�D���_�ľ*2���:���QU��;�W�NA��gKVJ])��d�,�7��S���̨>dUJ=Ğ�#�!�l���:�:A�_J�ч/]P�$@SO9�`��h_ųmOL����^ "�(����4l��j�':Ԫw=�Rl�G<�*�392��]*��M�"����P�@ehc�Z�$ԁ�(��V��F������%�����}��u�W�%R������}u����q�S�o1���68���6�#����V4��/���
��8a����:X�N�ۧ�[����H+�����֧��P#n��~S�X�J骬j���߀��fi@�ӵ2Mߊ��p�o�^��`�N���@C~���;5S�r�y"�Nno���ݟ<�!'M�~
f��
A�Za��??��9�wK���v��$|�,~�%]��IH^qSC�[�U6_��[�piC�ɫ�J�U�B�q����Z�p��|�$i9&�V
Ǣ�on���tJ�=�^�P32]0�a�I��B:Hwm��M�%�dq�Rʦ��\(tB���F|���iR)˒u}P��A�V��H��*L_<�F��D��=K�[��T����s��O�w�3tf��
Dx��5�@,��-�6^-���H����y�y}�Th�� �5*�B���՚6��@�±hic�T��j��t����Q �^��:@ 2FH
a��0tZR�S�F���as�f��H�v��0R�N:p.��Җ��;��Ø&e�_(��QAο�d2�*/��̾���y�8[|�FɅ�
w��U�3�a�f-���6��I c���l��]a|���_��-������տ�v�p�C��T�@m���Y���p�4+
є�f�(թ_Xy!���h��/lwl�ۯz>(��ᗯ� �e�HY��)��O'�م]��KBK?�����Ӡ{�/��]����e&��n�9j�
�CF,� �e���/�����EY�s������[ ٪ؓ0���%�)�B߂�bdPn��D��O0>՜-�ۓ]�=d�K�q~W6y}(���JQ�_����3��Yb�����p6C�P�4���^sF������m��@��]%-�v��z+���^H�ed��s��_�f����L�͉Xh;�mO�n���O��)We�qq���ʃ�m�Xi�POݐ�ff%|4��1���� �8�~JH��f(���÷|bǕ���?eo�:��9>Y����7T@�YSay��9�CS���ۙ����8nV�-f+����r3
b-�/25 �>�{�1��c�UO-��Ua�!Ƭ?�G?����܁�m�����Ͱ��'�iGe��UJ��}rn��K���KH�.��H���^?�3ghB��=��q�.����4�9w5Bх�{|�>��Mx�F1q�Ύ��S� ���Ǿ�������p)+���ԣL��>�C?U'o�d�-��A4δ�+2%Gn�p>�̰ʻ&���3N��*���(��m��K��� �aH��V�U�|��LϺ=�f]Zk��)�$��_,4{m��`�]�p7Sm����Q����Q[kx(\gc,Am=�i���:�1y���V��H�7�7�̔Y����'[����%�!>Fm�{�#��u�,�_�S�����ͭ����W�u��R]Z���Ϝh��5�_�3�;����K}�����(�-��u'��oa������:]���b�w���"�hy�����tJ4/*���y�r�Y�
�!��;��VN����C͘�p���1�U��V��<�2>,�8�q���BZt�1��fH5Nt�:C�0�W�O�
�d���C�"� 3A����앙�h�N�4S8��',�s3cc5�/�s���8���t]�aqM��������ۏ���=������c�L�,)���OkK�����6�ʏ��=T��t�<����n"��)������Zr:J�[���K�/�X�t�~��s3辅��G~���1��+R#=WOHP��T�r��5�Ss�
�+�NC�=z�:%����W�`�i�����;�{>���d�
�2���"=������! |q��p�Q�D��4K�a��z_}�M�V^!�M�VEѻ����U'A��r�W':��J�7OA���pY�x|,��> �$���Y�3�4��+W�V<��zk&@j
)�[Ii�v]P�Y���� l�K�o�棜�Gb��8�g�N����PR�c��I
{�`��p�דB�I!�KbW.6!g�AN�r������g���
�h!!t�bB�ESs����Tr�ݺ삣�|���'��6�Z�8����!-�6�������8i��<2n�u=��q�^3�;��*
��"T�������GH��4)Ƚ�h(�վҮ1ɭ��M�F
:��C���GQ?��
]%_��ǃ�u�<�2�'�Υ�Z�����X���Vo٣�u�jM�7dFƤ@٤����MX��3�o����^�NRyP�2m�RQ�L���Kd��j�\���f/;�b����|=��s����TX�b�:�W|#�Oz��L����D�Z)��p�W�%]a�t�ƭrG�NҐ~��B��/H��W��*]�P�� �%�tK�V��O�<��-���T���j��M么����)!�#֑}�wp1@�o~һv�e\o��jt�6��v�����+sT��F|/D>
j�PX�:qp��/|Bc[���^��$S��(���M���PlVaה����`ɚ:,i�a��k�3������i�pi� ���t1��iej�n�n��NU��%���P
��?Sr1�O���F�������[�3;Sk�'��J�Y� �<������o�~��~���ع���c:m�/w'�Ԋ��v�����ĵ�Cg����z��2|ס ��6Ӌ��\�V������~�W�I��H��#J+?e��Dk�HR%�G�0�ݫ�`fw�N��f\��4�8諭��}��aU9�H>�[��6�ݲ��{��`�[~���Ż���>9&{gZi(���C�,A{M��=�bi&Y��O]?��/���#���=e���6�ruKh��''��[����4��~j�g�q68��\�b�7;�
|q�C�0dYWG�/x��{G���uJ}*���|���8��:
����8�Oc����j�m�'�y}E�D�g\�X6W^�8h-����������u��Thwvo/���YrF��MX�X���u����\��4���7��h�׆-%�9@���2��u��?��|-��J�\�7�ʕɷ�<�BK���b�/890���l���P�%2x2�l�<�}���!��p&D|�>�S�̣_~)���
k`���,_�-�`9צ.�S��}8$����+���V?Sqˮ�=���qYbP���:;IG�.���� #�E�SR��'��(�a&�S&�v�Yp��������Q��Dty��
|����A�����Nf�<3��]�,S�=!�nV���)���(�^ғ]��o��O[���3���d�� �T|b��h�3c
ϋ�g���it\0j���B��D�o2זBr"��2Hy���m7,�"�)��7Yt�4l��5��:�!$��q����l,f;�S��E�^�Ȓ���$�5�|�-��,öd�:�5�� ��.��g�����yR麄�%Q
f�������l���eS�� m�Z�������o�Эa�Ӈ������K|�y�}_6�z�Wt�8���؛�(����X�p�^�?S�"X5M����r�7�JȘRoO��23�@`"]#�5j���q�/*bK}��l0�ߐ�'�������G���H����Q�]
�@&�lJ��� ,�T%�v�����b�}��G�{����`���řG�ڦ����
n�Άʐ�����v�O����%�CU�J�nF������)=@�I���<�#��O�'Cv��NwU��z�}�o���i�5nd%������+��8n=ϿPER��V*ߧn(�\Zʒ~���%_ �/���dXٓFQ'L
�5ChH;��|��|j���9!��z�����Ο�E�鮃n�9�Q�)�8�yR>�a�7P.Gi�1������v�E͟�>��gt/G����vV��nj#�����$_ӓ���t*y%�L�^�.��LJ�˥���r�Z��{�������������ϾXpk܂jwA�x��,~^I��QMF� d�T(d�^r�ű}�Ii�ӑ�hS��^������f��n�i�_o�߅lu�BJ�qԦ>JҤ�̵�r�z�%�����K�_�Č�|�so�G�Dȍ�3sӷ"�2qI\8s��Œ�{������&�i��NJ#p}Nh�'_����ao��
߀�Cu
��?�&�@xf�9��[��j�4��O��.���*\^d[Da���\RD ��:���y�,+O{*uU��:&}�k�ɣ�6'|�dc�">�{�d�n��9f?�Ri� �/�������)C����+�����N�|�3,e�,�~������nR�9(&�Y���@b�3�Z�r�2V��Fu�|��P�M����b�����!�x�8�wl���v�]��nEش����Q�S jFƔy;V��=
`U]Oe;\iv8l.G���^Bg߽�Ҟ2��?�>59l�u�i��}�,b�:���oS��cT|�-H!�3h��|p�|P7&��{
D���H�֩V�z�4�(amg �c�l��;���!$������8Kf?�q�� g��0a�]b�7�G���
�L�i��
_���\���/XC�@��0�q��S� �XAL`wG�>�E�7�������9y�������9t9�$���`#�� ���q=1�o��k�_8_�`�@18{*͒�\,��� �!P�UP�1�6�~�����1�}0��
��3S_V�O�t�9���p�F]u8�q��5`����y��p�搸�ƴ=ގ'���
���2��],�;
���w�$�X
&��0&wvZ�{��N�ޚ� �b������ew�IQ*%�.u�^ʻ�tә�΅|�����o�qF�H��n�N��%���y��Q�룃a�)�6�N�(��QE�c�!6��v$��2_,���oo_=�}�
���.��a��mC�7��
�W�>db�E��b�#C��%+r9�(z�=��gQ|��c���/�,�cg*���(iPK��Y�\>�,i� �Q�?|(=�~"��c�ɿ)2�łb����*���'�&�p��g�.s�_+"�,�>
endobj
20 0 obj
<< /ProcSet [ /PDF /Text ] /ColorSpace << /Cs1 7 0 R >> /ExtGState << /Gs2
22 0 R /Gs1 23 0 R >> /Font << /TT1 8 0 R /TT5 12 0 R /TT4 11 0 R /TT6 13 0 R
/TT8 21 0 R /TT7 14 0 R >> >>
endobj
22 0 obj
<< /Type /ExtGState /AAPL:AA true >>
endobj
23 0 obj
<< /Type /ExtGState /AAPL:AA false >>
endobj
25 0 obj
<< /Length 26 0 R /Filter /FlateDecode >>
stream
x�}[�#�q�;~4
��Xb��h\�F�
mY�������w��Ι�������}�]��X;&�L����Z�Y�?��y��us\�uߟևc���v�������{j֯��M�����ձ�6}Ӯ?���a���*���������w���ݼZo7��9���ѿ�}����S�:�=�m��e�9N�Z���,�nsض!��;��|��4��ߝ����a\w����1�@W�]0ø�N�f�o��r�����~�n�mg���9v\'3��=@��M�2�>�$̳?��7�m���6
�
���~{����r�v�m�@���
v�q� -5l��i�e��a��i� ml���VAI�'?
��@z����ؖ/�A ��'�֡������$G��4XF:��cЪӾ5�AA�ͦݟ��L�sm�$MkH�y��y��t
x�4
#%Ǝ�t�o�������v�4��v��G&i�H2ގ��H�ssܟvi��t*�f���$9�V�IҴ���)�y��Lx�4
#%�����/�O�����v�4�����n���H2�e���A�m93���f�ٟ����K0H�,��6�Ӿ:=�&IS�v��/
���;x�4�K6� �����$��F!��N���?�����c0"�D�s7���|I��$9�V�I�TC��yZ����d�?��L7��+Ai�i�(#c!�Id:�*i
��3�vF���t�Ƥi�o�4�$��
6�����3�is�v@��J �%�jd�Ӳw0L^Տ¼on;U��UM��i�&y;�%M�nZxZĪ��`Ai��
��*$�y�![�� ٵM�IҴV��AL�{GO�imcۉ�i�����Hr��L��o/�&8w#i��[O&i���M��5$ϼ�%�{ZG�<��`�n��6
�͔��?��\6�$���dp�L��L�f��M���g��rz�i
�3�i �֓I�s�i)��غ'�n�l;�6�Ӓg�̼�KS�vd
6G��P���^�
�?L����{̿�p��f\��@^���*3Ji&�<�J�G����'�b80�AW��Hڮd;vF�&���땡�e���q�t�-�,zw�a� t#H��'�N���� 1bZh�I������(2�E�@�$�?q�YO�p'2�V��*Ơ��Pb���Cr4� ���3"
f=�;� Ħ����#ݩ�]lk���`&��!��l�0�䦭k\a�J��*7��`�lfBT�⟡�$'t����^@F�+�C��2W��&� ��uۻS��H������.͆γ�7���s� y7Ј�m7���`W��_5afkbŊ^D �\7 ��8B�÷n!�L��v=ɡrC'+^L"�Z4I�)y�N$2�Er�C�&]�t@8��^���Kzϐ��{M���\�J�j���T��:���9U���H��`D:%7g�4��"�ś,��H������N.��d��
K�Kn��"J�!�d�JfN&O!)9��*��#�D�$����np���*
) ����qPo0��J���Nh�[S�B_t/M��}3t�]�ġ'5.�w}cr��X4�S#��eM�1�xzv��].L5���U�a���)t~%���9��LBtmK�����H �&�,
�u�
Y� �SՑ�S��ؔU�O�h�?���i8C��f|=���R.J��Y���Idj)�@�N;��1+�ތ��ޔ0��їܰd��8b�}�m� �cp���d%9�.����Q4B$A�"ZS�6H��j��4x�7��D漑D;�����0���u�t@6[^��S��t�Z�$��qe�U�gꜯ�TDfWJ�ЙK�U0"�}�e��.��_�n�4����Ę��YA��0 /�R�E/B�$�1s
�,{�7
���;DN��i��+�=���{ /�O���bH��b�u
ͳ`�$���9/
�Q��A��V6Uoq� ki���I^����p:=.��\ C�6�� 7�yN�
u55x����˅�����G�̣�R2� PIP������\O2r�+ dۙ�TC�-H^�y��)a�d)�$i�$�5%�+���c��c[a�f�r��O 3;U7|#�TV�
�%i��8YҺ]?�x'K��H'��ѭIf��d/.�s1���t��N��yt��%�Pهz�����BS�����8��*�B�hS%����H�[��w�� ؏�m����ӯ���x���������5�(����M��̱�V�v�����/z܅������ÿ><_��f���9�ޭ��}�ݭ^{Z�~�mv�����a��5~|��~[?|���l�_��?��|�!u�?Q[���O�4�x�����m��@ D��sK~�ߧV����a�����/����^�g�����ϡ0V�0P�)�����(R9N���q�Ok�ɡ�
����%��E���>!Y1���O����~W��c�
�� ��X��KDnHA٢b��(L���a��$����I|�ِr��N��������/{ew��Y�‿��YU�!�K��ıK���7Y"��9$v���0W�Wɭ`�<���khaT��zK��՜��(��������/�m��dD�_;��m۞|���H"YM�3�V��EH[%Q��HXV�$�#��t )��[K��O���BI��W �A�S���Ƴ_?���㳅���]�� U#z�� 'N0�_�f�[��a"!n�m�[2!͓�H\Da���ه.�d���
�3���?e�Xo�lR�Js�����Z/�Q��+��ҵ���1u�z8����.{�z�J��F4o4F��o���V��u��,��0XuV�N���;����Dj�Ո|�ey\�68`��M�J��pB�0}�)�lQs�}�x�r$%��2b��&e���]����S��#��dz�JjU6U�D'���^�c��1�%������)��|�M7[�A�;��ɞE(�Xk�i!�҂��{�A�O�PW����`�G���-� ��Z�Esr���4��|^�[y/&�n���]����˷��p*�����.�:����(r�0:$�}���K�C�á��������L�O�R����������U��Ux�r��)əi��v�S�e�@G9�����|*���M��D��擼
�Խrm��
�Z�D���:��k��w[T �R���}������Ev�7x���Qe�3��OD֢N|
�[������_Z�y>�e:��Qx9aݶ�6D���ا�mfvc�JLg�>�����_~z4D�)ٯ�$
)|Z�By�p���}�0��O����3�~D�
����!����:�Z�����oҴ�n��w�#�v#D9.��[�{�����B����R\��XJ+���j�̲W1����-^����.��C��痟�Da�Z��`���d�Nsd��Vh"�pA�z�m�R�a� �%��*|}w��Q��+��霁B�q�ԑmQ#EYO�D���!Kgou�!.�·��U�?/f�|Di��84�(MɣOLm����ɣ�JS:C+��곪�\�z���a qL9����q,�_�ʐkl���=Y�P���}�'�����<3�C���c���Ǣ�]pT%J�ჰ�)�*�b�23�����8�K��9����Mw��_U���xH���GI"�)����?����̻��?���
��5䌥�KaY����y�������UZ�y�5��$ �xE�s
��U���֞�}Vb"7�s�6�:F��tc�x��\��qy��e���q�&)���`�8�tr��d*��}��VR:���=�r��1����H�zxdk�55����E#_=����R/"R��O4,�=C\"C��8zMY�X���w�舙T�c��Z57�� ��p=�%�sťG�o]��c"��Y�l��?PTl(��A�����K�Ȩ?��Q�N^�o��/y#F��1���>Ɇ$_�a�#uQ���Iک6jC<, ߫�k�^b��s�\?RF#��@Q�H<��p�"c�Sti�pHd3�2p�8T_#�T�4�a�Ĕ�K��.$�:��р� r�R���+𢡄�R��or��P�(v
���5bq/�4.6$?�Å� �۰`�>�]:*U��t��t��Z'4O��C��"��NM_�咻26�BqHO���yM��S��S��|�
�ג1�R
���5�S���#v@x9�"]i����p�EO��b��R���KpD��������:�������g#u�[��Dj �����/�Ow�(�͖;`XW{��#L���7�ƂS�bJ��7&2��l���Y�T���e����B�e�5/�#�]#O�ޙʮy��0��L�u�ep�4��)<_�� l��;� 0J���3+:!ӧɢ����ElB�]���,�;&RP��^�����4�2s9S� 8\�r�1!��Յ�F�lc�.�t�!7��y��H�Z�<�l�0�m�k�����r���ЛSJ�x�&�Q���8���";'�jF�3����_j�
Y�6��'�)1�b"�2�SdX��u�rd�)S_l:�6�Ɋ�%˄���{��K��=��9�*�w�1�����C(}]t�
K��p�ɉ#���$
�h~��M-�����'[�\���#���H8flO$\ǟg��Ŀ�D�S�'��j�"�$Ji1��ĭ��,1���C�ڰ�2���,!��Y�����Z�������?�r�gi���趝L���j�8��,%] �O�d^3���I�zxC-�
J[ٛ�wš�S鹚r a[k���췐��-ژ�7���j�X��� KGf
f��H��� Q�Yٶ��;y$
*C@�9�GJ��Tg�)h|�h�
TաTإ(#����_�t^�Kq���m6
��J~�.W2��t���]�C6�����;Ӗ�U_Q��p��O��V�C�E��n*WW��}��8���RvRN�\�S��lÂ�Q(?��6�W:�-��H*��㥅b��b�h��f���͞ز�G���qW揟�����M�A��ˀ�2d�8(�z� ���>v�@>ˠ�aS]�
'j��~Ӵ'\J�:�r�A[�8s�]S|�P�*�?ɸ�O�·��f��H9"5欎%
w�1N���b��+����
�yl�v�Ƙ*���M�>~�
�I�a�,Fe��bm�AzL^\�RZ��A
���`_vXI�]83�jC}���j�EJ����d�aQ$L���(���* >J��'n�-�e��(�4xc��+k<����H�*yf!�q���`'!�� ���C����Fs}(�������Aȸl�d<<�G
5j��}�-��.�`�:���u&Ȥ��.���c�L ���"y�+lQ���}Rw32#����o6�x���G��2'�M�#��M�z���e�`r@��f.8�*��A�:�j۰I9\�[N5Y ��]�MV�������L����4aDDF�I�t��A:�>�C���m�C~�.eʂ�D~Z��h����V�a��~�T��j�JGr��|�0=��UG��
�z�g�h9�!%VqpT�����t��ԥ�U��ł����Vc�'�����37�$Y����Ϸ�o�nqXg�ߌ������ٓ��Nzo�
q��\ v����X��fUZ�&�k9'U�4��D���u��E6eWP̅Ԏ�D���:y
T�/K3O�������J��JE�|�^�"'h�2�;*�'<�guGG�\ʹێ���*��w�����xs�d�����͑߈&Ŵ�1&��eѰ�4�Ԇ���9(VJ�k|��gXJ`
�o�ͫ���1,��JlfgS��J�_e�ƃ��ofB�mޑr��:�;n�S��p���o?���:�<�ZD (��CІ��r�-��6�rJf�@�j"�sSMI^�ޢ8Z�hB��������hԹ���'���B�v5�>ܤWR@�O
��8m�Y��*_5�т;���>�榬%�C�գ��WIG"�^�[X1&ujJi"�נ�}�>�K4���t��)e��&�}��ߑ؆��L!�|e�O9�B!Hd��$�ͅhJS&�0!Md9[�@7wr�pax�?��x��4��c ���y�� ��/Ğ+6��K-F25�>�-88��S��F�J�O�)�����(�8PD>�����K�����N���_�A}Ժ_����!k��e��6��Z�c�>m3�XK
��ʭ�6��l ���\/ &�aoz}�� &Eۿ��ّ�y�6�+��]OZ�d�Ry�,�!k�=��o�I�Ҩ��,kg�cS�=���*�q����_?��z�y�p�i�^IAF�hz2RS����"L��������BĊ5��U~�qp��t����V�9 v&t�%l��gf�"���6�z��>�eIL�D���>�4w�'֡$�u�n�o�` mT�
%�)γZ��*�ӡ��Q�R�%���T
� �Q��'F~cq�Ym��㧮Wtp���7;���ro��9��wq;M]�Өh������֦�c�&^�D���3S(
�x�7�]r7ՃU�����(0z�Z��W�8���m��I����,G�?�Io,#�e�Y�P�R�~��]߬g��ZJ�����A0k�^8)A���p(J� P'�ěJ|�G�;I��RSB'Q��ă��X����_�W��~H���!��=x��o��B�GLR)5,��Y'[��d٦R����T3S-K�^(f�v��E��{A&u��&T�Z]�ks�_?��,����a�m����s6����v�U�,��W��]�=�8�&�P��ܡ��|�x��^��1D�#r8��A0�8��m3l�ъ3��v�˥X�rvVYN�&$�m�ʢ�6��X0 P�I
{v�'��=��E���y0��4��`t�����:;�J7ՠ+$�
�& �_@)�D��_�
q��m�K�v�/tD�:Nglp1H�ڵ��b�eg9��v��IdY 1RҔ?�:9<���]��2.����l��iV�>��s�e�Bё?D{Iۓ�(1�+;�04ѧ?��C��nU��v�Z��(�*�Y$�#!��Z���A��ޒ�F8f:l@��߈�/�LouYZ"�B ��2�%�e`yV��^�&�ea�D�dޤ6�st�"��'%]욨�b��;$:̍
����ࢼ�F�ț�cBC�.>�ԛMa��n�hW[�rH]�i�^���.�~^�y�i
۳U���d��a��"�U��.���U��3�i)O2T嵱���)�AY~��z���k�D?@!�wT
��_�A�CAE�I�d~I7!Ӕ��ڤxA����#�C�Q�9\�96��Jv@�%v��k>�k������-��#Ɩį'�=�dF��[u�;7�x�R�4�q*"5p���R���c
��������7a������e&�������e�c���g+�^{�h�}�~�v�;�=r�p�|ۇ�{x&9����M[�F�?Ujp>W��Pͫ4��OP����s_,�<}�v�����=���G�މ��I��Ƶ-���})�!�[atꌴT.�p�/�e`�OH8�:���6�!�:}!7����k���l$7e�8�R�9˦�&���Pq��A(��L
��%C7��-��ˀ��]�SL'�iCOp(=��n�[5Ei˘ܗ,�����()��p�o�7��H��|���(.�Q��^�YRNFZr|,����+�#>t��\��`���������P��spu�����F#l�p����oDʘȳH��V���[$[2H3G�?���S߀�M����s%u%��+
�T�v���˩e~��n�;u�*��p+�U��\��]!cynj�H������2����2f�AaQ)�F*�jp�ަ�lð�&w
G�@8�K*�:s��\��w\�s7 �� �{��y����> �P��,�[|�_��Y�z48��/"��rT9�詚w�R'I�Ɲ�^=8)D�S���[Ѩ��~KH�>(�X�\�~�:n�����*�J)��?䨢d�[~Eg$�}�1TzE��(v/��7�u"2�<�=N|&�A����/c
�M
ROw([!�N�N��D½�s-�����,��3�Y�w��q;�aP�\HQ�@"�\���i���8,���̙\�-$���8��cB�(?]�P�J]��E��n���mP�XT"�9gtǝ�XGY*ܳu��j�����́���M�����N���=��CY�k�ð,4\�K����5��Z T���S��S������$�Ʈ{���[�m�N=�[M[��q��#/�����E�!��Ј8�Pl���~�d�36�}za�-�8��hdX��m/L��2h�j��I�;�a�f���|���m����F���VJ
��"�4�ߛb�J�[�Y�+!��
ۙ��67̙t+��W��]�Y�t�t�Lx�����P�{�M������y
.�1*W���2�M\���o�۔��'`�]��C:��(�u��A5E������U���g4�+R�P��P�&���cgiP��3����/Fη(l ��6����ˮ
k�ճ�Ѻ�Z�/C6�2M��
*���ƣUح�⪙ʛ\b2,c����<�J��%(�lq)dL������� �sCS.�?����:.x�������2r�ș
�(*��"
��}�`��=��b�^�*��8�%�TD�w�u5�Y����$a:V��ωU�&;$ު*�-Wm:I�"]�.QqP�;(]��Y�N�r�|�����7'hY9�!G�T����v|��i��g�NgvT
H]��Q�&�s��MQj}Qn᩻:[��AQq�yTW�'��b�'��`����Z +��;�D?�/�D�e�ͭ���m|, �����az(����|1�"1Pk�c0]!��b��W�A��&�e"�ȸ�Z�.W��{��+%�x�cv�����^2\�zs>&,�g��Y*�,�a��W WL��}ią�齒���JA��i�^��L�_~�.y#9<`�oQ���"����/'<�DP8 �l�-@�P ���
���
P�
�l�E��Q�}6Sk�V��mt���ى��i�x
S�ӷf��¢'BL��,w�=d߸@1���6[��|�[�B�Iswh9�� �N��x�.Bs��M�Hl5y�P������E:�<��tS���B�N��0B�j�B�h.��8��Ib�V��8�pn�Ύ�'6GN��oF
O���b�8L�
*�sV�u��.7��J�Ե~v5���2r�L���cIPb?��/SD�T(��a�7r�y�!L���2Vē$b�o�D3�x��z!ύ�D2&��V�&�5
�B�8_onqeX�Ճ�L�'��!��M�9�$*�d�^��dq�*�
�}]�.r\�qv_��
m�e@T6��bn�N�C�ә)A�s��L?�����U%u����aLC
ꒌ �
w��;�5{<@ﵗ���o�}[zVS��j�X���s�N,�9�{2��}P�5����T�](���8ъ7��^������٬�b���#eie�Y暓���o[ퟩf:�咘�vWʹ\�;R N�WLZ&T_�X&{���ak,5���x�^"�bX�QjP�R��|�W��v��b�.����7�C�H%��>��b)"��_A7�Bt�X�ɱ�������Xp���E�w��nj7�C��f��v��v��}����?��U�Q��k�����-�)r���n8*�T1}wOb�爣���n���Q���Rc���"0.<]4D����ۏ>������]�kS�����ȞU�Qŝ��ֳP�Kw���O��:��%A��-6F���JXZ��c��;��[�v��uZ���`c�0l��]���v�:��e�M��Ճz\�c_�}��+<�"����=^*�/r��Nh�����Z�t{K��?'D�MN�K)���Iα��
^� �+�Y��m���dJ�;4%���ڔ��HE�=��߁�C��s��c���F���sb�s�=�����>|ǴH{��n��_��Q��J����w�#�r%~�
>
U[�J0/>|�?�>� 6ثC��wHX�.�6��M�#��=�{�������v�D�_����sVFo{�-���d�b�p�O�l˒Y����t>��SW�P� rj��R��x���ŷ�ۖX�`���G):�~x6i���V�#5g�ݖ���舃�57�-�,xzg���Pb���u��@�&�B�
���er�ؚ2\~�H�ck���%��2����W"���ˀ����Q[Q���=W��wq9t��}�ݜz��1�E<�#0-
^����6=��D?,
s!�j��;lN���Nch�̻���-��`xc����c�J�[?�\�5�������g�P��"@C��p����ۗOϞ�扳�Rt����etNa��!\��':D6��J���X�z��ł�eE�|0/��m�C1�R�P��u��5�Hvwc̖�ň>�$��?p�-�}�����rR8�5,#�i��b�N�(Q��i]��U��bH�Eռ^�@�A��+t��P�`�O�zz���D��Ó���|Q���/�\�~���
�j��|z��3!���o��}��9�%&���[̯H������ �z`P�A��l���/1�~_mX�6��z�J5�:j�0]���
֓c��--X,c��5�i�Ϫ�ή�9d�9��'�%N6��}w&��w������km����G�3��K�̾n^�y���s��j�xF{��t�43lg�Hv�wd*MT
��T�D�]��#_-�=s��[/mBT�� :��s㤳�����p�����������x��/?}��/�����ř2b\B���~Iȩ�)q��M?����yC ��&�"�k3~�w ��Z
J}Z5!�p~�"��!��?��:���,�V_Z��m�E=9j�X��A��
7yN��Rr�p�V��'�gUn�N���r�F����n�[g$QT�2�k�9��C�s��V�*'�sg9�v���:#��J�J���eߨd
ݢ (�[+�����H� Yd8? ^U�2�ֵvT
�@_�D�Q�/)�lYV[�R��40�N��?�т�������2o�*�E�����������|�1-��w��_?�Y������//�ʛ���KB?��!_�����Cm��2�������m�;�;�u��q}�:��2�5�����G �U���p��j��t&�:�R�AC�����n�;,d8�)�;.'�!1㱫?}�+,�\���dQ�fu�齦 O�
R�tIɔ��/;����J���
��15�AzzZ9�]z+y~�}�s�eL�.�gU��}������ձ��2KB)�����d��ܛ�A��rQp���r�CP7&2��4�7��z���>��u�]�M�5��A�
�-b�N?�nK���pJ��q}�o��r�����_�t7<��I�UP��sm�b�M��9�jQB�4]R�i춻�4�C�G(����^v��X���lP�Nښ� f)�߂�0�ɭ�D��j��'%#���1^��VNl,өU��GN����?�E��S~*�D�(�I���Y�
x&���
;�m��9f��\��dgf�G}���_,=n0��>�-�Cf
����/?�e���5rq,��v�Ŏq�9#�M���I��)UD:�_�lbʍYc)�DR���qδ@ �Y�mJ��2���SX�GBz8�lK���Q�lj�[�5�h��L���R����a��U��hx��c9P�8�5��)
���:'%?�^9��e��C&.E��Ŭ����\ �v@�"'���ʶg�+�ùc�J� ,������:Kh֢��b1���G?ֽp5Q��!��a�I�'���OO?����y�{z�x@� �|�[������39��M�a]��۟�I���I6��6���Qs��h��D
��_�����o
t��aViz
�lZ߱���FS�s��"Ƅ��C^U�r���Ouۄ���J��e �r��]�qχ�t���I8K1��W���'����j9�M�������"\�i� itК�5���B3,)�ΧW(�㒜��d�nY+LY�p)Z��Z�mi�0�Z������Z�+1�~�<;�x}X�V���>�G<��T{cb@����,�J)vM�L�WԌ��c��d���� �SD7���^���G�=Vjx����1��.���v���� �y5ĜIǙ ��I{����~���4���!�E��8ɛ�7���s��ybM2�q�^��}���(�.�vi5~*'ł��P�9g}q\g{/
�VO/{R��F�u H-W�z�9\t�F�`��)�Ű�E̚���=��6؟3ζ����_-�U���\f�{uJO���T�Y���*n�p�����)� ^b!��F��T��[�D�mP�y�4\�Q�C�p�f�藩��뇁oƵ�:�k���Z�6TC����d ;=�;��R�A��]>�&>���LY/�:���u�w,H�Rw8v`hX�L�H"d[�����:
�iiAR��q�����#���[l�uh���1�.9�)Yʠ'Y�s���|0�?;m5�n�#���<.�lO�ɚ�y�،���e�r�r��Q����Ah���B������[�:J㝧�P/���Sr�ؘ���M%�i�.8V/ܰ�5��1���8`S�n�
@������}k�A, ��v�
T�d�&V����8M��&:A.�q�Da ��jⰲr��J��X�-'�L���\��\*�R{f���ѥT�U���.�bT����K���u����|�[��g:�u�32�۬-s��Yn�YLu�_Л[����J����1l�w�֝�:�u6iT��)Y��a;3*��^�]��h�kw�8�V!*����Ε�v�b�Ÿ>�Is��9��J�
|�D��XK��]N`Q�T�>P_��=8{�������Y���t���d���ֹ[k��Vr�1��Egl�qg��M����$�A]��s�����X�|������-ٓXP
�=J��:m���Y+!�g%�n��а�,[�╷p}<�x�>�}y7�i�#!���q�Ĵ1�FZQ�w�j����/���v�iƳ��ϸc宗��ty��k����Ճ�n���ӿ�N�aO�>F�<0HX
�E�=
Fv�� �� ��� w�HR���yk����gƋ#�uY��A��s�"�����/?}ƹ���H�� q]{r�F>7C�K}�c������E��4�ѧ�}[�>vaυ&�KN8y�� s��"C��k
���+^ģ��8! i=AH�M�yc��Eg��ن��n��G/�6L^K+�:wG������p���)������,&�)�)��P=�ը����N
FV+9���C9lw���*R�� ��4�Ε��>�\�j���_l�@(��Y����v�&�H!&��M��K���4�X���Wğ�G���N�~�U�ލ�,-�[�-52E@������dBHZ�;�������1�fv� U�@�X�RDx��{EJ��8v�c�☌�RJ|�����A蛺��y������
;���a4O֪s����f$��;��8�J���2h�Q�ҨU��t�x�Y����������ԝ#�����Ϧղ�))z�㖱����
>�^ ����`�yU�9@��L�,��oQ���y�#�g!R_�,gќ�Ь�و.�G��y��K�&�< д�뛶G���kۄ�U%i�ṧ}\⳦�l�}�Y6�� ������^�a���
r���;� �yy�p�J�6�K2�di��{HS��I]�����gh����nu}�@B��gD�"�t�.��`X��G�?���=��X.�=�Sd.�7��,��n^=�L�e�m]�z��#���ԣk+�l[���<�d/�{sV�f���
�F�s���!�)<a��ab��;�~\�4R��ߣ��w=:�Z����w��նn<�߸�X�ۡ+t^]��߹�M�n�!�f��Ց�WR��#Y�2�7Db
l|�_ʏ�Txi"���)�Gp�G�
�As# 4�"�ns��5�D�>D��q�3bg�@\o3+�⮳vO��2�.4�c0-v�d|Z��)D��!��#h�tv�ђ)���r�⸳˪��vy:��_�.��LZ:�+�KYN˸ܲ^u�"S{%�ȳS��� Ӝb��]��ٕ�y9;�8X�do���Eŧp�q�d���q�0Q~pk�L��*�sU�EU�!j6`bW&~���2T�;l���qk]�*Ԏ#��Pp���z�fc�
i`���a\���hR������$����h�ih�Pi����
2�E��.+}wD���� �glb���U�c�c�J̭�N7���j*Aߡ��εT��C*HE�m�v���ĭd'g�G�ʲ���*��u�����c���7k��R}�hu鏿H���9�-�N/���'����q�C�G�L�����F1Wr����^�TX</�N��d!�G8i��p�*�//xb}�6I�vUb5���B�S��W�2�s�pMc݅n@ y`�p��J��kBѼtMO����j� ��@�>���/�,���5���&�Hm~����{C�r-�?́�TW��7��q�#�����4.mh�.`q_�������8"s#��>e��H�2H�l�_�ZDVb��'@�\uJIQ+�_~���4�z[����p�ȺG�i�>\ i�e��8�����V�Ri�״�LjW2�
%Tr�I2�䤇R�@�i<��
��wZ�.H��I1�����c�Β�R�rx2>�O�Ƈ'����Vg��-�*}�:r�;���������n�Kw�_�#'S�g��@&=���\(�ƵMm��n��O�Z�k�щ�wK��,"�
�Y�`�����T�At���;=U�;2��X��;*\i�|1�ɨZ�.w�]T�C�)��_���^ģ�9�������p�r�;���n�l��c+n�ܬ;��Yw���6�o�ۈ���7��½�v�Cx��v� ��j�ix]}��H�A�4���\<'y���DݥY�R5�����k��s�aƑ��b���d�CK�oC|���8<;.�\E4�a��1L�+b!Y���AҰ0�P/���\'-g�BG�����\�7��/��uxB��Hٰi��tQ|�ý��p���o��VjQ���BcPu*�P�E���l&{iqH��?��k`��v�/��IJXn8m9��40�؝
���`r*�]·��H�Al�� ��2S���\�*�l�Ɵ�W�U�q� �����kh���,7�O��+�E�$����1oF�^�Ź�[���x�f��i�9���avKi�).!c��ox��db���'lS�e�#?�������r���l� ���HƇ0/]�f�gS�������.�H���V�T�?�q
��>|[���-�:��w���nYp��xp>L�U爆'��G�����ъ�hZ?���
�K�)��)��T;�ir��O���Y@#���p=G����R�є���������E�yZ��J8�Wª ��$Yx���M]��J��b5&��o�!��A��ʅ&)+�펛�{L�H&���� �2lx�;(�^�Az<�~�z�D9&��i�z��`�)��6�(+�j�P���hɥ��Wy�h�q+�ӒO"��r�G���
�)Tsړ��1�F���9�.x1ws�
v1��ƨ�o�m�L�LJ�_��J'�j�?��N��V�6�'hS*����)9h�%�� ���?q�R+��g�q��Y�F�l�q�X��N�S8��Dl���Zƕ�/���C5<�YZ���w`ѽ���K�ٞ�z+�nyRI>�Ǧ�����AiSe�q�{�^�������C8�
ns=�I���K8C�q�hDd7I�H��8�c�\t��y�O�U��6o<"����ԥox����?�gdl6
endstream
endobj
26 0 obj
19572
endobj
24 0 obj
<< /Type /Page /Parent 3 0 R /Resources 27 0 R /Contents 25 0 R /MediaBox
[0 0 595.28 841.89] >>
endobj
27 0 obj
<< /ProcSet [ /PDF /Text ] /ColorSpace << /Cs1 7 0 R >> /ExtGState << /Gs2
22 0 R /Gs1 23 0 R >> /Font << /TT4 11 0 R /TT7 14 0 R /TT5 12 0 R /TT6 13 0 R
/TT8 21 0 R /TT3 10 0 R /TT1 8 0 R >> >>
endobj
29 0 obj
<< /Length 30 0 R /Filter /FlateDecode >>
stream
x�}Y�$�q�{��d�VC���+�y# aw����Z�ɇ�c�{�G���3�_���g�Y�v��T[�v����������ۺ9��f=���Ю��Y�q�i������u���U���v��i���~�i
�a���C����������ݼ}Xo7ö9ɿ�}�o���خ�f��tCe�9쏘a02a��q3a@�]7����ٷCĘ�n��7��~3t}����\x�t]��A=0��U��{k�M�m���!�%���*[�(�
d��F����#��#L �l����a۴��a7l��\7m�94��>��o�f����]B��5�b����C �,��B52�VI@E��� #6Q�h0��ovۦۯ6 ��<�UXa�0�m�=�2u]�P��R�<�EH6A�h���<��YO&������dB���b�H
Jt�`�
jH�>�֊�d�,R� X4�:�K��텼0�~w:���$�x9��������Y�[�i�æ�`�5����oj)�YN�^�،<�>j�4��HX9Q ��]�P���Y9m$�!.Pg�����+����$� �N!(�����$��m7��Ȭf�LPl6���86q�]�AY�����5u��A%J'�t�Σ)#$�%��#'^��d��q`�bV�9�v��6��h��I�����^���j&N�1Z�9����lgUqld��E)9�52o��h���h�L�tm;�HkE���a711�ʙ,�I%�.e�3�I�a1f�S9FNai0��V�LI�13FR�j�tVU2����gQT����,�
F�!��������l�l�H�F�#�㝆�N�O 7�șa�)���ЬM�#쎽ۋ�I��8j�,�.�QC� �ad� �d�k@p�.�.Y/���S=���I�9Ħ�͚�4�G%F���,lb��<���SgUr��H����M~�,���F5$�� '(hB���l [�d�Ժ'�N��@���3�YƝ9u���R�j��XI�H�#M�%#Xf�k9�F�[�d�H,gO r�e�r���伱qS�NF���`�h:��U�|$nbb扚
�1!|"���bn�1t���]�s�b�� ���Q���!�9�n��d���BD̆k����O{��A���A~�[���C�=�z�IL�82N�ͼ�żE5��N��<�EH:�&>J��H��`�k+�YN�B���7��J�cIK�a�Ѵ�[O2���sQIY�sZI��R��1n
M����F�&o�V�
�
Vn� g9�T�������������N�Y��&�t�9�L--�ym������g �]�����q�ѮZ�F�)��S8}�䃏l"V��#'�%��������i�ub
�~Ku0�� L��R
��H�s�D.T��a�iS3���7�nL�� ���c�����T67��ܘH��{��9�1�Y��٠:�$���4�n��SM���$�2�g��Lg�@XL>l�9y�T� 1�� E��E�lT?���
$���cg��E)7�`��`�]4��8�i��F3�g�:��jÃ�y�φ$df4�f#��YMc-���$,0��r�G�'�ɀ�����nJ g�v��k�7���Nh��֛���������!��;x�x�B�γ��M�(�}OfK9/�:Z\������sP��eL
��A�ӥ�<�GgU�$���D�Z�
��i��IkH�9�Xi�z,Ӡ��yi#�8��uOfP93gP+�V�8X����������y�GSF�xI����;^�%gJ٩P�Mc�'�V<�F�((��f2h�zLX��xH�'fvP5���6z>:=ϼ�89j;��j(���R��,�r�6���R�DgWIV�Mv���0�����W/�'��9�f��j32s�Kj��H���<���D-7 aAH���ky1�$�ɩ{�o���X������,�ή�Siq���40�}3:�$�7r��Č�kA�
��E�M돾6��h\�P���
� ;�y��A���iA9�0�`���Hʪ6�D��X%��ǜFRxs��0Q�Fٷ�ؑ}#]�Yl�v�F��(:���
v��֊��&�i&�3��D�K��'i c���|/a����3c$u����[�쬠*��Z䳌��CXJ������ϣ
��hh�!x���zx9��]�xj"U��"I{ՀAtFI#M�hM�JX5�c���Q+g�sN3sV��K9�A�hnTѝ���l�=�eI���������?���E�Ԙ{����������u��OW�8�G�p����H"��+�$P(H�OA6��>���_�K��j.Q��"M����+0!R�FZ��KI����w����������;� i��K���qs)G��@2��R����N���H}{���Ҧ��E���鹒��T5Y��Ԍ�4���%���R�'��Wц�����Q�_�I3�S��OY�i=�ԍ�>�'m�Ş~��(�>n�RsB��o3Y�H����՛�;J?6��v��;\@�?�=�w��e��
��=���s0�4���}��eTZ�
��ˇ���8�;�� ��X=�}w���I��n8��BD'�!��#}���%�k@�3�Z?-��(Bdȟ����e����_�"lV�1h�}A!��+�.���u�V�������4f 9�(^�մ%��<�J^�ȸpe��9����������n
[�ke� {�N8�yX?�詑H��7����ÿ�ܛy_�keD�nO�Y���ȭ=��~�wq��]����sr_�Z�~�+ }9�$uA)Z^���{&���3>�B�'\����e��2����z�IW��W�����9�������2��^��Q*�Z2���ܑ�C5&�N\��mN�R�٩D��?�Rs�g�
��W�\,Cnhek4����ߧ?lf�BS$�s9^��ȉ�r���"9�W����H/�Y �y�Y%+�&��u�<�GI_�;�샃T\��In�.H�)���"�0)4� �N��p��6�d�������w_W�3�+������?��|��Ө�B0�E]��X�8I�L9���ԴDԕ�|��PH}1R�!�ߩ�x
Dְ��w�ÈW)�/�mb@����#��敧l}ɳ��2������iH��`�
����I\I�����qh,m&���o�'��3N�F�N�DDDF=�
Q).��3z��"�����g�L�W�]s����A��E)�$�'G)�dk4A�ڒKI܇�6��R.7�B$'��-���!T�376a_������Lc���P�����iK�-��j^d0��)$��� �"��w0�4�ſ�1��=�$�Y�\���I��Yi��y}�]��jLm�X�v���,�@�5̎f�99T�SNC���ڹ?7ֱܕ��óQE��G,�N=z\��61�����.�Y��&����;��B�6��SW��xMA��VI�x5�o��'P
x����4�ʠw���ٵJ!s�ԝ��ڎZ���4Y�d�[
���!��i���hi��)O�_�s�T��z5��ݟj`�rUh8��#~NZD->����µJ6����H�sa�Z~����bj2E���\�����4DF��wK��
�i-N�k
�y����0��TK�I��u0ț�]]Ċ�:�������0�(."�%w.�]N�˺mА��<�G���(�_K�����Q燜�Ā��q�\ڮ�3<�9��`8Nƥ��T��9*穮�!���l�&�R��e���л�Š��>4au���~��Xp�`tx5G���>!�yph�$ ��]����%�����l���GQN�_V�,��$8I�#�i���'"� �.���,+�xZ��zu&U^k]�v9��r�oI�Ǎ�\)��);6�ß��+N�\S^Qk����O[���I�ؖ|�&v��Z��/E�����q,�/�q��C)�Bw��1��UJB���:�,�(7���Q����/K������[�����U����8�q�s�O��0���XHF�):=Db�?(~2�r����!̴���6���q[�3��R��xIB��/��eQ�rE�o¥FV�v��rv���
PC����L����*�ؠ~�ZI?� A���.�4ϢΎP�8̈́��q�9���q~�=N�ljq":0+�=������u )�^����.Tu#Mqĭ�(<�0�G�m�W3�>�eл5�z8A
��q؈q�����#Xn=j�g��U�1@Fpr/���K���<�ūyS�<��O(I=�|O�9����}���7�߾�j㈥���.�6�e؈��m{�}9�ȳ�:q;������;4��CPj?!a�#����|�^0Lg�=��f�옕 �qO�}!Q.B!9�B"S���#nu�WZ�q},�<��ZS��?��/�}J'��\\�p��5�?������Ni��{d�O�BY�G< x��栻�٨O.n�E��DWw����5\�lO�^j�z�ގ�)�y�9O�}�/i��2���[aLې�����$f
��a�c��L�T�E9"۳l���f�+�!r���;�@T�U�C�ǜ es�'6^87q7b┷ګ����NhvJd5�-Vz<�*&�7�+�|eS�����6���-�V��9O������7a���t�2�Z��
8vvZB�OE�@���a�������:���/��ktX
���m�@N,9_&H6�Ip2p��X����I�j�hu���?~����96���M�}ol�y��wA`^i��sq�����B��V��&A��0_��}���ٷm�Ț���dQ^5`��Jb6
�P�Ol��%�d�V�g7 �\q-qLN
��=*I^�fH"2�{��W�~)��B����j{�N��8�8�|H{�K�4&
�b���)�2f�{��$νv�tĄua�}��lC�$QH%·2 S0��馆��kٕ�l#9��9�~c�#�`�\�G&�����O7�ݾ��f�~�4'��q8��Hkn"��1�,M�]��{d6J6��.�����6 ��44�f�4ȚR*��dL�6��d�O�Q��ӌ.�o����E'�y��9�OK�
�5�(� �K���$�����1Ի�af`�04�뙝b�eH�n��L�]nQ ��"��d��o�x���nA���r�(��+��P�8�
�/
�:1T�l��oe�£���
%
�@���v;��5�Aݤ�"]�����4�����$\Ğ3�4��:�=7�N�������?}�5黀ѭ�����n�~�X�����7
I�r�q��6�0������O?|���~skn��Q n̥(��)����?C&��n����<�]���
5�Ƕ�wx.>���k�� ��|�.-A(�E�ɡ�[�!.K����'��e���?����bed,U҈��G�_�p��xl0���^'32�|�$'��[�>����<}x�n�� $A¥���O3i1C�wѸ�i����Cc`#���fk�x��[��u<H�[�v��j�_����w�-jb�y��}mĵ��z���iW�L>�w�G�F}J/���<�Mo�D��K�W�aU��✟�z�>f�U�����A�V���V������#�k�N��$C��E���[�4蛗3��q;�a��e}�#�SP���K�������I�o���59�RC��XC��c ɫ'�H�D K#=)CU��\���D'�E�!�0+�:g���;�XX�����ho��%����H����#��\�e�!�W>�j��}V���cF1��^��2N���+�Uu!pv<�Ӊw�=o���V [�f�.V�#=7#9 ��b��
ˣ�����;��?�h���X�j0i��噲�_r�or�;�D�f2�R��k\�]�k,9��v[�8d�9�Qz1�qN�8RrzqU8*���Z�n���-Ak�Y�X7�"1��c9���F;�ʹnbdЖ��T#��Q���]��xF0�&Ys[�)j>#��`�<��p�EA�I!��x��E� J�}��g�����Q��[-ɢgT���d^�'fU����|���6�@��R`�iQHQ�#�,��L'�#���h��g�C`�>���1��`��YI`�y��#c�6f���c��7e���4�j�����]<�e�ZB(c'R��S�)Ɯ��>�8E�Q�8��N��LAf��3�ۖ��Of]�Fy��G���N͛�e#�9HW�����ǂ�LB�9���ߤ&g�Z��(l'6���2]���*���H�WN�(�Ip�2ε!�@[��=p^��rj�#xEq�܁^p�H?����8�GT�Pr�����v��J�c�7�+��!���zZ�{�=���=7��*��\�~Tʈ���u��r0�n���
�M��h�O1+�+���.p�65=�\ĩ��H��Z�(�qgY>g��Y�� �����þ�&/�̕����p��
u�0��Or}dTi�,V2��;�ش`�N�+ ���X龴�G,L\C�.i���&�Ki����%)h_�js��Œv�6?�c��P���O�z�U̙���P���۵��\�8s��l8m-�oqTjZt!���-:�����,7I:b�Z�]������QxBe�9z;���ǽ�Q�8���@�?C��,%��5�x��%��� ��6xLyb6NY�t5ah�,aj��
6�p�D-l�-s�d��Osm�ii
8m�P�mT��s�ĭ�7��-\���%��.�t��@t8��B};�jF�
�0�t�dJY:���g��sI�V`��-�t2��[َ��*��Mg����V�\���ŵ���;�]�1�h
�%%�����6�C'\V���X�x���7Mx�k'�pK��e�`Q=���x@����s҉����$�I�-O�֢�H:>`�����CS��֟
|o�
��9'��X(B�ڲ'��% ��}���Oj`�������+@�25�����eZ5��(�@v77v�ZeOڎS��l`�^�jr���:��uq�H���{F�3��C��k�K̓t�|&������
��
�k@fv#��k,I�}��C�dS�.�%�kH�6_tiq���؆�J��q$���Z����o���/���4קu���%qI���N$R�B�;��&Rˣ~���ʓC�G�co\&z�z
$��>�cU����Dc /��~���������[�E)�� �( #>�9�
��̹ᴎjdm��r^�0% ��5�y�Sq��z����͋�����pO��[��@��M+�1��Ni̻,D3zo"мH�<�ʥ4�j�õԉ�x0��&7>&��X�3\�`���f��"���/� i>z)���������JV��p�z~p�2*)ꎸviU��NJ�$�-��7gB�B(E�oqr�L�.�)R��$�9[�nZTQ=(�0V��Y9JW����G��!�8/o�G[m��a�N���"Y�P�L��Na��:c;�Jw7ha$)�d��[}���
eHR�cJW���yp�-�f��>�DT�^�,٭�Hp�@G�@�� G�A,�2��v�l�^�*#���HK�'�G�7'I�8[�w����F'�H�����Nk��b���#8M"�<א��)�h��d��^��$�KdҌ���;KR9��Z]F�ʱ$��Ӆ� \���dq!�ӧ��ZZe����G��lT��aQ�k
���k��k����K������dq�_��?�`�dO�Mv�xչ��/�W�7���G�TxC�ғ6J 5;���R���:ȧ����z�=J����ԡ��|�pTXkLQ���L=���-O YZ�(KA��H:+�2��|oz���6�ܒ�.�Ñ|iO�n�@`8�\aK�K��Ԩ<�?�^�D-Mq|oK+��6V�L���6�2����{�����:���b8�$<��@�[������Ϧ�������p9A<���-��-���
�������h�(ŽK�&%G%���j�;��j�a���*�ō\;�mO2,�X��m����;��ȯbllz�;t��m�=:���b�{��#a���
�n��U��/��t
è�������(�X��ʭaL��,PE�X�L�%&*���FSoQ��ř�n�����M�{���6��0�9:��9:�Z��x�?�IŜ�Y��dt74
wĠn1�"���%�Omy����ʊ$p�bnTO �K�ߐ��L�&��eӑ�7?��(����6>��!�HA��]�P����&o�l���]�_\�k�;����5s�:)�R"lB��Ey(&Č��CW�B���O�i\v�pX=5�T�Ww��p
�YI��"{7���BN��H�Փ
�n��'�7
C���#�yun�1�y�$.GSY���&D�i�wSIR�H=��;���N�O�+{�eB�<~"٠�PJ�5�z"J��5������j�ʶ�m�G�@��=�ŷ<��7���)d�ZT4GJ�e�FDWH��dQ�f�h�*�ڌ.��XWR���Y���fw�5���� ��F�!V�
lh�D���um�[��*�QX;�t�-�E!���\������!Z�$Ef�S���8�8BBT��3��~$��O���������b�3a��B�86�����l��>R��k��zO�<�ci[���9
�2b*.1|=*���[�$��L~@
B�c�����:���as�݅E�
���������ax��=�I߮���'|pKf�U��}������t!�ڛ�L� �P�S(o#
���C��7:��Ǡl�<����z���Cxg��s��L�
���681oA��Y-�v�Q�Ns�H��p��R>�H�0�$�p�%�F�S�W4���[X�O�� �S�Wx/��7�7r�����zs�j~��n�
\S����{�E;�u�?U��/4��-Zr�ܥ����jb�w�8�a'�5�����iT��?����KfY΄�{�B���8<+ƩU��f5�d6ArW�.?����23ʮ'����$+�|��q�&Q�P���'8;�%TM�S���Y��l��G�v �r��{g�J,!G�J���}�~����cG!���|Y*6�X�~����Q���,6-�ޤbB�FG\��;�0��+٧�]&�I���&'3�?��)cc�������-�n�p�?^����k=o�6����8�*�K~�1DP��φ?�8���DG
���/��5Ւ��˃%��
v*V[�7:5��`�]-�k2øv���a�4~��7� �������6\0�0�"'���ۘ���PCP�ϕ��� ��k;���ԗ0�{��ղj�Sa���T%�yb0gĞEU ��U6�L_8߈Md&�9�$�e�1Ա�r�V����B9ʔ ��|��
�-ԕh)�9/��~����NpV�<���)D��J+Ӽ�v��K���m�RHC�p7CIt)#'����O�����+K����!��A�$�̓��Z)���
?�7�;����
��q��K��써�����Q�\�"�A�,���C��e`q�W��!:��;'mq�$���#-Y��&�w�=��2��Y��c��}�Sh���f�ȨZ�ؔ,%��o���&���c���PԾ��1i����$�5?�"h���}�S�_&�M�1�U�
n���
$a�_�h�LFb��Ƭ�ٳ�C������X���X�䪽�a�~ː�Ƹm̯�q��D t\��+�V=J���)Cq4�A��@��
�h�`���J�z�Fp?���N�U�?Sk�Ÿ�!����)Զ�G���o�v.��=Q�m�&/�wvE�*�P+�sD�6����,�@AQ���dC�B�=�d|����Z�����*�:'a`0n��qYL�hF��,���S�
�˭G�q4chH$�1
1)�6��v�@�uG\Q��W�@��m]->��KC�Z|�Z
�`��I��
�խن���S��o��k;�����g��>�V�j�`��8�u[8ej�q}�{T�Q�3uh �lM�#�rn2w����O.�����g'�9���o9�V�X��4X4ւ�|�ԡ���P�^������X���j�������c��~�g"o���N��(C((2���9uQk�~ǥ�(��(P��=���(�q�i�}x����
��Z��n�7R�#u�/4���P��}�)��7���t���Q=�{�et[on��k���mGF���!7'�T�r���r��y�½7%l�9��z��+8Ο�_�}v?��ee�Oy�A���`��ԧ���L�#"��B%�he�b��L\�����ڻ�(Ut�
F0B�ι��m�m$Fxg��s�\�ƒ�]�C��R�\p`�K���.��W0��*JU��J�bV�T�9[|���S�L�h�?
�`j��5�vJ$�C�/͖��\�`�l���>�� ����=XQq9�R�d���'C�a�6�R�r_+-�w�Xo&��1)�A��3%�E�.�L���'��K�i#����r�m"�C�X�)�V������\����P�����=.� ���<�oa?�m+�� !w���Bq�
�!l4�5)"x7��rqh�sv�q��9fp�
0���Y��&<uSᦉ�4~�A��@+�W�q���ݵݨC�o7XnͶ�qJ�߶m?�1f� �z������I�����by6l��
^�:,K��X��OѱD�)#:o-槔�h�H�D�`���˄��f�JD�>��ʈ�:����M��
_HP��Fa����J,�[���� ��T|_?'�0a��ַ'��ϥ�x����~FjO�W{���{�7�W{6�jO�Tjo�M�
���j��14�k�ch�`y������S��h��o S)����
�FF\ �=h@�.����!�{j��5�ġ�/']���o�142�ʌ�ro�t!<�x�;����m�F!���07�#m�f����#�I;�߲#��У���y;Xw �A��#l��aގXk�#�v���#��acƎ�F���hv���@/^�ĭ�j�-��h���f�8rey���
���Z���LN̾�
�2�,���I
��n���x�JĒ�J\�QK��3�m��o�LF�'�LU�Oc�4�Y&��e'�P.YtA��~#�������+$Ȁ�#ǸRhDA;������SqfW��B��,�1��Y1N���(���o\������� �F!�bm��p�6�����۰�MpT�ɈM���w�9��@�������Xe,�1��s,l-����a��x.��5߬��Z�R��d�p����!��bH_����d�ÿ3�W/�y�O/.���
�#Q�
���#��{�/$4���pi�D�@�
��K�T6���^@U�o
#�����%���� �t-��յ��
T�ˮh~�C� D�a7�Vr�d\��#�2T��D��<��� );����Q~�m��Θ�5��;�}���&�K��왨J�s�´�1�*������L���y�����dH=\r5�9�EQ�^K����D��;\H:Q�x:��s��D3f�э�I�=�b����M���-�P���)ZjȚ��=��03A�B<<�GY,��"U%9�|��Όp ��N�3�7���r�I_�gX���d:�dɩ85�K(�!;��2z"���w<�@7�T:�ϖF�f���v^4v�����b��(�D~V[M݊ˮI�����pLYY�U�}x���lL�T�go�1��|�j���N��$����]'�p�����1�i��0��/7eW�B���m�/�z������zS���|z=�}C*
U?�7�-��q7�x�Ap_�!�����P�w<�����4\c���� ���Hm]K�8C��E%�M����E<��s �u-�y7���y�2��:o�Ѕo�p�_dQbf�PXzOÈq.�bn!�hTA�/]oTq Q�
��(.Y��R;�."��].�Wu~Ð�K�i������6}X��?it�ۑ�)�ɺ��6���G,ϘS��K�3ȫ��=����mHd�r�9�V��N�3��=�ЪC��Sx�n�hY� ��H'�#_���:�)��(ͬ:̀C�'*���!�ⷈJ[k���P��0ߣk�z\�s�����V�m�W}�Ќ�Ԟ������[? '��sc3��u�����AH�G!�7#93r��t�)9��i
���z��0�7Xk3#�f��c
/�p�n �)<�4E3$��+�F�\�]�Y|c�3������
cԓ&S�y�$����J�D+�H� �O�qm��(�O�0qdܲ��=b9�oY����z��h}s�T��$�Ɇy�d�_��(@kq��1�#��H�1� #@�+>~:HŦl�HP)����=�������+��۩�(C�,����bBo=��[{S;<��Z��k�>=L�,�|&S�6��wF�I+2��rP�M=��L�(�ή�5�3�C� ���V�U�[�]���I�&�i����(F�؞;z����%vac}<��r�rU���i_��N�����W塘6 �*�;���>h�5�wl��9y���X�:c�/�9Il}2�@����)�n,wQM_Ia(D�����r��xpנ�gzNn"~� $t��Lm����YR���`�5��F��ڄE*R@r�)�7�X�_����PrQhk�^-��D&�@F���An���-���">ڇ�n�AפQ0di�@�(�gר�I�"�W[v�_��[(xB�C��1�Y�SE�kaT.�<`f֑���au!����S`]�^T2u�O�?d��)ȕ��e������ғ�Q&Y��2�q4u*ܴj����z��Y�u��ʡ%���N#)�h[�-]��@P�4�1\�n�<�L�a�$֡��9[S��:�������_�����z�'C6{�N��|����9�j���g�lh����A8�jgPx.X5J�p�N��/U��p��&oչZ�.PI��IW25���a����`�n'�]����Uǧ��(����=ΏN�������W�uJz�C�l�R������b�!�^e��2�P��,���B�ߕs��PeYA�
�$Dc7R1��w`���w`��v�rsJ��~є��~���-��a�`�X���ɦt%{��=�t����� U2�3��>gSt���6�������^>o]=�N��M�.�nPO�����'����-���=k�m4�"'�%�֭��ݰ�Sb�#�3�1���͏.I�Ϊb��k�P�����qm��<;�a��2��i����wK�4a,IlC��Ŋ^��k�S�cpCJ5�U�X!x4�����ـk��[
t;:!a��3p=�C��ߐZ(=lw�W�
Cj���X5���J��D��5ʕ3�#�炀u��F�v8��~���>�a��J�-�uhV�:t0uh���h�zD����rژ���G�V0��H[i=�HX�9�6����4Q�dZ��(�p=q2�a(�#/�Zm�qB�ƫ����ƴ�w#�˰��5-�n\�b /t֡ �u�`�Є��h�c="��xܑ�Z��][����w"�S��
eQA�ע'�=p��Ι�Ҹf!Y���D�q@��y��E+�=�m!��m譁LH|�&֡��C�#�{Ti�uh �ǖ��J�[�<aYZ4ۊ�8لd���+Dd4��Y�`E�̈́�~�ޗ�� m��IHs;|gk������v-�CI�k- q0�q��z�B��@��$V��Ț�k+֮U�!�ֱ@.V��UZ�ztm]�K�.�D���0�v�B�N�����yqo�����B���h���nۦub�̋]�Ob���N�db�Rc;ߡ���6�3����VH���2�<6�ք�`71L"�����
�^�w"�Ï_� 8]H��j'`H���#��#������@�h�B(
��cGN&ԓ�k���8%�� ��k��n`.D��5�zs�LG�f��;�/���'�ɮ>�i�O&��w�\���S��ޚew�oF?�;ʫ�҂�I0��.�.�fo"����N?=;S�F9��<�U &�D�mn��o��'�Cܪ�n�դ� ��kU�q���t����O���[6"1�)�JM�̂�� �W��
?a�}3��1���kq��P���*\P緉i7+���.���H�I��F9�����o���.�7��i�lT�c�v��N�r2R"1��hd�^�$I����GQK5kg�RL)�M�B�@"�^o����ɃzE���ޝ��,*Q&��}�v��ؽ��$?Ɗ���&8����=��%��o=9қ,"����%K��$K�p�pQ�7�|SШ���,1._t�J��uA�pO�� �\s]��q_j����s�&��_Қ�@��
%���%a����������v��U��g�ѭ��qz��ҵU�����N��EGz{��>}y���e*~n(E�8Ƹ5>.ĒO|f[�3��^��4����w��&.OVR��u�{/g��l�s���Ӈ�s��q2-J\��
n���
�!F��B�&�
Q�$��ٍ�+��9�|�;���������C�Z�#X����6��
֜�O��)*���c�C�����4�^����J�{�mߡ���fq���e���u��
�/���u�#�6y��P�,!��x�2"ٵ�6�q:t��PVg�L[�ף����l���>��`����i�:t��G���i���i�z���Ѓr���a�Dw���G�=<%,X�~c���z���g+0.Q��ʄiq*/a�8#1��SJC��]S���]<>P���o*p����\p%E��2��=w�"r����#D)n��pM���Kvš��/�!�՝�9�mžT�9�Jr�l�H0�L?D@WS������Ȏ���O��*�!cn�#���I�GM�8�XxQ�,���ARg��7�f-�j�Z_1+�o�?�"P��Q�)����9�%�T�,�!d���I>&ᐌ) ��?\&�"�8���Ւu��"���{��F��9V��#�D�h��²���6���u��cA4+��`�CV�c�w�ρ��r`�.��Y�VJE�;�~|b�aa�3a2���I��B�"ZZ��hV�B�)6���f��̀<9�k�Y��1�8��l�;R��27ؕw�s��f:)�:�K����$�((�!���-��Ne&�5("�1�$*v&�V{�O�㹝:F���)�bx���a�9�by���)��W!_��:l2����Q-D.ð�0���]3*�1��Z� k��H�ķpl��m�p�l��ۍx���p��t�������^�ш��B��qt7[=�g�,t�E����S�K�d��'��i��|hٰ3�t�,�ͧ�2��щ�
���ق��{|�<�\�]AZ��DZ�?����&9�;}q�sB:D�p�AT|��LA�/��a���ջ`V�;�=O[��qk!�Mt��k�^�8�vX���mY�Q$w�������r:w\�c��q�\a�������Oo>}�����|ټ}�������_�9<0����(���D\˳����q�ɀg����5�o�;����7`��p��7��C��������]R�_̖�pרC���wi[u�8KX��w4D���{
mA�q�����o5�q<���4�sm��&Y �����>"���w�Ďl[��ᢸ�u��"���^9�����Z�E�$�b�����$X
ϖl�E��
�A�3�'6��P^�m�V ���8
��A�JB��s�5�E�\���Zv� ~}���Q���4wHo"a]<g�PJ�G<�g�Z��H���ną)���uF�S_�v�1�9c�t˾���G�)�Z�!��fM3�OQ^ƛ����Jc�a����M�QNLF )��䈚
�����%E'��.�4�T�b��hh��H�%A52�slT���WN��-���l[�X
X�q���~������6i���B��`�ʓ��[7��CMƒ�u�??XW���6���9�]��D�N����+�ǎl���J�u�١I+�7�4e�r7os�m�u��D�sF!�V.�s����o6s; o�s�pgV�qB 쐵
#n��0����.d�>V�e��Ł`q�.��{�!�,�,� �~]J+�`Ug5V�s�-��~ڎ8����kdܪ3��sy�ꢈ���E>)��������}j-���eF�p�K ����Z���e͈�p5Á��|s*\_Շ�eN^ê�:�=�� -\1�h�����p'|���8WN���������@� |�#�����p�.&������L.T�a�uWd��м3�m�c�o�Cc�>��e���>�ykj�ĵ��(X=��[�뱉H�ƣ���Ve$�V7��{e�v��pĝwu��+���� ?Z�BA� Q��o�|��a*z*M�l��8��ֆLOKW�H_��ԅ�R-d'�����T�W�R��'N�M4/���KQ���}_
�K��"q�
�OpkSDh��/:p� q�O�ؐ@B�B�0��i-�=�xlC21jgx؛��l߷�[�����J :����e�C��t���
�=n[t�)ڹ㔪?l���c�E��\2���m�c���J���k�x9�\�p܊�k�˥�-���cD�=�i]g�2�x�3p �g�a���^���e�m�4�����и/d@��O�䄮�L�"OS|(�¥�Ի���d�_�J�Ӛ�D١X�;Tu[�۵���l���aKs�������>�{��w����R�UF�>d����֚)P�ߝ�^4������=��-��p�4�PT.�B)TB����i��w�*�e��pE�M�x,@ԕϢ?�/�`&���'d����i��^��"���\Q��.�ĉ-��݈!��TmU���p��_gX�Ww�' mWA
��$t�.�pË���+r�9�_�b'����u"� @|p��o�c��)ܺ)?��~ި�)�F�N��b�%1pH �,W�ŤY���^|�O��j��#1�����*���ٛ.����P4P�N�,T)T�Q����1U2�����9p�}��J��`57�c�� ��A������@Q�'υS�ܡ���pzur�8�q�5<���8�����B��`{��G],ʁ�����<�WZ�.��q8�zh#Y
�����
sCU�LhI���XP1-����V)A�Y�+�p�b�~�d%O)P���evmg@ٖ���Wc%���/Wwj�V�E�i>n�ȫ�(�5������G�wY���e�L�9q�����{R�����-�?�th�
^[�.m���hH�I~��9Y!l�y���k��S����,u���(�{m&0e���er�hF�|���������m� ��s�Ȅ�J�aS�⣏L��~m�'u��ܛ-X��f�M��q'��@C�����E��
endstream
endobj
30 0 obj
21436
endobj
28 0 obj
<< /Type /Page /Parent 3 0 R /Resources 31 0 R /Contents 29 0 R /MediaBox
[0 0 595.28 841.89] >>
endobj
31 0 obj
<< /ProcSet [ /PDF /Text ] /ColorSpace << /Cs1 7 0 R >> /ExtGState << /Gs2
22 0 R /Gs1 23 0 R >> /Font << /TT5 12 0 R /TT8 21 0 R /TT6 13 0 R /TT7 14 0 R
/TT4 11 0 R /TT3 10 0 R >> >>
endobj
33 0 obj
<< /Length 34 0 R /Filter /FlateDecode >>
stream
x�}k��u���iF8܌����ʬ��I��;�mY!j} �{8�Iv��c���s�s�@VWeV)6�`52�����#�����K��7ݺ��C�۷͗�����_=��ۧf��tko��Ͳ_�ͧ��햭|\���1���������_����f��W��v�����n٭V�v�����~ۅ^V���X�=�e���n|/����j�}w@�召�����_��v�w���"�۶�;���Y������_���j�QfY� 凅u[�0kb[�.!�a,�{�t��0W�1�n��պ�6��v�?@~��[�^�q�E��n�ߙ켦���B�T���Y�*�&*�]3�6�.Y��*!�?�FX+cQeYK�n�]�7�&#Be��_p�:5�Wk��
�r
e�����E��,&�f|�u��8V0��a�2���IkY]���dd2u*�e��,�t���F��fS�u��6[��\�*�`!����W u{0�.U�Nјd;V�N�b�_�f]o�i�������SൗIo����,6O��TM:�:Td��,��^d��a�w��"��2!�� ��Vq�[�Le0�(�d�%o���:ۮ]n����R��L����|g�Ģs4�z�C�v��QUE���h}�� I��b�q0�4GՌAў�$%�����hz�&y-2P��$��U=�3�FI���K�YuFP�4{�Y
�ټ�6Ú��ܬ,Wd^ .&3*d&�OQ6��XW������J÷�#�,�G[�<7W��R����x�|=�
��2���YjL�$�OU�8Y��4+yY�Q�V���E<�Z鉝�?ě�T5?�7Ԋ����b�E����I:L�,��,<1W��
����n�&Ϸ0�E�w�h����c��
Tx�G��Xb�=��B��(�����M���@�i%z-g�˼%�g�DxY�����1)@�)�Q�Sg\\����%=f���|B���L�^F�L҄7/;K�^�3�a�,��&1]fu#��$6����\�)L�t��l��.@)�T�ӌu)�˦hS(纤w�T�2QG��&��5��;�u��*�2��s�Df%�=��Q$&�H�ۇ 4Ӡ��f�Ag��P�J���ՌIt�,u
�=�b0;�����i(����@NeGt�Lb�����m�[��X�"�������e]�l6�b;kI��2��� �`�/�e��N��3..Y�.�b2�)��}:)-ee�ZVWe'59�%1*�:0�Аe���YK�Ќ
�Q�B�:�q� �����ol�2v��2֥L��ӳ�̸.��唊�dcFC��5i>��IZ;)ߠ24�e��C�a.{�l��C�E�?�U
�
����I*�ռ�1Y6���/�;K��ϧ�*���I��}~2db�I_4Yo���}�Y��H�"u�XѪ�~����c�Ӭ�F�|
yKBPQ��r�z��Ic($P�����Q�wb�EU�E�̆�QR�:kiP�HP�4{�Y/�0��ͻj3������rEb.�=��
I0��T$�U�Ja��O(2��h���z�E�s�R��9�9��"��Y;������`��_���Te���,���_V�
������nE1������?��J���ZE3�N3�%N��JG�~���0�t�C6��t�(�c\��t���JN��Y�Y<����Y�6���P�C�l7[C7�aE-�c�^I�|�@�rf�LU��i��M%�,F�> �U �H�?��SR-��,�-�>/%fuU6P��0J$J^�i��hr&cՅ�cRħ�`"�͌�UR}Kä���f<�x[�r�%ב"v �N�(lq5ҧ�N3�6�L5UrD��N��S���&�*ˀ%�/Ħ*H���8������T�5a �~��N�t32͕�֧3`�
U]F�<�Ѱ���i��n�]&��T������Z*��`�Ƣw ����.��6�-��߶��RX�e����#?Yd��$�̈`t+Y�c�����c�"�t�K�]����[��MĻד.�4Aѵ{&��H�坦2�0����.a��J�X���.�,���0XO�,�d�G�t�I���'��wK�����L��&j��2=N(Ac�ˤ3�T�i-�Eb�d�_AٿAQ�B8[�B�L�*�48Ơ�H�9D�)賈��n%�~�,�A��vۂɬf,;�IU��/��|��"�ExA�������h���Q��yS�Q��I�&��|.��@��c�^�C�u�:�)�g������H��خͬL���NS�*Jf��\�S�τ�y�i��O�'�)a) }��+��P�WW����1V�?�=��$'�q���3�z�*����TM�2�8ˌìL��UU��*� ��c%P�I�J�2��l5:�&a�i�J�e���[��Y�?l:nm��_�W����ã��O�f�zlg�.n?5�|�`c2����Yo�x�bo�fݼ��|��M�=�o�o�����u�F���|����y�n������ſ������}��?XQ���Q�a)�x�R<`[|���/����Ӈ�����}�G$���X77l�5Lj�s����?� ��]�Ap����)D��Kl&�H��R����sb��R���������$Y�,_7u� ��h��i(�DI�d��Q�@��1TY/n �y��p���.v3Pl��m������n��z|x���}�������K
_7o�s���g���Y�������($k`o?B(��}�Z=�Դ��*�����3�}]ɬF���u�A�t%%�.Hc�}-j8�s�`7���|5��
���߮��A/ ���'��j>0�]U ��g�ϻ'z���`���gZ8�⑯pD>���u�X��m:>���:)|CO��gk �_�=��3�g]�]Aa��+8���* �����?$鱳wF6ʮ��wF�DT(u��$�aX0�H��:a���a%��e1����6��p�(��>���Bs�p"d��ظ>"
����3�����,&pFB=�<����T&#�,� ���a#�&���i{���0=EG�v�߯1�(��\n�8]��Q�jG�
2.�8�c�fZ�C��Ul������z�K��HX�W��*�z"���Ak9�-���?3�����lE�Xs���I���k�8?��l��z���ݏ��˟�LJ�w����{��������ya�|��"Q��^�h��~1�O#�M������ �J����8p�?�����o�����L>���FZ���GN4~�LD9O�>�o+�Tn��鏔݈P�?���ff iJ�^��ģ�w�Fkh�y«�0��ɤ��|�@�5|��7����+rs�P\��S�G�9=�8@�B,����MjJ�Ro=�� 0 d�l�m�o�m���<��R!q�T==��[��$���.�T-�"�@zb�$�F`�Z�0S�H:`���Q��o�x츊�G�
�� s矟&�ո��CeR��s��yF<2L�&y=М5L�>|~~������-��
�̵���9�z�L�2^Pn0
�2��8!C�[��`h{��d
�n��`�0�])��9��`�Q�4�,]y��->�q�!JY��vk�'�N�F�f�GN�")"�W����G$.&�GR�>掝�i:\i�O��4oq��Į�Y`��۾����|�����R�����UM0�>�E�ms�6bS�3N�3ۘ���ZH��%681���1t����e�G
�)j��(2�2�zz�p���
��9k���&�*���ez)"��?�}
Uj��������r"|���b����#%)\ܐB�,���H�|C|���E�J"�� ���N���C�v���W�_�e'�!�bТ[-� ��R�{܀5�����7���+�'v6o���gӣ��`����g����^V%��{\�~�{�+{�YG�%�n�I��.$�
@#�"$���>Y^�Pq�Y������1�m�z��������4��a�����fEs�A��M�卋��۶���H�X��:���/Y\�T���f�,���Uz�!
C/#H�0�(ҰV={(*ݘT���|!I�-_
(9�(!�:��C�3����^�
}�����r؎����n�&P8n}����M£B�@B{D����=��'t�����"Q�Z�&�� h�"�1h���q
"�����!�pr@�7�t+u$G�,/�*��
|~}^]���g��c
o��`�|������9NX�p�"M�=\y:"=�P���Ф!��|E.�Fنg���f�xv�6X����*�<:aC�ȿI�&z�����'���"�B�.�����{.p��#�ނ �_`{XBB� Nxd k.��w����VC� �db�?��I�K�ME\�Q t�p�zH�c�r�5�;��6v��������u��f��$��9j��b�zepSsqi��)�Bp4����喳
z#�-�R��_9�� � �;����LojjUc�D�i0�hs�ە���7��a�z�w�� ���&��9��G[�@$��@d���CY��2��d?�=N��w�
�Da{�[�u��t�?Y��x:'��`��W;����<���#�hIӃ]��u�Ř��bnbbO�n�����*;�R�s>�oz���6�� �YxBt�wk�Dh��P�pHU��AiqS�+��P��êl�� �|��%�"�,���w��5y���+.�v���(�m���=�Ld8Z�?�p[i�h��m����=L�9�6e�7��B�/�{4�/ċ�?�}#������})�0 �w/�
�j� _̘8����f7�Ǹ��`sX#����\���&���?�p�wLZ� h4�2Y�/�{�r��w��Ӕ��y�C3r��l�����`gM-��A�s�%�FW��vL��觯���&E��T~L[�Y�fLa�Ǵ��;��a�� E�[m����hw]�"�c���$F��ͼ��>�H���u۷L��p����n,��Uß��5%H#���e�-�0NV5������J@$!T����'�����d�R�k�L;"��~B;rj��E�m*�e��K�h�Z*�*��[p*��YN���^(v,5�8r6
{���)v��p[
;˄oZ,L��f�d�x�fv�PYn�x��@(�릲��A��E9%�dXzC�U����ӟn`��l`�(�6z./�*�13E,��-L����dgX��+�˽)H[y�(��U�?� DZ�����b����-���w�>?i�J��9�g9\*D��� �T�7�#no�Mtf���1&BwV�NcU��S���SK|�XM-t�9��ӫ2���~�>���L����V]���Ԇ�3]ÿ5�z!�ULK�J
� �d�'-��j':J�8����X R%/�S����_�����P3t��j/�VJf!�
f��B�=�:�+��iFer.��7P�T���D�bK��Բ?f8��}�l+�|Dr�����f�Xd�W*ՔLA$����I��m9�%�l�{>���_���#��*���� �K�갂*+SmC�����r��5�kHf����`��=�{2M!��$�+C+:EK�����g�8�cx�G������M�ލ]�Kmq�#�y�SG9cM�(N�:݀/B����&WCS�Y|�+x"�������)�������%2#��ՍqP�����1��S�a!���������Z������ ��j��,�U)���jSf"XD�(�s"1RbҼP��a�9;�GխGt,:�ŕ|9gIT?�.������Q�Ίh���<�����>��H�>N�)m #����(P"]��t���s���������!���3̑�b����xI����K��c��~�����zD�Ĵ!!��z��Y��ؒ�ibT�W_?�*�d��O�K�|W�'ueB�eV�����$,��0�q���aQ��]W4�"8����AT��z���h��wzԬl�~����T��{��"��ˍd���
>`$#j �Į��������^����QI��]�S ǜl�/��#�V"b��
卶$^���<ϱ�88����R�o
=�ѭH��A�7>�xt��������[��"5��7o?O=�^F��Ñ�-g��:(��g�� <��v������Q[d�0�аS��TE����������w���+d��&�fd^��->xb���<r��c���X���/`3�Qf�roOܒK�־��X�i(%���D!Q#����AC#QEul��忱m�����LR�l�5���Ot�2
��tU�B 7I��^�4��b�߶�X����)�������.ގ�������(?�b���KW�����~����������\ˁ�����M+�6
��`1��!�/\Ì2;��lf_�4bfҸt3 ���w�;%\�K�����D��yt���c��e��g_8�WŢ��u#D㲝-�Va���N]7��\Ϟz�6�F���.m:����ЏB�P=�.m_
�z"K�fZ��9q��v�����}5�i����{���RD�61�|�'��U�eN���-�\�ԗsL���#�*�`
���8g�U�dZ�-�6��Ҫ� '�D�<#j�;��&��s>avZ/���� @uB�3A�` ��,X���_�C.�d�W�P��`�Ikx���"�H�B���#���\�+Ԭ����������}�3¬y�A�8hQf�h$�-G,�?��`$Q �N�d����(%�n����TIF�A���,g�k|6��>�z����M*��"���qvJS*G���,�
� &�I�ſ���`�k�Gw�j�mLE�G�6�atu�IIP+K���2@�k,|@QR�J&��&���Dg͎�ẻ��4*j�D�v�;Q��c�tF���n6��7[���������>_�L,�2Bȝl�QVJF�ءUPM����1g\D�jY�Qc�&*n������#�@�W����&�A�o�
��gh�o�uW�>�-���uK�Gx!�bxQ���t��!W���%:�_�N6�d|��D�<�R$�c�����0�16<�d{�pB}��g�!�9G��3pBf�1����{����}�+��Y���eMZ�������MS���F�Ћl��(�W��|����^���S| ���ep�>:��8c8&��z#r���Vn�H�����c�˫��b�~� %F��_�ޏ�J��~�|d�H�x���q�Ri:$��Oj���dh['�bE�c�>�_��#{�g��4�p�#��S�/�UG��$l\f/l��6��*��`�cn�䓧:~�jK+Ű��U�^���o�=��4�-F>�#��*�H�-�]�����/ڛ7��(l�zw������dv ��W�.y5�c�9@��!����>�Y|�
�[��r �c��ۻ���OeS�G���G��
.;�w���3����$��n��_?�{`��$���<�#�Wc"n+�}I�ŝ�?���⌀}�k�ǻV��S���h���֗9�m7Ș���/s�}�(Ɣ畆Z�0W{|�%k�1�r^���
��#�z6Iiª�ԩ��l��Ρ9���t�)����+z�6.P� D�����M=��E'�E`���f`w�nl����8���N��qw��,��y��� �A�T6{M�����u=x�v!�Ϋ��b�9�8�þ�Zu�����?��j]���!?�-��ӻ���On���@M�g���/��F�AO��a*'%`E���{K� ��(��*�!n��rE/��3g��XN��=�7�Ǵ���I��
!S���0R����T�Ì���ז�bǚ)e��(�*��@L��dj�Xju�A.^�ێ��\SN��G�1�7�;IEQ<�z��(m�6AB�Z�Ȗp��-��%\b|�����4�`X�>αQ�E�L�B(H>PNi>���0�7���pZط�c��h�Q�uTQ�X�AR��w�#[AD��A��>�CҰ��P�����ݩ���4��Js�dQ@�_*�E���z�x�R!�͑-kd�����)�M��6�1;&�!������|�Q����%j)My@2z����OiQ��^��F_��(��������c���r�!e�n�L�[�q���^$E|�T%E�J�ΟM�,g�=;;��cN]�D�LU�"����D���-��Gq��+���]��d�+�;S^J��
K��^=�I����j �d�=�"�";��E�܈YVe� ���и���fo;~��ގ���0��Ii�5vI���L�����T�/���D��}�6%�2@�� 3fP>r�0_�h�?_7�i��UBޒ=����=�����>���Ҵ%�9}{���S�uo���g�aM�Dsd�����a���X��N�C�A�Dcۼm7��=��k#�ƕ�����\/z�t.mf`��L�Y��6�.2
V��P�h����&lSm�����e��:\�݈8HfS`ٝ+�'����-�?��^��-�#��~n�P��0�!_O�����bN#�tL�:����ؗ��.�@?(��U�~�6ۆQ��6���#־
q��]�"c/0@���;������ɽ4|a�U����V�nc�1m:fh]�4ڇk]����C#q~����(������J�eoU��.��1M�.��qQ��`�m?���I������7/���_[H_���]�����G[��O���;��Li��n��1U�I;��Jo~���
��Kϒ���@U�5El�D� �<#������e����J"��n5i36pw�����,��¯�������O�����B����
�:2M&dn0'�+��A�ڿE�<��ı%�|�XS��A0��ȲLg_6_�E�N�@���r��/b���p���Q�s��[i��%�TDC$����܇r�2�'8i1��[���\�ϻ�"�ःN���p�x���<�FBz��B|������I��.D`
�Y,�!�aT�qL�-D��D�$4�ay��A�t2VZ� �y���1��'e.D: �~c?��>�����n�D=>T\�!�����43
��`���؎A�}o�}x�b�?V��H���2��I"����k�1��W���亠*��߄p���>_ʗ��[M��
$��[� h:��,��Uo�mmv]���6�IZ���xڈ/ع�`C��.�!��
��
3��s�?_� Dq�&�=ߘ�$��hk��f���rB
=���!��l���2EU�]�����$�gz�H5�!��"aS ᢺ~�[�����Fæ�����Bt�b�8��"�;�V����o>-�y�Ƈp�\>A�F��J��園��V��;LA|��xY*���{��+�_̀/�I�E�7���6ɪlLZB�����Ū*D����A]Q�4ve�i�|����j�����%�Kt�Z�_��S+q����lINR��y/��c4�,�sD��D�T��J�ә[���e'#$�e�'�NL}#
���mk
6��b�t8�<U�Jt,�R��;Ή��W�����Gͩ�I`3)"���A�z�!Ԃ���/���8�@s\�[B���Jp\��
@uY�I�dgp�Pv���� d/|Qw��r����է�?|��2i����{L�gW�7K��M��������@^�vJ,2����Շ�3f�!O2���V
T��2K�4�X�C|��5e�����Q��_�%�9l��͖K���LcFZٹ� �+�8�y�O9}��8W�B\���"/4����u�Y���a�� ��4�$Z9��4�t�꒹Q�'��������aҡ%#0}ä)�~%/��I?��� (vxh�Q2�*<@(2�\�D�_�Ů�%�; �t�c���ˏ�|앱k���v㫷���fs�v���Ÿ!\�jI��thgc�ە�yeW���vin�������l~enڲ��'����ȍn\ps=>�
B��[��j�����J���z���-����k��!�f��e�_�_n�v^���h�z�4��K���^x�o��^\(��!�
���Q0���K�nW���T����L�a]�٨����a�Off-"����52/��#>�2�f�a��OJ���^5�>�>mԧΒ�`9Ǿ�^�^5���Qn���F|3���:���4�?Ml�8�-zȏ%0��c�+1�=zdc����0@z`�����ģ4ۃ]����I�T�ܯpO�߭��N����s��l��]֖.*����T;���ٰ����(���J��ZЙ���f��B"��صi�LR�I� �,a��1�g�\%�����>8����?S$�7 &��(M|s�X��.P{fQf�ݮ���M<+�L�u����<(Ӿ��@�L
��-���{�#|���ˬA�QV٫��k��D�7u�"�eJ��/$���m�ଲ0h�L"`]����-�������
�HuYs���{�JS'�F�0�������*ix���i~�����8M==M���� ��ʪh��>���p�y���잹&,8�M�;Y|0c��fۣ�9�<ʩv:�UM�YW�Knz�r"oc�.n�H�:Dm��L|������ e�V��O�����)2H�
v�JX��L�F��b$�OS�+ \��I>���b����)�2��p�JW�.�Z|��4�+-�R��
����1�(���ĎS�̱]%�_���qB��%G��96�FÈ�����N�,�#�0��&9������ّ��\S�G(#�ɦ����3���m�ħ����_�%��
�����N��7�EpG��ߘ��1���o�h�%�9�i�@�6��G�,/�b��nR���z���߈2���Ӵ��r�f�`P�&�eȟ�4w�Ў'ǯعl:m�;��px
��Un�D{�r�U%���^FT��* H� �r&��t76�̳��IEo�6�rr�
��iT9)�m˶�
��G���&n7��0Ei���\�8O�G�pnI��i���GT��[�H�L��������<`��a�Ȳ�@��B@`pſ�G2K ��(Fd�d�,ǚ�Rхo�(�d,w/ݴ�Auݭ�j�z}lF��UP��Vc^tE��(�'���{��^S�H�p,3�у*�%�
Z�hX�@�a*�
�$��>2;Ug|#�U|��}�=�����#Dz�EC)V�@�pN )I�O���N��p%
3��P��B%$��ް$!�ۭ����\�}"Ա���K���r2����l����{Rd��np�jnQ��lJ �?2ە4m��4�ӧ(w=�t�K�
�-E�H�T<뀙h�,�E8�t��۸˹I�����D�WI�{�,�H`b��Ppu�Ƕ�Ս#!-��(f�Y�2d�%و�`�]W5��g���'UB
X�r+b��i|��.�dW�T��r��#b[�Fn�h�7�U��`��J��;%�a �U�����S4H��C42�'��ʳF�]ɱ���i�bx�4�yO���%�T�VMR^R����7r ��A�Ԕ��8�(Kr/���цզ�p����Ϧ-#<�dd-x�D�f
*χ�cg�"/�Sf�1,E(��\e+c���'���O����=�M������UNl�E�lw�w���S���d����IL���en5��h�e��RJ��PJ�$ՔT�6ͅ�E����-+|c$�&���(N�I�K
(U ���7;���{�[q%�5�����b.n�!�hzCf���1bڀ$g�1M���|FP
&{|�z����k]�]��m��#�b��9!��^�G�`jHB���I���� �9�McݎO�s\�Pu$-��e�f��nbF��?/s{�'m=a� ]�L<�#�vEn~np����;���]g�C&S>ʒ>�@�}�k�b_�]$�~�!��o���:3.�K�:���y�o�.cI��+�������|�}�!�:uM��-��n}���������4q�m|�MV�����ݖ�����r���v?�a�Ǡl}�l>ۅ���h�
�!b�m��>��1�=DNF���#^��-M����MC!��B�:=r��J-�#ң!��B6�#ꑻNm���:e���#,���mT͎��3S�5x��3���;�Φ��G3�01�Fu,\��k�c~Q.qX�Đ��\@���jM��
�_����T���}�uCE����$�C?{�"t"�OX��?3��Z(�(�2����g��d2�y�p�) ��>y-]���l��܅E�X�Y�%�z���5xW�j��UI!���F�,HP4��v?��|몵���̧��_>����黛�R_I�+�
F��yO.1�_�A��t6��B{M�[�M�G����b�9��zP�D��)d�32�r�m� ��v� ��2I�>����!�Eߦ��F6��ma˚��dv �*����Fخ�<@�,�� বD��D1��1E��Kp�U��s��{z�<5ie�5��%�v�ąX�� �jk���@w��8��n|q0�-���N�>yS������l,��o���2W�yG�M�;t�,�H.
*�D6���j.
��/�A7�^u(_,C�Ƒ-��D<>�q����mH�^}��9P@m��^�8{05�,�%?�!u_��"a��϶t\��(\�6��D*Tا�(Q�ncC�$7r#��c�Z������cq��f�E�{�b,�֭���HXG�ҝ���煡������}�ViLb'>ۊ,�h3�fiv�C��Hׁfr�+G��f{Xn7�9������o�����H:)'*�*4�(�̪�9""c�Zl;|�x�js�
���[1��#K#c�4Ab��͍����ѽ��Ql��G�ϟ�Û�F ����z0�l'[��7��X�1B1�KUܑ$l��٤��
8�&��i�s�=��&H�\��fV��_O2.��+2SȖf�-GT���*����c:���Y�h�F�$\�ݮ�pF�+_&��2[�����J`��떂�`)J���G�)�t%�H@�N��y�FP�B���|d8��ah��IH8W�U�'��Q��"s4� �p���b�K�lu�V��a��G&��HH���U.�s�8'������n(h�]V�� b�5�B:�D��T���걋�d�hpp�1���\����7�tG�����iu�S��W��� 7
��W��^c�����þ���|��� ���pA�w��w��P,P|L��s�Z|`Y� ae;X�YхZ��Ҡ}�\n�G������YZ5:��[99r���3>HSs�F���t~�]�|k�_�48MG�<�_����[kh�Qȑ�@�D7/�C�B��;��sPu̯���s��EBA��ҥ^�
�Z���(��p���{�,a5?I��w��`]k��:0^N�R�4e����_qZ
o:STif�L�C9hq��vk���G�!����F�l)��T�YY�J}2u�������f��Bc6X�J����Ç�`�PJ����$o�]N�f�r!��Kš�W�d����c�Jp�JP�)y"oն4$sB��
�K�Ü�p-��(ИB��h��8t�N���b�8�F5� ����\B�U� f/�r��v�+C�qN�k.�S��d����(3��P��Qȩ+���PJ=���IjҐɶk���l�0(��ȴj�"'�X?kp��un�G���M��Q�c�����y<���u��19]�[���6X�!5I�G��?R_.]J�|�2
�",�K�i�_�<^����b|����)�1/V�,�����-nh7�k�0�m�'��ϓ���}ܸ�A�v�ɗ|np����A ���4/�M���3K�ȷ��]k��L�╉BN1�H�`������ �b�g�U3u�)��
VV����
hs�L��4�]x�N���ډ^V�l_�Kc�ڞ;V�mk�,�+O�*���L�h�>�����ap$�ާ�t��Ɛ�e뙇�
�'=�f���iP�r,�������Pg��_�������oa=��n�wCB�@�m6٧p��1����崺Dty��k�`���7^����C�ְp�v��O
����؏צ2�Wee=n�����W�b����I�k��N`;�Qs���5��̘u��?��4�3]Vh��\̼�Z��t#k���8E�,�{�8 ����ŸМ1..�aA�IfϱE��߯*��PelZ}�EEW�V�"3b�"4����nqO�Hc��T�
���}Sw;�R�8جF�p��YJ�b|_�:���<6�yr�'�i��I/n&H:����I���[���X��G�L9�'�V��~a~�[���KVFv���Ύ�l��]��
�����3%���k���zT�L<=��ƃL)U�U-x�2��f�
�0jL��M?�$��&u����Ѡ�3�浲�a~Mi���>�Ud� ~k췿�7�h�Lw<�卧�v�
Bɚ���]�Zws�M�]�[pp.o�oZ��a�m�rb�{�؟�1p�Y���d������a�p���gAMf9�R�r���*��`Y#(�/�Z��ޕ�i��
~'ʤ�"��|�Ώy=q�@�N��`D��Wk.&
e��l���_V���~�|��c�%W*�9�8�9�������ٖb#�n�ppX:��R2d��F��?n'aS��٥�r���-�2c�I�����7L0%���?���<���stJ��FB�,
jn��ޕ�Ӿ�S�d��z��4P��삃��n�� ���>�<���U^���<]]�Wx�70�����r["-�l��i~�!E�X[�+�lrD,�p|B��NjӅ������_>����o�������ئ����_��|w���/�S
�4�L��Z�N;N��w��k*�S����1G RĜ�����ɴd��Vl�y�"ߗ��p4H�?�hP=I�K�/B��+߸��V��m�'�V�W�������z Fl�7����>[��+��ն��]>�Y������n���^#�ao��-������/�J��fiZ3~�{�-�
��`}lo�����C�=.�����=�
4y�� ��ׇ�6��~2�J#���`s��
�'��~[�e�>U�*�r>�1F�vE�C|g�V��rq�7�����ηd��s�!�y�j�����!��������3��}I{u���E���UowQ��t��3c턡g0p嶗:H?9YU2X.��8��[��Gʤu��,@�m�rZ���E��K���]�i��=?�����yZh���{�
OÇ&��z�iX֍c�j�����{Z�D����{�d���ӼZ��5RLm�ޔ�~��"�M������f"�D�qM�*�G|}�v6:�q'�7äsb�Fb�Ve[���\���&f�s`U�R������j�Xh����N3�i恵��)������z�
<�c�^�����p�I�rb���p
����jbD��hS��E� $S�`9�]c��@��rދ�4ӊG2HakJ�c�6�4�u��[�#��
�`d~l��~��&,Y�
endstream
endobj
34 0 obj
17020
endobj
32 0 obj
<< /Type /Page /Parent 3 0 R /Resources 35 0 R /Contents 33 0 R /MediaBox
[0 0 595.28 841.89] >>
endobj
35 0 obj
<< /ProcSet [ /PDF /Text ] /ColorSpace << /Cs1 7 0 R >> /ExtGState << /Gs2
22 0 R /Gs1 23 0 R >> /Font << /TT5 12 0 R /TT4 11 0 R /TT6 13 0 R /TT8 21 0 R
/TT7 14 0 R >> >>
endobj
37 0 obj
<< /Length 38 0 R /Filter /FlateDecode >>
stream
x�Y�r7��w�����v��U�*.䚇l�:H�_��
4X-��R
\�������~�?h�d��I���g�'}�����z{�-��n����[������-�+Ua���������R���߁�ŭ6�76��D�i��IN��0%�!��.�+h�Ц��b۳LSW������OiϢ��>
endobj
39 0 obj
<< /ProcSet [ /PDF /Text ] /ColorSpace << /Cs1 7 0 R >> /ExtGState << /Gs2
22 0 R /Gs1 23 0 R >> /Font << /TT4 11 0 R /TT5 12 0 R >> >>
endobj
3 0 obj
<< /Type /Pages /MediaBox [0 0 595.28 841.89] /Count 6 /Kids [ 2 0 R 17 0 R
24 0 R 28 0 R 32 0 R 36 0 R ] >>
endobj
40 0 obj
<< /Type /Catalog /Pages 3 0 R >>
endobj
8 0 obj
<< /Type /Font /Subtype /TrueType /BaseFont /RUVTKM+Geneva /FontDescriptor
41 0 R /Encoding /MacRomanEncoding /FirstChar 32 /LastChar 121 /Widths [ 333
0 0 0 0 0 0 0 0 0 0 0 0 0 0 538 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 651
0 0 0 674 0 0 0 0 583 788 0 0 0 0 606 606 0 0 0 0 0 0 0 0 0 0 0 0 0 553 0
0 0 576 0 0 583 235 0 0 235 894 583 606 602 0 386 509 443 583 0 780 0 572
] >>
endobj
41 0 obj
<< /Type /FontDescriptor /FontName /RUVTKM+Geneva /Flags 32 /FontBBox [-808 -617 1686 1222]
/ItalicAngle 0 /Ascent 1000 /Descent -250 /CapHeight 758 /StemV 0 /Leading
83 /XHeight 667 /MaxWidth 1716 /FontFile2 42 0 R >>
endobj
42 0 obj
<< /Length 43 0 R /Length1 11636 /Filter /FlateDecode >>
stream
x�zyxU��9��^�K�;�SUi�� �1�@�M��D&h4F@���%a�;D���8zF�ĥ ���(Χ����qr�·��s�S"d�y�ynU�:�[g��w;����� �!�\P�rҮ����%��+y�Q����EI�6��-[yCs"�_���
7�z��κƆ���z��E�P����G76��N�!��iŒ�z���5ׯ�}y����}��++W��2��ܕ�4���X�P��I(
�E<����纙��ZRO!t��2�-%�`UК{���Y�xsݒ�w[��L�t�BV�ѓ
xO@q������C�i�p
�%�+�*1T!/6�*��arXv�$��o�t��,Ӟ�*lRe��.�T��_��y��DG��y��d�|����*� �)ry�K^
a��%o��Pt�kT�<B��U�K��C|��c����w=P�/��GCt4yr!�<>�6�Y�*������`k{�Y�� ��'XѼ��F��g0՚(�z�S��G*���G���iu��Ѿ�{���g�u�G>��=��D��F�� @ұO���a_��I�ܳ���D���Rh�
0��lu�|
)~V��n��
M.�ڛ�/F�#�&
Ǩ�{V�F����BR�(ϳ����;��;������l~G�#�ߡ�;Ry�`D�,� ����{l�l8�p��I�1��hixV��������8��uahdx�3��i4��M��twHU�d
<��F�F���Z3t�+�&��1o�Dc��w4�?I�#��$�09���]�T��-��7@��v�6��m�+ʡ�ݤB�����4���!���P-��)�r��FT7��o�!�T>��PS���''�S�/���[_TyE_[��*Z�}�'�����F�UI��H_���J�W^8O뫼i�d4}V�!M�����u�m��s�D4�&�d�OC8G�x��Y,L|X�ہ���\��ԇ��xjG� t
�@w�P5�Ʃ���Ө�(=Ԗ��`;��:��V�[ݨW����������ը ��Q� yo��C�aF&m�Q[Q�fj!Z�����o�6zQډ�C}�Wv���Q:*@a��#��.�w�<}%A��P3���p��#�5�.z�é�1�;z�?5(���J�m�{N��m�k��j���W������zk�Z����;7���'�[p�Bo�����pރ�/Rc�qT)�}��Mg����׃����^@����U�V5���`s@k�k4���J��T�@7���N�=��k8G�H|�`����`�X�㉠�P�v��G;�۴�z�}�}��%�{�3�5��k�� .ŕ0��0���p7~���,>�߄�rS�2P"��aN�G���t��>
�{�Efa���.N���x#�g�>�>x?�Q�J�dTX/�Ț����3��; �"�Ņ��8�2\���<\��E�����>���xJ���<*�YL������SOP'�W�H�]+�@7ý��p�D��A
�k��3����9V`e��v�4��Us�pwq��E>�o�{��9���H���&;��h�n@�0?��?���r��F�wp
>@u�u��>B�Go�J�������uW���
�=�!���V^��7����D�'�L�+���q��cx�A}r��3���](ej7
����fg2�d��}��i�"�zF�$�]�$��f�D��d4�uϱMa�US���(��N��M��z(����.�@Qŕ4Q��WUWP��r��p�2-����� L}NM<�֨�pm�p���v�SDځW���ZX>��ZQp��eM'n�̚Y5Ѷ��(8��� I��c D��14~x�0��M��1Ø�gB��D+��A���9�?�ut�t�O�AhF��
b��Y�ᶙ�.D^5�xU�
ê-��&f��=$ݰq��_5��H�ӡ�>F���6TMoCP�Ε"��/�l��&CȈ8��Q�|'Q��ă����*��
aC}\�x�|����.��\&d�݇�$H[�
ّRI�w#:�j��z��L&�;�]�>ĵ��VH��t{�z���7(��{'���a�y0�zh*��=�{h��c9��������/��@������j�[�P�8P2@�9c�����~����l�$'����0
�fd��Fe���&���@�bL!��^
��,~�a?UWxh&t�i���T\݄J6�Uc����#N/�?�CO~2H�y�~������6\gp�)�BHr�lV��ۙ�B����nyS8��T\��U�I]�X���?�]�h2,�h�
����٤Т��V0�L�>6X�eLfQj3�pc��Ҕy;�eD3M#���Ŏyr��E������H� ( ,o��6��Y5p�}���@0�KN���C%��of5v�<��p�6��Iи-�z�|Η���Kc/N�:q�W����˽,�4��z��Y��?����k�A��i��z�����t��8@j.�o_�n�ַ6�7�q� �JC���4�=�8�t��&���V��k�ݢ��t{w��.�=�{L�[�wYw��X�=��dHrHzV�d�JvG��J���MD$Xm.��|�'�ψ��#@ti؞�y̧Y�Bi���gV���<�/����~��ت�%�b(���x�0c�4Dss\Sք��R��y��LJ��Y8��i�FZ#U"�|*�,������RLD7�q�>{���b�=yySS���;��sr��%-�oq�㫮{lsᨼ���B�g��W�
�S5�N�:/�-|����/2x'�����i�|z>3�_ /PL�џ����YB/a���WXW�
Y
�-ts��nf���+��ﲜ� c��k~�� ��gM�q?~Ԅ7��Vn��5&�d����w���~�7Ql�?S5I���;���i�}'��ұ:KNF]�!��®EB0T�3Ԡ��
��o���H�?B9O��`;����kU�Mm����+H��X���H�K��e�D���:�����S����[U��_�����WN]���]�������f���'�X�#��
{�\6)V��yxi�/O������]�ë���Y��|�mﯚ�ª�7�cf=��DC������O�M�O���|
���ծ_����ii���������]/�_LyqT�������.G�N��1�#���Lq^2��y��2z[��ڒ��k�%�O��,
Xp��v�핚 ���H��V��Pf�?�'l��Rqn������1[8~�?�KW�%Ť�Q�>� �(Q�(�b���7����B���`�o\a�ߛV,P)&Z�!ٓ�4�h�k�M�y���{^�&[����N�.�s���.̮�o�Ik&����h�v�
s����i�f�����|��*0����5#�=
�O"��Xfr��:�ӡ[�vf�}��I��>�?4���f1�s��V��tL>�r�sP=��\)�]V�kIv��ْ��ɪ�w��!y��G��${�[C`��i�.�U������0p�@�O�A��b��jx�*�7�F�xR(.�u)��[�Q�)9+w:R��CA6���R,r:V���f�r T�y�ʧ�B%̝��p�&�=G7����s0�%�}���?|v��������^�Ų~�ޙx���sn�ⷥ��/���'UwU>��2�����u���i�v�]�_:�������&i��!us$N
6��8��B�5ou*�X6`Crȍ�4�C�>�.w���>�w���6�xU�!`�É:��'��:��E�MҒ��k�v{�;|�?��Md��s"b�}�H�4_*���4�nj���o�5Ӛ[ؗ�r�익\�@�u5���
S��^_Yw�!{���|�p8��ʟk��z�ә�1O�4͆@��?zX�kL̨��
�OpH��>E�d���ͱ�X������c"��g�9����j�C��.p<�,�
@QR{Y���6ss��%3!;��~��L<#�����ě�ے:J���f���N-�������=t�]o7�Mv��SG뽆�&�Y�(�E�|C�)ߜ��I
ɕ�J�<�<}2,����12LJ����$ſFHY#�Oq���M�g�l6�Cv&�p�3��"����6W�+@��Z�@V���[�%�ð��pk������7B�3�A���s��~�O��O��
��2�#�O��`��eKQ�)UL���B��������a�`�1�"��g^�D�
� r�=+��^�U�7�-/�sav��&/�;�Hp��9������DN5�d�7�_�]��Ɂ
��d��|p�I����}C���a���p"v��&m��$� ��$i6�Y�4�Y����L���
����-"q��K�� ���9yT"oN�b��d�5F4bcrmKaʭ�ݠ�]2D�.�'���zb�/i�d�(�Y�s������mr��1x��niBXR��AX�3���F�ʢ�$�V�D&I�z�mH#k�E�%YJ�:�q����\1@ьqi_߄�����n����
ח<�k��/���F����X2;�3�烃���j�7�p��w����%t(���D�;<�fi���H�XEI�*RК#���X[��a��Xl10� �ʢG&�T��!=�'[��B�B�d�ᵽjޝCZ]3T���
U
Iq6�������-,��-�i"k����v����И�h��w�'dN��t�����(W:��������s�s0��vx�Abi�S�S��LS�9�R��������h�[���v���o���2�vcg���4�S�i�ki�H~�x ��iĝ��4�ck�d\�F�O�Ӂu�(6%mL�Q�X�pR�u���,���#��r2�#�U�2 �c�,$l�v7�b�Y������)���6;,�Tq�Ti_��j��|G�L��`_˶��n�w�[�nn�n�~��GO��}�Dx����q��#�>�Oz�������{�{��G�G�K�K㗦/͟؋��jŅ�.�>����?���o�7�J����3�Π7�6��20:�B%I]"��gpO�;v;$zy�'ϒ�ߐ�Y+�fL�V8��9��3rS�`2��s����'�)�Hs��%J����� bQf���ݼ��b��NƁ���s�F����UoG��q}�S��W]&
�R]�,�������D̊��C�s(���2�|5���U�W�ۜ��lCO�ӽ<�ŏ�t2�������v��h���OeQ����G�����R�|��:���p�Fxl�:� �%���
ܣ���'�74�Ҙ�a7�9x��ХsŨ���M�'�����xډwR{��^�q�(~�z�y��YbbLz�y���U�Q�@�g�<�#��HS��:=V�4� Zb��0'�9�1Wo0É�D!�ƺ��%�1� ���"u[m1<�W�uȘ�&��[��Q2���n@�ҁ�fa�K;9�8�ƫ`C�*���
����Dh�+o����#�1���}[SUKդ&��t���U�=f����Ю���O].(��,��3���72eh*��f�k�L4�Fs�+���ZT�L,��� � ����ϝ^�l������ե����v;!<�i/Cx�y���h� ̅�B�v;!<�i/Cxkp�6�p#eD>8"?eD�rD~ƈ|Ո���9#���Ѿ��l|����4"ӈ<�W�r��G�W�ȯ��eD��y����o�'_�]����_����
endstream
endobj
43 0 obj
7976
endobj
21 0 obj
<< /Type /Font /Subtype /TrueType /BaseFont /UISFJY+CourierNewPS-BoldMT /FontDescriptor
44 0 R /Encoding /MacRomanEncoding /FirstChar 32 /LastChar 122 /Widths [ 600
0 0 0 0 0 0 0 0 0 0 0 0 0 0 600 0 0 600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 600 600 600 600
600 600 600 600 600 0 600 600 600 600 600 600 0 600 600 600 600 600 600 600
600 600 ] >>
endobj
44 0 obj
<< /Type /FontDescriptor /FontName /UISFJY+CourierNewPS-BoldMT /Flags 32 /FontBBox
[-192 -710 702 1222] /ItalicAngle 0 /Ascent 833 /Descent -300 /CapHeight 625
/StemV 0 /XHeight 458 /MaxWidth 600 /FontFile2 45 0 R >>
endobj
45 0 obj
<< /Length 46 0 R /Length1 25060 /Filter /FlateDecode >>
stream
x�� |[ŵ?>s�v���bY��[�"˒9��D�qc���F‱b�@�N��S��M���/�e-�(v'�&JKiJ^YC[��4�yIy -K���,����>���}��vϙ;3�̙3#]��b �D$�y-"�9��筿ԟK���1�?��\�{
!ꞕk���Vc,'��Fg��q��/G��S��G
��t���G��(^�(zτp3`+�0���G�9��G�.�i�˲ț����<~6���7��My|q����8���Ɍ|zz��`|j�:��y�c�8��Ȃ�-���?�}���ɏ�cu#<5g��i��>��lQ(��A�v���Ećv�t��N�#��t?�t?ݓ9[�H����h-�fY���Fڍhˍ��~��yt�<��P� ���P�Jށ�8 ����b���<-%�/ }d��a�wd�/�i0�i0�i0����79�7A�M<�&h� ZorZ'S��tD\�9��Ћ��>Ss���-�I-x���_��Nڃ�@����ҙ 95f�g��&FIO6 g�$�4�n+9n��bt$ >A1* ��� b)R�H��T R%H�QL ,�R�Z�1��D�����$�G�jj~.�Ed�mm��o�hg1Z_*��;ϻG�k�c��m��G�Y,�p^��1�Op9�5�}#ޙ���YX�Q �nр�6���m�ƀq6�{`����
���
�F�E^)�ݺK�
9,�F^$�t��Rت8����Ea�pXv�v��*��S
�6��>uJݧToV+SBJ��D����K���6��RP*�*�6U_�j�Bb��'B�? �X�|dX�#���~� �2@ ��xl�ۆ0�c{�a�X��<�j��<���~a
����wQ�]"
�
��\Ix-`r��@t�;������d�.@�.�`���F�L�� �-�,����;�5�����7�P���z��^%YV8���[{J��o�nۄ�!�#��V��d3`7�,j�KqZ})� \C�����
����WC�6�.�\�s�[X���A�"�ŀA��
�Հ"g<8�A��A��<�c<�c���[X`<1��c<9�Aab����\ �
�ޡ�;@��;8��������;@��;@��������N���o�F�o�FN��A��9�F�o�F�o��A��A�QܮhlA#4�A#g��`�8�9�8�� q� q0��A�3��A�`�/�8��A?��s��?��?�鏃�8菃�8�?��?���8菃�8�s��?��?��oVb"= ����<�
��|�,�~�2�r�s6b�z��ň-����-,���A�|8�A��A��|�g|�g���F�@/���r:>��3��
[X`|���Ox�,/��+�>}��>}�����O��O��>}��>}�O�� �a��S��N]���9u�S8u�S��N]��N]�S8u�S8uqN]��N]���9u�Sި|�8��4��p``��&)�H�G��H�G
<8�? �Z9H�?��9hj�H��
�)�l��%����@�/h�=��F|[y�.�
*|+rًs���g}�O�b���\�"�֪�2Fwʵ�-�Vo�WoI��D�[*�["�-%�->��ڦ�h$�Qc��4�J�����eȕlwmSI�`;P��q &8�X��T#�ҿK�3a�vaJ�*v
�f�����H�r���1���4�ͤiK'�\83z��3�\Й^0o�1azzxV���s>O�Փ���%����2���0�m�8����D;������δ���%�)�^Ri�PY�d�fY�Me�NB����go�����ק)�s��Y�����Yѓ��(��}�l��L�kU�jվ���v.@斟�����` r�O���K�Y^,��8.�d������)�`�g�N�6!�:��;��%Oԃp�P� ��0�G��V/(�`�J���z���mo���@����봝^g��u��:��uD�~Nb��u* �:�T��S�s���uJ����n��������$�I�����ַ�Z�C������W9������dgE���_~�*��
���������,���������Y��Ь�d}��%����F���[C�f��v�L�9��w'�mO��&��JF,�xu�����V��x�a��0^]r�պ�I_���2����:��~w�g�]��E`Z�q�{���}�'m�L�tĚcͬ�ϊ��6��M�w���E�͡�"��O����K������KMri�Х��ճN��F�]����@+W�K.��xƥ�D �X6���W�������p�%=,���Y�]�_Q��KI4J�����(_�*`y�%��>��.�=��zɥ���eh���,�a@x2rY��w7�W\N��d�����u��03�����<��s>�KK����!?A��H6қ����E��
��ﳗ'�f~�H9���(9�܋�/���WP�7�2.���~��E�ez��|Xj�*��
�U|J-�#d=�@�[��{A!#�ζ���&�Me�g$Bdr���A~HM4��8��$;x�f���,C�v2F*v+��nœ���N��V)��N�-sCv0�x�K�z�eEv1)&SI��C^W�Q��|"��sv;�GI3(m�;�/�>�:����(I�f}�ײ�5\}琻��?��l��P$�/��8H�>���d��#���)��0��I:K�%�
�w/�w)�U\���@���*h�i']@���@o])^��K���-���Iz�1R���O&(EΧ��Z� �F�ҿ/�g(>͞��/+`T�$@J�tPX���%;��_�щ�����;�z�N�������o*+~����W���C��og��=zf$1҉�^H���1rw�����9
љ�b��}Xd?�?�/зiF(��Ż�gT!+�V��1g~��ζf{���~��
�r�1y3n���6z&�G��~P��~�>F_��
��1"�����)�o)�gz3wevf�K��[����&�$S`�,$�Cd=�m�}���&�w;����y�r�|F�Q--�F� �M�3�VK��6z?}���~H�)P�$*�s��χ���7���ŧ��7�7v��"���?S�Y5]��z⾉2B�<ӛUg���l[���K�������I%��\��5df�F�5��}����1���ofZB#t=�^���}��c�=���4����CE���ߡ�����W�q���|�j�q���KBFԋn1��lЧ�G��!�SaTX�4ŀ�Nœ��_+۔s���̪�T��,d�sʇ�
u�/��?\���!��r��~������$��������#��b���L��B� "vNߥ{�6��}[����"�"��*ZEo��
�F��03�B^�!�!�#� {Žt���~No'��.�B!YI�@��[�,�F('!r)��RVP��з+��U�-|"�Mco����mt�F�1��ҳ��¸�^�s��ِRj�T�J��
��
��v��\HŽ��m��f���\JZ�<ػ��Zb���l?��]��I�$����^2;���GB3�nr������d�G~A�C�wP��9S<�(ĪqD�Q�f��r�nv�-4�$�O� ��Bo�Aޣv�`vM��qo�����"���J/��2�^_ToS��jRU���*�
�|e��E9EY�,W�N�I����ϊ}�_(V|�[�(T���?��������1%VaNzD���_��p�+��6�4Z���o��g��ӳS��L&s,�R�g�3wg���e�'^>���o�~���Ļ�_/��f��pYvi����7[�����;t3�1L& _��^���0�v 4�,�A%�!��!���(�I������T��`�#���z��1�D��+@
=~&���DZ���e�T�!qhl�"��:�g~LJ�e.���I�Fg�O��x�W=�;UO�c����n�nZ�fEs~B��g�Μ
�v5٩�;�z�|��g-Z�`����ӛ�56L������Nīb�ъ��H�$�}^O���t�mV�Y2z�V�V)�@Iekhv�?�O+"�3Έ�th2���џ�#k��u�~��2�VSF�������)��I%i�U�[C���Y!�]:o ��
��Ӈx|�+"p�L�8L������M���~VyӦ����yKNy�`zz@�
����f��m*ꈣq���Ur/��
��/𧵡��U�.�ǀ�6���+#.��3{��Z��. �)w�g٬��6�i���N��<�$V�]2�zs�є�
N���se<ƫ�X���IYC�i������a)��t�`�C�>;=gY>G� �(d���K�e��4v l^�[0�h��N�* {CC�;Iҽ��4����[�d����%���,w�9�����J�L�.b%Ó%'�a�����KiM�ĿI�[[W5����P<�+�\��ߺ�??U;��ʕ�E��,K[[��n�Mm���K1�Yz�
KiE�*>�W��5��<��g���3ra�.��������G'˿F�1�oh���i��Ok�a�ع�F�\�t�&�ie�Ѵ!�ֆ1O�ᴑǭ��qQԟ6���YL'B�Ң%ob�_�O/��fir�iJwC���0�+A�L<]0(���*5oj�w8ª�=�!Ԅ�R8m�q{x�if-0sޖaQ��HM��6����ig�A�&�q�o�i��n��A��M�/Z�V��L�b���vh?��م��tW��Ҟ�����(�*�O�U�#<揄��6)�����P�g,����4B�������
�T�҈�
u���c"��ƪ�i�����M�Ʋ��C~)�i�h훆Z���t,��Vwz�m=���h#T�@fn�[�m��-�.� ?����KF`з���a" �,\���\>�K�� ���d%��'z{�����ܝ�.�a@+�z�{�p⇁��|��n�8p4�J��!�-�"{����|���s����mE�ky
�tU�kp�D��BP. F�$�-HY���*/�I\ĝ�]Cjȍ�,�E�T���T��:�yY;�p���sӯ����Yn��i�K�C���VWz�����,ꕸZ&��4٫R���T�N�<"��K�V�ĩ���+m�3�4W��i�4�DRMM���90V*�q��縬$_����Odm���Q��Y�ü{['`
�al� Ke�No���:d(,��F��U�y�6F_�~�#*�+$��l4�n4^�25����
�k)U�U�`$Y7��O������(�t�\���.��]RѤ��+�RaS�]�܈ȴ�m�>CaS�I���d���im�+�BJ� +���P�����Wt/�՝�Ed
(Y�L��-A)$�H�}�}�}%������:�eScrk`O��qXGUT��RQĖ��P )�;�6�R˞��V��8Y�Ԏ s���M�1��(@�����UjV�Z�?4D.m�#��9n_�4JuZ�O����.lj�%|{1x�����H��9z��ߑ�:t���@���
qh�c��d��ht�� 0똷wh�:�D��h��^��7��.$ɔ�d]$Tc(rcQ���mx1�O9�T����.n��K*��u�/�ն������Wohi�D�T�4�5�X��c���\클�'>��:]NV(i��*�����TE*�����x�Q����ռ�z��������q�:�%< <(�@�y���DŔ �7���)u���W�믓t�:A�
�]���vU���r����
X��W]���u��ݼxG�/H��a�E�
��6&ƄE�E-S>�_�P�j��Գ��Ι`�80:�6�:Ĝ�&I�-MI���[
��s(ji��]w��*|j��k�(�q,���ܣx����`n�>��4�x�:Az�b��������KN=�����
n6���"{mM��7gי����?꽪k��;��
���3�C��F�#��8r��k�Nu�,�x�=Q^�����V]�XR0��)�
��l�,m��5�A���2�%�X�[T�f��(���T�-r�R�ju�Y�+�5_i>A2�J�H\��%�ȧ�O+�����%%�֔��G�D���xʁ�[V�r�.�!F�d�Xm���� P�m'��Nm2��m/�����TxI0�P�te����F�MYݭV��9o�.�vU���A��ߞ��n��g��vj��fwFϻ�σ�Z>�6����)<���27��xM���g
d�TG��0�ߐ��+eWy�?���>-�"�>Z�)����'����H��1����p�
`JEIt�4T"�%B0�aÀm��R̾h/�|S3���F0EJs�֜�P&�!l���v�E�2?�_ۑ�����B\4r��ȶ;�|Hi��UWg����̱��6��Yx��
��5k��x$�VHz����7�a{�d�ǖ���%�~m�:��ش!��2`^i(<��k�Jo��v˜�˟m�K>�}\�v9D��:�vC�����=F;��r�W;�@�G��VP�A�j��
��Lyx�n�>��uŬ\��"�D��Dd(��8+��s ˙u��9��;���@�@:��D�+&vL�%�\`O�X�e��
*T�Ꞝ.�\�
mP���H鉮͋�M�
� YG ����ʆ��
O��j�uw<��K��g�*��n�|q�����Ew�+C��;f8,���O�sŭ.iΌ�Y��>��H}~f̀�}���!9��k��B�Jz_��/U���¸�_���+���'��KL~&o|j#�g��SDܲ�I_A� ���s��ގ�6��7E��m�ݬ�[��Y�H_���n�a!\,�� ��x`���q��.�O���q鰔�4�%*9�훹�1�b�\N�$�psR&}vB�tLĘ��&b�P����}�Ԉ����N��|�W�
z�W����bN�/�V�/�|l(-��(=E��6ĵ2�
nQ2/_�S�K1=�.C�ξ�������:�|�r�uǏ��_`�TS^A���G#��نX�)�k�}��CJ胲n�2f{��k������[�BXc���ջ�w��>�}��o��-�m��}2ի�T�e�m�����C�������=�ʩ�����Z�t�hEcò�����G4(��g,^ٓ��f�`��R�;�6{�w�:�$�-��aP��I�&�_'��%���/i(l�D`Kv�" �cB��\���hhv�����*�;��zW��r�����*��>�U���:�3ܾ&��!�� ��D:57ġ�a
Eqq~�+;)����F�y:d�x��/����]�b��W����X�ޔ�梔�Ah,��0�0�(�o����d�*E(897��-B=@���?����~>�[>�[����/2�ijߵ�Y{F����}�Wݗ��v/��5V��[���w�iIm�Eg�X�d��%�ӻѡwA�k�9�v�K�S܊�#T0I�Z"�e�pҡ9�Xz�e��e�
�V�7�e��p��3[�}����(���x�����ݧU�'5�$�fo{���VW"�Y� و�X�@Y�C,+b�dE��Rr$�����v�*�
�VX�ёh�r�~"��D@��Q��0E�wI�W2�l3������nIA�n��%���t����<�@j:��c�b�H@�4I�Rk�7�"��A�?�0�t��^j�]�*`ے���f-K��y�9[@�U�Z�L���Yx�r.u�����rkd�����&�'����3���p���}S+����鱹,�}ff��E�'$L���r��T�Ԇ"C�Rm�i�~��M���/��������{G}_�*�:z4v�Z_ʴz5"-"��P�H
��8�P�[�{B9!�P*�
�J��09~o��(b��]q���T�q-�����d�\N����m�>�ݭ}]����Њ>m\ۥ���nK�E��R�
1������������i_9��'�b����=6�X���>H�aA�K2L�ܖ���l�t�毨�+��>R�E
��h�?iZ�4��]\펇��H��]'t;���%e��e��WnU`��fUrR�m��'ͪ�������_<U�#t��?b����j��������soO=v�e�1�������y�R��ϟ������=-�e��>���u�<���.H�S����3�9��*�]U�!�:!g.9�]�B�vL�`.+��V��D�7��96��ɑg��]�@�*2�m��I��o�T��'d=��]^Vf6K:��ɪ����!L����X�1����jZ�l��
~�Z�`2�wOH�ԡ����ŷ?Bɷ8�Bs
;��w���"s�D�7�'-ݻ�Z.x����Č�O�S 眒�9�V�tU�:>�HU;���6ng$|ƃ�3L�&�S}��t���%��S�r�/�tcщ�q��%\�â�/�!0�+D�[K��(�T,�ɜ�>�v�'�Nʼn��\��=��t]8��%,ƺ�G.06�p���
:��ȵ�{�G�
�ݦ�B�-a뷉6�g��\ؘa�(�
�Tj-VF�m8z��0��k�۵��>J�/��hc��0�Fi?s�D3��rJ
�}s?��Z�����e]n��:l�Tts�W�W�oX�X����[?�6�$���*�����W��i���m�>\���Gb�,��ɦ���;�*��n��#��K�}���O��YEm��E}p ps���g�OB�L�l�-!�V�n�~5����c- $�.� �
��f|�.�SU���(�Qo��kZ�s� �bq��J�e�L�)A#�/}F�ה���%�l��*��^Vl�b�tY>��8�xp�:D{���en'��$���� l�4M�&�9RSϤg���;7w�sn
ʭ\�8Y��n5��2�`]ðl4�l2R6�b6���iX�<�1Ҟ|�c���i���߇����|�c�a`s�#ͅҊ
D)��<�?��a9�� �p[.0ؐd��ޒ�����=�lN���ZD�ɔT"��k�e-f�MF�[�Fg�0&@JY�e���,��Y���!27c5�,�8�t��DP̂�XP�>��?��uQ��هmg�����`j�v� ^ʏ>y�!��x�\��g��u��wݺ�k�^�4}NF�����R�IK�;�K�/N�,���b�V��/i��?�H��E�'�*�[a'�\uW�e巙ws+Lid�����r&V�N֓���I��̘onK�����ɺZo���֬�,���{�����mlk�\>�#�Y)�k�n�����oY+s���o��}ܔ���d��L���裪'=OV>���}�r��J��9+G]!�M���:ˠo�j�oC�f�檭��U��*]�f|�8��jk�uS�e+"�K�O���8mZ�υ��4<�́9�o�����Sˈ���$��M���2>��5��gd�E9yѦ*�+G�[�df����4M��x�M;Q����HR�LW@WP\�S�T%����B��X�)��5I�u���X7�U�ۇ���-v��>F��f�ߗ� >�|l<�
^�l�%��\IF8��x�p$Q��E8�7!{&����U�ё&i�PG$�u5M�6m|ځiG�)_��V.�����Su���uӆ[�;�1�M��"8��n��%�w[p��F��8�ɣ��贝B��HG{{�:�ĔhLT#Lm�Ə�=9�yr�a���i�ߣ�����=���Oؙ����v��v��9�=����l��)f �L��C[g�il�����p�?�B��2�F��|�ݓ���~�GSP6��Z��x��S_���#:
\�L�(cj�_����X7C��T� (�,3�Y�&�p��x�/V����0��Q���G�Ymxg��(䛈"baΫ*s��봴
;����Zs�@+j�%cK*�5�k;W�1��`(� 'y4*�]-C���H�hn���ok�WVVF�w'�l�������5s^.Q����9��2
W
��͒�Pv�Mq\;��No�d�����EJ�^/VU��No�B�V��8���=��V��\�*�'!�p�=!��176{I|Y�d�ٙhj�p
2�I�������T��%L�dcU�p���4�?}���3�I�������A��c�[�p�`b���SF17>��v����;uc׳,dC�Ǩ$~nۅ�'�� GWn�Z��K��ܐ[t�����W6�'s��ۘ����|�r<�Wc�L��R>�9aL��n��=�[�o;�r��~��C�?�/U�8_q�C�
:?u+�s�]�����S���
�ŏ(�>��I��&�j�|Հ�B��v�-`P�pt)1G���v�7��y�*�� ���i�!��ى6Ӈ��
����"��A�6eaA!`'�pNHpvDm�i �X��DaW�6ع�"��7d&n�-Kn�%{�mT�qo۲��u����}f��o���+�>t˭�^{ނ����{����fݍ���:����
N�OĎ&�֩Tn]Dx6�J���wb���|n���%ƼV fϱsA���n�����;�<}?
��l�}�;�����N��$�9����@ �|KY/�~����_��i?����W�\N'�|�+����4�
��2�[�AF2^�?.l:���sQ���N
��H��<$}��_��T�bj��sCom]Y�7T F*��>ZBP��p�]3��b:4z���̫&���C���|\��*wq,\历���(���żFM@�2+� tlߘ�Tb̳X�.��~�����Z�sqɯy��~Sv6
'y=]u5�3p�N�99�y�eO��\��m��}�/��������L��"\c�����D�oc��xq�^���K���?��&~K�϶rz�s~J�SQ[�+��:$�i�i3����Q���'��������s�������#�(�qO҆������rs�@��lt�*Q×�Qo��gm�:ZnԏQ�027�����ݭ�P�������A�J�A`���@`(�
8+N�{s�����Xg.�9�bi�`�B~����{?(V� ��$A�cHi�!"�v�͉���x�p����g�Y�y�>�s�N�����&�('�U�i�'�Oܜ�'�pՎ����־�{�����/�fU+�Zu}Y�>�V>;�)a�c{8��)�#&� M!3�gU��Jʒ�����VI��_!�E�
ڸ!Q��<�ӕ�4ޤ�5���ƃ
i�2.��h��H��2�"�. �
΄P���'X`��i���N��H�iL"�/�oȕ����,�1/��ʕ���ӻ��b4e}K2�R�ژ��0���56��nLX#�&�l�D�����nh=�*�Z�Z_+m�C�V�>�����M�"��+�B�|;I �s��]�ҀM/�]�?�<7ʔ�yH��Hii�t@RI�v���"�2%8��{=s}���D�X����P]��܉oW��`u2G�����������Ia�FN�h����9��Ʊ@�ק~֙s��(Y��ײ��"�� ��,he�,p70���l��p���3�Y��Z�� <8p���<�e�u%{��LFC.Bͩ6���q5�u�-F��2�;>�T�E8+��y^i���M�� ��x1�U����Vi;7i���Y57]>�W��]��u�n}��ޔ)hI`/�1�o<����d��.X�{���nh��S%���T�>_�7�$Sqq��yw\��S����J���岸:�/��}��؈��GU���Cw)~�oo=5������kw�pأ�S��!'u:m��r:d8`�̕���pI�+�x��������m{llGl: �,cئ�9c�p�'���5�)�5�+�W��4̏8�΄نg}��7��*(D��C��C�7W��`�{��m$y¯����'}u�5?���S6�_�?o�n��:�f�|9�����@��)Z�w=r}��܄��b�)/z�~�6RN5rP��E˼K:�˸Z����_Yn�j�.2N�5}dR�^½���L�?9��u�t�>X ��B�&[e�l��d�\,{d��ԫu���r�J�ð=�;�Ǽ�^�ܦ78��TF�����-���z�y�B}jqV�n���'l6.���9�&��V�8�Ɲ~!�7��8��3��
2�"6
�x�c\�`�������U}m��=�/���<6�����jR���-�y����V�9|I_1������n6#��&���Ĭ���/�b�R(h��
;�h�k�϶_x��N���O��,K�{�{�����QY�X���}�}���ˁB�f���B=n���VT2���d�8I�]I��JZ؊
����Y��=�xi�yڙK�7 �.�[���>"Y��>�m�.�JX��B8� ԇۅ��s��߱�f{����,/[g{��W�=�/i�l���
�"N��a{d��t�Y���eԸ��[��ƙ���x���0+�����l�Ø�u8���2Q.4�M��f�.��ѹC�PIIx���IO$�o�vo��ۖr�b�5���dKb��$��dkd]��V �Ș�_�ڐ����-f$>ث�˘lY�%�2[�P�Q(�Z��n���J�Zd���~�,y��N�Ua��yu�]�{�,�'d�����?��-�5��cY��w⋨6�����8r�x~?�A��l�|g�/��9�L��e9�G�z���f�d�9��LN����8 �:
�)���o�i���z_6�PD���HH�1��|�9�#%8Li�_d;�:���#w�B�^���7k���<��40OC�y���&�Fzx�B�c�������������4�ʟf�}Kn���}��C�5ZG�OY@uX���I�;�P��'�{�
����w��
�w��H�:^�HM�������n�!��H�ߑy��Ɍ���}���D3���/T<�� \��dsK��O%E��nL�~�6�0$?�� b��e��J��ٕo)���7췼e�K���W&}�i��V�k�_U*}ݩ�GNq�I%Ʋi�X3?�/�x����+��U��|B!uz��7�{��=���hм��]�>�f����z�^o�����Eu�x�X�l����6kڪ�Z�r��0���(�yL>�����|Fj�������Q���Ȗ(�a]o�y<,{>\�,�)��&I
�(�%\�k����ykª�%�}5v�xg�_�4wF{����qT�}>�;�K����bs�D�b�ѦXK��ح�����b���K���Kc�/�Ώ^��x��+2:$[��0ΖT1Mg2���В���I�PR��5�I_�����f�i}��u��3�����.�i�|_٣���k��u
Ŵ`��mdcwr�k��i�n��.�'��q3;�e6>hqM����N��>}���_�ijڨ��)p^�yĄ�uģ���A�G����Ǘ;*���`J`?/ƞ"w�|(��[˭�SJէ%i�TI(:�$O-:e�T~U&Vz���3:>�HM�J��NNIu�A⚫��n�XN�%St7�h�)�C0*Dj8�h���TN�\]Z�6#�.�>و��|�L�r��f��Į��Y��t��n��4�2�A`b=����.ӏL;��+&��k�n4�c��W�U�r����{���F^���,[ ���Mͦ��5���OM��a�6dJ�6�
�;M"*����J)�i2�6-6-�{/$��+�W���O�'L��OL_�[�zC4h�j�m��}����/k�:��o��-qk�/���)h��5eKvY�l�.s������g����
5&�]�I���@�u?2�����d�b[�2�����gS�rG�r�N���_�[��V���Y*b�C;]!�����N(Թ��[��:a����
yU��O>���P��`�/�uzA)��B���,��~��e'�� 'w��r���3�o�?�ȶB��W
�Dg��^,}�,l9%�V}!k�B���G�Y2�%}�~���Z�K�1$( �[��+���vkqbF��"����|��lt�����M��!.�L`��@r�f �����&�a6���c~ED�:l�������a+|C6��>n��R:{<��
p���u��������v�#=%PH�EW�
���P�yVE��6�y�'B��=�j���� �� �w7���O12DfْY��7��tiǯu��8�b�M��7\�2�"��K=d)�S{~]�}(���T�;�����艶^�n�����w/��\�b�����]
endstream
endobj
46 0 obj
16824
endobj
9 0 obj
<< /Type /Font /Subtype /TrueType /BaseFont /YQVSGD+Verdana-BoldItalic /FontDescriptor
47 0 R /Encoding /MacRomanEncoding /FirstChar 33 /LastChar 116 /Widths [ 402
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 847 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 664 0 0 0 0
0 0 0 0 0 686 0 0 0 0 456 ] >>
endobj
47 0 obj
<< /Type /FontDescriptor /FontName /YQVSGD+Verdana-BoldItalic /Flags 96 /FontBBox
[-537 -303 1705 1014] /ItalicAngle -6 /Ascent 1005 /Descent -210 /CapHeight
750 /StemV 0 /XHeight 666 /MaxWidth 1777 /FontFile2 48 0 R >>
endobj
48 0 obj
<< /Length 49 0 R /Length1 4600 /Filter /FlateDecode >>
stream
x�7tձ3�Ү�ZI�cG�w��Cّ�v�ZX�C�R�)R@ �2q���IC���c�M����
���{�:-�$4�ky@?4
��ihh)�C��YIq���s��Js�|�̽3����w� F��`��t
�����ޝ�R��<��ޘݲ�HshG�l���"m6h>�ߗ�ix�z?1�4���ӿ}xW�6y���6�[��T}�����8C�tSz{_Q��C�k��C�%����go�+�c��)�.i�p��Apl`�x����i0��~q����t��~���|�_=w��>m~@����4B�!;�1�E!7�����L�K.����W���%���?���(��?�L�M�^�g��>��Q���i�Hx���3Du`Y���yf���llV<���/�+^$��'���Ա�1�z�Sz�_�<�7��K�5��;|�]��i;���.f�i�~&5���Tm�A�ǞL=�}���oT�A����a��������v������w��>�O/�M���x��J��}���}^q߈W�퉊w펊_��{ � ���w�y���ZıY�;ƞ����&&�m4*�:GG*��#�đ=k
�<��"�k2k3�L"����p��-�;W�<�++V��-:�+��:�J�eE�u�eO�u�l���*��Z��\Q���,_d�;��V�f2�-&��h�x���hM��I��Z� 7�1Av�e��W�h��#t��p�@�Z��-:�m։Фc��أ�nWH��v����A���U��k㓈�$��0{����)�:{h��)�T�c."U�)��n�E,��.U2эq%�4��V�O.M����ᡡ!�GϤ^���j�|M�#�i�59<��k*�R^�èd�HxH��W����A�w�c�!/�R�B�J
!���A���hk���6�)��K��&���^Z��3s�.�����yQ<3��Q�S�P�,��9�qwao>�����z\�x~��
���Ѕ�!�D��Э�p��6�&�������Yx����}�'U��
������� �`l�N�`ưo�Q+���N��+�&��Ј�0���!��S��̯���]�U�y��hC��0=���o�!��p��V�
�*<ʮf��98��[�[�����4�n��������Yq��j���-�UK��WV,*w�9�6�j1������A�E���@%�u���D]�^��V�j��n��\�&��
��o誋�(S:�PXx:^Q��`��t\E�J�D2rd�RʤRd�I�x�W
����C}��Z�4 5F��I�x?�#�2ɀ�\W���H���0�����4u�8ޓ�Q��R�YQ H���
��Wڪ�
�&k�s���IyM9��.��iZ�I`�#��D�g�T��h�o�q�N)G����V��?�[������xD�y�ud��c/��\�b����ܸ���T�Vu�DE]��+I���@;�t���V]�_�Lj@�e ���r��
��/�VP��Sb��L+��d�H&�Q���!%�]�{��R��.�(�J
$�$�p��Z
,��4"��T�j�^�JbD慒�z%�R�^I���L�Mj����&��i����R�Ղ,��)y�
5��8���*�;R�\�,u�R����h�, rn2�e#)��+H���\J���"�����^����x��m�y��< TRTXT�4Z��/u�莻���� -d\Ż /�j!Q�6Q�K˦�Q�:Yr��%��V�s�Tz(���x����u�>/�#�J��%�M�dt^r�<%Sr�Y�*:���P���(X����r���.F-x��b/��Ve������Dz"xm|�՚��j�6��
��R$w�
���L�:�R�����KQѣD ��`�J��4��2:����+H2gAaϒ���I�n��ލ��t���?� J�'u�C`� �=k�1�j?��W@����@_!�
݅�"����߿����ȋ6����&B��\I4�-�>8�����1�р
�g_x��4Իmn[55HZ�j��!d
12�}D���80sg�~��E7A�$��^�^lū��<�#�����&�?��_�g�,;B����ӂ��j_��}IiL�_�n��W�n�n6�!��P~������3�;>z�����~I1�Q�-J����'�Q�3h��u؍�R:�6̣�_�W�-|'�����:^2ƌ)#��Ƭ�Y���w
�qN�1�:^-���h5�fm�r�_ӡ�F�C���ͣ���!�a9�_�}Qs�;\���Y�ex;/1-L=���n~+��G�,ob:-B������^o2�P͜k�5|� �I�����yC2Q��+^^H���/x�����5&}ɏ�N�H� �n���֎��G��"��k��)������=������E�~��4w�w�e0\Wm2Z�$��8��HUL�A�U�u�����d�F�[#�q�b��C���yR��G��H��=�r�~);V�~ �X��5B���Y:f>�Bx{��ygm�6{3}
�6R�g M�6�'�^��mg�������5���Ӹ�.8�.+s��7��Y�ceٞ����K�gnL]�e_9?�*�����<�����2߱W Ww���)�~���7���mA����#��*�:�ι���
d�:+&��{�+w�OT�Xu���G��l�B�p�(L,cxN#/��潨9��60������Ͽ�����.�|�{>0T[�1q�.�/����2���E˖��Nt<��-��ᶣ=C�먦��^g��>Up0�TcG�כf��0x��p���8�(6�k�fn=���]lj��t���ˢ&Bo���4*��[������h��\��rh���8�Lɠ��mlT3E�)ڸe�W�[xRhm� ���.[~��!ig�y7k���ğ;l�}�`�`'n�Į@�kI�=Ա�ZWU����?~�Ժ�)��+�'f�^�����4�e��G��v�i:_����
4�WB\S#�K�/��
ڸ.��P�͙�M���m����m[{�T�?r
endstream
endobj
49 0 obj
3162
endobj
10 0 obj
<< /Type /Font /Subtype /TrueType /BaseFont /HIVFEY+Verdana-Italic /FontDescriptor
50 0 R /Encoding /MacRomanEncoding /FirstChar 32 /LastChar 121 /Widths [ 352
0 0 0 0 0 0 0 0 0 0 0 0 0 364 454 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 683 0
698 0 0 0 0 0 421 0 0 0 0 0 0 0 0 0 684 616 0 0 0 0 0 0 0 0 0 0 0 0 601 623
521 623 596 352 622 633 274 0 587 274 973 633 607 623 623 427 521 394 633
591 818 0 591 ] >>
endobj
50 0 obj
<< /Type /FontDescriptor /FontName /HIVFEY+Verdana-Italic /Flags 96 /FontBBox
[-417 -303 1461 1001] /ItalicAngle -6 /Ascent 1005 /Descent -210 /CapHeight
750 /StemV 0 /XHeight 663 /MaxWidth 1519 /FontFile2 51 0 R >>
endobj
51 0 obj
<< /Length 52 0 R /Length1 10168 /Filter /FlateDecode >>
stream
x�z \T�9�.3w�;0��ð88��
b�CT��
��AQ�%N��A
`P���썯M�4͘� 5��fi��&i�b����5i�����;����}���e�g��s~���㮻�g)2�^� e��R���z��ur��ށ�xYd��D��~.�|��e��qB�t-��L����wAC��K�ݵz}/����w՚%���z���0>?z��
����<�M��Y�N����wFnZ:���X��i�t:̯J��^e^9�*
����F�g�%�t4 ݶ�Qڻ�Qڳ{�4��N���ѫ�{�Ҥ]}����|���S���I� ��W=���*��m��G%�wZ}yot��*�mA)�
+ۦՕ{:�t6v�w�;�u��%%'�K�%���K,�l�|��М�5M�s�L�9�,�Iv�3%�3=Ø��fLJv�6��,Z�� ��^�50,g@�Ds��(|/O��!fT�f!%7�X3�Ae
��g�+hi�S���J+1��*�R�Ǭ����6f�p�[�{OjќX��1&4-h;��m��#�Nb�cw�$p���_�v���>'T�'qo���voF��qn[,��+��;2ڑ���֮]K��8.��;����
��]�����?���ñ���8�)���ƶ�b�����*�ibZP'��ש+@k�y{&��;4L,!ގt���4q�\��mGh�+��α�/���Lm@���߂�ϕO��W���s��zB=�EC���Ρ��Ϡ���<�:���O��t�P�݂ zfyQ[y���h-4���hڎ���>u5���bT�6�v��1: s}��Gw�]h�p/@���A˓�7�3lC�؊�����zr� >r;�����Q�,�xF��=����01�k������.t
�"���*PYQ^V�/).�M.,��{&���d��\�����LKMq$'�mV�h6
z������
p,�?U�u�\����zڕ��#~�!�9�|�x���3���y�~]�c
�z������Ű=��,�v-�4��`�
w�;�Z�Èz�(���_����z]��n����顨�<9���j�4���5Ĭ`r��\Sv��இ�C��R�=�w!�x�cj ����F�W�)1�[>^0<�礈���Nwg�¶�D=���`W3�`f8�]r��yՋZ�ȃP����ꮇQ������װj��1�7v5��z�y'3L�iupp@��?���^}���=��@T�Q}aApE-P:�WX@I�'H�^Aײ���3�BܽT]�um��.`Lǿzjp0��vvt�i��u1�Y�����rHW�>�4���jO��hM�8��z��z�A*�[��-����:gĔpL^"�М67�����hpI%�cx
.,hl�4*��ny�k�a�ȗtŗZ:�[��kD;�
�����0�89ֻ�-���㍍��`fmj�ahj�3ְ�=&��pОJ@Ü����HT�&�D
D�T�ߌ��5���jikw!�h�ʉ;$�J��8�(�����D�<^t��t�>�����X��D]F���!��~�i��DOR���8<��<�¿��6���,&ۂ]U1��?t/M��lum��P��q2���W�^(O�[^u�Do�kvV�ˢ,��\w���mrp�$Z�wJ�D���58�baz,��R7��C���64�w�O��|Ř���F�q7�5���w͝�vJ����1�I]����<@�W�7|�63�5p����>�z��6�R��P�}�P%�E���Em0���%q"�$%��}�л�TI��wP;{a�-�<�Bka�P/�mb�B��{�����$�7�hģ�P��|h�������d�����������n�y���B���o���[�u*�O��@�u៝Sk>\������d�����7�sZ�Ӯ�smg��k˻�g�σ3�)5c`Ϫ:٭4`B�9+j�4�����pNX����`ĈL.S�40�����
Zච�%��(�>�a@��d��g���%�]�]`\.��ё�+���ё\���I}����N��>`�����=J;��|I9�*{�oFR��9Y��|}:2�2�23��K��ť������*�'���
~g�bM�HFG����u�Lzz�m�{<9G
�R�-ئ*^��ch�wD�آ��y�i���0UWsg��6a� �+�������٠��� �tC
����q3+���u��/_�9��P�ۜ���������ݡʖ��u9�w�����?�4��w�\76O�fv�nqJ�C�kk߉���O�$U[��
�9w�^�T��U �z,�
���%��5�ڦ��҃�!��Y���[�����-���D;�P�N��0�
zCv�P��/����=���ɮҟ�6��CQ�:̏Ӫ������!�`�B�@;I�#�*0���4����z��.ki������1�|�7���c��UY�u��Ǯ=�ll��7r�X���6��*x�����8z�W�}N�����e ���>=�lq�b"�2v��9۹�e�&��V�X!��#�����m���
v�l���,�D=L�N�ij��*{��1�)()�e�ߛ�+l� ��ǦNQϟ���ŏ�z��j��S�����k�7�����<������{�����<�W֢����/��Nr�_�[�>��ǹا̟�6#k�F,[����v��0�'6;!�쀭6��� i%=�#�a" "�5$Jz��'8�&������6�8l�|�rV~�n=t�8GUSl��� ��Rp��nM���$��p��C��]�=��������"���:VU�^���L���=�>�����j���\|~����7뽮MۛK������Ȝ息)a���n�V9j�X5�QŁT]��#���YX'0.��(8Ҙ>��_s���I�iT�J�:b T�w���7� ]L��]&R�Ku�uq[��v3�۳��w�0�i�/��y�E���<��{o�l��S�t�Ua�I)+7������ �q�gg�hͨL�����_Y3�f� �%� �p�Һ�üVo跙��4�MBD`��̢Y6�)E梔�S4)�4s6�,���2�5Ɛ���S�R������I8 뵦��,�H P-�QcF=��O��G�F($S�-0ӌ]@@6w����/t��͛%�͎?��鷣�Q���C5�<�R�uˎ���s�sξi�������p�e�����2�;�d��tr�D5=�hJĵ�kB�ߝ��Y������\k�5hm���r�Ҳ�*ъ�U���F���;���Z�`��p��KR�.�;,��\t(Y�5f�8�o��l��M�:a��<����R������v�Z�\���]���f�|X�M�O�����*O7/��旙K��p�䢖�����T:������WUL]u���aC�����i�O�N.��_\\_�ܓ��e��-�\9��f��Z���$�R��#'*l
�V�rr�me>��$�ݓ�m�J�dڐI��
�VۏY;Ƭ�l�ۓm�M�-V��be-V��NXks-e�����c�,iδ*˩4�!�hE��� j�[����p�-k�����RT�D�vɌ_4��A�����Uל�wf����O/���>e�4�%[�f�5�4W]8
f��ƦTϫಐ{G�\��Rta�~G��檘����9���Q>*�á�y(Wt�9�2N�\5
�J�q��n�24��;����
Ш�ơ^5M�@��|��Y�yD�0t�(v�T�:A�2�_r�^�-�-;p�Y暙�j���k�MIURG�Ȗ�fy�M�}�4�2cN�%ܲ�6�S��W؆9`<�n�&� �%��_����� �����?� �Wjj�J=��G@�$hq~r��"�S��G��'�I���:�''QԚI���7��5>��O�O
�T�\��>�ݱ�y�����nA��?�~�|���@���;+˫�7��&���l��>�+�mzwtO�k={�͞��M�B��x'� ����e��A6�mn�s��g݄7k#ƈms��,��$���8�Ѩ���
v=�t�ف
��m���߬gH��2z�m�9�މ�S!��J"V���j�g�Z_��aH�AS�{ s9������>��U��pǐ3���c�B�����o^���@%�����˺7z���ܷ=��V!��;����e�T�����*���i�YۀGۜ���l@T���Ζf�غm,Ū���1����Ϩh5MF!�uٛ˰*E��L�*�D����}<��jϚ 8�!����S?�oh���W����|�R���g���jHZ��g.����Y˛g��k��VU��|.ŊnP�R���}��5h R���I:� 謔���j�ر-���ʄ��*��`�۪�S6���f�Y�.A�m��.�fS�%�F-�8��iݤ`���Z�8=v:��TKqA>sD'�T_��
� 4����-c�z��h��!$q%iII%e�:��������S�'2x1�7��J!�8����e3��5�h�(C��Eɦ��T,�K�R�NG���'�W����HSj�D���G���H��M��ªY�s��,:�Mg]���L?��M����|]R]�ocp��s��[]���S~���I:qZ�w�U[���%�zf�~�yU�����kiY�*$�][�_�+P^W�3l,p�һ���I��M�=PP�f�c�3۸{!w{���`M�X�m���m�l�LHe8S,��H�;�R��� }3�j�,U�B��0$,�2d]�F9Ձ�]�3�H:N'�)Gӝf�Q8b���^���S��~?�X����4A6����5pR��>a� �7.������-+�e�N���ѮsWF���fE�����Ѽ��3�N�>`�n�)�L"mG��3T�7�5~$;=�,1k%m�v3C�M�Fm�B9�A6&%%�(�������M�~��n4ڍ+�$�`��(
P�I��lV#R! �j�5P\j��@Ed4�����Om��n?����n���)ܵ4H�P��(�D�&@�������}p� �����a6��1p��vg)���-y�����L-��1Pǯ`�X�\6����J D�:�W7�Y�LfS�Dj�Y�"n��@��i>=��iT� ��>u�L��h�D�:ia��&���1l�h��X$��i�p~���x�<������3azR����PA�s),�,0O���
<�2H�z�<�A2��GH���h(�,��F0*�`�*���Q���b̪Á}\�+k��B�)�S��1y_>
endobj
53 0 obj
<< /Type /FontDescriptor /FontName /IUKZDU+Verdana-Bold /Flags 32 /FontBBox
[-544 -303 1707 1014] /ItalicAngle 0 /Ascent 1005 /Descent -210 /CapHeight
753 /StemV 0 /XHeight 565 /MaxWidth 1777 /FontFile2 54 0 R >>
endobj
54 0 obj
<< /Length 55 0 R /Length1 11156 /Filter /FlateDecode >>
stream
x�z xTE�pUݽ���%�t��Nw�N�$M6@r�&a
&��$���D��aQA�qǑA�{�� ���fƇ���2.3�::�8#:3Bn�S�d���?�����֭�V�:����Y��P7b��py[i���.\��/���-�.^/��q�/۰(^6ބP�Ύ6�]� -鄊x����s���e����e+���P���톑��P�\߶�#�?�������˹�yCtU�H�0R��C>�C�D"HF
jB�px!���An��_�7�<�[����s٬�̋���W
�5>*�@_ F�_�W2�]<4�5>��4Ҩ=r��O��ݟ}jq*�o����=��_��e�O��?p��c�����}Ͻ����v��������$����}2�wC^9�@w���]{��{��w���L'��G/��O�OO2����F�`�?��A�{�������<��_���_N��)x+�9�T���#w�HőH,�������1��st�#/�B�D�OC据1�p���q��eq��<ܷ�>E�����p��w�I,?�y�츭��{[�}[WȽ�����֞Z��=���q�fE�C}����X� ��z�*s�o`��]N�-]u�nx�3n�{FW�+���f��a�u�ם��u���mM�u��s��sf�ɟaN��<^s���JI5:���vG�1�j3�e��`4$�����a9�� ���D�y�0�1�
4u!��URW@�y�F�k��6��L��Fe�{F��Q}ce̊�9�2
���!V��I3�4�c��jcd;��1�n �H�j��<��h�.(Ҏ���]�\�s--��X{���X4�%VD3w���\�^��f~�����
����5�����/>��H�_5y��1`8tt8���
���Ձ5�].?��`;�6���v�G�+�
��hy�#-�p4��K��?.���{��
�%9�~��o�[q7n���r�/�
^�[ ��� ��C�s��I1�a�E��S��H�/��wݯ��8�
Ѱ�v@���7�:�TlB��~}� jF�8
g�r|
�
FO����~t��/>E_c��u��E�d2i�~N\�o#S�E֏��$��̳���ѳ���~���'G�
h
z��
s��e��,9��2�����xl��� 8&?/���������{=��Wr�3�a�Y,��d4�u�(����p� |�$\^��%������!��C �������S~TN�Q9�ryZ�b�|U�t�~4���ư-��,�:f���}��fI,��=�7�}�'6���(��z]���C����uz��!}��x�D�eȤ�q�����X���z/�);"��U�ҡ��CHݝW6!x-� A7-�c|UL���,�)m1��ӟ7ػs@F"C���mns�i��#&���J03ܑNO��y��5��NO/�i���jx�'�Z�j���ֶ��%�oN�x����8�xh��w�'����+[��OKK�3?�ӫ���������ig0?�����=��²���Y��ӻ�C�u��ֵ������[��iok����U1�Q{��V�O
���e�j���ZK��pM�oh���_[5� ���5����m�P8kcJ$�Y艡�f�\F��2Ի���1����g��V�ː}��oQG|翤�P�6R�g��"�8�7)��;����m�^��Ⱦ�����hMf���P��Wl�Ζ������&54W��XG�8c��������a9��<����멊��� ���!RF�-���⨃.&�����K�sǀ��c�3��eZ�z
)��#B[G[�M��{�����i�$��������t��a����o�Y���9�bhN��>!��|v���/&b\�kB�G���ԛ嫟�����R>V��u��l�0=���~�>�_��g�6��lol~�`R�li�
�9 �nz�=������;�zr�zЍ\�K��w�S�i���S���>�sO�����w������l��c�A��l�f�f�
����<��Ӟ}�z��Aw�ַ���{�gA�#��6��ZQ2W���_�F�3q��g��A({�
�E�0�k��D���`����0Q.�5$��
�K`���H&8�U�� ��t��c
�8�n�6t�L�7���Ꮴ����f�@
�e��`4�`2�L&���d�،�]f�iI0���hNJ*e0�\�r
y
�� ;o����aT���?Å۸1�m���x_zf�ؒP�#{�+�xl�/������+�lҧ|�����å�7���:Z��ƺ��:zs���X�?���o��_��>X��H Oy(=x0U##���'<���J�(2~��(�A$�M��r<�j2K�8r�����>��6xϥX�o1z��x>^��0�)��k9� _���6:ۍ�I���K38���c������$�9i�á` �*���'a/f}�3���m�xTh�Q���֩h�R`��(����5fX��Z&[f[���u�����Y�r��HJES��f:�S�x[�;;ݲ<:���%��DQzV56+.3�;�����s���9��㼎��ٕh��q ��K'�b����R�yX��LX�ruWl�ƙm�q���z&c�0�3w�9g ���]�{��>ѴhŔ��=����R�5�㚀TA|�G��JO$I'|TH:���q|)_&�����QX�/n�W
�|�0{�:�C: �`o�e8LC>Q�
S��-"�BD0���0b����k9��9jU�ڍ��
?7�,i\�&qg�摇���`W�J�R;�(��t�'B/�~2��ox�
0O����@�a���XA��ntT�v���<���}F'w>�r���P�&�_O�
��F]$*49]b���� ��6�m��mQ��+Wy������xyQ�=�]}�L�8¨���Ǚ&`����O|�F)��r�}G�.�K/���d)Wb$ֻ�c�L�(V3����삽�����O���O���d�R���(t��@�PQ��_�v�ԟ���^��{T��dbQ��kjo))����hk]�V�'�>5��ۡ�Au�������'�M(;�엛o=1~|Y9�ˇ?�q_��8y�w+&���
�&�J!J�Ged�N���s��:��P��NZk�!q}���M�,�6��A��؛�z�!*0����X=�MɖM�dm�H0B�Tr|J����<�?W�p�FD6`���,5�VKS�:KG�F˚ڟ���S�6؆� p,!���Cy�/��E,�=����Mn��C<���!w=���[��+�5��D��C�؋�KrZՋ���e��nj���?ǿ�@=u�`J().�l��\W���u,��Ǯi3&���_�l@1�:W�i�<%�w��9�����b��D��.� [���L�!�NQ����z5�v�A.���8�Qc>6��6�iAeJ�E`{��f-e1���r��X,VŊ�.$�.<��ژZY��B0��fI0�f>�Lo�1�8�����{�o&.�K�=���̱K��=�� sf����h��G����|�0��hftD"���Eb&���E\%��E�(�Q�Qb�l3O8��7�[{C�,�M���
o"|:Jg*Q%��fx�J�R��((j��Y̳C�
Cὸwrg5K���9{���1v��h�2���\mJגr��|]ʺ�U9�|#���pd)FsiV��p@6v8
ܸ�'�lQ�����$;[�I:Q���o���w�P"j[�L�+�m�V��Kd�PۗWRnp&*�%+rSgg��~���;�q���j9��-����^��o7Y�.���lּ^��g���>P��\a�fs�s��XX}���D��e�v�
�I�ּ���u%�}&YB��C�lA'�|��G<��� ē�����g �%'�J���EJ�D�����V��a�9�?W����kів¬I���$W�W���,������}�S�^1�� U3Pg%�<�튯����'����"N��$U���s�o�2=��60�65nL�P�P!SEQ cYN�o�+��Ou�*�����!#����3�`��Drp��D6��:
�4�k�K��� �,�Jj�Q����D�e_��d1a���oZ[,�7���/6���9�����T/���u����M���������\Y���I(Ht����G�v[�]=�
��~�"��d���Wʌ'V�x��s�I�i�8��Fzг�-� /,!�|�)�Q���B�@e���ӴH�Md�R�^z�Y�T���qK5u���۽{�ͅׯ�r
��
�8�~V��w1�dɦ��ݝpRJ]b������Wf�I@"tUd*7UWe�"�rstM�%�uR�I\C6HkLkl6�הC����8K\(�9Qd���A'ӂi8��O����a]��*at?y5FӰ�Ց���zd/]zI<����'fo|w���z7���m�=��h�V��ggCP�}a.�#
�Q��^jZ�j�z�����4�k�'��;���QD��dw2͢��c�o\a$F�p�k�xP���*p
�I*���V���{"��圚��;��������fl.�B�҅Kw2+.�_}UO�r[��+�������i�i��BaG8�ı4�I�hX�������~��i.����L��Ir�����c��N�s^�� �(l��P/��zq����u"�
bH�t�ߔ��oZg��䎵�ʫ��
��Ey�P�q�BӜ%4bb��}&�mjMa�x���H���gH~�6��tdқ�3~�&���$E�5�P�r�MV�U3f�G=��˘�RD����ך�F#�@t�@�ѩ=�&v�C�2��Y�^R��$�ލ�R>J��TH�p�����r�o���#�ϓ���ɷ�$�l��͢[$b���Kb������d`�]�y��%घ���J?K�Z��HLa��tAA�^��1j$"���NKQ\$��Bc�1�Bp�P`%;��/$�~נ��_.���=�A�}�^���.��_���/��eP��@��g��@II9������ o�^�F�Y�bO�vv��u�q�%fޝ,[݄5Iw�d�ٔ���K�=�b�1�!"�rsPnA��h.7�`S���5��K����f1R���=.���~E#{A�'&$�V�g������+X�ʂ�ϩ��K]U�l&��9Rذ�����αo�mX���ޙ�R8k�Ñ����~����/\o���@Ҙ����L��ԋ�* ���s��@��_�#`5Bd�h�PJ�ut�]��s��s��{B��`<^���|~��u�ؙ�,8im)/l!� �_�pz��'��C�6\�pkvNzJn���s��d��tW����D�ՎJ��T��=
�k��ݺA�J��Yd�9m?�лlx��%��{5��#�H>����Fc��˖���&6�\s�3�u%.�2o|��nS�ߐMM������P��`˼�~��]`˼l�)ʼ�.�8�1l� J�ҭ�V1{7�%6lz��֑=��b(@HxD�\Ʉ̻��E�S�US���� �Am�!�]xhQ��0�|�"6�
�fE.
�:'��
�
��>ܸ?(^8uH�[@*%g��6Lgj>��v8U(�V(
��0��foI�l�&���<��h_��n�K.�nj=`%�C��lc��~�����8��|.�q3��S42�p�Կ�P�uM��l�̥�&4f�V�����������g�\�����Kٽ�?�VY:ζ�''z�cr2,�ݜ����JUϕ��e���v9�A�K`������)y:���>�'z�(���.W"�դ@O�jNŢQ�щ+��P'],�![��}Xa8�j��b��5N�^T�A/
17��<�3w��p��$1�&W��IHә-}����_PW�o��r�ZB����{X9:>��b�c]f�6B���If�ݜk�_\ R#t
�
�}��b���+��NR��b������m֩5c�cq�MS��}��?�f�ʌ��t/C�t>��<��S�J��lq�9$�-���/�t��:l�T��C�ع�,�2��.��t�H��$�ҥ�V6l��X�l����s�L<���K�����k��zPS��7�LD�L�㽐�WlT��&�I1EL<�P���>�K@����Ɛ�08�z���_xL}D���G�&�I6~�+�=�.�x?�vH�.��=�ӛ�d�=X��W�A�g��%u�80|TɄL
gՏ���pS%L�Z�l���-�H��Mz���˃|)B���<'B �N��|y߯��j��"�(�z�b*
$q"`J@��
P��n�A��}�h=�yD8*��zF���
pe�R�F1fn
��@���d��3�B����\��.B��4��@}T�+�8>��rX^���aX�'<�Z�����C�����"o��#,=��_v5�.�uJ#�.1 �kD6S,o��?����?%q{��)�L!U�R�!l$kA`�S6��G+�2��ѣ���@���Z���� �S��J8��z�iHǎ����C/1�������Z,|<���_�
��Z��O\�P���x��dz֑��T��P *Ee�U�4 MF���p���'�3�LԀf����ѵ�V+�}�Eam�\<�YT�T�Z��ݱ��������ڡ���h
endstream
endobj
55 0 obj
8229
endobj
14 0 obj
<< /Type /Font /Subtype /TrueType /BaseFont /QKNJYR+CourierNewPS-ItalicMT
/FontDescriptor 56 0 R /Encoding /MacRomanEncoding /FirstChar 32 /LastChar
122 /Widths [ 600 0 0 0 0 0 0 0 0 0 0 0 0 600 600 600 0 0 600 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 600 0
600 0 0 0 600 600 600 600 600 600 600 600 600 0 0 600 600 600 600 600 0 600
600 600 600 0 600 600 600 600 ] >>
endobj
56 0 obj
<< /Type /FontDescriptor /FontName /QKNJYR+CourierNewPS-ItalicMT /Flags 96
/FontBBox [-124 -274 800 1000] /ItalicAngle -6 /Ascent 833 /Descent -300 /CapHeight
625 /StemV 0 /XHeight 438 /MaxWidth 600 /FontFile2 57 0 R >>
endobj
57 0 obj
<< /Length 58 0 R /Length1 19564 /Filter /FlateDecode >>
stream
x�| |Tս�9��ٷ;��̞�2�}��@�!aIИ�
*P���ƅh���Ck�� Th+.UKm�Z�-y�GM������{�LҾ�����?3g?���߹�v��K��l"<��X�M��4�_-�im ]V���GK��Y�.�'Du����-M�]H*>^�d��t��GZ��2�D��l��[�eKo�~�L��0ʓW,�%�|� ʁ�X���k�v�\�V.�f��սzI�?m��nL�]S�}�H
�%
������po
�e֮ d���坦����|�-�^d�#��v����k��5rր�/?N��n�Y�����5�}|}��e>~1�� �EH �Ą���0�@��R��"lE��&~i��X.
�K�L����;�
}������WK�?.��
�9Zr4q���g�GG}G�G�Ǝ6���Z-��G��V��rt���G[�.W�.����aW��Hi R��K �a�n�����A�E�\��o%��k%�B�h�&�{�FH�^[��� .����&a��[!(H��lB�жQ.F:� �nو�bVJ `-���HTrK-r��+S����w#��
?)�v��h{��ۿ���O�h���-���%���p�?�?�PB)�P���Ӊ-����eFn� ������N�c�{$�"ñE�7~����"C�"ÜE�ً�E�z��g�|�a�<ôy��y���U���E���i;��@~.���L�Cr�m}���5}��^E��]�Odz�ZM�}�������^�Ɵ�"�珱�>~: �ʟ��Vj*5�z_�X�^��T��}V�{��7����-V��z�T���ވ�7���-jQmT��Z�Z�TjNMԶ�Ԡc�`S�,Q
,�ȱ<"Ą�j�L'I+��5ϩ���ËH��@�ܜ��Κ�T��h��L�[�\�q��Ujvr|�9�i��m���������m��X�欤eJ�~�U���X������M��Z�ds���_D]reW}���u!�\s˺C�Ϲ�6~�K�_�*R����?S埪�OR�+U�RՅ���^��^��^ʮ�M�z�ꝩꝪꝤ�T�^|�˛��<�-���=Y�2)o{s����U�W7��~?�I{�~��45̖���ۛ��r?nn�_k��V��~�\�tq?�C}�~d �O���~^����aI��W����S����l��D�>vBZ�>-v"?�O�aͣ}T�$(� ����7}���Oο�sabK�.*�S�a9����=jR�>�t��'�PdHL~"���?Et���6\�ԅ�Hm�+&���>�D�
���ĠkC������zT2ME�]ƚ��FFT�2M�
�Y��&�f���$:2����)$fR�g��t�/<�'���[��|'���wS牒LR���w����[����Vj�^���D~I~E�h�u��';�1�����ȝ�]$@*@�#����$��
I�&��M�.� �N����S��?@<��lr/�K�%��t<��u�e�*�O������T���i���&r'Fq
r�0�Q-�Q�"W
l����/ Aa�0GX*�Ya���OS��v���\��7�{�6��PuӉ�n:̭��Jz�V��k"d)�O�.y��#zO)�W���� ��)�d��TS����b~Ú��*2�\��-#ג��{�yr��1�ߟh.�h�N���t
�1G9������p��;�]�#O�R�S�q� k��E��5��K�$���&F�)�
�o�����������s�^�+���L�:��C���W��A2[@n¸n'������ט�`
ϑ�W��c�C:H��ŸN|�p=�^��ܟ�����O�/�'1s�ȇ�ũ�R/�?㼜,�.'7�w��<@"O`�ߖ��G�9�+9+�@�T��O�-��<��^Co����t7}�������8%'r6.��n9w-���߹�Q~"? 3}���
��&uB��^xL�����(��r��C�����#�#Oa���:b!^�`PX�5�@�L/��>�q�F��b5N���3�m�����Vbߦ�et�D�[�}�n�Ob�_�{�Az��KM?����
F��B\���*���d��k�w7�k�p�@T���
����vr���ܯ�����=��_���|�/���r����o��m�.��������~�o��ba��]�i@O��'�6�k�SJQ�
�þ�҄'Cة�
�7qQ�0V;DK�I'o�B���m��q
��z#V�㜙�q���t�#(6&|@����U@�x�%u�Ň��c�s@���"�σ�&2�� ��3��a@Ⴈ�E
O���Cv�3 ��%<����&�7Q�I'�-��oD�!w�[��Ś����^��q�4��hO��������z~������r��=��3Sw�J��?V���\�0�-�=r+�:š�!�̘D���H[��::Dx�
����"�?�����p�?|�>��nXM���ptFj=�V1�W�ja��v2��&�v0�4f����rr��&��ˀfP�(+�K�^���k䩁���H�9n���i3�K/L%�w~7t�Jz-M=#<�?��7r-�i��Wq?#y����𛊔��"/Q?ֵ��r� �Rw������
��La�}PY�_QE.SN! zN�P�[iF{ۼ+�Ι=�%1sjS��I5'�Ǐ���(/+-).*�E��r#9�P0��y����n���SBϥ����=���TԐ���@C8�|�>��g�!�@}�=���3伐+(��"��ZVHҮ@C��e=
]�E�t�N;%�JzRK�
����@R�/빶��I���}��?5H<
��ֶp0Y�n_P���Fzf��wK��[�
����j�1�2�����t�M���Y�y��rR6��8Z�H��x-Oz�Ǫ��NqUr1�ayR3��G��걔4����@�W����525ʈ�a�8�,I�擱X2ep�����'�媢����b ������ %X�`���}Y�BrӬ�t9@f���-��Z���粖M�-c�w��{�H�Iu���$:�
�&$��h^�no�n�5�-��ӕ���o���lA�nh���)m|�@9.��[�W��B�>)D�Sʐ�x@�(�54И����vm0�A������iv��\�,3��Xf��a''~�����{��V��u~O��[mb8��Ȓʈ���aLyR�T��?(�{*"���v6+(���I1�>����.J<��w����SR'�1:#I�"I��G�I�1J�F}>=���2b'iz�[ں��b6���&��`�託o�;����=�k�%1��^��a�#�)��;�T�6��0��s����C
��@�'�3>+lH�ܬ��uE����prN������]����g}g�(V>��4��b��d������W�ܶ����X�*�.��g�q�dk#f���ס;�VGN����$[@���S,��l��]^s$��e�Y5�?=
��ǥ���5�G��4��=]=R��b�g?UOw�[�d�ܗ�l���ZF'�0r�nO��3k�D�3�m?IJ�=�m}�*�tյ��rJ�A@J��a��.�Dـ�A�*���"����G^C�"�E�����#ܣA��I�>�!�!�w����a�h��V{釃��X��?��ߨ�X
��z��@#t�>k����h
+(�����N-�|vI�bkSK��\.�S송���G}��0�j�����E�)��,�١�C3�s3�a����kO���X,@�aV7�9�V���Rg���6}���IR�:EbP�S�Ƨ?P�W��X,��^0v;'2����
����rfVS�T5q�
:,��w�?��Ӝ��
�]~��Ŷ��Z9�����S�枑��l��3[�Z����
�^�Qr���uX��%7��~��
�#���\9��04���uR�}��S+4�I�
��ɷ�u:�hzР5��I�}@2j�k>j4V�n����b51�0�yv��q�L�2V�I�����ev2���r��|�ȧo{m��� ��~�I
}�l���Tf�͏�S��0����{�5�&��uZ��i�Z�^ԑ|kX��Y�T031_�t:Q�<�����$�]g�4t:���$-��"��I���b5�䟧ҡ��P÷
�&��<��v�F��ȫ#�rv��2�V���v����:r0uL��7����vJ�VmSqw�Ω�
�U��2����1ʛى��g*,�)����5U���)�����q*}Q����㴈���v�͒�?����"�}�h����ځ�a�o˯����I�g
��:�뜥��Z�d �:轒���"���~U�-���t91$r��H:Km"�Y�"��ܶߦ��S�)�K���R��T��E�=!'"����Ϭ<(aGl���h�9����gϞ��c������H���sC[�1#H�+FF�K%�k�55
FI��z`f����3��R��Ud�}e.��V�<2@�Z���"�ⴤ3��D�L4�3�f /���X�*8nM+ʝ㪫*���k>�f�9*ʫ������[=��1/_a2b�7�O[�g��7�a�m/0��5��-P�j���M��j�v��>�zg�羪���߉�W�W������<^~O�e;}�<.��B=�C�C!� i͵~5���~�&(��B�`�JLh�5�,A�^�'��$<5��wV��&��"y�6/�י�5o0O���,a�ʼn>�D,�%�%[KK����>�El����b�5�,���6m���PGLF`�Z���xS__�ē�b�q��8ը0��H%[~�uN��n�FO怙�uz���Z���8*�����ݮ����F��i��~�d�[�-���:�U�1���X�J�Z]_Vw�k���4�f6���o�œ7��#,<�:���X���[�~,�})V�xI�
�&Dp�fT2���g��F'j��6�2���˵�I[i����ۥ�"ۢ�F�]���Gm��5(�5��`��z�����<�����n�K�r^���44�<�e�C8`Ni�F����Z�v[X���4�Z����S/`o���F�:�>��E�<��������k�\����4Nk./��|�F��uz�ޞ��ha>�p9�)L���ğ6�N�J�F��n���.�NZ��0+���-TAu��T��d�)���)~ڱj5�Y2�����"�z�?F�A�(�)�9.Ӂ�]���;��1�!��x7��4�G�O�Þ}ڗo�
���t�D���H�4�
a�IG�~8�",9`�DS���L�_�9��co>C���������Pp�����9�F���?��;?�L���I?NӅ�ۓWm��ȉ���c��w��@���
����s�Sp��$��|D�ET�s�Id���t�t;2~V�v�JԈ:Q��c@�k������r��+�.�}���W�t�p�A�jrg���3rg�-B���>�q�w����.� �+A��Kѕ���Ji�2h���T�)42i#X�K��}��c>��S�WH�`���8���� W�IȌ��e��8·j��qY��E��ҋ�qo��i����/bS`7���6�0�:��O&\���DH����>b�b���)m�f��~�������~�C��ݱ��T w��?����N��"�|�������]���Z����z}�/��7��d5YIJΏ�_yd�U�|����6�ŭ��Q+��T�Ϥ��jw�#S\��,|4�3�j֫1%���|�o.���r���F�Z�U�G���=b1l��إ��M�9����d�O-��'zl���G��'��^j�bu�GC�q�Ha�sDt��Z��&U�"���>����iŊ�mp�g��{'F�v͌�Z(��5ĺ� ƫW���BU`�mPVn/�܊qLcr����l�UAT����PՆW2���#/���,�[Wng��T����zИE�et�0��p��an?C���m�i,��w���(���F6(J�sQ��v��3��(���h ղ�2�����!ߍEw��mTY����~<_\��,,[���rkѶ���2iQi�ޢ��o�+��@)v9��W@�R�b�e�&�N��QX�D�X����3�|����u��/�O��gt���&|]����>��
w�R;�̑�f��p55U'�WVo�>]����4q���N�%�1hD��C�eeOf��,l��f�8�
(d)�c���QrSZ!\���>s����e�>&�e�e�WS�m�/�_� �S�����`������پ2[֫�s$��$un��*&�)Mh���X�t
Fɧj2�a
7��C���J��˘G*�L<�!�L2��\�#�}(��o.
�t����/���ջ?z����-�`䮹�ni~��F��$��2x��?���+�b����ˣu������li;�qͳso�>����Цqr���'�fiV��b�8br�\$N����9b�ZS�_Ѩi�L
M�X�Y��{�����)���ª�(x
����gw�=iT�Ɗ��+�y@zi(�J��<.̓�On�J&��_���SC4LB�!�
�@Eb!���2[,�hL�I�4���%�;�eT��Ԯ�n��֦�J��&�(��$9����ҊΊ�+���?��9 �tV�� �����2�=��v1�
Ջ���Q���~=?DB����eB&�3P`�yF���c��L��!#�sW߰���w<�\���zD����k����誋��B<�o��Z��������W�n�b�&-̓f�~�fX��}?Q�>g����%2Acwn��v�� ZmL��^e�k��M�#/��S��g��l6;G��d��H�lA�7hm�|�M�҇�_� ���v���+$슄hsڼZ<�p���p�ߜ�Nӂ�a��F&��6�'�n[�6hln�x��cZg��4�c�،���F]L���ގ��ښs��e�/���d�H�:��w0�0Ug���G%(���[��?�����XL�?������~d���]�4�f:�kXsp�E���銩f�_���@iu���f��B��=3؞�E8���7�8F1H�p��`p�b���8(*D��ϭ�q��F
YY��8>���5i��F�Bt\��.L��|{�'ϰ ����=e��2���>x��|���p�Ԩ��4��,c��Ȋe������Ѣ�(�^�)�o�z
*�
qc��c�xe�a�q�kj�ԆE�F�0�4���G��������L�L�I�K���^��L�և&�7�����V���*�ZS�a2�5��$W�vN(77ֆB�`��Fn�����s����jmU���4j.gM�i��4L��بm]�PP����h2��.���
��8���@���}UĆ1^N�� c��>xFɸeTS�yoB�2���t�ѪD��>Q3I[5#��EI�h:�dBL��S��T�J��RV�Rt��N�9���:�V�[�u��[T�
DK��B�$GU��������=��:��U3`y������e0���$��W6l���'�*(ʌ�23YFhXm)v��,U �lc��1\���I��R�˒��ט��BM��U��)mue�45�g�ɰ{�hk��7�1��,����E
,"�_3dbJH_NC��,��2i=R)��.f��(Ƣ*��E
�/��~�g�3@߃$M�.�Aw��1�l#lM��R5�0�U�%�(}�r�
5WX��8}��F��������)m771$�~�01���i�Mr����G�&~��5�
�
KZl��}��q�3��&e�]3�[����Z!e,M/���ux�CX:0�Nơeu(,�i�
���瘽s<����O�罼Λ�
�"o%��]B�Ozw{�tF\$Q$��]bP̩T6*{B�T<�5������ߥ
�i��d����e
+}�")C4e�l&eh� �-�x�Ï�Y�,\L�3�LiŦ�ފ_˒��1�b�����.A跤��a�=
��3�@\"B����Wu����=�X%��lo�V(�vλ���b ��~o����6��_�x�O�l�c�˱Ya�����?�6�������>Ǟ���W��K���[��l7f?�=�yQ������Mݛ�/vY���D^kSd�+ڔ��ٖf��ݜ���H�;�׳
9��k�b�s��>�f�]�_۾r���q��T�,�ZmB�
Q�V���<���x�wL-�8�dA��G�)?%z��N8�\�S}VG�ȳG5�vXS��u56@����O �pB^yuzٍ��^�����s���>rr�M'7�x˂�����{��IMO�z�=#g�ߺ���^����w���F6?ǺEH}]���<>���iT�V�W�/��/:T�sᢛ�vń��J9K���W�WT<�{����8 xy ���wɣ���]�9�s�}��MsG�}q߄��{|�Kմ�To0�Ý���9�݂#uiA�DB8o�D�%������{}6��!�B�ڹ0��F��[�-�6uU�Fڭ�T�
I�|^�������N�J�F�V��2!Xv�W�u������ì�b�l?_�6��-������^�X�0>��ki��1#��B�R'���菅�=��)m/_A:-�n�����v��ߏ�?
a)Ω
q��m��1ӀbF�?�M�,�j�L�Z7�@��`��۰���vG ���>�
ޘ�?f�'���:�i�����^��xp��o�����l"��S��M�#_��>�1�g��=r�'#J�Y����&2����*��q���Ϭ{T�T�<3��Zf��:�b��*�49�X���V�^�Z�^i�I�X>�1��A�
D&
��Z����Rz��u�+-+
�Yn3l��gy���m��j��>�[V�?�z:�[\4;˅���@bM����q��������7+LF%^AR�jk�sl�pN$�X (���K�D��=�JdekÅ�9aѐU�KEU�"��ɱ%İ3\��-a���!�B�'�t:.xcf|V#~v�+�
�r�;���b���]GLsƤ�.4�Q�����A:�!�e`���(z���~E��՛�J\�_:���e�vxE�-|�������6�*�=���=m�F*M5�l^� Sϙ��h�w@Z��,!G��,���P�V�[
�[�tM�c�g�s��϶�%?-��r����H����/����3�GZ.�?�}�A1��aJȟ�Q�����+�`�֔)��H��TM 2X�78d��קa�_�qxXJ4$��$4��v��է�ژg�'8]�5�2��N�?SQ�(�IT�fW��*fՒr��|��t9_���^���
s�BLgK�[2e`Ә��6;�{���r���;&�N�mtL�O��E�s�̠̅*�|̐�]��d_�7����f��D���],b��nʤ�LZ�D�1���<},�0��>�Q���3�����?���ti[�Ec�*d#!��CU��|���J��U�V���ҦMO\Y?1F5�����}��R��68�"Jz('���p\w�ƺ+}�f>��0Q�"�ZU��+Wr�mYK��tU��M�F|���>��s�Ų
Z�kG��px��0���-M�r-����^�(-���lU�9�*��E@�";�x���Jx�T���Bc�pu~QX���\�q�Gr�-�>�rr��D�F�K�5EE�p`)�
�a.��p�_���!tq{Vʼ���v�#�ss�В��$�Ef�_5��Қ7�';,� ?Q���B���Y�\}F�VY0�f�yi�/��A�R�z��>n�J��c�U�M�Ml����bQg�{����=鉕��߫�Y&۫�-��"�@�~�e+M�
V�n)����s%����kP��S����B�fwH��&��V���K�Pj�2]�9W�k�
�
��3����[�
=�'���k�3�W��u+��(�*��Ŕp���v���c��PЇ3���"c�Y4�h>��s�S�a��,>�Ɔ�;���džo��(�:q�C4�����2Jx4���i<�}O�5'1���Z��
v�����I�^�1���@��j�U�`E�!����Ke*�
݁�p4Ի�=��if�gP�>�c�"g�u�4��K\9`�S�L9���/�d3s�0��#�<҂�^��A-`�!\nUl��td�����v�ݞw�^|�z�,
�,̜r�7kd��eY��'״r8��?`w�%�i��%'S)E=��Z)arcA
���mTa�u%\\{tY�Y������'��5�r�]��w�C��������Rz�Ͻ �Zo�p�NA4����epP�f�T�?��x��z�n�ڈ�E�n��r��嶹8����/����)���D��m �2a�+����HL��HّJ��t��|&މ�D�}�Z*y�p���~nb�*����uN
k�AIïr��B�8���r��[��>OK$�E��W�"�T��[!`y��(�+���q,v�a��d�ik�Os�����W�]�sLaf$�@Y3T{���-�b�}o
�+�E���2`�4hA��4�JG<�Д4'EP�F<�����H�^%��a�hz��=���GJ�Ī�q!w��|��K���Q����%,��EP�||��Q�Ƚ 꺃En �En $��"���`�[�.9X�dH�b���En�lqo^��>���v��c���]��"�L�,r�Ł�qv��݁
��q�\f�aeF.�A�2�$���X��HQ>ݏ�c��&��}H/�l���W���x�Ǐj裞+���`�|.�����#�[�.`��I��w���7Q�̎|B�ʧ\��q��3k���ᥜm�
��
��C��F�M�
u���-���X&��b�X,���b�X.V�,Z� ʜɧ
�*�>�����UVW6U�������7����ȇU<��U1�ܷ��yS���aI��ʂ�J��`���S�])$% �奉�ĔN�Վւκ�)++]+�VN�����Ry2�x�W9_|Y�$��Jjn����P�XUI�C�D(aMXn�Ɣj���k+y#��D���:ј�4Y�g��g0f�S��tm��W轰Uҧ%��(X��GA̩���R*G_�vo��W}�M/7��v���G<�����1DC��G��C���� ��q`���"+�<�3��S����FR���8���̌C�z8�'s��/27��{+�9��@�F�p��.КI�i��K�:k��������)p.����~U3"�,�
�'�y�|����j�,
L�Z1�謥.D9.-Y����2@`���A�2�`)��%2f�^���!�D�8&zZ2�9.[���%��y�����g�j���GF�*̺���G�H�@WѩJ�.��#�8��QC�8�W� ����I!��S�&�)KQZx�XR��i���?3�e6�w��p���)�h3�D;���'�}YY��}D�b��4<�3�>���ʽF-���
�}BBݭ�,@_�g�(��V�ȉG��D�%�W�B<�g����D�l\@L��{ڔ46
��xx9:ҟ͌���adz�4;�1�sQ�d� �'����p�q�:�{n�P��6�� �V;����b������ByY�dP>�(��AFd��X�?���Z)hjq�1�J�eC���kE����ON�n����q����^�4�Q
�j��M
;:NxP<�7ޭ�Z�����k��r�
>�6OZ˴u��f3���~����=�' �?4�D�G��巌�����(�G3`i����9&H��w�琹�O�y��4\I�����C��E��JX�ɬ���gǦ��q��%�g.��eNѴ��_�hF�'� �
endstream
endobj
58 0 obj
13851
endobj
12 0 obj
<< /Type /Font /Subtype /TrueType /BaseFont /LJPKLP+Verdana /FontDescriptor
59 0 R /Encoding /MacRomanEncoding /FirstChar 32 /LastChar 122 /Widths [ 352
394 459 0 0 1076 0 269 454 454 0 0 364 454 364 454 636 636 636 0 0 0 0 636
0 0 454 0 0 0 0 0 0 684 686 698 771 632 575 775 751 421 455 693 557 843 748
787 603 0 695 684 616 732 684 989 685 615 0 454 0 454 0 0 0 601 623 521 623
596 352 623 633 274 344 592 274 973 633 607 623 623 427 521 394 633 592 818
592 592 525 ] >>
endobj
59 0 obj
<< /Type /FontDescriptor /FontName /LJPKLP+Verdana /Flags 32 /FontBBox [-495 -303 1446 1001]
/ItalicAngle 0 /Ascent 1005 /Descent -210 /CapHeight 742 /StemV 0 /XHeight
561 /MaxWidth 1521 /FontFile2 60 0 R >>
endobj
60 0 obj
<< /Length 61 0 R /Length1 20456 /Filter /FlateDecode >>
stream
x�| `T���9�.s��3��$�ef2d!���@.����a$` �A�*[�"�(�K��.��j[# ���������V�V�ZQk�R�L��; h��������{��{�{��y���ٰn�Rb';�D�%�;{�x����ՒM�f[�C�mY���f[��v��U[��m�m��^ٽ���l�|Vvc�٦��ѽz�f���z�Uk�$�[���������?���s�R����ݳf��d;�?�Y�4y>mE�=?��h֑��B.#
a�MJ�\�i�'0^�?B����o���A24����Z;�O<�����~�~����
�-͖�E��h�6h��WJuGɜ�cF�������Ɓz�8�}�?���`GpJ�éi��Z��˚[��5s��<8�͜�*Ϛ�g���Sg�S�����rލUruM�<�f�<�&"O�ɒ'�̒'�m�]SQ*��u�e�rE���"[~����˥#�<��Pyd�����Q|~h8��C�y��k�[<(�8k�GT�5���N�{V�lf�o��.f�H�4�Ȩ4nMuKjF�5;SB��];]7��������[r㎝;v�i��}���vW��J�:f��핮�4|��Ak�t��n���Ŕ,v/fF�w:�k-�y�"_��UɅ�y��/�|�r$F�;�"3�1J�������D��L�K���=�!�4���5k��n�껥iVkߎ��#�i��}�ƶ>�iv�$1�Z�a�zA|a�'���uݝ}j�v=o8y�����+Z�}���>������� �l���D��ez��٪O�X9)o�ۥW�ud�/�o$6'�m��Ir��%�ɯ����j��=bg'�zz# �"RK.%��W�5�� :
��c��]G6����(��鋯�4�d%��<�3~&�sH��}�k-�J�%w��"��5�w�����������@��7���`�1��";U���\��o���$��A����f���ȃl%�f�[挩,-���(/7�K�zv�dQ�Oʭ��E;�����{����E���ڌH���(�ݵ�>��뛲�;mO?���c�u���ϸ�D�6��H��#�q�_p(�����#ׅ*:���#n��#f�vu^��'u�^t������ɸ��d`O���Xw��Z|�K�c�>�uW�XF��u}�X_=�T���iO]ڊ0o�ٳ+�������s����>dž)�){�L�������ydp��h���PSӞ���p����G���r}[����^��qL��Z��uG���3[�v�,�8@��X[��G�
��#;���#*x=�U�`�p��h�����=�yK�k��C�Lz(Jw�|Ƞ�g�o=
���z�Q6�cRg#�<���o�\������<�~H��}�|����{��x�g�����q��7��V �>�����=t������rY���ENȷ�j9�9!-$�J��"�:���s�9���_�����CH�+����=r���������_�ny��cd>W�O���{-�79�J�?|B�'?���9��˯���{8OZ)���O&��C8w�z=���jN���n����V�$8��.�K�[��hi@Vb�r���7.Aa*.xy����I%i$V'�d�,�
���!Q2��<�O
��#�B��+�UL.�EF�RRF�I�$c�XRE.&�H5,�RC2�L"�a��W��"7�"ZGo���0��泝�E��r��Z���s�F=im��V��L��ez�Zo�m�[�9�w�t���v=��~�s��j�q]���Y�R�G����R���;=��2�7�!�o��d�d}��vhe83�9��̙H�' �B���{De2���^}NlF��x"�\l(�:�C!��'�G��H���F��kiQ4�NI�l��Y��ڕ#��r�Y��\�8{�����l�!ê�ť�����V<�V;�9UVR3z��RJ���I��3��_*'�=-�9[�"d���II���=�3�LU%u�Τ"L%r���TY{�)\����ڼ\����ձ����?a���K�7��Y�S�%�"��-c���V=M
�*ҴTkZZjp��g����hps��ngʖЦ�-�M��ܙ%R��$)4Sg.ɩ�f�Ӎt��>zf���n8��yQ!�
�N��6�̝Y�B�IN�[-)���O��{��L��dH���Θ�S�K;��ќ���ʲ�@.���iy^4G��e���҆�8��O<�(;8p������
���cm]�Z[�u�������_~�O����cgK��_�z{������ڕHM��}�Iz���aeL�.��"I����d>�2�;�t|��D���7�d�1Y��%��[
���6H
J�e]dYC�Xz�f�Y��x-�ڷ�T�y�����B�B�����X�����h�c���jQ���M
R%��=��Co��_S��8����]���i1�^���x����{ �֎m���h����\iT�����)y4O�K���SC2R��3�)RG����H=)�|~/�� ���T�mGO���❶�����9��i�}w3K���rL��������W���:>��q����?aՉ�g�u�ض�f>p-���x���DX��FV,&�
#/Hi�U�*VGp�6���s���¦�,�+i/+!�ӥ|��uMa5�wn�1͊�e{97ng�%���k�
�䂛s)ͤYYD)0�S@ ��@�""��}���~�7���?��l.�H1=2��a�\(�5�QX�S�~X����~��G8���x^�T�V��+Q��ͥcI#��s�rz��Z��I%�
�#:AjJ���:վ�B�K�e?bϨ�3�fF�|Cޫ|}��]FN%�����yǥ�g��F[���۔V�m�7�,�(Y]����Ĺ"���k Nܞ�4~�ܕ��
�a3"*N4R��T7�s���Uo��a�ۓ�3u;u�H�m$쥕��y�z��E���B�{�%�$Nv����Y�����-�n���ҵp;{/�&q-�N���D���3_��m�_2��K��~x�^�}ɬK04�y�V~��ۨP���]rJ
TsyB�����\v���a��-�0���H=�$ٹ�G���a��|�h�6�� �l�I�V_r;*��
R�P��^��*-i/)���Kk�J��Cj<��R�~�2OD�x�V&��ٗ{Q�|u���n�/}�ijO`���nR>&a�1sF�#�I�$�g�g�2�Q�ɪɮ
5)
�:gsVsvch��.�+���E�3�3e-�^)u�K=��k�{�Oo�7�7;�y��4��w�N��U��d�r.�ey0���e���Xh*�BL��n�y
Ȝ!Κt��@�_)ߕ�� �00����Sp�o{Ny�K`�c1�16������ n�xp�Ń�G��+^\p��ۯ]��Rk��5oS9V���鲷�H����=�J�I/D/~�'-�'M�ܸ��s�GDG�7��U�l����F���Z���0��F��HLsi!m�aL�K�Z�*�Vq��Tq���}j�1�a(�T�F|�o�s}�9��sN%�A����d#",��s���u��YH�J �'�(7
��ꤊPެ�#�$�f��F��_�X��:h��㌘=h�IX�l�̟��Y��[5�w��K�U�K�Su���¤r��%�jp e5�=Vɪ[U�nU(0���]R��U�{��n�u��v�*1�R���(K�m�E鲹�i��K��G��5UU�@�i�.w��رc��AH{$*E$�.�Re�7Ƿ��4˦��Ĺ�Y��D�rr`3{%��!V�
O?:SF�W�����6�ߛ�z=E��<-�㊚�m�*פ�r��{��Y3l\@]a!�G?12��]y\k�^.ݖ\?*��ΐ��ځI�W��h �!�dm��¨`�E>���s0 ��M�a��T��������@�M\�0�j�eU���BG⥦�D�bꍷ����>UUř`�¨�r����ôF���T���'��S?��;�ӣ��3u��U�o�q�����k�|�{yII~oe��k'���߫[N�Ys��Ic��iy�]W~�X=��ʩ��Ĭ���E�o�_����6cD~����V� �[H�s��U_�f�>���?ٷ@k��:�tH������K ��^VX�W�Zdm�����BE%E5Ek������i����w�8�Nq���H�7�H�0ќ�y���;�r0d�?�/�fL�2eL[���s�I|��cU��E�q��nvm�d�ڇ�릷L��X�����
SS2t.��O�9]��.n���ӛ��7��/^�rzr�D��oD������! ���M�����儨|(�7����!a�t$��THۆ�+T2`����?b�}^�N��2(���\�ؐPɩ�eH�����xh��s�%v�
/S�v�������G����5k�_�M^PY��(��o���4��U�U��r���;�#���^AT��`��#�P�R�$k�d�B�w�T�}T(�\ ��E�r�m*S�@�'��B��*��Q�n7�.��7{"~��wĤ��Mr�r�/���]����N�8����y�*�
M�hDj�q�qd�%#(���Q�P����j_�$�����`(N��^�L�-0���{�.�+���I\�/C�~�Y��9�a�B�ϊ�D�� �1}����q�W��`W�`�f����4���P*���Ijn�YA�T���_�B�����&^��BM5���r�-O�-S���?��r��!����a
�ǵ+��XjDu�T��R)����m��')l~[�`�5!' L9�ć�9��Ú{������\�#@L?GM��z�I6��'o����s�П������?Yk�V"h`�2�d���%=%�������C��Ě,�9/s[���`b&�Hu�Rui�gX!��opF<�I�������{���G}��6rsͥ������W=���~ԙ]�_�a���.��9x�����4z����R�1�@�Oջ�=��u��Z�l����U�J��5�F��v)]j[G�hn����Bσ0��~�ـ�R�%��ju9���D���^颚$�&/D�ߊװT
�GKB�>��������R�i�B����>vlk`�5ޞ�q��u����eT٘��:D�ŏ��٭w%,���!�E��_�n)d�a&�� ��w
Sg��e���"�'��:<�0�k������i`�q��r���>)��Ov�h,�k�c�X�Һ�uHk�k/R)�J��֢ϵηI]�i#���$]e����WcY�tX�V�#�e����ڠQG��|$[�`�z�;l&aDxN��)A�ӄ #�����t9C�N�}a3DD� �YL����q-��!cY帀i0+���ܓ:$"K�ՄC��J����<�%��6D٭#��`�qA&"�F�O�'oJ,=J�H�)�4p���l��4>�7`�Әa�-!K���2��iYk�lR��25D�j�Z��V/�j/�Qmv*�l>mQ�[�ɚJtFX�w!6q�t�)��C�dج�iԙ��qh����p� 6Ƅ�����L�GX
\*Т<� ��]'�m�S�@�����ɫ.@�I\��8���)⺵��<83Y3?�� Gi���R~�'�
�����7����HE~�F�Ldp��M%�j�=�;��Sf[�Z��E)�S�~�+J��Ő6�[�,���"�5
�}M��ꛦ�;�� �r��#�G"��\TM��-5����%5.�!�8��6�Q��ה5�9ǵ�eI/'��Y,zZ�U�5W$a�i�{�Htt8ct �����PƻB���d��&��DX�ŧ���DR�t!Vh�b�+��@�-�J_>��O��,�~���,�F�ʊ�ф|K݄�/|��q��kmhi�U�Q�>�_�oA*���`���q ��QU�nD(#��Xɨ��x�$��5��,�Ŵ*����kȚO��|k�
�a]j�*�h�pG�&nK�� �ʷj���*S��T�6"�Ǐ��팑Ź����Z�@2Tmq8�a�x�]aK�%��|��4��rSK���v$R��Z->ϫx�A�2
~^�ò��d�Hdl�%��{��ݻ5�\pύ���M3�;�����16#ާ����q��C�5��d��).D�%� �g�FA�II��Y��@7s�N2�*������O��W!��|��ZAڈЈ�*��=6�"TY8U�s7�ԅ��������PK�e��2����:J�zB=�
����Fu����
\�'X g��Hny�Z��D
�Aa���`�XK��'����2� ��+��J]�=�L_9�C�w�)t��O�%3
��!���W��Y^�ų��Z�5�zn/�����|l��3�'��f�!HE9�" a�]�b�&P���������N�ZZp��:�4=������w[:[���?��b|0�{ߧ?�w�8��zܙ����_�0��
��������oXtuw��Lg����5�����H�r�*IX��ͺDP$Y��G|jX9���H�qa��T4x[�`�,���Ab����������@��syDZ������'��R"}�g�9F�gY�FF�M/�קI��+R�H�2���]/�
��7<
�BbyF/���`$�O݄�II����9,�HU�����:h*F�4� N�� a��}i�����_�q9<�V,8��!`�2�~��_]{���3�G�n]y�-����l�=�1m�ԆY��@�6�m��U'M�T��������zcY=m����:O�Ku>pS����kdI�aYV��"���ng*�7Jk�Z��k�$����L�J.G����&Ť
�EZ*m�T���3��pC�j���[�����y����3�7_�/��y��z�M%����7`���i��zi��E���d�)�f���t)MI��m#���H�8V%���Z�^f����j�Zm�>��dk��!��y�6�ź��dK��J})���zm��κ�v�݇�Z|�9����X-�K":�8�8#�n�#�j�U����J���89{������f������ʄ��c���g��q��rC�+J�"����U�n���<�_:W�T(��\��&z��8�@m� �֍t��Ye����"9j�O�'Y[�Er�2O�a�g�V���r�úܶM^oM���>͂��J�!���j��L��H���c���)����D�E��0�bE�_e�䡘�Eh*Y��t5]�V�
�"UU�!�n/�o`q�U���O����L0A���x�ѷ+�g�����~y�0NK�w�w�{�{Y;����H�F^2.-�Er���bPC6,3,�r��Pӵ|�@���iKՕ���1�$PVq���b�d�<� >fk��l���0f�͙�s�+4DB� ����� �4'��[ƍ`/|��m�Y3_�bUn^�!D�T�S0`�8G�w⧏�?y��J�@�_�6Km�e�O�|���>��ZH�Vf1���
�
S�XD�g�Z�&�Ca�(��b}x�(��d���0-�=:?������z�:(��n��,����ǽ@�>�Y��m���-z�jFۙL�}D���KPh"��n��a㹝g�gp�����_�Z:#�X�Β7C���
��n���VT�!R[�ĶXlۜ3�/-Z���ZS�ͺ�ד���ʴ��<��y>��/���e-�.�C���������b_���qL���A��)P�>,E��0g�.
P���2�B�� ��kB@�i�c�b�q�S�ƿiW�7��X��G�Ub�n,uMXr��C#>�� �t~�36���-<��������1�!�5O��٢��}���������~Ì���z�����i���X.��_�8;�|����1"�CJV�E��|*�6����Q�9������i���@EZ#m��:���h�s]��J�;S�n_�]�D�5��њ����j�� �v���� 熼�0#܈QD��4���V�H��I�h����g�-?�יu�w��n�����ݷ̸o�Kh9����%�f��ӷ�������/~]�=���w�y;�RC䄑�'���q����r��){�cF`��#u�ck��V�B���~^S�./(�q�Yj\P҈��!����;kI���*�յB�"�B�C
a�
�P��`�W��+��+��ǽ�ٻs8�&�i
n�y^�6&"p�#|^�
�5&����W䎁�'T��/�����N��8Ac����#t�-����巏5jA�s�H[�!��g�^��{\
�j��j6x�cyPHVP�,4_�o�� ����9A�(� �4Tw�N�y�����צi0�x���X�}�:WS��',�p��d����|��
ﮁ���w���7v�kl�M�9�"Qb�O�PXZt�Z�)eZᤢ�Qh�2?���RV�+=aO����l�Zs��Fր�q�D�ťR52�T0��}���L�aJH��i��O����~�U�KC�5�,&D/&f%��&�K�M�|.҄�D� �N�e�V����C�6�M��o �����V�9ZV�\,�^���9u�5���'��m?�e��DW�W���;6C��L|��ΫᏚ�f�q���g}�7�V����cފ�F�_^��v2�C˾����F
��u�d=����5�a���h��"���~��i�Rd'��K-,O��*53��]L���HU���r<'�窉r8?�ׁ!B8k��!����Mi���4��� ��ԡ 2�&F�,
t�A�� �ldS��o�Nh�M�N���kc�^By����|r��P-̴0��:dB��_^��MK_�4�����[��<�S�}�����
����Y/0� `�Ux�W��k��Z��a����U�7�CF��U�,�h���%�4¤ �b!���W�L� jJ2$��4�0�O�XYe�6<����W��x�����I�z�%{�����\�6�D����H��I#jU26<���t�fsGs*M���~��(
�a&�@���D\��صÚڃ�m��L8N�5��49�o���t����+s� �^���[8��n/�o�-����th�(Eh)��ŸQ܍q���1ֹ��8���������Z�{���1֧N��m�kgJW���ϠmB�l�Q[�~O_�%��!��B�bZ����9�l+��4(։�ub�H��*�d�{�ȱ�=���A��J1BJ$!%qd���HA���h$���hK��48U�� �h&t�BW�k��������W�@�V�����0��b�YË��g���~:�'}oC�:�7d%�p�1��
pK"_1�(�q����&���dN�r{Q\94FI��|�sY��x�B��3�A얇š]H>��(���]1-�%^/FOM�idʈ����ڼG
-�sin(+SK�T�#g)ԝ��4T<��(�Q�S����sG����X *��
*�}|_�Z NnJ�(.�T�Nb�'��؈���D;ݹ���SB"\�a�`�+����q�����������c�qyA�8'�Ġ������6AqN�-�`�Ф�Hfz3��h���u|v��m��� �_n��8�����OXnL�^HR�����E������^�{�M$C�6!,!��|���h1�F�79�r�$���/u�B*�@��Z3v���.������W��G>o�k�q����q�rw�o\��Y��54W�.�k$+�fe���'&ضg��i(�S#��驰z+�g��%pՔsA�5�s)&��]x��&}M���Rd��q�Eԓ��L�"+�
����ř #�O �[��Ώ�ޙ6l���_^8���x���J���H��k���T�=�z�4��o����v���G��h5��o|���Gx��?���߁�G]�>p�g�r��RV�/
Of��I��&}U۞i�&)�&�6{2��$�"�|2�$d����CP�cӹ'�4����r���6�cLk��6��5���KI7x~�]X��a�pQ�3L��O:�5������V>��{�μ� �;�X��7.�:3� Q��scMK��91�*�kD�%�u�x�υň���#�rqx����95�3(
��i2(vdPt��̑��(�?ͤ�5ڄ��ϙ�t
h[D�f�[!욓_E����,�Ђ@� ��\�F�Y����y?��ũٵ�,�]�K6O���k�Ϻ��������jS㌂�Q�����W�x�EdR���{Q_�#70���'[]X���?��Q��!>���cv�p����z���FDN�j � &�%�8�!VtjC����<�,A��L��N9o.Di<� �kuy�3Y�?,�xpq����r�=H+�<�6��H�gէ�������M
�~�M��a�9c�C~cr
bQEo�bf�"�,�?��k�Ţ����J`���nbé,�g, ��:d[�����d���<�g^y�u8!�|���K�k|#�.���_O���ܵ����U_�ؿ���?���Zkï�,�1V���k�����۟}qrrr��4g����mU2ft����K�р=͚�8s=a�}W�³��Iv%��$��2�a�*�HL7g�f1'�>Ks��h#Y
��4@bЪYx�Y��w���J�x�pR�-�\�-���7�[R9�-�3/n(���d�V���]��u�q�P���
Y��+�8���O�Nl��ӛ/�
�|�{�Y6�.:1��] �uI� 7C�R�0�<�<�1|65ݲ�"1ů+䤩��I�O�vV8<�2����A�����:�M�`� {j&G&7�ɑ�A~�\~����D��q��A��tt�����?�%�v]�1���7Y/\�����ϗ^x��y��~���~w0c��5�oo���Q)~u˖XQ��q�$���r/x����y�H�R�R�ȍ�:R�Re�ҁ'�8S�Т��Kc�i*����ϴd�V�Qg]��,�{������"�x��$���b�$K���HW�ւ�$�n7k0/��@�_nOȽ��$j~I�SH¹{���]���L�����ⓣDs�
���kӸ�����!eIE����r�>
endobj
62 0 obj
<< /Type /FontDescriptor /FontName /DRXUSO+CourierNewPSMT /Flags 32 /FontBBox
[-122 -680 622 1021] /ItalicAngle 0 /Ascent 833 /Descent -300 /CapHeight 586
/StemV 0 /XHeight 438 /MaxWidth 600 /FontFile2 63 0 R >>
endobj
63 0 obj
<< /Length 64 0 R /Length1 32476 /Filter /FlateDecode >>
stream
x���T��>3�m߽}�{/w�{�õǁ�( �5�j;K�w��`�Q�Fco ���1h4p��ϼݣ����ۛ>�y3���y+�;1�UD ��ų���kD���V��e#ʚug/��8_��F�j��E��/�2���>+_&G��/@E�Lk��,^��|�#B����-�{����ųYx>���/f/����6�%K�,_Q(��=���y��t*!�����b��p%�ɕDE�H�L�p�j
Q��*Bү>s�,s�Z�V����De\��rwN�
�am
:�?���
�N��JN�{]<|�E���]dRn���wr�d���ūW��g0)i���mX���,E�*�Hf!^Y�H�6^�A$��ݤa/�k�fjv�fjv��M�'TxB��a��<��o�y�>�C`�
�Z��g�Y�t=�4�7�넵�M!�0ʔ|�8���nw��_�S�44+�M�5��P��Ĩ�Ĩ�Ĩ�Ĩ�ELq�M�߄�M�ߤ�o"T�U$U�U!sg��Y�Af�^��$ո��B:E8��:�gX�0�ޢě�IȯW�YJ<^�W*�+��%�Dɷ)��B�_[���qHɛy,�.�ARx�Da��N:H��(��4a���F)驨w�~��A�H�#��h�G�|
�<%�����Yhc�,���,�L�Y��a�R3�J�W�'F��0a��q-2�6�Z�V���mZ�B3�7���
a<�,���!h�f�a��T"��T�O)�+ŸJ�R���q�[G�HÅ4�֒ �A��7����62�a)�*��We5���[�0a�J�{� hIb����ڄ�l� �S}���JZS�O��|j�V���'�0M)r��!�0�^u�B�t���W�!� /�dc2��Ÿ�X�V�}�RA K�D8���b�r1�u�.��5%�g �)��J0��S�
�>a=��E�z%nC<��Q�ϙ��h/ә�1�t�yX�}<�u���0o�q�����V�����~�����/�_�~A�����w=~����X
��̞�U��ne���{������f���fݲ�8���V��;Lb"�AL�_J����IJ�d�Ӂ�f�n�a�y�i��i3L#g�*f���ٕ1}�1mȘ�̘�3����&cJeL�,��N!&�W�j%�*q�N�5ݓt:�h�x[���'�~������k�\�/M�'M�rG�22?T��I�x�)w ��DC3r��E�,���)הiJ4Ś�&��k�ZI[�5j�Z�V��LK����~��Z≚�B"*y��<"ĄQ-#cH�M�ƞ1����;������X?�O�֣�
�=ֱd����~M������݄�S�Rz}'J=�~J&M��9^u����>u'�����|����_3u�H����8/hs�Y[-CF��Q�R�="s��},���zn{�Ԟ��=�<�t��<��1u'kd�#v��tNݩ_�;N���U#0��~$��;I�'J?��H��~A���%x��T�O践%�1bkQ�O�ҧ��>�O�3_�3��GPƯ�b�>��$��h�+c?�O0����'��7��W��,�I�з��_�1/��똇�ݳ���Us�ᝤ��͛�=B�{��<�=����7��=6"�u�r��=��1�[����n�X�7�w�<�#6{Dgߨ���Nxܵ��ۚ�����o����\wҳ�ͣ����z�?k�#��1���twJK[hn��/�� }�2�=�����ae�x��7��\hr_�����$T[bÉ���_�����_��˗���|&��+���+�G�,'�\�Ì
�sڼa�B����;We}��O��W���C��������!��G���V�!���-?�b|�篣�)q\��P�#~�p#�!
s��In_!|��,ߞ���;�<��(�I�f��G��Sry�,&7�[QWC�L"21��M"P���l$������Q!��oI)B��BV�,���2>S���A�
�YȈ_�8�i������.��-�E^��9=�},��q�$�0K[���}O��/����f���8y��Q�d�̭�m��I��!!0��\Un1��L����R�`���B;Yۓ�c��1�$O��h�
��t��5���$O�Wɻ�J����U�
���<�}67:7'��t����
�����4a������e�炸�$r�%���'�#����
L�&���c�GZ�42��cz��H�Q-��C�L����Da�Ypx�80���ng��&���dy��F��{�s*P2�AE���ӛ���Q�8���ػ� \.�Q�*�vN��#���#~��[�58��
������2�T��q ��ɍʭ�=�{��H1��@�� ����"�_��q�+���S�O̒@�Ԋ��=��A��(������5�E���)d�W�)��۲�lo��l.�H�'��������9�X�.�(�Wl;��9@� ?�j�XO�c��������]�e9H��E�x[�����mپ\mn`K���!��
4M&�����{��X�>@����AZIG�3�T�M�%t)]F/��bV���n�6��~�D�f�S��eW��l{���D8:�2�a��MxM�\��R�R'v��� ���ڗ���,�3p������s�k��d��~�3���>!jR�1v�����W���=���1Ə�g�+������#)�֎q��ȧ@d:�t!�}���'�^�}��D_��o����kLfg��`���~?���$��j�ZE7�f�p
��V�C����J�Tg�nQmR=�zA��ZRO��y�������UXD6C;�/�묙����c��&X;k�l�P���5��u�ى���7a��2a���d���i�j�M�O���@��+l3�%lo[�;�/��)�D$��0ڊ�{�,�
� [�?�;����bfʭ?S1�u��ʄ?�i� �����&v=��,уHG�����(�ֱ1��-"�3x��d�M�ui>�G'�;�*r]�B��H�-eQ��d�zuscm��l"
&6���:��Q++��N��t
)�t/y��@��<��#��F��[�S�VzX|Q|��a�d���2 �^Ј��̈��4�|��[��R���Co����ad<�',g#�-��aB
fl�I�z����U�+�i4·�d��Ou�o�r��Hv��(�!��s
��Z��)�}�3�D1�Ɗ�ܙ��E�0�F!�ò�i3���tY�@'�grۋ�V�J<_���0����Fr�=��}�[Ř�S1�3@{����Šo�J��*�F�r&�i7����d(�]�Q�j,�c&�;�,D�rp�K�e���dh�-���0�:�5�9v;��O��dz&yS�V\I<�����R˽����ԿX
��}�{;�����������+u;)!�鏢���a��֖榡C�jk��*+��J3�TIq2�E#�P0��y=n��a�Y-���d4�uZ�Z%
��Ҏ���pO��GL�N9���c�Q1����0�F�ا'̯���z��y�I=�|O�hO*��IsYi�#�yeD,�O�M���u#b�ឃJ~��ߠ�M�G"� ��^0"�C��=#/X���{DY)�jз�����J�V�Yr=��ҭ��J�su�ʈքW���Ft�xb�����0qj�_$�YV�C�����.f�.�]yL���G�<&|Nކ�
o-ݻf]�D�tg�g�Κ=cj�0���d��=����qsț��o� k:��y�5kV�{6O�zܵ��Cg'�kYbd���x�:��X�)���:��Ы�H�� �����=���5��4�5=��"�^��3��x;�k&M�Ez�|���#�[�d���y��Ė�ҭ�%?�[�̅��t|f&=ߦ��<7���3K�c�{d@��0F25�wj�ѼF�fn#�W���9�G�F���G��b�5?@@���'��.Ԩ��7r89
j=t�`�'��I�9�hڱ�c�R�++����[*��@!"0��;�V`�#��k�e2��U���a2��K�
�
����lqL�-�[�^�$o�A��G�<�o����C{��4�˷�=#6v�5��;�R��O(�
m�\��}��c��9��V�iG��0��#&�V���~�P��������|ܩ�D
8��vQ�;~�����=C3�����tB����c'�䰱���Y�?�m$�ٚ5#c�k����ϭ�K�5;!�$�,�ʯhn�Z_��u�x�t(����[c���[ez�Ӧ%|ͤ��mڻ�wv�������ӯ���_a]��6 �A��+H?E���#@x�Y�[����V�kAy
�J���"�����BX�Ї�a=�B�h�}�����2~�;�B������8!܀0xͫ�߈0� �a���f-3�!5�Ldn��Z(��S�M[���=MП��X��`��n�;����C��%����n �������_zC�$HR)�px|
�\h e��JR��jRɧ�ԃ���!�֛�o[����� ���_z���s،o��1 ����v��4��3��u5���>��_��E��?�o��Y�6Y���i��Cv���c��;ܻ��+��!�58!�
��kdL����'�$7_T2f�TX�/��6|b`Z��HԶ�?!�L�kp>.�R}k�q:�L͓l4V$KO#��c���H[�A� �X�j��VǢ�b!YW[_S
�CPbu��bO$��bu������gZZ�<o��z���!Z^�ѶdJ�[�e>F��w�3��-��Z��gW�z��qϛ��.v1��ecز��e��[�ʲ�: cO�i!�����Wj����$���w:!��Jx�C1w�R3��)�ű�5R�x�j:_ɺ�a��z֛����|
�ߝ�\����.�e�l��/x�:J���2j�P8���b]I�=.�c�X�'y^�0�Ghj��
k�p49s���`�{�
�~��,���KZ̥�4��P������0�}ĝ��P�ǃX!�@>C��X����!]�R��f�!.�Y�E�v�j�m-!C�K�\���r�$����%�."�dȵ�4��!
�ڪ����2D�����l*G qQDy��bo*��.��j�c{�a�n����/�7��H����TB��4�u�e]��a*P��d,�v؝5��*U����!�6�Z�/}٧����[.��y�ĉ�y����Hc�hTVA_��#�u�9��ӭ-�����vۢE��+�@xm@��z���f�E��v.�4i��3N?��+{:�g�j��1-1��Ȧ�:�j��r��6�8�ζ�(N@��������z��8�5n�P�tP´��`C8�q뢵Vk���2���e|LCq�%YW����"�G�3��X���e��r���1�ۢ7�)������z���c����e����ѦtL�zE>b�U�rJ*5F��c��D�o�]t��x��=�+�=a�v�4��d��e��et9�N��?���˳��cQ��}��r����?a��
�-��i���h�h�|��/�d�ޟ�v�j�*���ƅt��t�mq�e�?��|�ŵ��@J��"�=b-M��*1A��≸=��ǁ����g��}>���۬v�ͪ�j�V��j��A��H�
�NU����L$�~A���u�VK4�q���)RD����Y+��Y��.����Ȇ�%KJX����'��4^Xne�����-�:�snL'O��
��UAY�����Lѯ�gW��3�ˈ�!����F�����qɒ�˖ƨ5�A*\��D��L��m���Ŧ��o�ۇ$���x�!���<���cq�
6a=
���P��N��bvj;?w����_��i���σ(i,�I9C�9*<7�K�/s9d�t0��P�d�%h�كW��G�`�����ed��~"���cF�*j����4!�H�������<�{"�&_�.d�vW�_jcz����Q~t��F|؝�!)t�8�3��f�r:]N��b�bQ�w�WSm�>�|�c�,t�]ȍ��<8BrNjO{J���ns{�]2�u���e�~��Mu�[�\��x>zc�+/|�%�e���y�[��8����v����O��[{�Z_�'�lQ��'�&X'�D�y{��&Y'�f�i���j�T�b�im�Ħ��������O�Nk�0�nv9dU�369̷X�|���Sl)�����@���%�f���v0/�i�2��J?z��BU%��K-Bv������tk`�B���o�:�G���?���s[m.��LN�MZ.??��x����j�>i�>CF%B]�ӷ����
T�m �G�3����\�מb�����K�N=P�@j�q[Zg��u�ƴ����{q�$f�8����t��:�K��3����T=E��� Dm�6�No��ӟ�)��
H�z�G���0[�υ� ��b�o�J�G��?��pq���6���(�9%|N���[��D8鈸eb�Yd�
�ej�#*`����SN��e�ΆHA��7��:Eը��@��j
���8c9�&%�/�z��_<�Q댒�u���w}��~A��]�"|�ο��o�,_��˺��K��o��k��^�"��o8��!����"X��E�$@�j���,C��c�����Ս7��ni���Ɲ�]��l/�_q}`���kۿ\�
�n�=����c�Ȥ�fC��"T` n����'.I�z��}ᰵ��^חl��6g�����+�\!�P4jd�ñBT�n�J�W��u�|�L=Z�1�
g2]˨e�Tp��$ȍE��d��ӕc�i����]����[��n�ݸ��UW^6A��I�xcv^(���/�T�h�8��u/����:$���q:�i��zAEb��>,ˣ�xm4� F��]��.�X.�����X�dq�V���a~Å�Xm�?�����Wǵ�~\�RE�]�k�bR��
���M�-�]d��vU|�m{�}��֯L6Ui5au�c���yṑ�"�,�XZ�ݝ~����S�u�B�d��m��#��<��%q�1aH�ie+/Ii2i�K]d�WG��^�":_?�����U�-:��#uIK�p�2-��b��:�qbd<m�����M��y��(�wtAp�;�m&�UV4*E���ğ(
GD�d���fAm4LL]*�e�E�飲�$����-*3�2�F�!�b� S�LRDANjV$9Nז)��L֓�����!l�S������S��qС�N��կ=���Oշ�Un~��I�n��dM��!�Ǔ�w��{6ϛ=��ٖ�b�}��|���^���s�5{�.�=����_vܹeݕ����|#��V:Ȫ�:��@j��4S����h2�w��A&�.��H�����,�E�h�L���m.�� �pT|>0N|�$Nx@w\
6qd�f�h����P�oӺ���#:HЅ��D��k�EV�Z\�T�➫�൸%��o��� RC'�e���dH���]qu�#C�Q���(X]k�"�v֔�:8�5O����s��C�=�Vql�W���-vFw�$չ��2\��o�z��*q��'�"c��D�����)�
�h��Z�*�������8M�]�M{@��[��:�G��ҧ���J��Pw��'P:��r#`TR��Gc��Td,bjؖM�K�Z�H�?��R��Q�ޣ����\�ЦPY�(&EP����+��h����$��2zV�W#ς!�;�`���G�H]-���ֻ�zaϰ��S����'kۇ$7θ�iC�n��U\�����uι����M�k"��W����;�_��'�L���-
���`�5���}i��퓱}��ubatb��u�^�A�K��ݰ{�H��
��LI���tG%KZʒ�]��Xr{�,�6�{e }�J,�a��YDXJ�*:�u��20G.���V���p���j�"����k�� �h��K�ZV�鸊�_E�j
�y�͠�bP���22%�
��K�]����0��'����;�)��s1h���C���W��Kna:���2]���!;�� ���UMϖ�ڒ~$�G�s�w����5���dO�/��L,Ϝ_�^�6�>��,͓V�JK-K�Km�1�q���T������D[�)�a%iu��?�K�Ҿ��9��^$=�B�� |uxM��������R-X�O8�V��4�� ����pq �t'��@���کeNm,a6���6�x�,�8��r�,A,���-,{-�Y�[���-���������f�Ey���xY��ե����hP2)�C(Ġ�:�*D0/���[2�H���hB+����e4�N(
��.[cTWW�2���X�Q�u��жHuC=W/b�U+9d)Y�חIw=w��O���bZ|��f�oqӅ�>���_�v6����ro���YwΜ�v��Y}̿�a�UG��,"����2�On��SN/�SiۢG&XVg��WΙ>��V_�����P_�/B^�oҰ�L��Y#�n|2���Y��U1�+�;��=?����9� %T��sz��#40J!��.�R>>8調Wd�y�&Z�pg�'><�nb��RLm��p�9+.�~�p�k��y�i-�JGp�S��z�Q��Z�^�,����0D���X,�tj�>s���r��Ӧ>�����uel�����8����ʋ˸f�ҙd2P�|���e4i�œ�:�؉`�2�6�4�������a3��N�mֽ�ۯ�N���%��L*ce���N���4u��*��Z��
VO��%�%��y���w�L�Zv��@�PV�q�eRح���l>�)(�J}&3����97
� X@�A�G�Q*V��ԁ`
��{G��dv5ǡ#���,Sh����<@���fuِ�Dz�����Wv����Y<�~��YX�s�JK�J��������}�=b^�1�2Y�Vd)@�H ���pcC��=�"USQQ](mΫ$s�m��������cPg
O^�18Si'�P�_tI&^R��2Mu���wc�����6��a �y�����pқHf2y馹�Iѧ&�
��e����-�l}��v���v˾k0�+��Co8i�cf6�-���Il���p�ϡ.,0V���,Xl�����n*�sц��Q�o� 6�K'4�P8���*q�'�Qp
�$@����Ue�(����+��4�o�k������B� 9�xC��
��r�g�]�ʖ��������}<���>����a2{*ݖ���X�`;`��J_�B���B,WŌaS�vT�+���c�����o��j7�v�1�?>0>��"A����y?�����!�䩶AU_��n+o/v�[���ܡ�ǚ��Kj�I�.��l+�'�n� �+�r�b�U�,�_,�'��
�j
��
�
T.86��'���� f7�Xl=6Y�&�[�����$�˗^&��]l�������rju�`78�;�]��5�I��?q�E�li���.Vk��XD��'�����4f�� �C̚unW�R"�,�ne���)��.
j�ޠ�
�`��ߵ����VvA������(�]M�<� �ۓ�
c�JN�v8�-*3ؠY�� �2*����Z�gc�2��qQ3/m<���p���{��8��ns����'8����;�}�������ߏU�~"�tN�֫@�b�#d���U�V���������8bI������1������Ly��i$��ª�f�p��~��:��r�#䁆���E7�/�~��#NzG���c$��$����KM�C�ȹ��y��S������<���I�Y�v���B�ª�J^���t��[�e��&ܥ��x{H���>���j�d�T�iW!\9nb�T�u��F�l*�Xk�C��4�+��5�p7��n�#�Z{m����.��1��������u����~أ�b���r�#�l���}�G�a�pt8ǸO�L3O�N�jS��z[�c��4��ê5��Z�ڧM��m�Ȟ*jmf�H4.��%��\E c��fl��О�x�����<�-��(�l��BQ�)�.���N=����}H%8���6����6��hs�Hq����䩪?��Ѳ��˿�C�~Jj�)�
������\s�F�j"������
��VIO%G�������d���"D�(�q6p�b�o��ag�ǡ�ADwZ5��;n��n\���/e_�u/]�͵��yj�a����o���m�ɢ"�v��9��C�Б�?�2���� ��+Ӂ+1RF��ݢW�i�u��J��|��}�Zܟ�F�����ˊ�i�F��!�;��-�ϴ�ʑ)��R�r�H0a5���,w������ފ2r�S��1hP���)8-��g6es\���C̜kv*f��� |��'�ܷ�.|':uO�W�ɘ(��{�$?�������}0�z섡gf�Ʈ{�>|E�-�?�b�Y�����N�"��M:㗭s��P�8mN� �閚S}�k�j.t^�\��ַn������#��B�
=4���o�>u����g�c��];�ܙ�S-M^�Ye'����2&��r}�b�$��k-�vh��k�k�v(��ڈ�v6$f�Y�;Ҟ�������g�M�Aƕ��9}и��:jU�L��)l̓v���������O�>��aS:?��W�YF@���~bdG�m�1��z�V?_���a�M�z����kB�x��
/][ɛ>�Z�[�^4|~��ʼn��~�4_����f���f��N�:(;�\ف��alg=x�'f����d\�C�,�_(�rX�W�����E���?�?˿Կſϯ���=��m��
P��q8PP>���������-W���}�n����������;Q$����Sza�Z%�#g/�{W��nX~"��O�!��7��@+���?��������S�pXg`�����|��j���jqH��8nO����E�9X��οJH[��gJ�L&�.`I�xyT�&�
ՁTe2��%S)wҪOZ-,N�@�Y��af���v�j�r�x�,��J�z������3a)b�Z(��e�&�4���d�����]�d�uyQƒ�Y�]��i�7h�c��[���P̋������+θv�&�R�
�u`����<�K�4V̤��60|��O�{�R��
vHħ�R�)����]INu��tn�^���9��<`F�2��T〯�0:��4����$#I)ٝ|
��d
�x:�f�A1m��h(�Y�D#h4)��,``4��W�j܁����]Fix\�FAt��.����QO2bO��!��V�C�v��:�AHb��X��{�����iX���q�d[4P�D[��U(�ڲ�H����kEYZN�����C-���l�0��d�����Tds��^���ov�Qp��|*��:������#N���˜�@���ږ�����n��9]*5����]��.�)E��tp߰���|������5Ϋ]{U{�;u�R����m_eTrJ.�)�D7P X�rճzg�k$���ӝS]t��^p���R|i��:�$����)�����K�ĥ�����kqU|CI<^\���Z�3�B:f�����}��Q7�t:�*`T�a/�b̂Q��x=�n�7w����ɵQ�U�t����c�{������h��B���F'K���rН��Ap$Q[��x�8lK��I���h)!�p]�M�%W��!���:�\[_�YU�L,^둓ŵ��l. ��*YY��䞒WK�-і�fAxr�R���eN��:eo�����9���mLN��yQ�*�x
���c�p��Ɏ���S{RR���x�zի*;�Jq0��N��8��G�~�x����2.�?�H˼����Z��7�}C��w4c��e��jp�2��
�yg�w����$��7�οW�
�Ʊ=I��0@?�V1����B 08���5M3���օ�i[�R�]�GwuuF�Ή '�͘�Vc��T'���o����!�t6r���������i)� mGpz�SL�D��#�6X�k�%; ���������!&��Q}Oi�֠�1B�:I_����뼇�7/���M�x�<(T�^�#��ϋ�������R�m����1���� �:}���*>�xgePx��"TU�:�nui���2�b�آ���)6�p�3�U8�UO����z�\Hj�&q��B��U���7�o�>��l���x�v͓E[�ۼ;�/�r�q�&�̸�O����
n/�q.R�Y��+\)'ف�W��w�@��}G�<�C}Vm�0�?�f�
.;0`7 ��-���������6�W60�z�+p�n�cP��EX�"��O�v����z��U��l
�$��h���]ʁ���_�~b�i��x�܋�}��;��5gѻ��ٛ�k���\���H�N?u��Y\�+��O��I �o���q� U(�=j�;y��px�`��f^�r�EP,M\��Q��.�+���? �W�Lqr�!OZ��������3K�*y(z� ���dpG�o�j���Z�b�V���x����t��K�e8���Zd8�]��$xQ����S�� '���z
R ���A�a�ح:�s��[~\a��:��q��h��w��:���nT�Q����7��>�go�1����~�����GlU�A/��ރ\�±��4�n{D��Rd�w|�x�xh�ėŚ���9"<.1�xr�+1�x�y��ĵ#����m�Nۙ�sg��U�q���MI)k»F�$���{��~�A�6{�>�g����#��Ii}���[W$f(j�vn�
��!��#`����IjN��p�דy��uƞ�y �1�O���a��P�[�ZTE.Ss� ��*�ʾ��H��{�U�:�
B�y\�|.�����h��K4�+�`���h�$F�]���u�U��C�zK�U��麾LzU��)5��|���G����8�$�JRU�?��=�}E��'1c{�b'NW|��s�-���/��{�Ҩ�*dL�Gy��5��2����Vx����ŠZ�����Z�F�X�Iަ̈́.��OdW4�D�6����� E"NO�=F����U��W�-���"7��N;|��m��CAX�>J��C�'��'���I4
�jIJ#:?yh柇ي$�T����f�Q���)��6n|�K������b���PߋO�r���?z _�!�4@f-yIN�� �U�+��Wm6��e~�y3�w�dm|A����rR��qL܁���b��,{)�j�%Q��JE��c�S^�V�zl�\'���d{_U@�f�T�K�9D�������w`��:m�Q(�x5sKۀ�5��x)���
�CP������!��B��A��>�A�h�W5{5
�5
)��<:VAw��.Ҽ���;����5�]k�u�/.���J�40�%��l'�Ǖ�tj�V�Kp-�X����U�2�2@f1v%��R;�0�F��ȁ��ȡ����ⲹsk.6]�ZV�.����
5��6��
1-�s�S���(#�L�;,��Xˢ�ƪHX����I�����@���z N��`�q��ݫЅ�u�U�
�ͱ���'�jl컘�Ԧg����} \l;�I*C�qC!�A�n�o/�i��հz��8�p��T[ɓ���W�9��2O)��\h�Q��]S��y1;���8�ykM��C�<����3�)^꿏��ع���~��/]wݟ�t�u/��P(��I�Kg�@0v�SG���I���d����+oz���-..4���۽��L�z��|�z�L�c=����W?�٦ڮ���]�>�ƫ�@�6�Cvf���]�%U�+
�3*KK+*�) �(N��o�b��Jy�Ր�Q�_�'\��UT��UWE)�|"�JJ�܍D�Hz�.�����ʆ�$��S�j%��_�
UXJ��vV0�@�C���L�'�Nnʛ�Ql��6q�2�{����N!%�O�Q'|*O�z5�>�^�گ_�N��M�]_X�����:��;���� ���s�m��
��SY�������n�_*+G�VV��F�j�,�FE��"�>j�9x�fv�����F�@�m�I^?*���H���hiG���Z;�����,[��p.Fluq�*F�M~��ɧN6��4����2C��B�M���\��-���D|r�.��$PcZZ����k+k�k�Z������R�*�ta]%2��u����.��s�ѝ�+�N!싅͑V
�Nm7����3ʞ[�;`s�o���:��ʔ��^Җ��u��*X+�9r�r����7���}!?W��]S�]����/�7^˿x�g��b��{��A�B�JsL��A��k��nm�G�:!��m��bb1A�f�'5�
+�|W!w]ң�X�����~,O�)��(l3��<�jp'@^�rz ���k�Dl��%�
pL�B�A�Qs*��ӓ�j���KRn|L@T)�8DUj�ޅ���!�6����A~����c{|�;LO��o���ɽO�4��"~�nD�)�E�G�mUvY"c�ۋT�[�esp��n
~>i��,�*w�5����ꓭ���hH����G)�G7�VS~����6��*+miW�?����;F��h:u��v�t�VyRǼ�7��
�S����yqP�P>P�HW�
o��Ҳg��jٽ�^u�VX�Y�as5gi�� �|���%�>�� ���\H"þ]�h�R�#G�H����,��YR�,��W�KuIH v�hg������t�O���m�����g�9M�{��E���x*7C��p�N�~LH�N�h;xO؎�4��'w��&��}~���'�� Cԧ
�;�������m[}vN� �%����|Oy�9|�B~�IP�oޔ��wv�o����G�F��b�/;^�Sڄ9+;G��kG|;H���yI�U?ZV�5n��v�f@��DO��Nщ�v�E�[��_5o��jα�yl�x���B�"�<��.�#"�#:�5�t�J��)i�KIe����P ���!���ղ�
2��e�Y#������*|���>7H��907�F]\�p�%�c����8��Q:�M��]�r��q�)h *�L:�G8Z��]��y�s:?BX
�숴zD��k9�Ocǎ���9�W��G6;���dz���GL0��)��� ��[/-��y��a���Z��=�M�h��x�[�f���={�ٔ�o��s�>�M4g�� ��*�yH1B]�Dll�2�E�&�sM+�%���
P�տ�yO�~�{U��?��y�K4�ۅG�=e���"��dX ��s)���XҰhE��XV����o����"bЧ"t��!���:1k��[SJ��As`<<�Kb�S}���c(�n[��fE��O� xR�DQ�����j��(��~{�{��{{���n�.�0���!�梢H@5�2"?���?���`�Xg��C+4(��:PA[+�2�3�j��8����������!:�������~����>��>_�~��U���˭��̓z=��s��xh�QFI/F���a]C�L|��S8��ǍL@*��l�t�Ħ�0��t��_��<��l��f��s��;�����?˻
��6��b���C�:�
�Ň����/H6������O?����1�uGŁ�4�^}j}�x'2N��$n-67ve�OH�Ҹ�U(�`8�S�="xm ����Ք79-i���dh�����'$hz��d��fEhFZ�fhZ�L���#��
&,��2��d�"��d0f
V���~��n����^�v�!I�H�|���7��,л�R8
VG(f�w�ٙ��b�dx��r�u��ڙ��"����Me��N�F.�^Ë7A>|Q�vu{�O
�J�t|$�TN����?��������S�*�vGGL
(��H��Ć��s�t[aQa��p�{�c�Ǵ�坲�;��l�4$G7�����ylW+�a��8��q�p�B�ĉq�T{�.��H�������qN��l�O�Rژ ���[�ZC ���P�����4��J6�u�w~��rS���QtO�H2 ��Z�D��M�Bf�*��,K��M[Z:D�v�4*��qZ�5FZT4b�*Ś�i�xu]潰�V�M�q�5~�vQ��`c�a��wir^�=8�)D�T'B�v�&�/���g��X��R�#��`�pQ5M�Z�p95M'5ǝ2p��p��~���: ɴ1~ �R*'��B�b��f��(1n��Lŕ��P�yzt�"fZaD>x���髟�ҮkZ����w�w��J{���q�`rS�K[n�^>���{M�:��OG�J�-]h͌o���J5����:?!{�џ��
4ƚ�wve�j~a۽+i��ff
씱�;z�R��!�ƿ$���廞U�
�WVʊ}��8Λ�X$�@=�`���s!0�<)0�vI�p`��)��ju�%��xJ�_~��%*ܺ^��NF}�CJ�t�Av0��c��%*4�^�_W�e�8v�n�F=W��Q�ة�8v�0��Z�ؽ��8H���� n�kҌU�������aM�4�Us�U��vY{�9i�q}4�>�7�[W��n�uz]M(�`dH�碈�يX#Hւ\7�כ[�<�O?��>P�V�mQ�H��l^/k(�xsg�x��+���ی��
;�o`{\���2��E%����+A��)���0lĀE<4y��|�nJ��6��x�U2^�"�y��\�OQ/��A�Fn����t��*�p}�W8�_w��ɫF����!��2�*
Y����`�@���v�ği��}{�6�q�)m���w�ާS$�uz� _���z7/|γ�^u�·�]�QZ��7��1��Y~>B��Xb.�O��$疎�#������&���.yQ��m��l��%�XJ��J�$��%���B���|IE5����<��W���4Q�k�n�rZJKjc:��6^�k�^*�b2�nlL�X�{I�.��%Bx�#�X\��rY8zgud��҃G#|m�����P����s�u�J�i�u
BXcլg��d6�9����5�B>44
M鯡�-(��&�,=�>W����>�A�ۈ��1�T�U�(t:ч�����t`�Ob��O��������v�y�S!NSH"雀�}cq�OǕP�I}Q\����%����˼،Hk�����#�|v'�psi>���/6n�������N�7�_P��~L���k vIhSjA��M��6%���䜷����MNEڡ�(樣�=�*�/���%���Ƌd�8m*1��8��#��8��(�x|D�b�8$
��:*H5�a�����hً<���X[�W>�&���h�+�&��_MI8��gw�������l��U~ʦ�a�`)i-3p1�bC`:���`�+�'~ct)�}�6�وQ�#�b
W#�$2�xp<��փ��&��ݘXH��L���$��I�G�Ox0��9џ��0�Q�nwvș�$�߇�ݦDL$�̀bһ���ņAݙkll�%29�aP�,�Maʁ�ST`� 6�П W�a)7&E�ޗNg��4���LH9�d$d��p*Q�H'D��أ+$�HD��a�h��>)mL�!V�~I�����Y@��YT��'��%4n�~B���߽��!��J����H=��7��%G������1U�/����2{g����T���� ��P��
�lE�A%N1��8o��P4�(g�M^��æ3G�t,�>�=\feP��,��>M�_7!<\�ު�Eԓ:F�_�4��t��v���R�|2�3����,�B̦���G�S�z%��%�E^u{P �ŏxQܼ�x�*�l�
�]�mּBQ��:R�{��t��
^���*�PZeD"�&h����E��l@T�q�c=�n�bэp ˳WV���>{挩�R��e��/����Sn���\-�
endstream
endobj
64 0 obj
22556
endobj
65 0 obj
(MiG Layout Cheat Sheet)
endobj
66 0 obj
(Mac OS X 10.10.5 Quartz PDFContext)
endobj
67 0 obj
(Mike)
endobj
68 0 obj
()
endobj
69 0 obj
(Safari)
endobj
70 0 obj
(D:20150902100410Z00'00')
endobj
71 0 obj
()
endobj
72 0 obj
[ () ]
endobj
1 0 obj
<< /Title 65 0 R /Author 67 0 R /Subject 68 0 R /Producer 66 0 R /Creator
69 0 R /CreationDate 70 0 R /ModDate 70 0 R /Keywords 71 0 R /AAPL:Keywords
72 0 R >>
endobj
xref
0 73
0000000000 65535 f
0000195126 00000 n
0000010898 00000 n
0000094795 00000 n
0000000022 00000 n
0000010877 00000 n
0000011008 00000 n
0000013912 00000 n
0000094969 00000 n
0000121274 00000 n
0000125141 00000 n
0000133319 00000 n
0000156954 00000 n
0000171491 00000 n
0000142330 00000 n
0000011176 00000 n
0000013891 00000 n
0000032998 00000 n
0000013948 00000 n
0000032976 00000 n
0000033111 00000 n
0000103686 00000 n
0000033310 00000 n
0000033363 00000 n
0000053087 00000 n
0000033417 00000 n
0000053065 00000 n
0000053200 00000 n
0000074945 00000 n
0000053411 00000 n
0000074923 00000 n
0000075058 00000 n
0000092376 00000 n
0000075258 00000 n
0000092354 00000 n
0000092489 00000 n
0000094530 00000 n
0000092677 00000 n
0000094509 00000 n
0000094643 00000 n
0000094919 00000 n
0000095363 00000 n
0000095598 00000 n
0000103665 00000 n
0000104104 00000 n
0000104337 00000 n
0000121252 00000 n
0000121632 00000 n
0000121868 00000 n
0000125120 00000 n
0000125560 00000 n
0000125792 00000 n
0000133298 00000 n
0000133760 00000 n
0000133989 00000 n
0000142309 00000 n
0000142754 00000 n
0000142990 00000 n
0000156932 00000 n
0000157443 00000 n
0000157667 00000 n
0000171469 00000 n
0000171984 00000 n
0000172212 00000 n
0000194859 00000 n
0000194881 00000 n
0000194922 00000 n
0000194975 00000 n
0000194998 00000 n
0000195017 00000 n
0000195042 00000 n
0000195084 00000 n
0000195103 00000 n
trailer
<< /Size 73 /Root 40 0 R /Info 1 0 R /ID [ <4e122cf7caaef73a05cf505a60bbe5ee>
<4e122cf7caaef73a05cf505a60bbe5ee> ] >>
startxref
195301
%%EOF
miglayout-5.1/src/site/resources/docs/examples/000077500000000000000000000000001324101563200217015ustar00rootroot00000000000000miglayout-5.1/src/site/resources/docs/examples/Example01.html000077500000000000000000000034501324101563200243300ustar00rootroot00000000000000