phex.gui.tabs.library.LibraryTreePane.java Source code

Java tutorial

Introduction

Here is the source code for phex.gui.tabs.library.LibraryTreePane.java

Source

/*
 *  PHEX - The pure-java Gnutella-servent.
 *  Copyright (C) 2001 - 2008 Phex Development Group
 *
 *  This program 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 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 * 
 *  --- SVN Information ---
 *  $Id: LibraryTreePane.java 4412 2009-03-22 13:40:44Z ArneBab $
 */
package phex.gui.tabs.library;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import java.io.IOException;

import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.ToolTipManager;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;

import org.apache.commons.lang.SystemUtils;

import phex.common.Environment;
import phex.common.log.NLogger;
import phex.gui.actions.FWAction;
import phex.gui.actions.GUIActionPerformer;
import phex.gui.common.FWPopupMenu;
import phex.gui.common.FWToolBar;
import phex.gui.common.FileDialogHandler;
import phex.gui.common.GUIRegistry;
import phex.prefs.core.LibraryPrefs;
import phex.servent.Servent;
import phex.share.SharedDirectory;
import phex.share.SharedFilesService;
import phex.utils.DirectoryOnlyFileFilter;
import phex.utils.Localizer;
import phex.utils.SystemShellExecute;

import com.jgoodies.forms.builder.PanelBuilder;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;

public class LibraryTreePane extends JPanel {
    private Component parent;
    private SharingTreeModel sharingTreeModel;
    private JTree mainTree;
    private FWPopupMenu fileTreePopup;

    private AddShareFolderAction addShareFolderAction;
    private RemoveShareFolderAction removeShareFolderAction;
    private ExploreFolderAction exploreFolderAction;

    public LibraryTreePane(Component parent) {
        this.parent = parent;
        prepareComponent();
    }

    public void addTreeSelectionListener(TreeSelectionListener listener) {
        mainTree.getSelectionModel().addTreeSelectionListener(listener);
    }

    public void appendPopupSeparator() {
        fileTreePopup.addSeparator();
    }

    public void appendPopupAction(FWAction action) {
        fileTreePopup.addAction(action);
    }

    public LibraryNode getSelectedTreeComponent() {
        TreePath path = mainTree.getSelectionPath();
        if (path == null) {
            return null;
        }
        LibraryNode node = (LibraryNode) path.getLastPathComponent();
        return node;
    }

    public void updateFileSystem() {
        sharingTreeModel.updateFileSystem();
    }

    /**
     * 
     */
    private void refreshActions() {
        addShareFolderAction.refreshActionState();
        removeShareFolderAction.refreshActionState();
        if (exploreFolderAction != null) {
            exploreFolderAction.refreshActionState();
        }
    }

    private void prepareComponent() {
        CellConstraints cc = new CellConstraints();
        FormLayout layout = new FormLayout("fill:d:grow", // columns
                "fill:d:grow, 1dlu, p"); //rows
        PanelBuilder tabBuilder = new PanelBuilder(layout, this);

        sharingTreeModel = new SharingTreeModel();
        mainTree = new JTree(sharingTreeModel);
        mainTree.setMinimumSize(new Dimension(0, 0));
        mainTree.setRowHeight(0);
        mainTree.setCellRenderer(new SharingTreeRenderer());
        mainTree.addMouseListener(new MouseHandler());

        mainTree.getSelectionModel().addTreeSelectionListener(new SelectionHandler());
        ToolTipManager.sharedInstance().registerComponent(mainTree);

        // open up first level of nodes
        TreeNode root = (TreeNode) sharingTreeModel.getRoot();
        int count = root.getChildCount();
        for (int i = 0; i < count; i++) {
            mainTree.expandPath(new TreePath(new Object[] { root, root.getChildAt(i) }));
        }

        JScrollPane treeScrollPane = new JScrollPane(mainTree);
        tabBuilder.add(treeScrollPane, cc.xywh(1, 1, 1, 1));

        FWToolBar shareToolbar = new FWToolBar(FWToolBar.HORIZONTAL);
        shareToolbar.setBorderPainted(false);
        shareToolbar.setFloatable(false);
        tabBuilder.add(shareToolbar, cc.xy(1, 3));

        addShareFolderAction = new AddShareFolderAction();
        shareToolbar.addAction(addShareFolderAction);

        removeShareFolderAction = new RemoveShareFolderAction();
        shareToolbar.addAction(removeShareFolderAction);

        if (SystemUtils.IS_OS_WINDOWS || SystemUtils.IS_OS_MAC_OSX) {
            exploreFolderAction = new ExploreFolderAction();
        }

        fileTreePopup = new FWPopupMenu();
        fileTreePopup.addAction(addShareFolderAction);
        fileTreePopup.addAction(removeShareFolderAction);

        if (SystemUtils.IS_OS_WINDOWS || SystemUtils.IS_OS_MAC_OSX) {
            fileTreePopup.addAction(exploreFolderAction);
        }
    }

