All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.alee.extended.filechooser.WebPathField Maven / Gradle / Ivy

/*
 * This file is part of WebLookAndFeel library.
 *
 * WebLookAndFeel library is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * WebLookAndFeel library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with WebLookAndFeel library.  If not, see .
 */

package com.alee.extended.filechooser;

import com.alee.extended.drag.FileDragAndDropHandler;
import com.alee.extended.layout.HorizontalFlowLayout;
import com.alee.global.GlobalConstants;
import com.alee.laf.button.WebButton;
import com.alee.laf.button.WebToggleButton;
import com.alee.laf.list.WebList;
import com.alee.laf.list.WebListCellRenderer;
import com.alee.laf.menu.WebMenuItem;
import com.alee.laf.menu.WebPopupMenu;
import com.alee.laf.panel.WebPanel;
import com.alee.laf.scroll.WebScrollPane;
import com.alee.laf.text.WebTextField;
import com.alee.managers.focus.DefaultFocusTracker;
import com.alee.managers.focus.FocusManager;
import com.alee.managers.hotkey.Hotkey;
import com.alee.managers.hotkey.HotkeyManager;
import com.alee.managers.hotkey.HotkeyRunnable;
import com.alee.managers.style.StyleId;
import com.alee.utils.CollectionUtils;
import com.alee.utils.FileUtils;
import com.alee.utils.SwingUtils;
import com.alee.utils.SystemUtils;
import com.alee.utils.filefilter.AbstractFileFilter;

import javax.swing.*;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import javax.swing.filechooser.FileSystemView;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

/**
 * Custom component which allows file system path selection.
 *
 * @author Mikle Garin
 * @author Michka Popoff
 */

public class WebPathField extends WebPanel
{
    /**
     * todo 1. Enhance path update method performance
     * todo 2. While menu is opened - open other menus on simple rollover
     * todo 3. Proper focus handling after finishing manual path editing
     */

    /**
     * Used icons.
     */
    protected static final ImageIcon down = new ImageIcon ( WebPathField.class.getResource ( "icons/down.png" ) );
    protected static final ImageIcon left = new ImageIcon ( WebPathField.class.getResource ( "icons/left.png" ) );
    protected static final ImageIcon right = new ImageIcon ( WebPathField.class.getResource ( "icons/right.png" ) );

    /**
     * Custom property used to store file icon into button.
     */
    protected static final String FILE_ICON = "fileIcon";

    /**
     * File system view.
     */
    protected static FileSystemView fsv = FileSystemView.getFileSystemView ();

    /**
     * Field listeners.
     */
    protected List listeners = new ArrayList ( 1 );

    /**
     * UI components.
     */
    protected WebPanel contentPanel;
    protected WebTextField pathField;
    protected FocusAdapter pathFocusListener;
    protected WebButton myComputer = null;

    /**
     * Autocomplete.
     */
    protected boolean autocompleteEnabled = true;
    protected JWindow autocompleteDialog = null;

    /**
     * Root item menu.
     */
    protected int rootsMenuItemsCount = 0;
    protected WebPopupMenu rootsMenu = null;
    protected WebToggleButton rootsArrowButton = null;

    /**
     * Field settings.
     */
    protected AbstractFileFilter fileFilter = GlobalConstants.DIRECTORIES_FILTER;
    protected int preferredWidth = -1;
    protected boolean filesDropEnabled = true;
    protected File selectedPath;

    /**
     * Runtime variables.
     */
    protected final DefaultFocusTracker focusTracker;
    protected boolean focusOwner = false;

    public WebPathField ()
    {
        this ( StyleId.pathfield );
    }

    public WebPathField ( final String path )
    {
        this ( StyleId.pathfield, path );
    }

    public WebPathField ( final File path )
    {
        this ( StyleId.pathfield, path );
    }

    public WebPathField ( final StyleId id )
    {
        this ( id, FileUtils.getDiskRoots ()[ 0 ] );
    }

    public WebPathField ( final StyleId id, final String path )
    {
        this ( id, new File ( path ) );
    }

