Compare commits
4 Commits
release-v1
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
35f0a83fa6 | ||
|
|
7254419b46 | ||
|
|
aa50ffe32e | ||
|
|
56fdb968b4 |
13
pom.xml
13
pom.xml
@ -15,7 +15,20 @@
|
||||
<junit.version>5.9.2</junit.version>
|
||||
<javafx.version>20.0.2</javafx.version>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>terminalfx-repo</id>
|
||||
<url>https://github.com/javaterminal/terminalfx/raw/master/releases</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.kodedu.terminalfx</groupId>
|
||||
<artifactId>terminalfx</artifactId>
|
||||
<version>1.2.0</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.fxmisc.richtext/richtextfx -->
|
||||
<!--JavaFX 的富文本区域-->
|
||||
<dependency>
|
||||
|
||||
@ -19,6 +19,7 @@ module org.jcnc.jnotepad {
|
||||
requires java.desktop;
|
||||
requires org.commonmark;
|
||||
requires javafx.web;
|
||||
requires com.kodedu.terminalfx;
|
||||
|
||||
exports org.jcnc.jnotepad;
|
||||
exports org.jcnc.jnotepad.model.enums;
|
||||
|
||||
@ -120,6 +120,7 @@ public class ApplicationManager {
|
||||
instance.checkFileTabStatus(instance.getSelected());
|
||||
}
|
||||
});
|
||||
primaryStage.setOnCloseRequest(event -> System.exit(0));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1,15 +1,16 @@
|
||||
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.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.RunBox;
|
||||
|
||||
/**
|
||||
* 底部Run,Debug,Cmd面板
|
||||
*
|
||||
*
|
||||
* @author cccqyu
|
||||
*/
|
||||
public class BuildPanel extends TabPane {
|
||||
@ -24,28 +25,25 @@ public class BuildPanel extends TabPane {
|
||||
return instance;
|
||||
}
|
||||
|
||||
private final CmdTerminalBox cmdTerminalBox;
|
||||
private final RunBox runBox;
|
||||
private final DebugBox debugBox;
|
||||
|
||||
private BuildPanel() {
|
||||
cmdTerminalBox = new CmdTerminalBox();
|
||||
TerminalConfig config = new TerminalConfig();
|
||||
TerminalBuilder builder = new TerminalBuilder(config);
|
||||
TerminalTab terminalTab = builder.newTerminal();
|
||||
terminalTab.setClosable(false);
|
||||
|
||||
runBox = new RunBox();
|
||||
debugBox = new DebugBox();
|
||||
|
||||
Tab runTab = new Tab("运行",runBox);
|
||||
Tab runTab = new Tab("运行", runBox);
|
||||
runTab.setClosable(false);
|
||||
|
||||
Tab buildTab = new Tab("构建", debugBox);
|
||||
buildTab.setClosable(false);
|
||||
|
||||
Tab cmdTab = new Tab("终端",cmdTerminalBox);
|
||||
cmdTab.setClosable(false);
|
||||
this.getTabs().addAll(runTab,buildTab,cmdTab);
|
||||
}
|
||||
|
||||
public CmdTerminalBox getCmdTerminalBox() {
|
||||
return cmdTerminalBox;
|
||||
this.getTabs().addAll(runTab, buildTab, terminalTab);
|
||||
}
|
||||
|
||||
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