!62 fix: #I7XN52优化设置页面UI

Merge pull request !62 from Luke/dev
This commit is contained in:
Luke 2023-08-31 18:29:49 +00:00 committed by Gitee
commit 7ff5233b9c
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
15 changed files with 189 additions and 122 deletions

View File

@ -38,6 +38,7 @@ public class LunchApp extends Application {
@Override
public void start(Stage primaryStage) {
Pane root = new Pane();
double width = AppConstants.SCREEN_WIDTH;
double length = AppConstants.SCREEN_LENGTH;
@ -46,6 +47,14 @@ public class LunchApp extends Application {
scene.getStylesheets().add(Objects.requireNonNull(getClass().getResource("/css/styles.css")).toExternalForm());
initUiComponents();
UiResourceBundle.bindStringProperty(primaryStage.titleProperty(), TextConstants.TITLE);
/* // 获取自定义标题栏的实例并添加到BorderPane的顶部
CustomTitleBar customTitleBar = CustomTitleBar.getInstance();
// 使自定义标题栏可拖动
customTitleBar.makeDraggable(primaryStage);*/
// primaryStage.initStyle(StageStyle.UNDECORATED); // 移除默认窗口装饰
primaryStage.setScene(scene);
primaryStage.setWidth(width);
primaryStage.setHeight(length);
primaryStage.setScene(scene);

View File

@ -2,11 +2,14 @@ package org.jcnc.jnotepad.root;
import org.jcnc.jnotepad.root.bottom.RootBottomSideBarVBox;
import org.jcnc.jnotepad.root.center.main.MainBorderPane;
import org.jcnc.jnotepad.root.left.sidebar.RootLeftSideBarVBox;
import org.jcnc.jnotepad.root.left.sidebar.tools.ToolHBox;
import org.jcnc.jnotepad.root.right.RootRightSideBarVBox;
import org.jcnc.jnotepad.root.top.RootTopSideBarVBox;
import org.jcnc.jnotepad.root.top.RootTopBorderPane;
import org.jcnc.jnotepad.ui.module.AbstractBorderPane;
/*
* 根舞台下的Root主布局
* */
public class RootBorderPane extends AbstractBorderPane {
private static final RootBorderPane INSTANCE = new RootBorderPane();
@ -16,11 +19,11 @@ public class RootBorderPane extends AbstractBorderPane {
}
private void initRootBorderPane() {
setCenterComponent(MainBorderPane.getInstance());
setLeftComponent(RootLeftSideBarVBox.getInstance());
setRightComponent(RootRightSideBarVBox.getInstance());
setTopComponent(RootTopSideBarVBox.getInstance());
setBottomComponent(RootBottomSideBarVBox.getInstance());
setCenterComponent(MainBorderPane.getInstance()); //中间,用于显示Main主布局
setLeftComponent(ToolHBox.getInstance()); //主布局的左边
setRightComponent(RootRightSideBarVBox.getInstance()); //主布局的右边
setTopComponent(RootTopBorderPane.getInstance()); //主布局的上面
setBottomComponent(RootBottomSideBarVBox.getInstance());//主布局的下面
}
public static RootBorderPane getInstance() {

View File

@ -1,9 +1,11 @@
package org.jcnc.jnotepad.root.center.main;
import org.jcnc.jnotepad.root.center.main.center.tab.JNotepadTabPane;
import org.jcnc.jnotepad.root.center.main.top.MainTopVBox;
import org.jcnc.jnotepad.ui.module.AbstractBorderPane;
/*
* MainBorderPane区域,用于显示文本框以及文本框周边
* */
public class MainBorderPane extends AbstractBorderPane {
private static final MainBorderPane INSTANCE = new MainBorderPane();
@ -13,11 +15,9 @@ public class MainBorderPane extends AbstractBorderPane {
}
private void initRootBorderPane() {
//setBottomComponent(JNotepadStatusBox.getInstance());
setCenter(JNotepadTabPane.getInstance());
setCenterComponent(JNotepadTabPane.getInstance()); //文本框
setTopComponent(MainTopVBox.getInstance());
}
public static MainBorderPane getInstance() {

View File

@ -1,20 +0,0 @@
package org.jcnc.jnotepad.root.center.main.top;
import javafx.scene.layout.VBox;
import org.jcnc.jnotepad.root.center.main.top.menu.JNotepadMenuBar;
import org.jcnc.jnotepad.root.center.main.top.tools.ToolHBox;
public class MainTopVBox extends VBox {
private static final MainTopVBox INSTANCE = new MainTopVBox();
private MainTopVBox() {
// 在构造函数中初始化
getChildren().add(JNotepadMenuBar.getInstance());
getChildren().add(ToolHBox.getInstance());
}
public static MainTopVBox getInstance() {
return INSTANCE;
}
}

View File

@ -1,21 +0,0 @@
package org.jcnc.jnotepad.root.left.sidebar;
import org.jcnc.jnotepad.ui.module.AbstractVBox;
public class RootLeftSideBarVBox extends AbstractVBox {
private static final RootLeftSideBarVBox INSTANCE = new RootLeftSideBarVBox();
private RootLeftSideBarVBox() {
initSidebarVBox();
}
private void initSidebarVBox() {
}
public static RootLeftSideBarVBox getInstance() {
return INSTANCE;
}
}

View File

@ -1,4 +1,4 @@
package org.jcnc.jnotepad.root.center.main.top.tools;
package org.jcnc.jnotepad.root.left.sidebar.tools;
import javafx.scene.control.Button;
import javafx.scene.control.ToolBar;

View File

@ -1,4 +1,4 @@
package org.jcnc.jnotepad.root.center.main.top.tools;
package org.jcnc.jnotepad.root.left.sidebar.tools;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;

View File

@ -0,0 +1,26 @@
package org.jcnc.jnotepad.root.top;
import org.jcnc.jnotepad.root.top.menu.JNotepadMenuBar;
import org.jcnc.jnotepad.ui.module.AbstractBorderPane;
/*
* MainBorderPane区域,用于显示文本框以及文本框周边
* */
public class RootTopBorderPane extends AbstractBorderPane {
private static final RootTopBorderPane INSTANCE = new RootTopBorderPane();
private RootTopBorderPane() {
initRootBorderPane();
}
private void initRootBorderPane() {
setTopComponent(JNotepadMenuBar.getInstance()); //文本框上面
}
public static RootTopBorderPane getInstance() {
return INSTANCE;
}
}

View File

@ -1,20 +0,0 @@
package org.jcnc.jnotepad.root.top;
import org.jcnc.jnotepad.ui.module.AbstractVBox;
public class RootTopSideBarVBox extends AbstractVBox {
private static final RootTopSideBarVBox INSTANCE = new RootTopSideBarVBox();
private RootTopSideBarVBox() {
initSidebarVBox();
}
private void initSidebarVBox() {
}
public static RootTopSideBarVBox getInstance() {
return INSTANCE;
}
}

View File

@ -1,4 +1,4 @@
package org.jcnc.jnotepad.root.center.main.top.menu;
package org.jcnc.jnotepad.root.top.menu;
import javafx.event.ActionEvent;
import javafx.scene.control.*;
@ -12,7 +12,7 @@ import org.jcnc.jnotepad.controller.event.handler.tool.SetBtn;
import org.jcnc.jnotepad.controller.i18n.LocalizationController;
import org.jcnc.jnotepad.root.center.main.center.tab.JNotepadTab;
import org.jcnc.jnotepad.root.center.main.center.tab.JNotepadTabPane;
import org.jcnc.jnotepad.root.center.main.top.tools.JNotepadToolBar;
import org.jcnc.jnotepad.root.left.sidebar.tools.JNotepadToolBar;
import org.jcnc.jnotepad.tool.LogUtil;
import org.slf4j.Logger;

View File

@ -6,7 +6,7 @@ import org.jcnc.jnotepad.constants.AppConstants;
import org.jcnc.jnotepad.root.center.main.bottom.status.JNotepadStatusBox;
import org.jcnc.jnotepad.root.center.main.center.tab.JNotepadTab;
import org.jcnc.jnotepad.root.center.main.center.tab.JNotepadTabPane;
import org.jcnc.jnotepad.root.center.main.top.menu.JNotepadMenuBar;
import org.jcnc.jnotepad.root.top.menu.JNotepadMenuBar;
import org.jcnc.jnotepad.ui.setStage.SetStage;
import org.jcnc.jnotepad.view.manager.ViewManager;

View File

@ -2,11 +2,10 @@ package org.jcnc.jnotepad.ui.setStage;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.control.SplitPane;
import javafx.scene.control.TitledPane;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import org.jcnc.jnotepad.tool.UiUtil;
@ -23,9 +22,7 @@ public class SetStage {
private static final SetStage SET_STAGE = new SetStage();
private StackPane contentDisplay;
private ListView<String> generalListView;
private ListView<String> appearanceListView;
private ListView<String> securityListView;
private TreeView<String> settingsTreeView;
private SetStage() {
// 私有构造方法以实现单例模式
@ -47,27 +44,11 @@ public class SetStage {
// 创建一个用于显示内容的 StackPane并初始化为默认显示的标签
contentDisplay = new StackPane(new Label("从左侧选择设置以显示内容"));
// 创建不同设置类别的 ListView并初始化设置项
generalListView = createListView("常规设置项1", "常规设置项2");
appearanceListView = createListView("外观设置项1", "外观设置项2");
securityListView = createListView("安全设置项1", "安全设置项2");
// 创建 TreeView并初始化设置项
settingsTreeView = createTreeView();
// 创建 TitledPanes每个面板包含一个标题和对应的设置列表
TitledPane generalPane = new TitledPane("常规设置", generalListView);
TitledPane appearancePane = new TitledPane("外观设置", appearanceListView);
TitledPane securityPane = new TitledPane("安全设置", securityListView);
// TitledPanes 添加点击事件监听器用于更新内容显示区域
generalPane.setOnMouseClicked(event -> updateContentDisplay(generalListView));
appearancePane.setOnMouseClicked(event -> updateContentDisplay(appearanceListView));
securityPane.setOnMouseClicked(event -> updateContentDisplay(securityListView));
// 创建一个垂直布局容器 TitledPanes 放入其中
VBox titledPaneContainer = new VBox(10);
titledPaneContainer.getChildren().addAll(generalPane, appearancePane, securityPane);
// 创建一个分割面板左侧是设置列表右侧是内容显示区域
SplitPane splitPane = new SplitPane(titledPaneContainer, contentDisplay);
// 创建一个分割面板左侧是设置树右侧是内容显示区域
SplitPane splitPane = new SplitPane(settingsTreeView, contentDisplay);
// 设置分割位置
splitPane.setDividerPositions(0.3);
@ -83,27 +64,40 @@ public class SetStage {
}
/**
* 创建一个 ListView 并初始化项
* 创建一个 TreeView 并初始化项
*
* @param items 要添加到 ListView 的项
* @return 初始化后的 ListView
* @return 初始化后的 TreeView
*/
private ListView<String> createListView(String... items) {
ListView<String> listView = new ListView<>();
listView.getItems().addAll(items);
return listView;
}
private TreeView<String> createTreeView() {
TreeItem<String> rootItem = new TreeItem<>("设置");
rootItem.setExpanded(true);
/**
* 更新内容显示区域根据选定的列表项显示相应的设置内容
*
* @param listView 选定项所属的 ListView
*/
private void updateContentDisplay(ListView<String> listView) {
String selectedItem = listView.getSelectionModel().getSelectedItem();
if (selectedItem != null) {
// 更新内容显示区域为选定项的设置内容标签
contentDisplay.getChildren().setAll(new Label(selectedItem + " 的设置内容"));
}
TreeItem<String> generalItem = new TreeItem<>("常规设置");
TreeItem<String> appearanceItem = new TreeItem<>("外观设置");
TreeItem<String> securityItem = new TreeItem<>("安全设置");
generalItem.getChildren().add(new TreeItem<>("常规设置项1"));
generalItem.getChildren().add(new TreeItem<>("常规设置项2"));
appearanceItem.getChildren().add(new TreeItem<>("外观设置项1"));
appearanceItem.getChildren().add(new TreeItem<>("外观设置项2"));
securityItem.getChildren().add(new TreeItem<>("安全设置项1"));
securityItem.getChildren().add(new TreeItem<>("安全设置项2"));
rootItem.getChildren().add(generalItem);
rootItem.getChildren().add(appearanceItem);
rootItem.getChildren().add(securityItem);
TreeView<String> treeView = new TreeView<>(rootItem);
treeView.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
if (newValue != null) {
// 更新内容显示区域为选定项的设置内容标签
contentDisplay.getChildren().setAll(new Label(newValue.getValue() + " 的设置内容"));
}
});
return treeView;
}
}

View File

@ -0,0 +1,95 @@
package org.jcnc.jnotepad.view.manager;
import javafx.animation.TranslateTransition;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import javafx.util.Duration;
/*
* 自定义的标题栏,没有完善好,暂时搁置
* */
public class CustomTitleBar extends HBox {
private static CustomTitleBar instance;
private CustomTitleBar() {
// 设置样式和布局
this.setAlignment(Pos.CENTER);
// 左侧图标
ImageView iconView = new ImageView(new Image("icon.png"));
iconView.setFitWidth(30);
iconView.setFitHeight(30);
Label titleLabel = new Label("自定义标题栏");
titleLabel.setStyle("-fx-font-size: 18px;");
// 右侧按钮区域
HBox buttonBox = new HBox(5);
buttonBox.setAlignment(Pos.CENTER_RIGHT);
Button minimizeButton = new Button("-");
minimizeButton.setStyle("-fx-background-color: transparent; ");
minimizeButton.setOnAction(event -> {
Stage stage = (Stage) this.getScene().getWindow();
stage.setIconified(true); // 最小化窗口
});
Button maximizeButton = new Button("");
maximizeButton.setStyle("-fx-background-color: transparent;");
maximizeButton.setOnAction(event -> {
Stage stage = (Stage) this.getScene().getWindow();
stage.setMaximized(!stage.isMaximized()); // 最大化/还原窗口
});
Button closeButton = new Button("X");
closeButton.setStyle("-fx-background-color: transparent;");
closeButton.setOnAction(event -> {
Stage stage = (Stage) this.getScene().getWindow();
stage.close();
});
buttonBox.getChildren().addAll(minimizeButton, maximizeButton, closeButton);
this.getChildren().addAll(iconView, titleLabel, buttonBox);
}
public static CustomTitleBar getInstance() {
if (instance == null) {
instance = new CustomTitleBar();
}
return instance;
}
public void makeDraggable(Stage stage) {
// 创建一个平移动画设置持续时间和目标位置
TranslateTransition minimizeAnimation = new TranslateTransition(Duration.seconds(0.3), stage.getScene().getRoot());
minimizeAnimation.setToY(stage.getHeight()); // 将根节点向下平移使窗口消失
final Delta dragDelta = new Delta();
// 当鼠标按下时记录初始偏移量
this.setOnMousePressed(mouseEvent -> {
dragDelta.x = stage.getX() - mouseEvent.getScreenX();
dragDelta.y = stage.getY() - mouseEvent.getScreenY();
});
// 当鼠标拖动时根据偏移量更新舞台的位置
this.setOnMouseDragged(mouseEvent -> {
stage.setX(mouseEvent.getScreenX() + dragDelta.x);
stage.setY(mouseEvent.getScreenY() + dragDelta.y);
});
}
private static class Delta {
double x, y;
}
}

View File

@ -74,6 +74,7 @@ public class ViewManager {
// 创建主界面布局
root = new BorderPane();
//root.setTop(CustomTitleBar.getInstance());
root.setCenter(RootBorderPane.getInstance());
scene.setRoot(root);

BIN
src/main/resources/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 381 B