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. RTB业务知识之1-原生广告

    一.背景 Native Advertising (Native Ads), 又称为原生广告, 是2013全球媒体界爆红的关键词,从2012年年底,就有人开始提了这个名词,接着到处都可以看到这个名词,再 ...

  2. 【spring boot】映射properties文件属性--到Java对象

    描述 将*.properties中的内容映射到java对象中: 主要步骤 添加 @Component 注解: 使用 @PropertySource 注解指定配置文件位置: 使用 @Configurat ...

  3. win server 2003 x64 IIS配置

    新装IIS第一个报错 The 'Microsoft.Jet.OLEDB.4.0' provider is not registered on the local machine 原因是 服务器 IIS ...

  4. P1916小书童--大战蚂蚁

    链接 题解:(这里蚂蚁0血也算活...) #include<iostream>#include<cstdio>#include<cmath>using namesp ...

  5. P1706 全排列问题

    题解:(其实我认为它就是个循环) #include<iostream> #include<cstdio> #include<iomanip> using names ...

  6. vue之文本渲染

    Vue使用了基于HTML的模板语法,允许开发者声明式地将DOM绑定至底层Vue实例的数据.所有Vue的模板都是合法的HTML,所以能被遵循规范的浏览器和HTML解析器解析. 在前面,我们一直使用的是{ ...

  7. springboot(五)读写分离,多个读库,Druid监控--待整理

    1.修改mybatis.properties # 主数据源,默认的 spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.d ...

  8. java 字节码 指令集 汇编(转)

    https://blog.csdn.net/github_35983163/article/details/52945845 网上找的没有指令码这列  自己把它加上 更方便查阅 指令从0x00-0xc ...

  9. OpenStack基础知识

        什么是云计算     地址规划 主机名 IP OpenStack01 172.30.2.135           有了云主机可以灵活扩展 OpenStack分为agent 和server端 ...

  10. windows server 2008 R2 安装

    微软服务器操作系统大致有: server 2000(简称2K),还有server 2003(2K3),server 2008(2K8),server 2000和2003是基于NT内核的,而2008是基 ...