    public WebPathField ( final StyleId id, final File path )
    {
        super ( id );

        // Files TransferHandler
        setTransferHandler ( new FileDragAndDropHandler ()
        {
            @Override
            public boolean isDropEnabled ()
            {
                return filesDropEnabled;
            }

            @Override
            public boolean filesDropped ( final List files )
            {
                // Setting dragged files
                final FileFilter filter = getFileFilter ();
                for ( final File file : files )
                {
                    final File actualFile = file.isDirectory () ? file : file.getParentFile ();
                    if ( filter == null || filter.accept ( actualFile ) )
                    {
                        folderSelected ( actualFile );
                        return true;
                    }
                }
                return false;
            }
        } );

        final StyleId contentStyle = StyleId.pathfieldContentPanel.at ( this );
        contentPanel = new WebPanel ( contentStyle, new HorizontalFlowLayout ( 0, true ) );
        add ( contentPanel, BorderLayout.CENTER );

        //        WebImage editImage = new WebImage ( WebPathField.class, "icons/edit.png" );
        //        editImage.setCursor ( Cursor.getPredefinedCursor ( Cursor.TEXT_CURSOR ) );
        //        editImage.addMouseListener ( new MouseAdapter ()
        //        {
        //            public void mousePressed ( MouseEvent e )
        //            {
        //                if ( SwingUtilities.isLeftMouseButton ( e ) )
        //                {
        //                    startEditing ();
        //                }
        //            }
        //        } );
        //        add ( editImage,BorderLayout.EAST );

        pathField = new WebTextField ( StyleId.pathfieldPathField.at ( contentPanel ) );
        pathField.addActionListener ( new ActionListener ()
        {
            @Override
            public void actionPerformed ( final ActionEvent e )
            {
                if ( autocompleteDialog == null || !autocompleteDialog.isVisible () )
                {
                    if ( pathField.getText ().trim ().equals ( "" ) )
                    {
                        folderSelected ( null );
                    }
                    else
                    {
                        final File chosenPath = new File ( pathField.getText () );
                        if ( chosenPath.exists () && chosenPath.isDirectory () )
                        {
                            folderSelected ( chosenPath );
                        }
                        else
                        {
                            updatePath ();
                        }
                    }
                    WebPathField.this.transferFocus ();
                }
            }
        } );
        pathField.addKeyListener ( new KeyAdapter ()
        {
            @Override
            public void keyPressed ( final KeyEvent e )
            {
                if ( autocompleteDialog == null || !autocompleteDialog.isVisible () )
                {
                    if ( Hotkey.ESCAPE.isTriggered ( e ) )
                    {
                        if ( selectedPath == null && pathField.getText ().trim ().equals ( "" ) ||
                                selectedPath != null && getProperSelectedPath ().equals ( pathField.getText () ) )
                        {
                            updatePath ();
                            WebPathField.this.transferFocus ();
                        }
                        else
                        {
                            pathField.setText ( getProperSelectedPath () );
                        }
                    }
                }
            }
        } );

        pathFocusListener = new FocusAdapter ()
        {
            @Override
            public void focusLost ( final FocusEvent e )
            {
                if ( selectedPath == null && pathField.getText ().trim ().equals ( "" ) ||
                        selectedPath != null && getProperSelectedPath ().equals ( pathField.getText () ) )
                {
                    updatePath ();
                }
            }
        };

        // Autocomplete dialog listener
        pathField.addCaretListener ( new CaretListener ()
        {
            private WebList list = null;
            private WebScrollPane listScroll;

            @Override
            public void caretUpdate ( final CaretEvent e )
            {
                if ( !autocompleteEnabled || !pathField.isVisible () || !pathField.isShowing () )
                {
                    if ( autocompleteDialog != null && autocompleteDialog.isVisible () )
                    {
                        hideDialog ();
                    }
                    return;
                }

                if ( autocompleteDialog == null )
                {
                    autocompleteDialog = new JWindow ( SwingUtils.getWindowAncestor ( WebPathField.this ) );
                    autocompleteDialog.getContentPane ().setLayout ( new BorderLayout () );
                    autocompleteDialog.setFocusable ( false );

                    SwingUtils.getWindowAncestor ( WebPathField.this ).addComponentListener ( new ComponentAdapter ()
                    {
                        @Override
                        public void componentMoved ( final ComponentEvent e )
                        {
                            hideDialog ();
                        }

                        @Override
                        public void componentResized ( final ComponentEvent e )
                        {
                            hideDialog ();
                        }
                    } );

                    list = new WebList ();
                    list.setFocusable ( false );
                    list.setSelectionMode ( ListSelectionModel.SINGLE_SELECTION );
                    list.setSelectOnHover ( true );
                    list.setCellRenderer ( new WebListCellRenderer ()
                    {
                        @Override
                        public Component getListCellRendererComponent ( final JList list, final Object value, final int index,
                                                                        final boolean isSelected, final boolean cellHasFocus )
                        {
                            final JLabel renderer =
                                    ( JLabel ) super.getListCellRendererComponent ( list, value, index, isSelected, cellHasFocus );
                            renderer.setIcon ( FileUtils.getFileIcon ( ( File ) value ) );
                            renderer.setText ( FileUtils.getDisplayFileName ( ( File ) value ) );
                            return renderer;
                        }
                    } );
                    list.addMouseListener ( new MouseAdapter ()
                    {
                        @Override
                        public void mousePressed ( final MouseEvent e )
                        {
                            final int index = list.getUI ().locationToIndex ( list, e.getPoint () );
                            if ( SwingUtilities.isLeftMouseButton ( e ) && index != -1 )
                            {
                                setSelectedPath ( ( File ) list.getModel ().getElementAt ( index ) );
                            }
                        }
                    } );
                    list.addKeyListener ( new KeyAdapter ()
                    {
                        @Override
                        public void keyPressed ( final KeyEvent e )
                        {
                            if ( Hotkey.ENTER.isTriggered ( e ) )
                            {
                                setSelectedPath ( ( File ) list.getSelectedValue () );
                            }
                        }
                    } );
                    listScroll = new WebScrollPane ( StyleId.pathfieldPopupScroll.at ( pathField ), list );
                    autocompleteDialog.getContentPane ().add ( listScroll, BorderLayout.CENTER );

                    pathField.addKeyListener ( new KeyAdapter ()
                    {
                        @Override
                        public void keyPressed ( final KeyEvent e )
                        {
                            if ( autocompleteDialog.isShowing () && list.getModel ().getSize () > 0 )
                            {
                                if ( list.getSelectedIndex () != -1 )
                                {
                                    if ( Hotkey.ESCAPE.isTriggered ( e ) || Hotkey.F2.isTriggered ( e ) ||
                                            Hotkey.CTRL_ENTER.isTriggered ( e ) )
                                    {
                                        hideDialog ();
                                    }
                                    else if ( Hotkey.ENTER.isTriggered ( e ) )
                                    {
                                        setSelectedPath ( ( File ) list.getSelectedValue () );
                                    }
                                    else if ( Hotkey.UP.isTriggered ( e ) )
                                    {
                                        if ( list.getSelectedIndex () == 0 )
                                        {
                                            list.setSelectedIndex ( list.getModel ().getSize () - 1 );
                                            scrollToSelected ();
                                        }
                                        else
                                        {
                                            list.setSelectedIndex ( list.getSelectedIndex () - 1 );
                                            scrollToSelected ();
                                        }
                                    }
                                    else if ( Hotkey.DOWN.isTriggered ( e ) )
                                    {
                                        if ( list.getSelectedIndex () == list.getModel ().getSize () - 1 )
                                        {
                                            list.setSelectedIndex ( 0 );
                                            scrollToSelected ();
                                        }
                                        else
                                        {
                                            list.setSelectedIndex ( list.getSelectedIndex () + 1 );
                                            scrollToSelected ();
                                        }
                                    }
                                }
                                else
                                {
                                    list.setSelectedIndex ( 0 );
                                    scrollToSelected ();
                                }
                            }
                        }

                        private void scrollToSelected ()
                        {
                            list.scrollRectToVisible (
                                    list.getUI ().getCellBounds ( list, list.getSelectedIndex (), list.getSelectedIndex () ) );
                        }
                    } );

                    pathField.addFocusListener ( new FocusAdapter ()
                    {
                        @Override
                        public void focusLost ( final FocusEvent e )
                        {
                            hideDialog ();
                        }
                    } );
                }

                //                new Thread ( new Runnable ()
                //                {
                //                    public void run ()
                //                    {
                // Taking only the part till the caret
                final String t = pathField.getText ().substring ( 0, pathField.getCaretPosition () );

                // Retrieving parent path
                int beginIndex = t.lastIndexOf ( File.separator );
                beginIndex = beginIndex != -1 ? beginIndex + 1 : 0;

                // Parent file
                final String parentPath = t.substring ( 0, beginIndex );
                final File parent = parentPath.trim ().equals ( "" ) ? null : new File ( parentPath );

                final List similar = getSimilarFileChildren ( parent, t.substring ( beginIndex ) );
                if ( similar != null && similar.size () > 0 )
                {
                    updateList ( similar );
                }
                else
                {
                    hideDialog ();
                }
                //                    }
                //                } ).start ();
            }

            private void updateList ( final List similar )
            {
                SwingUtils.invokeLater ( new Runnable ()
                {
                    @Override
                    public void run ()
                    {
                        list.setModel ( new AbstractListModel ()
                        {
                            @Override
                            public int getSize ()
                            {
                                return similar.size ();
                            }

                            @Override
                            public Object getElementAt ( final int i )
                            {
                                return similar.get ( i );
                            }
                        } );
                        list.setVisibleRowCount ( Math.min ( similar.size (), 6 ) );
                        list.updateUI ();
                        if ( similar.size () > 0 )
                        {
                            list.setSelectedIndex ( 0 );
                        }

                        // Fixing window bounds
                        final Point los = pathField.getLocationOnScreen ();
                        autocompleteDialog.setSize ( pathField.getWidth (), listScroll.getPreferredSize ().height );
                        autocompleteDialog.setLocation ( pathField.getComponentOrientation ().isLeftToRight () ? los.x :
                                los.x + pathField.getWidth () - autocompleteDialog.getWidth (), los.y + pathField.getHeight () );

                        // Showing dialog if needed
                        if ( !autocompleteDialog.isShowing () )
                        {
                            autocompleteDialog.setVisible ( true );
                            WebPathField.this.transferFocus ();
                        }
                    }
                } );
            }

            private void hideDialog ()
            {
                SwingUtils.invokeLater ( new Runnable ()
                {
                    @Override
                    public void run ()
                    {
                        autocompleteDialog.setVisible ( false );
                    }
                } );
            }

            private void setSelectedPath ( final File path )
            {
                String text = path.getAbsolutePath ();
                text = text.endsWith ( File.separator ) ? text : text + File.separator;
                pathField.setText ( text );
                pathField.setCaretPosition ( text.length () );
            }
        } );

        // Edit start listeners
        contentPanel.addMouseListener ( new MouseAdapter ()
        {
            @Override
            public void mousePressed ( final MouseEvent e )
            {
                if ( SwingUtilities.isLeftMouseButton ( e ) )
                {
                    startEditing ();
                }
            }
        } );
        HotkeyManager.registerHotkey ( WebPathField.this, WebPathField.this, Hotkey.F2, new HotkeyRunnable ()
        {
            @Override
            public void run ( final KeyEvent e )
            {
                startEditing ();
            }
        }, true );

        // Resize listener
        addComponentListener ( new ComponentAdapter ()
        {
            @Override
            public void componentResized ( final ComponentEvent e )
            {
                if ( !pathField.isShowing () )
                {
                    updatePath ();
                }
            }
        } );

        // Focus listener
        focusTracker = new DefaultFocusTracker ()
        {
            @Override
            public void focusChanged ( final boolean focused )
            {
                focusOwner = focused;
                WebPathField.this.repaint ();
            }
        };
        FocusManager.addFocusTracker ( WebPathField.this, focusTracker );

        // Updating initial path
        updatePath ( path );
    }

