├── .github └── workflows │ └── build.yml ├── .gitignore ├── .mvn ├── jvm.config └── wrapper │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── README.md ├── core ├── pom.xml └── src │ ├── main │ └── java │ │ ├── module-info.java │ │ └── net │ │ └── miginfocom │ │ └── layout │ │ ├── AC.java │ │ ├── AlignX.java │ │ ├── AlignY.java │ │ ├── AnimSpec.java │ │ ├── BoundSize.java │ │ ├── CC.java │ │ ├── ComponentWrapper.java │ │ ├── ConstraintParser.java │ │ ├── ContainerWrapper.java │ │ ├── DimConstraint.java │ │ ├── Grid.java │ │ ├── HideMode.java │ │ ├── IDEUtil.java │ │ ├── InCellGapProvider.java │ │ ├── LC.java │ │ ├── LayoutCallback.java │ │ ├── LayoutUtil.java │ │ ├── LinkHandler.java │ │ ├── PlatformDefaults.java │ │ ├── ResizeConstraint.java │ │ ├── UnitConverter.java │ │ └── UnitValue.java │ └── test │ └── java │ └── net │ └── miginfocom │ └── layout │ └── IDEUtilTest.java ├── demo ├── pom.xml └── src │ └── main │ └── java │ └── net │ └── miginfocom │ └── demo │ ├── CallbackDemo.java │ ├── HiDPISimulator.java │ ├── JavaFXCallbackDemo.java │ ├── SwingDemo.java │ ├── SwtDemo.java │ ├── SwtTest.java │ └── Test.java ├── examples ├── pom.xml └── src │ └── main │ └── java │ └── net │ └── miginfocom │ └── examples │ ├── BugTestApp.java │ ├── Example.java │ ├── Example01.java │ ├── Example02.java │ ├── ExampleGood.java │ ├── JavaOneShrink.java │ ├── MigLayoutBug.java │ ├── SwtTest.java │ └── VisualPaddingOSX.java ├── javafx ├── maven.txt ├── pom.xml └── src │ ├── main │ └── java │ │ ├── module-info.java │ │ └── org │ │ └── tbee │ │ └── javafx │ │ └── scene │ │ └── layout │ │ ├── LayoutAnimator.java │ │ ├── MigPane.java │ │ └── fxml │ │ └── MigPane.java │ └── test │ ├── java │ ├── module-info.java │ └── org │ │ └── tbee │ │ └── javafx │ │ └── scene │ │ └── layout │ │ ├── test │ │ ├── AssertNode.java │ │ ├── MigPaneInternalLayoutTest.java │ │ └── TestUtil.java │ │ └── trial │ │ ├── AnimDemo.java │ │ ├── MigPaneBaselineTrial.java │ │ ├── MigPaneHidemodeTrial.java │ │ ├── MigPanePackTrial.java │ │ ├── MigPanePosTrial.java │ │ ├── MigPaneSizeGroupTrial18.java │ │ ├── MigPaneSizeTrial.java │ │ ├── MigPaneTest11.java │ │ ├── MigPaneTest14.java │ │ ├── MigPaneTest15.java │ │ ├── MigPaneTest3.java │ │ ├── MigPaneTest5.java │ │ ├── MigPaneTest8.java │ │ ├── MigPaneTest8Controller.java │ │ ├── MigPaneTest9.java │ │ ├── MigPaneTrial1.java │ │ ├── MigPaneTrial16.java │ │ ├── MigPaneTrial17.java │ │ └── MigTestTest10.java │ └── resources │ ├── MigPaneTest8.xml │ ├── MigPaneTrial16.png │ ├── Roboto-Medium.ttf │ └── org │ └── tbee │ └── javafx │ └── scene │ └── layout │ └── test │ └── MigPaneInternalLayoutTest.css ├── mvnw ├── mvnw.cmd ├── nbm └── pom.xml ├── pom.xml ├── release.txt ├── src ├── changes │ └── changes.xml └── site │ ├── apt │ └── index.apt │ ├── resources │ └── docs │ │ ├── MiGLayout.html │ │ ├── QuickStart.odt │ │ ├── QuickStart.pdf │ │ ├── cheatsheet.html │ │ ├── cheatsheet.pdf │ │ ├── examples │ │ └── Example01.html │ │ ├── license.txt │ │ ├── quickstart.png │ │ ├── quickstart_flat.png │ │ └── whitepaper.html │ └── site.xml ├── swing ├── pom.xml └── src │ ├── main │ └── java │ │ ├── module-info.java │ │ └── net │ │ └── miginfocom │ │ └── swing │ │ ├── MigLayout.java │ │ ├── SwingComponentWrapper.java │ │ └── SwingContainerWrapper.java │ └── test │ ├── Test.iml │ └── java │ ├── module-info.java │ └── net │ └── miginfocom │ └── swing │ ├── MigLayoutCellTest.java │ ├── MigLayoutTest.java │ └── SwingScreenInfo.java └── swt ├── pom.xml └── src └── main └── java └── net └── miginfocom └── swt ├── MigLayout.java ├── SwtComponentWrapper.java └── SwtContainerWrapper.java /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: 4 | push: 5 | branches: 6 | - '*' 7 | pull_request: 8 | branches: 9 | - '*' 10 | 11 | jobs: 12 | build: 13 | name: Build 14 | strategy: 15 | fail-fast: false 16 | matrix: 17 | os: [ubuntu-latest, macos-latest, windows-latest] 18 | runs-on: ${{ matrix.os }} 19 | env: 20 | DISPLAY: ':99' 21 | 22 | steps: 23 | - name: Checkout 24 | uses: actions/checkout@v2 25 | 26 | - name: Setup Java 27 | uses: actions/setup-java@v2 28 | with: 29 | distribution: 'zulu' 30 | java-version: '11' 31 | java-package: 'jdk+fx' 32 | 33 | - name: Cache Maven 34 | uses: actions/cache@v2 35 | with: 36 | path: ~/.m2 37 | key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} 38 | restore-keys: ${{ runner.os }}-m2 39 | 40 | - name: Setup xvfb (Linux) 41 | if: runner.os == 'Linux' 42 | run: | 43 | sudo apt-get install -y xvfb libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-xinput0 libxcb-xfixes0 44 | sudo /usr/bin/Xvfb :99 -screen 0 1280x1024x24 > /dev/null 2>&1 & 45 | 46 | - name: Build 47 | run: mvn --no-transfer-progress -B --file pom.xml verify 48 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /release.properties 2 | target/ 3 | .project 4 | .classpath 5 | .settings 6 | 7 | .idea 8 | *.iml 9 | 10 | *.versionsBackup 11 | 12 | pom.xml.releaseBackup 13 | -------------------------------------------------------------------------------- /.mvn/jvm.config: -------------------------------------------------------------------------------- 1 | --add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED 2 | --add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED 3 | --add-exports jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED 4 | --add-exports jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED 5 | --add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED 6 | --add-exports jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED 7 | --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED 8 | --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED 9 | --add-opens jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED 10 | --add-opens jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikaelgrev/miglayout/0d75360e1d255cdae9dda74e2e39c3b3db17bcc3/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.6/apache-maven-3.8.6-bin.zip 18 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # miglayout 2 | Official MiG Layout for Swing, SWT and JavaFX 3 | 4 | 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. 5 | 6 | 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. 7 | 8 | For documentation see http://miglayout.com 9 | -------------------------------------------------------------------------------- /core/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | com.miglayout 6 | miglayout-parent 7 | 11.4.2 8 | 9 | miglayout-core 10 | MiGLayout Core 11 | MiGLayout - core layout logic 12 | http://www.miglayout.com/ 13 | 14 | -------------------------------------------------------------------------------- /core/src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * License (BSD): 3 | * ============== 4 | * 5 | * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without modification, 9 | * are permitted provided that the following conditions are met: 10 | * Redistributions of source code must retain the above copyright notice, this list 11 | * of conditions and the following disclaimer. 12 | * Redistributions in binary form must reproduce the above copyright notice, this 13 | * list of conditions and the following disclaimer in the documentation and/or other 14 | * materials provided with the distribution. 15 | * Neither the name of the MiG InfoCom AB nor the names of its contributors may be 16 | * used to endorse or promote products derived from this software without specific 17 | * prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 25 | * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 28 | * OF SUCH DAMAGE. 29 | * 30 | * @version 1.0 31 | * @author Mikael Grev, MiG InfoCom AB 32 | * Date: 2006-sep-08 33 | */ 34 | 35 | module com.miglayout.core { 36 | exports net.miginfocom.layout; 37 | 38 | requires java.desktop; 39 | } -------------------------------------------------------------------------------- /core/src/main/java/net/miginfocom/layout/AlignX.java: -------------------------------------------------------------------------------- 1 | package net.miginfocom.layout; 2 | 3 | public enum AlignX { 4 | LEADING("leading"), LEFT("left"), CENTER("center"), RIGHT("right"), TRAILING("trailing"); 5 | 6 | private final String code; // toString().toLowerCase() is not an alternative because of Locale issues (e.g. tr_TR) 7 | 8 | private AlignX(String code) { 9 | this.code = code; 10 | } 11 | 12 | public String code() { 13 | return code; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /core/src/main/java/net/miginfocom/layout/AlignY.java: -------------------------------------------------------------------------------- 1 | package net.miginfocom.layout; 2 | 3 | public enum AlignY { 4 | TOP("top"), CENTER("center"), BOTTOM("bottom"), BASELINE("baseline"); 5 | 6 | private final String code; // toString().toLowerCase() is not an alternative because of Locale issues (e.g. tr_TR) 7 | 8 | private AlignY(String code) { 9 | this.code = code; 10 | } 11 | 12 | public String code() { 13 | return code; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /core/src/main/java/net/miginfocom/layout/AnimSpec.java: -------------------------------------------------------------------------------- 1 | package net.miginfocom.layout; 2 | 3 | /* 4 | * License (BSD): 5 | * ============== 6 | * 7 | * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) 8 | * All rights reserved. 9 | * 10 | * Redistribution and use in source and binary forms, with or without modification, 11 | * are permitted provided that the following conditions are met: 12 | * Redistributions of source code must retain the above copyright notice, this list 13 | * of conditions and the following disclaimer. 14 | * Redistributions in binary form must reproduce the above copyright notice, this 15 | * list of conditions and the following disclaimer in the documentation and/or other 16 | * materials provided with the distribution. 17 | * Neither the name of the MiG InfoCom AB nor the names of its contributors may be 18 | * used to endorse or promote products derived from this software without specific 19 | * prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 23 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 | * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 25 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 27 | * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 30 | * OF SUCH DAMAGE. 31 | * 32 | * @version 1.0 33 | */ 34 | 35 | import java.io.Serializable; 36 | 37 | /** 38 | * @author Mikael Grev, MiG InfoCom AB 39 | * Date: 14-09-24 40 | * Time: 17:05 41 | */ 42 | public class AnimSpec implements Serializable 43 | { 44 | // public static final AnimSpec OFF = new AnimSpec(-1, 0, 0); 45 | public static final AnimSpec DEF = new AnimSpec(0, 0, 0.2f, 0.2f); 46 | 47 | private final int prio; 48 | private final int durMillis; 49 | private final float easeIn, easeOut; 50 | 51 | /** 52 | * @param prio The animation priority. When added with the general animation priority of the layout the animation will 53 | * be done if the resulting value is > 0. 54 | * @param durMillis Duration in milliseconds. <=0 means default value should be used and > 0 is the number of millis 55 | * @param easeIn 0 is linear (no ease). 1 is max ease. Always clamped between these values. 56 | * @param easeOut 0 is linear (no ease). 1 is max ease. Always clamped between these values. 57 | */ 58 | public AnimSpec(int prio, int durMillis, float easeIn, float easeOut) 59 | { 60 | this.prio = prio; 61 | this.durMillis = durMillis; 62 | this.easeIn = LayoutUtil.clamp(easeIn, 0, 1); 63 | this.easeOut = LayoutUtil.clamp(easeOut, 0, 1); 64 | } 65 | 66 | /** 67 | * @return The animation priority. When added with the general animation priority of the layout the animation will 68 | * be done if the resulting value is > 0. 69 | */ 70 | public int getPriority() 71 | { 72 | return prio; 73 | } 74 | 75 | /** 76 | * @param defMillis Default used if the millis in the spec is set to "default". 77 | * @return Duration in milliseconds. <=0 means default value should be used and > 0 is the number of millis 78 | */ 79 | public int getDurationMillis(int defMillis) 80 | { 81 | return durMillis > 0 ? durMillis : defMillis; 82 | } 83 | 84 | /** 85 | * @return Duration in milliseconds. <= 0 means default value should be used and > 0 is the number of millis 86 | */ 87 | public int getDurationMillis() 88 | { 89 | return durMillis; 90 | } 91 | 92 | /** 93 | * @return A value between 0 and 1 where 0 is no ease in and 1 is maximum ease in. 94 | */ 95 | public float getEaseIn() 96 | { 97 | return easeIn; 98 | } 99 | 100 | /** 101 | * @return A value between 0 and 1 where 0 is no ease out and 1 is maximum ease out. 102 | */ 103 | public float getEaseOut() 104 | { 105 | return easeOut; 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /core/src/main/java/net/miginfocom/layout/ContainerWrapper.java: -------------------------------------------------------------------------------- 1 | package net.miginfocom.layout; 2 | /* 3 | * License (BSD): 4 | * ============== 5 | * 6 | * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) 7 | * All rights reserved. 8 | * 9 | * Redistribution and use in source and binary forms, with or without modification, 10 | * are permitted provided that the following conditions are met: 11 | * Redistributions of source code must retain the above copyright notice, this list 12 | * of conditions and the following disclaimer. 13 | * Redistributions in binary form must reproduce the above copyright notice, this 14 | * list of conditions and the following disclaimer in the documentation and/or other 15 | * materials provided with the distribution. 16 | * Neither the name of the MiG InfoCom AB nor the names of its contributors may be 17 | * used to endorse or promote products derived from this software without specific 18 | * prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 21 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 | * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 24 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 25 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 26 | * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 29 | * OF SUCH DAMAGE. 30 | * 31 | * @version 1.0 32 | * @author Mikael Grev, MiG InfoCom AB 33 | * Date: 2006-sep-08 34 | */ 35 | 36 | /** A class that wraps a container that contains components. 37 | */ 38 | public interface ContainerWrapper extends ComponentWrapper 39 | { 40 | /** Returns the components of the container that wrapper is wrapping. 41 | * @return The components of the container that wrapper is wrapping. Never null. 42 | */ 43 | public abstract ComponentWrapper[] getComponents(); 44 | 45 | /** Returns the number of components that this parent has. 46 | * @return The number of components that this parent has. 47 | */ 48 | public abstract int getComponentCount(); 49 | 50 | /** Returns the LayoutHandler (in Swing terms) that is handling the layout of this container. 51 | * If there exist no such class the method should return the same as {@link #getComponent()}, which is the 52 | * container itself. 53 | * @return The layout handler instance. Never null. 54 | */ 55 | public abstract Object getLayout(); 56 | 57 | /** Returns if this container is using left-to-right component ordering. 58 | * @return If this container is using left-to-right component ordering. 59 | */ 60 | public abstract boolean isLeftToRight(); 61 | 62 | /** Paints a cell to indicate where it is. 63 | * @param x The x coordinate to start the drawing. 64 | * @param y The x coordinate to start the drawing. 65 | * @param width The width to draw/fill 66 | * @param height The height to draw/fill 67 | */ 68 | public abstract void paintDebugCell(int x, int y, int width, int height); 69 | } 70 | -------------------------------------------------------------------------------- /core/src/main/java/net/miginfocom/layout/HideMode.java: -------------------------------------------------------------------------------- 1 | package net.miginfocom.layout; 2 | 3 | /** 4 | * NORMAL: Bounds will be calculated as if the component was visible.
5 | * SIZE_0_RETAIN_GAPS: If hidden the size will be 0, 0 but the gaps remain.
6 | * SIZE_0_GAPS_0: If hidden the size will be 0, 0 and gaps set to zero.
7 | * DISREGARD: If hidden the component will be disregarded completely and not take up a cell in the grid.. 8 | */ 9 | public enum HideMode { 10 | NORMAL(0), SIZE_0_RETAIN_GAPS(1), SIZE_0_GAPS_0(2), DISREGARD(3); 11 | 12 | private final int code; 13 | 14 | private HideMode(int code) { 15 | this.code = code; 16 | } 17 | 18 | public int getCode() { 19 | return code; 20 | } 21 | 22 | static public HideMode of(int code) { 23 | for (HideMode hideMode : values()) { 24 | if (hideMode.code == code) { 25 | return hideMode; 26 | } 27 | } 28 | throw new IllegalArgumentException("Code does not exist " + code); 29 | } 30 | } -------------------------------------------------------------------------------- /core/src/main/java/net/miginfocom/layout/InCellGapProvider.java: -------------------------------------------------------------------------------- 1 | package net.miginfocom.layout; 2 | 3 | /* 4 | * License (BSD): 5 | * ============== 6 | * 7 | * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) 8 | * All rights reserved. 9 | * 10 | * Redistribution and use in source and binary forms, with or without modification, 11 | * are permitted provided that the following conditions are met: 12 | * Redistributions of source code must retain the above copyright notice, this list 13 | * of conditions and the following disclaimer. 14 | * Redistributions in binary form must reproduce the above copyright notice, this 15 | * list of conditions and the following disclaimer in the documentation and/or other 16 | * materials provided with the distribution. 17 | * Neither the name of the MiG InfoCom AB nor the names of its contributors may be 18 | * used to endorse or promote products derived from this software without specific 19 | * prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 23 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 | * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 25 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 27 | * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 30 | * OF SUCH DAMAGE. 31 | * 32 | * @version 1.0 33 | * @author Mikael Grev, MiG InfoCom AB 34 | * Date: 2006-sep-08 35 | */ 36 | 37 | /** An interface to implement if you want to decide the gaps between two types of components within the same cell. 38 | *

39 | * E.g.: 40 | * 41 | *

42 |  * {@code
43 |  * if (adjacentComp == null || adjacentSide == SwingConstants.LEFT || adjacentSide == SwingConstants.TOP)
44 |  *	  return null;
45 |  *
46 |  * boolean isHor = (adjacentSide == SwingConstants.LEFT || adjacentSide == SwingConstants.RIGHT);
47 |  *
48 |  * if (adjacentComp.getComponentType(false) == ComponentWrapper.TYPE_LABEL && comp.getComponentType(false) == ComponentWrapper.TYPE_TEXT_FIELD)
49 |  *    return isHor ? UNRELATED_Y : UNRELATED_Y;
50 |  *
51 |  * return (adjacentSide == SwingConstants.LEFT || adjacentSide == SwingConstants.RIGHT) ? RELATED_X : RELATED_Y;
52 |  * }
53 |  * 
54 | */ 55 | public interface InCellGapProvider 56 | { 57 | /** Returns the default gap between two components that are in the same cell. 58 | * @param comp The component that the gap is for. Never null. 59 | * @param adjacentComp The adjacent component if any. May be null. 60 | * @param adjacentSide What side the adjacentComp is on. {@link javax.swing.SwingUtilities#TOP} or 61 | * {@link javax.swing.SwingUtilities#LEFT} or {@link javax.swing.SwingUtilities#BOTTOM} or {@link javax.swing.SwingUtilities#RIGHT}. 62 | * @param tag The tag string that the component might be tagged with in the component constraints. May be null. 63 | * @param isLTR If it is left-to-right. 64 | * @return The default gap between two components or null if there should be no gap. 65 | */ 66 | public abstract BoundSize getDefaultGap(ComponentWrapper comp, ComponentWrapper adjacentComp, int adjacentSide, String tag, boolean isLTR); 67 | } 68 | -------------------------------------------------------------------------------- /core/src/main/java/net/miginfocom/layout/LayoutCallback.java: -------------------------------------------------------------------------------- 1 | package net.miginfocom.layout; 2 | 3 | /* 4 | * License (BSD): 5 | * ============== 6 | * 7 | * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) 8 | * All rights reserved. 9 | * 10 | * Redistribution and use in source and binary forms, with or without modification, 11 | * are permitted provided that the following conditions are met: 12 | * Redistributions of source code must retain the above copyright notice, this list 13 | * of conditions and the following disclaimer. 14 | * Redistributions in binary form must reproduce the above copyright notice, this 15 | * list of conditions and the following disclaimer in the documentation and/or other 16 | * materials provided with the distribution. 17 | * Neither the name of the MiG InfoCom AB nor the names of its contributors may be 18 | * used to endorse or promote products derived from this software without specific 19 | * prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 23 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 | * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 25 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 27 | * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 30 | * OF SUCH DAMAGE. 31 | * 32 | * @version 1.0 33 | * @author Mikael Grev, MiG InfoCom AB 34 | * Date: 2006-sep-08 35 | */ 36 | 37 | /** A class to extend if you want to provide more control over where a component is placed or the size of it. 38 | *

39 | * Note! Returned arrays from this class will never be altered. This means that caching of arrays in these methods 40 | * is OK. 41 | */ 42 | public abstract class LayoutCallback 43 | { 44 | /** Returns a position similar to the "pos" the component constraint. 45 | * @param comp The component wrapper that holds the actual component (JComponent is Swing and Control in SWT). 46 | * Should not be altered. 47 | * @return The [x, y, x2, y2] as explained in the documentation for "pos". If null 48 | * is returned nothing is done and this is the default. 49 | * @see UnitValue 50 | * @see net.miginfocom.layout.ConstraintParser#parseUnitValue(String, boolean) 51 | */ 52 | public UnitValue[] getPosition(ComponentWrapper comp) 53 | { 54 | return null; 55 | } 56 | 57 | /** Returns a size similar to the "width" and "height" in the component constraint. 58 | * @param comp The component wrapper that holds the actual component (JComponent is Swing and Control in SWT). 59 | * Should not be altered. 60 | * @return The [width, height] as explained in the documentation for "width" and "height". If null 61 | * is returned nothing is done and this is the default. 62 | * @see net.miginfocom.layout.BoundSize 63 | * @see net.miginfocom.layout.ConstraintParser#parseBoundSize(String, boolean, boolean) 64 | */ 65 | public BoundSize[] getSize(ComponentWrapper comp) 66 | { 67 | return null; 68 | } 69 | 70 | /** A last minute change of the bounds. The bound for the layout cycle has been set and you can correct there 71 | * after any set of rules you like. 72 | * @param comp The component wrapper that holds the actual component (JComponent is Swing and Control in SWT). 73 | */ 74 | public void correctBounds(ComponentWrapper comp) 75 | { 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /core/src/main/java/net/miginfocom/layout/LinkHandler.java: -------------------------------------------------------------------------------- 1 | package net.miginfocom.layout; 2 | 3 | import java.util.HashMap; 4 | import java.util.WeakHashMap; 5 | /* 6 | * License (BSD): 7 | * ============== 8 | * 9 | * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) 10 | * All rights reserved. 11 | * 12 | * Redistribution and use in source and binary forms, with or without modification, 13 | * are permitted provided that the following conditions are met: 14 | * Redistributions of source code must retain the above copyright notice, this list 15 | * of conditions and the following disclaimer. 16 | * Redistributions in binary form must reproduce the above copyright notice, this 17 | * list of conditions and the following disclaimer in the documentation and/or other 18 | * materials provided with the distribution. 19 | * Neither the name of the MiG InfoCom AB nor the names of its contributors may be 20 | * used to endorse or promote products derived from this software without specific 21 | * prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 | * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 29 | * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 30 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 32 | * OF SUCH DAMAGE. 33 | * 34 | * @version 1.0 35 | * @author Mikael Grev, MiG InfoCom AB 36 | * Date: 2006-sep-08 37 | */ 38 | 39 | /** 40 | */ 41 | public final class LinkHandler 42 | { 43 | public static final int X = 0; 44 | public static final int Y = 1; 45 | public static final int WIDTH = 2; 46 | public static final int HEIGHT = 3; 47 | public static final int X2 = 4; 48 | public static final int Y2 = 5; 49 | 50 | // indices for values of LAYOUTS 51 | private static final int VALUES = 0; 52 | private static final int VALUES_TEMP = 1; 53 | 54 | private static final WeakHashMap[]> LAYOUTS = new WeakHashMap[]>(); 55 | 56 | private LinkHandler() 57 | { 58 | } 59 | 60 | public synchronized static Integer getValue(Object layout, String key, int type) 61 | { 62 | Integer ret = null; 63 | 64 | HashMap[] layoutValues = LAYOUTS.get(layout); 65 | if (layoutValues != null) { 66 | int[] rect = layoutValues[VALUES_TEMP].get(key); 67 | if (rect != null && rect[type] != LayoutUtil.NOT_SET) { 68 | ret = rect[type]; 69 | } else { 70 | rect = layoutValues[VALUES].get(key); 71 | ret = (rect != null && rect[type] != LayoutUtil.NOT_SET) ? rect[type] : null; 72 | } 73 | } 74 | return ret; 75 | } 76 | 77 | /** Sets a key that can be linked to from any component. 78 | * @param layout The MigLayout instance 79 | * @param key The key to link to. This is the same as the ID in a component constraint. 80 | * @param x x 81 | * @param y y 82 | * @param width Width 83 | * @param height Height 84 | * @return If the value was changed 85 | */ 86 | public synchronized static boolean setBounds(Object layout, String key, int x, int y, int width, int height) 87 | { 88 | return setBounds(layout, key, x, y, width, height, false, false); 89 | } 90 | 91 | @SuppressWarnings("unchecked") 92 | synchronized static boolean setBounds(Object layout, String key, int x, int y, int width, int height, boolean temporary, boolean incCur) 93 | { 94 | HashMap[] layoutValues = LAYOUTS.get(layout); 95 | if (layoutValues != null) { 96 | HashMap map = layoutValues[temporary ? VALUES_TEMP : VALUES]; 97 | int[] old = map.get(key); 98 | 99 | if (old == null || old[X] != x || old[Y] != y || old[WIDTH] != width || old[HEIGHT] != height) { 100 | if (old == null || incCur == false) { 101 | map.put(key, new int[] {x, y, width, height, x + width, y + height}); 102 | return true; 103 | } else { 104 | boolean changed = false; 105 | 106 | if (x != LayoutUtil.NOT_SET) { 107 | if (old[X] == LayoutUtil.NOT_SET || x < old[X]) { 108 | old[X] = x; 109 | old[WIDTH] = old[X2] - x; 110 | changed = true; 111 | } 112 | 113 | if (width != LayoutUtil.NOT_SET) { 114 | int x2 = x + width; 115 | if (old[X2] == LayoutUtil.NOT_SET || x2 > old[X2]) { 116 | old[X2] = x2; 117 | old[WIDTH] = x2 - old[X]; 118 | changed = true; 119 | } 120 | } 121 | } 122 | 123 | if (y != LayoutUtil.NOT_SET) { 124 | if (old[Y] == LayoutUtil.NOT_SET || y < old[Y]) { 125 | old[Y] = y; 126 | old[HEIGHT] = old[Y2] - y; 127 | changed = true; 128 | } 129 | 130 | if (height != LayoutUtil.NOT_SET) { 131 | int y2 = y + height; 132 | if (old[Y2] == LayoutUtil.NOT_SET || y2 > old[Y2]) { 133 | old[Y2] = y2; 134 | old[HEIGHT] = y2 - old[Y]; 135 | changed = true; 136 | } 137 | } 138 | } 139 | return changed; 140 | } 141 | } 142 | return false; 143 | } 144 | 145 | int[] bounds = new int[] {x, y, width, height, x + width, y + height}; 146 | 147 | HashMap values_temp = new HashMap(4); 148 | if (temporary) 149 | values_temp.put(key, bounds); 150 | 151 | HashMap values = new HashMap(4); 152 | if (temporary == false) 153 | values.put(key, bounds); 154 | 155 | // TODO: generic array creation is not supported, so array should be migrated to List or a class 156 | LAYOUTS.put(layout, new HashMap[] {values, values_temp}); 157 | 158 | return true; 159 | } 160 | 161 | /** This method clear any weak references right away instead of waiting for the GC. This might be advantageous 162 | * if lots of layout are created and disposed of quickly to keep memory consumption down. 163 | * @since 3.7.4 164 | */ 165 | public synchronized static void clearWeakReferencesNow() 166 | { 167 | LAYOUTS.clear(); 168 | } 169 | 170 | public synchronized static boolean clearBounds(Object layout, String key) 171 | { 172 | HashMap[] layoutValues = LAYOUTS.get(layout); 173 | if (layoutValues != null) 174 | return layoutValues[VALUES].remove(key) != null; 175 | return false; 176 | } 177 | 178 | synchronized static void clearTemporaryBounds(Object layout) 179 | { 180 | HashMap[] layoutValues = LAYOUTS.get(layout); 181 | if (layoutValues != null) 182 | layoutValues[VALUES_TEMP].clear(); 183 | } 184 | } 185 | -------------------------------------------------------------------------------- /core/src/main/java/net/miginfocom/layout/ResizeConstraint.java: -------------------------------------------------------------------------------- 1 | package net.miginfocom.layout; 2 | 3 | import java.io.*; 4 | /* 5 | * License (BSD): 6 | * ============== 7 | * 8 | * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) 9 | * All rights reserved. 10 | * 11 | * Redistribution and use in source and binary forms, with or without modification, 12 | * are permitted provided that the following conditions are met: 13 | * Redistributions of source code must retain the above copyright notice, this list 14 | * of conditions and the following disclaimer. 15 | * Redistributions in binary form must reproduce the above copyright notice, this 16 | * list of conditions and the following disclaimer in the documentation and/or other 17 | * materials provided with the distribution. 18 | * Neither the name of the MiG InfoCom AB nor the names of its contributors may be 19 | * used to endorse or promote products derived from this software without specific 20 | * prior written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 23 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 24 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 | * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 26 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 28 | * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 31 | * OF SUCH DAMAGE. 32 | * 33 | * @version 1.0 34 | * @author Mikael Grev, MiG InfoCom AB 35 | * Date: 2006-sep-08 36 | */ 37 | 38 | /** A parsed constraint that specifies how an entity (normally column/row or component) can shrink or 39 | * grow compared to other entities. 40 | */ 41 | final class ResizeConstraint implements Externalizable 42 | { 43 | static final Float WEIGHT_100 = 100f; 44 | 45 | /** How flexible the entity should be, relative to other entities, when it comes to growing. null or 46 | * zero mean it will never grow. An entity that has twice the growWeight compared to another entity will get twice 47 | * as much of available space. 48 | *

49 | * "grow" are only compared within the same "growPrio". 50 | */ 51 | Float grow = null; 52 | 53 | /** The relative priority used for determining which entities gets the extra space first. 54 | */ 55 | int growPrio = 100; 56 | 57 | Float shrink = WEIGHT_100; 58 | 59 | int shrinkPrio = 100; 60 | 61 | public ResizeConstraint() // For Externalizable 62 | { 63 | } 64 | 65 | ResizeConstraint(int shrinkPrio, Float shrinkWeight, int growPrio, Float growWeight) 66 | { 67 | this.shrinkPrio = shrinkPrio; 68 | this.shrink = shrinkWeight; 69 | this.growPrio = growPrio; 70 | this.grow = growWeight; 71 | } 72 | 73 | // ************************************************ 74 | // Persistence Delegate and Serializable combined. 75 | // ************************************************ 76 | 77 | private Object readResolve() throws ObjectStreamException 78 | { 79 | return LayoutUtil.getSerializedObject(this); 80 | } 81 | 82 | @Override 83 | public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException 84 | { 85 | LayoutUtil.setSerializedObject(this, LayoutUtil.readAsXML(in)); 86 | } 87 | 88 | @Override 89 | public void writeExternal(ObjectOutput out) throws IOException 90 | { 91 | if (getClass() == ResizeConstraint.class) 92 | LayoutUtil.writeAsXML(out, this); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /core/src/main/java/net/miginfocom/layout/UnitConverter.java: -------------------------------------------------------------------------------- 1 | package net.miginfocom.layout; 2 | /* 3 | * License (BSD): 4 | * ============== 5 | * 6 | * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) 7 | * All rights reserved. 8 | * 9 | * Redistribution and use in source and binary forms, with or without modification, 10 | * are permitted provided that the following conditions are met: 11 | * Redistributions of source code must retain the above copyright notice, this list 12 | * of conditions and the following disclaimer. 13 | * Redistributions in binary form must reproduce the above copyright notice, this 14 | * list of conditions and the following disclaimer in the documentation and/or other 15 | * materials provided with the distribution. 16 | * Neither the name of the MiG InfoCom AB nor the names of its contributors may be 17 | * used to endorse or promote products derived from this software without specific 18 | * prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 21 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 | * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 24 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 25 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 26 | * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 29 | * OF SUCH DAMAGE. 30 | * 31 | * @version 1.0 32 | * @author Mikael Grev, MiG InfoCom AB 33 | * Date: 2006-sep-08 34 | */ 35 | 36 | /** 37 | */ 38 | public abstract class UnitConverter 39 | { 40 | /** Value to return if this converter can not handle the unit sent in as an argument 41 | * to the convert method. 42 | */ 43 | public static final int UNABLE = -87654312; 44 | 45 | /** Converts value to pixels. 46 | * @param value The value to be converted. 47 | * @param unit The unit of value. Never null and at least one character. 48 | * @param refValue Some reference value that may of may not be used. If the unit is percent for instance this value 49 | * is the value to take the percent from. Usually the size of the parent component in the appropriate dimension. 50 | * @param isHor If the value is horizontal (true) or vertical (false). 51 | * @param parent The parent of the target component that value is to be applied to. 52 | * Might for instance be needed to get the screen that the component is on in a multi screen environment. 53 | *

54 | * May be null in which case a "best guess" value should be returned. 55 | * @param comp The component, if applicable, or null if none. 56 | * @return The number of pixels if unit is handled by this converter, UnitConverter.UNABLE if not. 57 | */ 58 | public abstract int convertToPixels(float value, String unit, boolean isHor, float refValue, ContainerWrapper parent, ComponentWrapper comp); 59 | } 60 | -------------------------------------------------------------------------------- /demo/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | com.miglayout 6 | miglayout-parent 7 | 11.4.2 8 | 9 | miglayout-demo 10 | MiGLayout Demo 11 | MiGLayout - Demo's for Swing and SWT 12 | http://www.miglayout.com/ 13 | 14 | 15 | 16 | ${project.groupId} 17 | miglayout-swing 18 | 19 | 20 | ${project.groupId} 21 | miglayout-swt 22 | 23 | 24 | ${project.groupId} 25 | miglayout-javafx 26 | 27 | 28 | org.openjfx 29 | javafx-base 30 | 31 | 32 | org.openjfx 33 | javafx-controls 34 | 35 | 36 | org.openjfx 37 | javafx-graphics 38 | 39 | 40 | org.openjfx 41 | javafx-fxml 42 | 43 | 44 | org.java.net.substance 45 | substance 46 | 5.3 47 | true 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /demo/src/main/java/net/miginfocom/demo/CallbackDemo.java: -------------------------------------------------------------------------------- 1 | package net.miginfocom.demo; 2 | 3 | import net.miginfocom.layout.BoundSize; 4 | import net.miginfocom.layout.ComponentWrapper; 5 | import net.miginfocom.layout.LayoutCallback; 6 | import net.miginfocom.layout.UnitValue; 7 | import net.miginfocom.swing.MigLayout; 8 | 9 | import javax.swing.*; 10 | import java.awt.*; 11 | import java.awt.event.*; 12 | import java.util.IdentityHashMap; 13 | 14 | /* 15 | * License (BSD): 16 | * ============== 17 | * 18 | * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) 19 | * All rights reserved. 20 | * 21 | * Redistribution and use in source and binary forms, with or without modification, 22 | * are permitted provided that the following conditions are met: 23 | * Redistributions of source code must retain the above copyright notice, this list 24 | * of conditions and the following disclaimer. 25 | * Redistributions in binary form must reproduce the above copyright notice, this 26 | * list of conditions and the following disclaimer in the documentation and/or other 27 | * materials provided with the distribution. 28 | * Neither the name of the MiG InfoCom AB nor the names of its contributors may be 29 | * used to endorse or promote products derived from this software without specific 30 | * prior written permission. 31 | * 32 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 33 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 34 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 35 | * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 36 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 37 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 38 | * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 39 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 40 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 41 | * OF SUCH DAMAGE. 42 | * 43 | * @version 1.0 44 | * @author Mikael Grev, MiG InfoCom AB 45 | * Date: 2006-sep-08 46 | */ 47 | 48 | public class CallbackDemo extends JFrame implements ActionListener, MouseMotionListener, MouseListener 49 | { 50 | private final Timer repaintTimer = new Timer(20, new ActionListener() { 51 | public void actionPerformed(ActionEvent e) { 52 | ((JPanel) getContentPane()).revalidate(); 53 | } 54 | }); 55 | private final IdentityHashMap pressMap = new IdentityHashMap(); 56 | private Point mousePos = null; 57 | 58 | public CallbackDemo() 59 | { 60 | super("MiG Layout Callback Demo"); 61 | 62 | MigLayout migLayout = new MigLayout("align center bottom, insets 30"); 63 | final JPanel panel = new JPanel(migLayout) { 64 | protected void paintComponent(Graphics g) 65 | { 66 | ((Graphics2D) g).setPaint(new GradientPaint(0, getHeight() / 2, Color.WHITE, 0, getHeight(), new Color(240, 238, 235))); 67 | g.fillRect(0, 0, getWidth(), getHeight()); 68 | } 69 | }; 70 | setContentPane(panel); 71 | 72 | // This callback methods will be called for every layout cycle and let you make correction before and after the calculations. 73 | migLayout.addLayoutCallback(new LayoutCallback() { 74 | 75 | // This is the size change part 76 | public BoundSize[] getSize(ComponentWrapper comp) 77 | { 78 | if (comp.getComponent() instanceof JButton) { 79 | Component c = (Component) comp.getComponent(); 80 | Point p = mousePos != null ? SwingUtilities.convertPoint(panel, mousePos, c) : new Point(-1000, -1000); 81 | 82 | 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)); 83 | fact = Math.max(2 - (fact / 200), 1); 84 | 85 | return new BoundSize[] {new BoundSize(new UnitValue(70 * fact), ""), new BoundSize(new UnitValue(70 * fact), "")}; 86 | } 87 | return null; 88 | } 89 | 90 | // This is the jumping part 91 | public void correctBounds(ComponentWrapper c) 92 | { 93 | Long pressedNanos = pressMap.get(c.getComponent()); 94 | if (pressedNanos != null) { 95 | long duration = System.nanoTime() - pressedNanos; 96 | double maxHeight = 100.0 - (duration / 100000000.0); 97 | int deltaY = (int) Math.round(Math.abs(Math.sin((duration) / 300000000.0) * maxHeight)); 98 | c.setBounds(c.getX(), c.getY() - deltaY, c.getWidth(), c.getHeight()); 99 | if (maxHeight < 0.5) { 100 | pressMap.remove(c.getComponent()); 101 | if (pressMap.size() == 0) 102 | repaintTimer.stop(); 103 | } 104 | } 105 | } 106 | }); 107 | 108 | for (int j = 0; j < 10; j++) 109 | panel.add(createButton(j), "aligny 0.8al"); 110 | 111 | JLabel label = new JLabel("Press one of those Swing JButtons!"); 112 | label.setFont(new Font("verdana", Font.PLAIN, 24)); 113 | label.setForeground(new Color(150, 150, 150)); 114 | panel.add(label, "pos 0.5al 0.2al"); 115 | 116 | panel.addMouseMotionListener(this); 117 | panel.addMouseListener(this); 118 | } 119 | 120 | private static Font[] FONTS = new Font[120]; 121 | private JButton createButton(int i) 122 | { 123 | JButton button = new JButton(String.valueOf("MIG LAYOUT".charAt(i))) { 124 | public Font getFont() 125 | { 126 | if (FONTS[0] == null) { 127 | for (int i = 0; i < FONTS.length; i++) 128 | FONTS[i] = new Font("tahoma", Font.PLAIN, i); 129 | } 130 | 131 | return FONTS[getWidth() >> 1]; 132 | } 133 | }; 134 | 135 | button.setForeground(new Color(100, 100, 100)); 136 | button.setFocusPainted(false); 137 | button.addMouseMotionListener(this); 138 | button.addActionListener(this); 139 | button.setMargin(new Insets(0, 0, 0, 0)); 140 | return button; 141 | } 142 | 143 | public void mouseDragged(MouseEvent e) {} 144 | public void mouseMoved(MouseEvent e) 145 | { 146 | if (e.getSource() instanceof JButton) { 147 | mousePos = SwingUtilities.convertPoint((Component) e.getSource(), e.getPoint(), getContentPane()); 148 | } else { 149 | mousePos = e.getPoint(); 150 | } 151 | ((JPanel) getContentPane()).revalidate(); 152 | } 153 | 154 | public void mousePressed(MouseEvent e) {} 155 | public void mouseReleased(MouseEvent e) {} 156 | public void mouseClicked(MouseEvent e) {} 157 | public void mouseEntered(MouseEvent e) {} 158 | public void mouseExited(MouseEvent e) 159 | { 160 | mousePos = null; 161 | ((JPanel) getContentPane()).revalidate(); 162 | } 163 | 164 | public void actionPerformed(ActionEvent e) 165 | { 166 | pressMap.put(e.getSource(), System.nanoTime()); 167 | repaintTimer.start(); 168 | } 169 | 170 | public static void main(String args[]) 171 | { 172 | try { 173 | UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 174 | } catch (Exception ex) {} 175 | 176 | CallbackDemo demoFrame = new CallbackDemo(); 177 | demoFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 178 | demoFrame.setSize(970, 500); 179 | demoFrame.setLocationRelativeTo(null); 180 | demoFrame.setVisible(true); 181 | } 182 | } -------------------------------------------------------------------------------- /demo/src/main/java/net/miginfocom/demo/JavaFXCallbackDemo.java: -------------------------------------------------------------------------------- 1 | package net.miginfocom.demo; 2 | 3 | import javafx.animation.AnimationTimer; 4 | import javafx.application.Application; 5 | import javafx.geometry.Point2D; 6 | import javafx.scene.Scene; 7 | import javafx.scene.control.Button; 8 | import javafx.scene.control.Label; 9 | import javafx.scene.input.MouseEvent; 10 | import javafx.scene.paint.Color; 11 | import javafx.scene.paint.CycleMethod; 12 | import javafx.scene.paint.LinearGradient; 13 | import javafx.scene.paint.Stop; 14 | import javafx.scene.text.Font; 15 | import javafx.stage.Stage; 16 | import net.miginfocom.layout.BoundSize; 17 | import net.miginfocom.layout.ComponentWrapper; 18 | import net.miginfocom.layout.LayoutCallback; 19 | import net.miginfocom.layout.UnitValue; 20 | import org.tbee.javafx.scene.layout.MigPane; 21 | 22 | import java.util.IdentityHashMap; 23 | 24 | /* 25 | * License (BSD): 26 | * ============== 27 | * 28 | * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) 29 | * All rights reserved. 30 | * 31 | * Redistribution and use in source and binary forms, with or without modification, 32 | * are permitted provided that the following conditions are met: 33 | * Redistributions of source code must retain the above copyright notice, this list 34 | * of conditions and the following disclaimer. 35 | * Redistributions in binary form must reproduce the above copyright notice, this 36 | * list of conditions and the following disclaimer in the documentation and/or other 37 | * materials provided with the distribution. 38 | * Neither the name of the MiG InfoCom AB nor the names of its contributors may be 39 | * used to endorse or promote products derived from this software without specific 40 | * prior written permission. 41 | * 42 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 43 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 44 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 45 | * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 46 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 47 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 48 | * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 49 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 51 | * OF SUCH DAMAGE. 52 | * 53 | * @version 1.0 54 | * @author Mikael Grev, MiG InfoCom AB 55 | * Date: 2006-sep-08 56 | */ 57 | 58 | public class JavaFXCallbackDemo extends Application 59 | { 60 | private AnimationTimer layoutTimer; 61 | 62 | private final IdentityHashMap jumpingMap = new IdentityHashMap<>(); 63 | private Point2D mousePos = null; 64 | private MigPane migPane = null; 65 | 66 | private Button createButton(int i) 67 | { 68 | Button button = new Button(String.valueOf("MIG LAYOUT".charAt(i))); 69 | 70 | button.setOnAction(event -> { 71 | jumpingMap.put(button, System.nanoTime()); 72 | layoutTimer.start(); 73 | }); 74 | button.addEventHandler(MouseEvent.MOUSE_MOVED, (MouseEvent event) -> { 75 | mousePos = button.localToParent(event.getX(), event.getY()); 76 | migPane.requestLayout(); 77 | }); 78 | 79 | button.widthProperty().addListener((observable, oldValue, newValue) -> { 80 | button.setFont(new Font(newValue.doubleValue() / 4)); 81 | }); 82 | button.setTextFill(Color.rgb(100, 100, 100)); 83 | button.setFont(new Font(24)); 84 | return button; 85 | } 86 | 87 | public void start(Stage stage) { 88 | 89 | migPane = new MigPane("align center bottom, insets 80"); 90 | 91 | // This callback methods will be called for every layout cycle and let you make correction before and after the calculations. 92 | migPane.addLayoutCallback(new LayoutCallback() { 93 | 94 | // This is the size change part 95 | public BoundSize[] getSize(ComponentWrapper wrapper) 96 | { 97 | if (wrapper.getComponent() instanceof Button) { 98 | Button c = (Button) wrapper.getComponent(); 99 | Point2D p = mousePos != null ? c.parentToLocal(mousePos) : new Point2D(-1000, -1000); 100 | 101 | double fact = Math.sqrt(Math.pow(Math.abs(p.getX() - c.getWidth() / 2f), 2) + Math.pow(Math.abs(p.getY() - c.getHeight() / 2f), 2)); 102 | fact = Math.max(2 - (fact / 200), 1); 103 | 104 | return new BoundSize[] {new BoundSize(new UnitValue((float) (70 * fact)), ""), new BoundSize(new UnitValue((float) (70 * fact)), "")}; 105 | } 106 | return null; 107 | } 108 | 109 | // This is the jumping part 110 | public void correctBounds(ComponentWrapper wrapper) 111 | { 112 | Long pressedNanos = jumpingMap.get(wrapper.getComponent()); 113 | if (pressedNanos != null) { 114 | long duration = System.nanoTime() - pressedNanos; 115 | double maxHeight = 100.0 - (duration / 70000000.0); 116 | int deltaY = (int) Math.round(Math.abs(Math.sin((duration) / 300000000.0) * maxHeight)); 117 | wrapper.setBounds(wrapper.getX(), wrapper.getY() - deltaY, wrapper.getWidth(), wrapper.getHeight()); 118 | if (maxHeight < 0.5) { 119 | jumpingMap.remove(wrapper.getComponent()); 120 | if (jumpingMap.isEmpty()) 121 | layoutTimer.stop(); 122 | } 123 | } 124 | } 125 | }); 126 | 127 | for (int j = 0; j < 10; j++) 128 | migPane.add(createButton(j), "aligny 0.8al"); 129 | 130 | Label label = new Label("Press one of those Buttons!"); 131 | label.setFont(new Font(24)); 132 | label.setTextFill(Color.rgb(150, 150, 150)); 133 | migPane.add(label, "pos 0.5al 0al"); 134 | 135 | migPane.addEventHandler(MouseEvent.MOUSE_MOVED, (MouseEvent event) -> { 136 | mousePos = new Point2D(event.getX(), event.getY()); 137 | migPane.requestLayout(); 138 | }); 139 | 140 | migPane.addEventHandler(MouseEvent.MOUSE_EXITED, event -> { 141 | mousePos = null; 142 | migPane.requestLayout(); 143 | }); 144 | 145 | // create scene 146 | Scene scene = new Scene(migPane, -1, 450); 147 | 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)))); 148 | 149 | // create stage 150 | stage.setTitle("Callback Demo"); 151 | stage.setScene(scene); 152 | stage.sizeToScene(); 153 | stage.show(); 154 | 155 | layoutTimer = new AnimationTimer() { 156 | public void handle(long now) { 157 | migPane.requestLayout(); 158 | } 159 | }; 160 | } 161 | 162 | public static void main(String[] args) { 163 | launch(args); 164 | } 165 | } -------------------------------------------------------------------------------- /demo/src/main/java/net/miginfocom/demo/SwtTest.java: -------------------------------------------------------------------------------- 1 | package net.miginfocom.demo; 2 | 3 | import net.miginfocom.swt.MigLayout; 4 | import org.eclipse.swt.SWT; 5 | import org.eclipse.swt.events.SelectionAdapter; 6 | import org.eclipse.swt.events.SelectionEvent; 7 | import org.eclipse.swt.layout.FillLayout; 8 | import org.eclipse.swt.layout.GridData; 9 | import org.eclipse.swt.layout.GridLayout; 10 | import org.eclipse.swt.widgets.Button; 11 | import org.eclipse.swt.widgets.Combo; 12 | import org.eclipse.swt.widgets.Composite; 13 | import org.eclipse.swt.widgets.Control; 14 | import org.eclipse.swt.widgets.Display; 15 | import org.eclipse.swt.widgets.Label; 16 | import org.eclipse.swt.widgets.Layout; 17 | import org.eclipse.swt.widgets.Shell; 18 | import org.eclipse.swt.widgets.Text; 19 | 20 | public class SwtTest extends Composite 21 | { 22 | private Combo combo; 23 | private Control control; 24 | 25 | public SwtTest(Composite parent, int style, Layout layout) 26 | { 27 | super(parent, style); 28 | setLayout(layout); 29 | createControls(); 30 | } 31 | 32 | private void createControls() 33 | { 34 | Label label = new Label(this, SWT.None); 35 | label.setText("Select Control: "); 36 | 37 | combo = new Combo(this, SWT.READ_ONLY | SWT.DROP_DOWN); 38 | combo.setLayoutData("wrap"); 39 | combo.add("Text Box"); 40 | combo.add("Combo"); 41 | combo.add("Radio Button"); 42 | 43 | combo.addSelectionListener(new SelectionAdapter() 44 | { 45 | @Override 46 | public void widgetSelected(SelectionEvent e) 47 | { 48 | 49 | if (control != null) 50 | control.dispose(); 51 | 52 | switch (combo.getSelectionIndex()) { 53 | case 0: 54 | control = new Text(SwtTest.this, SWT.BORDER); 55 | break; 56 | case 1: 57 | control = new Combo(SwtTest.this, SWT.DROP_DOWN); 58 | break; 59 | case 2: 60 | control = new Button(SwtTest.this, SWT.RADIO); 61 | break; 62 | } 63 | 64 | if (SwtTest.this.getLayout() instanceof GridLayout) { 65 | GridData data = new GridData(SWT.FILL, SWT.NONE, false, false); 66 | data.horizontalSpan = 2; 67 | control.setLayoutData(data); 68 | } else if (SwtTest.this.getLayout() instanceof MigLayout) { 69 | control.setLayoutData("spanx 2, grow"); 70 | } 71 | 72 | SwtTest.this.layout(true); 73 | } 74 | }); 75 | } 76 | 77 | public static void main(String[] args) 78 | { 79 | Display display = new Display(); 80 | Shell shell = new Shell(display); 81 | shell.setText("SWT"); 82 | shell.setLayout(new FillLayout()); 83 | 84 | /** 85 | * Swap out GridLayout for MigLayout to profile and see resources cleaned up. 86 | */ 87 | // GridLayout layout = new GridLayout(2, false); 88 | MigLayout layout = new MigLayout(); 89 | new SwtTest(shell, SWT.NONE, layout); 90 | 91 | shell.open(); 92 | 93 | // Set up the event loop. 94 | while (!shell.isDisposed()) { 95 | if (!display.readAndDispatch()) { 96 | // If no more entries in event queue 97 | display.sleep(); 98 | } 99 | } 100 | 101 | display.dispose(); 102 | } 103 | } -------------------------------------------------------------------------------- /demo/src/main/java/net/miginfocom/demo/Test.java: -------------------------------------------------------------------------------- 1 | package net.miginfocom.demo; 2 | 3 | import net.miginfocom.swing.MigLayout; 4 | 5 | import javax.swing.*; 6 | import java.awt.Color; 7 | import java.awt.HeadlessException; 8 | import java.awt.Toolkit; 9 | 10 | public class Test extends JFrame 11 | { 12 | public Test() throws HeadlessException 13 | { 14 | System.out.println("res " + Toolkit.getDefaultToolkit().getScreenResolution()); 15 | 16 | JPanel panel = new JPanel(); 17 | panel.setBackground(Color.BLACK); 18 | setLayout(new MigLayout()); 19 | add(panel, "w 100mm"); 20 | 21 | pack(); 22 | setLocationRelativeTo(null); 23 | setVisible(true); 24 | } 25 | 26 | public static void main(String[] argv) { 27 | new Test(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /examples/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | com.miglayout 6 | miglayout-parent 7 | 11.4.2 8 | 9 | miglayout-examples 10 | MiGLayout Examples 11 | MiGLayout - Examples for Swing and SWT 12 | http://www.miglayout.com/ 13 | 14 | 15 | 16 | ${project.groupId} 17 | miglayout-swing 18 | 19 | 20 | ${project.groupId} 21 | miglayout-swt 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /examples/src/main/java/net/miginfocom/examples/BugTestApp.java: -------------------------------------------------------------------------------- 1 | package net.miginfocom.examples; 2 | 3 | import javax.swing.*; 4 | import net.miginfocom.swing.MigLayout; 5 | 6 | import java.awt.Color; 7 | import java.awt.LayoutManager; 8 | /* 9 | * License (BSD): 10 | * ============== 11 | * 12 | * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) 13 | * All rights reserved. 14 | * 15 | * Redistribution and use in source and binary forms, with or without modification, 16 | * are permitted provided that the following conditions are met: 17 | * Redistributions of source code must retain the above copyright notice, this list 18 | * of conditions and the following disclaimer. 19 | * Redistributions in binary form must reproduce the above copyright notice, this 20 | * list of conditions and the following disclaimer in the documentation and/or other 21 | * materials provided with the distribution. 22 | * Neither the name of the MiG InfoCom AB nor the names of its contributors may be 23 | * used to endorse or promote products derived from this software without specific 24 | * prior written permission. 25 | * 26 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 27 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 28 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 29 | * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 30 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 31 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 32 | * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 33 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 35 | * OF SUCH DAMAGE. 36 | * 37 | * @version 1.0 38 | * @author Mikael Grev, MiG InfoCom AB 39 | * Date: 2006-sep-08 40 | */ 41 | 42 | /** 43 | * @author Mikael Grev, MiG InfoCom AB 44 | * Date: Dec 15, 2008 45 | * Time: 7:04:50 PM 46 | */ 47 | public class BugTestApp 48 | { 49 | private static JPanel createPanel() 50 | { 51 | JPanel c = new JPanel(); 52 | c.setBackground(new Color(200, 255, 200)); 53 | c.setLayout(new MigLayout("debug")); 54 | 55 | JLabel lab = new JLabel("Qwerty"); 56 | lab.setFont(lab.getFont().deriveFont(30f)); 57 | c.add(lab, "pos 0%+5 0%+5 50%-5 50%-5"); 58 | c.add(new JTextField("Qwerty")); 59 | 60 | JFrame f = new JFrame(); 61 | f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 62 | f.setLayout(new MigLayout()); 63 | f.add(c, "w 400, h 100"); 64 | f.setLocationRelativeTo(null); 65 | f.pack(); 66 | f.setVisible(true); 67 | return null; 68 | } 69 | 70 | private static JPanel createPanel2() 71 | { 72 | JFrame tst = new JFrame(); 73 | tst.setLayout(new MigLayout("debug, fillx","","")); 74 | 75 | tst.add(new JTextField(),"span 2, grow, wrap"); 76 | tst.add(new JTextField(10)); 77 | tst.add(new JLabel("End")); 78 | 79 | tst.setSize(600, 400); 80 | tst.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 81 | tst.setVisible(true); 82 | return null; 83 | } 84 | 85 | public static void main2(String[] args) 86 | { 87 | SwingUtilities.invokeLater(new Runnable() { 88 | public void run() { 89 | try { 90 | UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 91 | } catch (Exception ex) { 92 | ex.printStackTrace(); 93 | } 94 | 95 | createPanel(); 96 | 97 | // JFrame frame = new JFrame("Bug Test App"); 98 | // frame.getContentPane().add(createPanel2()); 99 | // frame.pack(); 100 | // frame.setLocationRelativeTo(null); 101 | // frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 102 | // frame.setVisible(true); 103 | } 104 | }); 105 | } 106 | public static void main(String[] args) throws Exception 107 | { 108 | // createFrame(new GridLayout(1,1)); 109 | createFrame(new MigLayout()); 110 | } 111 | 112 | private static void createFrame(LayoutManager outerPanelLayout) 113 | { 114 | JPanel innerPanel = new JPanel(new MigLayout()); 115 | for (int i = 0; i < 2000; i++) 116 | innerPanel.add(new JLabel("label nr "+i), "wrap"); 117 | 118 | JPanel outerPanel = new JPanel(outerPanelLayout); 119 | outerPanel.add(innerPanel); 120 | 121 | JFrame f1 = new JFrame(outerPanelLayout.getClass().getSimpleName()); 122 | f1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 123 | f1.getContentPane().add(new JScrollPane(outerPanel)); 124 | f1.pack(); 125 | f1.setLocation((int)(Math.random() * 800.0), 0); 126 | f1.setVisible(true); 127 | } 128 | 129 | } 130 | -------------------------------------------------------------------------------- /examples/src/main/java/net/miginfocom/examples/Example.java: -------------------------------------------------------------------------------- 1 | package net.miginfocom.examples; 2 | 3 | import net.miginfocom.swt.MigLayout; 4 | import org.eclipse.swt.SWT; 5 | import org.eclipse.swt.widgets.Composite; 6 | import org.eclipse.swt.widgets.Display; 7 | import org.eclipse.swt.widgets.Label; 8 | import org.eclipse.swt.widgets.Shell; 9 | import org.eclipse.swt.widgets.Table; 10 | import org.eclipse.swt.widgets.TableItem; 11 | 12 | /* 13 | * License (BSD): 14 | * ============== 15 | * 16 | * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) 17 | * All rights reserved. 18 | * 19 | * Redistribution and use in source and binary forms, with or without modification, 20 | * are permitted provided that the following conditions are met: 21 | * Redistributions of source code must retain the above copyright notice, this list 22 | * of conditions and the following disclaimer. 23 | * Redistributions in binary form must reproduce the above copyright notice, this 24 | * list of conditions and the following disclaimer in the documentation and/or other 25 | * materials provided with the distribution. 26 | * Neither the name of the MiG InfoCom AB nor the names of its contributors may be 27 | * used to endorse or promote products derived from this software without specific 28 | * prior written permission. 29 | * 30 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 31 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 32 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 33 | * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 34 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 35 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 36 | * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 37 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 38 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 39 | * OF SUCH DAMAGE. 40 | * 41 | * @version 1.0 42 | * @author Mikael Grev, MiG InfoCom AB 43 | * Date: 2006-sep-08 44 | */ 45 | 46 | public class Example 47 | { 48 | protected void buildControls(Composite parent) 49 | { 50 | parent.setLayout(new MigLayout("inset 0", "[fill, grow]", "[fill, grow]")); 51 | 52 | Table table = new Table(parent, SWT.BORDER|SWT.H_SCROLL|SWT.V_SCROLL); 53 | table.setLayoutData("id table, hmin 100, wmin 300"); 54 | table.setHeaderVisible(true); 55 | table.setLinesVisible(true); 56 | 57 | Label statusLabel = new Label(parent, SWT.BORDER); 58 | statusLabel.setText("Label Text"); 59 | statusLabel.moveAbove(null); 60 | statusLabel.setLayoutData("pos table.x table.y"); 61 | 62 | for (int i = 0; i < 10; i++) { 63 | TableItem ti = new TableItem(table, SWT.NONE); 64 | ti.setText("item #" + i); 65 | } 66 | } 67 | 68 | public static void main(String[] args) 69 | { 70 | final Display display = new Display(); 71 | final Shell shell = new Shell(display); 72 | new Example().buildControls(shell); 73 | shell.open(); 74 | while (!shell.isDisposed()) 75 | { 76 | if (!display.readAndDispatch()) 77 | display.sleep(); 78 | } 79 | display.dispose(); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /examples/src/main/java/net/miginfocom/examples/Example01.java: -------------------------------------------------------------------------------- 1 | package net.miginfocom.examples; 2 | 3 | import javax.swing.*; 4 | import net.miginfocom.swing.MigLayout; 5 | /* 6 | * License (BSD): 7 | * ============== 8 | * 9 | * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) 10 | * All rights reserved. 11 | * 12 | * Redistribution and use in source and binary forms, with or without modification, 13 | * are permitted provided that the following conditions are met: 14 | * Redistributions of source code must retain the above copyright notice, this list 15 | * of conditions and the following disclaimer. 16 | * Redistributions in binary form must reproduce the above copyright notice, this 17 | * list of conditions and the following disclaimer in the documentation and/or other 18 | * materials provided with the distribution. 19 | * Neither the name of the MiG InfoCom AB nor the names of its contributors may be 20 | * used to endorse or promote products derived from this software without specific 21 | * prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 | * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 29 | * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 30 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 32 | * OF SUCH DAMAGE. 33 | * 34 | * @version 1.0 35 | * @author Mikael Grev, MiG InfoCom AB 36 | * Date: 2006-sep-08 37 | */ 38 | /** 39 | */ 40 | public class Example01 41 | { 42 | private static JPanel createPanel() 43 | { 44 | JPanel panel = new JPanel(new MigLayout()); 45 | 46 | panel.add(new JLabel("First Name")); 47 | panel.add(new JTextField(10)); 48 | panel.add(new JLabel("Surname"), "gap unrelated"); // Unrelated size is resolved per platform 49 | panel.add(new JTextField(10), "wrap"); // Wraps to the next row 50 | panel.add(new JLabel("Address")); 51 | panel.add(new JTextField(), "span, grow"); // Spans cells in row and grows to fit that 52 | 53 | return panel; 54 | } 55 | 56 | public static void main(String[] args) 57 | { 58 | SwingUtilities.invokeLater(new Runnable() { 59 | public void run() { 60 | try { 61 | UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 62 | } catch (Exception ex) { 63 | ex.printStackTrace(); 64 | } 65 | 66 | JFrame frame = new JFrame("Example 01"); 67 | frame.getContentPane().add(createPanel()); 68 | frame.pack(); 69 | frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 70 | frame.setVisible(true); 71 | } 72 | }); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /examples/src/main/java/net/miginfocom/examples/Example02.java: -------------------------------------------------------------------------------- 1 | package net.miginfocom.examples; 2 | 3 | import javax.swing.*; 4 | import javax.swing.border.CompoundBorder; 5 | import javax.swing.border.EmptyBorder; 6 | import javax.swing.border.EtchedBorder; 7 | import net.miginfocom.swing.MigLayout; 8 | /* 9 | * License (BSD): 10 | * ============== 11 | * 12 | * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) 13 | * All rights reserved. 14 | * 15 | * Redistribution and use in source and binary forms, with or without modification, 16 | * are permitted provided that the following conditions are met: 17 | * Redistributions of source code must retain the above copyright notice, this list 18 | * of conditions and the following disclaimer. 19 | * Redistributions in binary form must reproduce the above copyright notice, this 20 | * list of conditions and the following disclaimer in the documentation and/or other 21 | * materials provided with the distribution. 22 | * Neither the name of the MiG InfoCom AB nor the names of its contributors may be 23 | * used to endorse or promote products derived from this software without specific 24 | * prior written permission. 25 | * 26 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 27 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 28 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 29 | * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 30 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 31 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 32 | * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 33 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 35 | * OF SUCH DAMAGE. 36 | * 37 | * @version 1.0 38 | * @author Mikael Grev, MiG InfoCom AB 39 | * Date: 2006-sep-08 40 | */ 41 | public class Example02 42 | { 43 | private static JPanel createPanel() 44 | { 45 | JPanel panel = new JPanel(new MigLayout()); 46 | 47 | panel.add(createLabel("West Panel"), "dock west"); 48 | panel.add(createLabel("North 1 Panel"), "dock north"); 49 | panel.add(createLabel("North 2 Panel"), "dock north"); 50 | panel.add(createLabel("South Panel"), "dock south"); 51 | panel.add(createLabel("East Panel"), "dock east"); 52 | panel.add(createLabel("Center Panel"), "grow, push"); // "dock center" from v3.0 53 | 54 | return panel; 55 | } 56 | 57 | private static JLabel createLabel(String text) 58 | { 59 | JLabel label = new JLabel(text); 60 | label.setHorizontalAlignment(JLabel.CENTER); 61 | label.setBorder(new CompoundBorder(new EtchedBorder(), new EmptyBorder(5, 10, 5, 10))); 62 | return label; 63 | } 64 | 65 | public static void main(String[] args) 66 | { 67 | SwingUtilities.invokeLater(new Runnable() { 68 | public void run() { 69 | try { 70 | UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 71 | } catch (Exception ex) { 72 | ex.printStackTrace(); 73 | } 74 | 75 | JFrame frame = new JFrame("Example 02"); 76 | frame.getContentPane().add(createPanel()); 77 | frame.pack(); 78 | frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 79 | frame.setVisible(true); 80 | } 81 | }); 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /examples/src/main/java/net/miginfocom/examples/ExampleGood.java: -------------------------------------------------------------------------------- 1 | package net.miginfocom.examples; 2 | 3 | import net.miginfocom.swt.MigLayout; 4 | import org.eclipse.swt.SWT; 5 | import org.eclipse.swt.widgets.Composite; 6 | import org.eclipse.swt.widgets.Display; 7 | import org.eclipse.swt.widgets.Label; 8 | import org.eclipse.swt.widgets.Shell; 9 | import org.eclipse.swt.widgets.Table; 10 | import org.eclipse.swt.widgets.TableItem; 11 | 12 | /* 13 | * License (BSD): 14 | * ============== 15 | * 16 | * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) 17 | * All rights reserved. 18 | * 19 | * Redistribution and use in source and binary forms, with or without modification, 20 | * are permitted provided that the following conditions are met: 21 | * Redistributions of source code must retain the above copyright notice, this list 22 | * of conditions and the following disclaimer. 23 | * Redistributions in binary form must reproduce the above copyright notice, this 24 | * list of conditions and the following disclaimer in the documentation and/or other 25 | * materials provided with the distribution. 26 | * Neither the name of the MiG InfoCom AB nor the names of its contributors may be 27 | * used to endorse or promote products derived from this software without specific 28 | * prior written permission. 29 | * 30 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 31 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 32 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 33 | * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 34 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 35 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 36 | * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 37 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 38 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 39 | * OF SUCH DAMAGE. 40 | * 41 | * @version 1.0 42 | * @author Mikael Grev, MiG InfoCom AB 43 | * Date: 2006-sep-08 44 | */ 45 | public class ExampleGood 46 | { 47 | protected void buildControls(Composite parent) 48 | { 49 | parent.setLayout(new MigLayout("inset 0", "[fill, grow]", "[fill, grow]")); 50 | 51 | Table table = new Table(parent, SWT.BORDER|SWT.H_SCROLL|SWT.V_SCROLL); 52 | table.setLayoutData("id table, hmin 100, wmin 300"); 53 | table.setHeaderVisible(true); 54 | table.setLinesVisible(true); 55 | 56 | Label statusLabel = new Label(parent, SWT.BORDER); 57 | statusLabel.setText("Label Text"); 58 | statusLabel.moveAbove(null); 59 | statusLabel.setLayoutData("pos 0 0"); 60 | 61 | for (int i = 0; i < 10; i++) 62 | { 63 | TableItem ti = new TableItem(table, SWT.NONE); 64 | ti.setText("item #" + i); 65 | } 66 | } 67 | 68 | public static void main(String[] args) 69 | { 70 | final Display display = new Display(); 71 | final Shell shell = new Shell(display); 72 | new ExampleGood().buildControls(shell); 73 | shell.open(); 74 | while (!shell.isDisposed()) 75 | { 76 | if (!display.readAndDispatch()) 77 | display.sleep(); 78 | } 79 | display.dispose(); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /examples/src/main/java/net/miginfocom/examples/JavaOneShrink.java: -------------------------------------------------------------------------------- 1 | package net.miginfocom.examples; 2 | 3 | import javax.swing.*; 4 | import javax.swing.border.LineBorder; 5 | import net.miginfocom.swing.MigLayout; 6 | 7 | import java.awt.Color; 8 | import java.awt.Container; 9 | import java.awt.Dimension; 10 | import java.awt.Font; 11 | /* 12 | * License (BSD): 13 | * ============== 14 | * 15 | * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) 16 | * All rights reserved. 17 | * 18 | * Redistribution and use in source and binary forms, with or without modification, 19 | * are permitted provided that the following conditions are met: 20 | * Redistributions of source code must retain the above copyright notice, this list 21 | * of conditions and the following disclaimer. 22 | * Redistributions in binary form must reproduce the above copyright notice, this 23 | * list of conditions and the following disclaimer in the documentation and/or other 24 | * materials provided with the distribution. 25 | * Neither the name of the MiG InfoCom AB nor the names of its contributors may be 26 | * used to endorse or promote products derived from this software without specific 27 | * prior written permission. 28 | * 29 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 30 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 31 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 32 | * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 33 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 34 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 35 | * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 36 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 37 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 38 | * OF SUCH DAMAGE. 39 | * 40 | * @version 1.0 41 | * @author Mikael Grev, MiG InfoCom AB 42 | * Date: 2006-sep-08 43 | */ 44 | 45 | /** 46 | * @author Mikael Grev, MiG InfoCom AB 47 | * Date: Apr 20, 2008 48 | * Time: 10:32:58 PM 49 | */ 50 | public class JavaOneShrink 51 | { 52 | private static JComponent createPanel(String ... args) 53 | { 54 | JPanel panel = new JPanel(new MigLayout("nogrid")); 55 | 56 | panel.add(createTextArea(args[0].replace(", ", "\n ")), args[0] + ", w 200"); 57 | panel.add(createTextArea(args[1].replace(", ", "\n ")), args[1] + ", w 200"); 58 | panel.add(createTextArea(args[2].replace(", ", "\n ")), args[2] + ", w 200"); 59 | panel.add(createTextArea(args[3].replace(", ", "\n ")), args[3] + ", w 200"); 60 | 61 | JSplitPane gSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, panel, new JPanel()); 62 | gSplitPane.setOpaque(true); 63 | gSplitPane.setBorder(null); 64 | 65 | return gSplitPane; 66 | } 67 | 68 | private static JComponent createTextArea(String s) 69 | { 70 | JTextArea ta = new JTextArea("\n\n " + s, 6, 20); 71 | ta.setBorder(new LineBorder(new Color(200, 200, 200))); 72 | ta.setFont(new Font("Helvetica", Font.BOLD, 20)); 73 | ta.setMinimumSize(new Dimension(20, 20)); 74 | ta.setFocusable(false); 75 | return ta; 76 | } 77 | 78 | public static void main(String[] args) 79 | { 80 | SwingUtilities.invokeLater(new Runnable() { 81 | public void run() { 82 | try { 83 | UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 84 | } catch (Exception ex) { 85 | ex.printStackTrace(); 86 | } 87 | 88 | JFrame frame = new JFrame("JavaOne Shrink Demo"); 89 | Container cp = frame.getContentPane(); 90 | cp.setLayout(new MigLayout("wrap 1")); 91 | 92 | cp.add(createPanel("", "", "", "")); 93 | cp.add(createPanel("shrinkprio 1", "shrinkprio 1", "shrinkprio 2", "shrinkprio 3")); 94 | cp.add(createPanel("shrink 25", "shrink 50", "shrink 75", "shrink 100")); 95 | cp.add(createPanel("shrinkprio 1, shrink 50", "shrinkprio 1, shrink 100", "shrinkprio 2, shrink 50", "shrinkprio 2, shrink 100")); 96 | 97 | frame.pack(); 98 | frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 99 | frame.setLocationRelativeTo(null); 100 | frame.setVisible(true); 101 | } 102 | }); 103 | } 104 | 105 | } 106 | -------------------------------------------------------------------------------- /examples/src/main/java/net/miginfocom/examples/MigLayoutBug.java: -------------------------------------------------------------------------------- 1 | package net.miginfocom.examples; 2 | 3 | import net.miginfocom.swing.MigLayout; 4 | 5 | import javax.swing.*; 6 | import java.awt.Color; 7 | 8 | /** 9 | * @author Mikael Grev, MiG InfoCom AB 10 | * Date: 14-06-03 11 | * Time: 21:31 12 | */ 13 | public class MigLayoutBug 14 | { 15 | public static void main(String[] args) 16 | { 17 | JFrame frame = new JFrame(); 18 | frame.setSize(500, 500); 19 | frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 20 | frame.setLocationRelativeTo(null); 21 | 22 | JPanel mainPanel = new JPanel(new MigLayout("debug", "", "")); 23 | 24 | JPanel greyPanel = new JPanel(); 25 | greyPanel.setBackground(Color.GRAY); 26 | 27 | JTextArea label = new JTextArea("text \n" + 28 | "over \n" + 29 | "two \n" + 30 | "rows"); 31 | 32 | mainPanel.add(label, "spany 2"); 33 | mainPanel.add(new JLabel("First row"), "wrap"); 34 | mainPanel.add(new JLabel("Second row"), "wrap"); 35 | mainPanel.add(greyPanel, "spanx 2, pushy, grow"); 36 | 37 | frame.setContentPane(mainPanel); 38 | frame.setVisible(true); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /examples/src/main/java/net/miginfocom/examples/SwtTest.java: -------------------------------------------------------------------------------- 1 | package net.miginfocom.examples; 2 | 3 | import net.miginfocom.swt.MigLayout; 4 | import org.eclipse.swt.SWT; 5 | import org.eclipse.swt.events.SelectionAdapter; 6 | import org.eclipse.swt.events.SelectionEvent; 7 | import org.eclipse.swt.layout.FillLayout; 8 | import org.eclipse.swt.widgets.Button; 9 | import org.eclipse.swt.widgets.Composite; 10 | import org.eclipse.swt.widgets.Display; 11 | import org.eclipse.swt.widgets.Label; 12 | import org.eclipse.swt.widgets.Shell; 13 | 14 | /* 15 | * License (BSD): 16 | * ============== 17 | * 18 | * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) 19 | * All rights reserved. 20 | * 21 | * Redistribution and use in source and binary forms, with or without modification, 22 | * are permitted provided that the following conditions are met: 23 | * Redistributions of source code must retain the above copyright notice, this list 24 | * of conditions and the following disclaimer. 25 | * Redistributions in binary form must reproduce the above copyright notice, this 26 | * list of conditions and the following disclaimer in the documentation and/or other 27 | * materials provided with the distribution. 28 | * Neither the name of the MiG InfoCom AB nor the names of its contributors may be 29 | * used to endorse or promote products derived from this software without specific 30 | * prior written permission. 31 | * 32 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 33 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 34 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 35 | * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 36 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 37 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 38 | * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 39 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 40 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 41 | * OF SUCH DAMAGE. 42 | * 43 | * @version 1.0 44 | * @author Mikael Grev, MiG InfoCom AB 45 | * Date: 2006-sep-08 46 | */ 47 | public class SwtTest 48 | { 49 | 50 | public static void main(final String[] args) 51 | { 52 | final Display display = new Display(); 53 | final Shell shell = new Shell(display); 54 | 55 | shell.setLayout(new FillLayout(SWT.VERTICAL)); 56 | 57 | final Composite cmpLabels = new Composite(shell, SWT.BORDER); 58 | cmpLabels.setLayout(new MigLayout("wrap 5")); 59 | 60 | final Label l0 = new Label(cmpLabels, SWT.NONE); 61 | l0.setText("L 0"); 62 | final Label l1 = new Label(cmpLabels, SWT.NONE); 63 | final Label l2 = new Label(cmpLabels, SWT.NONE); 64 | l2.setText("L 2"); 65 | final Label l3 = new Label(cmpLabels, SWT.NONE); 66 | final Label l4 = new Label(cmpLabels, SWT.NONE); 67 | l4.setText("L 4"); 68 | 69 | final Composite cmpButtons = new Composite(shell, SWT.NONE); 70 | cmpButtons.setLayout(new FillLayout()); 71 | 72 | final Button btn1 = new Button(cmpButtons, SWT.PUSH); 73 | btn1.setText("Set 1"); 74 | btn1.addSelectionListener(new SelectionAdapter() 75 | { 76 | @Override 77 | public void widgetSelected(final SelectionEvent e) 78 | { 79 | l3.setText(""); 80 | l1.setText("Some Text"); 81 | cmpLabels.layout(); 82 | cmpLabels.redraw(); 83 | } 84 | }); 85 | 86 | final Button btn3 = new Button(cmpButtons, SWT.PUSH); 87 | btn3.setText("Set 3"); 88 | btn3.addSelectionListener(new SelectionAdapter() 89 | { 90 | @Override 91 | public void widgetSelected(final SelectionEvent e) 92 | { 93 | l1.setText(""); 94 | l3.setText("Some Text"); 95 | cmpLabels.layout(); 96 | cmpLabels.redraw(); 97 | } 98 | }); 99 | 100 | shell.setSize(300, 100); 101 | shell.open(); 102 | while (!shell.isDisposed()) { 103 | if (!display.readAndDispatch()) { 104 | display.sleep(); 105 | } 106 | } 107 | display.dispose(); 108 | } 109 | } -------------------------------------------------------------------------------- /examples/src/main/java/net/miginfocom/examples/VisualPaddingOSX.java: -------------------------------------------------------------------------------- 1 | package net.miginfocom.examples; 2 | 3 | import javax.swing.*; 4 | import javax.swing.border.Border; 5 | import javax.swing.border.EmptyBorder; 6 | import javax.swing.border.LineBorder; 7 | import javax.swing.border.MatteBorder; 8 | import net.miginfocom.swing.MigLayout; 9 | 10 | import java.awt.Color; 11 | import java.awt.image.BufferedImage; 12 | 13 | public class VisualPaddingOSX extends JFrame 14 | { 15 | public VisualPaddingOSX() 16 | { 17 | super("MigLayout Test"); 18 | 19 | setDefaultCloseOperation(EXIT_ON_CLOSE); 20 | 21 | setLayout(new MigLayout("nogrid, debug")); 22 | 23 | String cc = ""; 24 | add(createButton(null), cc); 25 | add(createButton("square"), cc); 26 | add(createButton("gradient"), cc); 27 | add(createButton("bevel"), cc); 28 | add(createButton("textured"), cc); 29 | add(createButton("roundRect"), cc); 30 | add(createButton("recessed"), cc); 31 | add(createButton("help"), cc); 32 | 33 | add(createIconButton(null), cc + ", newline"); 34 | add(createIconButton("square"), cc); 35 | add(createIconButton("gradient"), cc); 36 | add(createIconButton("bevel"), cc); 37 | add(createIconButton("textured"), cc); 38 | add(createIconButton("roundRect"), cc); 39 | add(createIconButton("recessed"), cc); 40 | add(createIconButton("help"), cc); 41 | 42 | add(createToggleButton(null), cc + ", newline"); 43 | add(createToggleButton("square"), cc); 44 | add(createToggleButton("gradient"), cc); 45 | add(createToggleButton("bevel"), cc); 46 | add(createToggleButton("textured"), cc); 47 | add(createToggleButton("roundRect"), cc); 48 | add(createToggleButton("recessed"), cc); 49 | add(createToggleButton("help"), cc); 50 | 51 | add(createBorderButton("button", null), cc + ", newline"); 52 | add(createBorderButton("button", new LineBorder(Color.BLACK)), cc); 53 | add(createBorderButton("button", new MatteBorder(3, 3, 3, 3, Color.BLACK)), cc); 54 | 55 | add(createCombo("JComboBox.isPopDown", false), cc + ", newline"); 56 | add(createCombo("JComboBox.isSquare", false), cc); 57 | add(createCombo(null, false), ""); 58 | 59 | add(createCombo("JComboBox.isPopDown", true), cc + ", newline"); 60 | add(createCombo("JComboBox.isSquare", true), cc); 61 | add(createCombo(null, true), cc); 62 | 63 | JTextField ta = new JTextField("No Border"); 64 | ta.setBorder(new EmptyBorder(0, 0, 0, 0)); 65 | add(ta, cc + ", newline"); 66 | JTextField tfo = new JTextField("Opaque"); 67 | tfo.setOpaque(true); 68 | add(tfo, cc); 69 | add(new JTextArea("A text"), cc); 70 | add(new JTextField("A text"), cc); 71 | add(new JScrollPane(new JTextPane()), cc); 72 | add(new JScrollPane(new JTextArea("A text", 1, 20)), cc); 73 | JList list = new JList<>(new Object[] {"A text"}); 74 | list.setVisibleRowCount(1); 75 | add(new JScrollPane(list), cc); 76 | 77 | add(new JTextField("Compared to"), cc + ", newline"); 78 | add(new JSpinner(new SpinnerNumberModel(1, 1, 10000, 1)), cc); 79 | add(new JSpinner(new SpinnerDateModel()), cc); 80 | add(new JSpinner(new SpinnerListModel(new Object[]{"One", "Two", "Fifteen"})), cc); 81 | JSpinner spinner = new JSpinner(); 82 | spinner.setEditor(new JTextField()); 83 | add(spinner, cc); 84 | 85 | add(createToggle("toggle", null, true, new EmptyBorder(0, 0, 0, 0)), cc + ", newline"); 86 | add(createToggle("toggle", null, true, null), cc); 87 | add(createToggle("toggle", "regular", true, null), cc); 88 | add(createToggle("toggle", "small", true, null), cc); 89 | add(createToggle("toggle", "mini", true, null), cc); 90 | add(createToggle("toggle", null, false, new EmptyBorder(0, 0, 0, 0)), cc); 91 | add(createToggle("toggle", null, false, null), cc); 92 | add(createToggle("toggle", "regular", false, null), cc); 93 | add(createToggle("toggle", "small", false, null), cc); 94 | add(createToggle("toggle", "mini", false, null), cc); 95 | 96 | add(createTabbedPane(), cc + ", newline, growx"); 97 | 98 | pack(); 99 | setLocationRelativeTo(null); 100 | } 101 | 102 | private JToggleButton createToggle(String name, String size, boolean radio, Border border) 103 | { 104 | JToggleButton button = radio ? new JRadioButton(name) : new JCheckBox(name); 105 | if (size != null) 106 | button.putClientProperty("JComponent.sizeVariant", size); 107 | button.setFocusable(false); 108 | 109 | if (border != null) 110 | button.setBorder(border); 111 | 112 | return button; 113 | } 114 | 115 | private JButton createButton(String type) 116 | { 117 | String name = String.valueOf(type); 118 | if (name.equals("help")) 119 | name = ""; 120 | JButton button = new JButton(name); 121 | button.setDefaultCapable(false); 122 | button.setFocusable(false); 123 | if (type != null && type.equals("...") == false) 124 | button.putClientProperty("JButton.buttonType", type); 125 | return button; 126 | } 127 | 128 | private JButton createIconButton(String type) 129 | { 130 | String name = String.valueOf(type); 131 | if (name.equals("help")) 132 | name = ""; 133 | JButton button = new JButton(name); 134 | button.setIcon(new ImageIcon(new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB))); 135 | button.setDefaultCapable(false); 136 | button.setFocusable(false); 137 | if (type != null && type.equals("...") == false) 138 | button.putClientProperty("JButton.buttonType", type); 139 | return button; 140 | } 141 | 142 | private JToggleButton createToggleButton(String type) 143 | { 144 | String name = String.valueOf(type); 145 | if (name.equals("help")) 146 | name = ""; 147 | JToggleButton button = new JToggleButton(name); 148 | button.setFocusable(false); 149 | if (type != null) 150 | button.putClientProperty("JButton.buttonType", type); 151 | return button; 152 | } 153 | 154 | private JButton createBorderButton(String name, Border border) 155 | { 156 | JButton button = new JButton(name); 157 | button.setDefaultCapable(false); 158 | button.setFocusable(false); 159 | button.setBorder(border); 160 | return button; 161 | } 162 | 163 | private JComboBox createCombo(String key, boolean editable) 164 | { 165 | JComboBox comboBox = new JComboBox<>(new Object[]{ String.valueOf(key)}); 166 | comboBox.setFocusable(editable); 167 | comboBox.setEditable(editable); 168 | if (key != null) 169 | comboBox.putClientProperty(key, Boolean.TRUE); 170 | return comboBox; 171 | } 172 | 173 | private JTabbedPane createTabbedPane() 174 | { 175 | JTabbedPane tabbedPane = new JTabbedPane(); 176 | tabbedPane.addTab("tab1", new JLabel("tab1")); 177 | tabbedPane.addTab("tab2", new JLabel("tab2")); 178 | return tabbedPane; 179 | } 180 | 181 | public static void main(String args[]) 182 | { 183 | VisualPaddingOSX migTest = new VisualPaddingOSX(); 184 | migTest.setVisible(true); 185 | } 186 | } -------------------------------------------------------------------------------- /javafx/maven.txt: -------------------------------------------------------------------------------- 1 | The JavaFX runtime is not available in any public Maven repository, it has to be installed in the local repository manually using the command below: 2 | 3 | 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 4 | 5 | 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). 6 | 7 | This is enough to get the JavaFX plugin to compile, but the test classes cannot be run because the JavaFX binaries are missing. 8 | 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. 9 | 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. 10 | 11 | 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. 12 | For example in Eclipse the run configuration of a test could be modified to include the following as "VM arguments": 13 | -Djava.library.path=C:\Progra~1\Oracle\JAVAFX~1.0\bin 14 | 15 | 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. 16 | 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. 17 | So for now we have to live with this and wait for Oracle to improve the Maven support in JavaFX. 18 | -------------------------------------------------------------------------------- /javafx/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | com.miglayout 6 | miglayout-parent 7 | 11.4.2 8 | 9 | miglayout-javafx 10 | MiGLayout JavaFX 11 | MiGLayout - Layout Manager for JavaFX 12 | http://www.miglayout.com/ 13 | 14 | 15 | 11 16 | 11 17 | 11 18 | 4.0.18 19 | 20 | 21 | 22 | 23 | ${project.groupId} 24 | miglayout-core 25 | 26 | 27 | 28 | org.openjfx 29 | javafx-base 30 | provided 31 | 32 | 33 | org.openjfx 34 | javafx-controls 35 | provided 36 | 37 | 38 | org.openjfx 39 | javafx-fxml 40 | provided 41 | 42 | 43 | org.openjfx 44 | javafx-graphics 45 | provided 46 | 47 | 48 | 49 | org.testfx 50 | testfx-core 51 | ${testfx.version} 52 | test 53 | 54 | 55 | org.testfx 56 | testfx-junit 57 | ${testfx.version} 58 | test 59 | 60 | 61 | 62 | 63 | 64 | 65 | org.apache.maven.plugins 66 | maven-compiler-plugin 67 | 3.8.1 68 | 69 | true 70 | lines,vars,source 71 | 72 | 73 | 74 | org.apache.maven.plugins 75 | maven-surefire-plugin 76 | 77 | 78 | org.ow2.asm 79 | asm 80 | 7.2 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /javafx/src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * License (BSD): 3 | * ============== 4 | * 5 | * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without modification, 9 | * are permitted provided that the following conditions are met: 10 | * Redistributions of source code must retain the above copyright notice, this list 11 | * of conditions and the following disclaimer. 12 | * Redistributions in binary form must reproduce the above copyright notice, this 13 | * list of conditions and the following disclaimer in the documentation and/or other 14 | * materials provided with the distribution. 15 | * Neither the name of the MiG InfoCom AB nor the names of its contributors may be 16 | * used to endorse or promote products derived from this software without specific 17 | * prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 25 | * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 28 | * OF SUCH DAMAGE. 29 | * 30 | * @version 1.0 31 | * @author Mikael Grev, MiG InfoCom AB 32 | * Date: 2006-sep-08 33 | */ 34 | 35 | module com.miglayout.javafx { 36 | exports org.tbee.javafx.scene.layout; 37 | exports org.tbee.javafx.scene.layout.fxml; 38 | 39 | requires com.miglayout.core; 40 | requires static javafx.base; 41 | requires static javafx.graphics; 42 | requires static javafx.controls; 43 | } -------------------------------------------------------------------------------- /javafx/src/main/java/org/tbee/javafx/scene/layout/LayoutAnimator.java: -------------------------------------------------------------------------------- 1 | package org.tbee.javafx.scene.layout; 2 | 3 | import javafx.animation.FadeTransition; 4 | import javafx.animation.Interpolator; 5 | import javafx.animation.Transition; 6 | import javafx.application.Platform; 7 | import javafx.geometry.Bounds; 8 | import javafx.geometry.Rectangle2D; 9 | import javafx.scene.Node; 10 | import javafx.scene.SnapshotParameters; 11 | import javafx.scene.image.ImageView; 12 | import javafx.util.Duration; 13 | 14 | import java.util.ArrayList; 15 | import java.util.HashMap; 16 | import java.util.IdentityHashMap; 17 | 18 | /** 19 | * @author Mikael Grev, MiG InfoCom AB 20 | * Date: 14-09-24 21 | * Time: 16:05 22 | */ 23 | public class LayoutAnimator 24 | { 25 | private static final String ANIM_REPLACE_ID = "mig-anim"; 26 | 27 | enum TransType { 28 | BOUNDS, OPACITY 29 | } 30 | 31 | public static final Duration ANIM_DURATION = new Duration(2000); 32 | 33 | private final MigPane pane; 34 | private final ArrayList addedNodes = new ArrayList<>(); 35 | private final ArrayList removedNodes = new ArrayList<>(); 36 | private final IdentityHashMap> nodeAnimMap = new IdentityHashMap<>(); 37 | private final IdentityHashMap replacedNodeMap = new IdentityHashMap<>(); 38 | 39 | public LayoutAnimator(MigPane pane) 40 | { 41 | this.pane = pane; 42 | } 43 | 44 | /** Animates the node. 45 | * @param node The node to animate. Not null. 46 | * @param toBounds If != null the animation will be to these bounds. 47 | */ 48 | void animate(Node node, Rectangle2D toBounds) 49 | { 50 | nodeAnimMap.compute(node, (n, oldTrans) -> createOrUpdateAnimation(n, oldTrans, toBounds)); 51 | 52 | Node replNode = replacedNodeMap.get(node); 53 | if (replNode != null) 54 | nodeAnimMap.compute(replNode, (n, oldTrans) -> createOrUpdateAnimation(n, oldTrans, toBounds)); 55 | } 56 | 57 | private HashMap createOrUpdateAnimation(Node node, HashMap transMap, Rectangle2D toBounds) 58 | { 59 | if (transMap == null) 60 | transMap = new HashMap<>(); 61 | 62 | double toOpacity = extractOpacity(node); 63 | 64 | transMap.compute(TransType.OPACITY, (transType, oldTrans) -> { 65 | if (toOpacity != -1) { 66 | if (oldTrans != null) 67 | oldTrans.stop(); 68 | FadeTransition fadeTrans = new FadeTransition(ANIM_DURATION, node); 69 | fadeTrans.setToValue(toOpacity); 70 | 71 | if (isReplacement(node)) { 72 | fadeTrans.setOnFinished(event -> { 73 | Node realNode = (Node) node.getUserData(); 74 | if (realNode != null) { 75 | Rectangle2D rb = getBounds(node); 76 | realNode.resizeRelocate(rb.getMinX(), rb.getMinY(), rb.getWidth(), rb.getHeight()); 77 | realNode.setVisible(true); 78 | } 79 | pane.remove(node); 80 | }); 81 | } 82 | 83 | fadeTrans.play(); 84 | 85 | // System.out.println("fade to " + toOpacity); 86 | return fadeTrans; 87 | } 88 | return oldTrans; 89 | }); 90 | 91 | if (toBounds != null) { 92 | transMap.compute(TransType.BOUNDS, (transType, oldTrans) -> { 93 | Rectangle2D curBounds = getBounds(node); 94 | 95 | if (!curBounds.equals(toBounds) && (oldTrans == null || !(((LayoutTrans) oldTrans).toBounds.equals(toBounds)))) { 96 | if (oldTrans != null) 97 | oldTrans.stop(); 98 | 99 | if (toOpacity == -1) { 100 | LayoutTrans trans = new LayoutTrans(node, ANIM_DURATION, toBounds); 101 | trans.play(); 102 | // System.out.println("layout to " + toBounds.toString()); 103 | return trans; 104 | } else { 105 | 106 | node.resizeRelocate(toBounds.getMinX(), toBounds.getMinY(), toBounds.getWidth(), toBounds.getHeight()); 107 | } 108 | } 109 | return oldTrans; 110 | }); 111 | } 112 | 113 | return transMap; 114 | } 115 | 116 | private double extractOpacity(Node node) 117 | { 118 | if (addedNodes.remove(node)) { 119 | node.setOpacity(0); 120 | return 1; 121 | } else if (removedNodes.remove(node)) { 122 | return 0; 123 | } 124 | return -1; 125 | } 126 | 127 | void nodeAdded(Node node) 128 | { 129 | if (isReplacement(node)) 130 | return; 131 | 132 | Node replNode = createReplacement(node); 133 | addedNodes.add(replNode); 134 | removedNodes.remove(node); 135 | 136 | node.setVisible(false); 137 | 138 | Platform.runLater(() -> { 139 | pane.add(0, replNode); 140 | // animate(replNode, null); 141 | }); 142 | } 143 | 144 | void nodeRemoved(Node node) 145 | { 146 | if (isReplacement(node)) 147 | return; 148 | 149 | Node replNode = createReplacement(node); 150 | removedNodes.add(replNode); 151 | addedNodes.remove(node); 152 | 153 | Platform.runLater(() -> { 154 | pane.add(0, replNode); 155 | animate(replNode, null); 156 | }); 157 | } 158 | 159 | private static boolean isReplacement(Node node) 160 | { 161 | return ANIM_REPLACE_ID.equals(node.getId()); 162 | } 163 | 164 | public Node createReplacement(Node node) 165 | { 166 | Rectangle2D b = getBounds(node); 167 | 168 | Node replNode = new ImageView(node.snapshot(new SnapshotParameters(), null)); 169 | 170 | replacedNodeMap.put(node, replNode); 171 | replNode.setUserData(node); 172 | 173 | replNode.setManaged(false); 174 | replNode.setId(ANIM_REPLACE_ID); 175 | replNode.resizeRelocate(b.getMinX(), b.getMinY(), b.getWidth(), b.getHeight()); 176 | 177 | return replNode; 178 | } 179 | 180 | void start() 181 | { 182 | // if (status == PAUSED) 183 | // nodeAnimMap.values().forEach(map -> map.values().forEach(Animation::play)); 184 | // status = RUNNING; 185 | } 186 | 187 | private static Rectangle2D getBounds(Node node) 188 | { 189 | Bounds lBounds = node.getLayoutBounds(); 190 | 191 | return new Rectangle2D( 192 | node.getLayoutX(), 193 | node.getLayoutY(), 194 | lBounds.getWidth(), 195 | lBounds.getHeight() 196 | ); 197 | } 198 | 199 | private class LayoutTrans extends Transition 200 | { 201 | private final Node node; 202 | private final double fromX, fromY, fromW, fromH; 203 | private final Rectangle2D toBounds; 204 | 205 | /** 206 | * @param node The node to animate 207 | * @param toBounds Target bounds. Never null. 208 | */ 209 | LayoutTrans(Node node, Duration duration, Rectangle2D toBounds) 210 | { 211 | this.node = node; 212 | this.fromX = node.getLayoutX(); 213 | this.fromY = node.getLayoutY(); 214 | 215 | Bounds bounds = node.getLayoutBounds(); 216 | this.fromW = bounds.getWidth(); 217 | this.fromH = bounds.getHeight(); 218 | 219 | this.toBounds = toBounds; 220 | 221 | setCycleDuration(duration); 222 | 223 | // setInterpolator(Interpolator.SPLINE(0.8, 0.2, 0.2, 0.8)); 224 | setInterpolator(Interpolator.SPLINE(0.0, 0.0, 0.2, 0.8)); 225 | // setInterpolator(Interpolator.EASE_OUT); 226 | } 227 | 228 | @Override 229 | protected void interpolate(double frac) 230 | { 231 | double x = fromX + (toBounds.getMinX() - fromX) * frac; 232 | double y = fromY + (toBounds.getMinY() - fromY) * frac; 233 | double w = fromW + (toBounds.getWidth() - fromW) * frac; 234 | double h = fromH + (toBounds.getHeight() - fromH) * frac; 235 | 236 | pane.incLayoutInhibit(); 237 | node.resizeRelocate(x, y, w, h); 238 | pane.decLayoutInhibit(); 239 | } 240 | } 241 | } 242 | -------------------------------------------------------------------------------- /javafx/src/main/java/org/tbee/javafx/scene/layout/fxml/MigPane.java: -------------------------------------------------------------------------------- 1 | package org.tbee.javafx.scene.layout.fxml; 2 | 3 | import javafx.beans.DefaultProperty; 4 | import javafx.scene.Node; 5 | import net.miginfocom.layout.CC; 6 | import net.miginfocom.layout.ConstraintParser; 7 | 8 | /** 9 | * This class provides some API enhancements to implement FXML (and this keep the original's API clean) 10 | * @author User 11 | * 12 | */ 13 | @DefaultProperty(value = "children") // for FXML integration 14 | public class MigPane extends org.tbee.javafx.scene.layout.MigPane 15 | { 16 | // The FXML simply is matching tag- and attributes names to classes and properties (getter/setter) in the imported Java files 17 | // Many thanks to Michael Paus for the grunt work! 18 | 19 | /** layout called in FXML on MigPane itself */ 20 | public void setLayout(String value) 21 | { 22 | this.fxmLayoutConstraints = value; 23 | setLayoutConstraints( ConstraintParser.parseLayoutConstraint( ConstraintParser.prepare( value ) ) ); 24 | } 25 | public String getLayout() { return fxmLayoutConstraints; } 26 | private String fxmLayoutConstraints; 27 | 28 | /** cols called in FXML on MigPane itself */ 29 | public void setCols(String value) 30 | { 31 | this.fxmlColumConstraints = value; 32 | setColumnConstraints( ConstraintParser.parseColumnConstraints( ConstraintParser.prepare( value ) ) ); 33 | } 34 | public String getCols() { return fxmlColumConstraints; } 35 | private String fxmlColumConstraints; 36 | 37 | /** rows called in FXML on MigPane itself */ 38 | public void setRows(String value) 39 | { 40 | this.fxmlRowConstraints = value; 41 | setRowConstraints( ConstraintParser.parseRowConstraints( ConstraintParser.prepare( value ) ) ); 42 | } 43 | public String getRows() { return fxmlRowConstraints; } 44 | private String fxmlRowConstraints; 45 | 46 | /** called from the subnodes in FXML via MigPane.cc="..." */ 47 | public static void setCc(Node node, CC cc) 48 | { 49 | node.getProperties().put(FXML_CC_KEY, cc); 50 | } 51 | 52 | public static void setCc(Node node, String cc) 53 | { 54 | CC lCC = ConstraintParser.parseComponentConstraint( ConstraintParser.prepare( cc ) ); 55 | setCc(node, lCC); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /javafx/src/test/java/module-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * License (BSD): 3 | * ============== 4 | * 5 | * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without modification, 9 | * are permitted provided that the following conditions are met: 10 | * Redistributions of source code must retain the above copyright notice, this list 11 | * of conditions and the following disclaimer. 12 | * Redistributions in binary form must reproduce the above copyright notice, this 13 | * list of conditions and the following disclaimer in the documentation and/or other 14 | * materials provided with the distribution. 15 | * Neither the name of the MiG InfoCom AB nor the names of its contributors may be 16 | * used to endorse or promote products derived from this software without specific 17 | * prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 25 | * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 28 | * OF SUCH DAMAGE. 29 | * 30 | * @version 1.0 31 | * @author Mikael Grev, MiG InfoCom AB 32 | * Date: 2006-sep-08 33 | */ 34 | 35 | // refer to https://sormuras.github.io/blog/2018-09-11-testing-in-the-modular-world.html#in-module-testing-with-module-infojava 36 | 37 | open module com.miglayout.javafx { 38 | exports org.tbee.javafx.scene.layout; 39 | exports org.tbee.javafx.scene.layout.fxml; 40 | 41 | requires com.miglayout.core; 42 | requires javafx.base; 43 | requires javafx.graphics; 44 | requires javafx.controls; 45 | 46 | requires junit; 47 | requires javafx.fxml; 48 | } -------------------------------------------------------------------------------- /javafx/src/test/java/org/tbee/javafx/scene/layout/test/AssertNode.java: -------------------------------------------------------------------------------- 1 | package org.tbee.javafx.scene.layout.test; 2 | 3 | import javafx.scene.Node; 4 | import javafx.scene.shape.Arc; 5 | import javafx.scene.transform.Rotate; 6 | import javafx.scene.transform.Scale; 7 | import javafx.scene.transform.Transform; 8 | import org.junit.Assert; 9 | 10 | import java.util.Arrays; 11 | import java.util.Collections; 12 | import java.util.List; 13 | 14 | public class AssertNode { 15 | 16 | public AssertNode(Node node) { 17 | this.node = node; 18 | this.description = "node=" + this.node; 19 | } 20 | final Node node; 21 | final String description; 22 | 23 | 24 | public AssertNode assertXYWH(double x, double y, double w, double h, double accuracy) { 25 | try { 26 | Assert.assertEquals(description + ", X", x, node.getLayoutX(), accuracy); 27 | Assert.assertEquals(description + ", Y", y, node.getLayoutY(), accuracy); 28 | Assert.assertEquals(description + ", W", w, width(node), accuracy); 29 | Assert.assertEquals(description + ", H", h, height(node), accuracy); 30 | } 31 | catch (java.lang.AssertionError e) { 32 | AssertNode.generateSource("migPane", node, Collections.emptyList(), false, AssertNode.A.XYWH); 33 | throw e; 34 | } 35 | return this; 36 | } 37 | 38 | public AssertNode assertRotate(double x, double y, double angle, double accuracy) { 39 | Rotate r = null; 40 | for (Transform t : node.getTransforms()) { 41 | if (t instanceof Rotate) { 42 | r = (Rotate)t; 43 | break; 44 | } 45 | } 46 | Assert.assertEquals(description + ", PivotX", x, r.getPivotX(), accuracy); 47 | Assert.assertEquals(description + ", PivotY", y, r.getPivotY(), accuracy); 48 | Assert.assertEquals(description + ", Angle", angle, r.getAngle(), accuracy); 49 | return this; 50 | } 51 | 52 | public AssertNode assertScale(double x, double y, double scaleX, double scaleY, double accuracy) { 53 | Scale s = null; 54 | for (Transform t : node.getTransforms()) { 55 | if (t instanceof Scale) { 56 | s = (Scale)t; 57 | break; 58 | } 59 | } 60 | Assert.assertEquals(description + ", PivotX", x, s.getPivotX(), accuracy); 61 | Assert.assertEquals(description + ", PivotY", y, s.getPivotY(), accuracy); 62 | Assert.assertEquals(description + ", X", scaleX, s.getX(), accuracy); 63 | Assert.assertEquals(description + ", Y", scaleY, s.getY(), accuracy); 64 | return this; 65 | } 66 | 67 | public AssertNode assertArcCenterRadiusAngleLength(double x, double y, double radiusX, double radiusY, double startAngle, double length, double accuracy) { 68 | Arc arc = (Arc)node; 69 | Assert.assertEquals(description + ", CenterX", x, arc.getCenterX(), accuracy); 70 | Assert.assertEquals(description + ", CenterY", y, arc.getCenterY(), accuracy); 71 | Assert.assertEquals(description + ", RadiusX", radiusX, arc.getRadiusX(), accuracy); 72 | Assert.assertEquals(description + ", RadiusY", radiusY, arc.getRadiusY(), accuracy); 73 | Assert.assertEquals(description + ", StartAngle", startAngle, arc.getStartAngle(), accuracy); 74 | Assert.assertEquals(description + ", Length", length, arc.getLength(), accuracy); 75 | return this; 76 | } 77 | 78 | public AssertNode assertClass(Class clazz) { 79 | Assert.assertEquals(description, clazz, node.getClass()); 80 | return this; 81 | } 82 | 83 | public AssertNode assertClassName(String className) { 84 | Assert.assertEquals(description, className, node.getClass().getName()); 85 | return this; 86 | } 87 | 88 | public AssertNode assertTextText(String text) { 89 | Assert.assertEquals(description, text, ((javafx.scene.text.Text)node).getText()); 90 | return this; 91 | } 92 | 93 | static private double width(Node n) { 94 | return n.getLayoutBounds().getWidth() + n.getLayoutBounds().getMinX(); 95 | } 96 | 97 | static private double height(Node n) { 98 | return n.getLayoutBounds().getHeight() + n.getLayoutBounds().getMinY(); 99 | } 100 | 101 | static public enum A {XYWH, ROTATE, SCALE, ARC, CLASS, CLASSNAME, TEXTTEXT} 102 | static public void generateSource(String paneVariableName, List nodes, List excludedNodeClasses, boolean newline, AssertNode.A... asserts) { 103 | 104 | // init 105 | int idx = 0; 106 | String lNewline = (newline ? "\n " : ""); 107 | // if no asserts are specified, use the default 108 | List lAsserts = Arrays.asList( (asserts != null && asserts.length > 0 ? asserts : new AssertNode.A[]{AssertNode.A.XYWH, AssertNode.A.CLASS}) ); 109 | 110 | // for all nodes 111 | for (Node lNode : nodes) { 112 | 113 | // skip node because of class? 114 | if (excludedNodeClasses != null && excludedNodeClasses.contains(lNode.getClass().getName())) { 115 | continue; 116 | } 117 | 118 | // output an assertline 119 | System.out.print("new AssertNode(" + paneVariableName + ".getChildren().get(" + idx + "))"); 120 | generateAsserts(lNode, lNewline, lAsserts); 121 | System.out.println(";"); 122 | 123 | idx++; 124 | } 125 | } 126 | 127 | static public void generateSource(String variableName, Node node, List excludedNodeClasses, boolean newline, AssertNode.A... asserts) { 128 | 129 | // init 130 | String lNewline = (newline ? "\n " : ""); 131 | // if no asserts are specified, use the default 132 | List lAsserts = Arrays.asList( (asserts != null && asserts.length > 0 ? asserts : new AssertNode.A[]{AssertNode.A.XYWH, AssertNode.A.CLASS}) ); 133 | 134 | // output an assertline 135 | System.out.print("new AssertNode(" + variableName + ")"); 136 | generateAsserts(node, lNewline, lAsserts); 137 | System.out.println(";"); 138 | } 139 | 140 | private static void generateAsserts(Node node, String newline, List asserts) { 141 | for (AssertNode.A a : asserts) { 142 | if (a == AssertNode.A.XYWH) { 143 | System.out.print(newline + ".assertXYWH(" + node.getLayoutX() + ", " + node.getLayoutY() + ", " + width(node) + ", " + height(node) + ", 0.01)"); 144 | } 145 | if (a == AssertNode.A.ROTATE) { 146 | Rotate r = null; 147 | for (Transform t : node.getTransforms()) { 148 | if (t instanceof Rotate) { 149 | r = (Rotate)t; 150 | break; 151 | } 152 | } 153 | System.out.print(newline + ".assertRotate(" + r.getPivotX() + ", " + r.getPivotY() + ", " + r.getAngle() + ", 0.01)"); 154 | } 155 | if (a == AssertNode.A.SCALE) { 156 | Scale s = null; 157 | for (Transform t : node.getTransforms()) { 158 | if (t instanceof Scale) { 159 | s = (Scale)t; 160 | break; 161 | } 162 | } 163 | System.out.print(newline + ".assertScale(" + s.getPivotX() + ", " + s.getPivotY() + ", " + s.getX() + ", " + s.getY() + ", 0.01)"); 164 | } 165 | if (a == AssertNode.A.ARC) { 166 | Arc arc = (Arc)node; 167 | System.out.print(newline + ".assertArcCenterRadiusAngleLength(" + arc.getCenterX() + ", " + arc.getCenterY() + ", " + arc.getRadiusX() + ", " + arc.getRadiusY() + ", " + arc.getStartAngle() + ", " + arc.getLength() + ", 0.01)"); 168 | } 169 | if (a == AssertNode.A.CLASS) { 170 | System.out.print(newline + ".assertClass(" + node.getClass().getName() + ".class)"); 171 | } 172 | if (a == AssertNode.A.CLASSNAME) { 173 | System.out.print(newline + ".assertClassName(\"" + node.getClass().getName() + "\")"); 174 | } 175 | if (a == AssertNode.A.TEXTTEXT) { 176 | System.out.print(newline + ".assertTextText(\"" + ((javafx.scene.text.Text)node).getText() + "\")"); 177 | } 178 | } 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /javafx/src/test/java/org/tbee/javafx/scene/layout/test/TestUtil.java: -------------------------------------------------------------------------------- 1 | package org.tbee.javafx.scene.layout.test; 2 | 3 | import javafx.application.Platform; 4 | import javafx.scene.Node; 5 | import javafx.scene.Scene; 6 | import javafx.scene.control.Control; 7 | import javafx.scene.control.Label; 8 | import javafx.scene.control.Skin; 9 | import javafx.scene.control.SkinBase; 10 | import javafx.scene.layout.Pane; 11 | import javafx.stage.Popup; 12 | import javafx.stage.Stage; 13 | 14 | import java.text.ParseException; 15 | import java.text.SimpleDateFormat; 16 | import java.time.LocalDate; 17 | import java.time.LocalDateTime; 18 | import java.time.format.DateTimeFormatter; 19 | import java.util.Calendar; 20 | import java.util.List; 21 | import java.util.concurrent.Callable; 22 | import java.util.concurrent.ExecutionException; 23 | import java.util.concurrent.FutureTask; 24 | 25 | public class TestUtil { 26 | 27 | /** 28 | * 29 | * @param s 30 | */ 31 | static public void printHierarchy(Stage s) { 32 | StringBuilder lStringBuilder = new StringBuilder(); 33 | lStringBuilder.append("Stage\n| Scene (window=" + s.getScene().getWindow() + ")"); 34 | printHierarchy(lStringBuilder, s.getScene().getRoot(), 2); 35 | if (lStringBuilder.length() > 0) { 36 | lStringBuilder.append("\n"); 37 | } 38 | System.out.println(lStringBuilder.toString()); 39 | } 40 | 41 | /** 42 | * 43 | * @param s 44 | */ 45 | static public void printHierarchy(Scene s) { 46 | StringBuilder lStringBuilder = new StringBuilder(); 47 | lStringBuilder.append("Scene (window=" + s.getWindow() + ")"); 48 | printHierarchy(lStringBuilder, s.getRoot(), 1); 49 | if (lStringBuilder.length() > 0) { 50 | lStringBuilder.append("\n"); 51 | } 52 | System.out.println(lStringBuilder.toString()); 53 | } 54 | 55 | /** 56 | * 57 | * @param p 58 | */ 59 | static public void printHierarchy(Popup p) { 60 | StringBuilder lStringBuilder = new StringBuilder(); 61 | lStringBuilder.append("Popup (owner=" + p.getOwnerNode() + ")"); 62 | for (Object lChild : p.getContent()) { 63 | printHierarchy(lStringBuilder, (Node)lChild, 1); 64 | } 65 | if (lStringBuilder.length() > 0) { 66 | lStringBuilder.append("\n"); 67 | } 68 | System.out.println(lStringBuilder.toString()); 69 | } 70 | 71 | /** 72 | * 73 | * @param n 74 | */ 75 | static public void printHierarchy(Node n) { 76 | StringBuilder lStringBuilder = new StringBuilder(); 77 | printHierarchy(lStringBuilder, n, 0); 78 | if (lStringBuilder.length() > 0) { 79 | lStringBuilder.append("\n"); 80 | } 81 | System.out.println(lStringBuilder.toString()); 82 | } 83 | 84 | /** 85 | * 86 | * @param stringBuilder 87 | * @param n 88 | * @param offset 89 | */ 90 | static private void printHierarchy(StringBuilder stringBuilder, Node n, int offset) { 91 | if (stringBuilder.length() > 0) { 92 | stringBuilder.append("\n"); 93 | } 94 | for (int i = 0; i < offset; i++) stringBuilder.append("| "); 95 | stringBuilder.append(n.getClass().getSimpleName()); 96 | if (n.getId() != null) { 97 | stringBuilder.append(" id='" + n.getId() + "'"); 98 | } 99 | if (n.getStyle() != null && n.getStyle().length() > 0) { 100 | stringBuilder.append(" style='" + n.getStyle() + "'"); 101 | } 102 | if (n.getStyleClass() != null && n.getStyleClass().size() > 0) { 103 | stringBuilder.append(" styleClass='" + n.getStyleClass() + "'"); 104 | } 105 | 106 | // scan children 107 | if (n instanceof Control) { 108 | Control lControl = (Control)n; 109 | Skin lSkin = lControl.getSkin(); 110 | stringBuilder.append(" skin=" + (lSkin == null ? "null" : lSkin.getClass().getSimpleName()) ); 111 | if (lSkin instanceof SkinBase) { 112 | SkinBase lSkinBase = (SkinBase)lSkin; 113 | for (Object lChild : lSkinBase.getChildren()) { 114 | printHierarchy(stringBuilder, (Node)lChild, offset + 1); 115 | } 116 | } 117 | if (lControl instanceof Label) { 118 | Label lLabel = (Label)lControl; 119 | stringBuilder.append(" text=" + lLabel.getText() ); 120 | } 121 | } 122 | else if (n instanceof Pane) { 123 | Pane lPane = (Pane)n; 124 | for (Node lChild : lPane.getChildren()) { 125 | printHierarchy(stringBuilder, lChild, offset + 1); 126 | } 127 | } 128 | } 129 | 130 | /** 131 | * 132 | */ 133 | static public String quickFormatCalendarAsDate(Calendar value) { 134 | if (value == null) return "null"; 135 | SimpleDateFormat lSimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); 136 | return value == null ? "null" : lSimpleDateFormat.format(value.getTime()); 137 | } 138 | 139 | static public String quickFormatLocalDateAsDate(LocalDate value) { 140 | if (value == null) return "null"; 141 | DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); 142 | return value == null ? "null" : value.format(formatter); 143 | } 144 | 145 | static public String quickFormatLocalDateTimeAsDate(LocalDateTime value) { 146 | if (value == null) return "null"; 147 | DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); 148 | return value == null ? "null" : value.format(formatter); 149 | } 150 | 151 | /** 152 | * 153 | */ 154 | static public String quickFormatCalendarAsTime(Calendar value) { 155 | if (value == null) return "null"; 156 | SimpleDateFormat lSimpleDateFormat = new SimpleDateFormat("HH:mm:ss"); 157 | return value == null ? "null" : lSimpleDateFormat.format(value.getTime()); 158 | } 159 | 160 | /** 161 | * 162 | */ 163 | static public String quickFormatCalendarAsDateTime(Calendar value) { 164 | if (value == null) return "null"; 165 | SimpleDateFormat lSimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS"); 166 | return value == null ? "null" : lSimpleDateFormat.format(value.getTime()); 167 | } 168 | 169 | /** 170 | * 171 | */ 172 | static public Calendar quickParseCalendarFromDateTime(String value) { 173 | try { 174 | if (value == null) return null; 175 | SimpleDateFormat lSimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS"); 176 | Calendar c = Calendar.getInstance(); 177 | c.setTime( lSimpleDateFormat.parse(value) ); 178 | return c; 179 | } 180 | catch (ParseException e) { 181 | throw new RuntimeException(e); 182 | } 183 | } 184 | 185 | /** 186 | * 187 | * @param value 188 | * @return 189 | */ 190 | public static LocalDateTime quickParseLocalDateTimeYMDhm(String value) { 191 | if (value == null) return null; 192 | DateTimeFormatter lDateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm"); 193 | LocalDateTime dt = LocalDateTime.parse(value, lDateTimeFormatter); 194 | return dt; 195 | } 196 | 197 | /** 198 | * 199 | * @param value 200 | * @return 201 | */ 202 | static public String quickFormatCalendarsAsDate(List value) { 203 | if (value == null) return "null"; 204 | String s = "["; 205 | for (Calendar lCalendar : value) 206 | { 207 | if (s.length() > 1) s += ", "; 208 | s += quickFormatCalendarAsDate(lCalendar); 209 | } 210 | s += "]"; 211 | return s; 212 | } 213 | 214 | /** 215 | * 216 | * @param value 217 | * @return 218 | */ 219 | static public String quickFormatCalendarsAsDateTime(List value) { 220 | if (value == null) return "null"; 221 | String s = "["; 222 | for (Calendar lCalendar : value) 223 | { 224 | if (s.length() > 1) s += ", "; 225 | s += quickFormatCalendarAsDateTime(lCalendar); 226 | } 227 | s += "]"; 228 | return s; 229 | } 230 | 231 | 232 | /** 233 | * 234 | * @param ms 235 | */ 236 | static public void sleep(int ms) { 237 | try { 238 | Thread.sleep(ms); 239 | } 240 | catch (InterruptedException e) { 241 | throw new RuntimeException(e); 242 | } 243 | } 244 | 245 | 246 | /** 247 | * This method also exist in PlatformUtil in commons, but we can't use that here 248 | */ 249 | static public void runAndWait(final Runnable runnable) { 250 | try { 251 | FutureTask future = new FutureTask<>(runnable, null); 252 | Platform.runLater(future); 253 | future.get(); 254 | } 255 | catch (InterruptedException | ExecutionException e) { 256 | throw new RuntimeException(e); 257 | } 258 | } 259 | 260 | /** 261 | * This method also exist in PlatformUtil in commons, but we can't use that here 262 | */ 263 | static public V runAndWait(final Callable callable) throws InterruptedException, ExecutionException { 264 | FutureTask future = new FutureTask<>(callable); 265 | Platform.runLater(future); 266 | return future.get(); 267 | } 268 | 269 | /** 270 | * This method also exist in PlatformUtil in commons, but we can't use that here 271 | */ 272 | static public void waitForPaintPulse() { 273 | Platform.requestNextPulse(); 274 | sleep(50); 275 | runAndWait(() -> {}); 276 | } 277 | 278 | /** 279 | * 280 | * @param r 281 | */ 282 | static public void runThenWaitForPaintPulse(Runnable r) { 283 | runAndWait(r); 284 | waitForPaintPulse(); 285 | } 286 | 287 | /** 288 | * 289 | * @param r 290 | * @return 291 | */ 292 | static public T runThenWaitForPaintPulse(Callable r) { 293 | try { 294 | T t = runAndWait(r); 295 | waitForPaintPulse(); 296 | return t; 297 | } 298 | catch (InterruptedException | ExecutionException e) { 299 | throw new RuntimeException(e); 300 | } 301 | } 302 | } 303 | -------------------------------------------------------------------------------- /javafx/src/test/java/org/tbee/javafx/scene/layout/trial/AnimDemo.java: -------------------------------------------------------------------------------- 1 | package org.tbee.javafx.scene.layout.trial; 2 | 3 | import javafx.animation.KeyFrame; 4 | import javafx.animation.Timeline; 5 | import javafx.application.Application; 6 | import javafx.scene.Scene; 7 | import javafx.scene.paint.Color; 8 | import javafx.scene.shape.Rectangle; 9 | import javafx.stage.Stage; 10 | import javafx.util.Duration; 11 | import org.tbee.javafx.scene.layout.LayoutAnimator; 12 | import org.tbee.javafx.scene.layout.MigPane; 13 | 14 | import java.util.Random; 15 | 16 | import static javafx.animation.Timeline.INDEFINITE; 17 | 18 | /** 19 | * @author Mikael Grev, MiG InfoCom AB 20 | * Date: 14-09-25 21 | * Time: 20:43 22 | */ 23 | public class AnimDemo extends Application 24 | { 25 | private final Random random = new Random(1); 26 | private MigPane pane; 27 | 28 | public static void main(String[] args) 29 | { 30 | launch(args); 31 | } 32 | 33 | public void start(Stage stage) 34 | { 35 | pane = new MigPane("flowy, align center center"); 36 | 37 | stage.setScene(new Scene(pane, 600, 800)); 38 | stage.sizeToScene(); 39 | stage.show(); 40 | 41 | for (int i = 0; i++ < 3;) 42 | pane.add(getIx(), createRect()); 43 | 44 | Timeline timer = new Timeline(new KeyFrame(new Duration(LayoutAnimator.ANIM_DURATION.toMillis() + 300), e -> { 45 | if (Math.random() > 0.6 || pane.getChildren().size() < 3) { 46 | pane.add(getIx(), createRect(), ""); 47 | } else { 48 | pane.remove(getIx()); 49 | } 50 | })); 51 | timer.setCycleCount(INDEFINITE); 52 | timer.play(); 53 | } 54 | 55 | private int getIx() 56 | { 57 | int size = pane.getChildren().size(); 58 | return size == 0 ? 0 : random.nextInt(size); 59 | } 60 | 61 | private Rectangle createRect() 62 | { 63 | Rectangle rect = new Rectangle(500, 100); 64 | rect.setFill(Color.color(Math.random(), Math.random(), Math.random())); 65 | rect.setArcHeight(15); 66 | rect.setArcWidth(15); 67 | return rect; 68 | } 69 | } 70 | 71 | -------------------------------------------------------------------------------- /javafx/src/test/java/org/tbee/javafx/scene/layout/trial/MigPaneBaselineTrial.java: -------------------------------------------------------------------------------- 1 | package org.tbee.javafx.scene.layout.trial; 2 | 3 | import javafx.application.Application; 4 | import javafx.scene.Scene; 5 | import javafx.scene.control.Label; 6 | import javafx.scene.control.TextField; 7 | import javafx.scene.text.Font; 8 | import javafx.stage.Stage; 9 | import net.miginfocom.layout.AC; 10 | import net.miginfocom.layout.LC; 11 | import org.tbee.javafx.scene.layout.MigPane; 12 | 13 | /** 14 | * Test miglayout managed and unmanaged nodes 15 | * @author Tom Eugelink 16 | * 17 | */ 18 | public class MigPaneBaselineTrial extends Application { 19 | 20 | public static void main(String[] args) { 21 | launch(args); 22 | } 23 | 24 | @Override 25 | public void start(Stage stage) { 26 | 27 | // root 28 | MigPane lRoot = new MigPane(new LC().debug(1000), new AC(), new AC()); 29 | 30 | 31 | // add managed nodes 32 | Label label = new Label("We should"); 33 | label.setFont(new Font(40)); 34 | lRoot.add(label, "split 2"); 35 | lRoot.add(new TextField("have the same baseline")); 36 | // lRoot.add(new Rectangle(30,30, Color.YELLOW), new CC()); 37 | 38 | // create scene 39 | Scene scene = new Scene(lRoot, -1, -1); 40 | 41 | // create stage 42 | stage.setTitle("Test"); 43 | stage.setScene(scene); 44 | stage.sizeToScene(); 45 | stage.show(); 46 | } 47 | } -------------------------------------------------------------------------------- /javafx/src/test/java/org/tbee/javafx/scene/layout/trial/MigPaneHidemodeTrial.java: -------------------------------------------------------------------------------- 1 | package org.tbee.javafx.scene.layout.trial; 2 | 3 | import javafx.application.Application; 4 | import javafx.scene.Scene; 5 | import javafx.scene.control.Button; 6 | import javafx.scene.control.Separator; 7 | import javafx.scene.control.TextField; 8 | import javafx.stage.Stage; 9 | import net.miginfocom.layout.AC; 10 | import net.miginfocom.layout.LC; 11 | import org.tbee.javafx.scene.layout.MigPane; 12 | 13 | /** 14 | * @author Mikael Grev, MiG InfoCom AB 15 | * Date: 14-04-29 16 | * Time: 14:22 17 | */ 18 | public class MigPaneHidemodeTrial extends Application 19 | { 20 | public static void main(String[] args) { 21 | launch(args); 22 | } 23 | 24 | @Override 25 | public void start(Stage stage) { 26 | 27 | 28 | // add managed nodes 29 | Button button = new Button("Change Visibility"); 30 | 31 | TextField textField0 = new TextField("hidemode 0"); 32 | TextField textField1 = new TextField("hidemode 1"); 33 | TextField textField2 = new TextField("hidemode 2"); 34 | TextField textField3 = new TextField("hidemode 3"); 35 | 36 | MigPane pane = new MigPane(new LC().debug().pack(), new AC(), new AC()); 37 | 38 | pane.add(button, "wrap"); 39 | pane.add(new Separator(), "growx, wrap"); 40 | pane.add(textField0, "hidemode 0, gap 10 10 10 10, wrap"); 41 | pane.add(new Separator(), "growx, wrap"); 42 | pane.add(textField1, "hidemode 1, gap 10 10 10 10, wrap"); 43 | pane.add(new Separator(), "growx, wrap"); 44 | pane.add(textField2, "hidemode 2, gap 10 10 10 10, wrap"); 45 | pane.add(new Separator(), "growx, wrap"); 46 | pane.add(textField3, "hidemode 3, gap 10 10 10 10, wrap"); 47 | pane.add(new Separator(), "growx, wrap"); 48 | 49 | // VBox pane = new VBox(); 50 | // pane.getChildren().add(button); 51 | // pane.getChildren().add(new Separator()); 52 | // pane.getChildren().add(textField0); 53 | // pane.getChildren().add(new Separator()); 54 | // pane.getChildren().add(textField1); 55 | // pane.getChildren().add(new Separator()); 56 | // pane.getChildren().add(textField2);q 57 | // pane.getChildren().add(new Separator()); 58 | // pane.getChildren().add(textField3); 59 | // pane.getChildren().add(new Separator()); 60 | 61 | button.setOnAction(event -> { 62 | textField0.setVisible(!textField0.isVisible()); 63 | textField1.setVisible(!textField1.isVisible()); 64 | textField2.setVisible(!textField2.isVisible()); 65 | textField3.setVisible(!textField3.isVisible()); 66 | }); 67 | 68 | // create scene 69 | Scene scene = new Scene(pane, -1, -1); 70 | 71 | // create stage 72 | stage.setTitle("Test"); 73 | stage.setScene(scene); 74 | stage.sizeToScene(); 75 | stage.show(); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /javafx/src/test/java/org/tbee/javafx/scene/layout/trial/MigPanePackTrial.java: -------------------------------------------------------------------------------- 1 | package org.tbee.javafx.scene.layout.trial; 2 | 3 | import javafx.animation.KeyFrame; 4 | import javafx.animation.Timeline; 5 | import javafx.application.Application; 6 | import javafx.scene.Scene; 7 | import javafx.scene.control.Label; 8 | import javafx.scene.text.Font; 9 | import javafx.scene.text.TextAlignment; 10 | import javafx.stage.Stage; 11 | import javafx.util.Duration; 12 | import net.miginfocom.layout.LC; 13 | import org.tbee.javafx.scene.layout.MigPane; 14 | 15 | import java.util.concurrent.atomic.AtomicBoolean; 16 | 17 | 18 | /** 19 | * Test miglayout managed and unmanaged nodes 20 | * @author Tom Eugelink 21 | * 22 | */ 23 | public class MigPanePackTrial extends Application { 24 | 25 | public static void main(String[] args) { 26 | launch(args); 27 | } 28 | 29 | @Override 30 | public void start(Stage stage) { 31 | 32 | // root 33 | MigPane rootMP = new MigPane(new LC().pack().packAlign(0.5f, 1f)); 34 | 35 | // add managed nodes 36 | Label label = new Label("Pack it up!"); 37 | 38 | rootMP.add(label, "alignx center, wrap unrel"); 39 | 40 | Label wrapLabel = new Label("The only thing changed\nis the font size"); 41 | wrapLabel.setTextAlignment(TextAlignment.CENTER); 42 | rootMP.add(wrapLabel, "alignx center"); 43 | 44 | // create scene 45 | Scene scene = new Scene(rootMP); 46 | 47 | // create stage 48 | stage.setTitle("Pack Trial"); 49 | stage.setScene(scene); 50 | stage.sizeToScene(); 51 | stage.show(); 52 | 53 | AtomicBoolean up = new AtomicBoolean(true); 54 | Timeline timeline = new Timeline(new KeyFrame(Duration.millis(40), event -> { 55 | double oldSize = label.getFont().getSize(); 56 | if (oldSize > 100) { 57 | up.set(false); 58 | } else if (oldSize < 10) { 59 | up.set(true); 60 | stage.centerOnScreen(); 61 | } 62 | label.setFont(new Font(oldSize + (up.get() ? 2 : -2))); 63 | })); 64 | timeline.setCycleCount(-1); 65 | timeline.play(); 66 | } 67 | } -------------------------------------------------------------------------------- /javafx/src/test/java/org/tbee/javafx/scene/layout/trial/MigPanePosTrial.java: -------------------------------------------------------------------------------- 1 | package org.tbee.javafx.scene.layout.trial; 2 | 3 | import javafx.application.Application; 4 | import javafx.scene.Scene; 5 | import javafx.scene.control.Label; 6 | import javafx.scene.layout.FlowPane; 7 | import javafx.stage.Stage; 8 | import org.tbee.javafx.scene.layout.MigPane; 9 | 10 | /** 11 | * Created by user mikaelgrev on 18-01-16. 12 | */ 13 | public class MigPanePosTrial extends Application 14 | { 15 | public static void main(String[] args) 16 | { 17 | launch(args); 18 | } 19 | 20 | @Override 21 | public void start(Stage stage) 22 | { 23 | MigPane migPane = new MigPane("debug"); 24 | 25 | FlowPane flowPane = new FlowPane(); 26 | flowPane.getChildren().add(new Label("1")); 27 | flowPane.getChildren().add(new Label("2")); 28 | flowPane.getChildren().add(new Label("3")); 29 | 30 | migPane.add(new Label("3"), "pos container.x 0"); 31 | // migPane.add(new Label("3"), "pos 0 0"); // This instead of above made it always work. 32 | migPane.add(flowPane, ""); 33 | 34 | // Before fix to Grid.java in 2018-01-16 the flowpane became too large. 35 | 36 | Scene scene = new Scene(migPane); 37 | stage.setScene(scene); 38 | stage.show(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /javafx/src/test/java/org/tbee/javafx/scene/layout/trial/MigPaneSizeGroupTrial18.java: -------------------------------------------------------------------------------- 1 | package org.tbee.javafx.scene.layout.trial; 2 | 3 | import javafx.application.Application; 4 | import javafx.scene.Scene; 5 | import javafx.scene.control.Label; 6 | import javafx.stage.Stage; 7 | import org.tbee.javafx.scene.layout.MigPane; 8 | 9 | /** 10 | * @author Mikael Grev, MiG InfoCom AB 11 | * Date: 15-10-07 12 | * Time: 21:11 13 | */ 14 | public class MigPaneSizeGroupTrial18 extends Application 15 | { 16 | public static void main(String[] args) 17 | { 18 | launch(args); 19 | } 20 | 21 | @Override 22 | public void start(Stage stage) 23 | { 24 | // root 25 | MigPane pane = new MigPane("debug"); 26 | 27 | // add managed nodes 28 | pane.add(new Label("Should have same sizes as ->"), "sgx"); 29 | pane.add(new Label("Short"), "sgx"); 30 | 31 | // With this line the layout will not be correct pre 2015-10-07 fix since the Grid is created 32 | // with the Scene set to null 33 | pane.prefHeight(-1); 34 | 35 | // Add this and it till work again since it clears the grid. Adding "nocache" 36 | // to the LC in the constructor also works. 37 | // pane.invalidateGrid(); 38 | 39 | // create scene 40 | Scene scene = new Scene(pane, -1, -1); 41 | 42 | // create stage 43 | stage.setTitle("Test"); 44 | stage.setScene(scene); 45 | stage.sizeToScene(); 46 | stage.show(); 47 | } 48 | } 49 | 50 | -------------------------------------------------------------------------------- /javafx/src/test/java/org/tbee/javafx/scene/layout/trial/MigPaneSizeTrial.java: -------------------------------------------------------------------------------- 1 | package org.tbee.javafx.scene.layout.trial; 2 | 3 | import javafx.application.Application; 4 | import javafx.scene.Scene; 5 | import javafx.scene.control.Button; 6 | import javafx.stage.Stage; 7 | import net.miginfocom.layout.LC; 8 | import org.tbee.javafx.scene.layout.MigPane; 9 | 10 | /** 11 | * @author Mikael Grev, MiG InfoCom AB 12 | * Date: 14-04-24 13 | * Time: 16:33 14 | */ 15 | public class MigPaneSizeTrial extends Application 16 | { 17 | public static void main(String[] args) { 18 | launch(args); 19 | } 20 | 21 | @Override 22 | public void start(Stage stage) { 23 | 24 | // root 25 | MigPane lRoot = new MigPane(new LC().debug().fillX()); 26 | 27 | // System.out.println(Screen.getPrimary().getDpi()); 28 | // System.out.println(Toolkit.getDefaultToolkit().getScreenResolution()); 29 | 30 | // add nodes 31 | lRoot.add(new Button("500 logical pixels (def)"), "w 500, wrap"); 32 | lRoot.add(new Button("500 logical pixels"), "w 500lp, wrap"); 33 | lRoot.add(new Button("500 pixels"), "w 500px, wrap"); 34 | lRoot.add(new Button("10 centimeters"), "w 10cm, wrap"); 35 | lRoot.add(new Button("4 inches"), "w 4in, wrap"); 36 | lRoot.add(new Button("30% of screen"), "w 30sp, wrap"); 37 | lRoot.add(new Button("30% of container"), "w 30%, wrap"); 38 | 39 | // create scene 40 | Scene scene = new Scene(lRoot); 41 | 42 | // create stage 43 | stage.setTitle("Test - resize to check container percentage"); 44 | stage.setScene(scene); 45 | stage.sizeToScene(); 46 | stage.show(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /javafx/src/test/java/org/tbee/javafx/scene/layout/trial/MigPaneTest11.java: -------------------------------------------------------------------------------- 1 | package org.tbee.javafx.scene.layout.trial; 2 | 3 | import javafx.application.Application; 4 | import javafx.application.Platform; 5 | import javafx.collections.FXCollections; 6 | import javafx.collections.ObservableList; 7 | import javafx.event.ActionEvent; 8 | import javafx.event.EventHandler; 9 | import javafx.scene.Parent; 10 | import javafx.scene.Scene; 11 | import javafx.scene.control.*; 12 | import javafx.scene.layout.BorderPane; 13 | import javafx.scene.layout.HBox; 14 | import javafx.scene.layout.VBox; 15 | import javafx.stage.Stage; 16 | import org.tbee.javafx.scene.layout.fxml.MigPane; 17 | 18 | import java.util.Date; 19 | 20 | /** 21 | * This test is ran out of memory because of a memory leak. 22 | * 23 | */ 24 | public class MigPaneTest11 extends Application 25 | { 26 | 27 | public static class ListElement extends MigPane 28 | { 29 | 30 | public ListElement(int i, Date date) 31 | { 32 | Label title = new Label("Element " + i); 33 | Label info = new Label("element created at: " + date); 34 | 35 | getChildren(). 36 | add(new VBox(title, info)); 37 | 38 | Button b1 = new Button("button-1"); 39 | Button b2 = new Button("button-2"); 40 | Button b3 = new Button("button-3"); 41 | b1.setMnemonicParsing(false); 42 | b2.setMnemonicParsing(false); 43 | b3.setMnemonicParsing(false); 44 | 45 | getChildren(). 46 | add(new HBox(b1, b2, b3)); 47 | } 48 | 49 | } 50 | 51 | public MigPaneTest11() 52 | { 53 | super(); 54 | // this.items = FXCollections.observableArrayList(); 55 | } 56 | // private ObservableList items; 57 | 58 | private Parent createRoot() 59 | { 60 | 61 | final ListView listView = new ListView(); 62 | // listView.setItems(this.items); 63 | 64 | Button testButton = new Button("Start test"); 65 | testButton.maxWidth(Double.MAX_VALUE); 66 | 67 | testButton.setOnAction(new EventHandler() 68 | { 69 | public void handle(final ActionEvent ev) 70 | { 71 | final Thread t = new Thread() 72 | { 73 | @Override 74 | public void run() 75 | { 76 | for (int loop = 0; loop < Integer.MAX_VALUE; loop++) 77 | { 78 | System.out.println("loop " + loop); 79 | Platform.runLater(new Runnable() 80 | { 81 | public void run() 82 | { 83 | // for (ListElement le : items) 84 | // { 85 | // le.getChildren().clear(); 86 | // } 87 | // items.clear(); 88 | ObservableList items = FXCollections.observableArrayList(); 89 | for (int i = 0; i < 10; i++) 90 | { 91 | items.add(new ListElement(i, new Date())); 92 | } 93 | listView.setItems(items); 94 | } 95 | }); 96 | try 97 | { 98 | Thread.sleep(10); 99 | } 100 | catch (final InterruptedException e) 101 | { 102 | // do nothing 103 | } 104 | } 105 | System.out.println("done"); 106 | } 107 | 108 | }; 109 | t.setDaemon(true); 110 | t.start(); 111 | } 112 | }); 113 | 114 | BorderPane borderPane = new BorderPane(); 115 | borderPane.setCenter(listView); 116 | borderPane.setBottom(testButton); 117 | return borderPane; 118 | } 119 | 120 | @Override 121 | public void start(Stage stage) throws Exception 122 | { 123 | Parent root = createRoot(); 124 | 125 | scene = new Scene(root); 126 | stage.setScene(scene); 127 | stage.setWidth(800); 128 | stage.setHeight(600); 129 | stage.show(); 130 | } 131 | static Scene scene = null; 132 | 133 | public static void main(String[] args) 134 | { 135 | launch(args); 136 | } 137 | 138 | } 139 | -------------------------------------------------------------------------------- /javafx/src/test/java/org/tbee/javafx/scene/layout/trial/MigPaneTest14.java: -------------------------------------------------------------------------------- 1 | package org.tbee.javafx.scene.layout.trial; 2 | 3 | import javafx.application.Application; 4 | import javafx.scene.Scene; 5 | import javafx.scene.control.TextField; 6 | import javafx.scene.paint.Color; 7 | import javafx.scene.shape.Rectangle; 8 | import javafx.stage.Stage; 9 | import net.miginfocom.layout.AC; 10 | import net.miginfocom.layout.CC; 11 | import net.miginfocom.layout.LC; 12 | import org.tbee.javafx.scene.layout.MigPane; 13 | 14 | /** 15 | * Test miglayout managed and unmanaged nodes 16 | * @author Tom Eugelink 17 | * 18 | */ 19 | public class MigPaneTest14 extends Application { 20 | 21 | public static void main(String[] args) { 22 | launch(args); 23 | } 24 | 25 | @Override 26 | public void start(Stage stage) { 27 | 28 | // root 29 | MigPane lRoot = new MigPane(new LC().debug(1000), new AC(), new AC()); 30 | 31 | // add managed nodes 32 | lRoot.add(new TextField(), new CC()); 33 | lRoot.add(new Rectangle(30,30, Color.YELLOW), new CC()); 34 | 35 | // add unmanaged (not external..) nodes 36 | Rectangle rectangle = new Rectangle(100, 50, 30, 30); // should not affect bounds or preferred size of MigPane 37 | rectangle.setManaged(false); 38 | lRoot.add(rectangle); 39 | 40 | // create scene 41 | Scene scene = new Scene(lRoot, -1, -1); 42 | 43 | // create stage 44 | stage.setTitle("Test"); 45 | stage.setScene(scene); 46 | stage.sizeToScene(); 47 | stage.show(); 48 | } 49 | 50 | } -------------------------------------------------------------------------------- /javafx/src/test/java/org/tbee/javafx/scene/layout/trial/MigPaneTest15.java: -------------------------------------------------------------------------------- 1 | package org.tbee.javafx.scene.layout.trial; 2 | 3 | import javafx.application.Application; 4 | import javafx.event.ActionEvent; 5 | import javafx.event.EventHandler; 6 | import javafx.scene.Scene; 7 | import javafx.scene.control.Button; 8 | import javafx.scene.control.ComboBox; 9 | import javafx.scene.control.Label; 10 | import javafx.stage.Stage; 11 | import org.tbee.javafx.scene.layout.MigPane; 12 | 13 | public class MigPaneTest15 extends Application { 14 | 15 | public static void main(String[] arguments) { 16 | launch(); 17 | } 18 | 19 | @Override 20 | public void start(Stage stage) throws Exception { 21 | Scene scene = createScene(); 22 | stage.setScene(scene); 23 | showStage(stage); 24 | } 25 | 26 | private Scene createScene() { 27 | final MigPane container = new MigPane(); 28 | Button control = new Button("Add Content"); 29 | control.setOnAction(new EventHandler() { 30 | @Override 31 | public void handle(ActionEvent actionEvent) { 32 | showContent(container); 33 | } 34 | }); 35 | 36 | MigPane parent = new MigPane(""); 37 | parent.add(control); 38 | parent.add(container); 39 | return new Scene(parent); 40 | } 41 | 42 | private void showContent(MigPane container) { 43 | container.getChildren().clear(); 44 | ComboBox comboBox = new ComboBox<>(); 45 | comboBox.getItems().add("There is a label to my left!"); 46 | Label label = new Label("I should be visible!"); 47 | container.add(label); 48 | container.add(comboBox); 49 | } 50 | 51 | 52 | private void showStage(Stage stage) { 53 | stage.setHeight(400); 54 | stage.setWidth(800); 55 | stage.show(); 56 | } 57 | } -------------------------------------------------------------------------------- /javafx/src/test/java/org/tbee/javafx/scene/layout/trial/MigPaneTest3.java: -------------------------------------------------------------------------------- 1 | package org.tbee.javafx.scene.layout.trial; 2 | 3 | import javafx.application.Application; 4 | import javafx.collections.FXCollections; 5 | import javafx.scene.Scene; 6 | import javafx.scene.control.*; 7 | import javafx.stage.Stage; 8 | import net.miginfocom.layout.AC; 9 | import net.miginfocom.layout.CC; 10 | import net.miginfocom.layout.LC; 11 | import org.tbee.javafx.scene.layout.MigPane; 12 | 13 | /** 14 | * Testing if grow and push actually grow stuff 15 | * @author Tom Eugelink 16 | * 17 | */ 18 | public class MigPaneTest3 extends Application { 19 | 20 | public static void main(String[] args) { 21 | launch(args); 22 | } 23 | 24 | @Override 25 | public void start(Stage stage) { 26 | 27 | // root 28 | MigPane lRoot = new MigPane(new LC().debug(1000), new AC(), new AC()); 29 | 30 | // create 10 buttons 31 | for (int i = 0; i < 5*3; i++) 32 | { 33 | int lRow = (int)(i / 3); 34 | int lCol = (i + 1) % 3; 35 | String lText = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX".substring(0, i + 1); 36 | 37 | // add a node 38 | Control lControl = null; 39 | if ( lRow == 0) lControl = new CheckBox(lText); 40 | else if ( lRow == 1) { lControl = new TextField(); ((TextField)lControl).setText(lText); } 41 | else if ( lRow == 2) { lControl = new ChoiceBox(FXCollections.observableArrayList("X", lText, "XX")); ((ChoiceBox)lControl).getSelectionModel().select(1); } 42 | else if ( lRow == 3) { lControl = new ToggleButton(lText); } 43 | else lControl = new Button(lText); // wrong 44 | 45 | CC lCC = new CC(); 46 | if (lCol == 2) lCC = lCC.grow().push(); 47 | if (lCol == 0) lCC = lCC.wrap(); 48 | lRoot.add(lControl, lCC); 49 | } 50 | 51 | // create scene 52 | Scene scene = new Scene(lRoot, -1, -1); 53 | 54 | // create stage 55 | stage.setTitle("Test"); 56 | stage.setScene(scene); 57 | stage.sizeToScene(); 58 | stage.show(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /javafx/src/test/java/org/tbee/javafx/scene/layout/trial/MigPaneTest5.java: -------------------------------------------------------------------------------- 1 | package org.tbee.javafx.scene.layout.trial; 2 | 3 | import javafx.application.Application; 4 | import javafx.scene.Scene; 5 | import javafx.scene.control.TextField; 6 | import javafx.scene.shape.Rectangle; 7 | import javafx.stage.Stage; 8 | import net.miginfocom.layout.CC; 9 | import org.tbee.javafx.scene.layout.MigPane; 10 | 11 | /** 12 | * Using string constraints 13 | * @author Tom Eugelink 14 | * 15 | */ 16 | public class MigPaneTest5 extends Application { 17 | 18 | public static void main(String[] args) { 19 | launch(args); 20 | } 21 | 22 | @Override 23 | public void start(Stage stage) { 24 | 25 | // root 26 | MigPane lRoot = new MigPane("debug", "[grow,fill]", ""); 27 | 28 | // add managed nodes 29 | lRoot.add(new TextField(), ""); 30 | 31 | // add external (not unmanaged..) nodes 32 | lRoot.add(new Rectangle(100, 50, 30, 30), new CC().external()); 33 | 34 | // create scene 35 | Scene scene = new Scene(lRoot, -1, -1); 36 | 37 | // create stage 38 | stage.setTitle("Test"); 39 | stage.setScene(scene); 40 | stage.sizeToScene(); 41 | stage.show(); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /javafx/src/test/java/org/tbee/javafx/scene/layout/trial/MigPaneTest8.java: -------------------------------------------------------------------------------- 1 | package org.tbee.javafx.scene.layout.trial; 2 | 3 | import javafx.application.Application; 4 | import javafx.fxml.FXMLLoader; 5 | import javafx.scene.Scene; 6 | import javafx.stage.Stage; 7 | import org.tbee.javafx.scene.layout.MigPane; 8 | 9 | import java.io.IOException; 10 | import java.net.URL; 11 | 12 | /** 13 | * Load a layout from FXML 14 | * 15 | * @author Michael Paus and Tom Eugelink 16 | * 17 | */ 18 | public class MigPaneTest8 extends Application { 19 | 20 | public static void main(String[] args) { 21 | launch(args); 22 | } 23 | 24 | @Override 25 | public void start(Stage stage) 26 | throws IOException 27 | { 28 | // load FXML 29 | String lName = getClass().getSimpleName() + ".xml"; 30 | URL lURL = getClass().getResource("/" + lName); 31 | System.out.println("loading FXML " + lName + " -> " + lURL); 32 | MigPane lRoot = (MigPane)FXMLLoader.load(lURL); 33 | 34 | // create scene 35 | Scene scene = new Scene(lRoot, 800, 300); 36 | 37 | // create stage 38 | stage.setTitle(this.getClass().getSimpleName()); 39 | stage.setScene(scene); 40 | stage.show(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /javafx/src/test/java/org/tbee/javafx/scene/layout/trial/MigPaneTest8Controller.java: -------------------------------------------------------------------------------- 1 | package org.tbee.javafx.scene.layout.trial; 2 | 3 | import javafx.event.ActionEvent; 4 | import javafx.fxml.FXML; 5 | import javafx.scene.control.Label; 6 | import javafx.scene.control.TextField; 7 | import org.tbee.javafx.scene.layout.MigPane; 8 | 9 | /** 10 | * Handler class for the FXML 11 | * 12 | * @author Michael Paus 13 | * @author Tom Eugelink 14 | * 15 | */ 16 | public class MigPaneTest8Controller extends MigPane 17 | { 18 | @FXML private TextField firstNameField; 19 | @FXML private TextField lastNameField; 20 | @FXML private Label messageLabel; 21 | 22 | @SuppressWarnings("unused") 23 | @FXML private void handleButtonAction(ActionEvent event) 24 | { 25 | String fullName = firstNameField.getText() + " " + lastNameField.getText(); 26 | if (fullName.length() > 1) 27 | { 28 | messageLabel.setText("Your name '" + fullName + "' was successfully entered into our spam database :-("); 29 | } 30 | else 31 | { 32 | messageLabel.setText("Sorry, but you have to provide your name!"); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /javafx/src/test/java/org/tbee/javafx/scene/layout/trial/MigPaneTest9.java: -------------------------------------------------------------------------------- 1 | package org.tbee.javafx.scene.layout.trial; 2 | 3 | import javafx.application.Application; 4 | import javafx.scene.Group; 5 | import javafx.scene.Scene; 6 | import javafx.scene.control.ButtonBase; 7 | import javafx.scene.control.ToggleButton; 8 | import javafx.scene.layout.StackPane; 9 | import javafx.stage.Stage; 10 | import net.miginfocom.layout.AC; 11 | import net.miginfocom.layout.CC; 12 | import net.miginfocom.layout.LC; 13 | import org.tbee.javafx.scene.layout.MigPane; 14 | 15 | /** 16 | * Wrap MigPane in a number of other containers and set a padding. 17 | * 18 | * @author Tom Eugelink 19 | * 20 | */ 21 | public class MigPaneTest9 extends Application { 22 | 23 | public static void main(String[] args) { 24 | launch(args); 25 | } 26 | 27 | @Override 28 | public void start(Stage stage) { 29 | 30 | // root 31 | MigPane lMigPane = new MigPane(new LC().debug(1000).align("center", "center").gridGap("0px", "0px"), new AC(), new AC()); 32 | for (int i = 0; i < 9; i++) 33 | { 34 | CC lCC = new CC(); 35 | if ((i + 1) % 3 == 0) 36 | { 37 | lCC = lCC.wrap(); 38 | } 39 | final ButtonBase btn = new ToggleButton("MMMMMMMMMMMMMMMMMMMMMMMMMMMM".substring(0, i + 1)); 40 | if (i == 0) 41 | { 42 | btn.setStyle("-fx-padding: 10; "); 43 | } 44 | lMigPane.add(btn, lCC); 45 | } 46 | 47 | // include in stackpane and set a padding 48 | StackPane lStackPane = new StackPane(); 49 | lStackPane.getChildren().add(lMigPane); 50 | lStackPane.setStyle("-fx-background-color: yellow; -fx-padding: 10; "); 51 | 52 | // create scene 53 | Scene scene = new Scene(new Group(lStackPane), -1, -1); 54 | 55 | // create stage 56 | stage.setTitle("ButtonTest"); 57 | stage.setScene(scene); 58 | stage.sizeToScene(); 59 | stage.show(); 60 | } 61 | } -------------------------------------------------------------------------------- /javafx/src/test/java/org/tbee/javafx/scene/layout/trial/MigPaneTrial1.java: -------------------------------------------------------------------------------- 1 | package org.tbee.javafx.scene.layout.trial; 2 | 3 | import javafx.application.Application; 4 | import javafx.scene.Scene; 5 | import javafx.scene.control.Label; 6 | import javafx.scene.control.Button; 7 | import javafx.stage.Stage; 8 | import net.miginfocom.layout.CC; 9 | import net.miginfocom.layout.LC; 10 | import org.tbee.javafx.scene.layout.MigPane; 11 | 12 | public class MigPaneTrial1 extends Application { 13 | 14 | public static void main(String[] args) { 15 | launch(args); 16 | } 17 | 18 | @Override 19 | public void start(Stage stage) throws Exception { 20 | MigPane migPane = new MigPane(new LC()); 21 | migPane.add(new Label("Label"), new CC().wrap()); 22 | migPane.add(new Label("Label"), new CC().wrap().push().grow()); 23 | migPane.add(new Label("Label"), new CC().wrap()); 24 | Button button = new Button("Button"); 25 | // migPane.add(button, new CC().dockWest().grow()); 26 | migPane.add(button, new CC().wrap().grow().push()); 27 | button.setRotate(90); 28 | Scene scene = new Scene(migPane); 29 | stage.setScene(scene); 30 | stage.show(); 31 | } 32 | } -------------------------------------------------------------------------------- /javafx/src/test/java/org/tbee/javafx/scene/layout/trial/MigPaneTrial16.java: -------------------------------------------------------------------------------- 1 | package org.tbee.javafx.scene.layout.trial; 2 | 3 | import javafx.application.Application; 4 | import javafx.event.ActionEvent; 5 | import javafx.event.EventHandler; 6 | import javafx.scene.Scene; 7 | import javafx.scene.control.Button; 8 | import javafx.scene.control.ButtonBase; 9 | import javafx.scene.control.Label; 10 | import javafx.scene.image.Image; 11 | import javafx.scene.image.ImageView; 12 | import javafx.stage.Stage; 13 | import net.miginfocom.layout.CC; 14 | import net.miginfocom.layout.LC; 15 | import org.tbee.javafx.scene.layout.MigPane; 16 | 17 | public class MigPaneTrial16 extends Application 18 | { 19 | public static final String PATH_TO_IMAGE = "/MigPaneTrial16.png"; 20 | 21 | public static void main(String[] arguments) { 22 | // URL url = new MigPaneTrial16().getClass().getResource(PATH_TO_IMAGE); 23 | // System.out.println(url); 24 | launch(); 25 | } 26 | 27 | 28 | @Override 29 | public void start(Stage stage) throws Exception { 30 | Scene scene = createScene(); 31 | stage.setScene(scene); 32 | stage.sizeToScene(); 33 | stage.show(); 34 | } 35 | 36 | private Scene createScene() { 37 | MigPane parent = new MigPane(new LC().debug(300)); 38 | addRowTo(parent); 39 | return new Scene(parent, 300, 100); 40 | } 41 | 42 | boolean b = true; 43 | private void addRowTo(MigPane parent) { 44 | ImageView mainIcon = new ImageView(); 45 | Button toggle = new Button("Hello", mainIcon); 46 | sizeUpButton(toggle); 47 | 48 | toggle.setOnAction(new EventHandler() { 49 | public void handle(ActionEvent event) 50 | { 51 | if (b) { 52 | mainIcon.setImage(new Image(PATH_TO_IMAGE)); 53 | // toggle.getBaselineOffset(); 54 | System.out.println("baseline img: " + toggle.getBaselineOffset()); 55 | } else { 56 | mainIcon.setImage(null); 57 | System.out.println("baseline: " + toggle.getBaselineOffset()); 58 | } 59 | b = !b; 60 | } 61 | }); 62 | parent.add(toggle, ""); 63 | parent.add(new Label("<-Click the Button"), new CC().growX().pushX()); 64 | } 65 | 66 | private void sizeUpButton(ButtonBase button) { 67 | // button.setMinSize(20, 20); 68 | // button.setPrefSize(20, 20); 69 | // button.setMaxSize(20, 20); 70 | } 71 | } -------------------------------------------------------------------------------- /javafx/src/test/java/org/tbee/javafx/scene/layout/trial/MigPaneTrial17.java: -------------------------------------------------------------------------------- 1 | package org.tbee.javafx.scene.layout.trial; 2 | 3 | import javafx.application.Application; 4 | import javafx.scene.Scene; 5 | import javafx.scene.control.Button; 6 | import javafx.stage.Stage; 7 | import net.miginfocom.layout.LC; 8 | import org.tbee.javafx.scene.layout.MigPane; 9 | 10 | public class MigPaneTrial17 extends Application { 11 | 12 | public static void main(String[] args) { 13 | launch(args); 14 | } 15 | 16 | @Override 17 | public void start(Stage stage) throws Exception { 18 | MigPane migPane = new MigPane(new LC().wrapAfter(1)); 19 | migPane.getChildren().add(0, new Button("Test")); 20 | Scene scene = new Scene(migPane); 21 | stage.setScene(scene); 22 | stage.show(); 23 | } 24 | } -------------------------------------------------------------------------------- /javafx/src/test/java/org/tbee/javafx/scene/layout/trial/MigTestTest10.java: -------------------------------------------------------------------------------- 1 | package org.tbee.javafx.scene.layout.trial; 2 | 3 | import javafx.application.Application; 4 | import javafx.scene.Scene; 5 | import javafx.scene.control.Button; 6 | import javafx.scene.paint.Color; 7 | import javafx.stage.Stage; 8 | import org.tbee.javafx.scene.layout.MigPane; 9 | 10 | /** 11 | * Test a nested MigPane 12 | * 13 | */ 14 | public class MigTestTest10 extends Application { 15 | 16 | public static void main(String[] args) { 17 | launch(args); 18 | } 19 | 20 | @Override 21 | public void start(final Stage stage) throws InterruptedException { 22 | 23 | MigPane lOuterMigPane = new MigPane("debug"); 24 | lOuterMigPane.setId("outer"); 25 | lOuterMigPane.setDebugCellColor(null); 26 | lOuterMigPane.setDebugOutlineColor(Color.BLUE); 27 | lOuterMigPane.setDebugContainerOutlineColor(Color.BLUE); 28 | lOuterMigPane.add(new Button("In outer MigPane")); 29 | 30 | MigPane lNestedMigPane = new MigPane("debug"); 31 | lNestedMigPane.setId("nested"); 32 | lNestedMigPane.setDebugCellColor(null); 33 | lNestedMigPane.setDebugOutlineColor(Color.RED); 34 | lNestedMigPane.setDebugContainerOutlineColor(Color.RED); 35 | lNestedMigPane.add(new Button("In nested MigPane")); 36 | lOuterMigPane.add(lNestedMigPane); 37 | 38 | Scene scene = new Scene(lOuterMigPane); 39 | stage.setScene(scene); 40 | stage.sizeToScene(); 41 | stage.show(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /javafx/src/test/resources/MigPaneTest8.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |