commit
35f0a83fa6
13
pom.xml
13
pom.xml
@ -15,7 +15,20 @@
|
|||||||
<junit.version>5.9.2</junit.version>
|
<junit.version>5.9.2</junit.version>
|
||||||
<javafx.version>20.0.2</javafx.version>
|
<javafx.version>20.0.2</javafx.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>terminalfx-repo</id>
|
||||||
|
<url>https://github.com/javaterminal/terminalfx/raw/master/releases</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.kodedu.terminalfx</groupId>
|
||||||
|
<artifactId>terminalfx</artifactId>
|
||||||
|
<version>1.2.0</version>
|
||||||
|
</dependency>
|
||||||
<!-- https://mvnrepository.com/artifact/org.fxmisc.richtext/richtextfx -->
|
<!-- https://mvnrepository.com/artifact/org.fxmisc.richtext/richtextfx -->
|
||||||
<!--JavaFX 的富文本区域-->
|
<!--JavaFX 的富文本区域-->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|||||||
@ -19,6 +19,7 @@ module org.jcnc.jnotepad {
|
|||||||
requires java.desktop;
|
requires java.desktop;
|
||||||
requires org.commonmark;
|
requires org.commonmark;
|
||||||
requires javafx.web;
|
requires javafx.web;
|
||||||
|
requires com.kodedu.terminalfx;
|
||||||
|
|
||||||
exports org.jcnc.jnotepad;
|
exports org.jcnc.jnotepad;
|
||||||
exports org.jcnc.jnotepad.model.enums;
|
exports org.jcnc.jnotepad.model.enums;
|
||||||
|
|||||||
@ -120,6 +120,7 @@ public class ApplicationManager {
|
|||||||
instance.checkFileTabStatus(instance.getSelected());
|
instance.checkFileTabStatus(instance.getSelected());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
primaryStage.setOnCloseRequest(event -> System.exit(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -1,15 +1,16 @@
|
|||||||
package org.jcnc.jnotepad.component.module.vbox;
|
package org.jcnc.jnotepad.component.module.vbox;
|
||||||
|
|
||||||
|
import com.kodedu.terminalfx.TerminalBuilder;
|
||||||
|
import com.kodedu.terminalfx.TerminalTab;
|
||||||
|
import com.kodedu.terminalfx.config.TerminalConfig;
|
||||||
import javafx.scene.control.Tab;
|
import javafx.scene.control.Tab;
|
||||||
import javafx.scene.control.TabPane;
|
import javafx.scene.control.TabPane;
|
||||||
import org.jcnc.jnotepad.component.module.vbox.components.CmdTerminalBox;
|
|
||||||
import org.jcnc.jnotepad.component.module.vbox.components.DebugBox;
|
import org.jcnc.jnotepad.component.module.vbox.components.DebugBox;
|
||||||
import org.jcnc.jnotepad.component.module.vbox.components.RunBox;
|
import org.jcnc.jnotepad.component.module.vbox.components.RunBox;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 底部Run,Debug,Cmd面板
|
* 底部Run,Debug,Cmd面板
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* @author cccqyu
|
* @author cccqyu
|
||||||
*/
|
*/
|
||||||
public class BuildPanel extends TabPane {
|
public class BuildPanel extends TabPane {
|
||||||
@ -24,12 +25,15 @@ public class BuildPanel extends TabPane {
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final CmdTerminalBox cmdTerminalBox;
|
|
||||||
private final RunBox runBox;
|
private final RunBox runBox;
|
||||||
private final DebugBox debugBox;
|
private final DebugBox debugBox;
|
||||||
|
|
||||||
private BuildPanel() {
|
private BuildPanel() {
|
||||||
cmdTerminalBox = new CmdTerminalBox();
|
TerminalConfig config = new TerminalConfig();
|
||||||
|
TerminalBuilder builder = new TerminalBuilder(config);
|
||||||
|
TerminalTab terminalTab = builder.newTerminal();
|
||||||
|
terminalTab.setClosable(false);
|
||||||
|
|
||||||
runBox = new RunBox();
|
runBox = new RunBox();
|
||||||
debugBox = new DebugBox();
|
debugBox = new DebugBox();
|
||||||
|
|
||||||
@ -39,13 +43,7 @@ public class BuildPanel extends TabPane {
|
|||||||
Tab buildTab = new Tab("构建", debugBox);
|
Tab buildTab = new Tab("构建", debugBox);
|
||||||
buildTab.setClosable(false);
|
buildTab.setClosable(false);
|
||||||
|
|
||||||
Tab cmdTab = new Tab("终端",cmdTerminalBox);
|
this.getTabs().addAll(runTab, buildTab, terminalTab);
|
||||||
cmdTab.setClosable(false);
|
|
||||||
this.getTabs().addAll(runTab,buildTab,cmdTab);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CmdTerminalBox getCmdTerminalBox() {
|
|
||||||
return cmdTerminalBox;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public RunBox getRunBox() {
|
public RunBox getRunBox() {
|
||||||
|
|||||||
@ -1,150 +0,0 @@
|
|||||||
package org.jcnc.jnotepad.component.module.vbox.components;
|
|
||||||
|
|
||||||
import javafx.animation.KeyFrame;
|
|
||||||
import javafx.animation.Timeline;
|
|
||||||
import javafx.application.Platform;
|
|
||||||
import javafx.concurrent.Task;
|
|
||||||
import javafx.geometry.Insets;
|
|
||||||
import javafx.scene.control.TextField;
|
|
||||||
import javafx.scene.layout.Priority;
|
|
||||||
import javafx.scene.layout.VBox;
|
|
||||||
import javafx.util.Duration;
|
|
||||||
import org.fxmisc.richtext.StyleClassedTextArea;
|
|
||||||
import org.jcnc.jnotepad.util.LogUtil;
|
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
import java.nio.charset.Charset;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 命令行终端界面。
|
|
||||||
*
|
|
||||||
* @author luke
|
|
||||||
*/
|
|
||||||
public class CmdTerminalBox extends VBox {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于显示命令输出的文本区域
|
|
||||||
*/
|
|
||||||
private final StyleClassedTextArea cmdOutput;
|
|
||||||
/**
|
|
||||||
* 用户输入命令的文本框
|
|
||||||
*/
|
|
||||||
private final TextField cmdInput;
|
|
||||||
/**
|
|
||||||
* 用于运行命令的进程
|
|
||||||
*/
|
|
||||||
private Process cmdProcess;
|
|
||||||
/**
|
|
||||||
* 用于向命令进程发送输入的写入器
|
|
||||||
*/
|
|
||||||
private PrintWriter cmdInputWriter;
|
|
||||||
|
|
||||||
String currentDirectory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建CmdTerminal对象的构造函数。
|
|
||||||
*/
|
|
||||||
public CmdTerminalBox() {
|
|
||||||
// 创建UI元素
|
|
||||||
cmdOutput = new StyleClassedTextArea();
|
|
||||||
cmdInput = new TextField();
|
|
||||||
|
|
||||||
// 设置CodeArea的大小策略和边距
|
|
||||||
// 让CodeArea在垂直方向上扩展以填充剩余空间
|
|
||||||
VBox.setVgrow(cmdOutput, Priority.ALWAYS);
|
|
||||||
// 设置CodeArea的边距
|
|
||||||
VBox.setMargin(cmdOutput, new Insets(8));
|
|
||||||
|
|
||||||
// 添加输入框的Enter键监听器,按下Enter执行命令
|
|
||||||
cmdInput.setOnAction(e -> executeCommand());
|
|
||||||
|
|
||||||
// 创建布局
|
|
||||||
getChildren().addAll(cmdOutput, cmdInput);
|
|
||||||
|
|
||||||
// 获取当前工作目录的文件夹路径
|
|
||||||
currentDirectory = System.getProperty("user.dir");
|
|
||||||
|
|
||||||
|
|
||||||
// 创建并启动cmd进程,使用GBK字符编码
|
|
||||||
try {
|
|
||||||
cmdProcess = new ProcessBuilder("cmd.exe")
|
|
||||||
// 设置CMD工作目录为当前文件夹路径
|
|
||||||
.directory(new File(currentDirectory))
|
|
||||||
.redirectErrorStream(true)
|
|
||||||
.start();
|
|
||||||
cmdInputWriter = new PrintWriter(new OutputStreamWriter(cmdProcess.getOutputStream(), Charset.forName("GBK")));
|
|
||||||
} catch (IOException e) {
|
|
||||||
LogUtil.getLogger(this.getClass()).info("已调用, {}", cmdProcess);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 延迟执行打印当前文件夹路径的语句
|
|
||||||
Timeline timeline = new Timeline(new KeyFrame(Duration.seconds(0.5), event -> {
|
|
||||||
appendTextToCmdOutput(currentDirectory + ">" + "\n");
|
|
||||||
|
|
||||||
}));
|
|
||||||
timeline.setCycleCount(1);
|
|
||||||
timeline.play();
|
|
||||||
|
|
||||||
// 读取cmd的输出并显示在UI中
|
|
||||||
InputStream cmdOutputInputStream = cmdProcess.getInputStream();
|
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(cmdOutputInputStream, Charset.forName("GBK")));
|
|
||||||
|
|
||||||
Thread cmdOutputThread = getCmdOutputThread(reader);
|
|
||||||
cmdOutputThread.start();
|
|
||||||
|
|
||||||
// 关闭cmd进程
|
|
||||||
Platform.runLater(() -> getScene().getWindow().setOnCloseRequest(e -> {
|
|
||||||
if (cmdProcess != null) {
|
|
||||||
cmdProcess.destroy();
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
private Thread getCmdOutputThread(BufferedReader reader) {
|
|
||||||
Task<Void> cmdOutputTask = new Task<>() {
|
|
||||||
@Override
|
|
||||||
protected Void call() {
|
|
||||||
String line;
|
|
||||||
try {
|
|
||||||
while ((line = reader.readLine()) != null) {
|
|
||||||
final String outputLine = line + "\n";
|
|
||||||
Platform.runLater(() -> appendTextToCmdOutput(outputLine));
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
LogUtil.getLogger(this.getClass()).info("已调用, {}", this);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Thread cmdOutputThread = new Thread(cmdOutputTask);
|
|
||||||
cmdOutputThread.setDaemon(true);
|
|
||||||
return cmdOutputThread;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 执行用户输入的命令。
|
|
||||||
*/
|
|
||||||
private void executeCommand() {
|
|
||||||
String command = cmdInput.getText();
|
|
||||||
if (cmdProcess != null && command != null) {
|
|
||||||
cmdInputWriter.println(command);
|
|
||||||
cmdInputWriter.flush();
|
|
||||||
cmdInput.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 将文本追加到命令输出文本区域,并滚动到最后一行。
|
|
||||||
*
|
|
||||||
* @param text 要追加的文本
|
|
||||||
*/
|
|
||||||
private void appendTextToCmdOutput(String text) {
|
|
||||||
Platform.runLater(() -> {
|
|
||||||
cmdOutput.appendText(text);
|
|
||||||
// 将滚动条滚动到最后一行
|
|
||||||
cmdOutput.moveTo(cmdOutput.getLength());
|
|
||||||
cmdOutput.requestFollowCaret();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user