    protected void startEditing ()
    {
        if ( !pathField.isFocusOwner () )
        {
            // Updating path field preferred size
            pathField.setPreferredSize ( new Dimension ( 1, contentPanel.getHeight () ) );

            // Clearing content
            contentPanel.removeAll ();

            // Updating path text
            if ( selectedPath != null )
            {
                pathField.setText ( getProperSelectedPath () );
            }
            else
            {
                pathField.setText ( "" );
            }
            pathField.selectAll ();

            // Adding field as main component
            contentPanel.add ( pathField );
            contentPanel.revalidate ();
            contentPanel.repaint ();

            // Focusing field
            WebPathField.this.transferFocus ();
            pathField.addFocusListener ( pathFocusListener );
        }
    }

    protected String getProperSelectedPath ()
    {
        String path = selectedPath.getAbsolutePath ();
        path = path.endsWith ( File.separator ) ? path : path + File.separator;
        return path;
    }

    public boolean isEditing ()
    {
        return pathField.isFocusOwner ();
    }

    @Override
    public void setForeground ( final Color foreground )
    {
        super.setForeground ( foreground );
        if ( isShowing () )
        {
            SwingUtils.setForegroundRecursively ( contentPanel, foreground );
            pathField.setForeground ( foreground );
        }
    }