    /**
     * Starts a download.
     */
    private class AddShareFolderAction extends FWAction {
        AddShareFolderAction() {
            super(Localizer.getString("LibraryTab_Share"),
                    GUIRegistry.getInstance().getPlafIconPack().getIcon("Library.ShareFolder"),
                    Localizer.getString("LibraryTab_TTTShare"));
        }

        public void actionPerformed(ActionEvent e) {
            try {
                File currentDirectory = null;
                TreePath selectionPath = mainTree.getSelectionPath();
                if (selectionPath != null) {
                    Object lastPathComponent = selectionPath.getLastPathComponent();
                    if (lastPathComponent instanceof LibraryNode) {
                        currentDirectory = ((LibraryNode) lastPathComponent).getSystemFile();
                    }
                }

                final File[] files = FileDialogHandler.openMultipleDirectoryChooser(parent,
                        Localizer.getString("LibraryTab_SelectDirectoryToShare"),
                        Localizer.getString("LibraryTab_Select"), Localizer.getChar("LibraryTab_SelectMnemonic"),
                        currentDirectory, Localizer.getString("LibraryTab_CopyrightWarnTitle"),
                        Localizer.getString("LibraryTab_CopyrightWarnMessage"));
                if (files == null) {
                    return;
                }
                Runnable runner = new Runnable() {
                    public void run() {
                        try {
                            for (int i = 0; i < files.length; i++) {
                                if (files[i] != null) {
                                    shareDirRecursive(files[i]);
                                }
                            }
                            GUIActionPerformer.rescanSharedFiles();
                        } catch (Throwable th) {
                            NLogger.error(LibraryTreePane.class, th, th);
                        }
                    }
                };
                Environment.getInstance().executeOnThreadPool(runner, "AddShareFolderAction");
            } catch (Throwable th) {
                NLogger.error(LibraryTreePane.class, th, th);
            }
        }

        @Override
        public void refreshActionState() {
        }

        private void shareDirRecursive(File file) {
            if (!file.isDirectory()) {
                return;
            }
            LibraryPrefs.SharedDirectoriesSet.get().add(file.getAbsolutePath());
            LibraryPrefs.SharedDirectoriesSet.changed();
            File[] dirs = file.listFiles(new DirectoryOnlyFileFilter());
            if (dirs == null) {// not a valid path or an IO error.
                return;
            }
            for (int i = 0; i < dirs.length; i++) {
                shareDirRecursive(dirs[i]);
            }
        }
    }

    private class RemoveShareFolderAction extends FWAction {
        RemoveShareFolderAction() {
            super(Localizer.getString("LibraryTab_StopShare"),
                    GUIRegistry.getInstance().getPlafIconPack().getIcon("Library.ShareFolderClear"),
                    Localizer.getString("LibraryTab_TTTStopShare"));
            refreshActionState();
        }

        public void actionPerformed(ActionEvent e) {
            TreePath selectionPath = mainTree.getSelectionPath();
            if (selectionPath == null) {
                return;
            }
            Object lastPathComponent = selectionPath.getLastPathComponent();
            if (!(lastPathComponent instanceof LibraryNode)) {
                return;

            }
            final File file = ((LibraryNode) lastPathComponent).getSystemFile();
            if (file == null) {
                return;
            }
            Runnable runner = new Runnable() {
                public void run() {
                    stopShareDirRecursive(file);
                    GUIActionPerformer.rescanSharedFiles();
                }
            };
            Environment.getInstance().executeOnThreadPool(runner, "RemoveShareFolderAction");
            refreshActionState();
        }

