2 * jSite2 - FileManager.java -
3 * Copyright © 2008 David Roden
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 package net.pterodactylus.jsite.gui;
22 import java.awt.BorderLayout;
23 import java.awt.Component;
24 import java.awt.Dimension;
25 import java.awt.FlowLayout;
26 import java.awt.GridBagConstraints;
27 import java.awt.GridBagLayout;
28 import java.awt.Insets;
29 import java.awt.event.ActionEvent;
30 import java.awt.event.ActionListener;
32 import java.util.List;
33 import java.util.logging.Level;
34 import java.util.logging.Logger;
36 import javax.swing.BorderFactory;
37 import javax.swing.JButton;
38 import javax.swing.JCheckBox;
39 import javax.swing.JComboBox;
40 import javax.swing.JDialog;
41 import javax.swing.JOptionPane;
42 import javax.swing.JPanel;
43 import javax.swing.JScrollPane;
44 import javax.swing.JTree;
45 import javax.swing.event.TreeSelectionEvent;
46 import javax.swing.event.TreeSelectionListener;
47 import javax.swing.tree.DefaultTreeModel;
49 import net.pterodactylus.jsite.i18n.I18n;
50 import net.pterodactylus.jsite.i18n.I18nable;
51 import net.pterodactylus.jsite.i18n.gui.I18nAction;
52 import net.pterodactylus.jsite.i18n.gui.I18nLabel;
53 import net.pterodactylus.jsite.project.Project;
54 import net.pterodactylus.util.io.MimeTypes;
55 import net.pterodactylus.util.logging.Logging;
56 import net.pterodactylus.util.swing.SortableTreeNode;
57 import net.pterodactylus.util.swing.SwingUtils;
60 * Manages physical and virtual files in a project.
62 * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
64 public class FileManager extends JDialog implements I18nable, ActionListener, TreeSelectionListener {
67 private static final Logger logger = Logging.getLogger(FileManager.class.getName());
69 /** The Swing interface. */
70 private final SwingInterface swingInterface;
72 /** The project whose files to manage. */
73 private final Project project;
75 /** The root of the file tree. */
76 private final SortableTreeNode fileTreeRoot;
78 /** The tree model for the project files. */
79 private final DefaultTreeModel fileTreeModel;
81 /** The “rescan” action. */
82 private I18nAction rescanAction;
84 /** The “close” action. */
85 private I18nAction closeAction;
87 /** The “project files” label. */
88 private I18nLabel projectFilesLabel;
90 /** The tree that shows the files. */
91 private JTree fileTree;
93 /** The scroll pane that holds the file tree. */
94 private JScrollPane fileScrollPane;
96 /** The “insert” action. */
97 private I18nAction insertAction;
99 /** The “insert” checkbox. */
100 private JCheckBox insertCheckBox;
102 /** The “use custom mime type” action. */
103 private I18nAction useCustomMimeTypeAction;
105 /** The “use custom mime type” checkbox. */
106 private JCheckBox useCustomMimeTypeCheckBox;
108 /** The “mime type” combo box. */
109 private JComboBox mimeTypeComboBox;
112 * Creates a new file manager.
114 * @param swingInterface
115 * The Swing interface
117 * The project whose files to manage
119 public FileManager(SwingInterface swingInterface, Project project) {
120 super(swingInterface.getMainWindow(), I18n.get("fileManager.title", project.getName()), true);
121 logger.log(Level.FINEST, "project: " + project);
122 this.swingInterface = swingInterface;
123 this.project = project;
124 fileTreeRoot = new SortableTreeNode(project.getName());
125 fileTreeModel = new DefaultTreeModel(fileTreeRoot);
129 SwingUtils.center(this);
137 * @see java.awt.Component#setVisible(boolean)
140 public void setVisible(boolean visible) {
144 super.setVisible(visible);
152 * Initializes all actions.
154 private void initActions() {
155 closeAction = new I18nAction("fileManager.button.close") {
160 public void actionPerformed(ActionEvent e) {
164 rescanAction = new I18nAction("fileManager.button.rescan") {
169 @SuppressWarnings("synthetic-access")
170 public void actionPerformed(ActionEvent actionEvent) {
175 insertAction = new I18nAction("fileManager.checkbox.insertFile") {
180 @SuppressWarnings("synthetic-access")
181 public void actionPerformed(ActionEvent actionEvent) {
185 insertAction.setEnabled(false);
186 useCustomMimeTypeAction = new I18nAction("fileManager.checkbox.useCustomMimeType") {
191 @SuppressWarnings("synthetic-access")
192 public void actionPerformed(ActionEvent actionEvent) {
196 useCustomMimeTypeAction.setEnabled(false);
200 * Initializes all components.
202 private void initComponents() {
203 JPanel contentPanel = new JPanel(new BorderLayout(12, 12));
204 contentPanel.setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12));
206 contentPanel.add(createFileManagerPanel(), BorderLayout.CENTER);
207 contentPanel.add(createButtonPanel(), BorderLayout.PAGE_END);
209 setContentPane(contentPanel);
213 * Creates the main panel with the file tree and the file properties.
215 * @return The mail panel
217 private Component createFileManagerPanel() {
218 JPanel fileManagerPanel = new JPanel(new BorderLayout(12, 12));
220 /* file tree panel */
221 JPanel fileTreePanel = new JPanel(new BorderLayout(12, 12));
222 fileManagerPanel.add(fileTreePanel, BorderLayout.LINE_START);
224 fileTree = new JTree(fileTreeModel);
225 fileTree.setShowsRootHandles(false);
226 fileTree.addTreeSelectionListener(this);
227 fileTreePanel.add(fileScrollPane = new JScrollPane(fileTree), BorderLayout.CENTER);
228 fileScrollPane.setPreferredSize(new Dimension(250, 400));
230 projectFilesLabel = new I18nLabel("fileManager.label.projectFiles", fileTree);
231 JPanel projectFilesLabelPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));
232 fileTreePanel.add(projectFilesLabelPanel, BorderLayout.NORTH);
233 projectFilesLabelPanel.add(projectFilesLabel);
235 /* the right panel */
236 JPanel rightPanel = new JPanel(new BorderLayout(12, 12));
237 fileManagerPanel.add(rightPanel, BorderLayout.CENTER);
239 /* properties panel */
240 JPanel propertiesPanel = new JPanel(new GridBagLayout());
241 rightPanel.add(propertiesPanel, BorderLayout.CENTER);
242 propertiesPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEtchedBorder(), BorderFactory.createEmptyBorder(12, 12, 12, 12)));
244 insertCheckBox = new JCheckBox(insertAction);
245 propertiesPanel.add(insertCheckBox, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
247 useCustomMimeTypeCheckBox = new JCheckBox(useCustomMimeTypeAction);
248 List<String> allMimeTypes = MimeTypes.getAllMimeTypes();
249 mimeTypeComboBox = new JComboBox(allMimeTypes.toArray(new String[0]));
250 mimeTypeComboBox.setEnabled(false);
251 mimeTypeComboBox.addActionListener(this);
252 propertiesPanel.add(useCustomMimeTypeCheckBox, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(6, 0, 0, 0), 0, 0));
253 propertiesPanel.add(mimeTypeComboBox, new GridBagConstraints(1, 1, 1, 1, 1.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(6, 6, 0, 0), 0, 0));
255 propertiesPanel.add(new JPanel(), new GridBagConstraints(0, 2, 1, 1, 1.0, 1.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
257 /* action button panel */
258 JPanel actionButtonPanel = new JPanel(new FlowLayout(FlowLayout.LEADING, 12, 12));
259 rightPanel.add(actionButtonPanel, BorderLayout.PAGE_END);
260 actionButtonPanel.setBorder(BorderFactory.createEtchedBorder());
262 JButton rescanButton = new JButton(rescanAction);
263 actionButtonPanel.add(rescanButton);
265 return fileManagerPanel;
269 * Creates the button panel.
271 * @return The button panel
273 private Component createButtonPanel() {
274 JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING, 12, 12));
276 buttonPanel.setBorder(BorderFactory.createEmptyBorder(-12, -12, -12, -12));
277 JButton closeButton = new JButton(closeAction);
278 buttonPanel.add(closeButton);
280 getRootPane().setDefaultButton(closeButton);
285 * Initiates a file scan.
287 private void initiateFileScan() {
288 swingInterface.getThreadPool().execute(new Runnable() {
291 * @see java.lang.Runnable#run()
293 @SuppressWarnings("synthetic-access")
295 String basePath = project.getBasePath();
296 File basePathDirectory = new File(basePath);
297 if (!basePathDirectory.exists() || !basePathDirectory.isDirectory()) {
299 JOptionPane.showMessageDialog(FileManager.this, I18n.get(""), I18n.get(""), JOptionPane.ERROR_MESSAGE);
302 synchronized (fileTreeRoot) {
303 fileTreeRoot.removeAll();
304 scanDirectory(fileTreeRoot, basePathDirectory);
306 fileTreeModel.reload();
307 fileScrollPane.revalidate();
308 rescanAction.setEnabled(true);
311 private void scanDirectory(SortableTreeNode rootNode, File directory) {
312 for (File file: directory.listFiles()) {
313 SortableTreeNode fileNode = new SortableTreeNode(file.getName());
314 rootNode.add(fileNode);
315 if (file.isDirectory()) {
316 scanDirectory(fileNode, file);
326 // INTERFACE I18nable
332 public void updateI18n() {
333 setTitle(I18n.get("fileManager.title", project.getName()));
337 // INTERFACE TreeSelectionListener
343 public void valueChanged(TreeSelectionEvent treeSelectionEvent) {
348 // INTERFACE ActionListener
354 public void actionPerformed(ActionEvent actionEvent) {