Browse Source
Merge in DESIGN/design from ~HENRY.WANG/design:feature/10.0 to feature/10.0 * commit '468b6600e872e10b1604618a9edbf2469d9afcf4': REPORT-55072 设计器内文件选择器替换为原生的 REPORT-55072 设计器内文件选择器替换为原生的 REPORT-55072 设计器内文件选择器替换为原生的feature/10.0
ju|剧浩宇
3 years ago
13 changed files with 483 additions and 723 deletions
@ -1,103 +0,0 @@ |
|||||||
package com.fr.design.gui.ifilechooser; |
|
||||||
|
|
||||||
import javax.swing.filechooser.FileFilter; |
|
||||||
import java.awt.*; |
|
||||||
import java.io.File; |
|
||||||
|
|
||||||
/** |
|
||||||
* @author hades |
|
||||||
* @version 10.0 |
|
||||||
* Created by hades on 2020/3/31 |
|
||||||
*/ |
|
||||||
public abstract class AbstractFileChooser { |
|
||||||
|
|
||||||
/** |
|
||||||
* 返回当前目录 |
|
||||||
* |
|
||||||
*/ |
|
||||||
public abstract File getCurrentDirectory(); |
|
||||||
|
|
||||||
/** |
|
||||||
* 返回当前的文件选择过滤器 |
|
||||||
* |
|
||||||
*/ |
|
||||||
public abstract FileFilter getFileFilter(); |
|
||||||
|
|
||||||
/** |
|
||||||
* 返回选择的文件 |
|
||||||
* |
|
||||||
*/ |
|
||||||
public abstract File getSelectedFile(); |
|
||||||
|
|
||||||
/** |
|
||||||
* 多文件选择模式下 返回选择的多个文件 |
|
||||||
* |
|
||||||
*/ |
|
||||||
public abstract File[] getSelectedFiles(); |
|
||||||
|
|
||||||
/** |
|
||||||
* 是否可以选择多个文件 |
|
||||||
* |
|
||||||
*/ |
|
||||||
public abstract boolean isMultiSelectionEnabled(); |
|
||||||
|
|
||||||
/** |
|
||||||
* 设置当前选择的目录 |
|
||||||
* |
|
||||||
*/ |
|
||||||
public abstract void setCurrentDirectory(File dir); |
|
||||||
|
|
||||||
/** |
|
||||||
* 设置左上角标题 |
|
||||||
* |
|
||||||
*/ |
|
||||||
public abstract void setDialogTitle(String title); |
|
||||||
|
|
||||||
/** |
|
||||||
* 设置当前的文件过滤器 |
|
||||||
* |
|
||||||
*/ |
|
||||||
public abstract void setFileFilter(final FileFilter filter); |
|
||||||
|
|
||||||
/** |
|
||||||
* 设置文件选择器模式 |
|
||||||
* |
|
||||||
* JFileChooser.FILES_ONLY |
|
||||||
* JFileChooser.DIRECTORIES_ONLY |
|
||||||
* JFileChooser.FILES_AND_DIRECTORIES |
|
||||||
*/ |
|
||||||
public abstract void setFileSelectionMode(int selectionMode); |
|
||||||
|
|
||||||
/** |
|
||||||
* 设置是否允许选择多个文件 |
|
||||||
* |
|
||||||
*/ |
|
||||||
public abstract void setMultiSelectionEnabled(boolean multiple); |
|
||||||
|
|
||||||
/** |
|
||||||
* 设置选择的文件 用于showSaveDialog |
|
||||||
* |
|
||||||
*/ |
|
||||||
public abstract void setSelectedFile(File file); |
|
||||||
|
|
||||||
/** |
|
||||||
* 弹出文件选择器 打开文件 |
|
||||||
* |
|
||||||
*/ |
|
||||||
public abstract int showOpenDialog(Component parent); |
|
||||||
|
|
||||||
/** |
|
||||||
* 弹出文件选择器 保存文件 |
|
||||||
* |
|
||||||
*/ |
|
||||||
public abstract int showSaveDialog(Component parent); |
|
||||||
|
|
||||||
|
|
||||||
/** |
|
||||||
* https://bugs.java.com/bugdatabase/view_bug.do?bug_id=4031440
|
|
||||||
* |
|
||||||
* 设置文件名后缀 起到文件过滤的作用 形如 "*.jpg;*.jpeg" |
|
||||||
* |
|
||||||
*/ |
|
||||||
public abstract void setExtensionFilter(String file); |
|
||||||
} |
|
@ -0,0 +1,12 @@ |
|||||||
|
package com.fr.design.gui.ifilechooser; |
||||||
|
|
||||||
|
import java.awt.*; |
||||||
|
import java.io.File; |
||||||
|
|
||||||
|
public interface FileChooserProvider { |
||||||
|
File[] getSelectedFiles(); |
||||||
|
|
||||||
|
File getSelectedFile(); |
||||||
|
|
||||||
|
int showDialog(Component parent); |
||||||
|
} |
@ -0,0 +1,5 @@ |
|||||||
|
package com.fr.design.gui.ifilechooser; |
||||||
|
|
||||||
|
public enum FileSelectionMode { |
||||||
|
FILE, MULTIPLE_FILE, DIR |
||||||
|
} |
@ -0,0 +1,158 @@ |
|||||||
|
package com.fr.design.gui.ifilechooser; |
||||||
|
|
||||||
|
|
||||||
|
import com.fr.design.i18n.Toolkit; |
||||||
|
import com.fr.design.upm.UpmUtils; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
import com.sun.javafx.application.PlatformImpl; |
||||||
|
import javafx.stage.DirectoryChooser; |
||||||
|
import javafx.stage.FileChooser; |
||||||
|
import javafx.stage.Window; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
import javax.swing.filechooser.FileNameExtensionFilter; |
||||||
|
import java.awt.*; |
||||||
|
import java.io.File; |
||||||
|
import java.util.List; |
||||||
|
import java.util.concurrent.CountDownLatch; |
||||||
|
|
||||||
|
public class JavaFxNativeFileChooser implements FileChooserProvider { |
||||||
|
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; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int showDialog(Component parent) { |
||||||
|
final CountDownLatch latch = new CountDownLatch(1); |
||||||
|
PlatformImpl.startup(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
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(null); |
||||||
|
if (file != null) { |
||||||
|
selectedFiles = new File[]{file}; |
||||||
|
} |
||||||
|
} else if (fileSelectionMode == FileSelectionMode.MULTIPLE_FILE) { |
||||||
|
List<File> fileList = fileChooser.showOpenMultipleDialog(null); |
||||||
|
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(null); |
||||||
|
if (folder != null) { |
||||||
|
selectedFiles = new File[]{folder}; |
||||||
|
} |
||||||
|
System.out.println(folder); |
||||||
|
} |
||||||
|
|
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e, e.getMessage()); |
||||||
|
} finally { |
||||||
|
latch.countDown(); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
try { |
||||||
|
latch.await(); |
||||||
|
} catch (InterruptedException ignore) { |
||||||
|
} |
||||||
|
return selectedFiles.length > 0 ? JFileChooser.APPROVE_OPTION : JFileChooser.CANCEL_OPTION; |
||||||
|
} |
||||||
|
|
||||||
|
public void setSelectionMode(FileSelectionMode fileSelectionMode) { |
||||||
|
this.fileSelectionMode = fileSelectionMode; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCurrentDirectory(File currentDirectory) { |
||||||
|
this.currentDirectory = currentDirectory; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
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) { |
||||||
|
this.fileSelectionMode = fileSelectionMode; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public Builder title(String title) { |
||||||
|
this.title = title; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public Builder filters(FileChooser.ExtensionFilter[] filters) { |
||||||
|
this.filters = filters; |
||||||
|
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; |
||||||
|
} |
||||||
|
} |
@ -1,154 +0,0 @@ |
|||||||
package com.fr.design.gui.ifilechooser; |
|
||||||
|
|
||||||
import com.fr.design.gui.ifilechooser.AbstractFileChooser; |
|
||||||
import com.fr.design.mainframe.DesignerContext; |
|
||||||
import com.fr.stable.os.OperatingSystem; |
|
||||||
|
|
||||||
import javax.swing.*; |
|
||||||
import javax.swing.filechooser.FileFilter; |
|
||||||
import java.awt.*; |
|
||||||
import java.io.File; |
|
||||||
import java.io.FilenameFilter; |
|
||||||
|
|
||||||
|
|
||||||
/** |
|
||||||
* 系统原生风格的文件选择器 |
|
||||||
* |
|
||||||
* jdk问题: |
|
||||||
* https://bugs.openjdk.java.net/browse/JDK-4811090 不支持文件扩展选择
|
|
||||||
* https://stackoverflow.com/questions/40713398/filter-not-working-in-filedialog windows下 setFilenameFilter不work
|
|
||||||
* |
|
||||||
* @author hades |
|
||||||
* @version 10.0 |
|
||||||
* Created by hades on 2020/3/31 |
|
||||||
*/ |
|
||||||
public class UINativeFileChooser extends AbstractFileChooser { |
|
||||||
|
|
||||||
private final FileDialog fileDialog; |
|
||||||
private FileFilter fileFilter; |
|
||||||
private int selectionMode; |
|
||||||
|
|
||||||
public UINativeFileChooser(File file) { |
|
||||||
fileDialog = new FileDialog(DesignerContext.getDesignerFrame()); |
|
||||||
if (file != null) { |
|
||||||
fileDialog.setDirectory(file.getAbsolutePath()); |
|
||||||
fileDialog.setFile(file.toString()); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public UINativeFileChooser() { |
|
||||||
this(null); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public File getCurrentDirectory() { |
|
||||||
return new File(fileDialog.getDirectory()); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public FileFilter getFileFilter() { |
|
||||||
return fileFilter; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public File getSelectedFile() { |
|
||||||
return new File(fileDialog.getDirectory() + fileDialog.getFile()); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public File[] getSelectedFiles() { |
|
||||||
return fileDialog.getFiles(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public boolean isMultiSelectionEnabled() { |
|
||||||
return fileDialog.isMultipleMode(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setCurrentDirectory(File f) { |
|
||||||
fileDialog.setDirectory(f.toString()); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setDialogTitle(String title) { |
|
||||||
fileDialog.setTitle(title); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setFileFilter(final FileFilter cff) { |
|
||||||
FilenameFilter filter = new FilenameFilter() { |
|
||||||
@Override |
|
||||||
public boolean accept(File Directory, String fileName) { |
|
||||||
return cff.accept(new File(Directory.getAbsolutePath() + fileName)); |
|
||||||
} |
|
||||||
}; |
|
||||||
fileDialog.setFilenameFilter(filter); |
|
||||||
fileFilter = cff; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setFileSelectionMode(int selectionMode) { |
|
||||||
this.selectionMode = selectionMode; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setMultiSelectionEnabled(boolean multiple) { |
|
||||||
fileDialog.setMultipleMode(multiple); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setSelectedFile(File file) { |
|
||||||
fileDialog.setDirectory(file.getAbsolutePath()); |
|
||||||
fileDialog.setFile(file.getName()); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int showOpenDialog(Component parent) { |
|
||||||
boolean appleProperty = OperatingSystem.isMacos() && selectionMode == JFileChooser.DIRECTORIES_ONLY; |
|
||||||
if (appleProperty) { |
|
||||||
System.setProperty("apple.awt.fileDialogForDirectories", "true"); |
|
||||||
} |
|
||||||
try { |
|
||||||
fileDialog.setLocale(JComponent.getDefaultLocale()); |
|
||||||
fileDialog.setMode(FileDialog.LOAD); |
|
||||||
fileDialog.setVisible(true); |
|
||||||
return fileDialog.getFile() == null ? JFileChooser.CANCEL_OPTION : JFileChooser.APPROVE_OPTION; |
|
||||||
} finally { |
|
||||||
if (appleProperty) { |
|
||||||
System.setProperty("apple.awt.fileDialogForDirectories", "false"); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int showSaveDialog(Component parent) { |
|
||||||
fileDialog.setLocale(JComponent.getDefaultLocale()); |
|
||||||
fileDialog.setMode(FileDialog.SAVE); |
|
||||||
fileDialog.setVisible(true); |
|
||||||
return fileDialog.getFile() == null ? JFileChooser.CANCEL_OPTION : JFileChooser.APPROVE_OPTION; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setExtensionFilter(String file) { |
|
||||||
fileDialog.setFile(file); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 确认本地文件选择器是否支持选择模式 |
|
||||||
* @param selectionMode 选择模式 |
|
||||||
* @return 是否支持选择模式 |
|
||||||
*/ |
|
||||||
public static boolean supportsSelectionMode(int selectionMode) { |
|
||||||
switch (selectionMode) { |
|
||||||
case JFileChooser.FILES_AND_DIRECTORIES: |
|
||||||
return false; |
|
||||||
case JFileChooser.DIRECTORIES_ONLY: |
|
||||||
return OperatingSystem.isMacos(); |
|
||||||
case JFileChooser.FILES_ONLY: |
|
||||||
default: |
|
||||||
return true; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
Loading…
Reference in new issue