        private void stopShareDirRecursive(File file) {
            if (!file.isDirectory()) {
                return;
            }
            LibraryPrefs.SharedDirectoriesSet.get().remove(file.getAbsolutePath());
            LibraryPrefs.SharedDirectoriesSet.changed();
            SharedFilesService sharedFilesService = GUIRegistry.getInstance().getServent().getSharedFilesService();
            SharedDirectory directory = sharedFilesService.getSharedDirectory(file);
            if (directory == null) {
                // in case there is no shared directory here..
                // we can assume there is no shared sub-directory available.
                return;
            }

            File[] dirs = file.listFiles(new DirectoryOnlyFileFilter());
            for (int i = 0; i < dirs.length; i++) {
                stopShareDirRecursive(dirs[i]);
            }
        }

        @Override
        public void refreshActionState() {
            TreePath selectionPath = mainTree.getSelectionPath();
            if (selectionPath == null) {
                setEnabled(false);
                return;
            }
            Object lastPathComponent = selectionPath.getLastPathComponent();
            if (!(lastPathComponent instanceof LibraryNode)) {
                setEnabled(false);
                return;
            }
            File file = ((LibraryNode) lastPathComponent).getSystemFile();
            if (file == null) {
                setEnabled(false);
                return;
            }
            setEnabled(true);
        }
    }

    private class ExploreFolderAction extends FWAction {
        ExploreFolderAction() {
            super(Localizer.getString("LibraryTab_Explore"),
                    GUIRegistry.getInstance().getPlafIconPack().getIcon("Library.Explore"),
                    Localizer.getString("LibraryTab_TTTExplore"));
        }

        public void actionPerformed(ActionEvent e) {
            TreePath selectionPath = mainTree.getSelectionPath();
            if (selectionPath == null) {
                return;
            }
            Object lastPathComponent = selectionPath.getLastPathComponent();
            if (!(lastPathComponent instanceof LibraryNode)) {
                return;

            }
            final File dir = ((LibraryNode) lastPathComponent).getSystemFile();
            if (dir == null) {
                return;
            }

            try {
                SystemShellExecute.exploreFolder(dir);
            } catch (IOException exp) {// ignore and do nothing..
            }
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public void refreshActionState() {
            TreePath selectionPath = mainTree.getSelectionPath();
            if (selectionPath == null) {
                setEnabled(false);
                return;
            }
            Object lastPathComponent = selectionPath.getLastPathComponent();
            if (!(lastPathComponent instanceof LibraryNode)) {
                setEnabled(false);
                return;
            }
            File file = ((LibraryNode) lastPathComponent).getSystemFile();
            if (file == null) {
                setEnabled(false);
                return;
            }
            setEnabled(true);
        }
    }

    private class SelectionHandler implements TreeSelectionListener {
        public void valueChanged(TreeSelectionEvent e) {
            final Object treeRoot = sharingTreeModel.getRoot();
            final Object lastPathComponent = e.getPath().getLastPathComponent();
            if (lastPathComponent == treeRoot) {
                EventQueue.invokeLater(new Runnable() {
                    public void run() {
                        Object[] path = new Object[] { treeRoot, sharingTreeModel.getChild(treeRoot, 0) };
                        mainTree.setSelectionPath(new TreePath(path));
                    }
                });
                return;
            }
            refreshActions();
        }
    }

    private class MouseHandler extends MouseAdapter implements MouseListener {
        @Override
        public void mouseClicked(MouseEvent e) {
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            if (e.isPopupTrigger()) {
                popupMenu((Component) e.getSource(), e.getX(), e.getY());
            }
        }

        @Override
        public void mousePressed(MouseEvent e) {
            if (e.isPopupTrigger()) {
                popupMenu((Component) e.getSource(), e.getX(), e.getY());
            }
        }

        private void popupMenu(Component source, int x, int y) {
            refreshActions();
            fileTreePopup.show(source, x, y);
        }
    }
}