refactor style inject

This commit is contained in:
Timi
2026-07-25 15:22:48 +08:00
parent 0ab2b755e9
commit 8d40522be0
51 changed files with 402 additions and 479 deletions
+2 -2
View File
@@ -133,12 +133,12 @@
<dependency> <dependency>
<groupId>com.imyeyu.fx</groupId> <groupId>com.imyeyu.fx</groupId>
<artifactId>timi-fx</artifactId> <artifactId>timi-fx</artifactId>
<version>0.0.5</version> <version>0.0.6</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.imyeyu.fx.icon</groupId> <groupId>com.imyeyu.fx.icon</groupId>
<artifactId>timi-fx-icon</artifactId> <artifactId>timi-fx-icon</artifactId>
<version>0.0.2</version> <version>0.0.3</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.imyeyu.lang</groupId> <groupId>com.imyeyu.lang</groupId>
@@ -1,6 +1,6 @@
package com.imyeyu.fx.ui; package com.imyeyu.fx.ui;
import com.imyeyu.fx.utils.ScreenFX; import com.imyeyu.fx.utils.screen.Screens;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty; import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ReadOnlyBooleanProperty; import javafx.beans.property.ReadOnlyBooleanProperty;
@@ -66,7 +66,7 @@ public class ScreenIdentify extends Stage implements TimiFXUI {
public void showIdentify() { public void showIdentify() {
show(); show();
List<Screen> screens = ScreenFX.SCREENS; List<Screen> screens = Screens.all();
for (int i = 0; i < screens.size(); i++) { for (int i = 0; i < screens.size(); i++) {
showingIdentifyList.add(new Identify(screens.get(i), i)); showingIdentifyList.add(new Identify(screens.get(i), i));
} }
@@ -111,7 +111,7 @@ public class ScreenIdentify extends Stage implements TimiFXUI {
getContent().setAll(text); getContent().setAll(text);
getScene().setFill(BLACK); getScene().setFill(BLACK);
getScene().getStylesheets().addAll(CSS_STYLE, CSS_FONT); TimiFXUI.applyStyle(getScene());
sizeToScene(); sizeToScene();
} }
} }
+87 -33
View File
@@ -1,18 +1,25 @@
package com.imyeyu.fx.ui; package com.imyeyu.fx.ui;
import com.imyeyu.fx.utils.BgFill; import com.imyeyu.fx.utils.BorderBuilder;
import com.imyeyu.fx.utils.BorderStroke; import com.imyeyu.fx.utils.bg.BackgroundFillBuilder;
import com.imyeyu.fx.utils.layout.Layout;
import com.imyeyu.lang.multi.ResourcesMultilingual; import com.imyeyu.lang.multi.ResourcesMultilingual;
import com.sun.javafx.css.StyleManager;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.geometry.VPos;
import javafx.scene.Node; import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.control.SeparatorMenuItem; import javafx.scene.control.SeparatorMenuItem;
import javafx.scene.control.TableColumn; import javafx.scene.control.TableColumn;
import javafx.scene.effect.DropShadow; import javafx.scene.effect.DropShadow;
import javafx.scene.layout.Background; import javafx.scene.layout.Background;
import javafx.scene.layout.Border; import javafx.scene.layout.Border;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color; import javafx.scene.paint.Color;
import java.util.Objects;
/** /**
* @author 夜雨 * @author 夜雨
* @version 2024-04-13 14:18 * @version 2024-04-13 14:18
@@ -22,14 +29,55 @@ public interface TimiFXUI {
/** 静态资源路径 */ /** 静态资源路径 */
String RESOURCE = "/timifx/"; String RESOURCE = "/timifx/";
String RESOURCE_STYLE = RESOURCE + "/style";
/** 样式文件 */ /** 样式文件 */
String CSS_STYLE = RESOURCE + "style/style.css"; String CSS_STYLE = resource("style/style.css");
/** 控件默认样式文件 */
String CSS_USER_AGENT = resource("style/user-agent.css");
/** 全局字体替换 */ /** 全局字体替换 */
String CSS_FONT = RESOURCE + "style/font.css"; String CSS_FONT = resource("style/font.css");
ResourcesMultilingual MULTILINGUAL = new ResourcesMultilingual(); ResourcesMultilingual MULTILINGUAL = new ResourcesMultilingual();
/**
* 获取静态资源路径
*
* @param path 相对静态资源目录的路径
*
* @return 静态资源绝对路径
*/
private static String resource(String path) {
return Objects.requireNonNull(TimiFXUI.class.getResource(RESOURCE + path)).toExternalForm();
}
/**
* 应用全局样式
*
* @param scene 场景
* @param stylesheets 追加的样式表
*/
static void applyStyle(Scene scene, String... stylesheets) {
if (!Boolean.TRUE.equals(scene.getProperties().get(CSS_USER_AGENT))) {
StyleManager.getInstance().addUserAgentStylesheet(scene, CSS_USER_AGENT);
scene.getProperties().put(CSS_USER_AGENT, true);
}
if (!scene.getStylesheets().contains(CSS_STYLE)) {
scene.getStylesheets().add(CSS_STYLE);
}
if (!scene.getStylesheets().contains(CSS_FONT)) {
scene.getStylesheets().add(CSS_FONT);
}
for (String stylesheet : stylesheets) {
if (!scene.getStylesheets().contains(stylesheet)) {
scene.getStylesheets().add(stylesheet);
}
}
}
/** /**
* *
* *
@@ -122,58 +170,58 @@ public interface TimiFXUI {
interface Stroke { interface Stroke {
/** 透明边框 */ /** 透明边框 */
Border TP = new BorderStroke(Colorful.TRANSPARENT).build(); Border TP = BorderBuilder.solid(Colorful.TRANSPARENT).build();
/** 默认边框 */ /** 默认边框 */
Border DEFAULT = new BorderStroke(Colorful.BORDER).build(); Border DEFAULT = BorderBuilder.solid(Colorful.BORDER).build();
/** 禁用边框 */ /** 禁用边框 */
Border DISABLE = new BorderStroke("#E1E1E1").build(); Border DISABLE = BorderBuilder.solid("#E1E1E1").build();
/** 聚焦边框 */ /** 聚焦边框 */
Border FOCUSED = new BorderStroke(Colorful.BORDER).build(); Border FOCUSED = BorderBuilder.solid(Colorful.BORDER).build();
/** 上边框 */ /** 上边框 */
Border TOP = new BorderStroke(Colorful.BORDER).top().build(); Border TOP = BorderBuilder.solid(Colorful.BORDER).top().build();
/** 左边框 */ /** 左边框 */
Border LEFT = new BorderStroke(Colorful.BORDER).left().build(); Border LEFT = BorderBuilder.solid(Colorful.BORDER).left().build();
/** 右边框 */ /** 右边框 */
Border RIGHT = new BorderStroke(Colorful.BORDER).right().build(); Border RIGHT = BorderBuilder.solid(Colorful.BORDER).right().build();
/** 下边框 */ /** 下边框 */
Border BOTTOM = new BorderStroke(Colorful.BORDER).bottom().build(); Border BOTTOM = BorderBuilder.solid(Colorful.BORDER).bottom().build();
/** 除了上边框 */ /** 除了上边框 */
Border EX_TOP = new BorderStroke(Colorful.BORDER).exTop().build(); Border EX_TOP = BorderBuilder.solid(Colorful.BORDER).exceptTop().build();
/** 除了左边框 */ /** 除了左边框 */
Border EX_LEFT = new BorderStroke(Colorful.BORDER).exLeft().build(); Border EX_LEFT = BorderBuilder.solid(Colorful.BORDER).exceptLeft().build();
/** 除了右边框 */ /** 除了右边框 */
Border EX_RIGHT = new BorderStroke(Colorful.BORDER).exRight().build(); Border EX_RIGHT = BorderBuilder.solid(Colorful.BORDER).exceptRight().build();
/** 除了下边框 */ /** 除了下边框 */
Border EX_BOTTOM = new BorderStroke(Colorful.BORDER).exBottom().build(); Border EX_BOTTOM = BorderBuilder.solid(Colorful.BORDER).exceptBottom().build();
/** 上右边框 */ /** 上右边框 */
Border TR = new BorderStroke(Colorful.BORDER).width(1, 1, 0, 0).build(); Border TR = BorderBuilder.solid(Colorful.BORDER).width(1, 1, 0, 0).build();
/** 右下边框 */ /** 右下边框 */
Border RB = new BorderStroke(Colorful.BORDER).width(0, 1, 1, 0).build(); Border RB = BorderBuilder.solid(Colorful.BORDER).width(0, 1, 1, 0).build();
/** 左下边框 */ /** 左下边框 */
Border BL = new BorderStroke(Colorful.BORDER).width(0, 0, 1, 1).build(); Border BL = BorderBuilder.solid(Colorful.BORDER).width(0, 0, 1, 1).build();
/** 左上边框 */ /** 左上边框 */
Border LT = new BorderStroke(Colorful.BORDER).width(1, 0, 0, 1).build(); Border LT = BorderBuilder.solid(Colorful.BORDER).width(1, 0, 0, 1).build();
/** 水平边框,边的方向而非位置 */ /** 水平边框,边的方向而非位置 */
Border H = new BorderStroke(Colorful.BORDER).width(1, 0).build(); Border H = BorderBuilder.solid(Colorful.BORDER).width(1, 0).build();
/** 垂直边框,边的方向而非位置 */ /** 垂直边框,边的方向而非位置 */
Border V = new BorderStroke(Colorful.BORDER).width(0, 1).build(); Border V = BorderBuilder.solid(Colorful.BORDER).width(0, 1).build();
} }
/** /**
@@ -279,37 +327,37 @@ public interface TimiFXUI {
interface BG { interface BG {
/** FX 默认背景(#F4F4F4 */ /** FX 默认背景(#F4F4F4 */
Background DEFAULT = new BgFill(Colorful.GRAY_WHITE).build(); Background DEFAULT = BackgroundFillBuilder.solid(Colorful.GRAY_WHITE).build();
/** 灰色背景 */ /** 灰色背景 */
Background GRAY = new BgFill(Colorful.GRAY).build(); Background GRAY = BackgroundFillBuilder.solid(Colorful.GRAY).build();
/** 亮灰背景 */ /** 亮灰背景 */
Background LIGHT_GRAY = new BgFill(Colorful.LIGHT_GRAY).build(); Background LIGHT_GRAY = BackgroundFillBuilder.solid(Colorful.LIGHT_GRAY).build();
/** 纯黑背景 */ /** 纯黑背景 */
Background BLACK = new BgFill(Colorful.BLACK).build(); Background BLACK = BackgroundFillBuilder.solid(Colorful.BLACK).build();
/** 纯白背景 */ /** 纯白背景 */
Background WHITE = new BgFill(Colorful.WHITE).build(); Background WHITE = BackgroundFillBuilder.solid(Colorful.WHITE).build();
/** 透明背景 */ /** 透明背景 */
Background TRANSPARENT = new BgFill(Colorful.TRANSPARENT).build(); Background TRANSPARENT = BackgroundFillBuilder.solid(Colorful.TRANSPARENT).build();
/** 淡蓝背景 */ /** 淡蓝背景 */
Background LIGHT_BLUE = new BgFill(Colorful.LIGHT_BLUE).build(); Background LIGHT_BLUE = BackgroundFillBuilder.solid(Colorful.LIGHT_BLUE).build();
/** 聚焦色背景 */ /** 聚焦色背景 */
Background FOCUSED = new BgFill(Colorful.FOCUSED_DEFAULT).build(); Background FOCUSED = BackgroundFillBuilder.solid(Colorful.FOCUSED_DEFAULT).build();
/** 指向背景,通常用于提示组件尺寸响应拖动 */ /** 指向背景,通常用于提示组件尺寸响应拖动 */
Background HOVER = new BgFill("#0007").build(); Background HOVER = BackgroundFillBuilder.solid("#0007").build();
/** 渐变的标题背景 */ /** 渐变的标题背景 */
Background TITLE = new BgFill("#DDD", "#F4F4F400").toRight().build(); Background TITLE = BackgroundFillBuilder.linear("#DDD", "#F4F4F400").toRight().build();
/** 填充的标题背景 */ /** 填充的标题背景 */
Background TITLE_FILL = new BgFill("#DDD").build(); Background TITLE_FILL = BackgroundFillBuilder.solid("#DDD").build();
} }
/** /**
@@ -378,6 +426,12 @@ public interface TimiFXUI {
return label; return label;
} }
static Label gridLabel(String text) {
Label label = Layout.margin.top(GridPane::setMargin, TimiFXUI.label(text), 4);
GridPane.setValignment(label, VPos.TOP);
return label;
}
/** /**
* 构建通用标题标签 * 构建通用标题标签
* *
@@ -2,7 +2,9 @@ package com.imyeyu.fx.ui.components;
import com.imyeyu.fx.TimiFX; import com.imyeyu.fx.TimiFX;
import com.imyeyu.fx.icon.TimiFXIcon; import com.imyeyu.fx.icon.TimiFXIcon;
import com.imyeyu.fx.icon.TimiIcon;
import com.imyeyu.fx.ui.TimiFXUI; import com.imyeyu.fx.ui.TimiFXUI;
import com.imyeyu.fx.utils.Nodes;
import com.imyeyu.java.bean.Callback; import com.imyeyu.java.bean.Callback;
import com.imyeyu.utils.Time; import com.imyeyu.utils.Time;
import com.sun.javafx.scene.control.DatePickerContent; import com.sun.javafx.scene.control.DatePickerContent;
@@ -62,16 +64,16 @@ public class DateTimePicker extends Region implements TimiFXUI, TimiFXUI.Colorfu
minute = new ListView<>(); minute = new ListView<>();
second = new ListView<>(); second = new ListView<>();
hour.getStyleClass().add(CSS.BORDER_RB); hour.setBorder(Stroke.RB);
minute.getStyleClass().add(CSS.BORDER_RB); minute.setBorder(Stroke.RB);
second.getStyleClass().add(CSS.BORDER_B); second.setBorder(Stroke.BOTTOM);
GridPane hmsPane = new GridPane(); GridPane hmsPane = new GridPane();
hmsPane.getStyleClass().add(STYLE_CLASS_TIME_BOX); hmsPane.getStyleClass().add(STYLE_CLASS_TIME_BOX);
hmsPane.addRow(0, hour, minute, second); hmsPane.addRow(0, hour, minute, second);
Button now = new Button(TimiFXUI.MULTILINGUAL.text("now_tick")); Button now = new Button(TimiFXUI.MULTILINGUAL.text("now_tick"));
now.getStyleClass().add(CSS.BORDER_L); now.setBorder(Stroke.LEFT);
now.getStyleClass().add(STYLE_CLASS_NOW); now.getStyleClass().add(STYLE_CLASS_NOW);
timePane = new BorderPane(hmsPane); timePane = new BorderPane(hmsPane);
@@ -111,8 +113,8 @@ public class DateTimePicker extends Region implements TimiFXUI, TimiFXUI.Colorfu
// 失焦关闭而非选择后关闭 // 失焦关闭而非选择后关闭
} }
}; };
IconButton clear = new IconButton(TimiFXIcon.fromName("FAIL", GRAY)); IconButton clear = new IconButton(TimiFXIcon.get(TimiIcon.FAIL, GRAY));
clear.getStyleClass().add(CSS.BORDER_ALL); clear.setBorder(Stroke.DEFAULT);
clear.getStyleClass().add(STYLE_CLASS_CLEAR); clear.getStyleClass().add(STYLE_CLASS_CLEAR);
clear.translateXProperty().bind(widthProperty().subtract(40)); clear.translateXProperty().bind(widthProperty().subtract(40));
clear.setTranslateY(15); clear.setTranslateY(15);
@@ -186,9 +188,9 @@ public class DateTimePicker extends Region implements TimiFXUI, TimiFXUI.Colorfu
minute.addEventFilter(ScrollEvent.SCROLL, middleScroll); minute.addEventFilter(ScrollEvent.SCROLL, middleScroll);
second.addEventFilter(ScrollEvent.SCROLL, middleScroll); second.addEventFilter(ScrollEvent.SCROLL, middleScroll);
TimiFX.hoverFocus(hour); Nodes.requestFocusOnHover(hour);
TimiFX.hoverFocus(minute); Nodes.requestFocusOnHover(minute);
TimiFX.hoverFocus(second); Nodes.requestFocusOnHover(second);
// 此刻 // 此刻
now.setOnAction(e -> setValue(Time.now())); now.setOnAction(e -> setValue(Time.now()));
@@ -1,13 +1,14 @@
package com.imyeyu.fx.ui.components; package com.imyeyu.fx.ui.components;
import com.imyeyu.fx.ObservableUtils;
import com.imyeyu.fx.icon.TimiFXIcon; import com.imyeyu.fx.icon.TimiFXIcon;
import com.imyeyu.fx.icon.TimiIcon;
import com.imyeyu.fx.task.RunAsync; import com.imyeyu.fx.task.RunAsync;
import com.imyeyu.fx.ui.TimiFXUI; import com.imyeyu.fx.ui.TimiFXUI;
import com.imyeyu.fx.ui.components.alert.AlertButton; import com.imyeyu.fx.ui.components.alert.AlertButton;
import com.imyeyu.fx.ui.components.alert.AlertConfirm; import com.imyeyu.fx.ui.components.alert.AlertConfirm;
import com.imyeyu.fx.ui.components.alert.AlertTextField; import com.imyeyu.fx.ui.components.alert.AlertTextField;
import com.imyeyu.fx.ui.components.alert.AlertTips; import com.imyeyu.fx.ui.components.alert.AlertTips;
import com.imyeyu.fx.utils.Observables;
import com.imyeyu.io.IO; import com.imyeyu.io.IO;
import com.imyeyu.java.TimiJava; import com.imyeyu.java.TimiJava;
import com.imyeyu.java.bean.CallbackArgReturn; import com.imyeyu.java.bean.CallbackArgReturn;
@@ -64,8 +65,8 @@ public class FileTreeView extends TreeView<File> implements TimiFXUI.Colorful {
setCellFactory(cell -> new TreeCell<>() { setCellFactory(cell -> new TreeCell<>() {
final Label loading = new Label(TimiFXUI.MULTILINGUAL.text("loading")); final Label loading = new Label(TimiFXUI.MULTILINGUAL.text("loading"));
final Text iconFile = TimiFXIcon.fromName("FILE"); final Text iconFile = TimiFXIcon.get(TimiIcon.FILE);
final Text iconDirectory = TimiFXIcon.fromName("FOLDER"); final Text iconDirectory = TimiFXIcon.get(TimiIcon.FOLDER);
{ {
iconFile.fillProperty().bind(Bindings.when(FileTreeView.this.focusedProperty().and(selectedProperty())).then(GRAY_WHITE).otherwise(GRAY)); iconFile.fillProperty().bind(Bindings.when(FileTreeView.this.focusedProperty().and(selectedProperty())).then(GRAY_WHITE).otherwise(GRAY));
@@ -94,10 +95,10 @@ public class FileTreeView extends TreeView<File> implements TimiFXUI.Colorful {
}); });
// 右键菜单 // 右键菜单
MenuItem menuMkdir = new MenuItem(TimiFXUI.MULTILINGUAL.text("file.mkdir"), TimiFXIcon.fromName("FOLDER_ADD")); MenuItem menuMkdir = new MenuItem(TimiFXUI.MULTILINGUAL.text("file.mkdir"), TimiFXIcon.get(TimiIcon.FOLDER_ADD));
MenuItem menuRename = new MenuItem(TimiFXUI.MULTILINGUAL.text("rename")); MenuItem menuRename = new MenuItem(TimiFXUI.MULTILINGUAL.text("rename"));
MenuItem menuRefresh = new MenuItem(TimiFXUI.MULTILINGUAL.text("refresh"), TimiFXIcon.fromName("REFRESH")); MenuItem menuRefresh = new MenuItem(TimiFXUI.MULTILINGUAL.text("refresh"), TimiFXIcon.get(TimiIcon.REFRESH));
MenuItem menuDestroy = new MenuItem(TimiFXUI.MULTILINGUAL.text("delete"), TimiFXIcon.fromName("FAIL", RED)); MenuItem menuDestroy = new MenuItem(TimiFXUI.MULTILINGUAL.text("delete"), TimiFXIcon.get(TimiIcon.FAIL, RED));
setContextMenu(new ContextMenu(menuMkdir, menuRename, menuRefresh, TimiFXUI.sep(), menuDestroy)); setContextMenu(new ContextMenu(menuMkdir, menuRename, menuRefresh, TimiFXUI.sep(), menuDestroy));
@@ -108,7 +109,7 @@ public class FileTreeView extends TreeView<File> implements TimiFXUI.Colorful {
menuMkdir.setOnAction(e -> mkdir(getSelectionModel().getSelectedItem())); menuMkdir.setOnAction(e -> mkdir(getSelectionModel().getSelectedItem()));
// 重命名 // 重命名
menuRename.disableProperty().bind(ObservableUtils.onlyOnceInList(getSelectionModel().getSelectedItems()).not()); menuRename.disableProperty().bind(Observables.onlyOnceInList(getSelectionModel().getSelectedItems()).not());
menuRename.setOnAction(e -> rename(getSelectionModel().getSelectedItem())); menuRename.setOnAction(e -> rename(getSelectionModel().getSelectedItem()));
// 刷新 // 刷新
@@ -1,8 +1,8 @@
package com.imyeyu.fx.ui.components; package com.imyeyu.fx.ui.components;
import com.imyeyu.fx.TimiFX;
import com.imyeyu.fx.ui.TimiFXUI; import com.imyeyu.fx.ui.TimiFXUI;
import com.imyeyu.java.TimiJava; import com.imyeyu.java.TimiJava;
import com.imyeyu.fx.utils.Nodes;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty; import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleBooleanProperty;
@@ -13,6 +13,7 @@ import javafx.scene.control.Button;
import javafx.scene.control.Skin; import javafx.scene.control.Skin;
import javafx.scene.image.Image; import javafx.scene.image.Image;
import javafx.scene.image.ImageView; import javafx.scene.image.ImageView;
import javafx.scene.layout.Border;
import javafx.scene.paint.Paint; import javafx.scene.paint.Paint;
/** /**
@@ -118,7 +119,7 @@ public class IconButton extends Button implements TimiFXUI, TimiFXUI.Colorful {
if (node != null) { if (node != null) {
setGraphic(node); setGraphic(node);
} }
TimiFX.hoverOpacity(this); Nodes.bindHoverOpacity(this);
// 自适应尺寸、单独图标、图标文本混合时设置不同的内边距 // 自适应尺寸、单独图标、图标文本混合时设置不同的内边距
paddingProperty().bind(Bindings.createObjectBinding(() -> { paddingProperty().bind(Bindings.createObjectBinding(() -> {
@@ -140,7 +141,22 @@ public class IconButton extends Button implements TimiFXUI, TimiFXUI.Colorful {
* @return 本实例 * @return 本实例
*/ */
public IconButton withBackground() { public IconButton withBackground() {
return withBackground(null); return withBackground((Border) null);
}
/**
* 添加按钮背景
*
* @param border 边框
* @return 本实例
*/
public IconButton withBackground(Border border) {
getStyleClass().add(CSS.BG_BUTTON);
if (border != null) {
setBorder(border);
}
opacityProperty().unbind();
return this;
} }
/** /**
@@ -150,11 +166,13 @@ public class IconButton extends Button implements TimiFXUI, TimiFXUI.Colorful {
* @return 本实例 * @return 本实例
*/ */
public IconButton withBackground(String borderClass) { public IconButton withBackground(String borderClass) {
getStyleClass().add(CSS.BG_BUTTON); return withBackground().appendBorderStyle(borderClass);
}
private IconButton appendBorderStyle(String borderClass) {
if (TimiJava.isNotEmpty(borderClass)) { if (TimiJava.isNotEmpty(borderClass)) {
getStyleClass().add(borderClass); getStyleClass().add(borderClass);
} }
opacityProperty().unbind();
return this; return this;
} }
@@ -1,9 +1,10 @@
package com.imyeyu.fx.ui.components; package com.imyeyu.fx.ui.components;
import com.imyeyu.fx.icon.TimiFXIcon; import com.imyeyu.fx.icon.TimiFXIcon;
import com.imyeyu.fx.icon.TimiIcon;
import com.imyeyu.fx.ui.TimiFXUI; import com.imyeyu.fx.ui.TimiFXUI;
import com.imyeyu.fx.utils.BgFill; import com.imyeyu.fx.utils.bg.BackgroundFillBuilder;
import com.imyeyu.fx.utils.SmoothScroll; import com.imyeyu.fx.utils.scroll.SmoothScroll;
import com.imyeyu.java.TimiJava; import com.imyeyu.java.TimiJava;
import com.imyeyu.java.ref.Ref; import com.imyeyu.java.ref.Ref;
import com.imyeyu.utils.Collect; import com.imyeyu.utils.Collect;
@@ -29,8 +30,12 @@ import javafx.stage.Stage;
import javafx.stage.StageStyle; import javafx.stage.StageStyle;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
/** /**
* {@link TimiFXIcon} 的图标选择器(标签搜索需要联网) * {@link TimiFXIcon} 的图标选择器(标签搜索需要联网)
@@ -58,7 +63,7 @@ public class IconPicker extends TextField implements TimiFXUI {
if (TimiJava.isEmpty(value)) { if (TimiJava.isEmpty(value)) {
root.setLeft(null); root.setLeft(null);
} else { } else {
Text icon = TimiFXIcon.fromName(value); Text icon = TimiFXIcon.get(TimiIcon.valueOf(value));
BorderPane.setMargin(icon, new Insets(0, 2, 0, 0)); BorderPane.setMargin(icon, new Insets(0, 2, 0, 0));
BorderPane.setAlignment(icon, Pos.CENTER); BorderPane.setAlignment(icon, Pos.CENTER);
root.setLeft(icon); root.setLeft(icon);
@@ -81,7 +86,7 @@ public class IconPicker extends TextField implements TimiFXUI {
if (newToggle == null) { if (newToggle == null) {
clear(); clear();
} else if (newToggle instanceof ToggleIcon icon) { } else if (newToggle instanceof ToggleIcon icon) {
setText(icon.name.toUpperCase()); setText(icon.value.toString());
} }
}); });
} }
@@ -109,7 +114,7 @@ public class IconPicker extends TextField implements TimiFXUI {
* @return 图标图像 * @return 图标图像
*/ */
public Image getValue() { public Image getValue() {
return TimiFXIcon.imageFromName(getText()); return TimiFXIcon.getImage(TimiIcon.valueOf(getText()));
} }
/** /**
@@ -122,7 +127,7 @@ public class IconPicker extends TextField implements TimiFXUI {
final ToggleGroup group; final ToggleGroup group;
final List<ToggleIcon> icons; final List<ToggleIcon> icons;
final Map<String, Character> nameMapping = TimiFXIcon.getNameMapping(); final Map<TimiIcon, String> unicodeMap = Arrays.stream(TimiIcon.values()).collect(Collectors.toMap(Function.identity(), TimiIcon::getUnicode));
public IconPickerPopup() { public IconPickerPopup() {
// 图标 // 图标
@@ -131,13 +136,12 @@ public class IconPicker extends TextField implements TimiFXUI {
icons = new ArrayList<>(); icons = new ArrayList<>();
group = new ToggleGroup(); group = new ToggleGroup();
Map<String, Character> items = Collect.sortMapByStringKeyASC(nameMapping); Map<TimiIcon, String> items = Collect.sortMap(unicodeMap, Comparator.comparing(Enum::name));
for (Map.Entry<String, Character> item : items.entrySet()) { for (Map.Entry<TimiIcon, String> item : items.entrySet()) {
icons.add(new ToggleIcon(group, item.getKey())); icons.add(new ToggleIcon(group, item.getKey()));
} }
tile.getChildren().addAll(icons); tile.getChildren().addAll(icons);
focusedProperty().addListener((_, _, isFocused) -> {
focusedProperty().addListener((obs, o, isFocused) -> {
if (!isFocused) { if (!isFocused) {
hide(); hide();
} }
@@ -156,12 +160,12 @@ public class IconPicker extends TextField implements TimiFXUI {
setPadding(new Insets(6, 8, 6, 8)); setPadding(new Insets(6, 8, 6, 8));
setFitToWidth(true); setFitToWidth(true);
SmoothScroll.scrollPane(this); SmoothScroll.pane.install(this);
}}); }});
}}); }});
}}); }});
scene.setFill(null); scene.setFill(null);
scene.getStylesheets().addAll(CSS_STYLE, CSS_FONT); TimiFXUI.applyStyle(scene);
setScene(scene); setScene(scene);
setWidth(360); setWidth(360);
setHeight(240); setHeight(240);
@@ -177,16 +181,16 @@ public class IconPicker extends TextField implements TimiFXUI {
*/ */
private static class ToggleIcon extends ToggleButton { private static class ToggleIcon extends ToggleButton {
private static final Background SELECTED = new BgFill("#99D1FF").build(); private static final Background SELECTED = BackgroundFillBuilder.solid("#99D1FF").build();
/** 图标名称 */ /** 图标名称 */
final String name; final TimiIcon value;
public ToggleIcon(ToggleGroup ownerGroup, String name) { public ToggleIcon(ToggleGroup ownerGroup, TimiIcon value) {
super(""); super("");
this.name = name; this.value = value;
setGraphic(TimiFXIcon.fromName(name)); setGraphic(TimiFXIcon.get(value, 16));
getStyleClass().clear(); getStyleClass().clear();
managedProperty().bind(visibleProperty()); managedProperty().bind(visibleProperty());
borderProperty().bind(Bindings.when(hoverProperty()).then(Stroke.FOCUSED).otherwise(Stroke.TP)); borderProperty().bind(Bindings.when(hoverProperty()).then(Stroke.FOCUSED).otherwise(Stroke.TP));
@@ -1,6 +1,7 @@
package com.imyeyu.fx.ui.components; package com.imyeyu.fx.ui.components;
import com.imyeyu.fx.icon.TimiFXIcon; import com.imyeyu.fx.icon.TimiFXIcon;
import com.imyeyu.fx.icon.TimiIcon;
import com.imyeyu.fx.ui.TimiFXUI; import com.imyeyu.fx.ui.TimiFXUI;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.beans.property.IntegerProperty; import javafx.beans.property.IntegerProperty;
@@ -15,6 +16,7 @@ import javafx.scene.control.Label;
import javafx.scene.control.ToggleButton; import javafx.scene.control.ToggleButton;
import javafx.scene.control.ToggleGroup; import javafx.scene.control.ToggleGroup;
import javafx.scene.input.MouseEvent; import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Border;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
import javafx.scene.layout.Region; import javafx.scene.layout.Region;
@@ -79,8 +81,7 @@ public class Pagination extends HBox implements TimiFXUI {
PageButton tb; PageButton tb;
// 上一页 // 上一页
prev = new IconButton(TimiFXIcon.fromName("ARROW_1_W")).withBackground(); prev = new IconButton(TimiFXIcon.get(TimiIcon.ARROW_1_W)).withBackground(Border.EMPTY);
prev.getStyleClass().add(CSS.BORDER_N);
prev.setMaxHeight(Double.MAX_VALUE); prev.setMaxHeight(Double.MAX_VALUE);
prev.disableProperty().bind(ip.isEqualTo(0)); prev.disableProperty().bind(ip.isEqualTo(0));
getChildren().add(prev); getChildren().add(prev);
@@ -96,7 +97,7 @@ public class Pagination extends HBox implements TimiFXUI {
// 2. 总页数大于等于 8,激活下标小于 4(1 - 4 页) // 2. 总页数大于等于 8,激活下标小于 4(1 - 4 页)
tb.visibleProperty().bind(cp.greaterThan(i).and(cp.lessThan(8)).or(cp.greaterThan(7).and(ip.lessThan(4)))); tb.visibleProperty().bind(cp.greaterThan(i).and(cp.lessThan(8)).or(cp.greaterThan(7).and(ip.lessThan(4))));
} else { } else {
tb.getStyleClass().add(CSS.BORDER_LR); tb.setBorder(Stroke.V);
} }
pageButtons.add(tb); pageButtons.add(tb);
getChildren().add(tb); getChildren().add(tb);
@@ -149,9 +150,8 @@ public class Pagination extends HBox implements TimiFXUI {
} }
// 下一页 // 下一页
next = new IconButton(TimiFXIcon.fromName("ARROW_1_E")).withBackground(); next = new IconButton(TimiFXIcon.get(TimiIcon.ARROW_1_E)).withBackground(Border.EMPTY);
next.setMaxHeight(Double.MAX_VALUE); next.setMaxHeight(Double.MAX_VALUE);
next.getStyleClass().add(CSS.BORDER_N);
next.disableProperty().bind(ip.isEqualTo(cp.subtract(1)).or(cp.isEqualTo(0))); next.disableProperty().bind(ip.isEqualTo(cp.subtract(1)).or(cp.isEqualTo(0)));
getStyleClass().add(STYLE_CLASS); getStyleClass().add(STYLE_CLASS);
@@ -324,7 +324,8 @@ public class Pagination extends HBox implements TimiFXUI {
public PageButton() { public PageButton() {
indexProperty = new SimpleIntegerProperty(); indexProperty = new SimpleIntegerProperty();
getStyleClass().addAll(CSS.BORDER_R, CSS.BG_BUTTON); getStyleClass().add(CSS.BG_BUTTON);
setBorder(Stroke.RIGHT);
// 页码即显示内容 // 页码即显示内容
textProperty().bind(indexProperty.add(1).asString()); textProperty().bind(indexProperty.add(1).asString());
managedProperty().bind(visibleProperty()); managedProperty().bind(visibleProperty());
@@ -1,6 +1,6 @@
package com.imyeyu.fx.ui.components; package com.imyeyu.fx.ui.components;
import com.imyeyu.fx.TimiFX; import com.imyeyu.fx.utils.Nodes;
import javafx.beans.property.BooleanProperty; import javafx.beans.property.BooleanProperty;
import javafx.beans.property.DoubleProperty; import javafx.beans.property.DoubleProperty;
import javafx.beans.property.IntegerProperty; import javafx.beans.property.IntegerProperty;
@@ -14,12 +14,16 @@ import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener; import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.control.Control; import javafx.scene.control.Control;
import javafx.scene.control.Skin; import javafx.scene.control.Skin;
import javafx.scene.control.ToggleButton; import javafx.scene.control.ToggleButton;
import javafx.scene.control.ToggleGroup; import javafx.scene.control.ToggleGroup;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent; import javafx.scene.input.MouseEvent;
import lombok.Getter;
/** /**
* 单选按钮组组件 * 单选按钮组组件
@@ -75,6 +79,7 @@ public class RadioButtonGroup extends Control {
public static final String STYLE_CLASS_SINGLE = "single"; public static final String STYLE_CLASS_SINGLE = "single";
/** 按钮列表 */ /** 按钮列表 */
@Getter
private final ObservableList<ToggleButton> buttons; private final ObservableList<ToggleButton> buttons;
/** 按钮组 */ /** 按钮组 */
@@ -99,8 +104,15 @@ public class RadioButtonGroup extends Control {
private final BooleanProperty allowClearSelection; private final BooleanProperty allowClearSelection;
/** 禁止重复点击清空 */ /** 禁止重复点击清空 */
private final javafx.event.EventHandler<MouseEvent> keepSelectionEvent = event -> { private final EventHandler<MouseEvent> keepSelectionEvent = event -> {
if (!isAllowClearSelection() && event.getSource() instanceof ToggleButton button && button.isSelected()) { if (shouldKeepSelection(event.getSource())) {
event.consume();
}
};
/** 禁止通过键盘重复触发清空 */
private final EventHandler<KeyEvent> keepSelectionKeyEvent = event -> {
if ((event.getCode() == KeyCode.SPACE || event.getCode() == KeyCode.ENTER) && shouldKeepSelection(event.getSource())) {
event.consume(); event.consume();
} }
}; };
@@ -130,7 +142,11 @@ public class RadioButtonGroup extends Control {
* 初始化选中同步 * 初始化选中同步
*/ */
private void initSelectionSync() { private void initSelectionSync() {
toggleGroup.selectedToggleProperty().addListener((obs, o, toggle) -> { toggleGroup.selectedToggleProperty().addListener((obs, oldToggle, toggle) -> {
if (!isAllowClearSelection() && toggle == null && oldToggle instanceof ToggleButton button && buttons.contains(button)) {
toggleGroup.selectToggle(button);
return;
}
if (toggle instanceof ToggleButton button) { if (toggle instanceof ToggleButton button) {
selectedButton.set(button); selectedButton.set(button);
selectedIndex.set(buttons.indexOf(button)); selectedIndex.set(buttons.indexOf(button));
@@ -178,7 +194,7 @@ public class RadioButtonGroup extends Control {
* 初始化模式样式 * 初始化模式样式
*/ */
private void initModeStyleClass() { private void initModeStyleClass() {
TimiFX.toggleStyleClass4Binding(this, mode.isEqualTo(Mode.SLIDER), STYLE_CLASS_SLIDER_MODE, STYLE_CLASS_BUTTON_MODE); Nodes.bindStyleClass(this, mode.isEqualTo(Mode.SLIDER), STYLE_CLASS_SLIDER_MODE, STYLE_CLASS_BUTTON_MODE);
} }
/** /**
@@ -192,6 +208,8 @@ public class RadioButtonGroup extends Control {
} }
button.setToggleGroup(toggleGroup); button.setToggleGroup(toggleGroup);
button.addEventFilter(MouseEvent.MOUSE_PRESSED, keepSelectionEvent); button.addEventFilter(MouseEvent.MOUSE_PRESSED, keepSelectionEvent);
button.addEventFilter(KeyEvent.KEY_PRESSED, keepSelectionKeyEvent);
button.addEventFilter(KeyEvent.KEY_RELEASED, keepSelectionKeyEvent);
} }
/** /**
@@ -201,11 +219,23 @@ public class RadioButtonGroup extends Control {
*/ */
private void detachButton(ToggleButton button) { private void detachButton(ToggleButton button) {
button.removeEventFilter(MouseEvent.MOUSE_PRESSED, keepSelectionEvent); button.removeEventFilter(MouseEvent.MOUSE_PRESSED, keepSelectionEvent);
button.removeEventFilter(KeyEvent.KEY_PRESSED, keepSelectionKeyEvent);
button.removeEventFilter(KeyEvent.KEY_RELEASED, keepSelectionKeyEvent);
if (button.getToggleGroup() == toggleGroup) { if (button.getToggleGroup() == toggleGroup) {
button.setToggleGroup(null); button.setToggleGroup(null);
} }
} }
/**
* 判断是否需要保持当前选中
*
* @param source 事件源
* @return true 为拦截当前重复触发
*/
private boolean shouldKeepSelection(Object source) {
return !isAllowClearSelection() && source instanceof ToggleButton button && button.isSelected();
}
/** /**
* 同步当前选中状态 * 同步当前选中状态
*/ */
@@ -235,15 +265,6 @@ public class RadioButtonGroup extends Control {
return new RadioButtonGroupSkin(this); return new RadioButtonGroupSkin(this);
} }
/**
* 获取按钮列表
*
* @return 按钮列表
*/
public ObservableList<ToggleButton> getButtons() {
return buttons;
}
/** /**
* 添加按钮 * 添加按钮
* *
@@ -1,11 +1,9 @@
package com.imyeyu.fx.ui.components; package com.imyeyu.fx.ui.components;
import com.imyeyu.fx.bean.Interpolates; import com.imyeyu.fx.bean.Interpolates;
import javafx.animation.KeyFrame; import javafx.animation.KeyFrame;
import javafx.animation.KeyValue; import javafx.animation.KeyValue;
import javafx.animation.Timeline; import javafx.animation.Timeline;
import javafx.application.Platform;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.beans.property.DoubleProperty; import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty; import javafx.beans.property.SimpleDoubleProperty;
@@ -14,7 +12,6 @@ import javafx.geometry.Bounds;
import javafx.scene.control.SkinBase; import javafx.scene.control.SkinBase;
import javafx.scene.control.ToggleButton; import javafx.scene.control.ToggleButton;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region; import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane; import javafx.scene.layout.StackPane;
import javafx.util.Duration; import javafx.util.Duration;
@@ -27,11 +24,8 @@ import javafx.util.Duration;
*/ */
public class RadioButtonGroupSkin extends SkinBase<RadioButtonGroup> { public class RadioButtonGroupSkin extends SkinBase<RadioButtonGroup> {
/** 高度补偿 */
private static final double HEIGHT_COMPENSATE = 2;
/** 动画时长 */ /** 动画时长 */
private static final Duration SLIDER_DURATION = Duration.millis(180); private static final Duration SLIDER_DURATION = Duration.millis(320);
/** 按钮容器 */ /** 按钮容器 */
private final HBox box; private final HBox box;
@@ -159,25 +153,6 @@ public class RadioButtonGroupSkin extends SkinBase<RadioButtonGroup> {
} }
} }
/**
* 刷新按钮尺寸策略
*/
private void refreshButtonSizing() {
boolean sliderMode = getSkinnable().getMode() == RadioButtonGroup.Mode.SLIDER;
for (ToggleButton button : getSkinnable().getButtons()) {
button.setMinSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);
button.setPrefHeight(Region.USE_COMPUTED_SIZE);
if (sliderMode) {
HBox.setHgrow(button, Priority.NEVER);
button.setMaxWidth(Region.USE_PREF_SIZE);
}
else {
HBox.setHgrow(button, Priority.ALWAYS);
button.setMaxWidth(Double.MAX_VALUE);
}
}
}
/** /**
* 应用滑块位置和尺寸 * 应用滑块位置和尺寸
*/ */
@@ -1,6 +1,7 @@
package com.imyeyu.fx.ui.components; package com.imyeyu.fx.ui.components;
import com.imyeyu.fx.icon.TimiFXIcon; import com.imyeyu.fx.icon.TimiFXIcon;
import com.imyeyu.fx.icon.TimiIcon;
import com.imyeyu.fx.ui.TimiFXUI; import com.imyeyu.fx.ui.TimiFXUI;
import com.imyeyu.java.bean.CallbackArg; import com.imyeyu.java.bean.CallbackArg;
import com.imyeyu.java.ref.Ref; import com.imyeyu.java.ref.Ref;
@@ -48,7 +49,7 @@ public class TabPane extends javafx.scene.control.TabPane implements TimiFXUI, T
closeBtn.setPrefWidth(18); closeBtn.setPrefWidth(18);
closeBtn.getStyleClass().clear(); closeBtn.getStyleClass().clear();
IconButton icon = new IconButton(TimiFXIcon.fromName("FAIL", GRAY)); IconButton icon = new IconButton(TimiFXIcon.get(TimiIcon.FAIL, GRAY));
icon.setAlignment(Pos.CENTER_LEFT); icon.setAlignment(Pos.CENTER_LEFT);
icon.setMouseTransparent(true); icon.setMouseTransparent(true);
icon.prefWidthProperty().bind(closeBtn.widthProperty()); icon.prefWidthProperty().bind(closeBtn.widthProperty());
@@ -1,11 +1,12 @@
package com.imyeyu.fx.ui.components; package com.imyeyu.fx.ui.components;
import com.imyeyu.fx.icon.TimiFXIcon; import com.imyeyu.fx.icon.TimiFXIcon;
import com.imyeyu.fx.icon.TimiIcon;
import com.imyeyu.fx.ui.TimiFXUI; import com.imyeyu.fx.ui.TimiFXUI;
import com.imyeyu.fx.ui.components.popup.PopupTipsService; import com.imyeyu.fx.ui.components.popup.PopupTipsService;
import com.imyeyu.fx.utils.Anchor; import com.imyeyu.fx.utils.grid.Column;
import com.imyeyu.fx.utils.Column; import com.imyeyu.fx.utils.layout.Layout;
import com.imyeyu.fx.utils.SmoothScroll; import com.imyeyu.fx.utils.scroll.SmoothScroll;
import com.imyeyu.java.TimiJava; import com.imyeyu.java.TimiJava;
import com.imyeyu.java.bean.Callback; import com.imyeyu.java.bean.Callback;
import com.imyeyu.java.ref.Ref; import com.imyeyu.java.ref.Ref;
@@ -38,6 +39,7 @@ import javafx.scene.input.ContextMenuEvent;
import javafx.scene.input.KeyCode; import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent; import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent; import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Border;
import javafx.scene.layout.AnchorPane; import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane; import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane; import javafx.scene.layout.GridPane;
@@ -116,31 +118,31 @@ public class TextAreaEditor extends TextArea implements TimiFXUI {
showLineNumber = new SimpleBooleanProperty(true); showLineNumber = new SimpleBooleanProperty(true);
// 撤销 // 撤销
undo = new IconButton(TimiFXIcon.fromName("ARROW_0_W")).withBackground(CSS.BORDER_R); undo = new IconButton(TimiFXIcon.get(TimiIcon.ARROW_0_W)).withBackground(Stroke.RIGHT);
undo.disableProperty().bind(undoableProperty().not()); undo.disableProperty().bind(undoableProperty().not());
PopupTipsService.installText(undo, TimiFXUI.MULTILINGUAL.text("undo")); PopupTipsService.installText(undo, TimiFXUI.MULTILINGUAL.text("undo"));
// 重做 // 重做
redo = new IconButton(TimiFXIcon.fromName("ARROW_0_E")).withBackground(CSS.BORDER_R); redo = new IconButton(TimiFXIcon.get(TimiIcon.ARROW_0_E)).withBackground(Stroke.RIGHT);
redo.disableProperty().bind(redoableProperty().not()); redo.disableProperty().bind(redoableProperty().not());
PopupTipsService.installText(redo, TimiFXUI.MULTILINGUAL.text("redo")); PopupTipsService.installText(redo, TimiFXUI.MULTILINGUAL.text("redo"));
// 复制 // 复制
copy = new IconButton(TimiFXIcon.fromName("COPY")).withBackground(CSS.BORDER_R); copy = new IconButton(TimiFXIcon.get(TimiIcon.COPY)).withBackground(Stroke.RIGHT);
PopupTipsService.installText(copy, TimiFXUI.MULTILINGUAL.text("copy")); PopupTipsService.installText(copy, TimiFXUI.MULTILINGUAL.text("copy"));
// 剪切 // 剪切
cut = new IconButton(TimiFXIcon.fromName("CUT")).withBackground(CSS.BORDER_R); cut = new IconButton(TimiFXIcon.get(TimiIcon.CUT)).withBackground(Stroke.RIGHT);
cut.disableProperty().bind(editableProperty().not()); cut.disableProperty().bind(editableProperty().not());
PopupTipsService.installText(cut, TimiFXUI.MULTILINGUAL.text("cut")); PopupTipsService.installText(cut, TimiFXUI.MULTILINGUAL.text("cut"));
// 粘贴 // 粘贴
paste = new IconButton(TimiFXIcon.fromName("PASTE")).withBackground(CSS.BORDER_R); paste = new IconButton(TimiFXIcon.get(TimiIcon.PASTE)).withBackground(Stroke.RIGHT);
paste.disableProperty().bind(editableProperty().not()); paste.disableProperty().bind(editableProperty().not());
PopupTipsService.installText(paste, TimiFXUI.MULTILINGUAL.text("paste")); PopupTipsService.installText(paste, TimiFXUI.MULTILINGUAL.text("paste"));
// 换行 // 换行
wrap = new ToggleIcon(TimiFXIcon.fromName("WRAP")); wrap = new ToggleIcon(TimiFXIcon.get(TimiIcon.WRAP));
wrap.setBorder(Stroke.RIGHT); wrap.setBorder(Stroke.RIGHT);
PopupTipsService.installText(wrap, TimiFXUI.MULTILINGUAL.text("wrap")); PopupTipsService.installText(wrap, TimiFXUI.MULTILINGUAL.text("wrap"));
@@ -154,12 +156,13 @@ public class TextAreaEditor extends TextArea implements TimiFXUI {
// 顶部背景(阻止触发文本域选择) // 顶部背景(阻止触发文本域选择)
Button headerBackground = new Button(" "); Button headerBackground = new Button(" ");
headerBackground.getStyleClass().addAll(CSS.BORDER_N, CSS.BG_TP); headerBackground.getStyleClass().add(CSS.BG_TP);
headerBackground.setBorder(Border.EMPTY);
headerBackground.setBackground(BG.DEFAULT); headerBackground.setBackground(BG.DEFAULT);
AnchorPane headerPane = new AnchorPane(); AnchorPane headerPane = new AnchorPane();
Anchor.def(header); Layout.anchor.fill(header);
Anchor.def(headerBackground); Layout.anchor.fill(headerBackground);
headerPane.getChildren().setAll(headerBackground, header); headerPane.getChildren().setAll(headerBackground, header);
headerPane.setBorder(Stroke.BOTTOM); headerPane.setBorder(Stroke.BOTTOM);
@@ -321,7 +324,7 @@ public class TextAreaEditor extends TextArea implements TimiFXUI {
}); });
// 平滑滚动 // 平滑滚动
SmoothScroll.scrollPaneV(scrollPane); SmoothScroll.pane.install(scrollPane);
root.setLeft(lineNumber); root.setLeft(lineNumber);
root.setCenter(scrollPane); root.setCenter(scrollPane);
@@ -412,7 +415,7 @@ public class TextAreaEditor extends TextArea implements TimiFXUI {
selects = FXCollections.observableHashMap(); selects = FXCollections.observableHashMap();
// 查找 // 查找
Text icon = TimiFXIcon.fromName("MAGNIFIER"); Text icon = TimiFXIcon.get(TimiIcon.MAGNIFIER);
keyword = new TextField() { keyword = new TextField() {
@Override @Override
@@ -426,7 +429,7 @@ public class TextAreaEditor extends TextArea implements TimiFXUI {
textGroup.setTranslateY(-.5); textGroup.setTranslateY(-.5);
// 匹配大小写 // 匹配大小写
toggleCase = new ToggleIcon(TimiFXIcon.fromName("FONTSIZE")); toggleCase = new ToggleIcon(TimiFXIcon.get(TimiIcon.FONT_SIZE));
toggleCase.setBorder(Stroke.LEFT); toggleCase.setBorder(Stroke.LEFT);
toggleCase.setCursor(Cursor.DEFAULT); toggleCase.setCursor(Cursor.DEFAULT);
toggleCase.setFocusTraversable(false); toggleCase.setFocusTraversable(false);
@@ -446,29 +449,31 @@ public class TextAreaEditor extends TextArea implements TimiFXUI {
} }
}; };
keyword.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE); keyword.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
keyword.getStyleClass().addAll("find-field", CSS.BORDER_R, CSS.PADDING_N); keyword.getStyleClass().addAll("find-field", CSS.PADDING_N);
keyword.setBorder(Stroke.RIGHT);
// 查找结果 // 查找结果
result = TimiFXUI.label(" "); result = TimiFXUI.label(" ");
result.setPadding(new Insets(0, 4, 0, 4)); result.setPadding(new Insets(0, 4, 0, 4));
IconButton prev = new IconButton(TimiFXIcon.fromName("ARROW_0_N")).withBackground(); IconButton prev = new IconButton(TimiFXIcon.get(TimiIcon.ARROW_0_N)).withBackground();
prev.getStyleClass().add(CSS.BORDER_R); prev.setBorder(Stroke.RIGHT);
prev.setFocusTraversable(false); prev.setFocusTraversable(false);
IconButton next = new IconButton(TimiFXIcon.fromName("ARROW_0_S")).withBackground(); IconButton next = new IconButton(TimiFXIcon.get(TimiIcon.ARROW_0_S)).withBackground();
next.getStyleClass().add(CSS.BORDER_R); next.setBorder(Stroke.RIGHT);
next.setFocusTraversable(false); next.setFocusTraversable(false);
// 关闭 // 关闭
IconButton close = new IconButton(TimiFXIcon.fromName("FAIL")).withBackground(); IconButton close = new IconButton(TimiFXIcon.get(TimiIcon.FAIL)).withBackground();
close.getStyleClass().add(CSS.BORDER_L); close.setBorder(Stroke.LEFT);
close.setFocusTraversable(false); close.setFocusTraversable(false);
// 替换值 // 替换值
TextField replaceValue = new TextField(); TextField replaceValue = new TextField();
replaceValue.getStyleClass().addAll("replace-field", CSS.BORDER_TR); replaceValue.getStyleClass().add("replace-field");
replaceValue.setBorder(Stroke.TR);
replaceValue.disableProperty().bind(editableProperty().not()); replaceValue.disableProperty().bind(editableProperty().not());
Button replace = new Button(TimiFXUI.MULTILINGUAL.text("replace")); Button replace = new Button(TimiFXUI.MULTILINGUAL.text("replace"));
replace.getStyleClass().add(CSS.BORDER_R); replace.setBorder(Stroke.RIGHT);
replace.setFocusTraversable(false); replace.setFocusTraversable(false);
replace.disableProperty().bind(editableProperty().not().or(replaceValue.textProperty().isEmpty().or(Bindings.isEmpty(selects)))); replace.disableProperty().bind(editableProperty().not().or(replaceValue.textProperty().isEmpty().or(Bindings.isEmpty(selects))));
replace.addEventFilter(MouseEvent.MOUSE_DRAGGED, e -> { replace.addEventFilter(MouseEvent.MOUSE_DRAGGED, e -> {
@@ -477,12 +482,12 @@ public class TextAreaEditor extends TextArea implements TimiFXUI {
} }
}); });
Button replaceAll = new Button(TimiFXUI.MULTILINGUAL.text("replace_all")); Button replaceAll = new Button(TimiFXUI.MULTILINGUAL.text("replace_all"));
replaceAll.getStyleClass().add(CSS.BORDER_R); replaceAll.setBorder(Stroke.RIGHT);
replaceAll.setFocusTraversable(false); replaceAll.setFocusTraversable(false);
replaceAll.disableProperty().bind(replace.disabledProperty()); replaceAll.disableProperty().bind(replace.disabledProperty());
getStyleClass().add("find-pane"); getStyleClass().add("find-pane");
getColumnConstraints().addAll(Column.build(), Column.build().width(260), Column.VALUE_FILL); getColumnConstraints().addAll(Column.builder().build(), Column.builder().width(260).build(), Column.valueFill());
setBorder(Stroke.BOTTOM); setBorder(Stroke.BOTTOM);
setBackground(BG.DEFAULT); setBackground(BG.DEFAULT);
@@ -645,7 +650,7 @@ public class TextAreaEditor extends TextArea implements TimiFXUI {
// 不可单向绑定,TextArea 内部需要调度 setVvalue,也不可双向绑定,会造成滚动错位 // 不可单向绑定,TextArea 内部需要调度 setVvalue,也不可双向绑定,会造成滚动错位
scrollPane.setVvalue(newV.doubleValue()); scrollPane.setVvalue(newV.doubleValue());
}); });
getStyleClass().add(CSS.BORDER_L); setBorder(Stroke.LEFT);
setEditable(false); setEditable(false);
setNodeOrientation(NodeOrientation.RIGHT_TO_LEFT); setNodeOrientation(NodeOrientation.RIGHT_TO_LEFT);
addEventFilter(MouseEvent.ANY, Event::consume); addEventFilter(MouseEvent.ANY, Event::consume);
@@ -688,7 +693,7 @@ public class TextAreaEditor extends TextArea implements TimiFXUI {
scrollPane.vvalueProperty().addListener((obs, o, n) -> scrollPane.setVvalue(ownerScrollPane.getVvalue())); scrollPane.vvalueProperty().addListener((obs, o, n) -> scrollPane.setVvalue(ownerScrollPane.getVvalue()));
scrollPane.getContent().setCursor(Cursor.DEFAULT); scrollPane.getContent().setCursor(Cursor.DEFAULT);
SmoothScroll.scrollPaneV(scrollPane); SmoothScroll.pane.install(scrollPane);
} catch (NoSuchFieldException | IllegalAccessException e) { } catch (NoSuchFieldException | IllegalAccessException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@@ -2,7 +2,9 @@ package com.imyeyu.fx.ui.components;
import com.imyeyu.fx.TimiFX; import com.imyeyu.fx.TimiFX;
import com.imyeyu.fx.icon.TimiFXIcon; import com.imyeyu.fx.icon.TimiFXIcon;
import com.imyeyu.fx.icon.TimiIcon;
import com.imyeyu.fx.ui.TimiFXUI; import com.imyeyu.fx.ui.TimiFXUI;
import com.imyeyu.fx.utils.Windows;
import com.imyeyu.java.bean.CallbackArg; import com.imyeyu.java.bean.CallbackArg;
import com.imyeyu.java.ref.Ref; import com.imyeyu.java.ref.Ref;
import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.SimpleStringProperty;
@@ -71,8 +73,7 @@ public class TextAreaEditorField extends TextField implements TimiFXUI {
textGroup.setTranslateY(-.5); textGroup.setTranslateY(-.5);
// 插入编辑器图标 // 插入编辑器图标
IconButton editor = new IconButton(TimiFXIcon.fromName("WRITING")).withBackground(); IconButton editor = new IconButton(TimiFXIcon.get(TimiIcon.WRITING)).withBackground(Stroke.LEFT);
editor.getStyleClass().add(CSS.BORDER_L);
editor.setCursor(Cursor.DEFAULT); editor.setCursor(Cursor.DEFAULT);
BorderPane root = new BorderPane(); BorderPane root = new BorderPane();
@@ -88,7 +89,7 @@ public class TextAreaEditorField extends TextField implements TimiFXUI {
if (onShowEditorEvent != null) { if (onShowEditorEvent != null) {
onShowEditorEvent.handler(editorStage); onShowEditorEvent.handler(editorStage);
} }
TimiFX.showCenter(getScene().getWindow(), editorStage); Windows.showCentered(getScene().getWindow(), editorStage);
}); });
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
@@ -138,12 +139,12 @@ public class TextAreaEditorField extends TextField implements TimiFXUI {
EditorStage() { EditorStage() {
editor = new TextAreaEditor(); editor = new TextAreaEditor();
editor.getStyleClass().add(CSS.BORDER_T); editor.setBorder(Stroke.TOP);
Scene scene = new Scene(editor); Scene scene = new Scene(editor);
scene.getStylesheets().addAll(CSS_STYLE, CSS_FONT); TimiFXUI.applyStyle(scene);
setScene(scene); setScene(scene);
getIcons().add(TimiFXIcon.iconFromName("WRITING")); getIcons().add(TimiFXIcon.rerender(TimiIcon.WRITING));
setWidth(850); setWidth(850);
setHeight(620); setHeight(620);
} }
@@ -2,7 +2,9 @@ package com.imyeyu.fx.ui.components;
import com.imyeyu.fx.TimiFX; import com.imyeyu.fx.TimiFX;
import com.imyeyu.fx.icon.TimiFXIcon; import com.imyeyu.fx.icon.TimiFXIcon;
import com.imyeyu.fx.icon.TimiIcon;
import com.imyeyu.fx.ui.TimiFXUI; import com.imyeyu.fx.ui.TimiFXUI;
import com.imyeyu.fx.utils.Nodes;
import com.imyeyu.utils.Time; import com.imyeyu.utils.Time;
import javafx.beans.property.IntegerProperty; import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty; import javafx.beans.property.SimpleIntegerProperty;
@@ -51,21 +53,20 @@ public class TimePicker extends HBox implements TimiFXUI {
textField.setAlignment(Pos.CENTER); textField.setAlignment(Pos.CENTER);
textField.setPrefWidth(70); textField.setPrefWidth(70);
textField.setOnContextMenuRequested(Event::consume); textField.setOnContextMenuRequested(Event::consume);
IconButton button = new IconButton(TimiFXIcon.fromName("CLOCK")).withBackground(); IconButton button = new IconButton(TimiFXIcon.get(TimiIcon.CLOCK)).withBackground(Stroke.EX_LEFT);
button.getStyleClass().add(CSS.BORDER_TRB);
// 时间选择 // 时间选择
hour = new ListView<>(); hour = new ListView<>();
minute = new ListView<>(); minute = new ListView<>();
second = new ListView<>(); second = new ListView<>();
hour.getStyleClass().add(CSS.BORDER_RB); hour.setBorder(Stroke.RB);
minute.getStyleClass().add(CSS.BORDER_RB); minute.setBorder(Stroke.RB);
second.getStyleClass().add(CSS.BORDER_B); second.setBorder(Stroke.BOTTOM);
// 此刻 // 此刻
Button now = new Button(TimiFXUI.MULTILINGUAL.text("now")); Button now = new Button(TimiFXUI.MULTILINGUAL.text("now"));
now.getStyleClass().add(CSS.BORDER_L); now.setBorder(Stroke.LEFT);
now.getStyleClass().add(STYLE_CLASS_NOW); now.getStyleClass().add(STYLE_CLASS_NOW);
HBox timeBox = new HBox(hour, minute, second); HBox timeBox = new HBox(hour, minute, second);
@@ -134,9 +135,9 @@ public class TimePicker extends HBox implements TimiFXUI {
minute.addEventFilter(ScrollEvent.SCROLL, middleScroll); minute.addEventFilter(ScrollEvent.SCROLL, middleScroll);
second.addEventFilter(ScrollEvent.SCROLL, middleScroll); second.addEventFilter(ScrollEvent.SCROLL, middleScroll);
TimiFX.hoverFocus(hour); Nodes.requestFocusOnHover(hour);
TimiFX.hoverFocus(minute); Nodes.requestFocusOnHover(minute);
TimiFX.hoverFocus(second); Nodes.requestFocusOnHover(second);
// 值监听 // 值监听
value.addListener((obs, o, n) -> { value.addListener((obs, o, n) -> {
@@ -1,8 +1,8 @@
package com.imyeyu.fx.ui.components; package com.imyeyu.fx.ui.components;
import com.imyeyu.fx.TimiFX;
import com.imyeyu.fx.ui.TimiFXUI; import com.imyeyu.fx.ui.TimiFXUI;
import com.imyeyu.fx.utils.BgFill; import com.imyeyu.fx.utils.Nodes;
import com.imyeyu.fx.utils.bg.BackgroundFillBuilder;
import com.imyeyu.java.TimiJava; import com.imyeyu.java.TimiJava;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty; import javafx.beans.property.BooleanProperty;
@@ -25,7 +25,7 @@ import javafx.scene.layout.Background;
public class ToggleIcon extends ToggleButton implements TimiFXUI { public class ToggleIcon extends ToggleButton implements TimiFXUI {
private static final String STYLE_CLASS = "toggle-icon"; private static final String STYLE_CLASS = "toggle-icon";
private static final Background BG_SELECTED = new BgFill("#99D1FF").build(); private static final Background BG_SELECTED = BackgroundFillBuilder.solid("#99D1FF").build();
/** 选中图标 */ /** 选中图标 */
protected final Node selected; protected final Node selected;
@@ -118,7 +118,7 @@ public class ToggleIcon extends ToggleButton implements TimiFXUI {
graphicProperty().bind(Bindings.when(selectedProperty()).then(selected).otherwise(otherwise)); graphicProperty().bind(Bindings.when(selectedProperty()).then(selected).otherwise(otherwise));
} }
selected.getStyleClass().add("icon"); selected.getStyleClass().add("icon");
TimiFX.hoverOpacity(this); Nodes.bindHoverOpacity(this);
getStyleClass().setAll(CSS.MINECRAFT, STYLE_CLASS); getStyleClass().setAll(CSS.MINECRAFT, STYLE_CLASS);
setAlignment(Pos.CENTER); setAlignment(Pos.CENTER);
@@ -106,7 +106,7 @@ public final class TrayFX implements TimiFXUI {
root = new StackPane(); root = new StackPane();
Scene scene = new Scene(root); Scene scene = new Scene(root);
scene.getStylesheets().addAll(CSS_STYLE, CSS_FONT, RESOURCE + "style/components/tray-menu.css"); TimiFXUI.applyStyle(scene, TrayFX.class.getResource(RESOURCE + "style/components/tray-menu.css").toExternalForm());
scene.setFill(null); scene.setFill(null);
stage = new Stage(); stage = new Stage();
stage.setWidth(1); stage.setWidth(1);
@@ -1,6 +1,6 @@
package com.imyeyu.fx.ui.components; package com.imyeyu.fx.ui.components;
import com.imyeyu.fx.utils.SmoothScroll; import com.imyeyu.fx.utils.scroll.SmoothScroll;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import javafx.scene.control.TreeItem; import javafx.scene.control.TreeItem;
@@ -20,7 +20,7 @@ public class TreeView<T> extends javafx.scene.control.TreeView<T> {
setRoot(dummyRoot); setRoot(dummyRoot);
setShowRoot(false); setShowRoot(false);
// 平滑滚动 // 平滑滚动
SmoothScroll.virtual(this); SmoothScroll.virtual.install(this);
} }
/** /**
@@ -1,8 +1,8 @@
package com.imyeyu.fx.ui.components.alert; package com.imyeyu.fx.ui.components.alert;
import com.imyeyu.fx.TimiFX;
import com.imyeyu.fx.ui.TimiFXUI; import com.imyeyu.fx.ui.TimiFXUI;
import com.imyeyu.fx.utils.ScreenFX; import com.imyeyu.fx.utils.Windows;
import com.imyeyu.fx.utils.screen.Screens;
import com.imyeyu.java.bean.CallbackArg; import com.imyeyu.java.bean.CallbackArg;
import com.imyeyu.java.bean.CallbackArgReturn; import com.imyeyu.java.bean.CallbackArgReturn;
import javafx.beans.property.ObjectProperty; import javafx.beans.property.ObjectProperty;
@@ -102,7 +102,7 @@ public abstract class AbstractAlert extends Stage implements TimiFXUI, TimiFXUI.
}}); }});
Scene scene = new Scene(root); Scene scene = new Scene(root);
scene.getStylesheets().addAll(CSS_STYLE, CSS_FONT); TimiFXUI.applyStyle(scene);
initModality(Modality.WINDOW_MODAL); initModality(Modality.WINDOW_MODAL);
setScene(scene); setScene(scene);
@@ -184,7 +184,7 @@ public abstract class AbstractAlert extends Stage implements TimiFXUI, TimiFXUI.
initOwner(owner); initOwner(owner);
} }
setOnShown(e -> { setOnShown(e -> {
TimiFX.relativeCenter(owner, this); Windows.centerOnOwner(owner, this);
callShownListeners(e); callShownListeners(e);
}); });
show(); show();
@@ -200,7 +200,7 @@ public abstract class AbstractAlert extends Stage implements TimiFXUI, TimiFXUI.
initOwner(owner); initOwner(owner);
} }
setOnShown(e -> { setOnShown(e -> {
TimiFX.relativeCenter(owner, this); Windows.centerOnOwner(owner, this);
callShownListeners(e); callShownListeners(e);
}); });
showAndWait(); showAndWait();
@@ -208,7 +208,7 @@ public abstract class AbstractAlert extends Stage implements TimiFXUI, TimiFXUI.
/** 相对于主屏幕中间显示 */ /** 相对于主屏幕中间显示 */
public void showRelativeCenter4PrimaryScreen() { public void showRelativeCenter4PrimaryScreen() {
showRelativeCenter4Screen(ScreenFX.primary); showRelativeCenter4Screen(Screens.primary());
} }
/** /**
@@ -219,7 +219,7 @@ public abstract class AbstractAlert extends Stage implements TimiFXUI, TimiFXUI.
public void showRelativeCenter4Screen(Screen screen) { public void showRelativeCenter4Screen(Screen screen) {
initModality(Modality.APPLICATION_MODAL); initModality(Modality.APPLICATION_MODAL);
setOnShown(e -> { setOnShown(e -> {
TimiFX.relativeCenter4Screen(screen, this); Windows.centerOnScreen(this, screen);
callShownListeners(e); callShownListeners(e);
}); });
show(); show();
@@ -227,7 +227,7 @@ public abstract class AbstractAlert extends Stage implements TimiFXUI, TimiFXUI.
/** 相对于主屏幕中间显示并等待 */ /** 相对于主屏幕中间显示并等待 */
public void showAwaitRelativeCenter4PrimaryScreen() { public void showAwaitRelativeCenter4PrimaryScreen() {
showAwaitRelativeCenter4Screen(ScreenFX.primary); showAwaitRelativeCenter4Screen(Screens.primary());
} }
/** /**
@@ -238,7 +238,7 @@ public abstract class AbstractAlert extends Stage implements TimiFXUI, TimiFXUI.
public void showAwaitRelativeCenter4Screen(Screen screen) { public void showAwaitRelativeCenter4Screen(Screen screen) {
initModality(Modality.APPLICATION_MODAL); initModality(Modality.APPLICATION_MODAL);
setOnShown(e -> { setOnShown(e -> {
TimiFX.relativeCenter4Screen(screen, this); Windows.centerOnScreen(this, screen);
callShownListeners(e); callShownListeners(e);
}); });
showAndWait(); showAndWait();
@@ -1,6 +1,7 @@
package com.imyeyu.fx.ui.components.alert; package com.imyeyu.fx.ui.components.alert;
import com.imyeyu.fx.icon.TimiFXIcon; import com.imyeyu.fx.icon.TimiFXIcon;
import com.imyeyu.fx.icon.TimiIcon;
import com.imyeyu.fx.ui.TimiFXUI; import com.imyeyu.fx.ui.TimiFXUI;
import com.imyeyu.fx.ui.components.FileTreeView; import com.imyeyu.fx.ui.components.FileTreeView;
import com.imyeyu.fx.ui.components.IconButton; import com.imyeyu.fx.ui.components.IconButton;
@@ -18,6 +19,7 @@ import javafx.scene.control.TextField;
import javafx.scene.control.TreeItem; import javafx.scene.control.TreeItem;
import javafx.scene.input.MouseButton; import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent; import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Border;
import javafx.scene.layout.BorderPane; import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
@@ -66,27 +68,23 @@ public abstract class AbstractAlertFile extends AbstractAlert implements TimiFXU
VBox header = new VBox(); VBox header = new VBox();
// 主页 // 主页
IconButton home = new IconButton(TimiFXIcon.fromName("HOME")).withBackground(); IconButton home = new IconButton(TimiFXIcon.get(TimiIcon.HOME)).withBackground(Stroke.RIGHT);
home.getStyleClass().add(CSS.BORDER_R);
PopupTipsService.installText(home, TimiFXUI.MULTILINGUAL.text("home")); PopupTipsService.installText(home, TimiFXUI.MULTILINGUAL.text("home"));
// 刷新 // 刷新
IconButton refresh = new IconButton(TimiFXIcon.fromName("REFRESH")).withBackground(); IconButton refresh = new IconButton(TimiFXIcon.get(TimiIcon.REFRESH)).withBackground(Stroke.RIGHT);
refresh.getStyleClass().add(CSS.BORDER_R);
PopupTipsService.installText(refresh, TimiFXUI.MULTILINGUAL.text("refresh")); PopupTipsService.installText(refresh, TimiFXUI.MULTILINGUAL.text("refresh"));
// 创建文件夹 // 创建文件夹
IconButton mkdir = new IconButton(TimiFXIcon.fromName("FOLDER_ADD")).withBackground(); IconButton mkdir = new IconButton(TimiFXIcon.get(TimiIcon.FOLDER_ADD)).withBackground(Stroke.RIGHT);
mkdir.getStyleClass().add(CSS.BORDER_R);
PopupTipsService.installText(mkdir, TimiFXUI.MULTILINGUAL.text("file.mkdir")); PopupTipsService.installText(mkdir, TimiFXUI.MULTILINGUAL.text("file.mkdir"));
// 删除 // 删除
IconButton destroy = new IconButton(TimiFXIcon.fromName("FAIL", Colorful.RED)).withBackground(); IconButton destroy = new IconButton(TimiFXIcon.get(TimiIcon.FAIL, Colorful.RED)).withBackground(Stroke.RIGHT);
destroy.getStyleClass().add(CSS.BORDER_R);
PopupTipsService.installText(destroy, TimiFXUI.MULTILINGUAL.text("delete")); PopupTipsService.installText(destroy, TimiFXUI.MULTILINGUAL.text("delete"));
// 切换隐藏 // 切换隐藏
toggleHide = new ToggleIcon(TimiFXIcon.fromName("HIDE")); toggleHide = new ToggleIcon(TimiFXIcon.get(TimiIcon.HIDE));
PopupTipsService.installText(toggleHide, TimiFXUI.MULTILINGUAL.text("file.show_hide")); PopupTipsService.installText(toggleHide, TimiFXUI.MULTILINGUAL.text("file.show_hide"));
BorderPane ctrl = new BorderPane(); BorderPane ctrl = new BorderPane();
@@ -99,9 +97,8 @@ public abstract class AbstractAlertFile extends AbstractAlert implements TimiFXU
// 绝对路径 // 绝对路径
absolutePath = new TextField(); absolutePath = new TextField();
absolutePath.getStyleClass().add(CSS.BORDER_N); absolutePath.setBorder(Border.EMPTY);
IconButton absolutePathGo = new IconButton(TimiFXIcon.fromName("ARROW_2_E")).withBackground(); IconButton absolutePathGo = new IconButton(TimiFXIcon.get(TimiIcon.ARROW_2_E)).withBackground(Stroke.LEFT);
absolutePathGo.getStyleClass().add(CSS.BORDER_L);
{ {
if (mode == SelectionMode.SINGLE) { if (mode == SelectionMode.SINGLE) {
PopupTipsLabel tips = PopupTipsService.installBindingText(absolutePath, absolutePath.textProperty()); PopupTipsLabel tips = PopupTipsService.installBindingText(absolutePath, absolutePath.textProperty());
@@ -128,10 +125,10 @@ public abstract class AbstractAlertFile extends AbstractAlert implements TimiFXU
{ {
confirm = AlertButton.confirm(); confirm = AlertButton.confirm();
confirm.getStyleClass().add(CSS.BORDER_L); confirm.setBorder(Stroke.LEFT);
cancel = AlertButton.cancel(); cancel = AlertButton.cancel();
cancel.getStyleClass().add(CSS.BORDER_L); cancel.setBorder(Stroke.LEFT);
setRightButtons(confirm, cancel); setRightButtons(confirm, cancel);
btnPane.setPadding(Insets.EMPTY); btnPane.setPadding(Insets.EMPTY);
@@ -1,6 +1,7 @@
package com.imyeyu.fx.ui.components.alert; package com.imyeyu.fx.ui.components.alert;
import com.imyeyu.fx.icon.TimiFXIcon; import com.imyeyu.fx.icon.TimiFXIcon;
import com.imyeyu.fx.icon.TimiIcon;
import com.imyeyu.fx.ui.TimiFXUI; import com.imyeyu.fx.ui.TimiFXUI;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.scene.control.SelectionMode; import javafx.scene.control.SelectionMode;
@@ -24,7 +25,7 @@ public class AlertFileBlendSelector extends AbstractAlertFile {
// 确认 // 确认
confirm.disableProperty().bind(Bindings.isEmpty(tree.getSelectionModel().getSelectedItems())); confirm.disableProperty().bind(Bindings.isEmpty(tree.getSelectionModel().getSelectedItems()));
getIcons().setAll(TimiFXIcon.iconFromName("FOLDER")); getIcons().setAll(TimiFXIcon.rerender(TimiIcon.FOLDER));
setTitle(TimiFXUI.MULTILINGUAL.text("file.tips.select_directory")); setTitle(TimiFXUI.MULTILINGUAL.text("file.tips.select_directory"));
} }
} }
@@ -1,6 +1,7 @@
package com.imyeyu.fx.ui.components.alert; package com.imyeyu.fx.ui.components.alert;
import com.imyeyu.fx.icon.TimiFXIcon; import com.imyeyu.fx.icon.TimiFXIcon;
import com.imyeyu.fx.icon.TimiIcon;
import com.imyeyu.fx.ui.TimiFXUI; import com.imyeyu.fx.ui.TimiFXUI;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.scene.control.SelectionMode; import javafx.scene.control.SelectionMode;
@@ -30,7 +31,7 @@ public class AlertFilePathSelector extends AbstractAlertFile {
return item == null || item.getValue().isFile(); return item == null || item.getValue().isFile();
}, tree.getSelectionModel().selectedItemProperty())); }, tree.getSelectionModel().selectedItemProperty()));
getIcons().setAll(TimiFXIcon.iconFromName("FOLDER")); getIcons().setAll(TimiFXIcon.rerender(TimiIcon.FOLDER));
setTitle(TimiFXUI.MULTILINGUAL.text("file.tips.select_directory")); setTitle(TimiFXUI.MULTILINGUAL.text("file.tips.select_directory"));
addItemFilter(File::isDirectory); addItemFilter(File::isDirectory);
@@ -1,6 +1,7 @@
package com.imyeyu.fx.ui.components.alert; package com.imyeyu.fx.ui.components.alert;
import com.imyeyu.fx.icon.TimiFXIcon; import com.imyeyu.fx.icon.TimiFXIcon;
import com.imyeyu.fx.icon.TimiIcon;
import com.imyeyu.fx.ui.TimiFXUI; import com.imyeyu.fx.ui.TimiFXUI;
import com.imyeyu.io.IO; import com.imyeyu.io.IO;
import com.imyeyu.java.TimiJava; import com.imyeyu.java.TimiJava;
@@ -44,7 +45,7 @@ public class AlertFileSelector extends AbstractAlertFile {
return item == null || item.getValue().isDirectory(); return item == null || item.getValue().isDirectory();
}, tree.getSelectionModel().selectedItemProperty())); }, tree.getSelectionModel().selectedItemProperty()));
getIcons().setAll(TimiFXIcon.iconFromName("FILE")); getIcons().setAll(TimiFXIcon.rerender(TimiIcon.FILE));
setTitle(TimiFXUI.MULTILINGUAL.text("file.select")); setTitle(TimiFXUI.MULTILINGUAL.text("file.select"));
addItemFilter(file -> { addItemFilter(file -> {
@@ -2,7 +2,8 @@ package com.imyeyu.fx.ui.components.alert;
import com.imyeyu.fx.TimiFX; import com.imyeyu.fx.TimiFX;
import com.imyeyu.fx.ui.TimiFXUI; import com.imyeyu.fx.ui.TimiFXUI;
import com.imyeyu.fx.utils.SmoothScroll; import com.imyeyu.fx.utils.scroll.SmoothScroll;
import com.imyeyu.fx.utils.Windows;
import com.imyeyu.java.bean.CallbackArg; import com.imyeyu.java.bean.CallbackArg;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanBinding; import javafx.beans.binding.BooleanBinding;
@@ -85,7 +86,7 @@ public class AlertTextArea extends AbstractAlertInput<TextArea> {
public AlertTextArea(AlertType type, String title, String content, String text, AlertButton... buttons) { public AlertTextArea(AlertType type, String title, String content, String text, AlertButton... buttons) {
super(new TextArea(), type, title, content, text, buttons); super(new TextArea(), type, title, content, text, buttons);
SmoothScroll.textarea(getInput()); SmoothScroll.text.install(getInput());
setResizable(true); setResizable(true);
// 没有按钮监听 // 没有按钮监听
@@ -102,7 +103,7 @@ public class AlertTextArea extends AbstractAlertInput<TextArea> {
super.content.setPadding(isEmpty ? Insets.EMPTY : PADDING_CONTENT); super.content.setPadding(isEmpty ? Insets.EMPTY : PADDING_CONTENT);
super.btnPane.setPadding(isEmpty ? Insets.EMPTY : PADDING_BUTTON); super.btnPane.setPadding(isEmpty ? Insets.EMPTY : PADDING_BUTTON);
}); });
TimiFX.toggleStyleClass4Binding(input, emptyButton, CSS.BORDER_T, CSS.BORDER_ALL); input.borderProperty().bind(Bindings.when(emptyButton).then(Stroke.TOP).otherwise(Stroke.DEFAULT));
root.borderProperty().bind(Bindings.when(tips.visibleProperty()).then(Stroke.TOP).otherwise(Border.EMPTY)); root.borderProperty().bind(Bindings.when(tips.visibleProperty()).then(Stroke.TOP).otherwise(Border.EMPTY));
} }
@@ -117,7 +118,7 @@ public class AlertTextArea extends AbstractAlertInput<TextArea> {
AlertTextArea alert = new AlertTextArea(content); AlertTextArea alert = new AlertTextArea(content);
alert.getInput().setEditable(false); alert.getInput().setEditable(false);
alert.clearButton(); alert.clearButton();
TimiFX.showCenter(owner, alert); Windows.showCentered(owner, alert);
return alert; return alert;
} }
@@ -146,7 +147,7 @@ public class AlertTextArea extends AbstractAlertInput<TextArea> {
alert.getInput().setPrefSize(750, 340); alert.getInput().setPrefSize(750, 340);
alert.content.setPadding(Insets.EMPTY); alert.content.setPadding(Insets.EMPTY);
alert.btnPane.setPadding(Insets.EMPTY); alert.btnPane.setPadding(Insets.EMPTY);
TimiFX.showCenter(owner, alert); Windows.showCentered(owner, alert);
return alert; return alert;
} }
@@ -2,7 +2,7 @@ package com.imyeyu.fx.ui.components.navigation;
import com.imyeyu.fx.TimiFX; import com.imyeyu.fx.TimiFX;
import com.imyeyu.fx.ui.TimiFXUI; import com.imyeyu.fx.ui.TimiFXUI;
import com.imyeyu.fx.utils.SmoothScroll; import com.imyeyu.fx.utils.scroll.SmoothScroll;
import javafx.beans.property.DoubleProperty; import javafx.beans.property.DoubleProperty;
import javafx.beans.property.ObjectProperty; import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleDoubleProperty; import javafx.beans.property.SimpleDoubleProperty;
@@ -94,7 +94,7 @@ public class Navigation extends ScrollPane implements TimiFXUI {
setFitToWidth(true); setFitToWidth(true);
setContent(contentBox); setContent(contentBox);
SmoothScroll.scrollPaneV(this); SmoothScroll.pane.install(this);
} }
/** /**
@@ -3,6 +3,7 @@ package com.imyeyu.fx.ui.components.table;
import com.imyeyu.fx.ui.TimiFXUI; import com.imyeyu.fx.ui.TimiFXUI;
import javafx.beans.property.StringProperty; import javafx.beans.property.StringProperty;
import javafx.scene.control.TextField; import javafx.scene.control.TextField;
import javafx.scene.layout.Border;
/** /**
* 表格可编辑单元格,相对原始的可编辑效果,此单元格没有输入框的样式,就像 Excel 那样 * 表格可编辑单元格,相对原始的可编辑效果,此单元格没有输入框的样式,就像 Excel 那样
@@ -27,7 +28,7 @@ public abstract class TextFieldTableCell<S> extends BindingTableCell<S, String,
@Override @Override
protected final TextField component() { protected final TextField component() {
TextField textField = new TextField(); TextField textField = new TextField();
textField.getStyleClass().add(CSS.BORDER_N); textField.setBorder(Border.EMPTY);
return textField; return textField;
} }
@@ -425,4 +425,3 @@
-fx-pref-height: 1; -fx-pref-height: 1;
-fx-background-color: -timi-fx-border-color; -fx-background-color: -timi-fx-border-color;
} }
@@ -1,5 +1,4 @@
@import "base.css"; @import "base.css";
@import "controls.css";
@import "layout.css"; @import "layout.css";
@import "utility.css"; @import "utility.css";
@@ -0,0 +1,2 @@
@import "base.css";
@import "controls.css";
@@ -4,7 +4,7 @@ import com.imyeyu.fx.bean.Interpolates;
import com.imyeyu.fx.ui.MinecraftFont; import com.imyeyu.fx.ui.MinecraftFont;
import com.imyeyu.fx.ui.TimiFXUI; import com.imyeyu.fx.ui.TimiFXUI;
import com.imyeyu.fx.ui.components.SelectableLabel; import com.imyeyu.fx.ui.components.SelectableLabel;
import com.imyeyu.fx.utils.BgFill; import com.imyeyu.fx.utils.bg.BackgroundFillBuilder;
import com.sun.scenario.animation.SplineInterpolator; import com.sun.scenario.animation.SplineInterpolator;
import javafx.animation.TranslateTransition; import javafx.animation.TranslateTransition;
import javafx.geometry.Insets; import javafx.geometry.Insets;
@@ -41,7 +41,7 @@ public class InterpolatorPane extends BorderPane implements TimiFXUI {
// 方块 // 方块
block = new Region(); block = new Region();
block.setBackground(BgFill.test()); block.setBackground(BackgroundFillBuilder.test());
// 轨道 // 轨道
HBox track = new HBox(block); HBox track = new HBox(block);
@@ -31,9 +31,8 @@ public class Sidebar extends Navigation {
Item alert = new Item(SidebarItem.ALERT); Item alert = new Item(SidebarItem.ALERT);
Item popupTips = new Item(SidebarItem.POPUP_TIPS); Item popupTips = new Item(SidebarItem.POPUP_TIPS);
Item runAsync = new Item(SidebarItem.RUN_ASYNC); Item runAsync = new Item(SidebarItem.RUN_ASYNC);
Item animationRenderer = new Item(SidebarItem.ANIMATION_RENDERER);
add(welcome, style, extendTools, bindingConfig, alert, popupTips, runAsync, animationRenderer); add(welcome, style, extendTools, bindingConfig, alert, popupTips, runAsync);
// 动画 // 动画
Item interpolator = new Item(SidebarItem.INTERPOLATOR); Item interpolator = new Item(SidebarItem.INTERPOLATOR);
@@ -54,7 +53,7 @@ public class Sidebar extends Navigation {
Item screen = new Item(SidebarItem.SCREEN); Item screen = new Item(SidebarItem.SCREEN);
Item tray = new Item(SidebarItem.TRAY); Item tray = new Item(SidebarItem.TRAY);
add(new NavigationGroup(TimiFXUI.MULTILINGUAL.text("other")).add(draggableNode, draggableWindow, screen, tray)); add(new NavigationGroup(TimiFXUI.MULTILINGUAL.text("other")).add(draggableNode, draggableWindow, screen, tray));
getStyleClass().add(CSS.BORDER_R); setBorder(Stroke.RIGHT);
setMinWidth(140); setMinWidth(140);
// ---------- 事件 ---------- // ---------- 事件 ----------
@@ -4,7 +4,6 @@ import com.imyeyu.fx.ui.TimiFXUI;
import com.imyeyu.fx.ui.examples.TimiFXExamples; import com.imyeyu.fx.ui.examples.TimiFXExamples;
import com.imyeyu.fx.ui.examples.component.AbstractPane; import com.imyeyu.fx.ui.examples.component.AbstractPane;
import com.imyeyu.fx.ui.examples.view.pages.AlertDemo; import com.imyeyu.fx.ui.examples.view.pages.AlertDemo;
import com.imyeyu.fx.ui.examples.view.pages.AnimationRendererDemo;
import com.imyeyu.fx.ui.examples.view.pages.BindingsConfigDemo; import com.imyeyu.fx.ui.examples.view.pages.BindingsConfigDemo;
import com.imyeyu.fx.ui.examples.view.pages.ButtonDemo; import com.imyeyu.fx.ui.examples.view.pages.ButtonDemo;
import com.imyeyu.fx.ui.examples.view.pages.ExtendDemo; import com.imyeyu.fx.ui.examples.view.pages.ExtendDemo;
@@ -69,9 +68,6 @@ public enum SidebarItem {
/** 异步任务 */ /** 异步任务 */
RUN_ASYNC(RunAsyncDemo.class, TimiFXUI.MULTILINGUAL.text("fx.example.run_async")), RUN_ASYNC(RunAsyncDemo.class, TimiFXUI.MULTILINGUAL.text("fx.example.run_async")),
/** 异步任务 */
ANIMATION_RENDERER(AnimationRendererDemo.class, TimiFXUI.MULTILINGUAL.text("fx.example.animation_renderer")),
// ---------- 动画 ---------- // ---------- 动画 ----------
/** 动画插值器 */ /** 动画插值器 */
@@ -17,7 +17,7 @@ import javafx.scene.image.Image;
@Configuration @Configuration
public class Resources implements TimiFXUI { public class Resources implements TimiFXUI {
public static final Image ICON_X64 = new Image(RESOURCE + "icon.png", 64, 64, true, false); public static final Image ICON_X64 = new Image(RESOURCE + "/icon.png", 64, 64, true, false);
/** @return 配置 */ /** @return 配置 */
@Bean @Bean
@@ -32,7 +32,7 @@ public abstract class ViewMain extends Application implements TimiFXUI {
perspectiveCamera.setTranslateZ(0); perspectiveCamera.setTranslateZ(0);
Scene scene = new Scene(root); Scene scene = new Scene(root);
scene.getStylesheets().addAll(CSS_STYLE, CSS_FONT); TimiFXUI.applyStyle(scene);
scene.setCamera(perspectiveCamera); scene.setCamera(perspectiveCamera);
stage.setTitle(TimiFXUI.MULTILINGUAL.text("fx.example.title")); stage.setTitle(TimiFXUI.MULTILINGUAL.text("fx.example.title"));
stage.getIcons().add(new Image(RESOURCE + "icon.png")); stage.getIcons().add(new Image(RESOURCE + "icon.png"));
@@ -15,7 +15,7 @@ import com.imyeyu.fx.ui.components.alert.AlertTips;
import com.imyeyu.fx.ui.components.alert.AlertType; import com.imyeyu.fx.ui.components.alert.AlertType;
import com.imyeyu.fx.ui.examples.component.AbstractDemoPane; import com.imyeyu.fx.ui.examples.component.AbstractDemoPane;
import com.imyeyu.fx.ui.examples.component.sidebar.SidebarItem; import com.imyeyu.fx.ui.examples.component.sidebar.SidebarItem;
import com.imyeyu.fx.utils.Column; import com.imyeyu.fx.utils.grid.Column;
import com.imyeyu.inject.annotation.Component; import com.imyeyu.inject.annotation.Component;
import com.imyeyu.java.bean.timi.TimiCode; import com.imyeyu.java.bean.timi.TimiCode;
import com.imyeyu.java.bean.timi.TimiException; import com.imyeyu.java.bean.timi.TimiException;
@@ -26,8 +26,14 @@ import javafx.scene.control.CheckBox;
import javafx.scene.control.ComboBox; import javafx.scene.control.ComboBox;
import javafx.scene.control.ListView; import javafx.scene.control.ListView;
import javafx.scene.control.SelectionMode; import javafx.scene.control.SelectionMode;
import javafx.scene.layout.Border;
import javafx.scene.layout.BorderStroke;
import javafx.scene.layout.BorderStrokeStyle;
import javafx.scene.layout.BorderWidths;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.GridPane; import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
/** /**
* 弹出窗体 * 弹出窗体
@@ -45,47 +51,47 @@ public class AlertDemo extends AbstractDemoPane {
// 一般 // 一般
Button info = new Button(TimiFXUI.MULTILINGUAL.text("info")); Button info = new Button(TimiFXUI.MULTILINGUAL.text("info"));
info.getStyleClass().add(CSS.BORDER_BLT); info.setBorder(Stroke.EX_RIGHT);
Button warning = new Button(TimiFXUI.MULTILINGUAL.text("warning")); Button warning = new Button(TimiFXUI.MULTILINGUAL.text("warning"));
warning.getStyleClass().add(CSS.BORDER_BLT); warning.setBorder(Stroke.EX_RIGHT);
Button warningDanger = new Button(TimiFXUI.MULTILINGUAL.text("warning")); Button warningDanger = new Button(TimiFXUI.MULTILINGUAL.text("warning"));
warningDanger.getStyleClass().add(CSS.BORDER_BLT); warningDanger.setBorder(Stroke.EX_RIGHT);
Button error = new Button(TimiFXUI.MULTILINGUAL.text("error")); Button error = new Button(TimiFXUI.MULTILINGUAL.text("error"));
error.getStyleClass().add(CSS.BORDER_BLT); error.setBorder(Stroke.EX_RIGHT);
Button deadlyError = new Button(TimiFXUI.MULTILINGUAL.text("fx.example.alert.deadly_error")); Button deadlyError = new Button(TimiFXUI.MULTILINGUAL.text("fx.example.alert.deadly_error"));
// 询问 // 询问
Button confirmInfo = new Button(TimiFXUI.MULTILINGUAL.text("info")); Button confirmInfo = new Button(TimiFXUI.MULTILINGUAL.text("info"));
confirmInfo.getStyleClass().add(CSS.BORDER_BLT); confirmInfo.setBorder(Stroke.EX_RIGHT);
Button confirmWarning = new Button(TimiFXUI.MULTILINGUAL.text("warning")); Button confirmWarning = new Button(TimiFXUI.MULTILINGUAL.text("warning"));
confirmWarning.getStyleClass().add(CSS.BORDER_BLT); confirmWarning.setBorder(Stroke.EX_RIGHT);
Button confirmWarningDanger = new Button(TimiFXUI.MULTILINGUAL.text("warning")); Button confirmWarningDanger = new Button(TimiFXUI.MULTILINGUAL.text("warning"));
confirmWarningDanger.getStyleClass().add(CSS.BORDER_BLT); confirmWarningDanger.setBorder(Stroke.EX_RIGHT);
Button confirmError = new Button(TimiFXUI.MULTILINGUAL.text("error")); Button confirmError = new Button(TimiFXUI.MULTILINGUAL.text("error"));
confirmError.getStyleClass().add(CSS.BORDER_BLT); confirmError.setBorder(Stroke.EX_RIGHT);
Button confirmCancel = new Button(TimiFXUI.MULTILINGUAL.text("fx.example.alert.can_cancel")); Button confirmCancel = new Button(TimiFXUI.MULTILINGUAL.text("fx.example.alert.can_cancel"));
// 输入 // 输入
Button textField = new Button(TimiFXUI.MULTILINGUAL.text("fx.example.alert.text_field")); Button textField = new Button(TimiFXUI.MULTILINGUAL.text("fx.example.alert.text_field"));
textField.getStyleClass().add(CSS.BORDER_BLT); textField.setBorder(Stroke.EX_RIGHT);
Button textArea = new Button(TimiFXUI.MULTILINGUAL.text("fx.example.alert.text_area")); Button textArea = new Button(TimiFXUI.MULTILINGUAL.text("fx.example.alert.text_area"));
// 文件 // 文件
Button file = new Button(TimiFXUI.MULTILINGUAL.text("file.select")); Button file = new Button(TimiFXUI.MULTILINGUAL.text("file.select"));
file.getStyleClass().add(CSS.BORDER_BLT); file.setBorder(Stroke.EX_RIGHT);
Button directory = new Button(TimiFXUI.MULTILINGUAL.text("file.select.directory")); Button directory = new Button(TimiFXUI.MULTILINGUAL.text("file.select.directory"));
directory.getStyleClass().add(CSS.BORDER_BLT); directory.setBorder(Stroke.EX_RIGHT);
Button fileBlend = new Button(TimiFXUI.MULTILINGUAL.text("fx.example.alert.file_blend")); Button fileBlend = new Button(TimiFXUI.MULTILINGUAL.text("fx.example.alert.file_blend"));
// 加载中 // 加载中
Button loading = new Button(TimiFXUI.MULTILINGUAL.text("loading")); Button loading = new Button(TimiFXUI.MULTILINGUAL.text("loading"));
loading.getStyleClass().add(CSS.BORDER_BLT); loading.setBorder(Stroke.EX_RIGHT);
// 自定义 // 自定义
Button custom = new Button(TimiFXUI.MULTILINGUAL.text("custom")); Button custom = new Button(TimiFXUI.MULTILINGUAL.text("custom"));
setCenter(new GridPane() {{ setCenter(new GridPane() {{
getColumnConstraints().addAll(Column.KEY, Column.KEY); getColumnConstraints().addAll(Column.key(), Column.key());
setHgap(12); setHgap(12);
setVgap(6); setVgap(6);
setPadding(new Insets(20)); setPadding(new Insets(20));
@@ -1,172 +0,0 @@
package com.imyeyu.fx.ui.examples.view.pages;
import com.imyeyu.fx.BindingUtils;
import com.imyeyu.fx.TimiFX;
import com.imyeyu.fx.ui.TimiFXUI;
import com.imyeyu.fx.ui.components.SelectableLabel;
import com.imyeyu.fx.ui.components.TextAreaEditor;
import com.imyeyu.fx.ui.components.alert.AlertTips;
import com.imyeyu.fx.ui.components.popup.PopupTipsService;
import com.imyeyu.fx.ui.examples.TimiFXExamples;
import com.imyeyu.fx.ui.examples.component.AbstractDemoPane;
import com.imyeyu.fx.ui.examples.component.sidebar.SidebarItem;
import com.imyeyu.fx.ui.examples.ctrl.Main;
import com.imyeyu.fx.utils.AnimationRenderer;
import com.imyeyu.fx.utils.Column;
import com.imyeyu.inject.annotation.Component;
import com.imyeyu.io.IO;
import com.imyeyu.utils.OS;
import javafx.geometry.Insets;
import javafx.geometry.Point3D;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.control.SplitPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Box;
import javafx.scene.shape.CullFace;
import javafx.scene.shape.DrawMode;
/**
* 动画渲染器
*
* @author 夜雨
* @since 2023-04-13 10:46
*/
@Component
public class AnimationRendererDemo extends AbstractDemoPane implements OS.FileSystem {
private final AnimationRenderer renderer;
public AnimationRendererDemo() {
title.setText(SidebarItem.ANIMATION_RENDERER.getText());
document.sync("https://doc.imyeyu.net/timi-fx/net/imyeyu/timifx/extend/AnimationRenderer.html");
source.sync("https://git.imyeyu.net/Timi/timi-fx/src/master/src/main/java/net/imyeyu/timifx/extend/AnimationRenderer.java");
tips.setText(TimiFXUI.MULTILINGUAL.text("fx.example.animation_renderer.tips"));
// 动画旋转立方体
Box box = new Box(128, 128, 128);
box.setDrawMode(DrawMode.LINE);
box.setCullFace(CullFace.BACK);
box.setMaterial(new PhongMaterial(Colorful.BLACK));
box.setTranslateY(60);
box.setRotationAxis(new Point3D(0, 64, 0));
renderer = new AnimationRenderer();
renderer.addRenderCallback(deltaSecond -> box.setRotate(box.getRotate() + 90 * deltaSecond));
String value = System.getProperty("javafx.animation.fullspeed");
boolean isFullSpeed = value != null && value.equalsIgnoreCase("true");
// 当前状态
Label labelStatus = TimiFXUI.label(TimiFXUI.MULTILINGUAL.text("fx.example.animation_renderer.status"));
SelectableLabel status = new SelectableLabel("-Djavafx.animation.fullspeed=" + isFullSpeed);
// 重启
Button restart = new Button(TimiFXUI.MULTILINGUAL.text("fx.example.animation_renderer.restart"));
// 示例
Label labelDemo = TimiFXUI.title(TimiFXUI.MULTILINGUAL.text("example"));
TextAreaEditor demo = new TextAreaEditor();
demo.getStyleClass().add(CSS.BORDER_N);
demo.setEditable(false);
demo.setText("""
Box box = new Box(128, 128, 128);
box.setDrawMode(DrawMode.LINE);
box.setCullFace(CullFace.BACK);
box.setMaterial(new PhongMaterial(RED));
box.setRotationAxis(new Point3D(0, 64, 0));
// 每秒 90 度旋转一个 3D 立方体,默认 60 FPS
AnimationRenderer renderer = new AnimationRenderer();
renderer.addRenderCallback(deltaSecond -> {
box.setRotate(box.getRotate() + 90 * deltaSecond);
});
// 控制 FPS
Slider fps = new Slider(5, 240, 60);
fps.valueProperty().addListener((obs, o, newFps) -> {
renderer.setPrefFPS(newFps.intValue())
});
""".trim());
// 预设 FPS
Label labelPrefFPS = TimiFXUI.label(TimiFXUI.MULTILINGUAL.text("fx.example.animation_renderer.pref_fps"));
Slider prefFPS = new Slider(5, 240, 60);
prefFPS.valueProperty().addListener((obs, o, newFps) -> renderer.setPrefFPS(newFps.intValue()));
PopupTipsService.installBindingText(prefFPS, BindingUtils.integerStringBinding(prefFPS.valueProperty()));
renderer.setPrefFPS((int) prefFPS.getValue());
// 当前渲染 FPS
Label labelFPS = TimiFXUI.label(TimiFXUI.MULTILINGUAL.text("fps"));
Label fps = new Label();
fps.textProperty().bind(renderer.fpsProperty().asString("%d"));
Label labelMPF = TimiFXUI.label(TimiFXUI.MULTILINGUAL.text("mpf"));
Label mpf = new Label();
mpf.textProperty().bind(renderer.mpfProperty().asString("%.2f ms"));
setCenter(new BorderPane() {{
setTop(new GridPane() {{
getColumnConstraints().addAll(Column.KEY, Column.VALUE_FILL);
setVgap(6);
setHgap(6);
setPadding(new Insets(20));
addRow(0, labelStatus, status);
add(restart, 1, 1);
}});
setCenter(new BorderPane() {{
setBorder(Stroke.TOP);
setTop(labelDemo);
setCenter(new SplitPane() {{
setBorder(Stroke.TOP);
setDividerPositions(.5);
getItems().addAll(demo, new BorderPane() {{
setTop(new GridPane() {{
getColumnConstraints().addAll(Column.KEY, Column.VALUE_FILL);
setHgap(6);
setVgap(6);
setPadding(new Insets(8, 12, 8, 12));
setBorder(Stroke.BOTTOM);
int row = 0;
addRow(row++, labelPrefFPS, prefFPS);
addRow(row++, labelFPS, fps);
addRow(row, labelMPF, mpf);
}});
setCenter(box);
}});
}});
}});
}});
// ---------- 事件 ----------
restart.setOnAction(e -> {
// JRE
String jre = System.getProperty("java.home") + SEP + "bin" + SEP + "java";
// 启动参数
String param = " -Djavafx.animation.fullspeed=%s -XX:+UnlockExperimentalVMOptions -XX:+UseZGC -jar ".formatted(!isFullSpeed);
// 启动 Jar
String jar = IO.getJarAbsolutePath(getClass());
// 重启
try {
TimiFX.doRestart(TimiFXExamples.getInject().getBean(Main.class), jre + param + jar);
} catch (Exception ex) {
AlertTips.error(getScene().getWindow(), TimiFXUI.MULTILINGUAL.text("tips.restart.error"));
}
});
}
@Override
protected void onShow() {
renderer.start();
}
@Override
protected void onHide() {
renderer.stop();
}
}
@@ -5,7 +5,7 @@ import com.imyeyu.fx.ui.components.Hyperlink;
import com.imyeyu.fx.ui.components.TitleLabel; import com.imyeyu.fx.ui.components.TitleLabel;
import com.imyeyu.fx.ui.examples.component.AbstractDemoPane; import com.imyeyu.fx.ui.examples.component.AbstractDemoPane;
import com.imyeyu.fx.ui.examples.component.sidebar.SidebarItem; import com.imyeyu.fx.ui.examples.component.sidebar.SidebarItem;
import com.imyeyu.fx.utils.SmoothScroll; import com.imyeyu.fx.utils.scroll.SmoothScroll;
import com.imyeyu.inject.annotation.Component; import com.imyeyu.inject.annotation.Component;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.scene.control.ScrollPane; import javafx.scene.control.ScrollPane;
@@ -81,7 +81,7 @@ public class ExtendDemo extends AbstractDemoPane {
source.sync("https://git.imyeyu.net/Timi/timi-fx/src/master/src/main/java/net/imyeyu/timifx/extend/XAnchorPane.java"); source.sync("https://git.imyeyu.net/Timi/timi-fx/src/master/src/main/java/net/imyeyu/timifx/extend/XAnchorPane.java");
}}); }});
}}); }});
SmoothScroll.scrollPane(this); SmoothScroll.pane.install(this);
}}); }});
} }
@@ -35,21 +35,21 @@ public class PopupTipsDemo extends AbstractDemoPane {
// 长文本 // 长文本
Button textLong = new Button(TimiFXUI.MULTILINGUAL.text("fx.example.popup_tips.text_long")); Button textLong = new Button(TimiFXUI.MULTILINGUAL.text("fx.example.popup_tips.text_long"));
textLong.getStyleClass().add(CSS.BORDER_TRB); textLong.setBorder(Stroke.EX_LEFT);
PopupTipsService.installText(textLong, TimiFXUI.MULTILINGUAL.text("fx.example.demo.text_long")); PopupTipsService.installText(textLong, TimiFXUI.MULTILINGUAL.text("fx.example.demo.text_long"));
// 图片 // 图片
Button image = new Button(TimiFXUI.MULTILINGUAL.text("image")); Button image = new Button(TimiFXUI.MULTILINGUAL.text("image"));
image.getStyleClass().add(CSS.BORDER_TRB); image.setBorder(Stroke.EX_LEFT);
PopupTipsService.installImage(image, new Image(RESOURCE + "icon.png", 64, 64, false, false)); PopupTipsService.installImage(image, new Image(RESOURCE + "icon.png", 64, 64, false, false));
// 自定义 // 自定义
Button custom = new Button(TimiFXUI.MULTILINGUAL.text("custom")); Button custom = new Button(TimiFXUI.MULTILINGUAL.text("custom"));
custom.getStyleClass().add(CSS.BORDER_TRB); custom.setBorder(Stroke.EX_LEFT);
// 保持显示 // 保持显示
Button keepShow = new Button(TimiFXUI.MULTILINGUAL.text("fx.example.popup_tips.keep_show")); Button keepShow = new Button(TimiFXUI.MULTILINGUAL.text("fx.example.popup_tips.keep_show"));
keepShow.getStyleClass().add(CSS.BORDER_TRB); keepShow.setBorder(Stroke.EX_LEFT);
{ {
ListView<String> list = new ListView<>(); ListView<String> list = new ListView<>();
for (int i = 0; i < 20; i++) { for (int i = 0; i < 20; i++) {
@@ -4,8 +4,8 @@ import com.imyeyu.fx.ui.TimiFXUI;
import com.imyeyu.fx.ui.components.Hyperlink; import com.imyeyu.fx.ui.components.Hyperlink;
import com.imyeyu.fx.ui.components.TitleLabel; import com.imyeyu.fx.ui.components.TitleLabel;
import com.imyeyu.fx.ui.examples.component.AbstractPane; import com.imyeyu.fx.ui.examples.component.AbstractPane;
import com.imyeyu.fx.utils.BgFill; import com.imyeyu.fx.utils.bg.BackgroundFillBuilder;
import com.imyeyu.fx.utils.Column; import com.imyeyu.fx.utils.grid.Column;
import com.imyeyu.inject.annotation.Component; import com.imyeyu.inject.annotation.Component;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.scene.control.Label; import javafx.scene.control.Label;
@@ -85,7 +85,7 @@ public class Style extends AbstractPane {
getChildren().addAll(new BorderPane() {{ getChildren().addAll(new BorderPane() {{
setTop(titleTimiFX); setTop(titleTimiFX);
setCenter(new GridPane() {{ setCenter(new GridPane() {{
getColumnConstraints().addAll(Column.KEY, Column.VALUE_FILL); getColumnConstraints().addAll(Column.key(), Column.valueFill());
setVgap(8); setVgap(8);
setHgap(10); setHgap(10);
setPadding(CONTENT_PADDING); setPadding(CONTENT_PADDING);
@@ -98,7 +98,7 @@ public class Style extends AbstractPane {
}}, new BorderPane() {{ }}, new BorderPane() {{
setTop(titleColor); setTop(titleColor);
setCenter(new GridPane() {{ setCenter(new GridPane() {{
getColumnConstraints().addAll(Column.KEY, Column.VALUE_FILL); getColumnConstraints().addAll(Column.key(), Column.valueFill());
setVgap(8); setVgap(8);
setHgap(10); setHgap(10);
setPadding(CONTENT_PADDING); setPadding(CONTENT_PADDING);
@@ -134,7 +134,7 @@ public class Style extends AbstractPane {
}}, new BorderPane() {{ }}, new BorderPane() {{
setTop(styleFile); setTop(styleFile);
setCenter(new GridPane() {{ setCenter(new GridPane() {{
getColumnConstraints().addAll(Column.KEY, Column.VALUE_FILL); getColumnConstraints().addAll(Column.key(), Column.valueFill());
setVgap(8); setVgap(8);
setHgap(10); setHgap(10);
setPadding(CONTENT_PADDING); setPadding(CONTENT_PADDING);
@@ -152,7 +152,7 @@ public class Style extends AbstractPane {
* @return 标签 * @return 标签
*/ */
private Label colorLabel(String text, Paint color) { private Label colorLabel(String text, Paint color) {
return colorLabel(text, new BgFill(color).build()); return colorLabel(text, BackgroundFillBuilder.solid(color).build());
} }
/** /**
@@ -1,6 +1,5 @@
package com.imyeyu.fx.ui.examples.view.pages; package com.imyeyu.fx.ui.examples.view.pages;
import com.imyeyu.fx.TimiFX;
import com.imyeyu.fx.ui.MinecraftFont; import com.imyeyu.fx.ui.MinecraftFont;
import com.imyeyu.fx.ui.TimiFXUI; import com.imyeyu.fx.ui.TimiFXUI;
import com.imyeyu.fx.ui.components.alert.AlertConfirm; import com.imyeyu.fx.ui.components.alert.AlertConfirm;
@@ -11,13 +10,13 @@ import com.imyeyu.fx.ui.examples.component.AbstractPane;
import com.imyeyu.fx.ui.examples.component.TimiVersionLabel; import com.imyeyu.fx.ui.examples.component.TimiVersionLabel;
import com.imyeyu.fx.ui.examples.ctrl.Main; import com.imyeyu.fx.ui.examples.ctrl.Main;
import com.imyeyu.fx.ui.examples.util.Resources; import com.imyeyu.fx.ui.examples.util.Resources;
import com.imyeyu.fx.utils.Column; import com.imyeyu.fx.utils.FXApplication;
import com.imyeyu.fx.utils.grid.Column;
import com.imyeyu.inject.annotation.Component; import com.imyeyu.inject.annotation.Component;
import com.imyeyu.inject.annotation.PostConstruct; import com.imyeyu.inject.annotation.PostConstruct;
import com.imyeyu.io.IO; import com.imyeyu.io.IO;
import com.imyeyu.java.bean.Language; import com.imyeyu.java.bean.Language;
import com.imyeyu.utils.OS; import com.imyeyu.utils.OS;
import javafx.geometry.HPos;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.control.ComboBox; import javafx.scene.control.ComboBox;
@@ -26,7 +25,6 @@ import javafx.scene.image.ImageView;
import javafx.scene.layout.GridPane; import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import javafx.scene.text.TextAlignment;
import javafx.util.StringConverter; import javafx.util.StringConverter;
/** /**
@@ -96,7 +94,7 @@ public class Welcome extends AbstractPane implements OS.FileSystem {
getChildren().add(new Label(TimiFXUI.MULTILINGUAL.text("fx.example.welcome.tips1"))); getChildren().add(new Label(TimiFXUI.MULTILINGUAL.text("fx.example.welcome.tips1")));
getChildren().add(new Label(TimiFXUI.MULTILINGUAL.text("fx.example.welcome.tips2"))); getChildren().add(new Label(TimiFXUI.MULTILINGUAL.text("fx.example.welcome.tips2")));
getChildren().add(new GridPane() {{ getChildren().add(new GridPane() {{
getColumnConstraints().addAll(Column.build(HPos.RIGHT), Column.VALUE); getColumnConstraints().addAll(Column.builder().right().build(), Column.value());
setHgap(8); setHgap(8);
setVgap(6); setVgap(6);
setPadding(new Insets(12, 0, 4, 0)); setPadding(new Insets(12, 0, 4, 0));
@@ -138,7 +136,7 @@ public class Welcome extends AbstractPane implements OS.FileSystem {
String jar = IO.getJarAbsolutePath(getClass()); String jar = IO.getJarAbsolutePath(getClass());
// 重启 // 重启
try { try {
TimiFX.doRestart(TimiFXExamples.getInject().getBean(Main.class), jre + param + jar); FXApplication.restart(TimiFXExamples.getInject().getBean(Main.class), jre + param + jar);
} catch (Exception ex) { } catch (Exception ex) {
AlertTips.error(this, TimiFXUI.MULTILINGUAL.text("tips.restart.error")); AlertTips.error(this, TimiFXUI.MULTILINGUAL.text("tips.restart.error"));
} }
@@ -6,7 +6,7 @@ import com.imyeyu.fx.ui.examples.bean.Config;
import com.imyeyu.fx.ui.examples.component.AbstractDemoPane; import com.imyeyu.fx.ui.examples.component.AbstractDemoPane;
import com.imyeyu.fx.ui.examples.component.animation.InterpolatorPane; import com.imyeyu.fx.ui.examples.component.animation.InterpolatorPane;
import com.imyeyu.fx.ui.examples.component.sidebar.SidebarItem; import com.imyeyu.fx.ui.examples.component.sidebar.SidebarItem;
import com.imyeyu.fx.utils.SmoothScroll; import com.imyeyu.fx.utils.scroll.SmoothScroll;
import com.imyeyu.inject.annotation.Component; import com.imyeyu.inject.annotation.Component;
import com.imyeyu.inject.annotation.PostConstruct; import com.imyeyu.inject.annotation.PostConstruct;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
@@ -46,7 +46,7 @@ public class InterpolatorDemo extends AbstractDemoPane {
// 重置 // 重置
Button reset = new Button(TimiFXUI.MULTILINGUAL.text("reset")); Button reset = new Button(TimiFXUI.MULTILINGUAL.text("reset"));
reset.getStyleClass().add(CSS.BORDER_TRB); reset.setBorder(Stroke.EX_LEFT);
// 持续时间 // 持续时间
duration = new Slider(); duration = new Slider();
@@ -102,7 +102,7 @@ public class InterpolatorDemo extends AbstractDemoPane {
setPadding(new Insets(12, 0, 12, 0)); setPadding(new Insets(12, 0, 12, 0));
getChildren().addAll(panes); getChildren().addAll(panes);
}}); }});
SmoothScroll.scrollPane(this); SmoothScroll.pane.install(this);
}}); }});
}}); }});
@@ -5,12 +5,11 @@ import com.imyeyu.fx.task.RunAsyncScheduled;
import com.imyeyu.fx.ui.TimiFXUI; import com.imyeyu.fx.ui.TimiFXUI;
import com.imyeyu.fx.ui.examples.component.AbstractDemoPane; import com.imyeyu.fx.ui.examples.component.AbstractDemoPane;
import com.imyeyu.fx.ui.examples.component.sidebar.SidebarItem; import com.imyeyu.fx.ui.examples.component.sidebar.SidebarItem;
import com.imyeyu.fx.utils.Column; import com.imyeyu.fx.utils.grid.Column;
import com.imyeyu.fx.utils.SmoothScroll; import com.imyeyu.fx.utils.scroll.SmoothScroll;
import com.imyeyu.inject.annotation.Component; import com.imyeyu.inject.annotation.Component;
import com.imyeyu.utils.Calc; import com.imyeyu.utils.Calc;
import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleObjectProperty;
import javafx.geometry.HPos;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.control.ComboBox; import javafx.scene.control.ComboBox;
@@ -46,7 +45,7 @@ public class SmoothScrollDemo extends AbstractDemoPane {
// 下拉框 // 下拉框
ComboBox<String> comboBoxDef = new ComboBox<>(); ComboBox<String> comboBoxDef = new ComboBox<>();
ComboBox<String> comboBox = new ComboBox<>(); ComboBox<String> comboBox = new ComboBox<>();
SmoothScroll.comboBox(comboBox); SmoothScroll.virtual.install(comboBox);
// 滚动面板 // 滚动面板
VBox spDefVB = new VBox(); VBox spDefVB = new VBox();
@@ -55,37 +54,42 @@ public class SmoothScrollDemo extends AbstractDemoPane {
ScrollPane scrollPane = new ScrollPane(spVB); ScrollPane scrollPane = new ScrollPane(spVB);
scrollPaneDef.setBorder(Stroke.LT); scrollPaneDef.setBorder(Stroke.LT);
scrollPane.setBorder(Stroke.LT); scrollPane.setBorder(Stroke.LT);
SmoothScroll.scrollPane(scrollPane); SmoothScroll.pane.install(scrollPane);
// 文本域 // 文本域
TextArea textAreaDef = new TextArea(); TextArea textAreaDef = new TextArea();
TextArea textArea = new TextArea(); TextArea textArea = new TextArea();
textAreaDef.getStyleClass().add(CSS.BORDER_LT); textAreaDef.setBorder(Stroke.LT);
textArea.getStyleClass().add(CSS.BORDER_LT); textArea.setBorder(Stroke.LT);
SmoothScroll.textarea(textArea); SmoothScroll.text.install(textArea);
// 列表 // 列表
ListView<String> listViewDef = new ListView<>(); ListView<String> listViewDef = new ListView<>();
ListView<String> listView = new ListView<>(); ListView<String> listView = new ListView<>();
listViewDef.getStyleClass().add(CSS.BORDER_LT); listViewDef.setBorder(Stroke.LT);
listView.getStyleClass().add(CSS.BORDER_LT); listView.setBorder(Stroke.LT);
SmoothScroll.virtual(listView); SmoothScroll.virtual.install(listView);
// 表格 // 表格
TableView<String> tableViewDef = new TableView<>(); TableView<String> tableViewDef = new TableView<>();
TableView<String> tableView = new TableView<>(); TableView<String> tableView = new TableView<>();
tableViewDef.getStyleClass().add(CSS.BORDER_LT); tableViewDef.setBorder(Stroke.LT);
tableView.getStyleClass().add(CSS.BORDER_LT); tableView.setBorder(Stroke.LT);
TableColumn<String, Object> col = new TableColumn<>("col"); TableColumn<String, Object> col = new TableColumn<>("col");
col.setCellValueFactory(param -> new SimpleObjectProperty<>(param.getValue())); col.setCellValueFactory(param -> new SimpleObjectProperty<>(param.getValue()));
tableViewDef.getColumns().add(col); tableViewDef.getColumns().add(col);
tableView.getColumns().add(col); tableView.getColumns().add(col);
SmoothScroll.virtual(tableView); SmoothScroll.virtual.install(tableView);
setCenter(new GridPane() {{ setCenter(new GridPane() {{
Column key = Column.build(HPos.RIGHT).percentWidth(10); getColumnConstraints().addAll(
Column value = Column.build(HPos.CENTER).percentWidth(18).fill(); Column.builder().right().percentWidth(10).build(),
getColumnConstraints().addAll(key, value, value, value, value, value); Column.builder().center().percentWidth(18).fill().build(),
Column.builder().center().percentWidth(18).fill().build(),
Column.builder().center().percentWidth(18).fill().build(),
Column.builder().center().percentWidth(18).fill().build(),
Column.builder().center().percentWidth(18).fill().build()
);
add(new StackPane() {{ add(new StackPane() {{
setBorder(Stroke.TOP); setBorder(Stroke.TOP);
@@ -3,7 +3,7 @@ package com.imyeyu.fx.ui.examples.view.pages.component;
import com.imyeyu.fx.ui.TimiFXUI; import com.imyeyu.fx.ui.TimiFXUI;
import com.imyeyu.fx.ui.examples.component.AbstractDemoPane; import com.imyeyu.fx.ui.examples.component.AbstractDemoPane;
import com.imyeyu.fx.ui.examples.component.sidebar.SidebarItem; import com.imyeyu.fx.ui.examples.component.sidebar.SidebarItem;
import com.imyeyu.fx.utils.Column; import com.imyeyu.fx.utils.grid.Column;
import com.imyeyu.inject.annotation.Component; import com.imyeyu.inject.annotation.Component;
import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty; import javafx.beans.property.StringProperty;
@@ -63,7 +63,7 @@ public class EditableTableCellDemo extends AbstractDemoPane {
tfxCol.prefWidthProperty().bind(tfx.widthProperty().subtract(50)); tfxCol.prefWidthProperty().bind(tfx.widthProperty().subtract(50));
setCenter(new GridPane() {{ setCenter(new GridPane() {{
getColumnConstraints().addAll(Column.VALUE_FILL, Column.VALUE_FILL); getColumnConstraints().addAll(Column.valueFill(), Column.valueFill());
setVgap(6); setVgap(6);
setHgap(20); setHgap(20);
setPadding(new Insets(32)); setPadding(new Insets(32));
@@ -4,8 +4,8 @@ import com.imyeyu.fx.ui.TimiFXUI;
import com.imyeyu.fx.ui.components.FileTreeView; import com.imyeyu.fx.ui.components.FileTreeView;
import com.imyeyu.fx.ui.examples.component.AbstractDemoPane; import com.imyeyu.fx.ui.examples.component.AbstractDemoPane;
import com.imyeyu.fx.ui.examples.component.sidebar.SidebarItem; import com.imyeyu.fx.ui.examples.component.sidebar.SidebarItem;
import com.imyeyu.fx.utils.Column; import com.imyeyu.fx.utils.grid.Column;
import com.imyeyu.fx.utils.Row; import com.imyeyu.fx.utils.grid.Row;
import com.imyeyu.inject.annotation.Component; import com.imyeyu.inject.annotation.Component;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.geometry.Pos; import javafx.geometry.Pos;
@@ -57,8 +57,8 @@ public class FileTreeViewDemo extends AbstractDemoPane {
hide.setShowHide(true); hide.setShowHide(true);
setCenter(new GridPane() {{ setCenter(new GridPane() {{
getColumnConstraints().addAll(Column.VALUE_FILL, Column.VALUE_FILL, Column.VALUE_FILL, Column.VALUE_FILL); getColumnConstraints().addAll(Column.valueFill(), Column.valueFill(), Column.valueFill(), Column.valueFill());
getRowConstraints().addAll(Row.build(), Row.build().alwaysPriority()); getRowConstraints().addAll(Row.builder().build(), Row.builder().alwaysPriority().build());
setVgap(5); setVgap(5);
setPadding(new Insets(32)); setPadding(new Insets(32));
@@ -1,6 +1,7 @@
package com.imyeyu.fx.ui.examples.view.pages.component; package com.imyeyu.fx.ui.examples.view.pages.component;
import com.imyeyu.fx.icon.TimiFXIcon; import com.imyeyu.fx.icon.TimiFXIcon;
import com.imyeyu.fx.icon.TimiIcon;
import com.imyeyu.fx.ui.TimiFXUI; import com.imyeyu.fx.ui.TimiFXUI;
import com.imyeyu.fx.ui.components.IconButton; import com.imyeyu.fx.ui.components.IconButton;
import com.imyeyu.fx.ui.examples.component.AbstractDemoPane; import com.imyeyu.fx.ui.examples.component.AbstractDemoPane;
@@ -24,16 +25,16 @@ public class IconButtonDemo extends AbstractDemoPane {
source.sync("https://git.imyeyu.net/Timi/timi-fx/src/master/src/main/java/net/imyeyu/timifx/component/IconButton.java"); source.sync("https://git.imyeyu.net/Timi/timi-fx/src/master/src/main/java/net/imyeyu/timifx/component/IconButton.java");
// 一般 // 一般
IconButton commonly = new IconButton(TimiFXUI.MULTILINGUAL.text("fx.example.icon_button"), TimiFXIcon.fromName("HAMMER")); IconButton commonly = new IconButton(TimiFXUI.MULTILINGUAL.text("fx.example.icon_button"), TimiFXIcon.get(TimiIcon.HAMMER));
// 按钮背景 // 按钮背景
IconButton commonlyWithBG = new IconButton(TimiFXUI.MULTILINGUAL.text("fx.example.icon_button"), TimiFXIcon.fromName("HAMMER")).withBackground(); IconButton commonlyWithBG = new IconButton(TimiFXUI.MULTILINGUAL.text("fx.example.icon_button"), TimiFXIcon.get(TimiIcon.HAMMER)).withBackground();
// 无文本 // 无文本
IconButton notText = new IconButton(TimiFXIcon.fromName("HAMMER")); IconButton notText = new IconButton(TimiFXIcon.get(TimiIcon.HAMMER));
// 无文本按钮背景 // 无文本按钮背景
IconButton notTextWithBG = new IconButton(TimiFXIcon.fromName("HAMMER")).withBackground(); IconButton notTextWithBG = new IconButton(TimiFXIcon.get(TimiIcon.HAMMER)).withBackground();
setCenter(new GridPane() {{ setCenter(new GridPane() {{
setVgap(4); setVgap(4);
@@ -6,8 +6,8 @@ import com.imyeyu.fx.ui.components.navigation.NavigationGroup;
import com.imyeyu.fx.ui.components.navigation.NavigationItem; import com.imyeyu.fx.ui.components.navigation.NavigationItem;
import com.imyeyu.fx.ui.examples.component.AbstractDemoPane; import com.imyeyu.fx.ui.examples.component.AbstractDemoPane;
import com.imyeyu.fx.ui.examples.component.sidebar.SidebarItem; import com.imyeyu.fx.ui.examples.component.sidebar.SidebarItem;
import com.imyeyu.fx.utils.Column; import com.imyeyu.fx.utils.grid.Column;
import com.imyeyu.fx.utils.Row; import com.imyeyu.fx.utils.grid.Row;
import com.imyeyu.inject.annotation.Component; import com.imyeyu.inject.annotation.Component;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.geometry.Pos; import javafx.geometry.Pos;
@@ -81,9 +81,13 @@ public class NavigationDemo extends AbstractDemoPane {
); );
setCenter(new GridPane() {{ setCenter(new GridPane() {{
Column col = Column.build().width(220); getColumnConstraints().addAll(
getColumnConstraints().addAll(col, col, col, col); Column.builder().width(220).build(),
getRowConstraints().addAll(Row.build(), Row.build().alwaysPriority()); Column.builder().width(220).build(),
Column.builder().width(220).build(),
Column.builder().width(220).build()
);
getRowConstraints().addAll(Row.builder().build(), Row.builder().alwaysPriority().build());
setVgap(5); setVgap(5);
setHgap(5); setHgap(5);
setPadding(new Insets(32)); setPadding(new Insets(32));
@@ -5,7 +5,7 @@ import com.imyeyu.fx.ui.components.TextAreaEditor;
import com.imyeyu.fx.ui.components.TextAreaEditorField; import com.imyeyu.fx.ui.components.TextAreaEditorField;
import com.imyeyu.fx.ui.examples.component.AbstractDemoPane; import com.imyeyu.fx.ui.examples.component.AbstractDemoPane;
import com.imyeyu.fx.ui.examples.component.sidebar.SidebarItem; import com.imyeyu.fx.ui.examples.component.sidebar.SidebarItem;
import com.imyeyu.fx.utils.Column; import com.imyeyu.fx.utils.grid.Column;
import com.imyeyu.inject.annotation.Component; import com.imyeyu.inject.annotation.Component;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.scene.control.Label; import javafx.scene.control.Label;
@@ -33,14 +33,14 @@ public class TextAreaEditorDemo extends AbstractDemoPane {
field.setTitle("TextAreaEditorField"); field.setTitle("TextAreaEditorField");
TextAreaEditor editor = new TextAreaEditor(); TextAreaEditor editor = new TextAreaEditor();
editor.getStyleClass().add(CSS.BORDER_L); editor.setBorder(Stroke.LEFT);
setCenter(new BorderPane() {{ setCenter(new BorderPane() {{
setBorder(Stroke.TOP); setBorder(Stroke.TOP);
setLeft(new BorderPane() {{ setLeft(new BorderPane() {{
setPadding(new Insets(12, 20, 12, 20)); setPadding(new Insets(12, 20, 12, 20));
setTop(new GridPane() {{ setTop(new GridPane() {{
getColumnConstraints().addAll(Column.KEY, Column.VALUE_FILL); getColumnConstraints().addAll(Column.key(), Column.valueFill());
setVgap(8); setVgap(8);
setHgap(10); setHgap(10);
@@ -1,6 +1,7 @@
package com.imyeyu.fx.ui.examples.view.pages.component; package com.imyeyu.fx.ui.examples.view.pages.component;
import com.imyeyu.fx.icon.TimiFXIcon; import com.imyeyu.fx.icon.TimiFXIcon;
import com.imyeyu.fx.icon.TimiIcon;
import com.imyeyu.fx.ui.TimiFXUI; import com.imyeyu.fx.ui.TimiFXUI;
import com.imyeyu.fx.ui.components.ToggleIcon; import com.imyeyu.fx.ui.components.ToggleIcon;
import com.imyeyu.fx.ui.examples.component.AbstractDemoPane; import com.imyeyu.fx.ui.examples.component.AbstractDemoPane;
@@ -27,16 +28,16 @@ public class ToggleIconDemo extends AbstractDemoPane {
// 默认 // 默认
Label labelDef = TimiFXUI.label(TimiFXUI.MULTILINGUAL.text("default")); Label labelDef = TimiFXUI.label(TimiFXUI.MULTILINGUAL.text("default"));
ToggleIcon def = new ToggleIcon(TimiFXIcon.fromName("ARROW_0_W")); ToggleIcon def = new ToggleIcon(TimiFXIcon.get(TimiIcon.ARROW_0_W));
// 跟随状态变换 // 跟随状态变换
Label labelDiff = TimiFXUI.label(TimiFXUI.MULTILINGUAL.text("fx.example.toggle_icon.diff")); Label labelDiff = TimiFXUI.label(TimiFXUI.MULTILINGUAL.text("fx.example.toggle_icon.diff"));
ToggleIcon diff = new ToggleIcon(TimiFXIcon.fromName("ARROW_0_W"), TimiFXIcon.fromName("ARROW_0_E")); ToggleIcon diff = new ToggleIcon(TimiFXIcon.get(TimiIcon.ARROW_0_W), TimiFXIcon.get(TimiIcon.ARROW_0_E));
// 按钮背景 // 按钮背景
Label labelWithBG = TimiFXUI.label(TimiFXUI.MULTILINGUAL.text("fx.example.toggle_icon.with_bg")); Label labelWithBG = TimiFXUI.label(TimiFXUI.MULTILINGUAL.text("fx.example.toggle_icon.with_bg"));
ToggleIcon withBG = new ToggleIcon(TimiFXIcon.fromName("ARROW_0_W")).withBackground(); ToggleIcon withBG = new ToggleIcon(TimiFXIcon.get(TimiIcon.ARROW_0_W)).withBackground();
ToggleIcon withBGDiff = new ToggleIcon(TimiFXIcon.fromName("ARROW_0_W"), TimiFXIcon.fromName("ARROW_0_E")).withBackground(); ToggleIcon withBGDiff = new ToggleIcon(TimiFXIcon.get(TimiIcon.ARROW_0_W), TimiFXIcon.get(TimiIcon.ARROW_0_E)).withBackground();
setCenter(new GridPane() {{ setCenter(new GridPane() {{
setHgap(5); setHgap(5);
@@ -4,7 +4,7 @@ import com.imyeyu.fx.ui.TimiFXUI;
import com.imyeyu.fx.ui.components.Pagination; import com.imyeyu.fx.ui.components.Pagination;
import com.imyeyu.fx.ui.examples.component.AbstractDemoPane; import com.imyeyu.fx.ui.examples.component.AbstractDemoPane;
import com.imyeyu.fx.ui.examples.component.sidebar.SidebarItem; import com.imyeyu.fx.ui.examples.component.sidebar.SidebarItem;
import com.imyeyu.fx.utils.Column; import com.imyeyu.fx.utils.grid.Column;
import com.imyeyu.inject.annotation.Component; import com.imyeyu.inject.annotation.Component;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.scene.control.Label; import javafx.scene.control.Label;
@@ -51,7 +51,7 @@ public class XPaginationDemo extends AbstractDemoPane {
setCenter(new VBox() {{ setCenter(new VBox() {{
setPadding(new Insets(20)); setPadding(new Insets(20));
getChildren().addAll(pagination, new GridPane() {{ getChildren().addAll(pagination, new GridPane() {{
getColumnConstraints().addAll(Column.build(), Column.build().width(40)); getColumnConstraints().addAll(Column.builder().build(), Column.builder().width(40).build());
setHgap(10); setHgap(10);
setVgap(8); setVgap(8);
setPadding(new Insets(20 , 0, 0, 0)); setPadding(new Insets(20 , 0, 0, 0));
@@ -5,7 +5,7 @@ import com.imyeyu.fx.ui.TimiFXUI;
import com.imyeyu.fx.ui.components.TextAreaEditor; import com.imyeyu.fx.ui.components.TextAreaEditor;
import com.imyeyu.fx.ui.examples.component.AbstractDemoPane; import com.imyeyu.fx.ui.examples.component.AbstractDemoPane;
import com.imyeyu.fx.ui.examples.component.sidebar.SidebarItem; import com.imyeyu.fx.ui.examples.component.sidebar.SidebarItem;
import com.imyeyu.fx.utils.BorderStroke; import com.imyeyu.fx.utils.BorderBuilder;
import com.imyeyu.inject.annotation.Component; import com.imyeyu.inject.annotation.Component;
import javafx.geometry.Orientation; import javafx.geometry.Orientation;
import javafx.scene.control.Label; import javafx.scene.control.Label;
@@ -26,7 +26,7 @@ public class DraggableNodeDemo extends AbstractDemoPane {
tips.setText(TimiFXUI.MULTILINGUAL.text("fx.example.draggable_node.tips")); tips.setText(TimiFXUI.MULTILINGUAL.text("fx.example.draggable_node.tips"));
TextAreaEditor demo = new TextAreaEditor(); TextAreaEditor demo = new TextAreaEditor();
demo.getStyleClass().add(CSS.BORDER_T); demo.setBorder(Stroke.TOP);
demo.setEditable(false); demo.setEditable(false);
demo.setText(""" demo.setText("""
StackPane box = new StackPane(); StackPane box = new StackPane();
@@ -48,7 +48,7 @@ draggable.maxYProperty().bind(box.heightProperty().multiply(.5).subtract(pane.he
StackPane box = new StackPane(); StackPane box = new StackPane();
StackPane pane = new StackPane(new Label(TimiFXUI.MULTILINGUAL.text("fx.example.drag_me"))); StackPane pane = new StackPane(new Label(TimiFXUI.MULTILINGUAL.text("fx.example.drag_me")));
pane.setBorder(new BorderStroke(Colorful.FOCUSED_DEFAULT).width(2).build()); pane.setBorder(BorderBuilder.solid(Colorful.FOCUSED_DEFAULT).width(2).build());
pane.setMaxSize(200, 40); pane.setMaxSize(200, 40);
pane.setEffect(Shadow.POPUP); pane.setEffect(Shadow.POPUP);
pane.setBackground(BG.WHITE); pane.setBackground(BG.WHITE);
@@ -5,7 +5,7 @@ import com.imyeyu.fx.ui.TimiFXUI;
import com.imyeyu.fx.ui.components.TextAreaEditor; import com.imyeyu.fx.ui.components.TextAreaEditor;
import com.imyeyu.fx.ui.examples.component.AbstractDemoPane; import com.imyeyu.fx.ui.examples.component.AbstractDemoPane;
import com.imyeyu.fx.ui.examples.component.sidebar.SidebarItem; import com.imyeyu.fx.ui.examples.component.sidebar.SidebarItem;
import com.imyeyu.fx.utils.BorderStroke; import com.imyeyu.fx.utils.BorderBuilder;
import com.imyeyu.inject.annotation.Component; import com.imyeyu.inject.annotation.Component;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.geometry.Insets; import javafx.geometry.Insets;
@@ -33,7 +33,7 @@ public class DraggableWindowDemo extends AbstractDemoPane {
popup = new Popup(); popup = new Popup();
popup.getContent().add(new BorderPane() {{ popup.getContent().add(new BorderPane() {{
setBorder(new BorderStroke(Colorful.RED).width(2).build()); setBorder(BorderBuilder.solid(Colorful.RED).width(2).build());
setBackground(BG.WHITE); setBackground(BG.WHITE);
setTop(new StackPane() {{ setTop(new StackPane() {{
setBorder(Stroke.BOTTOM); setBorder(Stroke.BOTTOM);
@@ -1,7 +1,7 @@
package com.imyeyu.fx.ui.examples.view.pages.other; package com.imyeyu.fx.ui.examples.view.pages.other;
import com.imyeyu.fx.TimiFX;
import com.imyeyu.fx.icon.TimiFXIcon; import com.imyeyu.fx.icon.TimiFXIcon;
import com.imyeyu.fx.icon.TimiIcon;
import com.imyeyu.fx.ui.TimiFXUI; import com.imyeyu.fx.ui.TimiFXUI;
import com.imyeyu.fx.ui.components.TextAreaEditor; import com.imyeyu.fx.ui.components.TextAreaEditor;
import com.imyeyu.fx.ui.components.TrayFX; import com.imyeyu.fx.ui.components.TrayFX;
@@ -9,9 +9,8 @@ import com.imyeyu.fx.ui.components.popup.PopupTipsService;
import com.imyeyu.fx.ui.examples.component.AbstractDemoPane; import com.imyeyu.fx.ui.examples.component.AbstractDemoPane;
import com.imyeyu.fx.ui.examples.component.sidebar.SidebarItem; import com.imyeyu.fx.ui.examples.component.sidebar.SidebarItem;
import com.imyeyu.fx.ui.examples.ctrl.Main; import com.imyeyu.fx.ui.examples.ctrl.Main;
import com.imyeyu.inject.annotation.Component; import com.imyeyu.fx.utils.Windows;
import com.imyeyu.inject.annotation.PostConstruct; import com.imyeyu.inject.annotation.PostConstruct;
import javafx.stage.Stage;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.geometry.VPos; import javafx.geometry.VPos;
import javafx.scene.control.Button; import javafx.scene.control.Button;
@@ -21,6 +20,7 @@ import javafx.scene.control.MenuItem;
import javafx.scene.control.TextField; import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane; import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import java.awt.TrayIcon; import java.awt.TrayIcon;
@@ -48,7 +48,7 @@ public class TrayFXDemo extends AbstractDemoPane {
show = new Button(TimiFXUI.MULTILINGUAL.text("show")); show = new Button(TimiFXUI.MULTILINGUAL.text("show"));
hide = new Button(TimiFXUI.MULTILINGUAL.text("remove")); hide = new Button(TimiFXUI.MULTILINGUAL.text("remove"));
hide.getStyleClass().add(CSS.BORDER_TRB); hide.setBorder(Stroke.EX_LEFT);
Label labelSendMsg = TimiFXUI.label(TimiFXUI.MULTILINGUAL.text("fx.example.tray.send_msg")); Label labelSendMsg = TimiFXUI.label(TimiFXUI.MULTILINGUAL.text("fx.example.tray.send_msg"));
@@ -108,9 +108,9 @@ public class TrayFXDemo extends AbstractDemoPane {
hide.disableProperty().bind(trayFX.showingProperty().not()); hide.disableProperty().bind(trayFX.showingProperty().not());
MenuItem show = new MenuItem(TimiFXUI.MULTILINGUAL.text("show")); MenuItem show = new MenuItem(TimiFXUI.MULTILINGUAL.text("show"));
MenuItem exit = new MenuItem(TimiFXUI.MULTILINGUAL.text("exit"), TimiFXIcon.fromName("FAIL", Colorful.RED)); MenuItem exit = new MenuItem(TimiFXUI.MULTILINGUAL.text("exit"), TimiFXIcon.get(TimiIcon.FAIL, Colorful.RED));
show.setOnAction(e -> TimiFX.requestTop(stage)); show.setOnAction(e -> Windows.requestTop(stage));
exit.setOnAction(e -> main.stop()); exit.setOnAction(e -> main.stop());
trayFX.addMenu(0, show, TimiFXUI.sep(), exit); trayFX.addMenu(0, show, TimiFXUI.sep(), exit);