Continue your JavaFX Components learning via this tutorial.
Example 1: Layout
Here are the code:
Step 1: Create Project
- Open your favorite Java IDE.
- In the menu go to
File --> Create New Project
.
Step 2: Dependencies
No dependencies are needed for this project.
Step 3: Write Code
Our code will comprise the following java files:
AutoResponsiveLayout.java
AutoResponsiveLayoutExample.java
- In your editor or IDE, create a file known as
AutoResponsiveLayout.java
. - Then add the following code:
(a). AutoResponsiveLayout.java
Go ahead and add the following imports:
import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList;
import javafx.geometry.Bounds;
import javafx.scene.Node;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Region;
Go ahead and add the following imports:
import java.util.ArrayList;
import java.util.List;
Create our class
as shown below:
public class AutoResponsiveLayout {
Our class
will have the following methods:
void initRows()
void resetRows()
void assignWidgetsToRows()
void calculateTotalChildMinWidth()
void calculateAverageRowWidthBasedOnMinWidths()
void clear()
void addWidget(Region child)
void addWidget(Region child, WidgetLayoutInfo layoutInfo)
protected void layoutPane()
void adjustPaneToParentScrollPaneOrMinUsedRowsHeight()
void transferMinWidthsAndHeightsToWidths()
void pullUpWidgets(ObservableList<Node> children, List<WidgetLayoutInfo> widgetLayoutInfos)
void expandWidgetWidthsToFitRow(double newWidth, ObservableList<Node> children)
void expandRowHeights()
void printWidgetRows(ObservableList<Node> children)
void assignChildrenToRowNumbersAccordingToMinWidths()
void assignChildrenToRowsUsingAverageRowWidth()
void positionAndSizeChildren(ObservableList<Node> children, List<WidgetLayoutInfo> widgetLayoutInfos)
Here is the full code:
package com.jenkov.javafx.layout;
import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList;
import javafx.geometry.Bounds;
import javafx.scene.Node;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Region;
import java.util.ArrayList;
import java.util.List;
/**
* An example of how to implement your own layout of controls contained inside a Pane. The JavaFX Pane class does not
* do any layout of its children. The Pane shows the children where the children wants to be layed out themselves.
* Thus, by changing layout position of the children of a Pane you can change it's layout.
*
* Future potential improvements:
* - Remodel the code so it more clearly shows the algorithm - even though it may slow the algorithm down a bit.
* - Max widths on widgets
* - Vertical stacking of widgets
* - Confine widgets to fixed row number
*
*/
public class AutoResponsiveLayout {
public static class WidgetLayoutInfo {
public double x = 0.0D;
public double y = 0.0D;
public double minWidth = 0.0D;
public double width = 0.0D;
public double minHeight = 0.0D;
public double height = 0.0D;
public int rowNo = 0;
}
public static class RowLayoutInfo {
public int rowNo = 0;
public double rowWidth = 0.0D;
public List<WidgetLayoutInfo> widgets = new ArrayList<>();
}
public static class PaneLayoutInfo {
public List<WidgetLayoutInfo> widgetLayoutInfos = new ArrayList<>();
public List<RowLayoutInfo> rowLayoutInfos = new ArrayList<>();
public int noOfRows = 0;
public double maxRowWidth = 0.0D;
public double totalChildWidth = 0.0D; //width of all children if placed on a single row
public double avgRowWidth = 0.0D; // total child width divided by number of rows.
public double visibleHeight = 0.0D; // The height visible within the parent ScrollPane
public void initRows() {
for(int i = this.rowLayoutInfos.size(); i <= noOfRows; i++) {
RowLayoutInfo rowLayoutInfo = new RowLayoutInfo();
rowLayoutInfo.rowNo = i;
this.rowLayoutInfos.add(rowLayoutInfo);
}
}
public void resetRows() {
for(int i=0; i<this.rowLayoutInfos.size(); i++) {
RowLayoutInfo rowLayoutInfo = this.rowLayoutInfos.get(i);
rowLayoutInfo.widgets.clear();
}
}
public void assignWidgetsToRows() {
resetRows();
for(int i=0; i<widgetLayoutInfos.size(); i++) {
WidgetLayoutInfo widgetLayoutInfo = widgetLayoutInfos.get(i);
RowLayoutInfo rowLayoutInfo = rowLayoutInfos.get(widgetLayoutInfo.rowNo);
rowLayoutInfo.widgets.add(widgetLayoutInfo);
}
}
public int determineRowCountFromWidgetLayoutInfos() {
this.noOfRows = getLastWidgetLayoutInfo(this.widgetLayoutInfos).rowNo + 1; // row numbers are 0-based (first row has index 0)
return this.noOfRows;
}
private WidgetLayoutInfo getLastWidgetLayoutInfo(List<WidgetLayoutInfo> widgetLayoutInfos) {
return widgetLayoutInfos.get(widgetLayoutInfos.size()-1);
}
public void calculateTotalChildMinWidth(){
this.totalChildWidth = 0.0D;
for(int i=0; i<this.widgetLayoutInfos.size(); i++) {
WidgetLayoutInfo widgetLayoutInfo = this.widgetLayoutInfos.get(i);
double childWidth = widgetLayoutInfo.minWidth;
this.totalChildWidth += childWidth;
}
}
public void calculateAverageRowWidthBasedOnMinWidths() {
this.avgRowWidth = this.totalChildWidth / this.noOfRows;
}
private double calcMinimumUsedRowHeights() {
int rowEndIndex = 0;
double minimumUsedRowHeights = 0.0D;
for(int rowNo = 0; rowNo < this.noOfRows; rowNo++){
double highestWidgetsOnRow = 0.0D;
while(rowEndIndex < this.widgetLayoutInfos.size() && rowNo == this.widgetLayoutInfos.get(rowEndIndex).rowNo) {
WidgetLayoutInfo widgetLayoutInfo = this.widgetLayoutInfos.get(rowEndIndex);
highestWidgetsOnRow = Math.max(highestWidgetsOnRow, widgetLayoutInfo.minHeight);
rowEndIndex++;
}
minimumUsedRowHeights += highestWidgetsOnRow;
}
return minimumUsedRowHeights;
}
}
// Feature flags. All features should be enabled for a fully automatic responsive layout
protected boolean balanceRows = true;
protected boolean pullUpChildren = true;
protected boolean extendChildWidth = true;
protected boolean extendChildHeight = true;
PaneLayoutInfo paneLayoutInfo = new PaneLayoutInfo();
private Pane targetPane = null;
private ScrollPane targetParentPane = null;
public AutoResponsiveLayout(Pane pane, ScrollPane parent) {
this.targetPane = pane;
this.targetParentPane = parent;
this.targetPane.widthProperty().addListener((ObservableValue<? extends Number> property, Number oldValue, Number newValue) -> {
this.paneLayoutInfo.maxRowWidth = newValue.doubleValue();
layoutPane();
});
parent.viewportBoundsProperty().addListener((ObservableValue<? extends Bounds> property, Bounds oldValue, Bounds newValue) -> {
this.paneLayoutInfo.visibleHeight = newValue.getHeight();
layoutPane();
});
}
public void clear() {
//this.paneLayoutInfo.resetRows();
this.paneLayoutInfo.widgetLayoutInfos.clear();
this.targetPane.getChildren().clear();
}
public void addWidget(Region child) {
WidgetLayoutInfo widgetLayoutInfo = new WidgetLayoutInfo();
widgetLayoutInfo.x = 0.0D;
widgetLayoutInfo.y = 0.0D;
widgetLayoutInfo.rowNo = 0;
widgetLayoutInfo.minWidth = child.getMinWidth();
widgetLayoutInfo.width = child.getMinWidth(); //start with min width as width
widgetLayoutInfo.minHeight= child.getMinHeight();
widgetLayoutInfo.height = child.getMinWidth();
addWidget(child, widgetLayoutInfo);
}
public void addWidget(Region child, WidgetLayoutInfo layoutInfo) {
this.targetPane.getChildren().add(child);
this.paneLayoutInfo.widgetLayoutInfos.add(layoutInfo);
}
protected void layoutPane() {
//System.out.println("============== BEGIN LAYOUT ===============");
ObservableList<Node> children = this.targetPane.getChildren();
if(children.size() == 0) {
return;
}
transferMinWidthsAndHeightsToWidths();
// Phase 1: Divide children into rows based on their minimum widths
assignChildrenToRowNumbersAccordingToMinWidths();
this.paneLayoutInfo.determineRowCountFromWidgetLayoutInfos();
//this.paneLayoutInfo.initRows();
//this.paneLayoutInfo.resetRows();
//this.paneLayoutInfo.assignWidgetsToRows();
adjustPaneToParentScrollPaneOrMinUsedRowsHeight();
// Phase 2.1: Now that number of rows is decided, calculate the average width of rows
paneLayoutInfo.calculateTotalChildMinWidth();
paneLayoutInfo.calculateAverageRowWidthBasedOnMinWidths();
// Phase 2.2: Assign children to rows based on average row width instead of max row width - for a more even distribution of children.
if(this.balanceRows) {
assignChildrenToRowsUsingAverageRowWidth();
}
// Phase 2.3 Pull up "dangling" widgets towards the top of the pane, so the grid looks more similar.
if(this.pullUpChildren) {
pullUpWidgets(children, this.paneLayoutInfo.widgetLayoutInfos);
}
// Phase 3: Expand widths of children to match row width
if(this.extendChildWidth) {
expandWidgetWidthsToFitRow(this.paneLayoutInfo.maxRowWidth, children);
}
// Phase 4: Expand heights of children to match highest child per row
if(this.extendChildHeight) {
expandRowHeights();
}
// Phase 5: Position children according to index and row
positionAndSizeChildren(children, this.paneLayoutInfo.widgetLayoutInfos);
}
private int determineRowCountFromWidgetLayoutInfos() {
return getLastWidgetLayoutInfo(this.paneLayoutInfo.widgetLayoutInfos).rowNo + 1; // row numbers are 0-based (first row has index 0)
}
private void adjustPaneToParentScrollPaneOrMinUsedRowsHeight() {
double minimumUsedRowHeights = this.paneLayoutInfo.calcMinimumUsedRowHeights();
double newHeight = Math.max(this.paneLayoutInfo.visibleHeight, minimumUsedRowHeights);
this.targetPane.setMinHeight(newHeight);
this.targetPane.setPrefHeight(newHeight);
this.targetPane.setMaxHeight(newHeight);
}
private void transferMinWidthsAndHeightsToWidths() {
for(int i=0; i<this.paneLayoutInfo.widgetLayoutInfos.size(); i++){
WidgetLayoutInfo widgetLayoutInfo = this.paneLayoutInfo.widgetLayoutInfos.get(i);
widgetLayoutInfo.width = widgetLayoutInfo.minWidth;
widgetLayoutInfo.height = widgetLayoutInfo.minHeight;
}
}
private void pullUpWidgets(ObservableList<Node> children, List<WidgetLayoutInfo> widgetLayoutInfos) {
int childrenPulledUpThisIteration = 0;
do{
childrenPulledUpThisIteration = 0;
//System.out.println("===== Pull up round =====");
double prevRowWidth = Double.MAX_VALUE;
double thisRowWidth = 0.0D;
int thisRowNo = 0;
//Node firstChildOnRow = children.get(0);
WidgetLayoutInfo firstChildOnRowWidgetLayoutInfo = widgetLayoutInfos.get(0);
for(int i = 0; i < children.size(); i++) {
WidgetLayoutInfo widgetLayoutInfo = widgetLayoutInfos.get(i);
if(thisRowNo == widgetLayoutInfo.rowNo) {
thisRowWidth += widgetLayoutInfo.minWidth;
} else {
double rowDiff = thisRowWidth - prevRowWidth;
//if(rowDiff >= firstChildOnRow.getLayoutBounds().getWidth()) {
if(rowDiff >= firstChildOnRowWidgetLayoutInfo.minWidth) {
//System.out.println("Move child " + i + " up to previous row");
firstChildOnRowWidgetLayoutInfo.rowNo--; //move first widget of this row up to previous row
childrenPulledUpThisIteration++;
} else {
//System.out.println("Row diff for row " + thisRowNo);
}
//firstChildOnRow = child;
firstChildOnRowWidgetLayoutInfo = widgetLayoutInfo;
prevRowWidth = thisRowWidth;
//thisRowWidth = child.getLayoutBounds().getWidth();
thisRowWidth = widgetLayoutInfo.minWidth;
thisRowNo++;
}
}
} while (childrenPulledUpThisIteration > 0);
}
private void expandWidgetWidthsToFitRow(double newWidth, ObservableList<Node> children) {
double usedRowWidth = 0.0D;
int rowStartIndex = 0;
int rowEndIndex = 0;
for(int rowNo = 0; rowNo < paneLayoutInfo.noOfRows; rowNo++){
while(rowEndIndex < this.paneLayoutInfo.widgetLayoutInfos.size() && rowNo == this.paneLayoutInfo.widgetLayoutInfos.get(rowEndIndex).rowNo){
rowEndIndex++;
}
for(int i=rowStartIndex; i<rowEndIndex; i++) {
//Node node = children.get(i);
//usedRowWidth += node.getLayoutBounds().getWidth();
WidgetLayoutInfo widgetLayoutInfo = this.paneLayoutInfo.widgetLayoutInfos.get(i);
usedRowWidth += widgetLayoutInfo.minWidth;
}
//System.out.println(" Max Row Width : " + newWidth + "(" + paneLayoutInfo.maxRowWidth + ")");
//System.out.println(" Used Row width: " + usedRowWidth);
double unusedRowWidth = paneLayoutInfo.maxRowWidth - usedRowWidth;
//System.out.println(" Unused row width: " + unusedRowWidth);
for(int i=rowStartIndex; i<rowEndIndex; i++) {
Node node = children.get(i);
WidgetLayoutInfo widgetLayoutInfo = this.paneLayoutInfo.widgetLayoutInfos.get(i);
double childWidth = widgetLayoutInfo.minWidth;
double childToRowRatio = childWidth / usedRowWidth;
double childWidthExtension = unusedRowWidth * childToRowRatio;
double childWidthExtended = childWidth + childWidthExtension;
//System.out.println(" Child Width Extension: " + childWidthExtension);
//System.out.println(" Child Width Extended : " + childWidthExtended);
widgetLayoutInfo.width = childWidthExtended;
//((Region) node).setMinWidth(childWidthExtended);
//((Region) node).setPrefWidth(childWidthExtended);
}
usedRowWidth = 0.0D;
rowStartIndex = rowEndIndex;
}
}
private void expandRowHeights() {
double minimumUsedRowHeights = this.paneLayoutInfo.calcMinimumUsedRowHeights();
double unusedHeight = 0.0D;
//if(this.paneLayoutInfo.visibleHeight > this.targetPane.getHeight()) {
if(this.paneLayoutInfo.visibleHeight > minimumUsedRowHeights) {
//unusedHeight = Math.max(0, this.targetPane.getHeight() - minimumUsedRowHeights);
unusedHeight = Math.max(0, this.paneLayoutInfo.visibleHeight - minimumUsedRowHeights);
}
//if minimumUsedRowHeights is larger than available height - do NOT use a negative unusedHeight - but use 0.
//System.out.println("Pane height : " + this.targetPane.getHeight());
//System.out.println("Visible height : " + this.paneLayoutInfo.visibleHeight);
//System.out.println("Minimum rows height: " + minimumUsedRowHeights);
//System.out.println("Unused height : " + unusedHeight);
int rowStartIndex = 0;
int rowEndIndex = 0;
for(int rowNo = 0; rowNo < paneLayoutInfo.noOfRows; rowNo++){
rowStartIndex = rowEndIndex;
double highestWidgetsOnRow = 0.0D;
while(rowEndIndex < this.paneLayoutInfo.widgetLayoutInfos.size() && rowNo == this.paneLayoutInfo.widgetLayoutInfos.get(rowEndIndex).rowNo) {
WidgetLayoutInfo widgetLayoutInfo = this.paneLayoutInfo.widgetLayoutInfos.get(rowEndIndex);
highestWidgetsOnRow = Math.max(highestWidgetsOnRow, widgetLayoutInfo.height);
rowEndIndex++;
}
double rowRatio = highestWidgetsOnRow / minimumUsedRowHeights;
double rowExtension = rowRatio * unusedHeight;
double expandedHeight = highestWidgetsOnRow + rowExtension;
//System.out.println("Row Height : " + highestWidgetsOnRow);
//System.out.println("Unused height : " + unusedHeight);
//System.out.println("Expanded height: " + expandedHeight);
rowEndIndex = rowStartIndex;
while(rowEndIndex < this.paneLayoutInfo.widgetLayoutInfos.size() && rowNo == this.paneLayoutInfo.widgetLayoutInfos.get(rowEndIndex).rowNo) {
WidgetLayoutInfo widgetLayoutInfo = this.paneLayoutInfo.widgetLayoutInfos.get(rowEndIndex);
widgetLayoutInfo.height = expandedHeight;
rowEndIndex++;
}
}
}
private void printWidgetRows(ObservableList<Node> children) {
System.out.println("=== Widget Row Nos ===");
for(int i = 0; i< children.size(); i++) {
WidgetLayoutInfo widgetLayoutInfo = this.paneLayoutInfo.widgetLayoutInfos.get(i);
System.out.println("Widget " + i + " has row " + widgetLayoutInfo.rowNo);
}
}
private WidgetLayoutInfo getLastWidgetLayoutInfo(List<WidgetLayoutInfo> widgetLayoutInfos) {
return widgetLayoutInfos.get(widgetLayoutInfos.size()-1);
}
private void assignChildrenToRowNumbersAccordingToMinWidths() {
ObservableList<Node> children = targetPane.getChildren();
double maxRowWidth = paneLayoutInfo.maxRowWidth;
double widgetsOnRowWidth = 0.0D;
int rowNo = 0;
for(int i = 0; i < children.size(); i++) {
WidgetLayoutInfo widgetLayoutInfo = this.paneLayoutInfo.widgetLayoutInfos.get(i);
double childWidth = widgetLayoutInfo.minWidth;
widgetsOnRowWidth += childWidth;
if(widgetsOnRowWidth > maxRowWidth && i>0) {
rowNo++;
widgetsOnRowWidth = childWidth;
}
widgetLayoutInfo.rowNo = rowNo;
}
}
private void assignChildrenToRowsUsingAverageRowWidth() {
//System.out.println("Avg. row width: " + avgRowWidth);
double avgRowWidth = paneLayoutInfo.avgRowWidth;
double maxRowWidth = paneLayoutInfo.maxRowWidth;
double totalWidgetsWidthUsed = 0.0D;
double widgetWidthOnRowUsed = 0.0D;
int rowNo = 0;
for(int i = 0; i < this.paneLayoutInfo.widgetLayoutInfos.size(); i++) {
WidgetLayoutInfo widgetLayoutInfo = this.paneLayoutInfo.widgetLayoutInfos.get(i);
double childWidth = widgetLayoutInfo.minWidth;
widgetWidthOnRowUsed += childWidth;
totalWidgetsWidthUsed += childWidth;
double avgRowWidthSum = avgRowWidth * ((double) (rowNo + 1) );
if(widgetWidthOnRowUsed > maxRowWidth){
// widget cannot fit within this row - push to next row.
widgetWidthOnRowUsed = childWidth;
rowNo++;
widgetLayoutInfo.rowNo = rowNo;
}
if(totalWidgetsWidthUsed >= avgRowWidthSum) {
// widget can fit within this row - but after this widget break to next row
widgetLayoutInfo.rowNo = rowNo;
rowNo++;
widgetWidthOnRowUsed = 0.0D;
} else {
widgetLayoutInfo.rowNo = rowNo;
}
}
}
private void positionAndSizeChildren(ObservableList<Node> children, List<WidgetLayoutInfo> widgetLayoutInfos) {
int rowNo = 0;
double x = 0.0D;
double y = 0.0D;
for(int i = 0; i< children.size(); i++) {
Region child = (Region) children.get(i);
WidgetLayoutInfo widgetLayoutInfo = widgetLayoutInfos.get(i);
if(rowNo != widgetLayoutInfo.rowNo) {
double highestWidgetOnRow = 0.0D;
System.out.print("Calculating height for row: " + rowNo);
for(int j=i-1; j>=0; j--) {
WidgetLayoutInfo widgetOnRow = widgetLayoutInfos.get(j);
if(widgetOnRow.rowNo != rowNo) { //reached previous row - skip loop now.
break;
}
//highestWidgetOnRow = Math.max(highestWidgetOnRow, widgetOnRow.minHeight);
highestWidgetOnRow = Math.max(highestWidgetOnRow, widgetOnRow.height);
}
System.out.println(" => " + highestWidgetOnRow);
rowNo = widgetLayoutInfo.rowNo;
x = 0.0D;
y += highestWidgetOnRow;
}
child.setLayoutX(x);
child.setLayoutY(y);
child.setPrefWidth(widgetLayoutInfo.width);
child.setPrefHeight(widgetLayoutInfo.height);
x += widgetLayoutInfo.width;
}
}
}
- Next create another file known as
AutoResponsiveLayoutExample.java
. - And add the following code:
(b). AutoResponsiveLayoutExample.java
We will start by adding some imports to this class:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.StrokeLineCap;
import javafx.scene.shape.StrokeLineJoin;
import javafx.scene.shape.StrokeType;
import javafx.scene.text.Font;
import javafx.scene.text.FontPosture;
import javafx.scene.text.FontWeight;
import javafx.stage.Stage;
We will start by adding some imports to this class:
import java.util.List;
Through inheritance we will be able to derive properties from a parent class
. However we have to extend that parent class
. So we do that using the extends
keyword.
public class AutoResponsiveLayoutExample extends Application {
Our class
will have the following methods:
void main(String[] args)
void start(Stage primaryStage)
void addButton(AutoResponsiveLayout autoResponsiveLayout, ToolBar toolbar, String buttonText, double minWidth, double minHeight)
All Java applications have an entry point known as the main
method. We will define it:
public static void main(String[] args) {
Here is the full code:
package com.jenkov.javafx.layout;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.StrokeLineCap;
import javafx.scene.shape.StrokeLineJoin;
import javafx.scene.shape.StrokeType;
import javafx.scene.text.Font;
import javafx.scene.text.FontPosture;
import javafx.scene.text.FontWeight;
import javafx.stage.Stage;
import java.util.List;
public class AutoResponsiveLayoutExample extends Application {
private int widgetCount = 0;
public static void main(String[] args) {
launch(args);
}
public void start(Stage primaryStage) {
ScrollPane scrollPane = new ScrollPane();
scrollPane.pannableProperty().set(true);
scrollPane.fitToWidthProperty().set(true);
//scrollPane.fitToHeightProperty().set(true);
//scrollPane.setPrefHeight(1024);
scrollPane.setPrefHeight(4096);
scrollPane.hbarPolicyProperty().setValue(ScrollPane.ScrollBarPolicy.AS_NEEDED);
scrollPane.vbarPolicyProperty().setValue(ScrollPane.ScrollBarPolicy.AS_NEEDED);
Pane containerPane = new Pane();
scrollPane.setContent(containerPane);
AutoResponsiveLayout autoResponsiveLayout = new AutoResponsiveLayout(containerPane, scrollPane);
ToolBar toolbar = createToolBar(containerPane, autoResponsiveLayout);
//VBox vBox = new VBox(toolbar, containerPane);
VBox vBox = new VBox(toolbar, scrollPane);
Scene scene = new Scene(vBox);
primaryStage.setScene(scene);
primaryStage.setWidth(1024);
primaryStage.setHeight(800);
primaryStage.setTitle("Auto-responsive Layout Example");
primaryStage.show();
}
private ToolBar createToolBar(Pane containerPane, AutoResponsiveLayout autoResponsiveLayout) {
ToolBar toolbar = new ToolBar();
addButton(autoResponsiveLayout, toolbar, "1x1", 256, 256);
addButton(autoResponsiveLayout, toolbar, "2x1", 512, 256);
addButton(autoResponsiveLayout, toolbar, "1x2", 256, 512);
addButton(autoResponsiveLayout, toolbar, "2x2", 512, 512);
toolbar.getItems().add(new Separator());
ToggleButton toggleButton2 = new ToggleButton("Balance Rows");
toggleButton2.setOnAction((event) -> {
autoResponsiveLayout.balanceRows = !autoResponsiveLayout.balanceRows;
autoResponsiveLayout.layoutPane();
});
toolbar.getItems().add(toggleButton2);
ToggleButton toggleButton1 = new ToggleButton("Pull Up Children");
toggleButton1.setOnAction((event) -> {
autoResponsiveLayout.pullUpChildren = !autoResponsiveLayout.pullUpChildren;
autoResponsiveLayout.layoutPane();
});
toolbar.getItems().add(toggleButton1);
ToggleButton toggleButton3 = new ToggleButton("Expand Child Width");
toggleButton3.setOnAction((event) -> {
autoResponsiveLayout.extendChildWidth = !autoResponsiveLayout.extendChildWidth;
autoResponsiveLayout.layoutPane();
});
toolbar.getItems().add(toggleButton3);
ToggleButton toggleButton4 = new ToggleButton("Expand Child Height");
toggleButton4.setOnAction((event) -> {
autoResponsiveLayout.extendChildHeight = !autoResponsiveLayout.extendChildHeight;
autoResponsiveLayout.layoutPane();
});
toolbar.getItems().add(toggleButton4);
toolbar.getItems().add(new Separator());
ToggleButton toggleButton5 = new ToggleButton("Clear");
toggleButton5.setOnAction((event) -> {
autoResponsiveLayout.clear();
autoResponsiveLayout.layoutPane();
});
toolbar.getItems().add(toggleButton5);
return toolbar;
}
private void addButton(AutoResponsiveLayout autoResponsiveLayout, ToolBar toolbar, String buttonText, double minWidth, double minHeight) {
Button buttonAdd = new Button(buttonText);
buttonAdd.setOnAction((event) -> {
Pane widgetPane = createWidgetPane(minWidth, minHeight);
autoResponsiveLayout.addWidget(widgetPane);
autoResponsiveLayout.layoutPane();
});
toolbar.getItems().add(buttonAdd);
}
private Pane createWidgetPane(double minWidth, double minHeight) {
this.widgetCount++;
Pane widgetPane = new Pane();
widgetPane.setMinWidth(minWidth);
widgetPane.setMinHeight(minHeight);
StrokeType strokeType = StrokeType.INSIDE;
StrokeLineJoin strokeLineJoin = StrokeLineJoin.MITER;
StrokeLineCap strokeLineCap = StrokeLineCap.BUTT;
double miterLimit = 10;
double dashOffset = 0;
List<Double> dashArray = null;
BorderStrokeStyle borderStrokeStyle =
new BorderStrokeStyle(
strokeType,
strokeLineJoin,
strokeLineCap,
miterLimit,
dashOffset,
dashArray
);
BorderStroke borderStroke =
new BorderStroke(
//Color.valueOf("08ff80"),
Color.valueOf("#303F9F"),
borderStrokeStyle,
new CornerRadii(0),
new BorderWidths(8)
);
Border border = new Border(borderStroke);
Label label = new Label("" + this.widgetCount);
label.setFont(Font.font("Arial", FontWeight.BOLD , FontPosture.REGULAR, 32));
label.setLayoutX(20);
label.setLayoutY(20);
widgetPane.getChildren().add(label);
widgetPane.setBorder(border);
return widgetPane;
}
}
Download
Download the code using the below links:
Number | Link |
---|---|
1. | Download Example |
2. | Follow code author |
3. | Code: Apache 2.0 License |