2023年10月9日18:19:01

master
zhangmeng 2023-10-09 18:19:15 +08:00
parent 83e4410b17
commit ec9eace48c
7 changed files with 1495 additions and 23 deletions

View File

@ -0,0 +1,879 @@
package com.zhangmeng.tools.controller;
import com.zhangmeng.tools.dto.FileTreeView;
import com.zhangmeng.tools.editors.ace.AceEditor;
import com.zhangmeng.tools.editors.ace.AceMode;
import com.zhangmeng.tools.editors.codemirr.CodeMirrWebView;
import com.zhangmeng.tools.editors.monaco.*;
import com.zhangmeng.tools.editors.timifx.TimiFxEditor;
import com.zhangmeng.tools.utils.AlertUtils;
import com.zhangmeng.tools.utils.ClipboardUtils;
import com.zhangmeng.tools.utils.ImagePath;
import com.zhangmeng.tools.utils.ResourcesUtils;
import eu.mihosoft.monacofx.Editor;
import eu.mihosoft.monacofx.MonacoFX;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Paint;
import javafx.scene.text.Font;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import javafx.util.Callback;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.fxmisc.flowless.VirtualizedScrollPane;
import org.fxmisc.richtext.CodeArea;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import static net.imyeyu.timifx.TimiFX.BORDER_EXLEFT;
@Slf4j
public class EditorListImplController {
public enum Type {
JAVA,
HTML,
GO,
JS,
CSS,
SQL,
XML,
YML,
MARKDOWN
}
private SimpleDoubleProperty width = new SimpleDoubleProperty(0.0);
private SimpleDoubleProperty height = new SimpleDoubleProperty(0.0);
private AnchorPane root;
private AceEditor acJsEditor;
private MonacoWebView monacoEdit;
private CodeMirrWebView codemirror;
private AnchorPane timiFx;
private SimpleObjectProperty<File> choose_file = new SimpleObjectProperty<>(null);
public static final String color_cell = "#f4f4f4";
@FXML
private ListView<ResourcesUtils.EditorList> listView;
@FXML
private SplitPane splitPane;
@FXML
public void date_query_menu_item() {
load_small_tools(5);
}
@FXML
public void cron_menu_item() {
load_small_tools(6);
}
@FXML
public void video_menu_item() {
load_player(0);
}
@FXML
public void music_menu_item() {
load_player(1);
}
@FXML
public void vip_parser_menu_item() {
load_player(2);
}
@FXML
public void hex_16() {
load_small_tools(0);
}
@FXML
private void hex_16_menu_item() {
load_small_tools(0);
}
@FXML
private void unicode_menu_item() {
load_small_tools(1);
}
@FXML
private void jwt_menu_item() {
load_small_tools(2);
}
@FXML
private void color_choose_menu_item() {
load_small_tools(3);
}
@FXML
public void qr_code_menu_item() {
load_small_tools(4);
}
@FXML
public void base_62_menu_item() {
load_codec_tools(0);
}
@FXML
public void base_64_menu_item() {
load_codec_tools(1);
}
@FXML
public void base_32_menu_item() {
load_codec_tools(2);
}
@FXML
public void morse_coder_menu_item() {
load_codec_tools(3);
}
@FXML
private void sql_code_gen_menu_item() {
load_sql_tools(0);
}
@FXML
public void netty_client_menu_item() {
load_network_tools(0);
}
public void load_network_tools(int index) {
AnchorPane fx = null;
try {
fx = FXMLLoader.load(ResourcesUtils.getResource("network-tools"));
} catch (IOException e) {
e.printStackTrace();
}
Scene scene = new Scene(fx);
Stage stage = (Stage) splitPane.getScene().getWindow();
stage.setScene(scene);
ListView<ResourcesUtils.Player> listView = (ListView) fx.lookup("#listView");
listView.getSelectionModel().select(index);
}
public void load_sql_tools(int index) {
AnchorPane fx = null;
try {
fx = FXMLLoader.load(ResourcesUtils.getResource("sql-tools"));
} catch (IOException e) {
e.printStackTrace();
}
Scene scene = new Scene(fx);
Stage stage = (Stage) splitPane.getScene().getWindow();
stage.setScene(scene);
ListView<ResourcesUtils.Player> listView = (ListView) fx.lookup("#listView");
listView.getSelectionModel().select(index);
}
public void load_codec_tools(int index) {
AnchorPane fx = null;
try {
fx = FXMLLoader.load(ResourcesUtils.getResource("codec-tools"));
} catch (IOException e) {
e.printStackTrace();
}
Scene scene = new Scene(fx);
Stage stage = (Stage) splitPane.getScene().getWindow();
stage.setScene(scene);
ListView<ResourcesUtils.Player> listView = (ListView) fx.lookup("#listView");
listView.getSelectionModel().select(index);
}
public void load_small_tools(int index) {
AnchorPane fx = null;
try {
fx = FXMLLoader.load(ResourcesUtils.getResource("small-tools"));
} catch (IOException e) {
e.printStackTrace();
}
Scene scene = new Scene(fx);
Stage stage = (Stage) splitPane.getScene().getWindow();
stage.setScene(scene);
ListView<ResourcesUtils.Player> listView = (ListView) fx.lookup("#listView");
listView.getSelectionModel().select(index);
}
public void load_player(int index) {
AnchorPane fx = null;
try {
fx = FXMLLoader.load(ResourcesUtils.getResource("player"));
} catch (IOException e) {
e.printStackTrace();
}
Scene scene = new Scene(fx);
Stage stage = (Stage) splitPane.getScene().getWindow();
stage.setScene(scene);
ListView<ResourcesUtils.Player> listView = (ListView) fx.lookup("#listView");
listView.getSelectionModel().select(index);
}
@FXML
public void initialize() {
init();
listView.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
if (newValue != null) {
boolean flag = false;
if (newValue.getIndex() == 0) {
if (acJsEditor != null) {
flag = true;
}
acJsEditor(flag);
}
if (newValue.getIndex() == 1) {
if (monacoEdit != null) {
flag = true;
}
monacoEdit(flag);
}
if (newValue.getIndex() == 2) {
if (codemirror != null) {
flag = true;
}
codemirror(flag);
}
if (newValue.getIndex() == 3) {
if (timiFx != null) {
flag = true;
}
timiFx(flag);
}
}
});
}
public static Image getImage(ResourcesUtils.EditorList player) {
return switch (player) {
case Ace_JS -> new Image(ImagePath.path(ImagePath.ImagePathType.MD5));
case Monaco_JS -> new Image(ImagePath.path(ImagePath.ImagePathType.MD5));
case CodeMirror_JS -> new Image(ImagePath.path(ImagePath.ImagePathType.MD5));
case Timi_Fx -> new Image(ImagePath.path(ImagePath.ImagePathType.MD5));
};
}
public void init() {
ResourcesUtils.EditorList[] values = ResourcesUtils.EditorList.values();
ObservableList<ResourcesUtils.EditorList> list = FXCollections.observableArrayList();
list.addAll(Arrays.asList(values));
listView.setItems(list);
listView.setFixedCellSize(40);
listView.setCellFactory(new Callback<>() {
private int position;
@Override
public ListCell<ResourcesUtils.EditorList> call(ListView<ResourcesUtils.EditorList> playerListView) {
Label label = new Label();
label.setPrefWidth(200);
ListCell<ResourcesUtils.EditorList> listCell = new ListCell<>() {
@Override
protected void updateItem(ResourcesUtils.EditorList player, boolean b) {
super.updateItem(player, b);
if (!b) {
HBox hBox = new HBox(25);
hBox.setAlignment(Pos.CENTER);
label.setText(player.getTitle());
label.setTextFill(Paint.valueOf("#000000"));
Image im = getImage(player);
ImageView iv = new ImageView(im);
iv.setPreserveRatio(true);
iv.setFitWidth(15);
hBox.getChildren().add(iv);
hBox.getChildren().add(label);
this.setGraphic(hBox);
}
this.setStyle("-fx-background-color: " + color_cell);
}
};
listCell.hoverProperty().addListener((observableValue, aBoolean, t1) -> {
if (t1 && !label.getText().equals("")) {
position = playerListView.getItems().indexOf(label.getText());
label.setFont(new Font(16));
playerListView.getFocusModel().focus(position);
listCell.setStyle("-fx-background-color: #369e7d");
} else {
label.setPrefHeight(20);
label.setFont(new Font(13));
listCell.setStyle("-fx-background-color: " + color_cell);
}
});
return listCell;
}
});
acJsEditor(false);
}
private void acJsEditor(boolean flag) {
//默认选择第一个
listView.getSelectionModel().select(0);
if (!flag) {
acJsEditor = new AceEditor();
root = acJsEditor;
WebView view = acJsEditor.getWebView();
AnchorPane.setTopAnchor(view, 0.0);
AnchorPane.setBottomAnchor(view, 0.0);
AnchorPane.setLeftAnchor(view, 0.0);
AnchorPane.setRightAnchor(view, 0.0);
} else {
root = acJsEditor;
}
common_method();
}
private void monacoEdit(boolean flag) {
//默认选择第一个
listView.getSelectionModel().select(1);
if (!flag) {
monacoEdit = new MonacoWebView();
root = monacoEdit;
} else {
root = monacoEdit;
}
common_method();
}
private void codemirror(boolean flag) {
//默认选择第一个
listView.getSelectionModel().select(2);
if (!flag) {
codemirror = new CodeMirrWebView();
root = codemirror;
} else {
root = codemirror;
}
common_method();
}
private void timiFx(boolean flag) {
//默认选择第一个
listView.getSelectionModel().select(3);
if (!flag) {
root = new TimiFxEditor();
timiFx = root;
} else {
root = timiFx;
}
common_method();
}
public void writer_file() {
log.info("writer_file__path:" + choose_file.get().getName());
int index = listView.getSelectionModel().getSelectedIndex();
String text = null;
switch (index) {
case 0 -> text = acJsEditor.getText();
case 1 -> text = monacoEdit.text_code.getValue();
case 2 -> text = codemirror.text_code.getValue();
}
try {
FileWriter writer = new FileWriter(choose_file.get());
writer.write(text);
writer.flush();
writer.close();
} catch (IOException ex) {
ex.printStackTrace();
}
AlertUtils.alert_warning("tab " + choose_file.get().getName() + "保存成功!");
}
public void file_checked(File file) {
String extension = FilenameUtils.getExtension(file.getName());
boolean flag = true;
if (extension.equals("mp4")) {
flag = false;
}
if (extension.equals("jpg")) {
flag = false;
}
if (extension.equals("png")) {
flag = false;
}
if (extension.equals("avi")) {
flag = false;
}
if (extension.equals("zip")) {
flag = false;
}
if (extension.equals("ico")) {
flag = false;
}
if (extension.equals("exe")) {
flag = false;
}
if (flag) {
Type type = null;
if (extension.equals("java")) {
type = Type.JAVA;
}
if (extension.equals("go")) {
type = Type.GO;
}
if (extension.equals("html")) {
type = Type.HTML;
}
if (extension.equals("sql")) {
type = Type.SQL;
}
if (extension.equals("xml")) {
type = Type.XML;
}
if (extension.equals("yml")) {
type = Type.YML;
}
if (type == null) {
type = Type.JAVA;
}
if (type == null) {
type = Type.MARKDOWN;
}
open_file(file, type);
} else {
AlertUtils.alert_warning("该文件不支持!");
}
}
public void open_file(File file, Type type) {
String file_content = null;
try {
file_content = Files.readString(choose_file.get().toPath(), StandardCharsets.UTF_8);
} catch (IOException e) {
try {
file_content = Files.readString(choose_file.get().toPath(), Charset.forName("GBK"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
int index = listView.getSelectionModel().getSelectedIndex();
switch (index) {
case 0 -> {
switch (type){
case JAVA -> acJsEditor.setAceMode(AceMode.JAVA);
case HTML -> acJsEditor.setAceMode(AceMode.HTML);
case XML -> acJsEditor.setAceMode(AceMode.XML);
case SQL -> acJsEditor.setAceMode(AceMode.SQL);
case MARKDOWN -> acJsEditor.setAceMode(AceMode.MARKDOWN);
}
acJsEditor.setAceText(file_content);
}
case 1 -> monacoEdit.setText(file_content);
case 2 -> codemirror.setText(file_content);
}
}
private void common_method() {
//splitPane.getItems().remove(1);
splitPane.getItems().clear();
//添加文件选择
File file = new File("D:\\generate");
FileTreeView fileTreeView = new FileTreeView(file);
fileTreeView.setBorder(BORDER_EXLEFT);
//fileTreeView.addItemFilter(file -> file.isDirectory() || file.getName().endsWith(".txt"));
splitPane.getItems().add(0, fileTreeView);
splitPane.getItems().add(1, root);
splitPane.setDividerPosition(0, 0.2);
splitPane.setDividerPosition(1, 0.8);
fileTreeView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<TreeItem<File>>() {
@Override
public void changed(ObservableValue<? extends TreeItem<File>> observable, TreeItem<File> oldValue, TreeItem<File> newValue) {
if (newValue != null) {
File value = newValue.getValue();
if (!value.isDirectory()) {
choose_file.setValue(value);
log.info("selectedItemProperty:------------>:" + value.getName());
}
}
}
});
fileTreeView.setOnMouseClicked(event -> {
if (event.getButton() == MouseButton.PRIMARY && event.getClickCount() == 2) {
// 双击左键的操作
log.info("open file:" + choose_file.get().getName());
file_checked(choose_file.get());
}
});
root.widthProperty().addListener((observable, oldValue, newValue) -> {
if (newValue != null) {
double width = splitPane.getWidth();
EditorListImplController.this.width.set(width);
log.info("home:--->width:{}", width);
}
});
root.heightProperty().addListener((observable, oldValue, newValue) -> {
if (newValue != null) {
double height = splitPane.getHeight();
EditorListImplController.this.height.set(height);
log.info("home:--->height:{}", height);
}
});
this.width.addListener((observable, oldValue, newValue) -> {
EditorListImplController.this.root.setPrefWidth(newValue.doubleValue() - listView.getWidth());
log.info("root:=====================>width:" + (newValue.doubleValue() - listView.getWidth()));
});
this.height.addListener((observable, oldValue, newValue) -> {
EditorListImplController.this.root.setPrefHeight(newValue.doubleValue() - listView.getHeight());
log.info("root:=====================>:height" + (newValue.doubleValue() - listView.getWidth()));
});
}
@FXML
public void http_request_menu_item(ActionEvent event) {
load_http_tools(0);
}
@FXML
public void http_upload_menu_item(ActionEvent event) {
load_http_tools(1);
}
@FXML
public void http_download_menu_item(ActionEvent event) {
load_http_tools(2);
}
public void load_http_tools(int index) {
AnchorPane fx = null;
try {
fx = FXMLLoader.load(ResourcesUtils.getResource("http-tools"));
} catch (IOException e) {
e.printStackTrace();
}
Scene scene = new Scene(fx);
Stage stage = (Stage) splitPane.getScene().getWindow();
stage.setScene(scene);
ListView<ResourcesUtils.Player> listView = (ListView) fx.lookup("#listView");
listView.getSelectionModel().select(index);
}
@FXML
public void mail_menu_item(ActionEvent event) {
load_small_tools(7);
}
public void http_server_menu_item(ActionEvent event) {
load_server_tools(0);
}
public void ftp_server_menu_item(ActionEvent event) {
load_server_tools(1);
}
public void load_server_tools(int index) {
AnchorPane fx = null;
try {
fx = FXMLLoader.load(ResourcesUtils.getResource("server-tools"));
} catch (IOException e) {
e.printStackTrace();
}
Scene scene = new Scene(fx);
Stage stage = (Stage) splitPane.getScene().getWindow();
stage.setScene(scene);
ListView<ResourcesUtils.Player> listView = (ListView) fx.lookup("#listView");
listView.getSelectionModel().select(index);
}
public void ssh_client_menu_item(ActionEvent event) {
load_server_tools(2);
}
public void socket_server_menu_item(ActionEvent event) {
load_server_tools(3);
}
public void telephone_menu_item(ActionEvent event) {
load_small_tools(8);
}
public void mybatis_plus_gen_menu_item(ActionEvent event) {
load_sql_tools(1);
}
public void JsonView_menu_item(ActionEvent event) {
load_small_tools(9);
}
public void maven_jar_install_menu_item(ActionEvent event) {
load_small_tools(10);
}
public void word_ocr_menu_item(ActionEvent event) {
load_small_tools(11);
}
public void bar_code_menu_item(ActionEvent event) {
load_small_tools(12);
}
public void pdf_menu_item(ActionEvent event) {
load_small_tools(13);
}
public void json_javabean_gen_menu_item(ActionEvent event) {
load_sql_tools(2);
}
public void music_parser_menu_item(ActionEvent event) {
load_player(3);
}
public void batch_update_file_name_menu_item(ActionEvent event) {
load_small_tools(14);
}
public void socket_client_aio_menu_item(ActionEvent event) {
load_server_tools(4);
}
public void socket_server_aio_menu_item(ActionEvent event) {
load_server_tools(5);
}
public void socket_server_nio_menu_item(ActionEvent event) {
load_server_tools(6);
}
public void socket_client_nio_menu_item(ActionEvent event) {
load_server_tools(7);
}
public void capter_screen_menu_item(ActionEvent event) {
load_small_tools(15);
}
public void sql_query_gen_menu_item(ActionEvent event) {
load_sql_tools(3);
}
public void video_transcoder_menu_item(ActionEvent event) {
load_player(4);
}
public void json_to_struct_menu_item(ActionEvent event) {
load_go_tools(0);
}
public void load_go_tools(int index) {
AnchorPane fx = null;
try {
fx = FXMLLoader.load(ResourcesUtils.getResource("go-tools"));
} catch (IOException e) {
e.printStackTrace();
}
Scene scene = new Scene(fx);
Stage stage = (Stage) splitPane.getScene().getWindow();
stage.setScene(scene);
ListView<ResourcesUtils.Player> listView = (ListView) fx.lookup("#listView");
listView.getSelectionModel().select(index);
}
public void file_edit_menu_item(ActionEvent event) {
load_small_tools(16);
}
public void web_socket_client_menu_item(ActionEvent event) {
load_server_tools(8);
}
public void layui_form_gen_menu_item(ActionEvent actionEvent) {
load_small_tools(17);
}
public void log_console_menu_item(ActionEvent actionEvent) {
load_small_tools(18);
}
public void edit_plus_code_menu_item(ActionEvent actionEvent) {
load_small_tools(19);
}
public void minio_upload_menu_item(ActionEvent actionEvent) {
load_small_tools(20);
}
public void js_edit_list(int index) {
AnchorPane fx = null;
try {
fx = FXMLLoader.load(ResourcesUtils.getResource("editor-list"));
} catch (IOException e) {
e.printStackTrace();
}
Scene scene = new Scene(fx);
Stage stage = (Stage) splitPane.getScene().getWindow();
stage.setScene(scene);
ListView<ResourcesUtils.Player> listView = (ListView) fx.lookup("#listView");
listView.getSelectionModel().select(index);
}
public void md5_menu_item(ActionEvent actionEvent) {
load_encrypt(0);
}
public void spring_security_menu_item(ActionEvent actionEvent) {
load_encrypt(1);
}
public void jks_file_menu_item(ActionEvent actionEvent) {
load_encrypt(2);
}
public void load_encrypt(int index) {
Stage stage = (Stage) splitPane.getScene().getWindow();
AnchorPane fx = null;
try {
fx = FXMLLoader.load(ResourcesUtils.getResource("home"));
} catch (IOException e) {
e.printStackTrace();
}
Scene scene = new Scene(fx);
stage.setScene(scene);
ListView<ResourcesUtils.Player> listView = (ListView) fx.lookup("#listView");
listView.getSelectionModel().select(index);
}
public void ace_js_menu_item(ActionEvent actionEvent) {
js_edit_list(0);
}
public void monaco_js_menu_item(ActionEvent actionEvent) {
js_edit_list(1);
}
public void codemirror_js_menu_item(ActionEvent actionEvent) {
js_edit_list(2);
}
public void timeFx_fx_menu_item(ActionEvent actionEvent) {
js_edit_list(3);
}
public void ace_menu_item(ActionEvent actionEvent) {
boolean flag = false;
if (acJsEditor != null) {
flag = true;
}
acJsEditor(flag);
}
public void monaco_menu_item(ActionEvent actionEvent) {
boolean flag = false;
if (monacoEdit != null) {
flag = true;
}
monacoEdit(flag);
}
public void codemirror_menu_item(ActionEvent actionEvent) {
boolean flag = false;
if (codemirror != null) {
flag = true;
}
codemirror(flag);
}
public void timeFx_menu_item(ActionEvent actionEvent) {
boolean flag = false;
if (timiFx != null) {
flag = true;
}
timiFx(flag);
}
}

View File

@ -645,4 +645,40 @@ public class HomeController implements Serializable {
public void codemirror_js_menu_item(ActionEvent actionEvent) {
js_edit_list(2);
}
public void ace_menu_item(ActionEvent actionEvent) {
js_edit_list_impl(0);
}
public void monaco_menu_item(ActionEvent actionEvent) {
js_edit_list_impl(1);
}
public void codemirror_menu_item(ActionEvent actionEvent) {
js_edit_list_impl(2);
}
public void timeFx_menu_item(ActionEvent actionEvent) {
js_edit_list_impl(3);
}
public void js_edit_list_impl(int index){
AnchorPane fx = null;
try {
fx = FXMLLoader.load(ResourcesUtils.getResource("editor-list-impl"));
} catch (IOException e) {
e.printStackTrace();
}
Scene scene = new Scene(fx);
Stage stage = (Stage) splitPane.getScene().getWindow();
stage.setScene(scene);
// ListView<ResourcesUtils.Player> listView = (ListView) fx.lookup("#listView");
// listView.getSelectionModel().select(index);
}
public void timeFx_fx_menu_item(ActionEvent actionEvent) {
js_edit_list(3);
}
}

View File

@ -0,0 +1,406 @@
package com.zhangmeng.tools.dto;
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javafx.application.Platform;
import javafx.beans.Observable;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TreeCell;
import javafx.scene.control.TreeItem;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.text.Text;
import javax.naming.NoPermissionException;
import net.imyeyu.timifx.TimiFX;
import net.imyeyu.timifx.component.ContextMenu;
import net.imyeyu.timifx.component.XTreeView;
import net.imyeyu.timifx.component.alert.AlertConfirm;
import net.imyeyu.timifx.component.alert.AlertTextField;
import net.imyeyu.timifx.component.alert.AlertTips;
import net.imyeyu.timifx.component.alert.AlertButton.Action;
import net.imyeyu.timifx.icon.TimiFXIcon;
import net.imyeyu.timifx.service.RunAsync;
import net.imyeyu.timijava.IO;
import net.imyeyu.timijava.Lang;
import net.imyeyu.timijava.TimiJava;
import net.imyeyu.timijava.bean.CallbackReturn;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FileTreeView extends XTreeView<File> implements TimiFX {
private static final Logger log = LoggerFactory.getLogger(net.imyeyu.timifx.component.FileTreeView.class);
protected final BooleanBinding findingItem;
protected final BooleanProperty showHide = new SimpleBooleanProperty(false);
protected final ObservableList<File> selectDeque = FXCollections.synchronizedObservableList(FXCollections.observableArrayList());
protected final List<CallbackReturn<File, Boolean>> itemFilters = new ArrayList();
public FileTreeView(File root) {
this.findingItem = Bindings.isNotEmpty(this.selectDeque);
this.disableProperty().bind(this.findingItem);
this.setCellFactory((cell) -> {
return new TreeCell<File>() {
final Label loading = new Label(Lang.text("public.loading"));
final Text iconFile = TimiFXIcon.fromName("FILE");
final Text iconDirectory = TimiFXIcon.fromName("FOLDER");
{
this.iconFile.fillProperty().bind(Bindings.when(FileTreeView.this.focusedProperty().and(this.selectedProperty())).then(TimiFX.GRAY_WHITE).otherwise(TimiFX.GRAY));
this.iconDirectory.fillProperty().bind(Bindings.when(FileTreeView.this.focusedProperty().and(this.selectedProperty())).then(TimiFX.GRAY_WHITE).otherwise(TimiFX.GRAY));
}
protected void updateItem(File file, boolean empty) {
super.updateItem(file, empty);
if (empty) {
this.setText("");
this.setGraphic((Node)null);
} else if (file == null) {
this.setGraphic(this.loading);
} else {
if (TimiJava.isEmpty(file.getName())) {
this.setText(file.toString());
} else {
this.setText(file.getName());
}
this.setGraphic(file.isFile() ? this.iconFile : this.iconDirectory);
}
}
};
});
MenuItem menuMkdir = new MenuItem(Lang.text("timifx.file.mkdir"), TimiFXIcon.fromName("FOLDER_ADD"));
MenuItem menuRename = new MenuItem(Lang.text("public.rename"));
MenuItem menuRefresh = new MenuItem(Lang.text("public.refresh"), TimiFXIcon.fromName("REFRESH"));
MenuItem menuDestroy = new MenuItem(Lang.text("public.delete"), TimiFXIcon.fromName("FAIL", RED));
this.setContextMenu(new ContextMenu(new MenuItem[]{menuMkdir, menuRename, menuRefresh, TimiFX.sep(), menuDestroy}));
menuMkdir.disableProperty().bind(menuRefresh.disableProperty());
menuMkdir.setOnAction((e) -> {
this.mkdir((TreeItem)this.getSelectionModel().getSelectedItem());
});
menuRename.disableProperty().bind(TimiFX.onlyOnceInList(this.getSelectionModel().getSelectedItems()).not());
menuRename.setOnAction((e) -> {
this.rename((TreeItem)this.getSelectionModel().getSelectedItem());
});
menuRefresh.disableProperty().bind(Bindings.createBooleanBinding(() -> {
List<TreeItem<File>> items = this.getSelectionModel().getSelectedItems();
return items == null || items.size() != 1 || ((File)((TreeItem)items.get(0)).getValue()).isFile();
}, new Observable[]{this.getSelectionModel().selectedItemProperty()}));
menuRefresh.setOnAction((e) -> {
this.refreshItem((TreeItem)this.getSelectionModel().getSelectedItem());
});
List<File> roots = new ArrayList<>();
roots.add(root);
menuDestroy.disableProperty().bind(Bindings.createBooleanBinding(() -> {
ObservableList<TreeItem<File>> items = this.getSelectionModel().getSelectedItems();
if (items.isEmpty()) {
return true;
} else {
for(int i = 0; i < items.size(); ++i) {
if (roots.contains(((TreeItem)items.get(i)).getValue())) {
return true;
}
}
return false;
}
}, new Observable[]{this.getSelectionModel().getSelectedItems()}));
menuDestroy.setOnAction((e) -> {
this.destroy(this.getSelectionModel().getSelectedItems());
});
this.addEventFilter(KeyEvent.KEY_RELEASED, (e) -> {
boolean control = e.isControlDown();
boolean shift = e.isShiftDown();
boolean alt = e.isAltDown();
KeyCode code = e.getCode();
if (!control && !shift && !alt) {
switch(code) {
case F2:
menuRename.fire();
break;
case F5:
menuRefresh.fire();
break;
case DELETE:
menuDestroy.fire();
}
}
if (control && shift && !alt && code == KeyCode.N) {
menuMkdir.fire();
}
});
CallbackReturn<File, Boolean> filterHidden = (file) -> {
return !file.isHidden();
};
this.itemFilters.add(filterHidden);
this.showHide.addListener((obs, o, n) -> {
if (this.isShowHide()) {
this.itemFilters.remove(filterHidden);
} else {
this.itemFilters.add(filterHidden);
}
});
for(int i = 0; i < roots.size(); ++i) {
this.getRoots().add(new FileItem((File)roots.get(i)));
}
}
public void mkdir(TreeItem<File> base) {
if (base != null) {
AlertTextField alert = new AlertTextField(Lang.text("timifx.file.mkdir"));
alert.setTips(Lang.text("public.name"));
alert.setOnActionEvent((action) -> {
if (action == Action.CONFIRM) {
try {
String var10000 = IO.fitPath(((File)base.getValue()).getAbsolutePath());
IO.dir(var10000 + alert.getText());
this.refreshItem((TreeItem)this.getSelectionModel().getSelectedItem());
} catch (NoPermissionException var5) {
var5.printStackTrace();
}
}
return true;
});
alert.autoSize().showRelativeCenter(this.getScene().getWindow());
}
}
public void rename(TreeItem<File> file) {
if (file != null) {
AlertTextField alert = new AlertTextField(Lang.text("timifx.file.rename"));
alert.setTips(Lang.text("public.name"));
alert.setOnActionEvent((action) -> {
if (action == Action.CONFIRM) {
IO.rename((File)((TreeItem)this.getSelectionModel().getSelectedItem()).getValue(), alert.getText());
this.refreshItem(((TreeItem)this.getSelectionModel().getSelectedItem()).getParent());
}
return true;
});
alert.autoSize().showRelativeCenter(this.getScene().getWindow());
}
}
public void destroy(final List<TreeItem<File>> files) {
if (!TimiJava.isEmpty(files)) {
(new AlertConfirm(Lang.text("timifx.file.destroy")) {
protected void onConfirm() {
(new RunAsync<TreeItem<File>>() {
protected TreeItem<File> call() {
List<File> items = files.stream().map(TreeItem::getValue).toList();
int l;
for(l = 0; l < items.size(); ++l) {
IO.destroy((File)items.get(l));
}
l = 2147483647;
TreeItem<File> item = null;
for(int i = 0; i < items.size(); ++i) {
int j = FileTreeView.this.getTreeItemLevel((TreeItem)files.get(i));
if (j < l) {
l = j;
item = (TreeItem)files.get(i);
if (item.getParent() != null) {
item = item.getParent();
}
}
}
return item;
}
protected void onFinish(TreeItem<File> item) {
if (item != null) {
FileTreeView.this.refreshItem(item);
}
}
protected void onException(Throwable e) {
log.error("destroy fail", e);
AlertTips.error(getScene().getWindow(), Lang.text("timifx.file.destroy_fail"));
}
}).start();
}
}).autoSize().showRelativeCenter(this.getScene().getWindow());
}
}
public void refreshItem(TreeItem<File> treeItem) {
if (treeItem instanceof net.imyeyu.timifx.component.FileTreeView.FileItem) {
FileTreeView.FileItem fileItem = (FileTreeView.FileItem)treeItem;
fileItem.getChildren().clear();
fileItem.getChildren().add(new FileTreeView.FileItem());
fileItem.asyncLoadChildren();
}
}
public void refreshItem(FileTreeView.FileItem fileItem) {
fileItem.getChildren().clear();
fileItem.getChildren().add(new FileTreeView.FileItem());
fileItem.asyncLoadChildren();
}
public void selectItem(String path) {
if (TimiJava.isEmpty(path)) {
path = "./";
}
this.selectItem(new File(path));
}
public void selectItem(File file) {
File parent = file.getAbsoluteFile();
if (!parent.exists()) {
parent = (new File("./")).getAbsoluteFile();
}
do {
this.selectDeque.add(0, parent);
} while((parent = parent.getParentFile()) != null);
if (TimiJava.isNotEmpty(this.selectDeque)) {
ObservableList<TreeItem<File>> roots = this.getRoots();
for(int i = 0; i < roots.size(); ++i) {
((TreeItem)roots.get(i)).setExpanded(false);
if (((File)((TreeItem)roots.get(i)).getValue()).equals(this.selectDeque.get(0))) {
this.selectDeque.remove(0);
((TreeItem)roots.get(i)).setExpanded(true);
if (TimiJava.isEmpty(this.selectDeque)) {
break;
}
}
}
}
}
/** @deprecated */
@Deprecated
public void setItemFactory(CallbackReturn<File, Boolean> itemFactory) {
this.itemFilters.clear();
this.itemFilters.add(itemFactory);
}
public void addItemFilter(CallbackReturn<File, Boolean> itemFilter) {
this.itemFilters.add(itemFilter);
}
public void removeItemFilter(CallbackReturn<File, Boolean> itemFilter) {
this.itemFilters.remove(itemFilter);
}
public void setShowHide(boolean showHide) {
this.showHide.set(showHide);
}
public boolean isShowHide() {
return this.showHide.get();
}
public BooleanProperty showHideProperty() {
return this.showHide;
}
public BooleanBinding findingItemProperty() {
return this.findingItem;
}
public final class FileItem extends TreeItem<File> {
FileItem() {
this((File)null);
}
FileItem(File file) {
super(file);
if (file != null && file.isDirectory()) {
this.getChildren().add(FileTreeView.this.new FileItem((File)null));
}
this.expandedProperty().addListener((obs, o, isExpanded) -> {
if (isExpanded) {
FileTreeView.this.getSelectionModel().clearSelection();
FileTreeView.this.getSelectionModel().select(this);
this.asyncLoadChildren();
} else {
this.getChildren().add(FileTreeView.this.new FileItem());
}
});
}
void asyncLoadChildren() {
RunAsync.runback(() -> {
List<FileTreeView.FileItem> fileItems = new ArrayList();
File[] files = ((File)this.getValue()).listFiles();
if (files != null) {
List<File> fileList = Arrays.stream(files).sorted(TimiJava.COMPARATOR_FILE_NAME).toList();
label26:
for(int i = 0; i < fileList.size(); ++i) {
for(int j = 0; j < FileTreeView.this.itemFilters.size(); ++j) {
if (!(Boolean)((CallbackReturn) FileTreeView.this.itemFilters.get(j)).handler((File)fileList.get(i))) {
continue label26;
}
}
fileItems.add(FileTreeView.this.new FileItem((File)fileList.get(i)));
}
}
return fileItems;
}, (items) -> {
this.getChildren().setAll(items);
if (TimiJava.isNotEmpty(FileTreeView.this.selectDeque)) {
File file = (File) FileTreeView.this.selectDeque.remove(0);
for(int i = 0; i < items.size(); ++i) {
if (((File)((FileTreeView.FileItem)items.get(i)).getValue()).equals(file)) {
if (((File)((FileTreeView.FileItem)items.get(i)).getValue()).isDirectory()) {
((FileTreeView.FileItem)items.get(i)).setExpanded(true);
}
break;
}
}
if (TimiJava.isEmpty(FileTreeView.this.selectDeque)) {
Platform.runLater(() -> {
FileTreeView.this.scrollTo(FileTreeView.this.getSelectionModel().getSelectedIndex() - 5);
});
}
}
});
}
}
}

View File

@ -48,6 +48,14 @@ public class AceEditor extends AnchorPane {
private JSObject editor;
private File file;
public File getFile() {
return file;
}
public void setFile(File file) {
this.file = file;
}
public WebView getWebView() {
return webView;
}
@ -77,7 +85,7 @@ public class AceEditor extends AnchorPane {
initialize();
}
private void setText(String text) {
public void setText(String text) {
this.text.set(text);
}
@ -86,7 +94,7 @@ public class AceEditor extends AnchorPane {
*
* @param value
*/
private void setAceText(String value) {
public void setAceText(String value) {
editor.call("setValue", value, 1);
// 或者调用js中定义好的方法
// JSObject editor = (JSObject) engine.executeScript("window");
@ -106,7 +114,7 @@ public class AceEditor extends AnchorPane {
/**
*
*/
private void setAceTheme(AceTheme aceTheme) {
public void setAceTheme(AceTheme aceTheme) {
editor.call("setTheme", aceTheme.getValue());
}
@ -126,7 +134,7 @@ public class AceEditor extends AnchorPane {
/**
*
*/
private void setAceMode(AceMode mode) {
public void setAceMode(AceMode mode) {
window.call("setEditorMode", mode.getValue());
}

View File

@ -9,18 +9,15 @@ public class AceHelper {
private static final String ace_js = "/static/editors/ace-builds/src-min/ace.js";
private static final String ext_language_tools_js = "/static/editors/ace-builds/src-min/ext-language_tools.js";
public static String getHtml(AceMode aceMode,AceTheme aceTheme) {
String model_js = "/static/editors/ace-builds/src-min/" + aceMode.getName();
public static String getHtml(AceMode aceMode, AceTheme aceTheme) {
String theme_js = "/static/editors/ace-builds/src-min/" + aceTheme.getName();
try (
InputStream aceJsStream = AceHelper.class.getResourceAsStream(ace_js);
InputStream ext_language_tools = AceHelper.class.getResourceAsStream(ext_language_tools_js);
InputStream modelJsStream = AceHelper.class.getResourceAsStream(model_js);
// InputStream themeJsStream = AceHelper.class.getResourceAsStream(theme_js);
) {
String html = """
StringBuilder html = new StringBuilder("""
<!DOCTYPE html>
<html lang="en">
<head>
@ -40,7 +37,7 @@ public class AceHelper {
#editor-container{
height: 100%;
width: 100%;
}
.ace_editor.ace_autocomplete {
width: 415px;
@ -57,25 +54,26 @@ public class AceHelper {
<body>
<div id="editor-container" ></div>
""";
""");
html += "<script>" + new String(Objects.requireNonNull(aceJsStream).readAllBytes(), StandardCharsets.UTF_8) + "</script>\n" +
"<!--要更改主题只需包含主题的JavaScript文件-->\n" +
"\n" ;
html.append("<script>").append(new String(Objects.requireNonNull(aceJsStream).readAllBytes(), StandardCharsets.UTF_8)).append("</script>\n").append("<!--要更改主题只需包含主题的JavaScript文件-->\n").append("\n");
//加载所有主题
//加载所有主题
for (AceTheme value : AceTheme.values()) {
String theme_path = "/static/editors/ace-builds/src-min/" + value.getName();
InputStream themeStream = AceHelper.class.getResourceAsStream(theme_path);
html += "<script>" + new String(Objects.requireNonNull(themeStream).readAllBytes(), StandardCharsets.UTF_8) + "</script>\n" ;
html.append("<script>").append(new String(Objects.requireNonNull(themeStream).readAllBytes(), StandardCharsets.UTF_8)).append("</script>\n");
}
html+=
"<!--默认情况下,编辑器只支持纯文本模式;许多其他语言作为单独的模块可用。在包含该模式的JavaScript文件后:-->\n" +
"<script>" + new String(Objects.requireNonNull(modelJsStream).readAllBytes(), StandardCharsets.UTF_8) + "</script>\n" +
"<script>" + new String(Objects.requireNonNull(ext_language_tools).readAllBytes(), StandardCharsets.UTF_8) +"</script>\n";
for (AceMode value : AceMode.values()) {
String model_js = "/static/editors/ace-builds/src-min/" + value.getName();
InputStream modelJsStream = AceHelper.class.getResourceAsStream(model_js);
html.append("<script>").append(new String(Objects.requireNonNull(modelJsStream).readAllBytes(), StandardCharsets.UTF_8)).append("</script>\n");
}
html += """
html.append("<script>").append(new String(Objects.requireNonNull(ext_language_tools).readAllBytes(), StandardCharsets.UTF_8)).append("</script>\n");
html.append("""
<script>
var editor = ace.edit("editor-container");
// 使用主题:
@ -143,9 +141,9 @@ public class AceHelper {
</script>
</body>
</html>""";
</html>""");
return html;
return html.toString();
} catch (Exception e) {
throw new RuntimeException(e);
}

View File

@ -0,0 +1,135 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane prefHeight="800.0"
prefWidth="1661.0" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="com.zhangmeng.tools.controller.EditorListImplController">
<children>
<MenuBar layoutX="14.0" layoutY="27.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0"
AnchorPane.topAnchor="0.0">
<menus>
<Menu mnemonicParsing="false" text="加密工具">
<items>
<MenuItem mnemonicParsing="false" onAction="#md5_menu_item" text="md5 加密"/>
<MenuItem mnemonicParsing="false" onAction="#spring_security_menu_item" text="spring security 加密"/>
<MenuItem mnemonicParsing="false" onAction="#jks_file_menu_item" text="jkd 文件生成"/>
</items>
</Menu>
<Menu mnemonicParsing="false" text="影音工具">
<items>
<MenuItem mnemonicParsing="false" text="视频播放" onAction="#video_menu_item"/>
<MenuItem mnemonicParsing="false" text="音乐播放" onAction="#music_menu_item"/>
<MenuItem mnemonicParsing="false" text="vip 视频解析" onAction="#vip_parser_menu_item"/>
<MenuItem mnemonicParsing="false" text="音乐解析" onAction="#music_parser_menu_item"/>
<MenuItem mnemonicParsing="false" text="视频转码" onAction="#video_transcoder_menu_item"/>
</items>
</Menu>
<Menu mnemonicParsing="false" text="常用小工具">
<items>
<MenuItem mnemonicParsing="false" text="16进制Hex" onAction="#hex_16_menu_item"/>
<MenuItem mnemonicParsing="false" text="Unicode和字符串转换" onAction="#unicode_menu_item"/>
<MenuItem mnemonicParsing="false" text="jwt工具" onAction="#jwt_menu_item"/>
<MenuItem mnemonicParsing="false" text="颜色选择工具" onAction="#color_choose_menu_item"/>
<MenuItem mnemonicParsing="false" text="二维码生成" onAction="#qr_code_menu_item"/>
<MenuItem mnemonicParsing="false" text="时间工具" onAction="#date_query_menu_item"/>
<MenuItem mnemonicParsing="false" text="cron表达式" onAction="#cron_menu_item"/>
<MenuItem mnemonicParsing="false" text="邮件发送" onAction="#mail_menu_item"/>
<MenuItem mnemonicParsing="false" text="手机号工具" onAction="#telephone_menu_item"/>
<MenuItem mnemonicParsing="false" text="JsonView" onAction="#JsonView_menu_item"/>
<MenuItem mnemonicParsing="false" text="maven-jar-install" onAction="#maven_jar_install_menu_item"/>
<MenuItem mnemonicParsing="false" text="word-ocr" onAction="#word_ocr_menu_item"/>
<MenuItem mnemonicParsing="false" text="条形码识别" onAction="#bar_code_menu_item"/>
<MenuItem mnemonicParsing="false" text="pdf识别" onAction="#pdf_menu_item"/>
<MenuItem mnemonicParsing="false" text="批量修改文件名" onAction="#batch_update_file_name_menu_item"/>
<MenuItem mnemonicParsing="false" text="截图工具" onAction="#capter_screen_menu_item"/>
<MenuItem mnemonicParsing="false" text="文件编辑器" onAction="#file_edit_menu_item"/>
<MenuItem mnemonicParsing="false" text="LayUI表单代码生成" onAction="#layui_form_gen_menu_item"/>
<MenuItem mnemonicParsing="false" text="日志输出" onAction="#log_console_menu_item"/>
<MenuItem mnemonicParsing="false" text="EditPlus注册码生成" onAction="#edit_plus_code_menu_item"/>
<MenuItem mnemonicParsing="false" text="minio文件上传" onAction="#minio_upload_menu_item"/>
</items>
</Menu>
<Menu mnemonicParsing="false" text="编解码工具">
<items>
<MenuItem mnemonicParsing="false" text="Base62编码解码" onAction="#base_62_menu_item"/>
<MenuItem mnemonicParsing="false" text="Base64编码解码" onAction="#base_64_menu_item"/>
<MenuItem mnemonicParsing="false" text="Base32编码解码" onAction="#base_32_menu_item"/>
<MenuItem mnemonicParsing="false" text="摩尔斯电码" onAction="#morse_coder_menu_item"/>
</items>
</Menu>
<Menu mnemonicParsing="false" text="代码工具">
<items>
<MenuItem mnemonicParsing="false" text="mysql代码生成" onAction="#sql_code_gen_menu_item"/>
<MenuItem mnemonicParsing="false" text="mybatis-plus 代码生成" onAction="#mybatis_plus_gen_menu_item"/>
<MenuItem mnemonicParsing="false" text="json转javaBean 代码生成" onAction="#json_javabean_gen_menu_item"/>
<MenuItem mnemonicParsing="false" text="sql 查询" onAction="#sql_query_gen_menu_item"/>
</items>
</Menu>
<Menu mnemonicParsing="false" text="http工具">
<items>
<MenuItem mnemonicParsing="false" text="http请求工具" onAction="#http_request_menu_item"/>
<MenuItem mnemonicParsing="false" text="http上传工具" onAction="#http_upload_menu_item"/>
<MenuItem mnemonicParsing="false" text="http下载工具" onAction="#http_download_menu_item"/>
</items>
</Menu>
<Menu mnemonicParsing="false" text="server 工具">
<items>
<MenuItem mnemonicParsing="false" text="http-server 请求工具" onAction="#http_server_menu_item"/>
<MenuItem mnemonicParsing="false" text="ftp-server 请求工具" onAction="#ftp_server_menu_item"/>
<MenuItem mnemonicParsing="false" text="ssh-client 请求工具" onAction="#ssh_client_menu_item"/>
<MenuItem mnemonicParsing="false" text="socket-server 服务工具" onAction="#socket_server_menu_item"/>
<MenuItem mnemonicParsing="false" text="socket-client-aio 客户端工具" onAction="#socket_client_aio_menu_item"/>
<MenuItem mnemonicParsing="false" text="socket-server-aio 服务端工具" onAction="#socket_server_aio_menu_item"/>
<MenuItem mnemonicParsing="false" text="socket-server-nio 服务端工具" onAction="#socket_server_nio_menu_item"/>
<MenuItem mnemonicParsing="false" text="socket-client-nio 客户端工具" onAction="#socket_client_nio_menu_item"/>
<MenuItem mnemonicParsing="false" text="web-socket-client 客户端工具" onAction="#web_socket_client_menu_item"/>
</items>
</Menu>
<Menu mnemonicParsing="false" text="go语言工具">
<items>
<MenuItem mnemonicParsing="false" text="json生成结构体" onAction="#json_to_struct_menu_item"/>
</items>
</Menu>
<Menu mnemonicParsing="false" text="编辑器工具">
<items>
<MenuItem mnemonicParsing="false" text="ace.js 编辑器" onAction="#ace_js_menu_item"/>
<MenuItem mnemonicParsing="false" text="monaco.js 编辑器" onAction="#monaco_js_menu_item"/>
<MenuItem mnemonicParsing="false" text="codemirror.js 编辑器" onAction="#codemirror_js_menu_item"/>
<MenuItem mnemonicParsing="false" text="timefx 编辑器" onAction="#timeFx_fx_menu_item"/>
</items>
</Menu>
<Menu mnemonicParsing="false" text="编辑器">
<items>
<MenuItem mnemonicParsing="false" text="ace.js 编辑器" onAction="#ace_menu_item"/>
<MenuItem mnemonicParsing="false" text="monaco.js 编辑器" onAction="#monaco_menu_item"/>
<MenuItem mnemonicParsing="false" text="codemirror.js 编辑器" onAction="#codemirror_menu_item"/>
<MenuItem mnemonicParsing="false" text="timefx 编辑器" onAction="#timeFx_menu_item"/>
</items>
</Menu>
</menus>
</MenuBar>
<SplitPane fx:id="splitPane" dividerPositions="0.5" layoutY="25.0" prefHeight="575.0" prefWidth="1200.0"
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0"
AnchorPane.topAnchor="25.0">
<items>
<ListView fx:id="listView" maxWidth="300.0" minWidth="200.0" prefHeight="200.0" prefWidth="200.0"/>
<AnchorPane prefHeight="200.0" prefWidth="200.0"/>
</items>
</SplitPane>
</children>
</AnchorPane>

View File

@ -108,6 +108,16 @@
<MenuItem mnemonicParsing="false" text="ace.js 编辑器" onAction="#ace_js_menu_item"/>
<MenuItem mnemonicParsing="false" text="monaco.js 编辑器" onAction="#monaco_js_menu_item"/>
<MenuItem mnemonicParsing="false" text="codemirror.js 编辑器" onAction="#codemirror_js_menu_item"/>
<MenuItem mnemonicParsing="false" text="timefx 编辑器" onAction="#timeFx_fx_menu_item"/>
</items>
</Menu>
<Menu mnemonicParsing="false" text="编辑器">
<items>
<MenuItem mnemonicParsing="false" text="ace.js 编辑器" onAction="#ace_menu_item"/>
<MenuItem mnemonicParsing="false" text="monaco.js 编辑器" onAction="#monaco_menu_item"/>
<MenuItem mnemonicParsing="false" text="codemirror.js 编辑器" onAction="#codemirror_menu_item"/>
<MenuItem mnemonicParsing="false" text="timefx 编辑器" onAction="#timeFx_menu_item"/>
</items>
</Menu>