commit 6cb6bb705f14fd21ca401fe9bc59da71a9402798
Author: zm <1334717033@qq.com>
Date: Fri Mar 8 18:20:49 2024 +0800
2024年3月8日18:20:13
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..4dc7b69
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,164 @@
+
+
+ 4.0.0
+
+ com.zhangmeng
+ javafx-tools-minio
+ 1.0-SNAPSHOT
+
+
+ 17
+ 17
+ 19
+
+
+
+
+ io.minio
+ minio
+ 8.5.7
+
+
+
+ com.squareup.okhttp3
+ okhttp
+ 4.8.1
+
+
+
+ org.projectlombok
+ lombok
+ 1.18.30
+
+
+
+ org.apache.commons
+ commons-lang3
+ 3.11
+
+
+
+ org.openjfx
+ javafx-controls
+ ${javafx.version}
+
+
+
+ org.openjfx
+ javafx-base
+ ${javafx.version}
+
+
+
+ org.openjfx
+ javafx-graphics
+ ${javafx.version}
+
+
+
+ org.openjfx
+ javafx-fxml
+ ${javafx.version}
+
+
+
+ org.openjfx
+ javafx-web
+ ${javafx.version}
+
+
+
+ org.openjfx
+ javafx-media
+ ${javafx.version}
+
+
+
+
+ org.openjfx
+ javafx-swing
+ ${javafx.version}
+
+
+
+ com.github.leewyatt
+ rxcontrols
+
+ 11.0.2
+
+
+
+ com.fasterxml.jackson.core
+ jackson-core
+ 2.16.1
+
+
+
+ com.google.guava
+ guava
+ 30.1-jre
+
+
+ log4j
+ log4j
+ 1.2.17
+
+
+ org.apache.tika
+ tika-core
+ 1.27
+
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 3.1.0
+
+
+
+ true
+ lib/
+ com.zhangmeng.minio.MiniToolsApplication
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+ 3.1.1
+
+
+ copy-dependencies
+ package
+
+ copy-dependencies
+
+
+ ${project.build.directory}/lib
+
+
+
+
+
+
+
+
+
+ jitpack.io
+ https://jitpack.io
+
+
+ zm
+ http://123.57.75.116:49000/repository/zm/
+
+
+
\ No newline at end of file
diff --git a/src/main/java/com/zhangmeng/minio/MiniToolsApplication.java b/src/main/java/com/zhangmeng/minio/MiniToolsApplication.java
new file mode 100644
index 0000000..0a9da57
--- /dev/null
+++ b/src/main/java/com/zhangmeng/minio/MiniToolsApplication.java
@@ -0,0 +1,64 @@
+package com.zhangmeng.minio;
+
+import com.google.common.eventbus.Subscribe;
+import com.zhangmeng.minio.controller.MinioController;
+import com.zhangmeng.minio.message.Message;
+import com.zhangmeng.minio.utils.ConfigUtils;
+import com.zhangmeng.minio.utils.EventBusUtils;
+import com.zhangmeng.minio.utils.MinioUtils;
+import javafx.application.Application;
+import javafx.fxml.FXMLLoader;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.stage.Stage;
+import lombok.extern.log4j.Log4j;
+import org.apache.log4j.Logger;
+import org.apache.log4j.spi.LoggerFactory;
+
+/**
+ * @author zhangmeng
+ * @version 1.0
+ * @date 2024-03-07 14:24
+ */
+public class MiniToolsApplication extends Application {
+
+ @Override
+ public void start(Stage primaryStage) throws Exception {
+
+ MinioUtils.objectMap.put(MinioUtils.primaryStage,primaryStage);
+
+ Parent root = FXMLLoader.load(this.getClass().getResource("/fxml/main.fxml"));
+ primaryStage.setScene(new Scene(root));
+ primaryStage.setTitle("javafx minio 工具");
+ primaryStage.show();
+ }
+
+ @Override
+ public void init() throws Exception {
+ EventBusUtils.getDefault().register(this);
+ }
+
+ @Override
+ public void stop() throws Exception {
+ EventBusUtils.getDefault().unregister(this);
+ MinioController minioController = (MinioController) MinioUtils.objectMap.get(MinioUtils.minioController);
+ if (minioController != null){
+ EventBusUtils.getDefault().unregister(minioController);
+ System.out.println("EventBusUtils.getDefault().unregister(minioController)");
+ }
+ System.out.println("EventBusUtils.getDefault().unregister(MiniToolsApplication) ");
+ }
+
+ public static void main(String[] args) {
+ launch(args);
+ }
+
+ @Subscribe
+ public void handlerMessage(Message message){
+ System.out.println(message.getMsg());
+ MinioController minioController = (MinioController) MinioUtils.objectMap.get(MinioUtils.minioController);
+ minioController.reload();
+
+ ConfigUtils.getDefaultConfig();
+ }
+}
diff --git a/src/main/java/com/zhangmeng/minio/controller/BucketChooseController.java b/src/main/java/com/zhangmeng/minio/controller/BucketChooseController.java
new file mode 100644
index 0000000..6fc4a0c
--- /dev/null
+++ b/src/main/java/com/zhangmeng/minio/controller/BucketChooseController.java
@@ -0,0 +1,59 @@
+package com.zhangmeng.minio.controller;
+
+import com.zhangmeng.minio.message.Message;
+import com.zhangmeng.minio.utils.AlertUtils;
+import com.zhangmeng.minio.utils.EventBusUtils;
+import com.zhangmeng.minio.utils.MinioUtils;
+import io.minio.MinioClient;
+import io.minio.messages.Bucket;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.control.ComboBox;
+import javafx.stage.Stage;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.List;
+
+/**
+ * @author zhangmeng
+ * @version 1.0
+ * @date 2024-03-07 15:40
+ */
+public class BucketChooseController {
+
+ @FXML
+ public ComboBox comboBox;
+
+ private final ObservableList list = FXCollections.observableArrayList();
+
+ @FXML
+ public void initialize() {
+ //获取所有储存桶
+ List buckets = MinioUtils.getAllBuckets();
+ if (buckets.size()>0){
+ for (Bucket bucket : buckets) {
+ list.add(bucket.name());
+ }
+ }
+ comboBox.setItems(list);
+ }
+
+ @FXML
+ public void save_choose(ActionEvent actionEvent) {
+
+ String selectedItem = comboBox.getSelectionModel().getSelectedItem();
+ if (selectedItem == null ){
+ AlertUtils.alert_warning("请选择储存桶再试!");
+ return;
+ }
+ MinioUtils.objectMap.put(MinioUtils.current_bucket,selectedItem);
+ Stage stage = (Stage) MinioUtils.objectMap.get(MinioUtils.bucket_choose_action_stage);
+ stage.close();
+
+ EventBusUtils.getDefault().post(new Message("save_choose ............."));
+ }
+}
diff --git a/src/main/java/com/zhangmeng/minio/controller/BucketFileCell.java b/src/main/java/com/zhangmeng/minio/controller/BucketFileCell.java
new file mode 100644
index 0000000..0335fac
--- /dev/null
+++ b/src/main/java/com/zhangmeng/minio/controller/BucketFileCell.java
@@ -0,0 +1,93 @@
+package com.zhangmeng.minio.controller;
+
+import com.zhangmeng.minio.model.BucketFile;
+import com.zhangmeng.minio.utils.AlertUtils;
+import com.zhangmeng.minio.utils.MinioUtils;
+import javafx.collections.ObservableMap;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.fxml.FXMLLoader;
+import javafx.geometry.Pos;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.scene.control.*;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.Region;
+import javafx.scene.text.Text;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+import javafx.stage.StageStyle;
+import javafx.stage.Window;
+
+import java.io.IOException;
+
+/**
+ * @author zhangmeng
+ * @version 1.0
+ * @date 2024-03-07 16:30
+ */
+public class BucketFileCell extends ListCell {
+
+ private final Label label;
+ private final BorderPane pane;
+
+ public BucketFileCell() {
+ pane = new BorderPane();
+ label = new Label();
+ BorderPane.setAlignment(label, Pos.CENTER_LEFT);
+ Button button = new Button();
+ button.getStyleClass().add("remove-btn");
+ button.setGraphic(new Region());
+ button.setOnAction(event -> {
+
+ try {
+ FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/alert.fxml"));
+ Parent root = fxmlLoader.load();
+ ObservableMap namespace = fxmlLoader.getNamespace();
+ Button yes = (Button) namespace.get("yes");
+ Button cancel = (Button) namespace.get("cancel");
+
+ Stage stage = AlertUtils.alert("文件删除",root,396,200, (Stage) MinioUtils.objectMap.get(MinioUtils.primaryStage));
+
+ yes.setOnAction(new EventHandler() {
+ @Override
+ public void handle(ActionEvent event) {
+ if (getItem() == getListView().getSelectionModel().getSelectedItem()) {
+ getListView().getSelectionModel().clearSelection();
+ }
+ getListView().getItems().remove(getItem());
+ stage.close();
+ }
+ });
+
+ cancel.setOnAction(new EventHandler() {
+ @Override
+ public void handle(ActionEvent event) {
+ stage.close();
+ }
+ });
+
+
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ });
+ pane.setCenter(label);
+ pane.setRight(button);
+ }
+
+ @Override
+ protected void updateItem(BucketFile item, boolean empty) {
+ super.updateItem(item, empty);
+ if (item == null || empty) {
+ setGraphic(null);
+ setText("");
+ } else {
+ String name = item.getFileName();
+ label.setText(name.substring(0, name.length() - 4) );
+ setGraphic(pane);
+ }
+
+ }
+}
diff --git a/src/main/java/com/zhangmeng/minio/controller/MinioController.java b/src/main/java/com/zhangmeng/minio/controller/MinioController.java
new file mode 100644
index 0000000..a93ce8c
--- /dev/null
+++ b/src/main/java/com/zhangmeng/minio/controller/MinioController.java
@@ -0,0 +1,333 @@
+package com.zhangmeng.minio.controller;
+
+import com.google.common.reflect.ClassPath;
+import com.zhangmeng.minio.model.BucketFile;
+import com.zhangmeng.minio.utils.AlertUtils;
+import com.zhangmeng.minio.utils.EventBusUtils;
+import com.zhangmeng.minio.utils.MinioUtils;
+import io.minio.messages.Bucket;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.collections.ObservableMap;
+import javafx.fxml.FXML;
+import javafx.fxml.FXMLLoader;
+import javafx.scene.control.*;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.KeyCodeCombination;
+import javafx.scene.input.KeyCombination;
+import javafx.scene.layout.AnchorPane;
+import javafx.stage.FileChooser;
+import javafx.stage.Stage;
+import org.apache.commons.lang3.ClassPathUtils;
+
+import java.io.*;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * @author zhangmeng
+ * @version 1.0
+ * @date 2024-03-07 15:29
+ */
+public class MinioController {
+
+ @FXML
+ public ListView listView;
+
+ @FXML
+ public AnchorPane center;
+
+ private final ObservableList list = FXCollections.observableArrayList();
+
+ @FXML
+ public MenuItem config_file;
+
+ @FXML
+ public MenuItem bucket_choose;
+
+ @FXML
+ public MenuItem reload_config;
+
+ @FXML
+ public Button upload;
+
+ @FXML
+ public Button choose_upload_file;
+
+ @FXML
+ public TextField upload_path;
+
+ @FXML
+ public TextField bucket_name;
+
+ @FXML
+ public Button bucket_btn;
+
+ @FXML
+ public TextField endpoint;
+
+ @FXML
+ public TextField accessKey;
+
+ @FXML
+ public TextField secretKey;
+
+ @FXML
+ public Button save_config;
+
+ @FXML
+ public ComboBox backet_list;
+
+ private final ObservableList backet_item_list = FXCollections.observableArrayList();
+
+ private File upload_file;
+
+ public MinioController() {
+ EventBusUtils.getDefault().register(this);
+ }
+
+ @FXML
+ public void initialize() {
+ listView.setItems(list);
+ listView.setCellFactory(fileListView -> new BucketFileCell());
+
+ //绑定快捷键
+ KeyCombination kc1 = KeyCombination.valueOf("ctrl+q");
+ config_file.setAccelerator(kc1);
+ config_file.setOnAction(event -> {
+ FileInputStream fileInputStream = null;
+ try {
+ FXMLLoader fxmlLoader = new FXMLLoader(this.getClass().getResource("/fxml/config.fxml"));
+ AnchorPane root = fxmlLoader.load();
+ ObservableMap namespace = fxmlLoader.getNamespace();
+ TextArea text_area = (TextArea) namespace.get("text_area");
+ Button save_p = (Button) namespace.get("save_p");
+ URL resource = this.getClass().getResource("/minio.properties");
+ fileInputStream = new FileInputStream(new File(resource.getFile()));
+ byte[] bytes = fileInputStream.readAllBytes();
+ text_area.setText(new String(bytes, StandardCharsets.UTF_8));
+ Stage stage = AlertUtils.alert("minio 配置文件",root,600,410,(Stage) MinioUtils.objectMap.get(MinioUtils.primaryStage));
+ save_p.setOnAction(event1 -> {
+ stage.close();
+ try {
+ FileWriter fileWriter = new FileWriter(resource.getFile());
+ fileWriter.write(text_area.getText());
+ fileWriter.flush();
+ fileWriter.close();
+ load_property();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ AlertUtils.alert_msg("保存成功!");
+ });
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ if (fileInputStream != null){
+ try {
+ fileInputStream.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ }
+ });
+
+ KeyCombination kc2 = KeyCombination.valueOf("ctrl+r");
+ reload_config.setAccelerator(kc2);
+
+ KeyCombination kc3 = KeyCombination.valueOf("ctrl+b");
+ bucket_choose.setAccelerator(kc3);
+ MinioUtils.objectMap.put(MinioUtils.minioController,this);
+
+ choose_upload_file.setOnAction(event -> {
+ //打开文件
+ Stage stage = new Stage();
+ FileChooser dc = new FileChooser();
+ dc.setTitle("文件选择");
+ dc.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("文件类型", "*.*"));
+ File file = dc.showOpenDialog(stage);
+ if (file != null){
+ //展示路径
+ upload_file = file;
+ upload_path.setText(file.getAbsolutePath());
+ }
+ });
+
+ upload.setOnAction(event -> {
+
+ if (upload_file == null){
+ AlertUtils.alert_warning("请选择上传的文件后再试!");
+ return;
+ }
+
+ MinioUtils.upload_file(upload_file);
+ });
+
+ bucket_btn.setOnAction(event -> {
+
+ if (endpoint.getText().length() == 0 ){
+ AlertUtils.alert_warning("endpoint 不能为空!");
+ return;
+ }
+
+ if (accessKey.getText().length() == 0 ){
+ AlertUtils.alert_warning("accessKey 不能为空!");
+ return;
+ }
+ if (secretKey.getText().length() == 0 ){
+ AlertUtils.alert_warning("secretKey 不能为空!");
+ return;
+ }
+
+ if (bucket_name.getText().length() == 0 ){
+ AlertUtils.alert_warning("bucket_name 不能为空!");
+ return;
+ }
+ MinioUtils.createBucket(bucket_name.getText());
+ });
+
+ load_property();
+
+ save_config.setOnAction(event -> save_properties());
+
+ backet_list.getSelectionModel().selectedItemProperty().addListener(new ChangeListener() {
+ @Override
+ public void changed(ObservableValue extends String> observable, String oldValue, String newValue) {
+ if (newValue != null){
+ MinioUtils.objectMap.put(MinioUtils.current_bucket,newValue);
+ reload();
+ }
+ }
+ });
+ }
+
+ public void save_properties(){
+
+ if (endpoint.getText().length() == 0 ){
+ AlertUtils.alert_warning("endpoint 不能为空!");
+ return;
+ }
+
+ if (accessKey.getText().length() == 0 ){
+ AlertUtils.alert_warning("accessKey 不能为空!");
+ return;
+ }
+ if (secretKey.getText().length() == 0 ){
+ AlertUtils.alert_warning("secretKey 不能为空!");
+ return;
+ }
+
+ // 创建一个Properties对象
+ Properties properties = new Properties();
+ URL resource = this.getClass().getResource("/minio.properties");
+ if (resource != null){
+ InputStream input = null;
+ OutputStream output = null;
+ try {
+ String file = resource.getFile();
+ input = new FileInputStream(new File(file));
+ output = new FileOutputStream(new File(file));
+ // load a properties file
+ properties.load(input);
+ properties.put("endpoint",this.endpoint.getText());
+ properties.put("accessKey",this.accessKey.getText());
+ properties.put("secretKey",this.secretKey.getText());
+ properties.store(output,"save");
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ if (input != null) {
+ try {
+ input.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ if (output != null){
+ try {
+ output.close();
+ }catch (IOException e){
+ e.printStackTrace();
+ }
+ }
+ }
+ load_property();
+ AlertUtils.alert_warning("配置文件保存成功!");
+ }
+ }
+
+ public void load_property(){
+ Properties prop = new Properties();
+ URL resource = this.getClass().getResource("/minio.properties");
+ if (resource != null){
+ String file = resource.getFile();
+ InputStream input = null;
+ try {
+ input = new FileInputStream(new File(file));
+ // load a properties file
+ prop.load(input);
+ // get the property value and print it out
+ String endpoint = prop.getProperty("endpoint");
+ this.endpoint.setText(endpoint);
+ String accessKey = prop.getProperty("accessKey");
+ this.accessKey.setText(accessKey);
+ String secretKey = prop.getProperty("secretKey");
+ this.secretKey.setText(secretKey);
+
+ MinioUtils.objectMap.put("endpoint",endpoint);
+ MinioUtils.objectMap.put("accessKey",accessKey);
+ MinioUtils.objectMap.put("secretKey",secretKey);
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ } finally {
+ if (input != null) {
+ try {
+ input.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ //获取所有储存桶
+ List buckets = MinioUtils.getAllBuckets();
+ if (buckets.size()>0){
+ for (Bucket bucket : buckets) {
+ backet_item_list.add(bucket.name());
+ }
+ }
+ this.backet_list.setItems(backet_item_list);
+ }
+
+ @FXML
+ private void bucket_choose_action(){
+ Stage primaryStage = (Stage) this.listView.getScene().getWindow();
+ FXMLLoader fxmlLoader =new FXMLLoader( getClass().getResource("/fxml/bucket_choose.fxml"));
+ AnchorPane bucket_choose = null;
+ try {
+ bucket_choose = fxmlLoader.load();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ Stage stage = AlertUtils.alert("设置", bucket_choose, primaryStage);
+ MinioUtils.objectMap.put(MinioUtils.bucket_choose_action_stage,stage);
+ }
+
+ @FXML
+ public void reload(){
+ String bucketName = MinioUtils.objectMap.get(MinioUtils.current_bucket).toString();
+ List bucketFiles = MinioUtils.getFileList(bucketName);
+ if (bucketFiles.size()>0){
+ list.clear();
+ list.addAll(bucketFiles);
+ }
+ }
+}
diff --git a/src/main/java/com/zhangmeng/minio/message/Message.java b/src/main/java/com/zhangmeng/minio/message/Message.java
new file mode 100644
index 0000000..ef890c1
--- /dev/null
+++ b/src/main/java/com/zhangmeng/minio/message/Message.java
@@ -0,0 +1,23 @@
+package com.zhangmeng.minio.message;
+
+/**
+ * @author zhangmeng
+ * @version 1.0
+ * @date 2024-03-08 10:19
+ */
+public class Message {
+
+ private String msg ;
+
+ public Message(String msg) {
+ this.msg = msg;
+ }
+
+ public String getMsg() {
+ return msg;
+ }
+
+ public void setMsg(String msg) {
+ this.msg = msg;
+ }
+}
diff --git a/src/main/java/com/zhangmeng/minio/model/BucketFile.java b/src/main/java/com/zhangmeng/minio/model/BucketFile.java
new file mode 100644
index 0000000..ee5ce33
--- /dev/null
+++ b/src/main/java/com/zhangmeng/minio/model/BucketFile.java
@@ -0,0 +1,19 @@
+package com.zhangmeng.minio.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+/**
+ * @author zhangmeng
+ * @version 1.0
+ * @date 2024-03-07 16:31
+ */
+@Data
+public class BucketFile {
+
+ private String bucketName;
+ private String fileName;
+ private boolean isDir;
+ private Long size;
+ private String url;
+}
diff --git a/src/main/java/com/zhangmeng/minio/utils/AlertUtils.java b/src/main/java/com/zhangmeng/minio/utils/AlertUtils.java
new file mode 100644
index 0000000..d3d01e1
--- /dev/null
+++ b/src/main/java/com/zhangmeng/minio/utils/AlertUtils.java
@@ -0,0 +1,83 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2023 芊芊墨客
+ *
+ * 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.
+ *
+ */
+
+package com.zhangmeng.minio.utils;
+
+import javafx.fxml.FXMLLoader;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.scene.control.Alert;
+import javafx.scene.layout.AnchorPane;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+import javafx.stage.StageStyle;
+import javafx.stage.Window;
+
+import java.io.IOException;
+
+/**
+ * @author : 芊芊墨客
+ * @version : 1.0
+ * @date : 2023-02-17 09:59
+ */
+public class AlertUtils {
+
+ /**
+ * 警告弹窗
+ */
+ public static void alert_warning(String msg) {
+ Alert alert = new Alert(Alert.AlertType.WARNING);
+ alert.initModality(Modality.APPLICATION_MODAL);
+ alert.setContentText(msg);
+ alert.setHeaderText(null);
+ alert.show();
+ }
+
+ public static void alert_msg(String msg) {
+ Alert alert = new Alert(Alert.AlertType.INFORMATION);
+ alert.initModality(Modality.APPLICATION_MODAL);
+ alert.setContentText(msg);
+ alert.setHeaderText(null);
+ alert.show();
+ }
+
+ public static Stage alert(String title, Parent node, Stage primaryStage){
+ return alert(title,node,600,400,primaryStage);
+ }
+ public static Stage alert(String title, Parent node, int width, int height, Stage primaryStage) {
+ Scene scene = new Scene(node);
+ Stage stage = new Stage();
+ stage.setScene(scene);
+ stage.setTitle(title);
+ stage.setWidth(width);
+ stage.setHeight(height);
+ stage.initStyle(StageStyle.UTILITY);
+ stage.initOwner(primaryStage);
+ stage.initModality(Modality.APPLICATION_MODAL);
+ stage.setResizable(false);
+ stage.show();
+ return stage;
+ }
+}
diff --git a/src/main/java/com/zhangmeng/minio/utils/ConfigUtils.java b/src/main/java/com/zhangmeng/minio/utils/ConfigUtils.java
new file mode 100644
index 0000000..194fca4
--- /dev/null
+++ b/src/main/java/com/zhangmeng/minio/utils/ConfigUtils.java
@@ -0,0 +1,64 @@
+package com.zhangmeng.minio.utils;
+
+
+import org.apache.commons.configuration2.Configuration;
+import org.apache.commons.configuration2.ex.ConfigurationException;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+/**
+ * @author zhangmeng
+ * @version 1.0
+ * @date 2024-03-08 14:17
+ */
+public class ConfigUtils {
+
+ public static void getDefaultConfig(){
+
+
+ }
+
+ public static class MinioConfig {
+
+ private String endpoint;
+ private String accessKey;
+ private String secretKey;
+
+ public MinioConfig() {
+ }
+
+ public MinioConfig(String endpoint, String accessKey, String secretKey) {
+ this.endpoint = endpoint;
+ this.accessKey = accessKey;
+ this.secretKey = secretKey;
+ }
+
+ public String getEndpoint() {
+ return endpoint;
+ }
+
+ public void setEndpoint(String endpoint) {
+ this.endpoint = endpoint;
+ }
+
+ public String getAccessKey() {
+ return accessKey;
+ }
+
+ public void setAccessKey(String accessKey) {
+ this.accessKey = accessKey;
+ }
+
+ public String getSecretKey() {
+ return secretKey;
+ }
+
+ public void setSecretKey(String secretKey) {
+ this.secretKey = secretKey;
+ }
+ }
+}
diff --git a/src/main/java/com/zhangmeng/minio/utils/EventBusUtils.java b/src/main/java/com/zhangmeng/minio/utils/EventBusUtils.java
new file mode 100644
index 0000000..a328cb0
--- /dev/null
+++ b/src/main/java/com/zhangmeng/minio/utils/EventBusUtils.java
@@ -0,0 +1,21 @@
+package com.zhangmeng.minio.utils;
+
+import com.google.common.eventbus.EventBus;
+
+/**
+ * @author zhangmeng
+ * @version 1.0
+ * @date 2024-03-08 10:00
+ */
+public class EventBusUtils {
+
+ private EventBusUtils (){
+
+ }
+
+ private final static EventBus EVENT_BUS = new EventBus();
+
+ public static EventBus getDefault(){
+ return EVENT_BUS;
+ }
+}
diff --git a/src/main/java/com/zhangmeng/minio/utils/MinioUtils.java b/src/main/java/com/zhangmeng/minio/utils/MinioUtils.java
new file mode 100644
index 0000000..38f694d
--- /dev/null
+++ b/src/main/java/com/zhangmeng/minio/utils/MinioUtils.java
@@ -0,0 +1,202 @@
+package com.zhangmeng.minio.utils;
+
+import com.google.common.io.Files;
+import com.zhangmeng.minio.model.BucketFile;
+import io.minio.*;
+import io.minio.http.Method;
+import io.minio.messages.Bucket;
+import io.minio.messages.Item;
+import javafx.application.Platform;
+import javafx.scene.control.TextField;
+import lombok.SneakyThrows;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.tika.Tika;
+import org.apache.tika.exception.TikaException;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * @author zhangmeng
+ * @version 1.0
+ * @date 2024-03-07 15:45
+ */
+public class MinioUtils {
+
+ private static MinioClient minioClient = null;
+
+ private static String endpoint = "http://192.168.1.254:9000";
+ private static String accessKey = "minioadmin";
+ private static String secretKey = "minioadmin";
+
+ public static Map objectMap = new HashMap<>();
+ public static String current_bucket = "current_bucket";
+ public static String primaryStage = "primaryStage";
+ public static String bucket_choose_action_stage = "bucket_choose_action_stage";
+ public static String minioController = "minioController";
+
+ public static MinioClient getDefault() {
+ if (minioClient == null) {
+ minioClient = MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey).build();
+ }
+ return minioClient;
+ }
+
+ /**
+ * 获得所有Bucket列表
+ *
+ * @return
+ */
+ @SneakyThrows(Exception.class)
+ public static List getAllBuckets() {
+ return getDefault().listBuckets();
+ }
+
+ /**
+ * 启动SpringBoot容器的时候初始化Bucket
+ * 如果没有Bucket则创建
+ *
+ * @param bucketName
+ */
+ @SneakyThrows(Exception.class)
+ public static void createBucket(String bucketName) {
+ if (!bucketExists(bucketName)) {
+ getDefault().makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
+ }else {
+ Platform.runLater(()->{
+ AlertUtils.alert_warning("bucket_name : "+ bucketName + "已存在");
+ });
+ }
+ }
+
+ /**
+ * 判断Bucket是否存在,true:存在,false:不存在
+ *
+ * @param bucketName
+ * @return
+ */
+ @SneakyThrows(Exception.class)
+ public static boolean bucketExists(String bucketName) {
+ return getDefault().bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
+ }
+
+ public String DateFormatString(ZonedDateTime zonedDateTime){
+ // 创建一个 DateTimeFormatter 对象,用于定义日期和时间的格式
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+ // 使用 formatter 来格式化 ZonedDateTime 对象
+ return zonedDateTime.format(formatter);
+ }
+
+ /**
+ * 根据文件前置查询文件
+ *
+ * @param bucketName 存储桶
+ * @param prefix 前缀
+ * @param recursive 是否使用递归查询
+ * @return MinioItem 列表
+ */
+ @SneakyThrows(Exception.class)
+ public static List- getAllObjectsByPrefix(String bucketName,
+ String prefix,
+ boolean recursive) {
+ List
- list = new ArrayList<>();
+ Iterable> objectsIterator = getDefault().listObjects(
+ ListObjectsArgs.builder().bucket(bucketName).prefix(prefix).recursive(recursive).build());
+ if (objectsIterator != null) {
+ for (Result
- o : objectsIterator) {
+ Item item = o.get();
+ list.add(item);
+ }
+ }
+ return list;
+ }
+
+ /**
+ * 获得文件外链
+ *
+ * @param bucketName
+ * @param objectName
+ * @return url
+ */
+ @SneakyThrows(Exception.class)
+ public static String getPresignedObjectUrl(String bucketName, String objectName) {
+ GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs.builder()
+ .bucket(bucketName)
+ .object(objectName)
+ .method(Method.GET).build();
+ return getDefault() .getPresignedObjectUrl(args);
+ }
+
+ @SneakyThrows(Exception.class)
+ public static List getFileList(String bucketName){
+ List
- itemList = getAllObjectsByPrefix(bucketName, null, true);
+ List list = new ArrayList<>();
+ if (itemList.size() > 0 ){
+ list = itemList.stream().map(i -> {
+ BucketFile bucketFile = new BucketFile();
+ bucketFile.setDir(i.isDir());
+ bucketFile.setFileName(i.objectName());
+ bucketFile.setSize(i.size());
+ //获取url
+ String presignedObjectUrl = getPresignedObjectUrl(bucketName, i.objectName());
+ bucketFile.setUrl(presignedObjectUrl);
+ return bucketFile;
+ }).collect(Collectors.toList());
+ }
+ return list;
+ }
+
+ public static void upload_file(File file){
+ //文件名
+ String fileName = file.getName();
+ String newFileName = System.currentTimeMillis() + "." + StringUtils.substringAfterLast(fileName, ".");
+ String contentType = getContentType(file);
+ String bucketName = objectMap.get(current_bucket).toString();
+ if (bucketName == null){
+ AlertUtils.alert_warning("上传的bucket不能为空!");
+ return;
+ }
+ uploadFile(bucketName, file, newFileName, contentType);
+ }
+
+ /**
+ * 使用MultipartFile进行文件上传
+ *
+ * @param bucketName 存储桶
+ * @param file 文件名
+ * @param objectName 对象名
+ * @param contentType 类型
+ * @return
+ */
+ @SneakyThrows(Exception.class)
+ public static ObjectWriteResponse uploadFile(String bucketName, File file, String objectName, String contentType) {
+ FileInputStream inputStream = new FileInputStream(file);
+ return minioClient.putObject(
+ PutObjectArgs.builder()
+ .bucket(bucketName)
+ .object(objectName)
+ .contentType(contentType)
+ .stream(inputStream,inputStream.available(), -1)
+ .build());
+ }
+
+
+ public static String getContentType(File file){
+ Tika tika = new Tika();
+ try {
+ return tika.detect(file);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java
new file mode 100644
index 0000000..f8424a1
--- /dev/null
+++ b/src/main/java/module-info.java
@@ -0,0 +1,20 @@
+/**
+ * @author zhangmeng
+ * @date 2024-03-07 14:29
+ * @version 1.0
+ */
+
+open module javafx.tools.minio {
+ requires com.google.common;
+ requires javafx.controls;
+ requires javafx.media;
+ requires javafx.fxml;
+ requires rxcontrols;
+ requires minio;
+ requires lombok;
+ requires com.fasterxml.jackson.core;
+ requires log4j;
+ requires org.apache.commons.lang3;
+ requires tika.core;
+ requires org.apache.commons.configuration2;
+}
\ No newline at end of file
diff --git a/src/main/resources/css/main.css b/src/main/resources/css/main.css
new file mode 100644
index 0000000..c677768
--- /dev/null
+++ b/src/main/resources/css/main.css
@@ -0,0 +1,56 @@
+.root{
+ /*-fx-background-image: url(../img/sunset.jpg);*/
+ /*-fx-background-size: 1200;*/
+
+ -base-hover-color: #1ECE9A;
+}
+
+.split-pane{
+ /*-fx-background-image: url(../img/sunset.jpg);*/
+ -fx-background-size: 1200;
+ -fx-background-color: white;
+}
+
+.list-view{
+ -fx-font-size: 14;
+ -fx-focus-color: #0000;
+ -fx-faint-focus-color: #0000;
+ -fx-background-color: white;
+}
+
+.list-cell {
+ -fx-pref-height: 40;
+ -fx-background-color: null;
+}
+
+.list-cell:hover,
+.list-cell:selected {
+ -fx-background-color: #F8F8F8;
+}
+
+.list-cell:hover .label,
+.list-cell:selected .label {
+ -fx-text-fill: -base-hover-color;
+}
+
+.menu-bar{
+ -fx-background-color: #beebb6;
+ -fx-text-fill: black;
+}
+
+.list-cell .remove-btn {
+ -fx-background-color: null;
+ -fx-pref-height: 20;
+ -fx-pref-width: 38;
+ visibility: hidden;
+}
+
+.list-cell .remove-btn Region {
+ -fx-background-color: -base-hover-color;
+ -fx-shape: "M798.938839 1017.751676h-497.58838a120.584726 120.584726 0 0 1-123.951493-118.62903V274.661607a29.706769 29.706769 0 0 1 31.910021-29.186901 30.89504 30.89504 0 0 1 31.885265 29.186901v624.461039a60.131451 60.131451 0 0 0 62.01288 58.349045h497.58838a61.319722 61.319722 0 0 0 62.01288-58.349045V274.661607a29.706769 29.706769 0 0 1 31.885266-29.186901 30.919795 30.919795 0 0 1 31.910021 29.186901v624.461039a125.189275 125.189275 0 0 1-127.615329 118.62903z m-92.041472-178.933771a30.89504 30.89504 0 0 1-31.885266-29.186901V393.315393a29.855303 29.855303 0 0 1 31.885266-29.261168 30.919795 30.919795 0 0 1 31.910021 29.261168v416.241344a32.182333 32.182333 0 0 1-31.910021 29.36019z m-155.960537 0a30.89504 30.89504 0 0 1-31.885266-29.186901V393.315393a29.706769 29.706769 0 0 1 31.885266-29.261168 30.969307 30.969307 0 0 1 31.910021 29.261168v416.241344a30.919795 30.919795 0 0 1-31.786243 29.36019z m-155.960537 0a30.870284 30.870284 0 0 1-31.910021-29.186901V393.315393a29.706769 29.706769 0 0 1 31.910021-29.261168 30.969307 30.969307 0 0 1 31.910021 29.261168v416.241344a30.919795 30.919795 0 0 1-31.662465 29.36019zM1063.551883 214.431133H38.098975A30.89504 30.89504 0 0 1 6.188954 185.268988a29.706769 29.706769 0 0 1 31.910021-29.261168H332.963412V95.802102A91.37307 91.37307 0 0 1 426.886314 6.31046h247.878231a92.561341 92.561341 0 0 1 93.898145 89.491642v60.205718h294.889193a29.335434 29.335434 0 1 1 0 58.423313zM394.976293 154.225414h311.673517V93.920673a29.706769 29.706769 0 0 0-31.885265-29.162145H426.886314a30.89504 30.89504 0 0 0-31.910021 29.162145zM799.013106 1023.940586h-497.58838a126.253768 126.253768 0 0 1-130.115648-124.842696V274.661607a35.994702 35.994702 0 0 1 38.098931-35.375811 36.861149 36.861149 0 0 1 38.074176 35.375811v624.436283a54.165342 54.165342 0 0 0 55.82397 52.184891h497.58838a55.526902 55.526902 0 0 0 55.82397-52.184891V274.661607a35.994702 35.994702 0 0 1 38.098931-35.375811 36.836393 36.836393 0 0 1 38.074175 35.375811v624.436283a130.586005 130.586005 0 0 1-133.878505 124.842696z m-589.728875-772.375992a23.666393 23.666393 0 0 0-25.721111 22.99799V898.998867a113.875948 113.875948 0 0 0 117.737828 112.464877h497.58838a119.693523 119.693523 0 0 0 121.30264-112.61341V274.661607a24.755641 24.755641 0 0 0-25.696355-22.997991 23.666393 23.666393 0 0 0-25.721111 22.997991v624.436283a67.360099 67.360099 0 0 1-68.201791 64.562711h-497.58838a66.518407 66.518407 0 0 1-68.20179-64.562711V274.661607a24.755641 24.755641 0 0 0-25.49831-22.997991z m497.58838 593.343198a36.861149 36.861149 0 0 1-38.098931-35.37581V393.315393a36.019457 36.019457 0 0 1 38.098931-35.450078 36.885905 36.885905 0 0 1 38.074175 35.450078v416.241344a38.371243 38.371243 0 0 1-38.049419 35.375811z m0-474.689412a23.691148 23.691148 0 0 0-25.721111 23.072257v416.241345a24.755641 24.755641 0 0 0 25.696355 22.99799 25.8944 25.8944 0 0 0 25.745867-23.56737v-415.647209a24.755641 24.755641 0 0 0-25.696355-22.99799z m-155.960537 474.689412a36.861149 36.861149 0 0 1-38.098931-35.37581V393.315393a36.019457 36.019457 0 0 1 38.098931-35.450078 36.885905 36.885905 0 0 1 38.074175 35.450078v416.241344a36.836393 36.836393 0 0 1-37.925641 35.450078z m0-474.689412a23.691148 23.691148 0 0 0-25.721111 23.072257v416.241345a25.869645 25.869645 0 0 0 51.417466 0V393.315393a24.755641 24.755641 0 0 0-25.547821-22.99799z m-155.960537 474.689412a36.861149 36.861149 0 0 1-38.098931-35.37581V393.315393a36.019457 36.019457 0 0 1 38.098931-35.450078 36.91066 36.91066 0 0 1 38.098931 35.450078v416.241344a36.861149 36.861149 0 0 1-37.826619 35.450078z m0-474.689412a23.691148 23.691148 0 0 0-25.721111 23.072257v416.241345a25.8944 25.8944 0 0 0 51.442222 0V393.315393a24.755641 24.755641 0 0 0-25.448799-22.99799zM1063.502372 220.52102H38.049464A36.836393 36.836393 0 0 1-0.024712 185.169965a36.019457 36.019457 0 0 1 38.074176-35.450077H326.774502V95.678324a98.032338 98.032338 0 0 1 100.087056-95.655796h247.853476a99.27012 99.27012 0 0 1 100.111811 95.655796v54.041564H1063.502372a36.885905 36.885905 0 0 1 38.098931 35.450077 37.306751 37.306751 0 0 1-37.826619 35.450078zM38.049464 162.097708a23.666393 23.666393 0 0 0-25.696355 23.072257 24.755641 24.755641 0 0 0 25.696355 22.973235H1063.502372a23.17128 23.17128 0 1 0 0-46.045492H762.449025V95.678324A86.644743 86.644743 0 0 0 674.715034 12.400348H426.861558A85.679273 85.679273 0 0 0 339.152323 95.678324v66.419384z m674.764501-1.782406h-324.051338V93.821651a36.861149 36.861149 0 0 1 38.098931-35.375811h247.853476a36.019457 36.019457 0 0 1 38.098931 35.375811z m-311.673518-12.377821h299.295697V93.821651a23.666393 23.666393 0 0 0-25.72111-22.997991H426.861558a24.755641 24.755641 0 0 0-25.721111 22.997991z";
+}
+
+.list-cell:hover .remove-btn,
+.list-cell:selected .remove-btn {
+ visibility: visible;
+}
\ No newline at end of file
diff --git a/src/main/resources/fxml/alert.fxml b/src/main/resources/fxml/alert.fxml
new file mode 100644
index 0000000..40ce9b8
--- /dev/null
+++ b/src/main/resources/fxml/alert.fxml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/fxml/bucket_choose.fxml b/src/main/resources/fxml/bucket_choose.fxml
new file mode 100644
index 0000000..cf2e4a8
--- /dev/null
+++ b/src/main/resources/fxml/bucket_choose.fxml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/fxml/config.fxml b/src/main/resources/fxml/config.fxml
new file mode 100644
index 0000000..edbd63f
--- /dev/null
+++ b/src/main/resources/fxml/config.fxml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/fxml/main.fxml b/src/main/resources/fxml/main.fxml
new file mode 100644
index 0000000..5c17106
--- /dev/null
+++ b/src/main/resources/fxml/main.fxml
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/img/sunset.jpg b/src/main/resources/img/sunset.jpg
new file mode 100644
index 0000000..572d452
Binary files /dev/null and b/src/main/resources/img/sunset.jpg differ
diff --git a/src/main/resources/minio.properties b/src/main/resources/minio.properties
new file mode 100644
index 0000000..9872f70
--- /dev/null
+++ b/src/main/resources/minio.properties
@@ -0,0 +1,3 @@
+endpoint = http://192.168.1.254:9000
+accessKey = minioadmin
+secretKey = minioadmin
\ No newline at end of file