public boolean showUpload2HomeDialog(final OperationInfo initDataInfo) {
boolean result = false;
try {
// Load the fxml file and create a new stage for the popup dialog.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getClassLoader().getResource("fxml/UploadHomeView.fxml"));
AnchorPane updateDatasetDialogView = (AnchorPane) loader.load(); // update the dialog Stage.
Stage dialogStage = new Stage();
dialogStage.setTitle("Upload To Home");
dialogStage.initModality(Modality.WINDOW_MODAL);
dialogStage.initOwner(primaryStage);
AlertDialogUtil.modifyDialogPosition(dialogStage, primaryStage);
Scene scene = new Scene(updateDatasetDialogView);
dialogStage.setScene(scene); Upload2HomeController controller = loader.getController();
controller.setDialogStage(dialogStage);
controller.setInitInput(initDataInfo.getLocalPath());
controller.setMainApp(this);
// Show the dialog and wait until the user closes it
dialogStage.showAndWait(); // update updateDataInfo to get datasetName and localPath
controller.updateInfo(initDataInfo); result = controller.isOkClicked();
} catch (IOException | DMGUIException e) {
logger.error(e.getLocalizedMessage(), e);
}
return result;
}
package cn.com.xxx.project.controller;

import java.io.File;
import java.util.ArrayList;
import java.util.List; import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPFileFilter; import cn.com.xxx.project.core.DMGUIException;
import cn.com.xxx.project.core.FTPFileManagerWrapper;
import cn.com.xxx.project.model.GlobalConfig;
import cn.com.xxx.project.model.OperationInfo;
import cn.com.xxx.project.util.AlertDialogUtil;
import cn.com.xxx.project.util.PathUtil;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.stage.DirectoryChooser;
import javafx.stage.FileChooser;
import javafx.stage.FileChooser.ExtensionFilter;
import javafx.stage.Stage; interface ItemFilter {
boolean matches(String inputStr, String optionalStr);
} public class Upload2HomeController {
@FXML private TextField inputPathField;
@FXML private ComboBox<String> remotePathComboBox; private Main mainApp;
private Stage dialogStage;
private boolean okClicked = false; //下拉条目查找器
private FTPFileManagerWrapper ftpFileMng; private final ObservableList<String> itemList = FXCollections.observableArrayList();
private boolean isFilterNotRequired = true;
private final ObservableList<String> filteredItemList = FXCollections.observableArrayList();
private final FTPFileFilter ftpFilter = file -> file.isDirectory() && ! file.getName().startsWith(".");
private final ItemFilter filter = (inputStr, optionalStr) -> optionalStr.startsWith(inputStr);
private String tempRemotePath = null;
private String oldRemotePath = null; private static final int MAX_VISIBLE_ROW_COUNT = 5; /**
* 属性初始化
*/
public void setMainApp(final Main mainApp) throws DMGUIException {
this.mainApp = mainApp;
initFTPFileMng();
mainApp.getRemoteDatasetsController().selectHomeTab(); Platform.runLater(()->{
String remotePath = mainApp.getRemoteDatasetController().getRemotePath(); remotePathComboBox.setItems(itemList);
remotePathComboBox.setVisibleRowCount(MAX_VISIBLE_ROW_COUNT); itemList.addAll(listAbsDirPath(remotePath));
setText(remotePath);
oldRemotePath = remotePath; setFocusedPropertyListener();
setKeyListener();
});
} private List<String> listAbsDirPath(String path){
List<FTPFile> files = ftpFileMng.list(path, ftpFilter); List<String> absDirPaths = new ArrayList<String>();
path = path.endsWith("/") ? path : path + "/";
for (FTPFile file: files) {
absDirPaths.add(path + file.getName());
}
return absDirPaths;
} public void initFTPFileMng() throws DMGUIException{
ftpFileMng = new FTPFileManagerWrapper();
ftpFileMng.setWorkPath(GlobalConfig.getInstance().getHomePath());
} private void setFocusedPropertyListener() {
remotePathComboBox.getEditor().focusedProperty().addListener(
(observable, oldValue, newValue) -> {
if (observable.getValue()){
remotePathComboBox.show();
String test = getText();
if (test != null){
Platform.runLater(()->{remotePathComboBox.getEditor().positionCaret(test.length());});
}
}
}
);
} private void setKeyListener() {
remotePathComboBox.addEventHandler(KeyEvent.KEY_RELEASED, new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event) {//NOPMD
if (event.getCode() == KeyCode.UP || event.getCode() == KeyCode.DOWN) {
show();
moveCaret();
return;
} if (isIgnoredKey(event.getCode())) {
return;
} reviseText(); refreshItems();
refreshFilteredItems();
resetComboBoxItemsAndDisplay();
oldRemotePath = getText();
}
});
} private boolean isIgnoredKey(final KeyCode keyCode) {
// BACK_SPACE/DELETE不做特殊处理
return keyCode.equals(KeyCode.SHIFT)
|| keyCode.equals(KeyCode.CONTROL)
|| keyCode.equals(KeyCode.LEFT)
|| keyCode.equals(KeyCode.RIGHT)
|| keyCode.equals(KeyCode.HOME)
|| keyCode.equals(KeyCode.END)
|| keyCode.equals(KeyCode.TAB)
|| keyCode.equals(KeyCode.ENTER);
} private void refreshItems() {
if (isRequiredRefresh()) {
itemList.setAll(listAbsDirPath(getDirPath(getText())));
}
} private String getDirPath(final String path){
int lastSlashCharIndex = path.lastIndexOf("/");
if (lastSlashCharIndex == -1) {
lastSlashCharIndex = path.length();
}else if(lastSlashCharIndex == 0){
lastSlashCharIndex = 1;
}
return path.substring(0, lastSlashCharIndex);
} /**
* 待优化,考虑角度:字符在末尾增减,在中间增减,增减单字符,增减多字符
*/
private boolean isRequiredRefresh(){
boolean isRequied = false;
final int changedPathLen = getText().length() - oldRemotePath.length(); if (changedPathLen>0) {
isRequied = getText().endsWith("/") && filteredItemList.size() > 0;//条件:斜杠前面的路径有效
// && filteredItemList.size() == 1
// && filteredItemList.get(0).equals(oldRemotePath);
isFilterNotRequired = isRequied;
}else if (changedPathLen < 0){
isRequied = oldRemotePath.endsWith("/");
}
return isRequied;
} private void refreshFilteredItems() {
tempRemotePath = getText(); if (isFilterNotRequired){
filteredItemList.setAll(itemList);
isFilterNotRequired = false;
}else{
filteredItemList.clear();//路径文本也会被刷掉
for (String aData : itemList) {
if (aData != null && tempRemotePath != null
&& filter.matches(tempRemotePath, aData)) {
filteredItemList.add(aData);
}
}
}
} private void setTextAndMoveCaret(final String text) {
setText(text);
moveCaret();
} private void setText(final String text) {
remotePathComboBox.getEditor().setText(text);
} private String getText() {
return remotePathComboBox.getEditor().getText();
} /**
* FTPClient#listFiles()无法准确处理路径末尾多斜杠问题,需要强制修正
*/
private void reviseText(){
setText(PathUtil.filterExtraSlash(getText()));
}
private void resetComboBoxItemsAndDisplay() {
remotePathComboBox.setItems(filteredItemList); remotePathComboBox.getSelectionModel().clearSelection();
remotePathComboBox.setVisibleRowCount(filteredItemList.size() < MAX_VISIBLE_ROW_COUNT ?
filteredItemList.size() : MAX_VISIBLE_ROW_COUNT);
// 调用了总开关,重置显示下拉布局;可以优化,只重置具体的下拉布局属性。
remotePathComboBox.hide();
remotePathComboBox.show(); setTextAndMoveCaret(tempRemotePath);
} private void show() {
if (!remotePathComboBox.getItems().isEmpty() && !remotePathComboBox.isShowing()) {
remotePathComboBox.show();
}
} private void moveCaret() {
String test = getText();
if (test != null) {
moveCaret(test.length());
}
} private void moveCaret(final int pos) {
remotePathComboBox.getEditor().positionCaret(pos);
}
public void setDialogStage(final Stage dialogStage) {
this.dialogStage = dialogStage;
} public void setInitInput(final String localPath) {
inputPathField.setText(localPath);
} public boolean isOkClicked() {
return okClicked;
} public void updateInfo(final OperationInfo updateInfo) {
updateInfo.setLocalPath(inputPathField.getText());
updateInfo.setRemotePath(
PathUtil.splicePath(GlobalConfig.getInstance().getHomePath(), getText()));
} @FXML
private void handleOk() { //NOPMD
try {
checkInput(); okClicked = true;
dialogStage.close();
} catch (DMGUIException e) {
AlertDialogUtil.createLazyAlertDialog(e.getMessage(), "输入错误!");
}
} @FXML
private void handleCancel() { //NOPMD
dialogStage.close();
} @FXML
private void handleBrowseDir() { //NOPMD
DirectoryChooser dirChooser = new DirectoryChooser();
dirChooser.setInitialDirectory(new File("."));
File file = dirChooser.showDialog(mainApp.getPrimaryStage()); if (file != null) {
inputPathField.setText(file.getPath().toString());
}
} @FXML
private void handleBrowseFile() { //NOPMD
// Open a directory selecting dialog
FileChooser fileChooser = new FileChooser();;
fileChooser.setInitialDirectory(new File("."));
fileChooser.getExtensionFilters().addAll(
new ExtensionFilter("All Files", "*.*"),
new ExtensionFilter("Text Files", "*.txt"),
new ExtensionFilter("CSV Files", "*.csv"),
new ExtensionFilter("Image Files", "*.png", "*.jpg", "*.gif"),
new ExtensionFilter("Audio Files", "*.wav", "*.mp3", "*.aac"),
new ExtensionFilter("XML files", "*.xml"));
File file = fileChooser.showOpenDialog(mainApp.getPrimaryStage()); if (file != null) {
inputPathField.setText(file.getPath().toString());
}
} private void checkInput() throws DMGUIException{
final StringBuilder errMsg = new StringBuilder();
checkInputLocalPath(errMsg);
checkInputRemotePath(errMsg); if(errMsg.length() != 0){
throw new DMGUIException(errMsg.toString());
}
} private void checkInputLocalPath(final StringBuilder errMsg){
if (this.inputPathField.getText() == null
|| this.inputPathField.getText().length() == 0) {
errMsg.append("本地路径为空,请重新输入!\n");
} else {
final File file = new File(inputPathField.getText());
if (!file.exists()) { // NOPMD
errMsg.append("本地路径不存在,请重新输入!\n");
}
} if(errMsg.length() == 0){
this.inputPathField.setStyle("-fx-border-color: null");
}else{
this.inputPathField.setStyle("-fx-border-color: red");
}
} private void checkInputRemotePath(final StringBuilder errMsg){
String inputRemotePath = getText();
boolean isExist = ftpFileMng.isDirExist(inputRemotePath); if (isExist){
remotePathComboBox.setStyle("-fx-border-color: null");
}else{
errMsg.append("远端路径不存在,请重新输入!\n");
remotePathComboBox.setStyle("-fx-border-color: red");
}
}
}
    public static List<String> filterExtraSubPath(final String[] fileNameArr){
List<String> newFileNameList = new ArrayList<>();
for(String fileName: fileNameArr){
if( ! fileName.equals(".") && ! fileName.equals("")){
newFileNameList.add(fileName);
}
}
return newFileNameList;
} public static String filterExtraSlash(final String path){
if (null == path){
return null;//NOPMD
}
String[] fileNameArr = path.split("/");
List<String> subPathList = filterExtraSubPath(fileNameArr);
return "/" + String.join("/", subPathList) + (path.endsWith("/") && !path.equals("/")?"/":"");
}

