/*
* This is free and unencumbered software released into the public domain.
*
* Anyone is free to copy, modify, publish, use, compile, sell, or
* distribute this software, either in source code form or as a compiled
* binary, for any purpose, commercial or non-commercial, and by any
* means.
*
* In jurisdictions that recognize copyright laws, the author or authors
* of this software dedicate any and all copyright interest in the
* software to the public domain. We make this dedication for the benefit
* of the public at large and to the detriment of our heirs and
* successors. We intend this dedication to be an overt act of
* relinquishment in perpetuity of all present and future rights to this
* software under copyright law.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* For more information, please refer to <http://unlicense.org/>
*/
package javafx.scene.layout;
import javafx.beans.property.Property;
import javafx.beans.value.ObservableValue;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.geometry.VPos;
import javafx.scene.Node;
import jxtn.jfx.makers.JFX;
/**
* {@link GridPane}建構器延伸(供客製化)
*
* @author AqD
* @param <Z> 要建構的物件型態(需繼承{@link GridPane})
* @param <B> 建構器本身的型態(需繼承{@link GridPaneMaker})
*/
public interface GridPaneMakerExt<Z extends GridPane, B extends GridPaneMaker<Z, B>>
extends javafx.scene.layout.PaneMakerExt<Z, B>
{
//////////////////////////////////////////////////////////////////////////
// 標籤及唯讀欄位
//
/**
* 增加唯讀欄位
* <p>
* 每個欄位佔第一行及第二行:
* <ol>
* <li>第一行顯示標籤({@code label}),向右中對齊</li>
* <li>第二行顯示文字控制{@link javafx.scene.control.TextField},向左上對齊,橫向填滿,連結資料{@code source}</li>
* </ol>
* </p>
*
* @param row 列號
* @param margin 邊界
* @param label 欄位標題
* @param source 資料來源
* @param styleClasses 輸入欄位樣式
* @return 自己
*/
default B addFieldRO(int row, Insets margin, String label, ObservableValue<? extends String> source, String... styleClasses)
{
return this.addFieldROIf(true, row, 0, margin, label, source, styleClasses);
}
/**
* 增加唯讀欄位
* <p>
* 每個欄位佔第一行及第二行:
* <ol>
* <li>第一行顯示標籤({@code label}),向右中對齊</li>
* <li>第二行顯示文字控制{@link javafx.scene.control.TextField},向左上對齊,橫向填滿,連結資料{@code source}</li>
* </ol>
* </p>
*
* @param row 列號
* @param column 行號
* @param margin 邊界
* @param label 欄位標題
* @param source 資料來源
* @param styleClasses 輸入欄位樣式
* @return 自己
*/
default B addFieldRO(int row, int column, Insets margin, String label, ObservableValue<? extends String> source, String... styleClasses)
{
return this.addFieldROIf(true, row, column, margin, label, source, styleClasses);
}
/**
* 增加唯讀欄位
* <p>
* 每個欄位佔第一行及第二行:
* <ol>
* <li>第一行顯示標籤({@code label}),向右中對齊</li>
* <li>第二行顯示文字控制{@link javafx.scene.control.TextField},向左上對齊,橫向填滿,連結資料{@code source}</li>
* </ol>
* </p>
*
* @param condition 條件,為true時才加入欄位
* @param row 列號
* @param margin 邊界
* @param label 欄位標題
* @param source 資料來源
* @param styleClasses 輸入欄位樣式
* @return 自己
*/
default B addFieldROIf(boolean condition, int row, Insets margin, String label, ObservableValue<? extends String> source, String... styleClasses)
{
return this.addFieldROIf(condition, row, 0, margin, label, source, styleClasses);
}
/**
* 增加唯讀欄位
* <p>
* 每個欄位佔第一行及第二行:
* <ol>
* <li>第一行顯示標籤({@code label}),向右中對齊</li>
* <li>第二行顯示文字控制{@link javafx.scene.control.TextField},向左上對齊,橫向填滿,連結資料{@code source}</li>
* </ol>
* </p>
*
* @param condition 條件,為true時才加入欄位
* @param row 列號
* @param column 行號
* @param margin 邊界
* @param label 欄位標題
* @param source 資料來源
* @param styleClasses 輸入欄位樣式
* @return 自己
*/
default B addFieldROIf(boolean condition, int row, int column, Insets margin, String label, ObservableValue<? extends String> source, String... styleClasses)
{
if (condition)
{
Insets labelMargin = column == 0 ? margin : new Insets(
margin.getTop(), margin.getRight(), margin.getBottom(), margin.getLeft() * 2);
Node fieldNode = JFX.textField()
.GridPane_margin(margin)
.GridPane_rowIndex(row).GridPane_columnIndex(column + 1)
.GridPane_fillWidth(true).GridPane_fillHeight(true)
.GridPane_halignment(HPos.LEFT)
.GridPane_valignment(VPos.TOP)
.GridPane_hgrow(Priority.ALWAYS)
.bindText(source)
.editable(false)
.styleClass(styleClasses)
.build();
this.self().childrenAdd(
JFX.label()
.GridPane_margin(labelMargin)
.GridPane_rowIndex(row).GridPane_columnIndex(column + 0)
.GridPane_fillWidth(true).GridPane_fillHeight(true)
.GridPane_halignment(HPos.RIGHT)
.GridPane_valignment(VPos.CENTER)
.labelFor(fieldNode)
.text(label)
.ellipsisString(label)
.afterBuild(lbl -> lbl.minWidthProperty().bind(lbl.prefWidthProperty()))
.build(),
fieldNode);
}
return this.self();
}
//////////////////////////////////////////////////////////////////////////
// 標籤及可輸入欄位
//
/**
* 增加可輸入欄位
* <p>
* 每個欄位佔第一行及第二行:
* <ol>
* <li>第一行顯示標籤({@code label}),向右中對齊</li>
* <li>第二行顯示文字控制{@link javafx.scene.control.TextField},向左上對齊,橫向填滿,連結資料{@code source}</li>
* </ol>
* </p>
*
* @param row 列號
* @param margin 邊界
* @param label 欄位標題
* @param source 資料來源
* @param styleClasses 輸入欄位樣式
* @return 自己
*/
default B addFieldRW(int row, Insets margin, String label, Property<String> source, String... styleClasses)
{
return this.addFieldRWIf(true, row, 0, margin, label, source, styleClasses);
}
/**
* 增加可輸入欄位
* <p>
* 每個欄位佔第一行及第二行:
* <ol>
* <li>第一行顯示標籤({@code label}),向右中對齊</li>
* <li>第二行顯示文字控制{@link javafx.scene.control.TextField},向左上對齊,橫向填滿,連結資料{@code source}</li>
* </ol>
* </p>
*
* @param row 列號
* @param column 行號
* @param margin 邊界
* @param label 欄位標題
* @param source 資料來源
* @param styleClasses 輸入欄位樣式
* @return 自己
*/
default B addFieldRW(int row, int column, Insets margin, String label, Property<String> source, String... styleClasses)
{
return this.addFieldRWIf(true, row, column, margin, label, source, styleClasses);
}
/**
* 增加可輸入欄位
* <p>
* 每個欄位佔第一行及第二行:
* <ol>
* <li>第一行顯示標籤({@code label}),向右中對齊</li>
* <li>第二行顯示文字控制{@link javafx.scene.control.TextField},向左上對齊,橫向填滿,連結資料{@code source}</li>
* </ol>
* </p>
*
* @param condition 條件,為true時才加入欄位
* @param row 列號
* @param margin 邊界
* @param label 欄位標題
* @param source 資料來源
* @param styleClasses 輸入欄位樣式
* @return 自己
*/
default B addFieldRWIf(boolean condition, int row, Insets margin, String label, Property<String> source, String... styleClasses)
{
return this.addFieldRWIf(condition, row, 0, margin, label, source, styleClasses);
}
/**
* 增加可輸入欄位
* <p>
* 每個欄位佔第一行及第二行:
* <ol>
* <li>第一行顯示標籤({@code label}),向右中對齊</li>
* <li>第二行顯示文字控制{@link javafx.scene.control.TextField},向左上對齊,橫向填滿,連結資料{@code source}</li>
* </ol>
* </p>
*
* @param condition 條件,為true時才加入欄位
* @param row 列號
* @param column 行號
* @param margin 邊界
* @param label 欄位標題
* @param source 資料來源
* @param styleClasses 輸入欄位樣式
* @return 自己
*/
default B addFieldRWIf(boolean condition, int row, int column, Insets margin, String label, Property<String> source, String... styleClasses)
{
if (condition)
{
Insets labelMargin = column == 0 ? margin : new Insets(
margin.getTop(), margin.getRight(), margin.getBottom(), margin.getLeft() * 2);
Node fieldNode = JFX.textField()
.GridPane_margin(margin)
.GridPane_rowIndex(row).GridPane_columnIndex(column + 1)
.GridPane_fillWidth(true).GridPane_fillHeight(true)
.GridPane_halignment(HPos.LEFT)
.GridPane_valignment(VPos.TOP)
.GridPane_hgrow(Priority.ALWAYS)
.bindBidirectionalText(source)
.editable(true)
.styleClass(styleClasses)
.build();
this.self().childrenAdd(
JFX.label()
.GridPane_margin(labelMargin)
.GridPane_rowIndex(row).GridPane_columnIndex(column + 0)
.GridPane_fillWidth(true).GridPane_fillHeight(true)
.GridPane_halignment(HPos.RIGHT)
.GridPane_valignment(VPos.CENTER)
.labelFor(fieldNode)
.text(label)
.ellipsisString(label)
.afterBuild(lbl -> lbl.minWidthProperty().bind(lbl.prefWidthProperty()))
.build(),
fieldNode);
}
return this.self();
}
//////////////////////////////////////////////////////////////////////////
// 標籤及自訂輸入欄位
//
/**
* 增加自訂欄位
* <p>
* 每個欄位佔第一行及第二行:
* <ol>
* <li>第一行顯示標籤({@code label}),向右中對齊</li>
* <li>第二行顯示指定控制項({@code fieldNode}),向左上對齊,橫向填滿</li>
* </ol>
* </p>
*
* @param row 列號
* @param margin 邊界
* @param label 欄位標題
* @param fieldNode 欄位節點
* @return 自己
*/
default B addFieldCustom(int row, Insets margin, String label, Node fieldNode)
{
return this.addFieldCustomIf(true, row, 0, margin, label, fieldNode);
}
/**
* 增加自訂欄位
* <p>
* 每個欄位佔第一行及第二行:
* <ol>
* <li>第一行顯示標籤({@code label}),向右中對齊</li>
* <li>第二行顯示指定控制項({@code fieldNode}),向左上對齊,橫向填滿</li>
* </ol>
* </p>
*
* @param row 列號
* @param column 行號
* @param margin 邊界
* @param label 欄位標題
* @param fieldNode 欄位節點
* @return 自己
*/
default B addFieldCustom(int row, int column, Insets margin, String label, Node fieldNode)
{
return this.addFieldCustomIf(true, row, column, margin, label, fieldNode);
}
/**
* 增加自訂欄位
* <p>
* 每個欄位佔第一行及第二行:
* <ol>
* <li>第一行顯示標籤({@code label}),向右中對齊</li>
* <li>第二行顯示指定控制項({@code fieldNode}),向左上對齊,橫向填滿</li>
* </ol>
* </p>
*
* @param condition 條件,為true時才加入欄位
* @param row 列號
* @param margin 邊界
* @param label 欄位標題
* @param fieldNode 欄位節點
* @return 自己
*/
default B addFieldCustomIf(boolean condition, int row, Insets margin, String label, Node fieldNode)
{
return this.addFieldCustomIf(condition, row, 0, margin, label, fieldNode);
}
/**
* 增加自訂欄位
* <p>
* 每個欄位佔第一行及第二行:
* <ol>
* <li>第一行顯示標籤({@code label}),向右中對齊</li>
* <li>第二行顯示指定控制項({@code fieldNode}),向左上對齊,橫向填滿</li>
* </ol>
* </p>
*
* @param condition 條件,為true時才加入欄位
* @param row 列號
* @param column 行號
* @param margin 邊界
* @param label 欄位標題
* @param fieldNode 欄位節點
* @return 自己
*/
default B addFieldCustomIf(boolean condition, int row, int column, Insets margin, String label, Node fieldNode)
{
if (condition)
{
Insets labelMargin = column == 0 ? margin : new Insets(
margin.getTop(), margin.getRight(), margin.getBottom(), margin.getLeft() * 2);
GridPane.setMargin(fieldNode, margin);
GridPane.setRowIndex(fieldNode, row);
GridPane.setColumnIndex(fieldNode, column + 1);
GridPane.setFillWidth(fieldNode, true);
GridPane.setFillHeight(fieldNode, true);
GridPane.setHgrow(fieldNode, Priority.ALWAYS);
GridPane.setHalignment(fieldNode, HPos.LEFT);
GridPane.setValignment(fieldNode, VPos.TOP);
this.self().childrenAdd(
JFX.label()
.GridPane_margin(labelMargin)
.GridPane_rowIndex(row).GridPane_columnIndex(column + 0)
.GridPane_fillWidth(true).GridPane_fillHeight(true)
.GridPane_halignment(HPos.RIGHT)
.GridPane_valignment(VPos.CENTER)
.text(label)
.ellipsisString(label)
.labelFor(fieldNode)
.afterBuild(lbl -> lbl.minWidthProperty().bind(lbl.prefWidthProperty()))
.build(),
fieldNode);
}
return this.self();
}
//////////////////////////////////////////////////////////////////////////
// 自訂標籤及自訂輸入欄位
//
/**
* 增加自訂欄位
* <p>
* 每個欄位佔第一行及第二行:
* <ol>
* <li>第一行顯示標籤({@code label}),向右中對齊</li>
* <li>第二行顯示指定控制項({@code fieldNode}),向左上對齊,橫向填滿</li>
* </ol>
* </p>
*
* @param row 列號
* @param margin 邊界
* @param labelNode 欄位標題
* @param fieldNode 欄位節點
* @return 自己
*/
default B addFieldCustom(int row, Insets margin, Node labelNode, Node fieldNode)
{
return this.addFieldCustomIf(true, row, margin, labelNode, fieldNode);
}
/**
* 增加自訂欄位
* <p>
* 每個欄位佔第一行及第二行:
* <ol>
* <li>第一行顯示標籤({@code label}),向右中對齊</li>
* <li>第二行顯示指定控制項({@code fieldNode}),向左上對齊,橫向填滿</li>
* </ol>
* </p>
*
* @param row 列號
* @param column 行號
* @param margin 邊界
* @param labelNode 欄位標題
* @param fieldNode 欄位節點
* @return 自己
*/
default B addFieldCustom(int row, int column, Insets margin, Node labelNode, Node fieldNode)
{
return this.addFieldCustomIf(true, row, column, margin, labelNode, fieldNode);
}
/**
* 增加自訂欄位
* <p>
* 每個欄位佔第一行及第二行:
* <ol>
* <li>第一行顯示標籤({@code label}),向右中對齊</li>
* <li>第二行顯示指定控制項({@code fieldNode}),向左上對齊,橫向填滿</li>
* </ol>
* </p>
*
* @param condition 條件,為true時才加入欄位
* @param row 列號
* @param margin 邊界
* @param labelNode 欄位標題節點
* @param fieldNode 欄位內容節點
* @return 自己
*/
default B addFieldCustomIf(boolean condition, int row, Insets margin, Node labelNode, Node fieldNode)
{
return this.addFieldCustomIf(condition, row, 0, margin, labelNode, fieldNode);
}
/**
* 增加自訂欄位
* <p>
* 每個欄位佔第一行及第二行:
* <ol>
* <li>第一行顯示標籤({@code label}),向右中對齊</li>
* <li>第二行顯示指定控制項({@code fieldNode}),向左上對齊,橫向填滿</li>
* </ol>
* </p>
*
* @param condition 條件,為true時才加入欄位
* @param row 列號
* @param column 行號
* @param margin 邊界
* @param labelNode 欄位標題節點
* @param fieldNode 欄位內容節點
* @return 自己
*/
default B addFieldCustomIf(boolean condition, int row, int column, Insets margin, Node labelNode, Node fieldNode)
{
if (condition)
{
Insets labelMargin = column == 0 ? margin : new Insets(
margin.getTop(), margin.getRight(), margin.getBottom(), margin.getLeft() * 2);
//
GridPane.setMargin(labelNode, labelMargin);
GridPane.setRowIndex(labelNode, row);
GridPane.setColumnIndex(labelNode, column + 0);
GridPane.setFillWidth(labelNode, true);
GridPane.setFillHeight(labelNode, true);
GridPane.setHalignment(labelNode, HPos.RIGHT);
GridPane.setValignment(labelNode, VPos.CENTER);
//
GridPane.setMargin(fieldNode, margin);
GridPane.setRowIndex(fieldNode, row);
GridPane.setColumnIndex(fieldNode, column + 1);
GridPane.setFillWidth(fieldNode, true);
GridPane.setFillHeight(fieldNode, true);
GridPane.setHgrow(fieldNode, Priority.ALWAYS);
GridPane.setHalignment(fieldNode, HPos.LEFT);
GridPane.setValignment(fieldNode, VPos.TOP);
this.self().childrenAdd(labelNode, fieldNode);
}
return this.self();
}
}