You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
266 lines
9.7 KiB
266 lines
9.7 KiB
package com.fr.design.gui.ifilechooser; |
|
|
|
|
|
import com.fr.design.i18n.Toolkit; |
|
import com.fr.design.mainframe.DesignerContext; |
|
import com.fr.log.FineLoggerFactory; |
|
import com.fr.stable.ArrayUtils; |
|
import com.fr.stable.StringUtils; |
|
import com.sun.javafx.application.PlatformImpl; |
|
import javafx.application.Platform; |
|
import javafx.scene.Scene; |
|
import javafx.scene.control.Label; |
|
import javafx.scene.layout.Background; |
|
import javafx.scene.layout.BackgroundFill; |
|
import javafx.scene.paint.Color; |
|
import javafx.stage.DirectoryChooser; |
|
import javafx.stage.FileChooser; |
|
import javafx.stage.Modality; |
|
import javafx.stage.Stage; |
|
import javafx.stage.StageStyle; |
|
|
|
import javax.swing.*; |
|
import java.awt.*; |
|
import java.io.File; |
|
import java.util.List; |
|
import java.util.concurrent.CountDownLatch; |
|
|
|
public class JavaFxNativeFileChooser implements FileChooserProvider { |
|
private static boolean showDialogState = false; |
|
private File[] selectedFiles = new File[0]; |
|
private FileSelectionMode fileSelectionMode = FileSelectionMode.FILE; |
|
private String title = Toolkit.i18nText("Fine-Design_Basic_Open"); |
|
private FileChooser.ExtensionFilter[] filters; |
|
private File currentDirectory; |
|
|
|
@Override |
|
public File[] getSelectedFiles() { |
|
return selectedFiles; |
|
} |
|
|
|
@Override |
|
public File getSelectedFile() { |
|
if (selectedFiles.length > 0) { |
|
return selectedFiles[0]; |
|
} |
|
return null; |
|
} |
|
|
|
public static boolean isShowDialogState() { |
|
return showDialogState; |
|
} |
|
|
|
public static void setShowDialogState(boolean showDialogState) { |
|
JavaFxNativeFileChooser.showDialogState = showDialogState; |
|
} |
|
|
|
@Override |
|
public int showDialog(Component parent) { |
|
setShowDialogState(true); |
|
final CountDownLatch latch = new CountDownLatch(1); |
|
PlatformImpl.startup(() -> { |
|
}); |
|
Platform.setImplicitExit(false); |
|
Platform.runLater(new Runnable() { |
|
@Override |
|
public void run() { |
|
Component fileChooserParent = parent; |
|
if (fileChooserParent == null) { |
|
fileChooserParent = DesignerContext.getDesignerFrame(); |
|
} |
|
Stage stage = showCoverStage(fileChooserParent); |
|
if (stage != null) { |
|
stage.setAlwaysOnTop(true); |
|
} |
|
try { |
|
if (fileSelectionMode == FileSelectionMode.FILE || fileSelectionMode == FileSelectionMode.MULTIPLE_FILE) { |
|
FileChooser fileChooser = new FileChooser(); |
|
fileChooser.setTitle(title); |
|
fileChooser.getExtensionFilters().addAll(filters); |
|
fileChooser.setInitialDirectory(currentDirectory); |
|
if (fileSelectionMode == FileSelectionMode.FILE) { |
|
File file = fileChooser.showOpenDialog(stage); |
|
if (file != null) { |
|
selectedFiles = new File[]{file}; |
|
} |
|
} else if (fileSelectionMode == FileSelectionMode.MULTIPLE_FILE) { |
|
List<File> fileList = fileChooser.showOpenMultipleDialog(stage); |
|
if (fileList != null) { |
|
selectedFiles = new File[fileList.size()]; |
|
fileList.toArray(selectedFiles); |
|
} |
|
} |
|
} else if (fileSelectionMode == FileSelectionMode.DIR) { |
|
DirectoryChooser directoryChooser = new DirectoryChooser(); |
|
directoryChooser.setTitle(title); |
|
directoryChooser.setInitialDirectory(currentDirectory); |
|
File folder = directoryChooser.showDialog(stage); |
|
if (folder != null) { |
|
selectedFiles = new File[]{folder}; |
|
} |
|
} |
|
} catch (Exception e) { |
|
FineLoggerFactory.getLogger().error(e, e.getMessage()); |
|
} finally { |
|
latch.countDown(); |
|
closeCoverStage(stage); |
|
} |
|
} |
|
|
|
private void closeCoverStage(Stage stage) { |
|
if (stage != null) { |
|
stage.close(); |
|
closeCoverStage((Stage) stage.getOwner()); |
|
} |
|
|
|
} |
|
|
|
|
|
private Stage showCoverStage(Component component) { |
|
try { |
|
if (component == null) |
|
return null; |
|
Stage parentStage = showCoverStage(component.getParent()); |
|
if (component instanceof JDialog || component instanceof JFrame) { |
|
return createStage(component.getX(), component.getY(), component.getWidth(), component.getHeight(), parentStage); |
|
} else { |
|
return parentStage; |
|
} |
|
} catch (Exception e) { |
|
FineLoggerFactory.getLogger().error(e, e.getMessage()); |
|
return null; |
|
} |
|
} |
|
|
|
private Stage createStage(double x, double y, double w, double h, Stage parentStage) { |
|
try { |
|
Stage stage = new Stage(); |
|
stage.setX(x); |
|
stage.setY(y); |
|
stage.setWidth(w); |
|
stage.setHeight(h); |
|
stage.setOpacity(0.2); |
|
stage.setResizable(false); |
|
stage.initStyle(StageStyle.UNDECORATED); |
|
|
|
Label label = new Label(); |
|
label.setBackground( |
|
new Background(new BackgroundFill(Color.color(0.78, 0.78, 0.80, 0.5), null, null))); |
|
stage.setScene(new Scene(label)); |
|
|
|
|
|
if (parentStage != null) { |
|
stage.initOwner(parentStage); |
|
stage.initModality(Modality.WINDOW_MODAL); |
|
} |
|
stage.show(); |
|
return stage; |
|
} catch (Exception e) { |
|
FineLoggerFactory.getLogger().error(e, e.getMessage()); |
|
return null; |
|
} |
|
} |
|
}); |
|
|
|
try { |
|
latch.await(); |
|
} catch (InterruptedException ignore) { |
|
} finally { |
|
setShowDialogState(false); |
|
} |
|
return selectedFiles.length > 0 ? JFileChooser.APPROVE_OPTION : JFileChooser.CANCEL_OPTION; |
|
} |
|
|
|
public void setSelectionMode(FileSelectionMode fileSelectionMode) { |
|
this.fileSelectionMode = fileSelectionMode; |
|
} |
|
|
|
@Override |
|
public void setCurrentDirectory(File currentDirectory) { |
|
this.currentDirectory = currentDirectory; |
|
} |
|
|
|
@Override |
|
public void setMultiSelectionEnabled(boolean multiple) { |
|
this.setSelectionMode(multiple ? FileSelectionMode.MULTIPLE_FILE : FileSelectionMode.FILE); |
|
} |
|
|
|
@Override |
|
public int showOpenDialog(Component parent, String approveButtonText) { |
|
return this.showDialog(parent); |
|
} |
|
|
|
public static class Builder { |
|
private FileSelectionMode fileSelectionMode = FileSelectionMode.FILE; |
|
private String title = Toolkit.i18nText("Fine-Design_Basic_Open"); |
|
private FileChooser.ExtensionFilter[] filters = new FileChooser.ExtensionFilter[0]; |
|
private File currentDirectory; |
|
|
|
public Builder fileSelectionMode(FileSelectionMode fileSelectionMode) { |
|
if (fileSelectionMode != null) { |
|
this.fileSelectionMode = fileSelectionMode; |
|
} |
|
return this; |
|
} |
|
|
|
public Builder title(String title) { |
|
if (StringUtils.isNotEmpty(title)) { |
|
this.title = title; |
|
} |
|
return this; |
|
} |
|
|
|
public Builder filters(FileChooser.ExtensionFilter[] filters) { |
|
if (filters != null) { |
|
this.filters = filters; |
|
} |
|
return this; |
|
} |
|
|
|
public Builder filters(ExtensionFilter[] filters) { |
|
if (filters != null) { |
|
for (ExtensionFilter filter : filters) { |
|
this.filters = ArrayUtils.add(this.filters, new FileChooser.ExtensionFilter(filter.getDes(), filter.getExtensions())); |
|
} |
|
} |
|
return this; |
|
} |
|
|
|
public Builder filter(String des, String... extensions) { |
|
if (extensions != null) { |
|
this.filters = new FileChooser.ExtensionFilter[]{new FileChooser.ExtensionFilter(des, extensions)}; |
|
} |
|
return this; |
|
} |
|
|
|
public Builder currentDirectory(File currentDirectory) { |
|
if (currentDirectory != null) { |
|
if (!currentDirectory.isDirectory()) { |
|
currentDirectory = currentDirectory.getParentFile(); |
|
} |
|
if (currentDirectory != null && currentDirectory.isDirectory()) { |
|
this.currentDirectory = currentDirectory; |
|
} |
|
} |
|
return this; |
|
} |
|
|
|
public Builder currentDirectory(String path) { |
|
if (path != null) { |
|
return currentDirectory(new File(path)); |
|
} |
|
return this; |
|
} |
|
|
|
public JavaFxNativeFileChooser build() { |
|
return new JavaFxNativeFileChooser(this); |
|
} |
|
} |
|
|
|
private JavaFxNativeFileChooser(Builder builder) { |
|
this.fileSelectionMode = builder.fileSelectionMode; |
|
this.title = builder.title; |
|
this.filters = builder.filters; |
|
this.currentDirectory = builder.currentDirectory; |
|
} |
|
} |