    public boolean isAutocompleteEnabled ()
    {
        return autocompleteEnabled;
    }

    public void setAutocompleteEnabled ( final boolean autocompleteEnabled )
    {
        this.autocompleteEnabled = autocompleteEnabled;
    }

    public AbstractFileFilter getFileFilter ()
    {
        return fileFilter;
    }

    public void setFileFilter ( final AbstractFileFilter fileFilter )
    {
        setFileFilter ( fileFilter, true );
    }

    public void setFileFilter ( final AbstractFileFilter fileFilter, final boolean updatePath )
    {
        this.fileFilter = fileFilter;
        if ( updatePath )
        {
            updatePath ();
        }
    }

    public boolean isFilesDropEnabled ()
    {
        return filesDropEnabled;
    }

    public void setFilesDropEnabled ( final boolean filesDropEnabled )
    {
        this.filesDropEnabled = filesDropEnabled;
    }

    public File getSelectedPath ()
    {
        return selectedPath;
    }

    public void setSelectedPath ( final File selectedPath )
    {
        updatePath ( selectedPath );
    }

    public WebTextField getPathField ()
    {
        return pathField;
    }

    public void updatePath ()
    {
        updatePath ( selectedPath );
    }

    protected synchronized void updatePath ( final File path )
    {
        // todo check if path is proper (filter/hidden)

        // todo Save focused state properly
        // Saving focus state
        // boolean hadFocus = focusOwner;

        // Saving new path
        selectedPath = path;

        // Clearing old path components
        pathField.removeFocusListener ( pathFocusListener );
        contentPanel.removeAll ();

        // Determining orientation
        final boolean ltr = WebPathField.this.getComponentOrientation ().isLeftToRight ();

        // Determining root
        if ( SystemUtils.isWindows () )
        {
            final WebButton computerButton = getMyComputer ();
            contentPanel.add ( computerButton );
            contentPanel.add ( getRootsArrowButton ( ltr ) );
        }

        if ( selectedPath != null )
        {
            // Creating parents list
            File folder = new File ( selectedPath.getAbsolutePath () );
            final List parents = new ArrayList ();
            parents.add ( 0, folder );
            while ( folder.getParent () != null )
            {
                folder = folder.getParentFile ();
                parents.add ( 0, folder );
            }

            // Adding path buttons
            boolean first = true;
            for ( final File file : parents )
            {
                final WebButton wb = new WebButton ( StyleId.pathfieldElementButton.at ( contentPanel ) );
                if ( !SystemUtils.isWindows () && first )
                {
                    wb.setIcon ( FileUtils.getMyComputerIcon () );
                    wb.putClientProperty ( FILE_ICON, FileUtils.getMyComputerIcon () );
                }
                else
                {
                    wb.setText ( fsv.getSystemDisplayName ( file ) );
                    wb.putClientProperty ( FILE_ICON, FileUtils.getFileIcon ( file, false ) );
                }
                wb.addActionListener ( new ActionListener ()
                {
                    @Override
                    public void actionPerformed ( final ActionEvent e )
                    {
                        folderSelected ( file );
                    }
                } );
                contentPanel.add ( wb );

                int childrenCount = 0;
                final WebPopupMenu menu = new WebPopupMenu ();
                final File[] files = FileUtils.sortFiles ( getFileChildren ( file ) );
                if ( files != null )
                {
                    for ( final File root : files )
                    {
                        if ( root.isDirectory () )
                        {
                            final WebMenuItem menuItem = new WebMenuItem ( FileUtils.getDisplayFileName ( root ) );
                            menuItem.setIcon ( FileUtils.getFileIcon ( root, false ) );
                            menuItem.addActionListener ( new ActionListener ()
                            {
                                @Override
                                public void actionPerformed ( final ActionEvent e )
                                {
                                    folderSelected ( root );
                                }
                            } );
                            menu.add ( menuItem );
                            childrenCount++;
                        }
                    }
                }
                if ( !SystemUtils.isWindows () && first )
                {
                    setRootsMenu ( menu, childrenCount );
                }

                final WebToggleButton children = new WebToggleButton ( StyleId.pathfieldMenuToggleButton.at ( contentPanel ) );
                children.setIcon ( ltr ? right : left );
                children.setSelectedIcon ( down );
                children.setComponentPopupMenu ( menu );
                children.setEnabled ( childrenCount > 0 );
                children.addActionListener ( new ActionListener ()
                {
                    @Override
                    public void actionPerformed ( final ActionEvent e )
                    {
                        // todo Apply orientation globally on change, not here
                        WebPathField.this.transferFocus ();
                        SwingUtils.applyOrientation ( menu );
                        menu.showBelowMiddle ( children );
                    }
                } );
                contentPanel.add ( children );

                menu.addPopupMenuListener ( new PopupMenuListener ()
                {
                    @Override
                    public void popupMenuWillBecomeVisible ( final PopupMenuEvent e )
                    {
                        //
                    }

                    @Override
                    public void popupMenuWillBecomeInvisible ( final PopupMenuEvent e )
                    {
                        children.setSelected ( false );
                    }

                    @Override
                    public void popupMenuCanceled ( final PopupMenuEvent e )
                    {
                        children.setSelected ( false );
                    }
                } );

                first = false;
            }
        }

        // Filling space
        contentPanel.add ( new JLabel () );

        // Shortening long elements
        if ( !SystemUtils.isWindows () )
        {
            while ( getRootsMenu ().getComponentCount () > getRootsMenuItemsCount () )
            {
                getRootsMenu ().remove ( 0 );
            }
        }
        if ( canShortenPath () )
        {
            getRootsMenu ().addSeparator ( 0 );
        }
        while ( canShortenPath () )
        {
            // Adding menu element
            final WebButton wb = ( WebButton ) contentPanel.getComponent ( 2 );
            final WebMenuItem menuItem = new WebMenuItem ();
            menuItem.setIcon ( ( Icon ) wb.getClientProperty ( FILE_ICON ) );
            menuItem.setText ( wb.getText () );
            menuItem.addActionListener ( wb.getActionListeners ()[ 0 ] );
            getRootsMenu ().add ( menuItem, 0 );

            // Removing hidden path and menu buttons from panel
            contentPanel.remove ( 2 );
            contentPanel.remove ( 2 );
        }

        // Updating pane
        revalidate ();
        repaint ();
    }

