Package com.tulskiy.musique.gui.dialogs

Source Code of com.tulskiy.musique.gui.dialogs.DirectoryChooser$DirectoryNode

/*
* Copyright (c) 2008, 2009, 2010 Denis Tulskiy
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.
*/

package com.tulskiy.musique.gui.dialogs;

import com.sun.java.swing.Painter;
import com.tulskiy.musique.images.Images;
import com.tulskiy.musique.util.Util;

import javax.swing.*;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.filechooser.FileSystemView;
import javax.swing.plaf.TreeUI;
import javax.swing.plaf.basic.BasicTreeUI;
import javax.swing.plaf.metal.MetalTreeUI;
import javax.swing.tree.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.*;

@SuppressWarnings({"unchecked"})
public class DirectoryChooser extends JTree {
    private static FileSystemView fsv = FileSystemView.getFileSystemView();
    private boolean enableFiles;

    public DirectoryChooser(boolean enableFiles) {
        this(null, enableFiles);
    }

    public DirectoryChooser(File dir, boolean enableFiles) {
        this.enableFiles = enableFiles;
        setModel(new DefaultTreeModel(new DirectoryNode(fsv.getRoots()[0])));
        getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
        setSelectedFile(dir);
        addTreeSelectionListener(new TreeSelectionListener() {
            @Override
            public void valueChanged(TreeSelectionEvent ev) {
                File oldDir = null;
                TreePath oldPath = ev.getOldLeadSelectionPath();
                if (oldPath != null) {
                    oldDir = ((FileNode) oldPath.getLastPathComponent()).getFile();
                    if (!fsv.isFileSystem(oldDir)) {
                        oldDir = null;
                    }
                }
                File[] files = getSelectedFiles();
                File newDir = files.length > 0 ? files[0] : null;
                firePropertyChange("selectedDirectory", oldDir, newDir);
            }
        });
        setToggleClickCount(2);
        putClientProperty("JTree.lineStyle", "None");
        buildListeners();
    }

    private void buildListeners() {
        addMouseListener(new MouseAdapter() {
            @SuppressWarnings({"unchecked"})
            @Override
            public void mouseClicked(MouseEvent e) {
                final int row = getClosestRowForLocation(e.getX(), e.getY());

                if (row != -1) {
                    Rectangle bounds = getRowBounds(row);
                    boolean isInBounds = bounds.getX() < e.getX();
                    boolean isExtraSpace = bounds.getX() + bounds.getWidth() < e.getX();
                    if (e.getButton() == MouseEvent.BUTTON1 && isExtraSpace) {
                        if (e.isControlDown()) {
                            if (!isRowSelected(row))
                                addSelectionRow(row);
                            else
                                removeSelectionRow(row);
                        } else if (e.isShiftDown()) {
                            int start = getSelectionModel().getLeadSelectionRow();
                            if (start == -1)
                                start = row;
                            if (start < row)
                                start = getSelectionModel().getMinSelectionRow();
                            setSelectionInterval(
                                    start,
                                    row);
                        } else {
                            setSelectionRow(row);
                        }
                    }

                    if (e.isPopupTrigger() && isInBounds) {
                        if (!isRowSelected(row)) {
                            setSelectionRow(row);
                        }
                    }
                }
            }
        });
    }

    public boolean isEnableFiles() {
        return enableFiles;
    }

    public void setEnableFiles(boolean enableFiles) {
        this.enableFiles = enableFiles;
    }

    public void setSelectedFile(File file) {
        if (file == null) {
            file = fsv.getDefaultDirectory();
        }
        TreePath path;
        try {
            path = makePath(file);
        } catch (Exception e) {
            path = makePath(fsv.getDefaultDirectory());
        }
        setSelectionPath(path);
        expandPath(path);
        int row = Math.max(0, getRowForPath(path) - 4);
        Rectangle rect = getRowBounds(row);
        rect.x = 0;
        rect.width = getWidth();
        scrollRectToVisible(rect);
    }

    public File[] getSelectedFiles() {
        TreePath[] paths = getSelectionPaths();
        ArrayList<File> files = new ArrayList<File>();
        if (paths != null)
            for (TreePath path : paths) {
                FileNode node = (FileNode) path.getLastPathComponent();
                File file = node.getFile();
                if (fsv.isFileSystem(file)) {
                    files.add(file);
                }

            }

        return files.toArray(new File[files.size()]);
    }

    private TreePath makePath(File dir) {
        DirectoryNode root = (DirectoryNode) getModel().getRoot();
        if (root.getFile().equals(dir)) {
            return new TreePath(root);
        }

        TreePath parentPath = makePath(fsv.getParentDirectory(dir));
        DirectoryNode parentNode = (DirectoryNode) parentPath.getLastPathComponent();
        Enumeration enumeration = parentNode.children();
        while (enumeration.hasMoreElements()) {
            FileNode child = (FileNode) enumeration.nextElement();
            if (child.getFile().equals(dir)) {
                return parentPath.pathByAddingChild(child);
            }
        }
        return null;
    }

