com.alee.extended.filechooser.WebDirectoryChooserPanel 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.layout.ToolbarLayout;
import com.alee.extended.tree.FileTreeNode;
import com.alee.extended.tree.FileTreeRootType;
import com.alee.extended.tree.WebFileTree;
import com.alee.global.GlobalConstants;
import com.alee.laf.button.WebButton;
import com.alee.laf.optionpane.WebOptionPane;
import com.alee.laf.panel.WebPanel;
import com.alee.laf.scroll.WebScrollPane;
import com.alee.laf.toolbar.ToolbarStyle;
import com.alee.laf.toolbar.WebToolBar;
import com.alee.managers.hotkey.Hotkey;
import com.alee.managers.language.LanguageManager;
import com.alee.managers.language.data.TooltipWay;
import com.alee.managers.tooltip.TooltipManager;
import com.alee.utils.CollectionUtils;
import com.alee.utils.FileUtils;
import com.alee.utils.filefilter.AbstractFileFilter;
import javax.swing.*;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.TreeSelectionModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
* This custom component provides a directory chooser functionality.
* It similar to file chooser component but has its own unique interface and doesn't need a lot of configuring to use.
*
* @author Mikle Garin
*/
public class WebDirectoryChooserPanel extends WebPanel
{
/**
* Used icons.
*/
protected static final ImageIcon FOLDER_UP_ICON =
new ImageIcon ( WebDirectoryChooserPanel.class.getResource ( "icons/folder_up.png" ) );
protected static final ImageIcon FOLDER_HOME_ICON =
new ImageIcon ( WebDirectoryChooserPanel.class.getResource ( "icons/folder_home.png" ) );
protected static final ImageIcon FOLDER_NEW_ICON =
new ImageIcon ( WebDirectoryChooserPanel.class.getResource ( "icons/folder_new.png" ) );
protected static final ImageIcon REFRESH_ICON = new ImageIcon ( WebDirectoryChooserPanel.class.getResource ( "icons/refresh.png" ) );
protected static final ImageIcon REMOVE_ICON = new ImageIcon ( WebDirectoryChooserPanel.class.getResource ( "icons/remove.png" ) );
/**
* Directory chooser listeners.
*/
protected List listeners = new ArrayList ( 1 );
/**
* Currently selected directory.
*/
protected File selectedDirectory = FileUtils.getDiskRoots ()[ 0 ];
/**
* File filter.
*/
protected AbstractFileFilter filter = GlobalConstants.NON_HIDDEN_DIRECTORIES_FILTER;
/**
* Toolbar components.
*/
protected WebButton folderUp;
protected WebButton folderHome;
protected WebButton folderNew;
protected WebButton refresh;
protected WebButton remove;
/**
* Path field.
*/
protected WebPathField webPathField;
/**
* File tree.
*/
protected WebFileTree fileTree;
protected TreeSelectionListener fileTreeListener;
/**
* Constructs new directory chooser panel.
*/
public WebDirectoryChooserPanel ()
{
super ();
// Panel settings
setOpaque ( true );
// Controls pane
final WebToolBar contolsToolbar = new WebToolBar ( WebToolBar.HORIZONTAL );
contolsToolbar.setToolbarStyle ( ToolbarStyle.attached );
contolsToolbar.setFloatable ( false );
folderUp = new WebButton ( FOLDER_UP_ICON );
folderUp.setLanguage ( "weblaf.ex.dirchooser.folderup" );
folderUp.addHotkey ( WebDirectoryChooserPanel.this, Hotkey.ALT_UP ).setHotkeyDisplayWay ( TooltipWay.down );
folderUp.setRolloverDecoratedOnly ( true );
folderUp.addActionListener ( new ActionListener ()
{
@Override
public void actionPerformed ( final ActionEvent e )
{
if ( selectedDirectory != null )
{
updateSelectedDirectory ( selectedDirectory.getParentFile (), true, true );
}
}
} );
contolsToolbar.add ( folderUp );
folderHome = new WebButton ( FOLDER_HOME_ICON );
folderHome.setLanguage ( "weblaf.ex.dirchooser.home" );
folderHome.addHotkey ( WebDirectoryChooserPanel.this, Hotkey.ALT_H ).setHotkeyDisplayWay ( TooltipWay.trailing );
folderHome.setRolloverDecoratedOnly ( true );
folderHome.addActionListener ( new ActionListener ()
{
@Override
public void actionPerformed ( final ActionEvent e )
{
updateSelectedDirectory ( FileUtils.getUserHome (), true, true );
}
} );
contolsToolbar.add ( folderHome );
contolsToolbar.addSeparator ();
for ( final File file : FileTreeRootType.drives.getRoots () )
{
final WebButton root = new WebButton ( FileUtils.getFileIcon ( file ) );
TooltipManager.setTooltip ( root, FileUtils.getDisplayFileName ( file ) );
root.setRolloverDecoratedOnly ( true );
root.addActionListener ( new ActionListener ()
{
@Override
public void actionPerformed ( final ActionEvent e )
{
updateSelectedDirectory ( file, true, true );
}
} );
contolsToolbar.add ( root );
}
refresh = new WebButton ( REFRESH_ICON );
refresh.setLanguage ( "weblaf.ex.dirchooser.refresh" );
refresh.addHotkey ( WebDirectoryChooserPanel.this, Hotkey.F5 ).setHotkeyDisplayWay ( TooltipWay.leading );
refresh.setRolloverDecoratedOnly ( true );
refresh.addActionListener ( new ActionListener ()
{
@Override
public void actionPerformed ( final ActionEvent e )
{
if ( selectedDirectory != null )
{
fileTree.reloadChilds ( selectedDirectory );
}
else
{
fileTree.reloadRootNode ();
}
}
} );
contolsToolbar.add ( refresh, ToolbarLayout.END );
folderNew = new WebButton ( FOLDER_NEW_ICON );
folderNew.setLanguage ( "weblaf.ex.dirchooser.newfolder" );
folderNew.addHotkey ( WebDirectoryChooserPanel.this, Hotkey.CTRL_N ).setHotkeyDisplayWay ( TooltipWay.down );
folderNew.setRolloverDecoratedOnly ( true );
folderNew.addActionListener ( new ActionListener ()
{
@Override
public void actionPerformed ( final ActionEvent e )
{
if ( selectedDirectory != null )
{
final String defaultName = LanguageManager.get ( "weblaf.ex.dirchooser.newfolder.name" );
final String freeName = FileUtils.getAvailableName ( selectedDirectory, defaultName );
final File file = new File ( selectedDirectory, freeName );
if ( file.mkdir () )
{
// Updating filestree
fileTree.addFile ( selectedDirectory, file );
// Editing added folder name
fileTree.startEditingFile ( file );
}
else
{
final String message = LanguageManager.get ( "weblaf.ex.dirchooser.newfolder.error.text" );
final String title = LanguageManager.get ( "weblaf.ex.dirchooser.newfolder.error.title" );
WebOptionPane.showMessageDialog ( WebDirectoryChooserPanel.this, message, title, WebOptionPane.ERROR_MESSAGE );
}
}
}
} );
contolsToolbar.add ( folderNew, ToolbarLayout.END );
remove = new WebButton ( REMOVE_ICON );
remove.setLanguage ( "weblaf.ex.dirchooser.delete" );
remove.addHotkey ( WebDirectoryChooserPanel.this, Hotkey.DELETE ).setHotkeyDisplayWay ( TooltipWay.down );
remove.setRolloverDecoratedOnly ( true );
remove.addActionListener ( new ActionListener ()
{
@Override
public void actionPerformed ( final ActionEvent e )
{
final File file = fileTree.getSelectedFile ();
if ( file == null )
{
return;
}
// Displaying delete confirmation
final String message = LanguageManager.get ( "weblaf.ex.dirchooser.delete.confirm.text" );
final String title = LanguageManager.get ( "weblaf.ex.dirchooser.delete.confirm.title" );
final int confirm = WebOptionPane
.showConfirmDialog ( WebDirectoryChooserPanel.this, message, title, WebOptionPane.YES_NO_OPTION,
WebOptionPane.QUESTION_MESSAGE );
// Proceed if delete was confirmed
if ( confirm == WebOptionPane.YES_OPTION )
{
// Retrieving index of deleted file node in parent node
final FileTreeNode parentNode = fileTree.getSelectedNode ().getParent ();
final int index = parentNode.indexOfFileChild ( file );
final int count = parentNode.getChildCount ();
// Removing file
FileUtils.deleteFile ( file );
fileTree.removeFile ( file );
// Restoring selection
fileTree.setSelectedNode ( count == 1 ? parentNode :
( index < count - 1 ? parentNode.getChildAt ( index ) : parentNode.getChildAt ( index - 1 ) ) );
}
}
} );
contolsToolbar.add ( remove, ToolbarLayout.END );
// Path field
webPathField = new WebPathField ( selectedDirectory );
webPathField.setFileFilter ( filter );
webPathField.addPathFieldListener ( new PathFieldListener ()
{
@Override
public void directoryChanged ( final File newDirectory )
{
updateSelectedDirectory ( webPathField.getSelectedPath (), false, true );
}
} );
// Files tree
fileTree = new WebFileTree ( FileTreeRootType.drives );
fileTree.setVisibleRowCount ( 15 );
fileTree.setFileFilter ( filter );
fileTree.setSelectedFile ( selectedDirectory, true );
fileTree.setSelectionMode ( TreeSelectionModel.SINGLE_TREE_SELECTION );
fileTree.setEditable ( true );
// Selected directory update
fileTreeListener = new TreeSelectionListener ()
{
@Override
public void valueChanged ( final TreeSelectionEvent e )
{
updateSelectedDirectory ( fileTree.getSelectedFile (), true, false );
}
};
fileTree.addTreeSelectionListener ( fileTreeListener );
// Toolbar update
fileTree.addTreeSelectionListener ( new TreeSelectionListener ()
{
@Override
public void valueChanged ( final TreeSelectionEvent e )
{
updateToolbarControlsState ();
}
} );
// Tree scroll
final WebScrollPane treeScroll = new WebScrollPane ( fileTree );
treeScroll.setPreferredWidth ( 400 );
// Panel content
setLayout ( new BorderLayout ( 0, 3 ) );
add ( contolsToolbar, BorderLayout.NORTH );
final WebPanel panel = new WebPanel ( new BorderLayout ( 0, 1 ) );
panel.setMargin ( 0, 3, 2, 3 );
panel.add ( webPathField, BorderLayout.NORTH );
panel.add ( treeScroll, BorderLayout.CENTER );
add ( panel, BorderLayout.CENTER );
updateSelectedDirectory ( null, true, true );
updateToolbarControlsState ();
}
/**
* Updates toolbar controls state.
*/
protected void updateToolbarControlsState ()
{
final File selectedFile = fileTree.getSelectedFile ();
folderUp.setEnabled ( selectedFile != null && selectedFile.getParentFile () != null );
folderNew.setEnabled ( selectedFile != null && selectedFile.canWrite () );
remove.setEnabled ( selectedFile != null && selectedFile.getParentFile () != null &&
selectedFile.canWrite () );
}
/**
* Updates currently selected directory.
*
* @param directory directory to select
* @param updatePath whether to update path field or not
* @param updateTree whether to update file tree or not
*/
protected void updateSelectedDirectory ( final File directory, final boolean updatePath, final boolean updateTree )
{
this.selectedDirectory = directory;
if ( updatePath )
{
webPathField.setSelectedPath ( directory );
}
if ( updateTree )
{
if ( directory != null )
{
fileTree.expandToFile ( directory, false, true, new Runnable ()
{
@Override
public void run ()
{
fileTree.removeTreeSelectionListener ( fileTreeListener );
fileTree.setSelectedNode ( fileTree.getNode ( directory ) );
fileTree.addTreeSelectionListener ( fileTreeListener );
}
} );
}
else
{
fileTree.clearSelection ();
fileTree.scrollToStart ();
}
}
fireSelectionChanged ( this.selectedDirectory );
}
/**
* Returns directory chooser file filter.
*
* @return directory chooser file filter
*/
public AbstractFileFilter getFilter ()
{
return filter;
}
/**
* Sets directory chooser file filter.
*
* @param filter directory chooser file filter
*/
public void setFilter ( final AbstractFileFilter filter )
{
this.filter = filter;
fileTree.setFileFilter ( filter );
}
/**
* Returns currently selected directory.
*
* @return currently selected directory
*/
public File getSelectedDirectory ()
{
return selectedDirectory;
}
/**
* Sets currently selected directory.
*
* @param selectedDirectory currently selected directory
*/
public void setSelectedDirectory ( final File selectedDirectory )
{
updateSelectedDirectory ( selectedDirectory, true, true );
}
/**
* Returns whether hotkeys are allowed or not.
*
* @return true if hotkeys are allowed, false otherwise
*/
public boolean allowHotkeys ()
{
// todo Remove this when hotkeys system will get updated
return !fileTree.isEditing () && !webPathField.isEditing () /*&& !fileList.isEditing()*/;
}
/**
* Adds directory chooser listener.
*
* @param listener directory chooser listener to add
*/
public void addDirectoryChooserListener ( final DirectoryChooserListener listener )
{
listeners.add ( listener );
}
/**
* Removes directory chooser listener.
*
* @param listener directory chooser listener to remove
*/
public void removeDirectoryChooserListener ( final DirectoryChooserListener listener )
{
listeners.remove ( listener );
}
/**
* Fires when directory selection changed.
*
* @param file newly selected directory
*/
protected void fireSelectionChanged ( final File file )
{
for ( final DirectoryChooserListener listener : CollectionUtils.copy ( listeners ) )
{
listener.selectionChanged ( file );
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy