`

Directory Chooser API

    博客分类:
  • Java
阅读更多

Java swing provides File chooser but, it doesn't provide any direct support for directory chooser. Following code helps to create a system directory chooser

 

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.Arrays;
import java.util.Enumeration;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.UIManager;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.filechooser.FileSystemView;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;

public class DirectoryChooser extends JTree implements TreeSelectionListener,
  MouseListener {

 private static FileSystemView fsv = FileSystemView.getFileSystemView();

 /* --- Begin Public API ----- */

 public DirectoryChooser() {
  this(null);
 }

 public DirectoryChooser(File dir) {
  super(new DirNode(fsv.getRoots()[0]));
  getSelectionModel().setSelectionMode(
    TreeSelectionModel.SINGLE_TREE_SELECTION);
  setSelectedDirectory(dir);
  addTreeSelectionListener(this);
  addMouseListener(this);
 }

 public void setSelectedDirectory(File dir) {
  if (dir == null) {
   dir = fsv.getDefaultDirectory();
  }
  setSelectionPath(mkPath(dir));
 }

 public File getSelectedDirectory() {
  DirNode node = (DirNode) getLastSelectedPathComponent();
  if (node != null) {
   File dir = node.getDir();
   if (fsv.isFileSystem(dir)) {
    return dir;
   }
  }
  return null;
 }

 public void addActionListener(ActionListener l) {
  listenerList.add(ActionListener.class, l);
 }

 public void removeActionListener(ActionListener l) {
  listenerList.remove(ActionListener.class, l);
 }

 public ActionListener[] getActionListeners() {
  return (ActionListener[]) listenerList
    .getListeners(ActionListener.class);
 }

 /* --- End Public API ----- */

 /* --- TreeSelectionListener Interface ----- */

 public void valueChanged(TreeSelectionEvent ev) {
  File oldDir = null;
  TreePath oldPath = ev.getOldLeadSelectionPath();
  if (oldPath != null) {
   oldDir = ((DirNode) oldPath.getLastPathComponent()).getDir();
   if (!fsv.isFileSystem(oldDir)) {
    oldDir = null;
   }
  }
  File newDir = getSelectedDirectory();
  firePropertyChange("selectedDirectory", oldDir, newDir);
 }

 /* --- MouseListener Interface ----- */

 public void mousePressed(MouseEvent e) {
  if (e.getClickCount() == 2) {
   TreePath path = getPathForLocation(e.getX(), e.getY());
   if (path != null && path.equals(getSelectionPath())
     && getSelectedDirectory() != null) {

    fireActionPerformed("dirSelected", e);
   }
  }
 }

 public void mouseReleased(MouseEvent e) {
 }

 public void mouseClicked(MouseEvent e) {
 }

 public void mouseEntered(MouseEvent e) {
 }

 public void mouseExited(MouseEvent e) {
 }

 /* --- Private Section ------ */

 private TreePath mkPath(File dir) {
  DirNode root = (DirNode) getModel().getRoot();
  if (root.getDir().equals(dir)) {
   return new TreePath(root);
  }

  TreePath parentPath = mkPath(fsv.getParentDirectory(dir));
  DirNode parentNode = (DirNode) parentPath.getLastPathComponent();
  Enumeration enumeration = parentNode.children();
  while (enumeration.hasMoreElements()) {
   DirNode child = (DirNode) enumeration.nextElement();
   if (child.getDir().equals(dir)) {
    return parentPath.pathByAddingChild(child);
   }
  }
  return null;
 }

 private void fireActionPerformed(String command, InputEvent evt) {
  ActionEvent e = new ActionEvent(this, ActionEvent.ACTION_PERFORMED,
    command, evt.getWhen(), evt.getModifiers());
  ActionListener[] listeners = getActionListeners();
  for (int i = listeners.length - 1; i >= 0; i--) {
   listeners[i].actionPerformed(e);
  }
 }

 private static class DirNode extends DefaultMutableTreeNode {
  DirNode(File dir) {
   super(dir);
  }

  public File getDir() {
   return (File) userObject;
  }

  public int getChildCount() {
   populateChildren();
   return super.getChildCount();
  }

  public Enumeration children() {
   populateChildren();
   return super.children();
  }

  public boolean isLeaf() {
   return false;
  }

  private void populateChildren() {
   if (children == null) {
    File[] files = fsv.getFiles(getDir(), true);
    Arrays.sort(files);
    for (int i = 0; i < files.length; i++) {
     File f = files[i];
     if (fsv.isTraversable(f).booleanValue()) {
      insert(new DirNode(f), (children == null) ? 0
        : children.size());
     }
    }
   }
  }

  public String toString() {
   return fsv.getSystemDisplayName(getDir());
  }

  public boolean equals(Object o) {
   return (o instanceof DirNode && userObject
     .equals(((DirNode) o).userObject));
  }
 }

 /* --- Main for testing --- */

 public static void main(String[] args) {
  try {
   UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
  } catch (Exception ex) {
  }

  final JDialog dialog = new JDialog((JFrame) null, true);
  final DirectoryChooser dc = new DirectoryChooser();
  final JButton okButton = new JButton("OK");
  final JButton cancelButton = new JButton("Cancel");

  dialog.getContentPane().add(new JScrollPane(dc), BorderLayout.CENTER);

  JPanel buttonPanel = new JPanel();
  buttonPanel.add(okButton);
  buttonPanel.add(cancelButton);
  dialog.getContentPane().add(buttonPanel, BorderLayout.SOUTH);

  ActionListener actionListener = new ActionListener() {
   public void actionPerformed(ActionEvent e) {
    Object c = e.getSource();
    if (c == okButton || c == dc) {
     System.out.println("You selected: "
       + dc.getSelectedDirectory());
    }
    dialog.hide();
   }
  };

  dc.addActionListener(actionListener);
  okButton.addActionListener(actionListener);
  cancelButton.addActionListener(actionListener);

  dc.addPropertyChangeListener(new PropertyChangeListener() {
   public void propertyChange(PropertyChangeEvent ev) {
    if (ev.getPropertyName().equals("selectedDirectory")) {
     okButton.setEnabled(dc.getSelectedDirectory() != null);
    }
   }
  });

  dialog.setBounds(200, 200, 300, 350);
  dc.scrollRowToVisible(Math.max(0, dc.getMinSelectionRow() - 4));
  dialog.show();
  System.exit(0);
 }
}

分享到:
评论

相关推荐

    im-chooser-0.5.3-1.fc8.i386

    标题“im-chooser-0.5.3-1.fc8.i386”指的是一个特定版本的输入法选择器软件,适用于Linux操作系统中的Fedora 8(FEDORA9的错误描述可能是笔误)。这个软件的主要功能是为用户提供一个界面,以便在多种不同的输入法...

    ImageChooser:一个Android ImageChooser

    在 Android 6.0(API 级别 23)及更高版本,必须在运行时请求存储和相机权限。在 AndroidManifest.xml 文件中声明相应的 `&lt;uses-permission&gt;` 标签是不够的,还需要在运行时使用 `requestPermissions()` 方法来请求...

    Pantone_Color_Chooser

    Pantone Color Chooser是一款专为纺织业设计的色彩选择工具,它以其直观易用的特点,为设计师们提供了一个高效、准确的色彩参考平台。 Pantone色卡是全球公认的色彩标准,被广泛应用于各行各业,尤其是纺织品设计。...

    im-chooser-common-1.6.4-4.el7.x86_64.rpm

    离线安装包,亲测可用

    Python库 | djangocms-lang-chooser-0.1.0.tar.gz

    4. **集成**:在Django CMS的模板中,使用提供的模板标签或JavaScript API来渲染语言选择器。 5. **测试**:确保语言切换功能正常工作,且不影响其他功能。 **文件结构** 在解压缩后的`djangocms-lang-chooser-...

    PyPI 官网下载 | wagtail_generic_chooser-0.2.1-py3-none-any.whl

    3. 可能包含与Wagtail的模型集成的API,使得在后台编辑时能够方便地插入或链接到不同数据类型的内容。 4. 可能提供了一些定制化的视图和模板,以适应不同类型的交互和展示需求。 为了使用`wagtail_generic_chooser`...

    48.Chooser CompoundChooserandStraddle1114.xls

    48.Chooser CompoundChooserandStraddle1114.xls

    android the file chooser manager

    在Android平台上,文件选择器管理器("android the file chooser manager")是一个至关重要的组件,它允许用户在应用中选择本地存储的文件。文件选择器是Android应用与用户交互,处理文件操作的关键部分,比如读取、...

    DNS Chooser

    DNS Chooser是一款实用工具,主要用于帮助用户选择和切换不同的DNS(域名系统)服务器。在日常网络使用中,DNS是互联网的重要组成部分,它负责将我们输入的网址(如www.example.com)转换为对应的IP地址(如192.168....

    CM魅族主题(含Theme Chooser)

    CM魅族主题是一款专为魅族手机用户设计的个性化主题应用,其中包含了Theme Chooser功能。这个主题包不仅提供了丰富的视觉样式,还允许用户自定义手机界面,打造出独特的操作体验。下面将详细介绍CM魅族主题及其相关...

    jcalendar -java calendar chooser

    6. **API丰富**:JCalendar提供了丰富的API接口,允许开发者轻松地设置日期范围限制、禁用特定日期、添加自定义的日期标记等功能。 7. **事件处理**:JCalendar支持多种事件处理,例如日期选择事件、面板显示事件等...

    file_chooser:安全无效的file_chooser

    Flutter的桌面嵌入 该项目最初是为了开发Windows,macOS和Linux嵌入式而创建的。 自那以后,这项工作已成为Flutter的一部分,这里剩下的只是实验性的,早期阶段的桌面。 如果要在台式机上开始使用Flutter,现在开始...

    l2fprod-common

    Swing已经构建很多组件,但是还有一些比较流行的组件没有提供.这个开源项目刚好提供这些少掉的组件.l2fprod-common提供的组件有:PropertySheet,collapsible task pane,button bar,font chooser,directory chooser

    wagtail-generic-chooser:Wagtail中用于自定义选择器弹出窗口的工具包

    它与现有的模型选择器附加组件( , , )不同,其设计目的是可以通过子类进行完全配置-特别是,它可以用于Django模型以外的数据源,例如REST API端点。 打算将wagtail-generic-chooser扩展到涵盖Wagtail内置...

    JavaScript应用实例-file_chooser_dialog.js

    JavaScript应用实例-file_chooser_dialog.js

    Unit11_Launcher_Chooser.zip_launcher

    在Windows Phone平台上,"launcher"和"chooser"是两个关键的概念,它们对于应用程序与系统交互、提供用户友好的体验起着至关重要的作用。本主题将深入探讨这两个概念以及如何在实际开发中应用。 首先,"launcher"...

    jqgrid-columnchooser:保存和重新排序数据库中的列位置

    jqgrid-columnchooser 从数据库中保存和加载列位置。 这是魔法发生的地方: 第一:关于保存列位置 $table . jqGrid ( 'navButtonAdd' , pagerId , { caption : "Select Columns" , buttonicon : 'ui-icon-carat-2-n-...

    Digit Chooser-crx插件

    "Digit Chooser-crx插件"是一款专为英文用户设计的浏览器扩展程序,它提供了一个实用的功能,即显示页面上每个字符对应的数字位置。这款工具的目的是为了帮助用户更轻松地满足某些特定场景下的输入需求,例如在访问...

    AutoJs源码-file-chooser-dialog

    AutoJs源码-file_chooser_dialog。本资源购买前提醒:本源码都是实际autojs项目模板,安装好autojs直接运行即可打开。1、支持低版本autojs。2、资源仅供学习与参考,请勿用于商业用途,否则产生的一切后果将由您自己...

Global site tag (gtag.js) - Google Analytics