    protected List getSimilarFileChildren ( final File file, final String namePart )
    {
        final String searchText = namePart.toLowerCase ( Locale.ROOT );
        final File[] children = getFileChildren ( file );
        final List similar = new ArrayList ();
        if ( children != null )
        {
            for ( final File child : children )
            {
                if ( child.getName ().toLowerCase ( Locale.ROOT ).contains ( searchText ) )
                {
                    similar.add ( child );
                }
            }
        }
        return similar;
    }

    protected File[] getFileChildren ( final File file )
    {
        return file != null ? file.listFiles ( fileFilter ) : FileUtils.getDiskRoots ();
    }

    protected boolean canShortenPath ()
    {
        return contentPanel.getPreferredSize ().width > contentPanel.getWidth () && contentPanel.getComponentCount () > 5;
    }

    protected WebButton getMyComputer ()
    {
        if ( myComputer == null )
        {
            myComputer = new WebButton ( StyleId.pathfieldRootButton.at ( contentPanel ), FileUtils.getMyComputerIcon () );
            myComputer.addActionListener ( new ActionListener ()
            {
                @Override
                public void actionPerformed ( final ActionEvent e )
                {
                    folderSelected ( null );
                }
            } );
        }
        return myComputer;
    }

    public WebPopupMenu getRootsMenu ()
    {
        return rootsMenu;
    }

