作者 钟来

初始提交

正在显示 31 个修改的文件 包含 3698 行增加0 行删除
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
# Avoid ignoring Maven wrapper jar file (.jar files are usually ignored)
!/.mvn/wrapper/maven-wrapper.jar
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
.DS_Store
!.mvn/wrapper/maven-wrapper.jar
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
### NetBeans ###
nbproject/private/
build/
nbbuild/
dist/
nbdist/
.nb-gradle/
\ No newline at end of file
... ...
The MIT License (MIT)
Copyright (c) 2018 zhazhapan
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
... ...
**JavaFX开发的工具集**
包括JSON解析,文件批量重命名、复制,文件的拆分与合并,剪贴板历史,随机生成器,二维码生成,编码转换
[download wetool-1.1.jar](http://oq3iwfipo.bkt.clouddn.com/tools/zhazhapan/wetool-1.1.jar)
\ No newline at end of file
... ...
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zhazhapan</groupId>
<artifactId>wetool</artifactId>
<version>1.4</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>com.googlecode.addjars-maven-plugin</groupId>
<artifactId>addjars-maven-plugin</artifactId>
<version>1.0.5</version>
<executions>
<execution>
<goals>
<goal>add-jars</goal>
</goals>
<configuration>
<resources>
<resource>
<directory>${basedir}/lib</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.zhazhapan.util.visual.WeToolApplication</mainClass>
</transformer>
</transformers>
<artifactSet>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.3.2</version>
</dependency>
<dependency>
<groupId>com.zhazhapan</groupId>
<artifactId>qiniu</artifactId>
<version>1.0.7</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.9-rc</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
... ...
package com.zhazhapan.util.visual;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.zhazhapan.config.JsonParser;
import com.zhazhapan.modules.constant.ValueConsts;
import com.zhazhapan.util.FileExecutor;
import com.zhazhapan.util.dialog.Alerts;
import com.zhazhapan.util.visual.constant.LocalValueConsts;
import com.zhazhapan.util.visual.model.ConfigModel;
import com.zhazhapan.util.visual.model.WaverModel;
import java.util.List;
/**
* @author pantao
* @since 2018/4/2
*/
class ConfigParser {
private static final String FILE_FILTER_TIP_PATH = "fileFilter.showTip";
private static final String WIDTH_PATH = "initialize.width";
private static final String HEIGHT_PATH = "initialize.height";
private static final String FILE_REGEX_PATH = "fileFilter.regex";
private static final String TAB_PATH = "initialize.tabs.load";
private static final String CLIPBOARD_SIZE_PATH = "clipboardSize";
private static final String FULLSCREEN = "initialize.fullscreen";
private static final String AUTO_WRAP = "autoWrap";
private static final String MYSQL_HOST = "mysql.host";
private static final String MYSQL_DB = "mysql.database";
private static final String MYSQL_CONDITION = "mysql.condition";
private static final String MYSQL_USERNAME = "mysql.username";
private static final String MYSQL_PASSWORD = "mysql.password";
private static final String WAVE = "waveViewer";
private static final String TABLE_NAME = "tableName";
private static final String DATA_FIELD = "dataField";
private static final String DATE_FIELD = "dateField";
private static final String TITLE = "title";
private static final String RESULT_SIZE = "firstResultSize";
/**
* 解析配置文件到 {@link ConfigModel}
*/
static void parserConfig() {
try {
JsonParser parser = new JsonParser(FileExecutor.read(WeToolApplication.class.getResourceAsStream
(LocalValueConsts.CONFIG_PATH)), ValueConsts.TRUE);
ConfigModel.setWidth(parser.getDoubleUseEval(WIDTH_PATH));
ConfigModel.setHeight(parser.getDoubleUseEval(HEIGHT_PATH));
ConfigModel.setTabs(parser.getArray(TAB_PATH));
ConfigModel.setFileFilterRegex(parser.getString(FILE_REGEX_PATH));
ConfigModel.setFileFilterTip(parser.getBooleanUseEval(FILE_FILTER_TIP_PATH));
ConfigModel.setClipboardSize(parser.getIntegerUseEval(CLIPBOARD_SIZE_PATH));
ConfigModel.setFullscreen(parser.getBooleanUseEval(FULLSCREEN));
ConfigModel.setAutoWrap(parser.getBooleanUseEval(AUTO_WRAP));
ConfigModel.setHost(parser.getStringUseEval(MYSQL_HOST));
ConfigModel.setDatabase(parser.getStringUseEval(MYSQL_DB));
ConfigModel.setCondition(parser.getStringUseEval(MYSQL_CONDITION));
ConfigModel.setUsername(parser.getStringUseEval(MYSQL_USERNAME));
ConfigModel.setPassword(parser.getStringUseEval(MYSQL_PASSWORD));
JSONArray array = parser.getJsonObject().getJSONArray(WAVE);
List<WaverModel> waves = ConfigModel.getWaver();
array.forEach(obj -> {
JSONObject object = (JSONObject) obj;
WaverModel model = new WaverModel();
model.setTableName(object.getString(TABLE_NAME));
model.setDataField(object.getString(DATA_FIELD));
model.setDateField(object.getString(DATE_FIELD));
model.setTitle(object.getString(TITLE));
model.setFirstResultSize(object.getInteger(RESULT_SIZE));
waves.add(model);
});
} catch (Exception e) {
Alerts.showError(LocalValueConsts.MAIN_TITLE, LocalValueConsts.LOAD_CONFIG_ERROR);
}
}
}
... ...
package com.zhazhapan.util.visual;
import com.zhazhapan.modules.constant.ValueConsts;
import com.zhazhapan.util.Checker;
import com.zhazhapan.util.ThreadPool;
import com.zhazhapan.util.dialog.Alerts;
import com.zhazhapan.util.visual.constant.LocalValueConsts;
import com.zhazhapan.util.visual.model.ConfigModel;
import com.zhazhapan.util.visual.model.ControllerModel;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.List;
/**
* @author pantao
* @since 2018/3/30
*/
public class WeToolApplication extends Application {
public static Stage stage = null;
private TrayIcon trayIcon;
private boolean isTraySuccess = false;
public static void main(String[] args) {
ThreadPool.init();
launch(args);
}
@Override
public void start(Stage stage) {
VBox root = WeUtils.loadFxml(LocalValueConsts.MAIN_VIEW);
if (Checker.isNull(root)) {
Alerts.showError(ValueConsts.FATAL_ERROR, LocalValueConsts.INIT_ERROR);
WeUtils.exitSystem();
}
assert root != null;
stage.setScene(new Scene(root));
stage.getIcons().add(new Image(getClass().getResourceAsStream(LocalValueConsts.ICON)));
stage.setTitle(LocalValueConsts.MAIN_TITLE);
stage.setOnCloseRequest((WindowEvent event) -> {
if (isTraySuccess) {
stage.hide();
} else {
stage.setIconified(true);
}
event.consume();
});
ConfigParser.parserConfig();
stage.setWidth(ConfigModel.getWidth());
stage.setHeight(ConfigModel.getHeight());
stage.setFullScreen(ConfigModel.isFullscreen());
ControllerModel.getMainController().loadTabs();
WeToolApplication.stage = stage;
if (Checker.isWindows()) {
enableTray();
}
stage.show();
}
/**
* 系统托盘
*/
private void enableTray() {
Platform.setImplicitExit(false);
PopupMenu popupMenu = new PopupMenu();
List<MenuItem> items = new ArrayList<>(8);
items.add(new MenuItem((LocalValueConsts.WOX)));
items.add(new MenuItem(LocalValueConsts.COLOR_PICKER));
items.add(new MenuItem(LocalValueConsts.SHOW));
items.add(new MenuItem(LocalValueConsts.HIDE));
items.add(new MenuItem(LocalValueConsts.EXIT));
ActionListener actionListener = e -> {
MenuItem item = (MenuItem) e.getSource();
switch (item.getLabel()) {
case LocalValueConsts.EXIT:
SystemTray.getSystemTray().remove(trayIcon);
WeUtils.exitSystem();
break;
case LocalValueConsts.SHOW:
Platform.runLater(stage::show);
break;
case LocalValueConsts.HIDE:
Platform.runLater(stage::hide);
break;
case LocalValueConsts.COLOR_PICKER:
WeUtils.startColorPicker();
break;
case LocalValueConsts.WOX:
WeUtils.startWox();
break;
default:
break;
}
};
//双击事件方法
MouseListener mouseListener = new MouseListener() {
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseClicked(MouseEvent e) {
Platform.setImplicitExit(false);
if (e.getClickCount() == ValueConsts.TWO_INT) {
Platform.runLater(() -> {
if (stage.isShowing()) {
stage.hide();
} else {
stage.show();
}
});
}
}
};
items.forEach(item -> {
item.addActionListener(actionListener);
popupMenu.add(item);
});
try {
SystemTray tray = SystemTray.getSystemTray();
java.awt.Image image = ImageIO.read(getClass().getResourceAsStream(LocalValueConsts.ICON));
trayIcon = new TrayIcon(image, LocalValueConsts.MAIN_TITLE, popupMenu);
trayIcon.setImageAutoSize(true);
trayIcon.setToolTip(LocalValueConsts.MAIN_TITLE);
trayIcon.addMouseListener(mouseListener);
tray.add(trayIcon);
isTraySuccess = true;
} catch (Exception e) {
Alerts.showError(LocalValueConsts.MAIN_TITLE, LocalValueConsts.TRAY_ERROR);
}
}
}
... ...
package com.zhazhapan.util.visual;
import com.zhazhapan.modules.constant.ValueConsts;
import com.zhazhapan.util.*;
import com.zhazhapan.util.dialog.Alerts;
import com.zhazhapan.util.visual.constant.LocalValueConsts;
import com.zhazhapan.util.visual.controller.FileManagerController;
import com.zhazhapan.util.visual.controller.WaveController;
import com.zhazhapan.util.visual.model.ConfigModel;
import com.zhazhapan.util.visual.model.ControllerModel;
import javafx.application.Platform;
import javafx.collections.ObservableList;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.ListView;
import javafx.scene.control.TextArea;
import javafx.scene.input.DragEvent;
import javafx.scene.layout.VBox;
import javafx.stage.FileChooser;
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;
import static com.zhazhapan.util.visual.WeToolApplication.stage;
/**
* @author pantao
* @since 2018/3/31
*/
public class WeUtils {
private static final String CURRENT_DIR = Paths.get(ValueConsts.DOT_SIGN).toAbsolutePath().normalize().toString();
private static final String COLOR_PICKER = CURRENT_DIR + File.separator + "ColorPicker.exe";
private static final String WOX = CURRENT_DIR + File.separator + "Wox.exe";
private static final String WOX_URL = "https://github.com/Wox-launcher/Wox/releases/latest";
private static final String WOX_ERROR = LocalValueConsts.CAN_NOT_FOUND + WOX;
private static final String WOX_TIP = "请下载 Wox-x.x.x.exe 文件到 " + CURRENT_DIR + " 目录,并重命名为:Wox.exe";
private static final String COLOR_PICKER_ERROR = LocalValueConsts.CAN_NOT_FOUND + COLOR_PICKER;
private static final String COLOR_PICKER_URL = "http://oq3iwfipo.bkt.clouddn.com/tools/zhazhapan/ColorPicker.exe";
private static Pattern FILE_FILTER = Pattern.compile(ConfigModel.getFileFilterRegex());
public static void startColorPicker() {
if (Checker.isWindows()) {
ThreadPool.executor.submit(() -> {
if (Checker.isNotExists(COLOR_PICKER)) {
Downloader.download(CURRENT_DIR, COLOR_PICKER_URL);
}
if (Checker.isExists(COLOR_PICKER)) {
run(COLOR_PICKER);
} else {
Platform.runLater(() -> Alerts.showError(LocalValueConsts.MAIN_TITLE, COLOR_PICKER_ERROR));
}
});
} else {
Alerts.showWarning(LocalValueConsts.MAIN_TITLE, LocalValueConsts.NOT_SUPPORT);
}
}
public static void startWox() {
if (Checker.isWindows()) {
if (Checker.isNotExists(WOX)) {
openLink(WOX_URL);
Alerts.showInformation(LocalValueConsts.MAIN_TITLE, WOX_TIP);
}
if (Checker.isExists(WOX)) {
run(WOX);
} else {
Alerts.showError(LocalValueConsts.MAIN_TITLE, WOX_ERROR);
}
} else {
Alerts.showWarning(LocalValueConsts.MAIN_TITLE, LocalValueConsts.NOT_SUPPORT);
}
}
public static void run(String executableFile) {
Platform.runLater(() -> {
try {
Runtime.getRuntime().exec(executableFile);
} catch (IOException e) {
Alerts.showError(LocalValueConsts.MAIN_TITLE, e.getMessage());
}
});
}
public static void closeMysqlConnection() {
WaveController controller = ControllerModel.getWaveController();
if (Checker.isNotNull(controller)) {
try {
if (Checker.isNotNull(controller.statement)) {
controller.statement.close();
}
if (Checker.isNotNull(controller.connection)) {
controller.connection.close();
}
} catch (SQLException e) {
Alerts.showError(LocalValueConsts.MAIN_TITLE, e.getMessage());
}
}
}
public static void deleteFiles(File file) {
if (Checker.isNotNull(file)) {
if (file.isDirectory()) {
try {
FileExecutor.deleteDirectory(file);
} catch (IOException e) {
Alerts.showError(LocalValueConsts.MAIN_TITLE, LocalValueConsts.DELETE_FILE_ERROR);
}
} else {
FileExecutor.deleteFile(file);
}
}
}
public static String whois(String domain) {
try {
return NetUtils.whois(domain);
} catch (Exception e) {
Alerts.showError(LocalValueConsts.MAIN_TITLE, LocalValueConsts.NETWORK_ERROR);
return null;
}
}
public static String getLocationByIp(String ip) {
try {
return NetUtils.getLocationByIp(ip);
} catch (Exception e) {
Alerts.showError(LocalValueConsts.MAIN_TITLE, LocalValueConsts.NETWORK_ERROR);
return null;
}
}
public static void putDragFileInTextArea(TextArea textArea, DragEvent event) {
List<File> files = event.getDragboard().getFiles();
if (Checker.isNotEmpty(files)) {
textArea.setText(readFile(files.get(0)));
}
}
public static void mergeFiles(ObservableList<File> fileObservableList, String filter, boolean isDelete) {
if (Checker.isNotEmpty(fileObservableList)) {
File file = getSaveFile();
File[] files = new File[fileObservableList.size()];
files = fileObservableList.toArray(files);
try {
FileExecutor.mergeFiles(files, file, Checker.checkNull(filter));
if (isDelete) {
for (File f : fileObservableList) {
f.delete();
}
fileObservableList.clear();
}
showSuccessInfo();
} catch (IOException e) {
Alerts.showError(LocalValueConsts.MAIN_TITLE, LocalValueConsts.MERGE_FILE_ERROR);
}
}
}
public static void removeSelectedItems(ListView<File> fileListView) {
ObservableList<File> files = fileListView.getSelectionModel().getSelectedItems();
if (Checker.isNotEmpty(files)) {
fileListView.getItems().removeAll(files);
}
}
public static void splitFile(File file, long[] points, String folder, boolean deleteSrc) {
try {
FileExecutor.splitFile(file, points, folder);
if (deleteSrc) {
file.delete();
}
showSuccessInfo();
} catch (IOException e) {
Alerts.showError(LocalValueConsts.MAIN_TITLE, LocalValueConsts.SPLIT_FILE_ERROR);
}
}
public static String getFolder(File file) {
return file.isDirectory() ? file.getAbsolutePath() : file.getParent();
}
public static void copyFiles(ObservableList<File> list, String folder, boolean deleteSrc) {
if (Checker.isNotEmpty(list) && Checker.isNotEmpty(folder)) {
ThreadPool.executor.submit(() -> {
File[] files = new File[list.size()];
list.toArray(files);
try {
FileExecutor.copyFiles(files, folder);
if (deleteSrc) {
int i = 0;
for (File f : list) {
list.set(i++, new File(folder + ValueConsts.SEPARATOR + f.getName()));
f.delete();
}
}
showSuccessInfo();
} catch (IOException e) {
Alerts.showError(LocalValueConsts.MAIN_TITLE, LocalValueConsts.COPY_FILE_ERROR);
}
});
}
}
public static void showSuccessInfo() {
Alerts.showInformation(LocalValueConsts.MAIN_TITLE, LocalValueConsts.OPERATION_SUCCESS);
}
public static String replaceVariable(String s) {
return Checker.checkNull(s).replaceAll(LocalValueConsts.DATE_VARIABLE, Formatter.dateToString(new Date()))
.replaceAll(LocalValueConsts.TIME_VARIABLE, Formatter.datetimeToCustomString(new Date(),
LocalValueConsts.TIME_FORMAT));
}
public static int stringToInt(String integer) {
int result = Formatter.stringToInt(integer);
return result > -1 ? result : 0;
}
public static double stringToDouble(String digit) {
double result = Formatter.stringToDouble(digit);
return result < 0 ? 0 : result;
}
@SuppressWarnings("unchecked")
public static void putFilesInListViewOfFileManagerTab(Object files) {
FileManagerController fileManagerController = ControllerModel.getFileManagerController();
if (Checker.isNotNull(fileManagerController)) {
int idx = fileManagerController.fileManagerTab.getSelectionModel().getSelectedIndex();
switch (idx) {
case 0:
putFilesInListView(files, fileManagerController.selectedFilesOfRenameTab);
break;
case 1:
putFilesInListView(files, fileManagerController.selectedFilesOfCopyTab);
case 2:
File file = null;
if (files instanceof File) {
file = (File) files;
} else if (files instanceof List) {
List<File> list = (List<File>) files;
if (Checker.isNotEmpty(list)) {
file = list.get(0);
}
}
if (Checker.isNotNull(file)) {
fileManagerController.splittingFile = file;
fileManagerController.fileContent.setText(readFile(file));
}
break;
case 3:
putFilesInListView(files, fileManagerController.selectedFilesOfMergeTab);
break;
case 4:
if (files instanceof File) {
fileManagerController.srcFolderOfDeleteTab.setText(getFolder((File) files));
}
break;
default:
break;
}
}
}
@SuppressWarnings("unchecked")
private static void putFilesInListView(Object files, ListView listView) {
ObservableList items = listView.getItems();
if (files instanceof List) {
putFilesInListView((List<File>) files, items);
} else if (files instanceof File) {
putFilesInListView((File) files, items);
}
}
public static void putFilesInListView(List<File> files, ObservableList items) {
if (Checker.isNotEmpty(files)) {
files.forEach(file -> putFilesInListView(file, items));
}
}
@SuppressWarnings("unchecked")
private static void putFilesInListView(File file, ObservableList items) {
if (Checker.isNotNull(file)) {
if (FILE_FILTER.matcher(file.getName()).matches()) {
if (file.isDirectory()) {
putFilesInListView((List<File>) FileExecutor.listFiles(file, null, ValueConsts.TRUE), items);
} else if (!items.contains(file)) {
items.add(file);
}
} else if (ConfigModel.isFileFilterTip()) {
Alerts.showInformation(LocalValueConsts.MAIN_TITLE, LocalValueConsts.FILE_NOT_MATCH, file
.getAbsolutePath());
}
}
}
public static void saveFile(File file, String fileContent) {
if (Checker.isNotEmpty(fileContent)) {
try {
FileExecutor.saveFile(file, fileContent);
} catch (IOException e) {
Alerts.showError(LocalValueConsts.MAIN_TITLE, LocalValueConsts.SAVE_FILE_ERROR);
}
}
}
public static String readFile(File file) {
String result;
try {
result = FileExecutor.readFile(file);
} catch (IOException e) {
result = "";
Alerts.showError(LocalValueConsts.MAIN_TITLE, LocalValueConsts.READ_FILE_ERROR);
}
return result;
}
public static File getSaveFile() {
return getFileChooser().showSaveDialog(stage);
}
public static List<File> getChooseFiles() {
return getFileChooser().showOpenMultipleDialog(stage);
}
public static File getChooseFile() {
return getFileChooser().showOpenDialog(stage);
}
private static FileChooser getFileChooser() {
FileChooser chooser = new FileChooser();
chooser.setTitle(LocalValueConsts.MAIN_TITLE);
chooser.setInitialDirectory(new File(System.getProperty("user.home")));
return chooser;
}
public static void openLink(String url) {
try {
Utils.openLink(url);
} catch (Exception e) {
Alerts.showError(LocalValueConsts.MAIN_TITLE, LocalValueConsts.OPEN_LINK_ERROR);
}
}
public static void exitSystem() {
closeMysqlConnection();
System.exit(ValueConsts.ZERO_INT);
}
public static VBox loadFxml(String url) {
try {
return FXMLLoader.load(WeUtils.class.getResource(url));
} catch (Exception e) {
Alerts.showException(ValueConsts.FATAL_ERROR, e);
return null;
}
}
}
... ...
package com.zhazhapan.util.visual.constant;
import com.zhazhapan.util.Utils;
/**
* @author pantao
* @since 2018/3/30
*/
public class LocalValueConsts {
public static final String CAN_NOT_FOUND = "找不到可执行文件:";
public static final String NOT_SUPPORT = "抱歉,暂时不支持 " + Utils.getCurrentOS().toUpperCase() + " 平台";
public static final String DELETE_FILE_ERROR = "删除文件失败";
public static final String WAVE_VIEW = "/view/WaveView.fxml";
public static final String WAVE_VIEWER = "波动图表";
public static final String QINIU_TOOL_VIEW = "/view/MainWindow.fxml";
public static final String QINIU_TOOL = "七牛云对象存储";
public static final String NETWORK_ERROR = "网络异常";
public static final String NETWORK_TOOL_VIEW = "/view/NetworkToolView.fxml";
public static final String NETWORK_TOOL = "网络工具";
public static final String CHARSET_CONVERTER_VIEW = "/view/CharsetConverterView.fxml";
public static final String CHARSET_CONVERTER = "编码转换器";
public static final String QR_CODE_ERROR = "生成二维码失败";
public static final String QR_CODE_GENERATOR_VIEW = "/view/QrCodeGeneratorView.fxml";
public static final String QR_CODE_GENERATOR = "二维码生成器";
public static final String TRAY_ERROR = "设置系统托盘失败";
public static final String WOX = "wox";
public static final String COLOR_PICKER = "color picker";
public static final String HIDE = "hide";
public static final String SHOW = "show";
public static final String EXIT = "exit";
public static final int ONE_THOUSAND = 1000;
public static final String CLIPBOARD_HISTORY_VIEW = "/view/ClipboardHistoryView.fxml";
public static final String CLIPBOARD_HISTORY = "剪贴板历史";
public static final String RANDOM_GENERATOR_VIEW = "/view/RandomGeneratorView.fxml";
public static final String RANDOM_GENERATOR = "随机生成器";
public static final String FILE_NOT_MATCH = "文件不匹配";
public static final String CONFIG_PATH = "/config.json";
public static final String LOAD_CONFIG_ERROR = "加载配置文件失败";
public static final String ABOUT_DETAIL = "当前版本:v1.4\r\n\r\n项目地址:https://github" +
".com/zhazhapan/wetool\r\n\r\n外部依赖:\r\n\thttps://gitee.com/zhazhapan_admin/qiniu" +
"\r\n\r\n外部工具:\r\n\thttps://gitee.com/zhazhapan_admin/ColorPicker\r\n\thttps://github" +
".com/Wox-launcher/Wox\r\n\r\n取色器说明:\r\n\t退出:Ctrl + Alt + Q\r\n\t复制:Ctrl + Alt + C";
public static final String ABOUT_APP = "关于应用";
public static final String MERGE_FILE_ERROR = "合并文件失败";
public static final String OPERATION_SUCCESS = "操作成功";
public static final String SPLIT_FILE_ERROR = "拆分文件失败";
public static final String COPY_FILE_ERROR = "复制文件失败";
public static final String AFTER_FILENAME = "文件名称之后";
public static final String BEFORE_FILENAME = "文件名称之前";
public static final String TIME_FORMAT = "HH.mm.ss";
public static final String TIME_VARIABLE = "%(TIME|time)%";
public static final String DATE_VARIABLE = "%(DATE|date)%";
public static final String FILE_MANAGER_VIEW = "/view/FileManagerView.fxml";
public static final String FILE_MANAGER = "文件批处理";
public static final String PARSE_JSON_ERROR = "解析JSON失败";
public static final String SAVE_FILE_ERROR = "保存文件失败";
public static final String READ_FILE_ERROR = "读取文件失败";
public static final String OPEN_LINK_ERROR = "打开链接失败";
public static final String JSON_PATH_GRAMMAR_URL = "https://github.com/alibaba/fastjson/wiki/JSONPath";
public static final String ICON = "/images/wetool.png";
public static final String FXML_LOAD_ERROR = "加载视图失败";
public static final String INIT_ERROR = "初始化失败,无法继续运行";
public static final String JSON_PARSER_VIEW = "/view/JsonParserView.fxml";
public static final String MAIN_VIEW = "/view/WeToolMainView.fxml";
public static final String JSON_PARSER = "JSON解析器";
public static final String MAIN_TITLE = "Visual Commons Tool";
}
... ...
package com.zhazhapan.util.visual.controller;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.CharsetUtil;
import com.zhazhapan.util.Checker;
import com.zhazhapan.util.visual.WeUtils;
import com.zhazhapan.util.visual.model.ConfigModel;
import com.zhazhapan.util.visual.model.ControllerModel;
import javafx.fxml.FXML;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TextArea;
import javafx.scene.input.DragEvent;
import javafx.scene.input.TransferMode;
/**
* @author pantao
* @since 2018/4/4
*/
public class CharsetConverterController {
private final String BASE64 = "BASE64";
@FXML
public TextArea originalContent;
@FXML
public ComboBox<String> originalCharset;
@FXML
public ComboBox<String> convertCharset;
@FXML
public TextArea convertedContent;
@FXML
private void initialize() {
String[] charset = {"UTF-8", "ISO-8859-1", "GBK", BASE64};
originalCharset.getItems().addAll(charset);
originalCharset.getSelectionModel().selectFirst();
convertCharset.getItems().addAll(charset);
convertCharset.getSelectionModel().selectFirst();
originalCharset.getSelectionModel().selectedItemProperty().addListener((o, ov, nv) -> convert());
convertCharset.getSelectionModel().selectedItemProperty().addListener((o, ov, nv) -> convert());
originalContent.textProperty().addListener((o, ov, nv) -> convert());
originalContent.setWrapText(ConfigModel.isAutoWrap());
convertedContent.setWrapText(ConfigModel.isAutoWrap());
ControllerModel.setCharsetConverterController(this);
}
private void convert() {
String originalText = originalContent.getText();
if (Checker.isNotEmpty(originalText)) {
String srcCharset = originalCharset.getSelectionModel().getSelectedItem();
String destCharset = convertCharset.getSelectionModel().getSelectedItem();
String result;
boolean baseDecode = BASE64.equals(srcCharset);
boolean baseEncode = BASE64.equals(destCharset);
if (baseDecode && baseEncode) {
result = originalText;
} else if (baseDecode) {
result = Base64.decodeStr(originalText);
} else if (baseEncode) {
result = Base64.encode(originalText);
} else {
result = CharsetUtil.convert(originalText, srcCharset, destCharset);
}
convertedContent.setText(result);
}
}
public void dragFileDropped(DragEvent event) {
WeUtils.putDragFileInTextArea(originalContent, event);
}
public void dragFileOver(DragEvent event) {
event.acceptTransferModes(TransferMode.COPY);
}
}
... ...
package com.zhazhapan.util.visual.controller;
import cn.hutool.core.date.DateUtil;
import com.zhazhapan.util.Checker;
import com.zhazhapan.util.visual.model.ConfigModel;
import com.zhazhapan.util.visual.model.ControllerModel;
import javafx.fxml.FXML;
import javafx.scene.control.TextArea;
import javafx.util.Pair;
import java.util.Date;
/**
* @author pantao
* @since 2018/4/3
*/
public class ClipboardHistoryController {
@FXML
public TextArea clipboardHistory;
@FXML
private void initialize() {
clipboardHistory.setWrapText(ConfigModel.isAutoWrap());
ControllerModel.setClipboardHistoryController(this);
for (int i = ConfigModel.getClipboardHistorySize() - 1; i >= 0; i--) {
Pair<Date, String> pair = ConfigModel.getClipboardHistoryItem(i);
if (Checker.isNotNull(pair)) {
insert(pair.getKey(), pair.getValue());
}
}
}
public void insert(Date date, String content) {
if (Checker.isNotEmpty(content)) {
String contentVariable = "%content%";
String dateVariable = "%datetime%";
String template = "---------------------------------------\r\n" + dateVariable + "\r\n" +
"---------------------------------------\r\n\r\n" + contentVariable + "\r\n\r\n";
content = template.replace(dateVariable, DateUtil.formatDateTime(date)).replace(contentVariable, content);
clipboardHistory.setText(content + clipboardHistory.getText());
}
}
}
... ...
package com.zhazhapan.util.visual.controller;
import com.zhazhapan.modules.constant.ValueConsts;
import com.zhazhapan.util.ArrayUtils;
import com.zhazhapan.util.Checker;
import com.zhazhapan.util.FileExecutor;
import com.zhazhapan.util.Formatter;
import com.zhazhapan.util.dialog.Alerts;
import com.zhazhapan.util.visual.WeUtils;
import com.zhazhapan.util.visual.constant.LocalValueConsts;
import com.zhazhapan.util.visual.model.ConfigModel;
import com.zhazhapan.util.visual.model.ControllerModel;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.control.cell.TextFieldListCell;
import javafx.scene.input.DragEvent;
import javafx.scene.input.TransferMode;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
/**
* @author pantao
* @since 2018/3/31
*/
public class FileManagerController {
@FXML
public ListView<File> selectedFilesOfRenameTab;
@FXML
public TextField filePrefixOfRenameTab;
@FXML
public TextField filePostfixOfRenameTab;
@FXML
public TextField startNumberOfRenameTab;
@FXML
public ListView<String> destFilesOfRenameTab;
@FXML
public TextField fileQueryStringOfRenameTab;
@FXML
public TextField fileReplaceStringOfRenameTab;
@FXML
public TextField fileAddableText;
@FXML
public ComboBox<String> fileAddableCombo;
@FXML
public TextField destFolderOfCopyTab;
@FXML
public ListView<File> selectedFilesOfCopyTab;
@FXML
public CheckBox isDeleteSrcOfCopyTab;
@FXML
public TabPane fileManagerTab;
@FXML
public CheckBox isDeleteSrcOfSplitTab;
@FXML
public TextField splitPoint;
@FXML
public TextArea fileContent;
@FXML
public TextField destFolderOfSplitTab;
@FXML
public File splittingFile;
@FXML
public ListView<File> selectedFilesOfMergeTab;
@FXML
public TextField contentFilter;
@FXML
public CheckBox deleteSrcOfMergeTab;
@FXML
public TextField srcFolderOfDeleteTab;
@FXML
public TextArea filenameOfDeleteTab;
@FXML
private void initialize() {
//设置多选
selectedFilesOfRenameTab.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
selectedFilesOfCopyTab.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
selectedFilesOfMergeTab.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
//设置可编辑
destFilesOfRenameTab.setCellFactory(TextFieldListCell.forListView());
destFilesOfRenameTab.setEditable(true);
fileAddableCombo.getItems().addAll(LocalValueConsts.BEFORE_FILENAME, LocalValueConsts.AFTER_FILENAME);
fileAddableCombo.getSelectionModel().selectLast();
fileAddableCombo.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) ->
generateRenameDestFilesOfAddable());
fileContent.setWrapText(ConfigModel.isAutoWrap());
ControllerModel.setFileManagerController(this);
}
@SuppressWarnings("unchecked")
public void dragFileDropped(DragEvent event) {
Object target = event.getGestureTarget();
if (target instanceof ListView) {
WeUtils.putFilesInListView(event.getDragboard().getFiles(), ((ListView<File>) target).getItems());
}
}
public void dragFileOver(DragEvent event) {
event.acceptTransferModes(TransferMode.COPY);
}
public void generateRenameDestFilesOfFormat() {
ObservableList<File> list = selectedFilesOfRenameTab.getItems();
if (Checker.isNotEmpty(list)) {
String startNumber = Checker.checkNull(startNumberOfRenameTab.getText());
int len = startNumber.length();
startNumber = startNumber.replaceAll(ValueConsts.SHARP, ValueConsts.EMPTY_STRING);
int i = WeUtils.stringToInt(startNumber);
int numLen = len - startNumber.length() + String.valueOf(i).length();
ObservableList<String> destFiles = destFilesOfRenameTab.getItems();
destFiles.clear();
for (File file : list) {
String postfix = WeUtils.replaceVariable(filePostfixOfRenameTab.getText());
if (Checker.isEmpty(postfix) || ValueConsts.DOT_SIGN.equals(postfix)) {
postfix = FileExecutor.getFileSuffix(file);
}
String prefix = WeUtils.replaceVariable(filePrefixOfRenameTab.getText());
String fileName = prefix + Formatter.numberFormat(i++, numLen) + (postfix.startsWith(ValueConsts
.DOT_SIGN) ? postfix : ValueConsts.DOT_SIGN + postfix);
destFiles.add(file.getParent() + ValueConsts.SEPARATOR + fileName);
}
}
}
public void renameFiles() {
ObservableList<File> srcFiles = selectedFilesOfRenameTab.getItems();
ObservableList<String> destFiles = destFilesOfRenameTab.getItems();
int len = srcFiles.size();
if (Checker.isNotEmpty(srcFiles) && len == destFiles.size()) {
for (int i = 0; i < len; i++) {
File srcFile = srcFiles.get(0);
File destFile = new File(destFiles.get(i));
FileExecutor.renameTo(srcFile, destFile);
srcFiles.remove(srcFile);
srcFiles.add(destFile);
}
WeUtils.showSuccessInfo();
}
}
public void removeFilesFromRenameTab() {
ObservableList<File> files = selectedFilesOfRenameTab.getSelectionModel().getSelectedItems();
if (Checker.isNotEmpty(files)) {
ObservableList<File> fileList = selectedFilesOfRenameTab.getItems();
ObservableList<String> destFiles = destFilesOfRenameTab.getItems();
if (Checker.isNotEmpty(destFiles)) {
int i = 0;
for (File file : files) {
destFiles.remove(fileList.indexOf(file) - (i++));
}
}
fileList.removeAll(files);
}
}
public void generateRenameDestFilesOfReplace() {
ObservableList<File> list = selectedFilesOfRenameTab.getItems();
if (Checker.isNotEmpty(list)) {
ObservableList<String> destFiles = destFilesOfRenameTab.getItems();
destFiles.clear();
final String dateVariable = "%date%";
final String timeVariable = "%time%";
for (File file : list) {
String fn = file.getName();
String queryStr = Checker.checkNull(fileQueryStringOfRenameTab.getText());
if (queryStr.toLowerCase().contains(dateVariable)) {
fn = fn.replaceAll("\\d{4}-\\d{2}-\\d{2}", dateVariable);
}
if (queryStr.toLowerCase().contains(timeVariable)) {
fn = fn.replaceAll("\\d{2}\\.\\d{2}\\.\\d{2}", timeVariable);
}
fn = fn.replaceAll(queryStr, Checker.checkNull(fileReplaceStringOfRenameTab.getText()));
destFiles.add(file.getParent() + ValueConsts.SEPARATOR + WeUtils.replaceVariable(fn));
}
}
}
public void generateRenameDestFilesOfAddable() {
ObservableList<File> list = selectedFilesOfRenameTab.getItems();
if (Checker.isNotEmpty(list)) {
ObservableList<String> destFiles = destFilesOfRenameTab.getItems();
destFiles.clear();
for (File file : list) {
String text = WeUtils.replaceVariable(fileAddableText.getText());
String fn = file.getName();
int idx = fn.lastIndexOf(ValueConsts.DOT_SIGN);
fn = LocalValueConsts.BEFORE_FILENAME.equals(fileAddableCombo.getSelectionModel().getSelectedItem())
? text + fn : fn.substring(0, idx) + text + fn.substring(idx);
destFiles.add(file.getParent() + ValueConsts.SEPARATOR + fn);
}
}
}
public void copyFiles() {
WeUtils.copyFiles(selectedFilesOfCopyTab.getItems(), destFolderOfCopyTab.getText(), isDeleteSrcOfCopyTab
.isSelected());
}
public void browseSrcFolder() {
File file = WeUtils.getChooseFile();
if (Checker.isNotNull(file)) {
int idx = fileManagerTab.getSelectionModel().getSelectedIndex();
switch (idx) {
case 1:
destFolderOfCopyTab.setText(file.getParent());
break;
case 2:
destFolderOfSplitTab.setText(file.getParent());
default:
break;
}
}
}
public void dragFileDroppedOfCopyTab(DragEvent event) {
List<File> files = event.getDragboard().getFiles();
if (Checker.isNotEmpty(files)) {
Object target = event.getGestureTarget();
if (target instanceof ListView) {
WeUtils.putFilesInListView(event.getDragboard().getFiles(), selectedFilesOfCopyTab.getItems());
} else if (target instanceof TextField) {
destFolderOfCopyTab.setText(WeUtils.getFolder(files.get(0)));
}
}
}
public void splitFile() {
String pointStr = splitPoint.getText();
String folder = destFolderOfSplitTab.getText();
if (Checker.isNotNull(splittingFile) && Checker.isNotEmpty(pointStr) && Checker.isNotEmpty(folder)) {
String[] points = pointStr.split(ValueConsts.COMMA_SIGN);
int len = points.length;
long[] ps = new long[points.length];
for (int i = 0; i < len; i++) {
ps[i] = Formatter.stringToLong(points[i]);
}
Arrays.sort(ps);
ps = ArrayUtils.unique(ps, ValueConsts.ONE_INT, Long.MAX_VALUE);
WeUtils.splitFile(splittingFile, ps, folder, isDeleteSrcOfSplitTab.isSelected());
}
}
public void dragFileDroppedOfSplitTab(DragEvent event) {
List<File> files = event.getDragboard().getFiles();
if (Checker.isNotEmpty(files)) {
Object target = event.getGestureTarget();
File file = files.get(0);
if (target instanceof TextArea) {
splittingFile = file;
fileContent.setText(WeUtils.readFile(file));
} else if (target instanceof TextField) {
destFolderOfSplitTab.setText(WeUtils.getFolder(file));
}
}
}
public void generateSplitPoint() {
int caret = fileContent.getCaretPosition();
String points = Checker.checkNull(splitPoint.getText()).trim();
if (!points.contains(String.valueOf(caret))) {
splitPoint.setText(points + (Checker.isEmpty(points) || points.endsWith(",") ? caret : "," + caret));
}
}
public void scrollTo() {
String points = splitPoint.getText();
if (Checker.isNotEmpty(points) && Checker.isNotEmpty(fileContent.getText())) {
int position = splitPoint.getCaretPosition();
String before = points.substring(0, position);
String after = points.substring(position);
String point = "";
if (Checker.isNotEmpty(before)) {
String[] temp = before.split(ValueConsts.COMMA_SIGN);
point = temp[temp.length - 1].trim();
}
if (Checker.isNotEmpty(after)) {
point += after.split(ValueConsts.COMMA_SIGN)[0].trim();
}
int caret = Formatter.stringToInt(point);
fileContent.setScrollTop(caret > -1 ? caret : 0);
}
}
public void mergeFiles() {
WeUtils.mergeFiles(selectedFilesOfMergeTab.getItems(), contentFilter.getText(), deleteSrcOfMergeTab
.isSelected());
}
public void removeFilesOfCopyTab() {
WeUtils.removeSelectedItems(selectedFilesOfCopyTab);
}
public void goForward() {
ObservableList<File> files = selectedFilesOfMergeTab.getSelectionModel().getSelectedItems();
if (Checker.isNotEmpty(files)) {
ObservableList<File> list = selectedFilesOfMergeTab.getItems();
int len = files.size();
if (len < list.size()) {
for (int i = 0; i < len; i++) {
int idx = list.indexOf(files.get(i));
if (idx > i) {
File temp = list.get(idx - 1);
list.set(idx - 1, files.get(i));
list.set(idx, temp);
}
}
}
}
}
public void goBack() {
ObservableList<File> files = selectedFilesOfMergeTab.getSelectionModel().getSelectedItems();
if (Checker.isNotEmpty(files)) {
ObservableList<File> list = selectedFilesOfMergeTab.getItems();
int size = list.size();
int len = files.size();
if (files.size() < size) {
for (int i = len - 1, j = 0; i >= 0; i--) {
int idx = list.indexOf(files.get(i));
if (idx < (size - (++j))) {
File temp = list.get(idx + 1);
list.set(idx + 1, files.get(i));
list.set(idx, temp);
}
}
}
}
}
public void removeFilesOfMergeTab() {
WeUtils.removeSelectedItems(selectedFilesOfMergeTab);
}
public void deleteFiles() {
String filenames = filenameOfDeleteTab.getText();
if (Checker.isNotEmpty(filenames)) {
deleteFiles(new File(srcFolderOfDeleteTab.getText()), filenames.split(ValueConsts.COMMA_SIGN));
Alerts.showInformation(LocalValueConsts.MAIN_TITLE, LocalValueConsts.OPERATION_SUCCESS);
}
}
private void deleteFiles(File folder, String[] filenames) {
if (folder.exists() && folder.isDirectory()) {
File[] files = folder.listFiles();
if (Checker.isNotNull(files) && files.length > 0) {
for (File file : files) {
String filename = file.getName();
for (String fn : filenames) {
String nf = fn.trim();
if (Checker.isNotEmpty(nf) && filename.endsWith(fn)) {
WeUtils.deleteFiles(file);
break;
}
}
if (file.isDirectory()) {
deleteFiles(file, filenames);
}
}
}
}
}
public void dragFileDroppedOfDeleteTab(DragEvent event) {
List<File> files = event.getDragboard().getFiles();
if (Checker.isNotEmpty(files)) {
srcFolderOfDeleteTab.setText(WeUtils.getFolder(files.get(0)));
}
}
public void dragFilesDroppedOfDeleteTab(DragEvent event) {
List<File> files = event.getDragboard().getFiles();
if (Checker.isNotEmpty(files)) {
for (File file : files) {
String fns = Checker.checkNull(filenameOfDeleteTab.getText()).trim();
boolean endsWith = Checker.isEmpty(fns) || fns.endsWith(ValueConsts.COMMA_SIGN);
filenameOfDeleteTab.appendText((endsWith ? "" : ", ") + file.getName());
}
}
}
}
... ...
package com.zhazhapan.util.visual.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONPath;
import com.zhazhapan.util.Checker;
import com.zhazhapan.util.Formatter;
import com.zhazhapan.util.ThreadPool;
import com.zhazhapan.util.dialog.Alerts;
import com.zhazhapan.util.visual.WeUtils;
import com.zhazhapan.util.visual.constant.LocalValueConsts;
import com.zhazhapan.util.visual.model.ConfigModel;
import com.zhazhapan.util.visual.model.ControllerModel;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.input.DragEvent;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.TransferMode;
/**
* @author pantao
* @since 2018/3/31
*/
public class JsonParserController {
@FXML
public TextArea jsonContent;
@FXML
public TextArea parsedJsonContent;
@FXML
public TextField jsonPath;
@FXML
private void initialize() {
jsonContent.setWrapText(ConfigModel.isAutoWrap());
parsedJsonContent.setWrapText(ConfigModel.isAutoWrap());
ControllerModel.setJsonParserController(this);
}
public void parseJson() {
String json = jsonContent.getText();
String path = jsonPath.getText();
ThreadPool.executor.submit(() -> {
try {
JSONArray jsonArray = JSON.parseArray("[" + json + "]");
Object object = JSONPath.eval(jsonArray, "[0]");
String parsedJson;
if (Checker.isEmpty(path)) {
parsedJson = object.toString();
} else {
parsedJson = JSONPath.eval(object, (object instanceof JSONArray ? "" : ".") + path).toString();
}
Platform.runLater(() -> parsedJsonContent.setText(Formatter.formatJson(Checker.checkNull(parsedJson))));
} catch (Exception e) {
Platform.runLater(() -> Alerts.showError(LocalValueConsts.MAIN_TITLE, LocalValueConsts
.PARSE_JSON_ERROR));
}
});
}
public void seeJsonPathGrammar() {
WeUtils.openLink(LocalValueConsts.JSON_PATH_GRAMMAR_URL);
}
public void dragFileOver(DragEvent event) {
event.acceptTransferModes(TransferMode.COPY);
}
public void dragFileDropped(DragEvent event) {
WeUtils.putDragFileInTextArea(jsonContent, event);
}
public void jsonPathEnter(KeyEvent keyEvent) {
if (keyEvent.getCode() == KeyCode.ENTER) {
parseJson();
}
}
}
... ...
package com.zhazhapan.util.visual.controller;
import cn.hutool.core.util.ClipboardUtil;
import com.zhazhapan.modules.constant.ValueConsts;
import com.zhazhapan.qiniu.QiniuApplication;
import com.zhazhapan.qiniu.view.MainWindow;
import com.zhazhapan.util.Checker;
import com.zhazhapan.util.ReflectUtils;
import com.zhazhapan.util.dialog.Alerts;
import com.zhazhapan.util.visual.WeToolApplication;
import com.zhazhapan.util.visual.WeUtils;
import com.zhazhapan.util.visual.constant.LocalValueConsts;
import com.zhazhapan.util.visual.model.ConfigModel;
import com.zhazhapan.util.visual.model.ControllerModel;
import javafx.application.Platform;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.layout.VBox;
import org.apache.log4j.Logger;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.util.Date;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
/**
* @author pantao
* @since 2018/3/30
*/
public class MainController {
private static Logger logger = Logger.getLogger(MainController.class);
@FXML
public TabPane tabPane;
@FXML
public ProgressBar jvm;
@FXML
private void initialize() {
// 监听剪贴板
ConfigModel.appendClipboardHistory(new Date(), ClipboardUtil.getStr());
Timer timer = new Timer();
TimerTask task = new TimerTask() {
@Override
public void run() {
String clipboard;
String last;
try {
// 忽略系统休眠时抛出的异常
clipboard = ClipboardUtil.getStr();
last = ConfigModel.getLastClipboardHistoryItem().getValue();
} catch (Exception e) {
logger.warn(e.getMessage());
clipboard = last = ValueConsts.EMPTY_STRING;
}
if (Checker.isNotEmpty(clipboard) && !last.equals(clipboard)) {
Date date = new Date();
ConfigModel.appendClipboardHistory(date, clipboard);
ClipboardHistoryController controller = ControllerModel.getClipboardHistoryController();
if (Checker.isNotNull(controller)) {
final String clip = clipboard;
Platform.runLater(() -> controller.insert(date, clip));
}
}
boolean isVisible = WeToolApplication.stage.isShowing() && !WeToolApplication.stage.isMaximized() &&
!WeToolApplication.stage.isIconified();
// 监听JVM内存变化
if (isVisible) {
System.gc();
Platform.runLater(() -> {
double total = Runtime.getRuntime().totalMemory();
double used = total - Runtime.getRuntime().freeMemory();
jvm.setProgress(used / total);
});
}
}
};
timer.scheduleAtFixedRate(task, LocalValueConsts.ONE_THOUSAND, LocalValueConsts.ONE_THOUSAND);
ControllerModel.setMainController(this);
}
public void loadTabs() {
for (Object tabName : ConfigModel.getTabs()) {
try {
ReflectUtils.invokeMethod(this, "open" + tabName + "Tab", null);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
Alerts.showError(LocalValueConsts.MAIN_TITLE, LocalValueConsts.FXML_LOAD_ERROR);
}
}
}
public void quit() {
WeUtils.exitSystem();
}
public void openNetworkToolTab() {
addTab(new Tab(LocalValueConsts.NETWORK_TOOL), LocalValueConsts.NETWORK_TOOL_VIEW);
}
public void openCharsetConverterTab() {
addTab(new Tab(LocalValueConsts.CHARSET_CONVERTER), LocalValueConsts.CHARSET_CONVERTER_VIEW);
}
public void openClipboardHistoryTab() {
addTab(new Tab(LocalValueConsts.CLIPBOARD_HISTORY), LocalValueConsts.CLIPBOARD_HISTORY_VIEW);
}
public void openRandomGeneratorTab() {
addTab(new Tab(LocalValueConsts.RANDOM_GENERATOR), LocalValueConsts.RANDOM_GENERATOR_VIEW);
}
public void openQrCodeGeneratorTab() {
addTab(new Tab(LocalValueConsts.QR_CODE_GENERATOR), LocalValueConsts.QR_CODE_GENERATOR_VIEW);
}
public void openJsonParserTab() {
addTab(new Tab(LocalValueConsts.JSON_PARSER), LocalValueConsts.JSON_PARSER_VIEW);
}
private void addTab(Tab tab, String url) {
ObservableList<Tab> tabs = tabPane.getTabs();
for (Tab t : tabs) {
if (t.getText().equals(tab.getText())) {
tabPane.getSelectionModel().select(t);
return;
}
}
VBox box = WeUtils.loadFxml(url);
if (Checker.isNull(box)) {
Alerts.showError(ValueConsts.ERROR, LocalValueConsts.FXML_LOAD_ERROR);
} else {
tab.setContent(box);
tab.setClosable(true);
tabs.add(tab);
tabPane.getSelectionModel().select(tab);
}
}
public void openFile() {
File file = WeUtils.getChooseFile();
if (Checker.isNotNull(file)) {
Tab tab = tabPane.getSelectionModel().getSelectedItem();
if (Checker.isNotNull(tab)) {
String tabText = Checker.checkNull(tab.getText());
String fileContent = WeUtils.readFile(file);
switch (tabText) {
case LocalValueConsts.JSON_PARSER:
JsonParserController controller = ControllerModel.getJsonParserController();
if (Checker.isNotNull(controller)) {
controller.jsonContent.setText(fileContent);
}
break;
case LocalValueConsts.FILE_MANAGER:
WeUtils.putFilesInListViewOfFileManagerTab(file);
break;
case LocalValueConsts.QR_CODE_GENERATOR:
QrCodeGeneratorController qrCodeGeneratorController = ControllerModel
.getQrCodeGeneratorController();
if (Checker.isNotNull(qrCodeGeneratorController)) {
qrCodeGeneratorController.content.setText(fileContent);
}
case LocalValueConsts.CHARSET_CONVERTER:
CharsetConverterController charsetConverterController = ControllerModel
.getCharsetConverterController();
if (Checker.isNotNull(charsetConverterController)) {
charsetConverterController.originalContent.setText(fileContent);
}
break;
default:
break;
}
}
}
}
public void saveFile() {
File file = WeUtils.getSaveFile();
if (Checker.isNotNull(file)) {
Tab tab = tabPane.getSelectionModel().getSelectedItem();
if (Checker.isNotNull(tab)) {
String tabText = Checker.checkNull(tab.getText());
String fileContent = null;
switch (tabText) {
case LocalValueConsts.JSON_PARSER:
JsonParserController jsonParserController = ControllerModel.getJsonParserController();
if (Checker.isNotNull(jsonParserController)) {
fileContent = jsonParserController.parsedJsonContent.getText();
}
break;
case LocalValueConsts.FILE_MANAGER:
FileManagerController fileManagerController = ControllerModel.getFileManagerController();
if (Checker.isNotNull(fileManagerController)) {
int idx = fileManagerController.fileManagerTab.getSelectionModel().getSelectedIndex();
if (idx == ValueConsts.TWO_INT) {
fileContent = fileManagerController.fileContent.getText();
}
}
break;
case LocalValueConsts.CLIPBOARD_HISTORY:
ClipboardHistoryController clipboardHistoryController = ControllerModel
.getClipboardHistoryController();
if (Checker.isNotNull(clipboardHistoryController)) {
fileContent = clipboardHistoryController.clipboardHistory.getText();
}
break;
case LocalValueConsts.CHARSET_CONVERTER:
CharsetConverterController charsetConverterController = ControllerModel
.getCharsetConverterController();
if (Checker.isNotNull(charsetConverterController)) {
fileContent = charsetConverterController.convertedContent.getText();
}
break;
case LocalValueConsts.NETWORK_TOOL:
NetworkToolController networkToolController = ControllerModel.getNetworkToolController();
if (Checker.isNotNull(networkToolController)) {
fileContent = networkToolController.whoisResult.getText();
}
default:
break;
}
if (Checker.isNotEmpty(fileContent)) {
WeUtils.saveFile(file, fileContent);
}
}
}
}
public void openFileManagerTab() {
addTab(new Tab(LocalValueConsts.FILE_MANAGER), LocalValueConsts.FILE_MANAGER_VIEW);
}
public void openMultiFile() {
List<File> files = WeUtils.getChooseFiles();
if (Checker.isNotEmpty(files)) {
Tab tab = tabPane.getSelectionModel().getSelectedItem();
if (Checker.isNotNull(tab)) {
String tabText = Checker.checkNull(tab.getText());
switch (tabText) {
case LocalValueConsts.FILE_MANAGER:
WeUtils.putFilesInListViewOfFileManagerTab(files);
break;
default:
break;
}
}
}
}
public void about() {
Alerts.showInformation(LocalValueConsts.MAIN_TITLE, LocalValueConsts.ABOUT_APP, LocalValueConsts.ABOUT_DETAIL);
}
public void closeAllTab() {
tabPane.getTabs().clear();
}
public void openAllTab() {
ConfigModel.setTabs(ConfigModel.getSupportTabs());
loadTabs();
}
public void openQiniuToolTab() {
QiniuApplication.initLoad(ValueConsts.TRUE);
Tab tab = new Tab(LocalValueConsts.QINIU_TOOL);
tab.setOnCloseRequest((event) -> MainWindow.setOnClosed(event, ValueConsts.TRUE));
addTab(tab, LocalValueConsts.QINIU_TOOL_VIEW);
}
public void openWaveViewerTab() {
Tab tab = new Tab(LocalValueConsts.WAVE_VIEWER);
tab.setOnCloseRequest(event -> WeUtils.closeMysqlConnection());
addTab(tab, LocalValueConsts.WAVE_VIEW);
}
public void openColorPicker() {
WeUtils.startColorPicker();
}
public void openWox() {
WeUtils.startWox();
}
}
... ...
package com.zhazhapan.util.visual.controller;
import cn.hutool.core.util.NetUtil;
import com.zhazhapan.config.JsonParser;
import com.zhazhapan.util.Checker;
import com.zhazhapan.util.NetUtils;
import com.zhazhapan.util.ThreadPool;
import com.zhazhapan.util.dialog.Alerts;
import com.zhazhapan.util.visual.WeUtils;
import com.zhazhapan.util.visual.constant.LocalValueConsts;
import com.zhazhapan.util.visual.model.ControllerModel;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
/**
* @author pantao
* @since 2018/4/13
*/
public class NetworkToolController {
@FXML
public TextField privateIpv4;
@FXML
public TextField privateIpv6;
@FXML
public TextField publicIp;
@FXML
public TextField publicAddress;
@FXML
public TextField macAddress;
@FXML
public TextField systemInfo;
@FXML
public TextField ipAddress;
@FXML
public TextField ipLocation;
@FXML
public TextField domain;
@FXML
public TextArea whoisResult;
@FXML
private void initialize() {
ControllerModel.setNetworkToolController(this);
//防止UI线程阻塞
ThreadPool.executor.submit(() -> {
try {
JsonParser parser = NetUtils.getPublicIpAndLocation();
Platform.runLater(() -> {
try {
publicIp.setText(parser.getStringUseEval("ip"));
publicAddress.setText(parser.getStringUseEval("address"));
privateIpv4.setText(NetUtils.getLocalIp());
macAddress.setText(NetUtil.getLocalMacAddress());
systemInfo.setText(NetUtils.getSystemName() + " " + NetUtils.getSystemArch() + " " + NetUtils
.getSystemVersion());
} catch (Exception e) {
Alerts.showError(LocalValueConsts.MAIN_TITLE, LocalValueConsts.NETWORK_ERROR);
}
});
} catch (Exception e) {
Platform.runLater(() -> Alerts.showError(LocalValueConsts.MAIN_TITLE, LocalValueConsts.NETWORK_ERROR));
}
});
}
public void queryIpLocation() {
String ip = ipAddress.getText();
if (Checker.isNotEmpty(ip)) {
ThreadPool.executor.submit(() -> {
String location = WeUtils.getLocationByIp(ip);
if (Checker.isNotEmpty(location)) {
Platform.runLater(() -> ipLocation.setText(location));
}
});
}
}
public void queryWhois() {
String domainName = domain.getText();
if (Checker.isNotEmpty(domainName)) {
String result = WeUtils.whois(domainName);
if (Checker.isNotEmpty(result)) {
whoisResult.setText(result);
}
}
}
}
... ...
package com.zhazhapan.util.visual.controller;
import cn.hutool.extra.qrcode.QrCodeUtil;
import com.zhazhapan.modules.constant.ValueConsts;
import com.zhazhapan.util.dialog.Alerts;
import com.zhazhapan.util.visual.WeUtils;
import com.zhazhapan.util.visual.constant.LocalValueConsts;
import com.zhazhapan.util.visual.model.ConfigModel;
import com.zhazhapan.util.visual.model.ControllerModel;
import javafx.fxml.FXML;
import javafx.scene.control.TextArea;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.DragEvent;
import javafx.scene.input.TransferMode;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
/**
* @author pantao
* @since 2018/4/4
*/
public class QrCodeGeneratorController {
@FXML
public TextArea content;
@FXML
public ImageView qrCode;
@FXML
private void initialize() {
content.setWrapText(ConfigModel.isAutoWrap());
ControllerModel.setQrCodeGeneratorController(this);
}
public void generateQrCode() {
int size = (int) Double.min(qrCode.getFitHeight(), qrCode.getFitWidth());
File image = new File(ValueConsts.USER_DESKTOP + ValueConsts.SEPARATOR + "qrcode.jpg");
try {
QrCodeUtil.generate(content.getText(), size, size, image);
InputStream is = new FileInputStream(image);
qrCode.setImage(new Image(is));
is.close();
image.delete();
} catch (Exception e) {
Alerts.showError(LocalValueConsts.MAIN_TITLE, LocalValueConsts.QR_CODE_ERROR);
}
}
public void dragFileDropped(DragEvent event) {
WeUtils.putDragFileInTextArea(content, event);
}
public void dragFileOver(DragEvent event) {
event.acceptTransferModes(TransferMode.COPY);
}
}
... ...
package com.zhazhapan.util.visual.controller;
import cn.hutool.core.util.RandomUtil;
import com.zhazhapan.modules.constant.ValueConsts;
import com.zhazhapan.util.Checker;
import com.zhazhapan.util.Formatter;
import com.zhazhapan.util.RandomUtils;
import com.zhazhapan.util.visual.WeUtils;
import javafx.fxml.FXML;
import javafx.scene.control.TextField;
import java.util.ArrayList;
import java.util.List;
/**
* @author pantao
* @since 2018/4/2
*/
public class RandomGeneratorController {
@FXML
public TextField uuidResult;
@FXML
public TextField floor;
@FXML
public TextField ceil;
@FXML
public TextField ignoreRange;
@FXML
public TextField precision;
@FXML
public TextField numberResult;
@FXML
public TextField emailResult;
@FXML
public TextField lowerCaseLength;
@FXML
public TextField lowerCaseResult;
@FXML
public TextField upperCaseLength;
@FXML
public TextField upperCaseResult;
@FXML
public TextField letterLength;
@FXML
public TextField letterResult;
@FXML
public TextField stringLength;
@FXML
public TextField stringResult;
@FXML
public TextField textLength;
@FXML
public TextField textResult;
public void generateUUID() {
uuidResult.setText(RandomUtil.randomUUID());
}
public void generateNumber() {
String flo = floor.getText();
String cei = ceil.getText();
int p = WeUtils.stringToInt(precision.getText());
if (p == 0) {
String[] ranges = Checker.checkNull(ignoreRange.getText()).split(ValueConsts.COMMA_SIGN);
List<int[]> rl = new ArrayList<>(ranges.length);
for (String range : ranges) {
String[] rs = range.trim().split("-");
if (rs.length > 1 && Checker.isDecimal(rs[0].trim()) && Checker.isDecimal(rs[1].trim())) {
int[] ri = new int[]{Formatter.stringToInt(rs[0]), Formatter.stringToInt(rs[1])};
rl.add(ri);
}
}
int[][] r = new int[rl.size()][2];
rl.toArray(r);
int f = WeUtils.stringToInt(flo);
int c = Checker.isDecimal(cei) ? Formatter.stringToInt(cei) : Integer.MAX_VALUE;
numberResult.setText(String.valueOf(RandomUtils.getRandomIntegerIgnoreRange(f, c, r)));
} else {
double f = WeUtils.stringToDouble(flo);
double c = Checker.isDecimal(cei) ? Formatter.stringToDouble(cei) : Double.MAX_VALUE;
numberResult.setText(String.valueOf(RandomUtils.getRandomDouble(f, c, p)));
}
}
public void generateEmail() {
emailResult.setText(RandomUtils.getRandomEmail());
}
public void generateLowerCase() {
lowerCaseResult.setText(RandomUtils.getRandomStringOnlyLowerCase(getLength(lowerCaseLength.getText())));
}
public void generateUpperCase() {
upperCaseResult.setText(RandomUtils.getRandomStringOnlyUpperCase(getLength(upperCaseLength.getText())));
}
public void generateLetter() {
letterResult.setText(RandomUtils.getRandomStringOnlyLetter(getLength(letterLength.getText())));
}
public void generateString() {
stringResult.setText(RandomUtils.getRandomStringWithoutSymbol(getLength(stringLength.getText())));
}
public void generateText() {
textResult.setText(RandomUtils.getRandomString(getLength(textLength.getText())));
}
private int getLength(String len) {
int length = WeUtils.stringToInt(len);
return length < 1 ? RandomUtils.getRandomInteger(ValueConsts.NINE_INT, ValueConsts.SIXTEEN_INT) : length;
}
}
... ...
package com.zhazhapan.util.visual.controller;
import com.zhazhapan.modules.constant.ValueConsts;
import com.zhazhapan.util.Checker;
import com.zhazhapan.util.Formatter;
import com.zhazhapan.util.dialog.Alerts;
import com.zhazhapan.util.visual.WeUtils;
import com.zhazhapan.util.visual.constant.LocalValueConsts;
import com.zhazhapan.util.visual.model.ConfigModel;
import com.zhazhapan.util.visual.model.ControllerModel;
import com.zhazhapan.util.visual.model.WaverModel;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.scene.chart.AreaChart;
import javafx.scene.chart.XYChart;
import javafx.scene.control.ComboBox;
import javafx.scene.control.DatePicker;
import javafx.scene.control.TextField;
import java.sql.*;
import java.time.LocalDate;
import java.util.Date;
import java.util.List;
/**
* @author pantao
* @since 2018/4/19
*/
public class WaveController {
private final String INSERT = "插入";
private final String DELETE = "删除";
private final String UPDATE = "更新";
@FXML
public ComboBox<String> tableCombo;
@FXML
public DatePicker startDate;
@FXML
public DatePicker endDate;
@FXML
public AreaChart<String, Object> chart;
@FXML
public ComboBox<String> crudMethod;
@FXML
public TextField sqlNumber;
@FXML
public TextField sql;
@FXML
public DatePicker sqlDate;
public Connection connection = null;
public Statement statement = null;
@FXML
private void initialize() {
List<WaverModel> waves = ConfigModel.getWaver();
if (Checker.isNotEmpty(waves)) {
try {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://" + ConfigModel.getHost() + "/" + ConfigModel.getDatabase() + "?" +
ConfigModel.getCondition();
connection = DriverManager.getConnection(url, ConfigModel.getUsername(), ConfigModel.getPassword());
statement = connection.createStatement();
} catch (Exception e) {
Platform.runLater(() -> Alerts.showError(LocalValueConsts.MAIN_TITLE, e.getMessage()));
}
waves.forEach(waverModel -> tableCombo.getItems().add(waverModel.getTableName()));
tableCombo.getSelectionModel().selectedItemProperty().addListener((o, ov, nv) -> getWaveDataToLineChart());
tableCombo.getSelectionModel().selectFirst();
crudMethod.getItems().addAll(INSERT, DELETE, UPDATE);
crudMethod.getSelectionModel().selectFirst();
crudMethod.getSelectionModel().selectedItemProperty().addListener((o, ov, nv) -> generateSql());
}
ControllerModel.setWaveController(this);
}
public void generateSql() {
WaverModel wave = ConfigModel.getWaver().get(tableCombo.getSelectionModel().getSelectedIndex());
LocalDate localDate = sqlDate.getValue();
String date;
if (Checker.isNull(localDate)) {
date = Formatter.dateToString(new Date());
} else {
date = Formatter.dateToString(Formatter.localDateToDate(localDate));
}
switch (crudMethod.getSelectionModel().getSelectedItem()) {
case INSERT:
sql.setText("insert into " + wave.getTableName() + "(" + wave.getDataField() + "," + wave
.getDateField() + ") values('" + sqlNumber.getText() + "','" + date + "')");
break;
case DELETE:
sql.setText("delete from " + wave.getTableName() + " where " + wave.getDateField() + "='" + date + "'");
break;
case UPDATE:
sql.setText("update " + wave.getTableName() + " set " + wave.getDataField() + "='" + sqlNumber
.getText() + "' where " + wave.getDateField() + "='" + date + "'");
default:
break;
}
}
public void getWaveDataToLineChart() {
if (Checker.isNotNull(statement)) {
chart.getData().clear();
WaverModel wave = ConfigModel.getWaver().get(tableCombo.getSelectionModel().getSelectedIndex());
String sql = "select " + wave.getDataField() + "," + wave.getDateField() + " from " + wave.getTableName();
LocalDate startLocalDate = startDate.getValue();
LocalDate endLocalDate = endDate.getValue();
boolean startIsNull = Checker.isNull(startLocalDate);
boolean endIsNull = Checker.isNull(endLocalDate);
if (!startIsNull) {
String start = Formatter.dateToString(Formatter.localDateToDate(startDate.getValue()));
sql += " where " + wave.getDateField() + ">='" + start + "' and";
}
String and = "and";
if (!endIsNull) {
String end = Formatter.dateToString(Formatter.localDateToDate(endDate.getValue()));
if (sql.endsWith(and)) {
sql += " " + wave.getDateField() + "<='" + end + "'";
} else {
sql += " where " + wave.getDateField() + "<='" + end + "'";
}
}
if (sql.endsWith(and)) {
sql = sql.substring(0, sql.length() - 4);
}
sql += " order by " + wave.getDateField();
if (startIsNull && endIsNull) {
sql += " limit 0," + wave.getFirstResultSize();
}
XYChart.Series<String, Object> series = new XYChart.Series<>();
series.setName(wave.getTitle());
try {
ResultSet resultSet = statement.executeQuery(sql);
while (resultSet.next()) {
String data = resultSet.getString(ValueConsts.ONE_INT);
String date = resultSet.getString(ValueConsts.TWO_INT);
Object value = data;
if (Checker.isDecimal(data)) {
if (data.contains(ValueConsts.DOT_SIGN)) {
int idx = data.lastIndexOf(ValueConsts.DOT_SIGN) + 3;
if (data.length() > idx) {
data = data.substring(0, idx);
}
value = WeUtils.stringToDouble(data);
} else {
value = WeUtils.stringToInt(data);
}
}
series.getData().add(new XYChart.Data<>(date.split(" ")[0], value));
}
} catch (SQLException e) {
System.out.println(sql);
Alerts.showError(LocalValueConsts.MAIN_TITLE, e.getMessage());
}
chart.getData().add(series);
chart.setTitle(wave.getTitle());
}
}
public void executeSql() {
if (Checker.isNotNull(statement)) {
try {
statement.executeUpdate(WeUtils.replaceVariable(sql.getText()));
Alerts.showInformation(LocalValueConsts.MAIN_TITLE, LocalValueConsts.OPERATION_SUCCESS);
getWaveDataToLineChart();
} catch (SQLException e) {
Alerts.showError(LocalValueConsts.MAIN_TITLE, e.getMessage());
}
}
}
}
... ...
package com.zhazhapan.util.visual.model;
import cn.hutool.core.util.ClipboardUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;
import com.zhazhapan.modules.constant.ValueConsts;
import com.zhazhapan.util.Checker;
import javafx.util.Pair;
import java.util.*;
/**
* 配置参数
*
* @author pantao
* @since 2018/4/2
*/
public class ConfigModel {
private static List<Pair<Date, String>> clipboardHistory = new LinkedList<>();
private static double width = 1000;
private static double height = 700;
private static JSONArray supportTabs;
private static String fileFilterRegex = "^[^.].*$";
private static boolean fileFilterTip = true;
private static int clipboardSize = 20;
private static JSONArray tabs = new JSONArray();
private static boolean fullscreen = false;
private static boolean autoWrap = false;
private static String host = "127.0.0.1:3306";
private static String database = "efo";
private static String condition = "useUnicode=true&characterEncoding=utf-8&useSSL=true";
private static String username = "zhazhapan";
private static String password = "zhazhapan";
private static List<WaverModel> waver = new ArrayList<>();
static {
tabs.add("JsonParser");
tabs.add("FileManager");
tabs.add("RandomGenerator");
tabs.add("ClipboardHistory");
tabs.add("QrCodeGenerator");
tabs.add("CharsetConverter");
tabs.add("NetworkTool");
tabs.add("QiniuTool");
tabs.add("WaveViewer");
supportTabs = ObjectUtil.cloneByStream(tabs);
}
public static String getHost() {
return host;
}
public static void setHost(String host) {
ConfigModel.host = host;
}
public static String getDatabase() {
return database;
}
public static void setDatabase(String database) {
ConfigModel.database = database;
}
public static String getCondition() {
return condition;
}
public static void setCondition(String condition) {
ConfigModel.condition = condition;
}
public static String getUsername() {
return username;
}
public static void setUsername(String username) {
ConfigModel.username = username;
}
public static String getPassword() {
return password;
}
public static void setPassword(String password) {
ConfigModel.password = password;
}
public static List<WaverModel> getWaver() {
return waver;
}
public static JSONArray getSupportTabs() {
return supportTabs;
}
public static boolean isAutoWrap() {
return autoWrap;
}
public static void setAutoWrap(boolean autoWrap) {
ConfigModel.autoWrap = autoWrap;
}
public static boolean isFullscreen() {
return fullscreen;
}
public static void setFullscreen(boolean fullscreen) {
ConfigModel.fullscreen = fullscreen;
}
public static int getClipboardHistorySize() {
return clipboardHistory.size();
}
public static void appendClipboardHistory(Date date, String content) {
if (getClipboardHistorySize() < clipboardSize) {
clipboardHistory.add(new Pair<>(date, Checker.checkNull(content)));
} else {
clipboardHistory.remove(ValueConsts.ZERO_INT);
appendClipboardHistory(date, content);
}
}
public static Pair<Date, String> getLastClipboardHistoryItem() {
Optional<Pair<Date, String>> last = Optional.ofNullable(getClipboardHistoryItem(getClipboardHistorySize() - 1));
return last.orElse(new Pair<>(new Date(), Checker.checkNull(ClipboardUtil.getStr())));
}
public static Pair<Date, String> getClipboardHistoryItem(int index) {
if (index >= 0 && index < clipboardSize) {
return clipboardHistory.get(index);
}
return null;
}
public static void setClipboardSize(int clipboardSize) {
ConfigModel.clipboardSize = clipboardSize;
}
public static double getWidth() {
return width;
}
public static void setWidth(double width) {
ConfigModel.width = width;
}
public static double getHeight() {
return height;
}
public static void setHeight(double height) {
ConfigModel.height = height;
}
public static JSONArray getTabs() {
return tabs;
}
public static void setTabs(JSONArray tabs) {
ConfigModel.tabs = tabs;
}
public static String getFileFilterRegex() {
return fileFilterRegex;
}
public static void setFileFilterRegex(String fileFilterRegex) {
ConfigModel.fileFilterRegex = fileFilterRegex;
}
public static boolean isFileFilterTip() {
return fileFilterTip;
}
public static void setFileFilterTip(boolean fileFilterTip) {
ConfigModel.fileFilterTip = fileFilterTip;
}
}
... ...
package com.zhazhapan.util.visual.model;
import com.zhazhapan.util.visual.controller.*;
/**
* 保存打开的窗口controller对象
*
* @author pantao
* @since 2018/3/31
*/
public class ControllerModel {
private static NetworkToolController networkToolController = null;
private static JsonParserController jsonParserController = null;
private static FileManagerController fileManagerController = null;
private static ClipboardHistoryController clipboardHistoryController = null;
private static MainController mainController = null;
private static QrCodeGeneratorController qrCodeGeneratorController = null;
private static CharsetConverterController charsetConverterController = null;
private static WaveController waveController = null;
public static WaveController getWaveController() {
return waveController;
}
public static void setWaveController(WaveController waveController) {
ControllerModel.waveController = waveController;
}
public static NetworkToolController getNetworkToolController() {
return networkToolController;
}
public static void setNetworkToolController(NetworkToolController networkToolController) {
ControllerModel.networkToolController = networkToolController;
}
public static CharsetConverterController getCharsetConverterController() {
return charsetConverterController;
}
public static void setCharsetConverterController(CharsetConverterController charsetConverterController) {
ControllerModel.charsetConverterController = charsetConverterController;
}
public static QrCodeGeneratorController getQrCodeGeneratorController() {
return qrCodeGeneratorController;
}
public static void setQrCodeGeneratorController(QrCodeGeneratorController qrCodeGeneratorController) {
ControllerModel.qrCodeGeneratorController = qrCodeGeneratorController;
}
public static MainController getMainController() {
return mainController;
}
public static void setMainController(MainController mainController) {
ControllerModel.mainController = mainController;
}
public static ClipboardHistoryController getClipboardHistoryController() {
return clipboardHistoryController;
}
public static void setClipboardHistoryController(ClipboardHistoryController clipboardHistoryController) {
ControllerModel.clipboardHistoryController = clipboardHistoryController;
}
public static FileManagerController getFileManagerController() {
return fileManagerController;
}
public static void setFileManagerController(FileManagerController fileManagerController) {
ControllerModel.fileManagerController = fileManagerController;
}
public static JsonParserController getJsonParserController() {
return jsonParserController;
}
public static void setJsonParserController(JsonParserController jsonParserController) {
ControllerModel.jsonParserController = jsonParserController;
}
}
... ...
package com.zhazhapan.util.visual.model;
/**
* @author pantao
* @since 2018/4/19
*/
public class WaverModel {
private String title;
private String tableName;
private String dataField;
private String dateField;
private int firstResultSize;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getTableName() {
return tableName;
}
public void setTableName(String tableName) {
this.tableName = tableName;
}
public String getDataField() {
return dataField;
}
public void setDataField(String dataField) {
this.dataField = dataField;
}
public String getDateField() {
return dateField;
}
public void setDateField(String dateField) {
this.dateField = dateField;
}
public int getFirstResultSize() {
return firstResultSize;
}
public void setFirstResultSize(int firstResultSize) {
this.firstResultSize = firstResultSize;
}
}
... ...
{
"initialize": {
"width": 1000,
"height": 700,
"fullscreen": false,
"tabs": {
"load": [
"ClipboardHistory"
],
"support": [
"FileManager",
"JsonParser",
"RandomGenerator",
"ClipboardHistory",
"QrCodeGenerator",
"CharsetConverter",
"NetworkTool",
"QiniuTool",
"WaveViewer"
]
}
},
"fileFilter": {
"regex": "^[^.].*$",
"showTip": true,
"description": "只获取匹配的文件,当文件不匹配时根据 `showTip` 设置是否显示提示"
},
"clipboardSize": 20,
"autoWrap": false,
"mysql": {
"host": "192.168.1.233:3306",
"database": "efo",
"condition": "useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC",
"username": "root",
"password": "root"
},
"waveViewer": [
{
"title": "频率计算器",
"tableName": "frequency",
"dataField": "fre_data",
"dateField": "fre_date",
"firstResultSize": 30
},
{
"title": "晚睡时间",
"tableName": "dismiss",
"dataField": "dis_data",
"dateField": "dis_date",
"firstResultSize": 30
}
]
}
\ No newline at end of file
... ...
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.Font?>
<VBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="400.0" prefWidth="600.0"
xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="com.zhazhapan.util.visual.controller.CharsetConverterController">
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</padding>
<TextArea fx:id="originalContent" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
onDragDropped="#dragFileDropped" onDragOver="#dragFileOver" prefHeight="82.0" prefWidth="580.0"
promptText="原字符集" VBox.vgrow="ALWAYS">
<tooltip>
<Tooltip autoHide="true" text="拖曳文件至此"/>
</tooltip>
</TextArea>
<HBox prefHeight="24.0" prefWidth="580.0" VBox.vgrow="NEVER">
<VBox.margin>
<Insets bottom="10.0" top="10.0"/>
</VBox.margin>
<ComboBox fx:id="originalCharset" prefWidth="150.0" HBox.hgrow="NEVER"/>
<Label text="转" HBox.hgrow="NEVER">
<HBox.margin>
<Insets left="10.0" top="5.0"/>
</HBox.margin>
<font>
<Font size="14.0"/>
</font>
</Label>
<ComboBox fx:id="convertCharset" prefWidth="150.0" HBox.hgrow="NEVER">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
</ComboBox>
</HBox>
<TextArea fx:id="convertedContent" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
prefHeight="200.0" prefWidth="200.0" promptText="转换后的字符集" VBox.vgrow="ALWAYS"/>
</VBox>
... ...
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.layout.VBox?>
<VBox prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="com.zhazhapan.util.visual.controller.ClipboardHistoryController">
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</padding>
<TextArea fx:id="clipboardHistory" prefHeight="200.0" prefWidth="200.0" promptText="剪贴历史" VBox.vgrow="ALWAYS"/>
</VBox>
... ...
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<VBox prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="com.zhazhapan.util.visual.controller.FileManagerController">
<TabPane fx:id="fileManagerTab" prefHeight="272.0" prefWidth="600.0" side="BOTTOM" tabClosingPolicy="UNAVAILABLE"
VBox.vgrow="ALWAYS">
<Tab closable="false" text="重命名文件">
<SplitPane dividerPositions="0.4816666666666667" prefHeight="160.0" prefWidth="200.0">
<padding>
<Insets bottom="10.0" top="10.0"/>
</padding>
<VBox>
<padding>
<Insets left="10.0" right="10.0"/>
</padding>
<ListView fx:id="selectedFilesOfRenameTab" editable="true"
onDragDropped="#dragFileDropped" onDragOver="#dragFileOver"
prefHeight="200.0" prefWidth="200.0" VBox.vgrow="ALWAYS">
<contextMenu>
<ContextMenu>
<items>
<MenuItem mnemonicParsing="false"
onAction="#removeFilesFromRenameTab" text="删除"/>
</items>
</ContextMenu>
</contextMenu>
<tooltip>
<Tooltip autoHide="true" text="拖曳文件至此"/>
</tooltip>
</ListView>
</VBox>
<VBox>
<padding>
<Insets left="10.0" right="10.0"/>
</padding>
<TabPane prefHeight="119.0" prefWidth="287.0" tabClosingPolicy="UNAVAILABLE"
VBox.vgrow="NEVER">
<Tab closable="false" text="格式化">
<VBox maxHeight="1.7976931348623157E308" prefHeight="72.0"
prefWidth="287.0">
<padding>
<Insets top="10.0"/>
</padding>
<TextField fx:id="filePrefixOfRenameTab"
onKeyReleased="#generateRenameDestFilesOfFormat"
promptText="文件前缀" VBox.vgrow="NEVER">
<tooltip>
<Tooltip autoHide="true"
text="支持变量:%DATE%, %TIME%"/>
</tooltip>
</TextField>
<HBox prefHeight="100.0" prefWidth="287.0">
<VBox.margin>
<Insets top="10.0"/>
</VBox.margin>
<TextField fx:id="filePostfixOfRenameTab"
onKeyReleased="#generateRenameDestFilesOfFormat"
prefHeight="27.0" prefWidth="193.0"
promptText="文件后缀" HBox.hgrow="ALWAYS">
<tooltip>
<Tooltip autoHide="true"
text="支持变量:%DATE%, %TIME%"/>
</tooltip>
</TextField>
<TextField fx:id="startNumberOfRenameTab"
onKeyReleased="#generateRenameDestFilesOfFormat"
prefHeight="27.0" prefWidth="107.0"
promptText="开始数字" text="1"
HBox.hgrow="ALWAYS">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
<tooltip>
<Tooltip autoHide="true"
text="支持变量:%DATE%, %TIME%"/>
</tooltip>
</TextField>
</HBox>
</VBox>
</Tab>
<Tab closable="false" text="替换文本">
<VBox>
<padding>
<Insets top="10.0"/>
</padding>
<TextField fx:id="fileQueryStringOfRenameTab"
onKeyReleased="#generateRenameDestFilesOfReplace"
promptText="查找" VBox.vgrow="NEVER"/>
<TextField fx:id="fileReplaceStringOfRenameTab"
onKeyReleased="#generateRenameDestFilesOfReplace"
promptText="替换成" VBox.vgrow="NEVER">
<VBox.margin>
<Insets top="10.0"/>
</VBox.margin>
<tooltip>
<Tooltip autoHide="true"
text="支持变量:%DATE%, %TIME%"/>
</tooltip>
</TextField>
</VBox>
</Tab>
<Tab closable="false" text="添加文本">
<VBox>
<padding>
<Insets top="10.0"/>
</padding>
<TextField fx:id="fileAddableText"
onKeyReleased="#generateRenameDestFilesOfAddable"
promptText="文本内容" VBox.vgrow="NEVER">
<tooltip>
<Tooltip autoHide="true"
text="支持变量:%DATE%, %TIME%"/>
</tooltip>
</TextField>
<ComboBox fx:id="fileAddableCombo"
maxWidth="1.7976931348623157E308"
prefHeight="27.0" prefWidth="293.0"
VBox.vgrow="NEVER">
<VBox.margin>
<Insets top="10.0"/>
</VBox.margin>
</ComboBox>
</VBox>
</Tab>
</TabPane>
<ListView fx:id="destFilesOfRenameTab" prefHeight="200.0" prefWidth="200.0"
VBox.vgrow="ALWAYS">
<VBox.margin>
<Insets/>
</VBox.margin>
</ListView>
<Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
mnemonicParsing="false" onAction="#renameFiles" prefHeight="27.0"
prefWidth="293.0" text="批量重命名">
<VBox.margin>
<Insets top="10.0"/>
</VBox.margin>
</Button>
</VBox>
</SplitPane>
</Tab>
<Tab closable="false" text="复制文件">
<VBox prefHeight="200.0" prefWidth="100.0">
<padding>
<Insets left="10.0" right="10.0" top="10.0"/>
</padding>
<HBox VBox.vgrow="NEVER">
<TextField fx:id="destFolderOfCopyTab" onDragDropped="#dragFileDroppedOfCopyTab"
onDragOver="#dragFileOver" promptText="目标文件夹" HBox.hgrow="ALWAYS">
<tooltip>
<Tooltip autoHide="true" text="拖曳文件至此"/>
</tooltip>
</TextField>
<Button mnemonicParsing="false" onAction="#browseSrcFolder" text="浏览"
HBox.hgrow="NEVER">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
</Button>
</HBox>
<ListView fx:id="selectedFilesOfCopyTab" onDragDropped="#dragFileDroppedOfCopyTab"
onDragOver="#dragFileOver" prefHeight="200.0" prefWidth="200.0"
VBox.vgrow="ALWAYS">
<tooltip>
<Tooltip autoHide="true" text="拖曳文件至此"/>
</tooltip>
<VBox.margin>
<Insets top="10.0"/>
</VBox.margin>
<contextMenu>
<ContextMenu>
<items>
<MenuItem mnemonicParsing="false" onAction="#removeFilesOfCopyTab"
text="删除"/>
</items>
</ContextMenu>
</contextMenu>
</ListView>
<HBox prefHeight="31.0" prefWidth="580.0" VBox.vgrow="NEVER">
<padding>
<Insets bottom="10.0" top="10.0"/>
</padding>
<CheckBox fx:id="isDeleteSrcOfCopyTab" mnemonicParsing="false" text="删除源文件">
<HBox.margin>
<Insets top="5.0"/>
</HBox.margin>
</CheckBox>
<Button maxWidth="1.7976931348623157E308" mnemonicParsing="false"
onAction="#copyFiles" prefHeight="27.0" prefWidth="368.0" text="批量复制文件"
HBox.hgrow="ALWAYS">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
</Button>
</HBox>
</VBox>
</Tab>
<Tab closable="false" text="拆分文件">
<VBox prefHeight="200.0" prefWidth="100.0">
<padding>
<Insets left="10.0" right="10.0" top="10.0"/>
</padding>
<HBox prefHeight="24.0" prefWidth="580.0" VBox.vgrow="NEVER">
<TextField fx:id="destFolderOfSplitTab" onDragDropped="#dragFileDroppedOfSplitTab"
onDragOver="#dragFileOver" promptText="目标文件夹" HBox.hgrow="ALWAYS">
<tooltip>
<Tooltip autoHide="true" text="拖曳文件至此"/>
</tooltip>
</TextField>
<Button mnemonicParsing="false" onAction="#browseSrcFolder" text="浏览"
HBox.hgrow="NEVER">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
</Button>
</HBox>
<TextArea fx:id="fileContent" onDragDropped="#dragFileDroppedOfSplitTab"
onDragOver="#dragFileOver" onMouseClicked="#generateSplitPoint" prefHeight="200.0"
prefWidth="200.0" promptText="文件内容, 可拖曳文件至此" VBox.vgrow="ALWAYS">
<tooltip>
<Tooltip autoHide="true" text="拖曳文件至此"/>
</tooltip>
<VBox.margin>
<Insets top="10.0"/>
</VBox.margin>
</TextArea>
<TextField fx:id="splitPoint" onMouseClicked="#scrollTo" promptText="拆分点"
VBox.vgrow="NEVER">
<VBox.margin>
<Insets top="10.0"/>
</VBox.margin>
</TextField>
<HBox prefHeight="31.0" prefWidth="580.0">
<padding>
<Insets bottom="10.0" top="10.0"/>
</padding>
<CheckBox fx:id="isDeleteSrcOfSplitTab" mnemonicParsing="false" text="删除源文件">
<HBox.margin>
<Insets top="5.0"/>
</HBox.margin>
</CheckBox>
<Button maxWidth="1.7976931348623157E308" mnemonicParsing="false"
onAction="#splitFile" prefHeight="27.0" prefWidth="368.0" text="拆分文件"
HBox.hgrow="ALWAYS">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
</Button>
</HBox>
</VBox>
</Tab>
<Tab closable="false" text="合并文件">
<VBox prefHeight="200.0" prefWidth="100.0">
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</padding>
<ListView fx:id="selectedFilesOfMergeTab" onDragDropped="#dragFileDropped"
onDragOver="#dragFileOver" prefHeight="200.0" prefWidth="200.0"
VBox.vgrow="ALWAYS">
<tooltip>
<Tooltip autoHide="true" text="拖曳文件至此"/>
</tooltip>
<contextMenu>
<ContextMenu>
<items>
<MenuItem mnemonicParsing="false" onAction="#goForward" text="上移"/>
<MenuItem mnemonicParsing="false" onAction="#goBack" text="下移"/>
<MenuItem mnemonicParsing="false" onAction="#removeFilesOfMergeTab"
text="删除"/>
</items>
</ContextMenu>
</contextMenu>
</ListView>
<HBox prefHeight="23.0" prefWidth="580.0">
<VBox.margin>
<Insets top="10.0"/>
</VBox.margin>
<TextField fx:id="contentFilter" promptText="文本过滤,过滤掉(正则表达式)匹配的字符串"
HBox.hgrow="ALWAYS"/>
<CheckBox fx:id="deleteSrcOfMergeTab" mnemonicParsing="false" text="删除源文件"
HBox.hgrow="NEVER">
<HBox.margin>
<Insets left="10.0" top="5.0"/>
</HBox.margin>
</CheckBox>
<Button mnemonicParsing="false" onAction="#mergeFiles" text="合并文件"
HBox.hgrow="NEVER">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
</Button>
</HBox>
</VBox>
</Tab>
<Tab text="删除文件">
<VBox>
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</padding>
<TextField fx:id="srcFolderOfDeleteTab" promptText="源文件夹(支持拖曳)" VBox.vgrow="NEVER"
onDragDropped="#dragFileDroppedOfDeleteTab"
onDragOver="#dragFileOver">
<tooltip>
<Tooltip autoHide="true" text="拖曳文件至此"/>
</tooltip>
</TextField>
<TextArea fx:id="filenameOfDeleteTab" prefHeight="200.0" prefWidth="200.0"
promptText="待删除的文件名,用英文逗号分隔" VBox.vgrow="ALWAYS" onDragDropped="#dragFilesDroppedOfDeleteTab"
onDragOver="#dragFileOver">
<VBox.margin>
<Insets top="10.0"/>
</VBox.margin>
<tooltip>
<Tooltip autoHide="true" text="拖曳文件至此"/>
</tooltip>
</TextArea>
<Button maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#deleteFiles"
text="删除文件夹下所有列出的文件" VBox.vgrow="NEVER">
<VBox.margin>
<Insets top="10.0"/>
</VBox.margin>
</Button>
</VBox>
</Tab>
</TabPane>
</VBox>
... ...
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<VBox prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/9" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="com.zhazhapan.util.visual.controller.JsonParserController">
<HBox VBox.vgrow="NEVER">
<TextField fx:id="jsonPath" onKeyReleased="#jsonPathEnter" prefHeight="27.0" prefWidth="251.0"
promptText="JSON路径" HBox.hgrow="ALWAYS"/>
<Button mnemonicParsing="false" onAction="#parseJson" text="解析" HBox.hgrow="NEVER">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
</Button>
<Hyperlink onAction="#seeJsonPathGrammar" text="路径语法" HBox.hgrow="NEVER">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
</Hyperlink>
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</padding>
</HBox>
<SplitPane dividerPositions="0.459866220735786" prefHeight="160.0" prefWidth="200.0" VBox.vgrow="ALWAYS">
<VBox>
<padding>
<Insets left="10.0" right="10.0"/>
</padding>
<TextArea fx:id="jsonContent" onDragDropped="#dragFileDropped" onDragOver="#dragFileOver" prefHeight="200.0"
prefWidth="200.0" promptText="可拖曳文件至此" VBox.vgrow="ALWAYS">
<tooltip>
<Tooltip autoHide="true" text="拖曳文件至此"/>
</tooltip>
</TextArea>
</VBox>
<VBox>
<padding>
<Insets left="10.0" right="10.0"/>
</padding>
<TextArea fx:id="parsedJsonContent" prefHeight="200.0" prefWidth="200.0" VBox.vgrow="ALWAYS"/>
</VBox>
<padding>
<Insets bottom="10.0" top="10.0"/>
</padding>
</SplitPane>
</VBox>
... ...
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<VBox prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/9" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.zhazhapan.util.visual.controller.NetworkToolController">
<!--<Accordion fx:id="accordion" VBox.vgrow="ALWAYS">-->
<!--<panes>-->
<!--<TitledPane fx:id="firstTitledPane" animated="false" text="本机网络">-->
<!--<VBox>-->
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</padding>
<HBox VBox.vgrow="NEVER">
<Label text="内网IP:" HBox.hgrow="NEVER">
<HBox.margin>
<Insets top="5.0" />
</HBox.margin>
</Label>
<TextField fx:id="privateIpv4" editable="false" maxWidth="200.0" HBox.hgrow="ALWAYS">
<HBox.margin>
<Insets left="10.0" />
</HBox.margin>
</TextField>
<Label text="IPV6:" visible="false" HBox.hgrow="NEVER">
<HBox.margin>
<Insets left="10.0" top="5.0" />
</HBox.margin>
</Label>
<TextField fx:id="privateIpv6" editable="false" maxWidth="300.0" visible="false" HBox.hgrow="ALWAYS">
<HBox.margin>
<Insets left="10.0" />
</HBox.margin>
</TextField>
</HBox>
<HBox VBox.vgrow="NEVER">
<VBox.margin>
<Insets top="10.0" />
</VBox.margin>
<Label text="公网IP:" HBox.hgrow="NEVER">
<HBox.margin>
<Insets top="5.0" />
</HBox.margin>
</Label>
<TextField fx:id="publicIp" editable="false" maxWidth="200.0" HBox.hgrow="ALWAYS">
<HBox.margin>
<Insets left="10.0" />
</HBox.margin>
</TextField>
<Label text="地址:" HBox.hgrow="NEVER">
<HBox.margin>
<Insets left="10.0" top="5.0" />
</HBox.margin>
</Label>
<TextField fx:id="publicAddress" editable="false" maxWidth="300.0" HBox.hgrow="ALWAYS">
<HBox.margin>
<Insets left="10.0" />
</HBox.margin>
</TextField>
</HBox>
<HBox VBox.vgrow="NEVER">
<VBox.margin>
<Insets top="10.0" />
</VBox.margin>
<Label text=" MAC:" HBox.hgrow="NEVER">
<HBox.margin>
<Insets top="5.0" />
</HBox.margin>
</Label>
<TextField fx:id="macAddress" editable="false" maxWidth="300.0" HBox.hgrow="ALWAYS">
<HBox.margin>
<Insets left="10.0" />
</HBox.margin>
</TextField>
</HBox>
<HBox VBox.vgrow="NEVER">
<VBox.margin>
<Insets top="10.0" />
</VBox.margin>
<Label text="系统名:" HBox.hgrow="NEVER">
<HBox.margin>
<Insets top="5.0" />
</HBox.margin>
</Label>
<TextField fx:id="systemInfo" editable="false" maxWidth="300.0" HBox.hgrow="ALWAYS">
<HBox.margin>
<Insets left="10.0" />
</HBox.margin>
</TextField>
</HBox>
<HBox VBox.vgrow="NEVER">
<VBox.margin>
<Insets top="10.0" />
</VBox.margin>
<Label text="IP归属地查询:" HBox.hgrow="NEVER">
<HBox.margin>
<Insets top="5.0" />
</HBox.margin>
</Label>
<TextField fx:id="ipAddress" maxWidth="200.0" promptText="IP地址" HBox.hgrow="ALWAYS">
<HBox.margin>
<Insets left="10.0" />
</HBox.margin>
</TextField>
<Button mnemonicParsing="false" onAction="#queryIpLocation" text="查询" HBox.hgrow="NEVER">
<HBox.margin>
<Insets left="10.0" />
</HBox.margin>
</Button>
<TextField fx:id="ipLocation" editable="false" maxWidth="300.0" promptText="归属地" HBox.hgrow="ALWAYS">
<HBox.margin>
<Insets left="10.0" />
</HBox.margin>
</TextField>
</HBox>
<VBox VBox.vgrow="ALWAYS">
<VBox.margin>
<Insets top="10.0" />
</VBox.margin>
<children>
<HBox prefHeight="34.0" prefWidth="580.0" VBox.vgrow="NEVER">
<children>
<Label text="WHOIS查询:" HBox.hgrow="NEVER">
<HBox.margin>
<Insets top="5.0" />
</HBox.margin>
</Label>
<TextField fx:id="domain" maxWidth="500.0" prefWidth="300.0" promptText="域名" HBox.hgrow="ALWAYS">
<HBox.margin>
<Insets left="10.0" />
</HBox.margin>
</TextField>
<Button mnemonicParsing="false" onAction="#queryWhois" text="查询" HBox.hgrow="NEVER">
<HBox.margin>
<Insets left="10.0" />
</HBox.margin>
</Button>
</children>
</HBox>
<TextArea fx:id="whoisResult" prefHeight="200.0" prefWidth="200.0" promptText="whois查询结果" VBox.vgrow="ALWAYS">
<VBox.margin>
<Insets top="10.0" />
</VBox.margin>
</TextArea>
</children>
</VBox>
<!--</VBox>-->
<!--</TitledPane>-->
<!--<TitledPane animated="false" text="端口扫描">-->
<!--<VBox/>-->
<!--</TitledPane>-->
<!--<TitledPane animated="false" text="网络抓包">-->
<!--<VBox/>-->
<!--</TitledPane>-->
<!--<TitledPane animated="false" text="接口测试">-->
<!--<VBox/>-->
<!--</TitledPane>-->
<!--<TitledPane animated="false" text="网络文件下载">-->
<!--<VBox/>-->
<!--</TitledPane>-->
<!--<TitledPane animated="false" text="WHOIS查询">-->
<!--<VBox/>-->
<!--</TitledPane>-->
<!--</panes>-->
<!--</Accordion>-->
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</padding>
</VBox>
... ...
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.Font?>
<VBox alignment="TOP_CENTER" prefHeight="600.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/9"
xmlns:fx="http://javafx.com/fxml/1"
fx:controller="com.zhazhapan.util.visual.controller.QrCodeGeneratorController">
<SplitPane dividerPositions="0.11538461538461539" orientation="VERTICAL" prefHeight="200.0" prefWidth="160.0"
VBox.vgrow="ALWAYS">
<HBox prefHeight="148.0" prefWidth="598.0">
<TextArea fx:id="content" onDragDropped="#dragFileDropped" onDragOver="#dragFileOver" prefHeight="134.0"
prefWidth="449.0" promptText="文本" HBox.hgrow="ALWAYS">
<tooltip>
<Tooltip autoHide="true" text="拖曳文件至此"/>
</tooltip>
</TextArea>
<Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false"
onAction="#generateQrCode" prefHeight="134.0" prefWidth="91.0" text="生成" HBox.hgrow="NEVER">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
<font>
<Font size="24.0"/>
</font>
</Button>
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</padding>
</HBox>
<ScrollPane fitToHeight="true" fitToWidth="true" maxHeight="1.7976931348623157E308"
maxWidth="1.7976931348623157E308">
<HBox alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308">
<ImageView fx:id="qrCode" fitHeight="555.0" fitWidth="555.0" pickOnBounds="true" preserveRatio="true"
HBox.hgrow="ALWAYS"/>
</HBox>
</ScrollPane>
</SplitPane>
</VBox>
... ...
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<VBox prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/9" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="com.zhazhapan.util.visual.controller.RandomGeneratorController">
<HBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="47.0" prefWidth="599.0"
VBox.vgrow="NEVER">
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</padding>
<Label text="UUID" HBox.hgrow="NEVER">
<HBox.margin>
<Insets top="5.0"/>
</HBox.margin>
</Label>
<Button mnemonicParsing="false" onAction="#generateUUID" text="生成" HBox.hgrow="NEVER">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
</Button>
<TextField fx:id="uuidResult" editable="false" promptText="结果" HBox.hgrow="ALWAYS">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
</TextField>
</HBox>
<HBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="47.0" prefWidth="599.0"
VBox.vgrow="NEVER">
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</padding>
<Label text="数字" HBox.hgrow="NEVER">
<HBox.margin>
<Insets top="5.0"/>
</HBox.margin>
</Label>
<TextField fx:id="floor" prefHeight="27.0" prefWidth="62.0" promptText="下限" HBox.hgrow="NEVER">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
<tooltip>
<Tooltip text="正数" autoHide="true"/>
</tooltip>
</TextField>
<TextField fx:id="ceil" prefHeight="27.0" prefWidth="63.0" promptText="上限" HBox.hgrow="NEVER">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
</TextField>
<TextField fx:id="ignoreRange" prefHeight="27.0" prefWidth="158.0" promptText="忽略区间, 格式: 0-3,5-7"
HBox.hgrow="NEVER">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
<tooltip>
<Tooltip text="仅针对整数" autoHide="true"/>
</tooltip>
</TextField>
<TextField fx:id="precision" prefHeight="27.0" prefWidth="47.0" promptText="精度" HBox.hgrow="NEVER">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
</TextField>
<Button mnemonicParsing="false" onAction="#generateNumber" text="生成" HBox.hgrow="NEVER">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
</Button>
<TextField fx:id="numberResult" editable="false" prefHeight="27.0" prefWidth="108.0" promptText="结果"
HBox.hgrow="ALWAYS">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
</TextField>
</HBox>
<HBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="47.0" prefWidth="599.0"
VBox.vgrow="NEVER">
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</padding>
<Label text="邮箱" HBox.hgrow="NEVER">
<HBox.margin>
<Insets top="5.0"/>
</HBox.margin>
</Label>
<Button mnemonicParsing="false" onAction="#generateEmail" text="生成" HBox.hgrow="NEVER">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
</Button>
<TextField fx:id="emailResult" editable="false" promptText="结果" HBox.hgrow="ALWAYS">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
</TextField>
</HBox>
<HBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="47.0" prefWidth="599.0"
VBox.vgrow="NEVER">
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</padding>
<Label text="小写字母" HBox.hgrow="NEVER">
<HBox.margin>
<Insets top="5.0"/>
</HBox.margin>
</Label>
<TextField fx:id="lowerCaseLength" prefHeight="27.0" prefWidth="82.0" promptText="长度" HBox.hgrow="NEVER">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
</TextField>
<Button mnemonicParsing="false" onAction="#generateLowerCase" text="生成" HBox.hgrow="NEVER">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
</Button>
<TextField fx:id="lowerCaseResult" editable="false" promptText="结果" HBox.hgrow="ALWAYS">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
</TextField>
</HBox>
<HBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="47.0" prefWidth="599.0"
VBox.vgrow="NEVER">
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</padding>
<Label text="大写字母" HBox.hgrow="NEVER">
<HBox.margin>
<Insets top="5.0"/>
</HBox.margin>
</Label>
<TextField fx:id="upperCaseLength" prefHeight="27.0" prefWidth="82.0" promptText="长度" HBox.hgrow="NEVER">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
</TextField>
<Button mnemonicParsing="false" onAction="#generateUpperCase" text="生成" HBox.hgrow="NEVER">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
</Button>
<TextField fx:id="upperCaseResult" editable="false" promptText="结果" HBox.hgrow="ALWAYS">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
</TextField>
</HBox>
<HBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="47.0" prefWidth="599.0"
VBox.vgrow="NEVER">
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</padding>
<Label text="字母(包含大小写)" HBox.hgrow="NEVER">
<HBox.margin>
<Insets top="5.0"/>
</HBox.margin>
</Label>
<TextField fx:id="letterLength" prefHeight="27.0" prefWidth="82.0" promptText="长度" HBox.hgrow="NEVER">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
</TextField>
<Button mnemonicParsing="false" onAction="#generateLetter" text="生成" HBox.hgrow="NEVER">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
</Button>
<TextField fx:id="letterResult" editable="false" promptText="结果" HBox.hgrow="ALWAYS">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
</TextField>
</HBox>
<HBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="47.0" prefWidth="599.0">
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</padding>
<Label text="无符号字符(只有字母和数字)" HBox.hgrow="NEVER">
<HBox.margin>
<Insets top="5.0"/>
</HBox.margin>
</Label>
<TextField fx:id="stringLength" prefHeight="27.0" prefWidth="82.0" promptText="长度" HBox.hgrow="NEVER">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
</TextField>
<Button mnemonicParsing="false" onAction="#generateString" text="生成" HBox.hgrow="NEVER">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
</Button>
<TextField fx:id="stringResult" editable="false" promptText="结果" HBox.hgrow="ALWAYS">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
</TextField>
</HBox>
<HBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="47.0" prefWidth="599.0">
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</padding>
<Label text="字符(包含字母/数字/符号)" HBox.hgrow="NEVER">
<HBox.margin>
<Insets top="5.0"/>
</HBox.margin>
</Label>
<TextField fx:id="textLength" prefHeight="27.0" prefWidth="82.0" promptText="长度" HBox.hgrow="NEVER">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
</TextField>
<Button mnemonicParsing="false" onAction="#generateText" text="生成" HBox.hgrow="NEVER">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
</Button>
<TextField fx:id="textResult" editable="false" promptText="结果" HBox.hgrow="ALWAYS">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
</TextField>
</HBox>
</VBox>
... ...
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>
<?import javafx.scene.chart.AreaChart?>
<?import javafx.scene.chart.CategoryAxis?>
<?import javafx.scene.chart.NumberAxis?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<VBox prefHeight="500.0" prefWidth="750.0" xmlns="http://javafx.com/javafx/9" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="com.zhazhapan.util.visual.controller.WaveController">
<HBox prefHeight="37.0" prefWidth="600.0" VBox.vgrow="NEVER">
<VBox.margin>
<Insets/>
</VBox.margin>
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</padding>
<ComboBox fx:id="tableCombo" maxWidth="200.0" prefWidth="150.0" HBox.hgrow="ALWAYS"/>
<Label text="开始日期" HBox.hgrow="NEVER">
<HBox.margin>
<Insets left="10.0" top="5.0"/>
</HBox.margin>
</Label>
<DatePicker fx:id="startDate" onAction="#getWaveDataToLineChart" HBox.hgrow="NEVER"
onKeyReleased="#getWaveDataToLineChart">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
</DatePicker>
<Label text="截止日期" HBox.hgrow="NEVER">
<HBox.margin>
<Insets left="10.0" top="5.0"/>
</HBox.margin>
</Label>
<DatePicker fx:id="endDate" onAction="#getWaveDataToLineChart" HBox.hgrow="NEVER"
onKeyReleased="#getWaveDataToLineChart">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
</DatePicker>
<Button mnemonicParsing="false" onAction="#getWaveDataToLineChart" text="刷新" HBox.hgrow="NEVER">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
</Button>
</HBox>
<AreaChart fx:id="chart" maxHeight="600.0" maxWidth="1.7976931348623157E308" VBox.vgrow="ALWAYS">
<xAxis>
<CategoryAxis side="BOTTOM"/>
</xAxis>
<yAxis>
<NumberAxis side="LEFT"/>
</yAxis>
<VBox.margin>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</VBox.margin>
</AreaChart>
<HBox prefHeight="32.0" prefWidth="750.0">
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</padding>
<ComboBox fx:id="crudMethod" prefWidth="150.0" HBox.hgrow="NEVER"/>
<DatePicker fx:id="sqlDate" onAction="#generateSql" HBox.hgrow="NEVER" onKeyReleased="#generateSql">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
</DatePicker>
<TextField fx:id="sqlNumber" onKeyReleased="#generateSql" prefHeight="27.0" prefWidth="78.0"
promptText="波动数" text="0" HBox.hgrow="NEVER">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
</TextField>
<TextField fx:id="sql" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
promptText="SQL, 支持变量" HBox.hgrow="ALWAYS">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
</TextField>
<Button mnemonicParsing="false" onAction="#executeSql" text="执行" HBox.hgrow="NEVER">
<HBox.margin>
<Insets left="10.0"/>
</HBox.margin>
</Button>
</HBox>
</VBox>
... ...
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<VBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="500.0" minWidth="600.0"
xmlns="http://javafx.com/javafx/9" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="com.zhazhapan.util.visual.controller.MainController">
<MenuBar VBox.vgrow="NEVER">
<Menu mnemonicParsing="false" text="文件">
<MenuItem mnemonicParsing="false" onAction="#openFile" text="打开"/>
<MenuItem mnemonicParsing="false" onAction="#openMultiFile" text="批量打开"/>
<MenuItem mnemonicParsing="false" onAction="#saveFile" text="保存"/>
<!--<MenuItem mnemonicParsing="false" text="设置"/>-->
<MenuItem mnemonicParsing="false" onAction="#openAllTab" text="打开所有标签"/>
<MenuItem mnemonicParsing="false" onAction="#closeAllTab" text="关闭所有标签"/>
<MenuItem mnemonicParsing="false" onAction="#quit" text="退出"/>
</Menu>
<Menu mnemonicParsing="false" text="工具">
<MenuItem mnemonicParsing="false" onAction="#openJsonParserTab" text="JSON解析"/>
<MenuItem mnemonicParsing="false" onAction="#openFileManagerTab" text="文件批处理"/>
<MenuItem mnemonicParsing="false" onAction="#openRandomGeneratorTab" text="随机生成器"/>
<MenuItem mnemonicParsing="false" onAction="#openClipboardHistoryTab" text="剪贴板历史"/>
<MenuItem mnemonicParsing="false" onAction="#openQrCodeGeneratorTab" text="二维码生成器"/>
<MenuItem mnemonicParsing="false" onAction="#openCharsetConverterTab" text="编码转换器"/>
<MenuItem mnemonicParsing="false" onAction="#openNetworkToolTab" text="网络工具"/>
<MenuItem mnemonicParsing="false" onAction="#openQiniuToolTab" text="七牛云对象存储"/>
<MenuItem mnemonicParsing="false" onAction="#openWaveViewerTab" text="波动图表"/>
<Menu mnemonicParsing="false" text="外部工具">
<MenuItem mnemonicParsing="false" onAction="#openColorPicker" text="取色器"/>
<MenuItem mnemonicParsing="false" onAction="#openWox" text="效率工具"/>
</Menu>
</Menu>
<Menu mnemonicParsing="false" text="帮助">
<MenuItem mnemonicParsing="false" onAction="#about" text="关于"/>
</Menu>
</MenuBar>
<TabPane fx:id="tabPane" VBox.vgrow="ALWAYS"/>
<HBox prefHeight="32.0" prefWidth="600.0" VBox.vgrow="NEVER">
<padding>
<Insets left="10.0" right="10.0" top="10.0" bottom="5.0"/>
</padding>
<Label text="USED JVM MEMORY: " HBox.hgrow="NEVER"/>
<ProgressBar fx:id="jvm" maxWidth="1.7976931348623157E308" prefWidth="200.0" progress="0.0"
HBox.hgrow="ALWAYS"/>
</HBox>
</VBox>
... ...