增加本地终端

This commit is contained in:
许轲 2023-09-17 23:30:24 +08:00
parent 88eee51941
commit 425c4ce6bd
9 changed files with 184 additions and 14 deletions

View File

@ -30,10 +30,12 @@ module org.jcnc.jnotepad {
exports org.jcnc.jnotepad.util; exports org.jcnc.jnotepad.util;
exports org.jcnc.jnotepad.common.interfaces; exports org.jcnc.jnotepad.common.interfaces;
opens org.jcnc.jnotepad.app.config; opens org.jcnc.jnotepad.app.config;
exports org.jcnc.jnotepad.views.root.center.main.bottom.status;
exports org.jcnc.jnotepad.plugin.interfaces; exports org.jcnc.jnotepad.plugin.interfaces;
exports org.jcnc.jnotepad.ui.dialog; exports org.jcnc.jnotepad.ui.dialog;
exports org.jcnc.jnotepad.ui.dialog.interfaces; exports org.jcnc.jnotepad.ui.dialog.interfaces;
exports org.jcnc.jnotepad.model.entity; exports org.jcnc.jnotepad.model.entity;
exports org.jcnc.jnotepad.views.root.bottom;
exports org.jcnc.jnotepad.views.root.bottom.status;
exports org.jcnc.jnotepad.views.root.bottom.cmd;
} }

View File

@ -7,7 +7,7 @@ import org.jcnc.jnotepad.app.i18n.UiResourceBundle;
import org.jcnc.jnotepad.common.constants.AppConstants; import org.jcnc.jnotepad.common.constants.AppConstants;
import org.jcnc.jnotepad.common.constants.TextConstants; import org.jcnc.jnotepad.common.constants.TextConstants;
import org.jcnc.jnotepad.ui.module.LineNumberTextArea; import org.jcnc.jnotepad.ui.module.LineNumberTextArea;
import org.jcnc.jnotepad.views.root.center.main.bottom.status.BottomStatusBox; import org.jcnc.jnotepad.views.root.bottom.status.BottomStatusBox;
import org.jcnc.jnotepad.views.root.center.main.center.tab.CenterTab; import org.jcnc.jnotepad.views.root.center.main.center.tab.CenterTab;
import org.jcnc.jnotepad.views.root.center.main.center.tab.CenterTabPane; import org.jcnc.jnotepad.views.root.center.main.center.tab.CenterTabPane;

View File

@ -4,7 +4,7 @@ import javafx.geometry.Insets;
import org.fxmisc.richtext.LineNumberFactory; import org.fxmisc.richtext.LineNumberFactory;
import org.fxmisc.richtext.StyleClassedTextArea; import org.fxmisc.richtext.StyleClassedTextArea;
import org.jcnc.jnotepad.util.LogUtil; import org.jcnc.jnotepad.util.LogUtil;
import org.jcnc.jnotepad.views.root.center.main.bottom.status.BottomStatusBox; import org.jcnc.jnotepad.views.root.bottom.status.BottomStatusBox;
import org.jcnc.jnotepad.views.root.center.main.center.tab.CenterTab; import org.jcnc.jnotepad.views.root.center.main.center.tab.CenterTab;
import org.jcnc.jnotepad.views.root.center.main.center.tab.CenterTabPane; import org.jcnc.jnotepad.views.root.center.main.center.tab.CenterTabPane;
import org.slf4j.Logger; import org.slf4j.Logger;

View File

@ -0,0 +1,75 @@
package org.jcnc.jnotepad.ui.module;
import javafx.application.Platform;
import javafx.geometry.Pos;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.VBox;
import org.fxmisc.richtext.CodeArea;
import org.fxmisc.richtext.LineNumberFactory;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class TerminalEmulatorComponent extends VBox {
private CodeArea terminalOutput;
private Process process;
public TerminalEmulatorComponent() {
initializeUI();
}
private void initializeUI() {
terminalOutput = new CodeArea();
TextField commandInput = new TextField();
// 设置行号
terminalOutput.setParagraphGraphicFactory(LineNumberFactory.get(terminalOutput));
commandInput.setOnKeyPressed(event -> {
if (event.getCode() == KeyCode.ENTER) {
String command = commandInput.getText();
executeCommand(command);
commandInput.clear();
}
});
getChildren().addAll(terminalOutput, commandInput);
setAlignment(Pos.CENTER);
// 设置布局样式和大小
setSpacing(10);
setMinSize(800, 600);
}
private void executeCommand(String command) {
try {
ProcessBuilder processBuilder = new ProcessBuilder(command.split(" "));
processBuilder.redirectErrorStream(true);
process = processBuilder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream(), "GBK"));
String line;
while ((line = reader.readLine()) != null) {
appendToTerminalOutput(line + "\n");
}
int exitCode = process.waitFor();
appendToTerminalOutput("Exit Code: " + exitCode + "\n");
} catch (IOException | InterruptedException e) {
appendToTerminalOutput("Error: " + e.getMessage() + "\n");
}
}
private void appendToTerminalOutput(String text) {
Platform.runLater(() -> {
terminalOutput.appendText(text);
// 将滚动条滚动到最后一行
terminalOutput.moveTo(terminalOutput.getLength());
terminalOutput.requestFollowCaret();
});
}
}

View File