pathutil.java

javafx自动补全的更多相关文章

  1. jQuery 邮箱下拉列表自动补全

    综述 我想大家一定见到过,在某个网站填写邮箱的时候,还没有填写完,就会出现一系列下拉列表,帮你自动补全邮箱的功能.现在我们就用jQuery来实现一下. 博主原创代码,如有代码写的不完善的地方还望大家多 ...

  2. eclipse自动补全的设置

    eclipse自动补全的设置   如果你用过Visual Studio的自动补全功能后,再来用eclipse的自动补全功能,相信大家会有些许失望. 但是eclipse其实是非常强大的,eclipse的 ...

  3. vim 添加php自动补全 并格式化代码

    自动补全,修改/etc/vimrc的配置 vim /etc/vimrc 添加: filetype plugin on autocmd FileType php set omnifunc=phpcomp ...

  4. Eclipse自动补全设置

    如果你用过Visual Studio的自动补全功能后,再来用eclipse的自动补全功能,相信大家会有些许失望. 但是eclipse其实是非常强大的,eclipse的自动补全没有VS那么好是因为ecl ...

  5. Autocomplete 自动补全(Webform实战篇)

    开篇语 因为项目中需要用到一个自动补全的功能,功能描述: 需求一:新增收件人的时候,自动下拉显示出数据库中所有的收件人信息(显示的信息包括:姓名-收件地址-联系方式) 需求二:选中一个值得时候,分别赋 ...

  6. eclipse自动补全的设置(自动提示)

      如果你用过Visual Studio的自动补全功能后,再来用eclipse的自动补全功能,相信大家会有些许失望. 但是eclipse其实是非常强大的,eclipse的自动补全没有VS那么好是因为e ...

  7. jQuery AutoComplete 自动补全

    jQuery.AutoComplete是一个基于jQuery的自动补全插件.借助于jQuery优秀的跨浏览器特性,可以兼容Chrome/IE/Firefox/Opera/Safari等多种浏览器. 特 ...

  8. Vim自动补全神器–YouCompleteMe

    一.简介 YouCompleteMe是Vim的自动补全插件,与同类插件相比,具有如下优势 1.基于语义补全 2.整合实现了多种插件 clang_complete.AutoComplPop .Super ...

  9. 通过trie树单词自动补全(二)

    经常使用iciba进行单词查询, 关于他的搜索建议是通过单词前缀做的索引, 所以自己想动手实现下, 当然如果借助mysql的话,一条sql语句就能实现, 网上查询了下trie正适合做这个,所以通过C语 ...

