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. SDRAM的初始化与刷新操作---看时序图写代码

    SDRAM的初始化与刷新操作---看时序图写代码 1.SDRAM的常见操作 2.初始化就是配置SDRAM 3.SDRAM初始化时序 时序解释如下: 4.刷新操作

  2. mysql update 忘加 where 文件恢复

    前提条件:mysql :data_row_format=rowmysql> show variables like '%image%';+------------------+-------+| ...

  3. 进程池pool

    如果有多个进程,同一时间只能有限个给cpu运行 from multiprocessing import Process,Pool import time,os def bar(arg): print( ...

  4. 移动互联网终端的touch事件判断方向

    var pressX = 0, pressY = 0; document.body.addEventListener('touchmove', function(event) { // 如果这个元素的 ...

  5. 前端学PHP之面向对象系列第四篇-----关键字

    public public表示公有,它具有最大的访问权限,被定义为公有的类成员可以在任何地方被访问 如果属性用 var 定义,则被视为公有,如果方法没有设置关键字,则该方法默认为公有 <?php ...

  6. Mysql 复制工作原理

    数据库配置的时候,一定要开启二进制日志,如果开始没开启后来再想开启的话,必须重启. 基于日志点的复制 备份数据库工具 ----------------------------------------- ...

  7. fiddler无法与手机连接是什么原因

    1.首先要确保手机和安装有Fiddler的计算机处在同一个局域网中,可以使用路由器,或者使用笔记本发送热点给手机使用.在这里本人是使用手机USB共享功能让笔记本联网的.进入cmd输入ipconfig/ ...

  8. WhereHows前后端配置文件

    前端: # This is the main configuration file for the application. # ~~~~~ # Secret key # ~~~~~ # The se ...

  9. 【Graphite】使用dropwizard.metrics向Graphite中写入指标项数据

    graphite 定时向Graphite中写入指标项数据,指标项模拟个数3000个 使用的类库 官方文档   dropwizard的github地址 Metric官方文档 metrics.dropwi ...

  10. R语言—统计结果输出至本地文件方法总结

    1.sink()在代码开始前加一行:sink(“output.txt”),就会自动把结果全部输出到工作文件夹下的output.txt文本文档.这时在R控制台的输出窗口中是看不到输出结果的.代码结束时用 ...