    public int getRootsMenuItemsCount ()
    {
        return rootsMenuItemsCount;
    }

    public void setRootsMenu ( final WebPopupMenu rootsMenu, final int childrenCount )
    {
        this.rootsMenu = rootsMenu;
        this.rootsMenuItemsCount = childrenCount;
    }

    protected WebToggleButton getRootsArrowButton ( final boolean ltr )
    {
        if ( rootsArrowButton == null )
        {
            rootsMenu = new WebPopupMenu ();

            final File[] rootFiles = FileUtils.getDiskRoots ();
            for ( final File root : FileUtils.sortFiles ( rootFiles ) )
            {
                final WebMenuItem menuItem = new WebMenuItem ( FileUtils.getDisplayFileName ( root ) );
                menuItem.setIcon ( FileUtils.getFileIcon ( root, false ) );
                menuItem.addActionListener ( new ActionListener ()
                {
                    @Override
                    public void actionPerformed ( final ActionEvent e )
                    {
                        folderSelected ( root );
                    }
                } );
                rootsMenu.add ( menuItem );
                rootsMenuItemsCount++;
            }

            rootsArrowButton = new WebToggleButton ( StyleId.pathfieldMenuToggleButton.at ( contentPanel ) );
            rootsArrowButton.setIcon ( ltr ? right : left );
            rootsArrowButton.setSelectedIcon ( down );
            rootsArrowButton.setComponentPopupMenu ( rootsMenu );
            rootsArrowButton.addActionListener ( new ActionListener ()
            {
                @Override
                public void actionPerformed ( final ActionEvent e )
                {
                    WebPathField.this.transferFocus ();
                    SwingUtils.applyOrientation ( rootsMenu );
                    rootsMenu.showBelowMiddle ( rootsArrowButton );
                }
            } );

            rootsMenu.addPopupMenuListener ( new PopupMenuListener ()
            {
                @Override
                public void popupMenuWillBecomeVisible ( final PopupMenuEvent e )
                {

                }

                @Override
                public void popupMenuWillBecomeInvisible ( final PopupMenuEvent e )
                {
                    rootsArrowButton.setSelected ( false );
                }

                @Override
                public void popupMenuCanceled ( final PopupMenuEvent e )
                {
                    rootsArrowButton.setSelected ( false );
                }
            } );
        }
        else
        {
            rootsArrowButton.setIcon ( ltr ? right : left );
        }
        while ( rootsMenu.getComponentCount () > rootsMenuItemsCount )
        {
            rootsMenu.remove ( 0 );
        }
        return rootsArrowButton;
    }

    protected void folderSelected ( File folder )
    {
        // Normalize file
        folder = FileUtils.normalize ( folder );

        // Update visual path
        updatePath ( folder );

        // Notify about selection change
        fireDirectoryChanged ( folder );

        // Requesting focus as it is internal change from internal event
        WebPathField.this.transferFocus ();
    }

    public void addPathFieldListener ( final PathFieldListener listener )
    {
        listeners.add ( listener );
    }

    public void removePathFieldListener ( final PathFieldListener listener )
    {
        listeners.remove ( listener );
    }

    protected void fireDirectoryChanged ( final File newDirectory )
    {
        for ( final PathFieldListener listener : CollectionUtils.copy ( listeners ) )
        {
            listener.directoryChanged ( newDirectory );
        }
    }

    @Override
    public void applyComponentOrientation ( final ComponentOrientation o )
    {
        super.applyComponentOrientation ( o );
        updatePath ();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy