From 2e6f44cbcf568acaeab34a5b6832524588f85faf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E7=99=BD=E4=B8=8E=E5=AD=9F=E6=B5=A9=E7=84=B6?= <1063889643@qq.com> Date: Sun, 22 Oct 2023 22:53:21 +0800 Subject: [PATCH 1/5] =?UTF-8?q?+=20=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/light/layout/MenuPane.java | 4 ++-- src/main/java/com/light/view/ManagerView.java | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/light/layout/MenuPane.java b/src/main/java/com/light/layout/MenuPane.java index c0c2224..187f781 100644 --- a/src/main/java/com/light/layout/MenuPane.java +++ b/src/main/java/com/light/layout/MenuPane.java @@ -47,10 +47,10 @@ public class MenuPane extends StackPane { private final ListView dynamicMenu = new ListView<>(); // 底部导航栏 - private final Label downloadLabel = new Label("下载中", new FontIcon(BootstrapIcons.ARROW_DOWN)); + private final Label downloadLabel = new Label("下载", new FontIcon(BootstrapIcons.ARROW_DOWN)); private final Text downloadLabelText = new Text(FxApplicationContextUtils.DOWNLOAD_PROPERTY.getValue()); private final HBox downloadBox = new HBox(10, downloadLabel, downloadLabelText); - private final Label updateLabel = new Label("更新中", new FontIcon(BootstrapIcons.ARROW_DOWN)); + private final Label updateLabel = new Label("更新", new FontIcon(BootstrapIcons.ARROW_DOWN)); private final Text updateLabelText = new Text(FxApplicationContextUtils.UPDATE_PROPERTY.getValue()); private final HBox updateBox = new HBox(10, updateLabel, updateLabelText); private final VBox bottomMenu = new VBox(downloadBox, updateBox); diff --git a/src/main/java/com/light/view/ManagerView.java b/src/main/java/com/light/view/ManagerView.java index 56efdb5..bcbcae7 100644 --- a/src/main/java/com/light/view/ManagerView.java +++ b/src/main/java/com/light/view/ManagerView.java @@ -203,9 +203,12 @@ public class ManagerView extends StackPane { SimpleDoubleProperty rate = project.downloadRate(); File localRepoFile = new File(project.local().get()); String remoteUrl = project.remote(); - if ("Gitee".equals(JGitUtils.getType(remoteUrl)) && JGitUtils.GITEE_FAIL_NUMBER.get() < 10) { + String type = JGitUtils.getType(remoteUrl); + if ("Gitee".equals(type) && JGitUtils.GITEE_FAIL_NUMBER.get() < 10) { pull(project, localRepoFile, remoteUrl, rate); - } else if ("Github".equals(JGitUtils.getType(remoteUrl)) && JGitUtils.GITHUB_FAIL_NUMBER.get() < 5) { + } else if ("Github".equals(type) && JGitUtils.GITHUB_FAIL_NUMBER.get() < 5) { + pull(project, localRepoFile, remoteUrl, rate); + } else if ("other".equals(type)) { pull(project, localRepoFile, remoteUrl, rate); } }, -- Gitee From 63d3f4bad913599efbd60937e7e300985719c048 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E7=99=BD=E4=B8=8E=E5=AD=9F=E6=B5=A9=E7=84=B6?= <1063889643@qq.com> Date: Mon, 23 Oct 2023 19:21:46 +0800 Subject: [PATCH 2/5] =?UTF-8?q?+=20=E8=AF=A6=E6=83=85=E9=A1=B5=E5=BC=80?= =?UTF-8?q?=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/light/layout/MenuPane.java | 6 +-- src/main/java/com/light/view/DetailView.java | 39 ++++++++++++++++++++ 2 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/light/view/DetailView.java diff --git a/src/main/java/com/light/layout/MenuPane.java b/src/main/java/com/light/layout/MenuPane.java index 187f781..0197d30 100644 --- a/src/main/java/com/light/layout/MenuPane.java +++ b/src/main/java/com/light/layout/MenuPane.java @@ -8,11 +8,10 @@ import com.light.theme.ThemeDialog; import com.light.util.FxApplicationContextUtils; import com.light.util.FxUtil; import com.light.util.Lazy; +import com.light.view.DetailView; import com.light.view.HomeView; import com.light.view.ManagerView; import com.light.view.NotificationView; -import javafx.collections.ListChangeListener; -import javafx.event.Event; import javafx.geometry.Orientation; import javafx.geometry.Pos; import javafx.scene.control.Button; @@ -25,7 +24,6 @@ import javafx.scene.layout.HBox; import javafx.scene.layout.Priority; import javafx.scene.layout.StackPane; import javafx.scene.layout.VBox; -import javafx.scene.text.Font; import javafx.scene.text.Text; import org.kordamp.ikonli.antdesignicons.AntDesignIconsFilled; import org.kordamp.ikonli.antdesignicons.AntDesignIconsOutlined; @@ -72,7 +70,7 @@ public class MenuPane extends StackPane { dynamicMenu.getItems().addAll( new NavItem(new FontIcon(AntDesignIconsOutlined.DOWNLOAD), "下载", new Lazy<>(HomeView::new)), new NavItem(new FontIcon(AntDesignIconsOutlined.PARTITION), "管理", new Lazy<>(ManagerView::new)), - new NavItem(new FontIcon(AntDesignIconsOutlined.EDIT), "笔记", null) + new NavItem(new FontIcon(AntDesignIconsOutlined.EDIT), "笔记", new Lazy<>(DetailView::new)) ); dynamicMenu.getSelectionModel().selectFirst(); } diff --git a/src/main/java/com/light/view/DetailView.java b/src/main/java/com/light/view/DetailView.java new file mode 100644 index 0000000..f07ceba --- /dev/null +++ b/src/main/java/com/light/view/DetailView.java @@ -0,0 +1,39 @@ +package com.light.view; + +import javafx.geometry.Insets; +import javafx.geometry.Pos; +import javafx.scene.control.ChoiceBox; +import javafx.scene.control.Label; +import javafx.scene.control.TextField; +import javafx.scene.layout.BorderPane; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Priority; +import javafx.scene.layout.VBox; + +public class DetailView extends BorderPane { + + public DetailView() { + super(); + setPadding(new Insets(5, 2, 5, 2)); + ChoiceBox choiceBox = new ChoiceBox<>(); + choiceBox.getItems().addAll("1", "2", "3", "4", "5"); + Label label = new Label("手动阀手动阀"); + + TextField textField = new TextField(); + textField.setVisible(false); + + VBox box = new VBox(10, choiceBox, label, textField); + VBox.setVgrow(choiceBox, Priority.ALWAYS); + box.setAlignment(Pos.CENTER_LEFT); + + setTop(box); + + label.setOnMouseClicked(event ->{ + if (event.getClickCount() == 2) { + textField.setText(label.getText()); + textField.setVisible(true); + label.setVisible(false); + } + }); + } +} -- Gitee From ce38c861e2a08999058fd38c57cb8c511f3b4746 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E7=99=BD=E4=B8=8E=E5=AD=9F=E6=B5=A9=E7=84=B6?= <1063889643@qq.com> Date: Tue, 24 Oct 2023 00:05:27 +0800 Subject: [PATCH 3/5] =?UTF-8?q?+=20=E8=AF=A6=E6=83=85=E9=A1=B5=E5=BC=80?= =?UTF-8?q?=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/light/component/EditorPane.java | 118 ++++++++++++++++++ .../light/component/OperationTableCell.java | 8 ++ src/main/java/com/light/layout/MenuPane.java | 12 +- src/main/java/com/light/layout/NavItem.java | 4 + src/main/java/com/light/model/GitProject.java | 6 +- src/main/java/com/light/view/DetailView.java | 90 ++++++++++--- src/main/java/module-info.java | 1 + 7 files changed, 218 insertions(+), 21 deletions(-) create mode 100644 src/main/java/com/light/component/EditorPane.java diff --git a/src/main/java/com/light/component/EditorPane.java b/src/main/java/com/light/component/EditorPane.java new file mode 100644 index 0000000..b2fea3a --- /dev/null +++ b/src/main/java/com/light/component/EditorPane.java @@ -0,0 +1,118 @@ +package com.light.component; + +import atlantafx.base.controls.Card; +import atlantafx.base.controls.ModalPane; +import atlantafx.base.controls.Spacer; +import atlantafx.base.layout.ModalBox; +import atlantafx.base.theme.Tweaks; +import com.light.model.GitProject; +import com.light.thread.FxAsyncTask; +import com.light.util.H2PoolUtils; +import javafx.geometry.Pos; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Priority; +import javafx.scene.layout.VBox; +import javafx.scene.text.Text; +import javafx.scene.web.HTMLEditor; +import javafx.scene.web.WebView; + +public class EditorPane extends ModalBox { + + private final ModalPane modalPane; + protected final Card content = new Card(); + private final Label header = new Label(); + private final HTMLEditor editor = new HTMLEditor(); + + private final WebView describeLabel; + private final Label remarkLabel; + + private GitProject gitProject; + + private boolean remark; + + public EditorPane(ModalPane modalPane, WebView describeLabel, Label remarkLabel) { + super(modalPane); + this.modalPane = modalPane; + this.modalPane.setPersistent(true); + this.describeLabel = describeLabel; + this.remarkLabel = remarkLabel; + createView(); + } + + private void createView() { + content.setHeader(header); + content.getStyleClass().add(Tweaks.EDGE_TO_EDGE); + content.setMaxSize(700, 550); + content.setBody(editor); + content.setFooter(createDefaultFooter()); + + // IMPORTANT: this guarantees client will use correct width and height + setMinWidth(USE_PREF_SIZE); + setMaxWidth(USE_PREF_SIZE); + setMinHeight(USE_PREF_SIZE); + setMaxHeight(USE_PREF_SIZE); + + AnchorPane.setTopAnchor(content, 0d); + AnchorPane.setRightAnchor(content, 0d); + AnchorPane.setBottomAnchor(content, 0d); + AnchorPane.setLeftAnchor(content, 0d); + + addContent(content); + } + + private HBox createDefaultFooter() { + var okBtn = new Button("确定"); + okBtn.getStyleClass().add("form-action"); + okBtn.setOnAction(event -> { + String htmlText = editor.getHtmlText(); + if (remark) { + if (htmlText.equals(gitProject.remark().get())) { + close(); + return; + } + gitProject.remark().set(htmlText); + remarkLabel.setText(htmlText); + } else { + if (htmlText.equals(gitProject.description().get())) { + close(); + return; + } + gitProject.description().set(htmlText); + describeLabel.getEngine().loadContent(htmlText); + } + + // 更新入库 + FxAsyncTask.runOnce("更新项目 " + gitProject.name().get(), () -> H2PoolUtils.updateGitProject(gitProject)); + close(); + }); + + var closeBtn = new Button("取消"); + closeBtn.getStyleClass().add("form-action"); + closeBtn.setCancelButton(true); + closeBtn.setOnAction(e -> close()); + + var footer = new HBox(10, new Spacer(), okBtn, closeBtn); + footer.getStyleClass().add("footer"); + footer.setAlignment(Pos.CENTER_RIGHT); + VBox.setVgrow(footer, Priority.NEVER); + + return footer; + } + + public void show(GitProject gitProject, boolean remark) { + if (remark) { + header.setText("备 注"); + editor.setHtmlText(gitProject.remark().get()); + } else { + header.setText("描 述"); + editor.setHtmlText(gitProject.description().get()); + } + this.remark = remark; + this.gitProject = gitProject; + + modalPane.show(this); + } +} diff --git a/src/main/java/com/light/component/OperationTableCell.java b/src/main/java/com/light/component/OperationTableCell.java index 8bb1900..9f54af4 100644 --- a/src/main/java/com/light/component/OperationTableCell.java +++ b/src/main/java/com/light/component/OperationTableCell.java @@ -4,6 +4,7 @@ import atlantafx.base.theme.Styles; import com.light.exception.AuthException; import com.light.exception.JGitException; import com.light.exception.TimeOutException; +import com.light.layout.NavItem; import com.light.model.GitAuthInfo; import com.light.model.GitProject; import com.light.thread.FxAsyncTask; @@ -18,6 +19,7 @@ import javafx.concurrent.Task; import javafx.geometry.Pos; import javafx.scene.Scene; import javafx.scene.control.Button; +import javafx.scene.control.ListView; import javafx.scene.control.TableCell; import javafx.scene.control.TableColumn; import javafx.scene.layout.HBox; @@ -69,6 +71,12 @@ public class OperationTableCell extends TableCell { } private void initEvent() { + detailButton.setOnAction(event -> { + GitProject project = getTableRow().getItem(); + ListView dynamicMenu = (ListView) FxApplicationContextUtils.GLOBAL_CONTEXT_MAP.get("menu"); + dynamicMenu.setUserData(project); + dynamicMenu.getSelectionModel().selectLast(); + }); updateButton.setOnMouseClicked(event -> { JGitUtils.GITHUB_FAIL_NUMBER.set(0); JGitUtils.GITEE_FAIL_NUMBER.set(0); diff --git a/src/main/java/com/light/layout/MenuPane.java b/src/main/java/com/light/layout/MenuPane.java index 0197d30..0f10937 100644 --- a/src/main/java/com/light/layout/MenuPane.java +++ b/src/main/java/com/light/layout/MenuPane.java @@ -4,6 +4,7 @@ import atlantafx.base.theme.Styles; import com.light.component.DownAndUpdatePane; import com.light.component.NoticePane; import com.light.component.PaymentQRCodePane; +import com.light.model.GitProject; import com.light.theme.ThemeDialog; import com.light.util.FxApplicationContextUtils; import com.light.util.FxUtil; @@ -66,6 +67,8 @@ public class MenuPane extends StackPane { this.contentPane = contentPane; initialize(); + FxApplicationContextUtils.GLOBAL_CONTEXT_MAP.put("menu", dynamicMenu); + // 菜单栏标题 dynamicMenu.getItems().addAll( new NavItem(new FontIcon(AntDesignIconsOutlined.DOWNLOAD), "下载", new Lazy<>(HomeView::new)), @@ -110,7 +113,14 @@ public class MenuPane extends StackPane { dynamicMenu.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> { Optional.ofNullable(newValue).ifPresent(menuItem -> { // 设置内容 - Optional.ofNullable(menuItem.getContent()).ifPresentOrElse(content -> contentPane.setContent(content.get()), () -> contentPane.setContent(null)); + Optional.ofNullable(menuItem.getContent()).ifPresentOrElse(content -> { + contentPane.setContent(content.get()); + // 详情按钮调整界面 + Object userData = dynamicMenu.getUserData(); + if ("笔记".equals(newValue.getTitle()) && userData != null) { + ((DetailView) content.get()).refresh((GitProject) userData); + } + }, () -> contentPane.setContent(null)); }); }); diff --git a/src/main/java/com/light/layout/NavItem.java b/src/main/java/com/light/layout/NavItem.java index a75bd9a..2f6cc6d 100644 --- a/src/main/java/com/light/layout/NavItem.java +++ b/src/main/java/com/light/layout/NavItem.java @@ -64,4 +64,8 @@ public class NavItem extends HBox { public Lazy getContent() { return content; } + + public String getTitle() { + return titleLabel.getText(); + } } diff --git a/src/main/java/com/light/model/GitProject.java b/src/main/java/com/light/model/GitProject.java index 169a15d..8c8e7cf 100644 --- a/src/main/java/com/light/model/GitProject.java +++ b/src/main/java/com/light/model/GitProject.java @@ -1,6 +1,5 @@ package com.light.model; -import com.light.util.FxApplicationContextUtils; import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleDoubleProperty; import javafx.beans.property.SimpleIntegerProperty; @@ -19,4 +18,9 @@ public record GitProject(SimpleIntegerProperty id, SimpleIntegerProperty level, SimpleDoubleProperty downloadRate, SimpleBooleanProperty selected) { + + @Override + public String toString() { + return name.get(); + } } diff --git a/src/main/java/com/light/view/DetailView.java b/src/main/java/com/light/view/DetailView.java index f07ceba..47cc786 100644 --- a/src/main/java/com/light/view/DetailView.java +++ b/src/main/java/com/light/view/DetailView.java @@ -1,39 +1,91 @@ package com.light.view; +import atlantafx.base.controls.ModalPane; +import com.light.component.EditorPane; +import com.light.enums.Level; +import com.light.model.GitProject; +import com.light.util.FxApplicationContextUtils; +import com.light.util.NoticeUtils; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.control.ChoiceBox; import javafx.scene.control.Label; -import javafx.scene.control.TextField; -import javafx.scene.layout.BorderPane; -import javafx.scene.layout.HBox; -import javafx.scene.layout.Priority; -import javafx.scene.layout.VBox; +import javafx.scene.control.Separator; +import javafx.scene.control.Tooltip; +import javafx.scene.layout.*; +import javafx.scene.web.WebView; -public class DetailView extends BorderPane { +public class DetailView extends StackPane { + + private final ChoiceBox choiceBox; + private final WebView describeWebView; + private final WebView remarkWebView; public DetailView() { super(); - setPadding(new Insets(5, 2, 5, 2)); - ChoiceBox choiceBox = new ChoiceBox<>(); - choiceBox.getItems().addAll("1", "2", "3", "4", "5"); - Label label = new Label("手动阀手动阀"); - TextField textField = new TextField(); - textField.setVisible(false); + BorderPane borderPane = new BorderPane(); + borderPane.setPadding(new Insets(5, 2, 5, 2)); + choiceBox = new ChoiceBox<>(FxApplicationContextUtils.GIT_PROJECT_OBSERVABLE_LIST); + choiceBox.setMaxWidth(300); + choiceBox.setMinWidth(300); - VBox box = new VBox(10, choiceBox, label, textField); + // 顶部 + var describeTitle = new Label("描 述: "); + Tooltip tooltip = new Tooltip("双击编辑"); + describeTitle.setTooltip(tooltip); + describeWebView = new WebView(); + HBox describeBox = new HBox(10, describeTitle, describeWebView); + HBox.setHgrow(describeTitle, Priority.ALWAYS); + describeBox.setAlignment(Pos.CENTER_LEFT); + VBox topBox = new VBox(10, choiceBox, describeBox, new Separator()); VBox.setVgrow(choiceBox, Priority.ALWAYS); - box.setAlignment(Pos.CENTER_LEFT); + topBox.setAlignment(Pos.TOP_LEFT); + + // 中间 + remarkWebView = new WebView(); + VBox centerBox = new VBox(10, remarkWebView); + + // 下边 + HBox bottomBox = new HBox(); + + // 整体 + VBox contextBox = new VBox(10, topBox, centerBox, new Separator(), bottomBox); - setTop(box); + // 备注 + var remarkLabel = new Label(); - label.setOnMouseClicked(event ->{ + borderPane.setCenter(contextBox); + + // 遮罩层 + ModalPane modalPane = new ModalPane(); + EditorPane editorPane = new EditorPane(modalPane, describeWebView, remarkLabel); + getChildren().addAll(modalPane, borderPane); + + describeTitle.setOnMouseClicked(event -> { + GitProject project = choiceBox.getValue(); + if (project == null) { + NoticeUtils.show(null, "请选择项目", Level.WARN); + return; + } if (event.getClickCount() == 2) { - textField.setText(label.getText()); - textField.setVisible(true); - label.setVisible(false); + editorPane.show(project, false); } }); + + choiceBox.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> { + if (null == newValue) { + return; + } + + describeWebView.getEngine().loadContent(newValue.description().get()); + + }); + } + + public void refresh(GitProject project) { + choiceBox.getSelectionModel().select(project); + describeWebView.getEngine().loadContent(project.description().get()); + remarkWebView.getEngine().loadContent(project.remark().get()); } } diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 3bf9a6f..e4428a9 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -13,4 +13,5 @@ open module com.leo { requires org.kordamp.ikonli.bootstrapicons; requires org.kordamp.ikonli.core; requires org.eclipse.jgit; + requires javafx.web; } -- Gitee From 0f92c77e27f9814626468838aee6c560d128f4a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E7=99=BD=E4=B8=8E=E5=AD=9F=E6=B5=A9=E7=84=B6?= <1063889643@qq.com> Date: Tue, 24 Oct 2023 17:14:57 +0800 Subject: [PATCH 4/5] =?UTF-8?q?+=20=E8=AF=A6=E6=83=85=E9=A1=B5=E5=BC=80?= =?UTF-8?q?=E5=8F=91=20-=20=E6=AE=8B=E5=BA=9F=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/light/component/EditorPane.java | 20 +-- .../com/light/component/TooltipTableRow.java | 5 +- src/main/java/com/light/view/DetailView.java | 132 ++++++++++++++---- 3 files changed, 115 insertions(+), 42 deletions(-) diff --git a/src/main/java/com/light/component/EditorPane.java b/src/main/java/com/light/component/EditorPane.java index b2fea3a..0f9e055 100644 --- a/src/main/java/com/light/component/EditorPane.java +++ b/src/main/java/com/light/component/EditorPane.java @@ -11,29 +11,28 @@ import com.light.util.H2PoolUtils; import javafx.geometry.Pos; import javafx.scene.control.Button; import javafx.scene.control.Label; +import javafx.scene.control.TextArea; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.HBox; import javafx.scene.layout.Priority; import javafx.scene.layout.VBox; import javafx.scene.text.Text; -import javafx.scene.web.HTMLEditor; -import javafx.scene.web.WebView; public class EditorPane extends ModalBox { private final ModalPane modalPane; protected final Card content = new Card(); private final Label header = new Label(); - private final HTMLEditor editor = new HTMLEditor(); + private final TextArea editor = new TextArea(); - private final WebView describeLabel; - private final Label remarkLabel; + private final Label describeLabel; + private final Text remarkLabel; private GitProject gitProject; private boolean remark; - public EditorPane(ModalPane modalPane, WebView describeLabel, Label remarkLabel) { + public EditorPane(ModalPane modalPane, Label describeLabel, Text remarkLabel) { super(modalPane); this.modalPane = modalPane; this.modalPane.setPersistent(true); @@ -46,6 +45,7 @@ public class EditorPane extends ModalBox { content.setHeader(header); content.getStyleClass().add(Tweaks.EDGE_TO_EDGE); content.setMaxSize(700, 550); + editor.setWrapText(true); content.setBody(editor); content.setFooter(createDefaultFooter()); @@ -67,7 +67,7 @@ public class EditorPane extends ModalBox { var okBtn = new Button("确定"); okBtn.getStyleClass().add("form-action"); okBtn.setOnAction(event -> { - String htmlText = editor.getHtmlText(); + String htmlText = editor.getText(); if (remark) { if (htmlText.equals(gitProject.remark().get())) { close(); @@ -81,7 +81,7 @@ public class EditorPane extends ModalBox { return; } gitProject.description().set(htmlText); - describeLabel.getEngine().loadContent(htmlText); + describeLabel.setText(htmlText); } // 更新入库 @@ -105,10 +105,10 @@ public class EditorPane extends ModalBox { public void show(GitProject gitProject, boolean remark) { if (remark) { header.setText("备 注"); - editor.setHtmlText(gitProject.remark().get()); + editor.setText(gitProject.remark().get()); } else { header.setText("描 述"); - editor.setHtmlText(gitProject.description().get()); + editor.setText(gitProject.description().get()); } this.remark = remark; this.gitProject = gitProject; diff --git a/src/main/java/com/light/component/TooltipTableRow.java b/src/main/java/com/light/component/TooltipTableRow.java index c7e4a99..6f333d6 100644 --- a/src/main/java/com/light/component/TooltipTableRow.java +++ b/src/main/java/com/light/component/TooltipTableRow.java @@ -3,6 +3,7 @@ package com.light.component; import atlantafx.base.controls.Card; import atlantafx.base.theme.Styles; import com.light.model.GitProject; +import javafx.beans.binding.Bindings; import javafx.geometry.Orientation; import javafx.scene.control.*; import javafx.scene.layout.HBox; @@ -27,7 +28,7 @@ public class TooltipTableRow extends TableRow { private final Label remoteAddr = new Label(); private final Label localAddr = new Label(); private final Label level = new Label(); - private final Label remark = new Label(); + private final Text remark = new Text(); private final HBox levelBox = new HBox(); public static Callback, TableRow> forTableRow() { @@ -42,6 +43,8 @@ public class TooltipTableRow extends TableRow { toolTipCard.setMinWidth(300); toolTipCard.setMaxWidth(700); name.getStyleClass().add(Styles.TITLE_3); + description.wrappingWidthProperty().bind(toolTipCard.widthProperty().subtract(50)); + remark.wrappingWidthProperty().bind(Bindings.subtract(toolTipCard.widthProperty(), 50)); VBox header = new VBox(5, name, description); toolTipCard.setHeader(header); diff --git a/src/main/java/com/light/view/DetailView.java b/src/main/java/com/light/view/DetailView.java index 47cc786..e467a5e 100644 --- a/src/main/java/com/light/view/DetailView.java +++ b/src/main/java/com/light/view/DetailView.java @@ -1,6 +1,7 @@ package com.light.view; import atlantafx.base.controls.ModalPane; +import atlantafx.base.theme.Styles; import com.light.component.EditorPane; import com.light.enums.Level; import com.light.model.GitProject; @@ -8,59 +9,130 @@ import com.light.util.FxApplicationContextUtils; import com.light.util.NoticeUtils; import javafx.geometry.Insets; import javafx.geometry.Pos; -import javafx.scene.control.ChoiceBox; -import javafx.scene.control.Label; -import javafx.scene.control.Separator; -import javafx.scene.control.Tooltip; +import javafx.scene.control.*; import javafx.scene.layout.*; -import javafx.scene.web.WebView; +import javafx.scene.paint.Color; +import javafx.scene.paint.Paint; +import javafx.scene.text.Text; public class DetailView extends StackPane { - private final ChoiceBox choiceBox; - private final WebView describeWebView; - private final WebView remarkWebView; + private final ComboBox choiceBox; + private final Label describeLabel; + private final Text remarkLabel; public DetailView() { super(); - BorderPane borderPane = new BorderPane(); - borderPane.setPadding(new Insets(5, 2, 5, 2)); - choiceBox = new ChoiceBox<>(FxApplicationContextUtils.GIT_PROJECT_OBSERVABLE_LIST); + choiceBox = new ComboBox<>(FxApplicationContextUtils.GIT_PROJECT_OBSERVABLE_LIST); choiceBox.setMaxWidth(300); choiceBox.setMinWidth(300); - // 顶部 var describeTitle = new Label("描 述: "); + describeTitle.getStyleClass().add(Styles.TITLE_4); Tooltip tooltip = new Tooltip("双击编辑"); describeTitle.setTooltip(tooltip); - describeWebView = new WebView(); - HBox describeBox = new HBox(10, describeTitle, describeWebView); - HBox.setHgrow(describeTitle, Priority.ALWAYS); + describeLabel = new Label(); + HBox describeBox = new HBox(10, describeTitle, describeLabel); + HBox.setHgrow(describeLabel, Priority.ALWAYS); + + describeLabel.setWrapText(true); describeBox.setAlignment(Pos.CENTER_LEFT); - VBox topBox = new VBox(10, choiceBox, describeBox, new Separator()); + VBox topBox = new VBox(10, choiceBox, describeBox); VBox.setVgrow(choiceBox, Priority.ALWAYS); topBox.setAlignment(Pos.TOP_LEFT); + topBox.setStyle("-fx-background-color: red"); // 中间 - remarkWebView = new WebView(); - VBox centerBox = new VBox(10, remarkWebView); + // 布局GridPane + GridPane gridPane = new GridPane(); + // 居中、组件水平距离和垂直距离 + gridPane.setAlignment(Pos.CENTER); + gridPane.setHgap(10); + gridPane.setVgap(10); + + // 给列设置样式 + ColumnConstraints columnConstraints = new ColumnConstraints(); + columnConstraints.setFillWidth(true); + columnConstraints.setHgrow(Priority.ALWAYS); + for (int i = 0; i < 4; i++) { + gridPane.getColumnConstraints().add(columnConstraints); + } + + // 给每行设置样式 + RowConstraints rowConstraints = new RowConstraints(); + rowConstraints.setFillHeight(true); +// rowConstraints.setVgrow(Priority.ALWAYS); + rowConstraints.setMinHeight(50d); + for (int i = 0; i < 6; i++) { + gridPane.getRowConstraints().add(rowConstraints); + } + + Label authorTitle = new Label("仓库作者: "); + authorTitle.getStyleClass().add(Styles.TITLE_4); + Text authorText = new Text("12234234"); + gridPane.add(authorTitle, 0, 0); + gridPane.add(authorText, 1, 0, 3, 1); + + Label remoteTitle = new Label("仓库地址: "); + remoteTitle.getStyleClass().add(Styles.TITLE_4); + Text remoteText = new Text("sdfsdafgasdgdfgdf"); + gridPane.add(remoteTitle, 0, 1); + gridPane.add(remoteText, 1, 1, 3, 1); + + Label localTitle = new Label("本地地址: "); + localTitle.getStyleClass().add(Styles.TITLE_4); + Text localText = new Text("dgfgsdgdfsg"); + gridPane.add(localTitle, 0, 2); + gridPane.add(localText, 1, 2, 3, 1); + + Label branchTitle = new Label("当前分支: "); + branchTitle.getStyleClass().add(Styles.TITLE_4); + ChoiceBox branchChoice = new ChoiceBox<>(); + gridPane.add(branchTitle, 0, 3); + gridPane.add(branchChoice, 1, 3); + + Label levelTitle = new Label("学习等级: "); + levelTitle.getStyleClass().add(Styles.TITLE_4); + ChoiceBox levelChoice = new ChoiceBox<>(); + gridPane.add(levelTitle, 2, 3); + gridPane.add(levelChoice, 3, 3); + + Label createTimeTitle = new Label("创建时间: "); + createTimeTitle.getStyleClass().add(Styles.TITLE_4); + Text createTimeText = new Text("1234rwer"); + gridPane.add(createTimeTitle, 0, 4); + gridPane.add(createTimeText, 1, 4); + + Label updateTimeTitle = new Label("最近更新: "); + updateTimeTitle.getStyleClass().add(Styles.TITLE_4); + Text updateTimeText = new Text("124235443"); + gridPane.add(updateTimeTitle, 2, 4); + gridPane.add(updateTimeText, 3, 4); + + Label remarkTitle = new Label("备注: "); + remarkTitle.getStyleClass().add(Styles.TITLE_4); + remarkLabel = new Text(); + remarkLabel.wrappingWidthProperty().bind(this.widthProperty().subtract(50)); + gridPane.add(remarkTitle, 0, 5); + gridPane.add(remarkLabel, 1, 5, 3, 1); + + gridPane.setStyle("-fx-background-color: green; -fx-grid-lines-visible: true"); // 下边 HBox bottomBox = new HBox(); // 整体 - VBox contextBox = new VBox(10, topBox, centerBox, new Separator(), bottomBox); - - // 备注 - var remarkLabel = new Label(); - - borderPane.setCenter(contextBox); + BorderPane borderPane = new BorderPane(); + borderPane.setPadding(new Insets(5, 2, 5, 2)); + borderPane.setTop(topBox); + borderPane.setCenter(gridPane); + borderPane.setBottom(bottomBox); // 遮罩层 ModalPane modalPane = new ModalPane(); - EditorPane editorPane = new EditorPane(modalPane, describeWebView, remarkLabel); - getChildren().addAll(modalPane, borderPane); + EditorPane editorPane = new EditorPane(modalPane, describeLabel, remarkLabel); + this.getChildren().addAll(modalPane, borderPane); describeTitle.setOnMouseClicked(event -> { GitProject project = choiceBox.getValue(); @@ -77,15 +149,13 @@ public class DetailView extends StackPane { if (null == newValue) { return; } - - describeWebView.getEngine().loadContent(newValue.description().get()); - + refresh(newValue); }); } public void refresh(GitProject project) { choiceBox.getSelectionModel().select(project); - describeWebView.getEngine().loadContent(project.description().get()); - remarkWebView.getEngine().loadContent(project.remark().get()); + describeLabel.setText(project.description().get()); + remarkLabel.setText(project.remark().get()); } } -- Gitee From 8c8b9b4f04da4dd17049316727d9806bb463ca2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E7=99=BD=E4=B8=8E=E5=AD=9F=E6=B5=A9=E7=84=B6?= <1063889643@qq.com> Date: Tue, 24 Oct 2023 23:46:34 +0800 Subject: [PATCH 5/5] =?UTF-8?q?+=20=E8=AF=A6=E6=83=85=E9=A1=B5=E5=AE=8C?= =?UTF-8?q?=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 + .../java/com/light/component/EditorPane.java | 10 +- src/main/java/com/light/util/H2PoolUtils.java | 1 + src/main/java/com/light/util/JGitUtils.java | 21 ++++ src/main/java/com/light/view/DetailView.java | 113 +++++++++++++----- 5 files changed, 112 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index cf386bb..953f994 100644 --- a/README.md +++ b/README.md @@ -39,3 +39,5 @@ - label 只能在fx主线程进行更新 - text 可以在fx异步线程中更新 + +- gridPane.setStyle("-fx-background-color: green; -fx-grid-lines-visible: true"); GridPane添加背景色和边框 \ No newline at end of file diff --git a/src/main/java/com/light/component/EditorPane.java b/src/main/java/com/light/component/EditorPane.java index 0f9e055..98472ea 100644 --- a/src/main/java/com/light/component/EditorPane.java +++ b/src/main/java/com/light/component/EditorPane.java @@ -25,19 +25,21 @@ public class EditorPane extends ModalBox { private final Label header = new Label(); private final TextArea editor = new TextArea(); - private final Label describeLabel; + private final Text describeLabel; private final Text remarkLabel; + private final Text updateTimeText; private GitProject gitProject; private boolean remark; - public EditorPane(ModalPane modalPane, Label describeLabel, Text remarkLabel) { + public EditorPane(ModalPane modalPane, Text describeLabel, Text remarkLabel, Text updateTimeText) { super(modalPane); this.modalPane = modalPane; this.modalPane.setPersistent(true); this.describeLabel = describeLabel; this.remarkLabel = remarkLabel; + this.updateTimeText = updateTimeText; createView(); } @@ -85,7 +87,9 @@ public class EditorPane extends ModalBox { } // 更新入库 - FxAsyncTask.runOnce("更新项目 " + gitProject.name().get(), () -> H2PoolUtils.updateGitProject(gitProject)); + FxAsyncTask.runOnce(System.currentTimeMillis(), "更新项目 " + gitProject.name().get(), + () -> H2PoolUtils.updateGitProject(gitProject), + () -> updateTimeText.setText(gitProject.updateTime().get())); close(); }); diff --git a/src/main/java/com/light/util/H2PoolUtils.java b/src/main/java/com/light/util/H2PoolUtils.java index 2325b58..9914cb4 100644 --- a/src/main/java/com/light/util/H2PoolUtils.java +++ b/src/main/java/com/light/util/H2PoolUtils.java @@ -429,6 +429,7 @@ public class H2PoolUtils { } public static void updateGitProject(GitProject project) { + project.updateTime().set(DateUtils.formatDateTime(new Date())); try (Connection conn = getConnection()) { String sql = "update git_project_info set branch = ? ,updatetime = ?, local = ?, description = ?, remark = ?, level = ? where id = ?"; PreparedStatement statement = conn.prepareStatement(sql); diff --git a/src/main/java/com/light/util/JGitUtils.java b/src/main/java/com/light/util/JGitUtils.java index a30b5e4..aa3a791 100644 --- a/src/main/java/com/light/util/JGitUtils.java +++ b/src/main/java/com/light/util/JGitUtils.java @@ -12,8 +12,10 @@ import javafx.beans.property.SimpleIntegerProperty; import javafx.beans.property.SimpleStringProperty; import org.apache.commons.collections4.CollectionUtils; import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.ListBranchCommand; import org.eclipse.jgit.api.PullCommand; import org.eclipse.jgit.api.PullResult; +import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.transport.CredentialsProvider; import org.eclipse.jgit.transport.RemoteConfig; import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; @@ -252,4 +254,23 @@ public class JGitUtils { throw new JGitException(); } } + + public static List branchs(File localRepoFile) throws JGitException { + List result = new ArrayList<>(); + try (Git git = Git.open(localRepoFile)) { + ListBranchCommand listBranchCommand = git.branchList(); + List callList = listBranchCommand.call(); + for (Ref ref : callList) { + result.add(ref.getName().replace("refs/heads/", "")); + } + } catch (Exception e) { + LOGGER.error("获取项目 {} 所有分支异常:{}", localRepoFile.getAbsolutePath(), e.getMessage()); + throw new JGitException(e); + } + return result; + } + + public static void main(String[] args) { + branchs(new File("D:\\workspace\\workspace-dev\\git-manager-client-fx")).forEach(System.out::println); + } } diff --git a/src/main/java/com/light/view/DetailView.java b/src/main/java/com/light/view/DetailView.java index e467a5e..33e8b9d 100644 --- a/src/main/java/com/light/view/DetailView.java +++ b/src/main/java/com/light/view/DetailView.java @@ -5,50 +5,56 @@ import atlantafx.base.theme.Styles; import com.light.component.EditorPane; import com.light.enums.Level; import com.light.model.GitProject; +import com.light.thread.FxAsyncTask; import com.light.util.FxApplicationContextUtils; +import com.light.util.H2PoolUtils; +import com.light.util.JGitUtils; import com.light.util.NoticeUtils; +import javafx.collections.FXCollections; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.control.*; import javafx.scene.layout.*; -import javafx.scene.paint.Color; -import javafx.scene.paint.Paint; import javafx.scene.text.Text; +import java.io.File; + public class DetailView extends StackPane { private final ComboBox choiceBox; - private final Label describeLabel; + private final Text describeLabel; private final Text remarkLabel; + private final Text updateTimeText; + private final Text createTimeText; + private final Text authorText; + private final Text remoteText; + private final Text localText; + private final ChoiceBox branchChoice; + private final ChoiceBox levelChoice; public DetailView() { super(); choiceBox = new ComboBox<>(FxApplicationContextUtils.GIT_PROJECT_OBSERVABLE_LIST); choiceBox.setMaxWidth(300); - choiceBox.setMinWidth(300); // 顶部 var describeTitle = new Label("描 述: "); describeTitle.getStyleClass().add(Styles.TITLE_4); Tooltip tooltip = new Tooltip("双击编辑"); describeTitle.setTooltip(tooltip); - describeLabel = new Label(); + describeLabel = new Text(); HBox describeBox = new HBox(10, describeTitle, describeLabel); - HBox.setHgrow(describeLabel, Priority.ALWAYS); - describeLabel.setWrapText(true); - describeBox.setAlignment(Pos.CENTER_LEFT); + describeLabel.setWrappingWidth(700); + describeBox.setAlignment(Pos.TOP_LEFT); VBox topBox = new VBox(10, choiceBox, describeBox); - VBox.setVgrow(choiceBox, Priority.ALWAYS); - topBox.setAlignment(Pos.TOP_LEFT); - topBox.setStyle("-fx-background-color: red"); // 中间 // 布局GridPane GridPane gridPane = new GridPane(); // 居中、组件水平距离和垂直距离 gridPane.setAlignment(Pos.CENTER); - gridPane.setHgap(10); + gridPane.setHgap(5); gridPane.setVgap(10); // 给列设置样式 @@ -70,69 +76,68 @@ public class DetailView extends StackPane { Label authorTitle = new Label("仓库作者: "); authorTitle.getStyleClass().add(Styles.TITLE_4); - Text authorText = new Text("12234234"); + authorText = new Text(); gridPane.add(authorTitle, 0, 0); gridPane.add(authorText, 1, 0, 3, 1); Label remoteTitle = new Label("仓库地址: "); remoteTitle.getStyleClass().add(Styles.TITLE_4); - Text remoteText = new Text("sdfsdafgasdgdfgdf"); + remoteText = new Text(); gridPane.add(remoteTitle, 0, 1); gridPane.add(remoteText, 1, 1, 3, 1); Label localTitle = new Label("本地地址: "); localTitle.getStyleClass().add(Styles.TITLE_4); - Text localText = new Text("dgfgsdgdfsg"); + localText = new Text(); gridPane.add(localTitle, 0, 2); gridPane.add(localText, 1, 2, 3, 1); Label branchTitle = new Label("当前分支: "); branchTitle.getStyleClass().add(Styles.TITLE_4); - ChoiceBox branchChoice = new ChoiceBox<>(); + branchChoice = new ChoiceBox<>(); + branchChoice.setMaxWidth(180d); gridPane.add(branchTitle, 0, 3); gridPane.add(branchChoice, 1, 3); Label levelTitle = new Label("学习等级: "); levelTitle.getStyleClass().add(Styles.TITLE_4); - ChoiceBox levelChoice = new ChoiceBox<>(); + levelChoice = new ChoiceBox<>(); + levelChoice.getItems().addAll(0, 1, 2, 3, 4, 5); + levelChoice.setMaxWidth(180d); gridPane.add(levelTitle, 2, 3); gridPane.add(levelChoice, 3, 3); Label createTimeTitle = new Label("创建时间: "); createTimeTitle.getStyleClass().add(Styles.TITLE_4); - Text createTimeText = new Text("1234rwer"); + createTimeText = new Text(); gridPane.add(createTimeTitle, 0, 4); gridPane.add(createTimeText, 1, 4); Label updateTimeTitle = new Label("最近更新: "); updateTimeTitle.getStyleClass().add(Styles.TITLE_4); - Text updateTimeText = new Text("124235443"); + updateTimeText = new Text(); gridPane.add(updateTimeTitle, 2, 4); gridPane.add(updateTimeText, 3, 4); Label remarkTitle = new Label("备注: "); + remarkTitle.setTooltip(tooltip); remarkTitle.getStyleClass().add(Styles.TITLE_4); remarkLabel = new Text(); - remarkLabel.wrappingWidthProperty().bind(this.widthProperty().subtract(50)); + remarkLabel.setWrappingWidth(700); gridPane.add(remarkTitle, 0, 5); gridPane.add(remarkLabel, 1, 5, 3, 1); - gridPane.setStyle("-fx-background-color: green; -fx-grid-lines-visible: true"); - - // 下边 - HBox bottomBox = new HBox(); + Pane centerPane = new Pane(gridPane); // 整体 - BorderPane borderPane = new BorderPane(); - borderPane.setPadding(new Insets(5, 2, 5, 2)); - borderPane.setTop(topBox); - borderPane.setCenter(gridPane); - borderPane.setBottom(bottomBox); + VBox vBox = new VBox(10, topBox, new Separator(), centerPane); + vBox.setPadding(new Insets(5, 2, 5, 2)); + VBox.setVgrow(centerPane, Priority.ALWAYS); // 遮罩层 ModalPane modalPane = new ModalPane(); - EditorPane editorPane = new EditorPane(modalPane, describeLabel, remarkLabel); - this.getChildren().addAll(modalPane, borderPane); + EditorPane editorPane = new EditorPane(modalPane, describeLabel, remarkLabel, updateTimeText); + this.getChildren().addAll(modalPane, vBox); describeTitle.setOnMouseClicked(event -> { GitProject project = choiceBox.getValue(); @@ -144,18 +149,62 @@ public class DetailView extends StackPane { editorPane.show(project, false); } }); + remarkTitle.setOnMouseClicked(event -> { + GitProject project = choiceBox.getValue(); + if (project == null) { + NoticeUtils.show(null, "请选择项目", Level.WARN); + return; + } + if (event.getClickCount() == 2) { + editorPane.show(project, true); + } + }); choiceBox.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> { - if (null == newValue) { + if (null == newValue || oldValue == newValue) { return; } refresh(newValue); }); + + levelChoice.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> { + GitProject gitProject = choiceBox.getValue(); + if (null == newValue || null == gitProject || newValue == gitProject.level().get()) { + return; + } + // 更新入库 + gitProject.level().set(newValue); + FxAsyncTask.runOnce(System.currentTimeMillis(), "更新项目学习等级 " + gitProject.name().get(), + () -> H2PoolUtils.updateGitProject(gitProject), + () -> updateTimeText.setText(gitProject.updateTime().get())); + }); } public void refresh(GitProject project) { choiceBox.getSelectionModel().select(project); + describeLabel.setText(project.description().get()); remarkLabel.setText(project.remark().get()); + updateTimeText.setText(project.updateTime().get()); + createTimeText.setText(project.createTime()); + authorText.setText(project.author().get()); + remoteText.setText(project.remote()); + localText.setText(project.local().get()); + + // 异步获取所有分支 + branchChoice.getSelectionModel().clearSelection(); + FxAsyncTask.runOnceBack(System.currentTimeMillis(), "获取项目所有分支 " + project.name().get(), + () -> JGitUtils.branchs(new File(project.local().get())), + success -> { + if (success.isEmpty()) { + return; + } + branchChoice.setItems(FXCollections.observableList(success)); + branchChoice.getSelectionModel().select(project.branch().get()); + }, + fail -> branchChoice.setItems(null)); + + + levelChoice.getSelectionModel().select(project.level().get()); } } -- Gitee