随机推荐

  1. 2017.11.6 - ant design table等组件的使用,以及 chrome 中 network 的使用

    一.今日主要任务 悉尼小程序后台管理开发: 景点管理页面: 获取已有数据列表,选取部分数据呈现在表格中,根据景点名称.分类过滤出对应的景点.   二.难点 1. 项目技术选取: ant design. ...

  2. MIME 设置

    1,打开iis7,选择你要设置网站,打开mime类型选项 2,找到.rar的mime类型,复制他的类型 3,复制后选项添加,在文件扩展名那一栏填入.*,然后在下面的mime类型复制你刚复制的appli ...

  3. 获取 TUniConnection.SpecificOptions默认值和下拉框列表值

    TUniConnection的SpecificOptions参数决定了数据库连接配置参数,但可惜的是,SpecificOptions设计器界面,Devart公司只能让它在设计期配置! Specific ...

  4. 黄聪:is_file和file_exists效率比较

    目前在弄文件缓存的时候用到了判定文件存在与否,is_file()还是file_exists()呢?is_file和file_exists两者效率比较起来,谁的运行速度更快呢?还是做个测试吧: 1 2 ...

  5. Qt error: stray '\241' in program

    转载:iGoforward 报错的意思是c++中的产生了编译错误. 该错误是指源程序中有非法字符,需要将非法字符去掉.一般是由于编程者(不用程序员这个名词是因为这种错误太低级)使用中文输入法 或者从别 ...

  6. Hadoop 管理工具HUE配置-集成Unix用户和用户组

    HUE安装完成之后,第一次登录的用户就是HUE的超级用户,可以管理用户,等等.但是在用的过程发现一个问题这个用户不能管理HDFS中由supergroup创建的数据. 虽然在HUE中创建的用户可以管理自 ...

  7. VisualSVNServer 无法启动 could not log pid to file

    启动SVN时候报了错误,然后查看日志发现报了如下错误 VisualSVNServer.exe: could not log pid to file C:/Windows/ServiceProfiles ...

  8. DP Big Event in HDU

    Big Event in HDU Time Limit : 10000/5000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) T ...

  9. 去除图像中的alpha通道或透明度

    自从appstore提交app改变后,虽然提交的流程还是和原来一样,但是相比以前还是有很大的改动,本来就不太喜欢 English,改版之后很多东西都变了,开发一个app就已经够他妈的蛋疼啦,上传一个a ...

  10. [UE4]使用UnrealVS扩展快速编译C++代码

    一.如果UE4 编辑器已经打开,则VS中的重新生成项目将不能使用,一定要关了UE4 编辑器才可以.一般不是有VS自身的编译UE4的C++代码 二.epic提供了UnrealVS扩展,可以快速编译C++ ...