javafx--自动补全

    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

posted on 2018-10-23 22:33 wenlin_gk 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/wenlin-gk/p/9840062.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值