    public void updateUI() {
        super.updateUI();

        if (!Util.isNimbusLaF()) {
            MetalTreeUI newUI = new MetalTreeUI() {
                @Override
                protected void paintRow(Graphics g, Rectangle clipBounds, Insets insets, Rectangle bounds, TreePath path, int row, boolean isExpanded, boolean hasBeenExpanded, boolean isLeaf) {
                    if (tree.isRowSelected(row)) {
                        Color bgColor;
                        bgColor = ((DefaultTreeCellRenderer) currentCellRenderer).getBackgroundSelectionColor();
                        g.setColor(bgColor);
                        g.fillRect(clipBounds.x, bounds.y, clipBounds.width, bounds.height);
                    }
                    super.paintRow(g, clipBounds, insets, bounds, path, row, isExpanded, hasBeenExpanded, isLeaf);

                    if (shouldPaintExpandControl(path, row, isExpanded, hasBeenExpanded, isLeaf)) {
                        paintExpandControl(g, clipBounds, insets, bounds,
                                path, row, isExpanded,
                                hasBeenExpanded, isLeaf);
                    }
                }


            };
            setUI(newUI);
        }

        DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer();
        if (Util.isGTKLaF()) {
            renderer.setClosedIcon(Images.loadIcon("directory.png"));
            renderer.setOpenIcon(Images.loadIcon("directory.png"));
            renderer.setLeafIcon(Images.loadIcon("file.png"));
        }
        setCellRenderer(renderer);

        setForeground(renderer.getTextNonSelectionColor());

        setBackground(renderer.getBackgroundNonSelectionColor());

        UIDefaults defaults = new UIDefaults();

        setRowHeight(getFont().getSize() + 10);
        renderer.setBorderSelectionColor(renderer.getBackgroundSelectionColor());

        Painter collapsedIconPainter = new Painter() {
            @Override
            public void paint(Graphics2D g, Object object, int width, int height) {
                g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                g.setColor(getForeground());
                g.fillPolygon(
                        new int[]{0, (int) (height * Math.sqrt(0.75)), 0},
                        new int[]{0, height / 2, height},
                        3
                );
            }
        };
        Painter expandedIconPainter = new Painter() {
            @Override
            public void paint(Graphics2D g, Object object, int width, int height) {
                g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                g.setColor(getForeground());
                g.fillPolygon(
                        new int[]{0, height, height / 2},
                        new int[]{0, 0, (int) (height * Math.sqrt(0.75))},
                        3
                );
            }
        };

        defaults.put("Tree[Enabled].collapsedIconPainter", collapsedIconPainter);
        defaults.put("Tree[Enabled].expandedIconPainter", expandedIconPainter);
        defaults.put("Tree:TreeCell[Focused+Selected].backgroundPainter", new SelectionBackgroundPainter(renderer.getBackgroundSelectionColor()));

        TreeUI treeUI = getUI();
        if (treeUI instanceof MetalTreeUI) {
            BasicTreeUI basicUI = (BasicTreeUI) treeUI;
            int size = 7;
            BufferedImage expandedIcon = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
            expandedIconPainter.paint(expandedIcon.createGraphics(), null, size, size);
            BufferedImage collapsedIcon = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
            collapsedIconPainter.paint(collapsedIcon.createGraphics(), null, size, size);
            basicUI.setCollapsedIcon(new ImageIcon(collapsedIcon));
            basicUI.setExpandedIcon(new ImageIcon(expandedIcon));
        }

        putClientProperty("Nimbus.Overrides", defaults);
        putClientProperty("Nimbus.Overrides.InheritDefaults", true);
    }

    private class SelectionBackgroundPainter implements Painter {
        private final Color selection;

        public SelectionBackgroundPainter(Color selection) {
            this.selection = selection;
        }

        @Override
        public void paint(Graphics2D g, Object object, int width, int height) {
            g.setColor(selection);
            g.fillRect(0, 0, width, height);
        }
    }

    class FileNode extends DefaultMutableTreeNode {
        File file;

        FileNode(File file) {
            super(file);
            this.file = file;
        }

        public File getFile() {
            return file;
        }

        @Override
        public String toString() {
            return file.getName();
        }
    }

    class DirectoryNode extends FileNode {
        DirectoryNode(File file) {
            super(file);
        }

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

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

        public boolean isLeaf() {
            return false;
        }

        public void reload() {
            children = null;
            populateChildren();
        }

        private void populateChildren() {
            if (children == null) {
                children = new Vector();
                File[] files = fsv.getFiles(file, true);
                Arrays.sort(files, new Comparator<File>() {
                    @Override
                    public int compare(File o1, File o2) {
                        if (o1.isDirectory() ^ o2.isDirectory()) {
                            return o1.isDirectory() ? -1 : 1;
                        } else {
                            return o1.compareTo(o2);
                        }
                    }
                });
                for (File f : files) {
                    if (fsv.isTraversable(f)) {
                        insert(new DirectoryNode(f),
                                (children == null) ? 0 : children.size());
                    } else if (f.isFile() && isEnableFiles()) {
                        insert(new FileNode(f),
                                (children == null) ? 0 : children.size());
                    }
                }
            }
        }

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

        public boolean equals(Object o) {
            return (o instanceof DirectoryNode &&
                    userObject.equals(((DirectoryNode) o).getUserObject()));
        }
    }
}
TOP

Related Classes of com.tulskiy.musique.gui.dialogs.DirectoryChooser$DirectoryNode

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.