@ -1,7 +1,12 @@
package org.jcnc.jnotepad.views.root.bottom; package org.jcnc.jnotepad.views.root.bottom;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import org.jcnc.jnotepad.ui.module.AbstractVerticalBox; import org.jcnc.jnotepad.ui.module.AbstractVerticalBox;
import org.jcnc.jnotepad.views.root.center.main.bottom.status.BottomStatusBox; import org.jcnc.jnotepad.views.root.bottom.cmd.CmdStatusBox;
import org.jcnc.jnotepad.views.root.bottom.status.BottomStatusBox;
import org.jcnc.jnotepad.views.root.left.sidebar.tools.SidebarToolBar;
/** /**
* 底部根侧边栏垂直布局 * 底部根侧边栏垂直布局
@ -12,12 +17,6 @@ import org.jcnc.jnotepad.views.root.center.main.bottom.status.BottomStatusBox;
*/ */
public class RootBottomSideBarVerticalBox extends AbstractVerticalBox { public class RootBottomSideBarVerticalBox extends AbstractVerticalBox {
private static final RootBottomSideBarVerticalBox INSTANCE = new RootBottomSideBarVerticalBox();
private RootBottomSideBarVerticalBox() {
initSidebarVerticalBox();
}
/** /**
* 获取 RootBottomSideBarVerticalBox 的唯一实例 * 获取 RootBottomSideBarVerticalBox 的唯一实例
* *
@ -28,6 +27,19 @@ public class RootBottomSideBarVerticalBox extends AbstractVerticalBox {
} }
private void initSidebarVerticalBox() { private void initSidebarVerticalBox() {
getChildren().addAll(BottomStatusBox.getInstance()); VBox bottomSideBarVerticalBox = new VBox();
bottomSideBarVerticalBox.getChildren().addAll(CmdStatusBox.getInstance(), BottomStatusBox.getInstance());
getChildren().addAll(bottomSideBarVerticalBox);
} }
private static final RootBottomSideBarVerticalBox INSTANCE = new RootBottomSideBarVerticalBox();
private RootBottomSideBarVerticalBox() {
initSidebarVerticalBox();
}
} }

View File

@ -0,0 +1,78 @@
package org.jcnc.jnotepad.views.root.bottom.cmd;
import javafx.application.Platform;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.TextArea;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.text.Text;
import javafx.stage.Modality;
import javafx.stage.Stage;
import org.jcnc.jnotepad.controller.event.handler.menubar.SaveAsFile;
import org.jcnc.jnotepad.util.LogUtil;
/**
* @author luke
*/
public class CmdStatusBox extends HBox {
private static final CmdStatusBox CMD_STATUS_BOX = new CmdStatusBox();
private CmdStatusBox() {
initStatusBox();
}
public static CmdStatusBox getInstance() {
return CMD_STATUS_BOX;
}
/**
* 初始化底部CMD按钮组件
*/
public void initStatusBox() {
var menuBar = new MenuBar();
HBox.setHgrow(menuBar, Priority.ALWAYS);
menuBar.setPadding(new Insets(-3, 0, -3, 35));
// 创建菜单项 1
var runMenu = new Menu();
var cmdMenu = new Menu();
var buildMenu = new Menu();
// 创建菜单项 2
var runLabel = new Label("运行");
var cmdLabel = new Label("终端");
var buildLabel = new Label("构建");
// 创建菜单点击事件 2
runMenu.setGraphic(runLabel);
cmdMenu.setGraphic(cmdLabel);
buildMenu.setGraphic(buildLabel);
cmdLabel.setOnMouseClicked(mouseEvent -> {
showTerminal();
LogUtil.getLogger(this.getClass()).info("打开终端成功!");
});
// 将一级菜单添加到菜单栏
menuBar.getMenus().addAll(runMenu, cmdMenu, buildMenu);
// 将菜单栏添加到CmdStatusBox
this.getChildren().add(menuBar);
}
/**
* 在菜单上方创建一个终端
*/
private void showTerminal() {
}
}

View File

@ -1,4 +1,4 @@
package org.jcnc.jnotepad.views.root.center.main.bottom.status; package org.jcnc.jnotepad.views.root.bottom.status;
import javafx.beans.value.ChangeListener; import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
@ -131,6 +131,7 @@ public class BottomStatusBox extends AbstractHorizontalBox {
/** /**
* 更新行列信息 * 更新行列信息
*
* @param caretPosition 光标位置 * @param caretPosition 光标位置
* @param text 文本内容 * @param text 文本内容
*/ */

View File

@ -2,7 +2,7 @@ package org.jcnc.jnotepad.views.root.center.main.center.tab;
import javafx.scene.control.TabPane; import javafx.scene.control.TabPane;
import org.jcnc.jnotepad.controller.config.AppConfigController; import org.jcnc.jnotepad.controller.config.AppConfigController;
import org.jcnc.jnotepad.views.root.center.main.bottom.status.BottomStatusBox; import org.jcnc.jnotepad.views.root.bottom.status.BottomStatusBox;
import org.jcnc.jnotepad.views.root.top.menu.TopMenuBar; import org.jcnc.jnotepad.views.root.top.menu.TopMenuBar;
/** /**

View File

@ -1,6 +1,7 @@
package org.jcnc.jnotepad.views.root.top.menu; package org.jcnc.jnotepad.views.root.top.menu;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
import javafx.geometry.Insets;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.input.KeyCombination; import javafx.scene.input.KeyCombination;
import javafx.stage.Stage; import javafx.stage.Stage;
@ -141,6 +142,7 @@ public class TopMenuBar extends MenuBar {
* 初始化菜单栏 * 初始化菜单栏
*/ */
public void initMenuBar() { public void initMenuBar() {
setPadding(new Insets(-3,0,-3,0));
initFileMenu(); initFileMenu();
initLanguageMenu(); initLanguageMenu();
initSettingMenu(); initSettingMenu();