diff --git a/source/Main.java b/source/Main.java index f8b2aa3d..3e75f856 100644 --- a/source/Main.java +++ b/source/Main.java @@ -9,6 +9,7 @@ import javax.swing.UIManager; import net.sourceforge.filebot.ArgumentBean; import net.sourceforge.filebot.FileBotUtil; import net.sourceforge.filebot.ui.FileBotWindow; +import net.sourceforge.filebot.ui.NotificationLoggingHandler; import org.kohsuke.args4j.CmdLineException; import org.kohsuke.args4j.CmdLineParser; @@ -21,21 +22,20 @@ public class Main { */ public static void main(String... args) { - final ArgumentBean argumentBean = parseArguments(args); + setupLogging(); - if (argumentBean.isClear()) { - try { - Preferences.userNodeForPackage(FileBotUtil.class).removeNode(); - } catch (BackingStoreException e) { - Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e); - } - } + final ArgumentBean argumentBean = handleArguments(args); try { // UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel"); + // UIManager.setLookAndFeel("a03.swing.plaf.A03LookAndFeel"); + // UIManager.setLookAndFeel("org.jvnet.substance.skin.SubstanceBusinessBlueSteelLookAndFeel"); + // UIManager.setLookAndFeel("org.jvnet.substance.skin.SubstanceNebulaBrickWallLookAndFeel"); + // UIManager.setLookAndFeel("org.jvnet.substance.skin.SubstanceSaharaLookAndFeel"); + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception e) { - Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e); + Logger.getLogger("global").log(Level.SEVERE, e.toString(), e); } SwingUtilities.invokeLater(new Runnable() { @@ -54,7 +54,14 @@ public class Main { } - private static ArgumentBean parseArguments(String... args) { + private static void setupLogging() { + Logger uiLogger = Logger.getLogger("ui"); + uiLogger.addHandler(new NotificationLoggingHandler()); + uiLogger.setUseParentHandlers(false); + } + + + private static ArgumentBean handleArguments(String... args) { ArgumentBean argumentBean = new ArgumentBean(); CmdLineParser argumentParser = new CmdLineParser(argumentBean); @@ -62,7 +69,7 @@ public class Main { try { argumentParser.parseArgument(args); } catch (CmdLineException e) { - Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.WARNING, e.getMessage()); + Logger.getLogger("global").log(Level.WARNING, e.getMessage()); } if (argumentBean.isHelp()) { @@ -73,6 +80,15 @@ public class Main { System.exit(0); } + if (argumentBean.isClear()) { + // clear preferences + try { + Preferences.userNodeForPackage(FileBotUtil.class).removeNode(); + } catch (BackingStoreException e) { + Logger.getLogger("global").log(Level.SEVERE, e.toString(), e); + } + } + return argumentBean; } diff --git a/source/net/sourceforge/filebot/resources/message.error.png b/source/net/sourceforge/filebot/resources/message.error.png new file mode 100644 index 00000000..745a5fac Binary files /dev/null and b/source/net/sourceforge/filebot/resources/message.error.png differ diff --git a/source/net/sourceforge/filebot/ui/AbstractSearchPanel.java b/source/net/sourceforge/filebot/ui/AbstractSearchPanel.java index fd56f60d..d71d94a0 100644 --- a/source/net/sourceforge/filebot/ui/AbstractSearchPanel.java +++ b/source/net/sourceforge/filebot/ui/AbstractSearchPanel.java @@ -134,6 +134,10 @@ public abstract class AbstractSearchPanel extends Fi private final AbstractAction searchAction = new AbstractAction("Find", ResourceManager.getIcon("action.find")) { public void actionPerformed(ActionEvent e) { + if (e.getActionCommand() == null) { + // command triggered by auto-completion + return; + } SearchTask searchTask = createSearchTask(); searchTask.addPropertyChangeListener(new SearchTaskListener()); @@ -166,7 +170,7 @@ public abstract class AbstractSearchPanel extends Fi switch (get().size()) { case 0: - MessageManager.showWarning(String.format("\"%s\" has not been found.", getSearchText())); + Logger.getLogger("ui").warning(String.format("\"%s\" has not been found.", getSearchText())); return null; case 1: return get().iterator().next(); @@ -266,10 +270,8 @@ public abstract class AbstractSearchPanel extends Fi } catch (Exception e) { tab.close(); - Throwable cause = ExceptionUtil.getRootCause(e); - - MessageManager.showWarning(cause.getMessage()); - Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, cause.getMessage(), cause); + Logger.getLogger("ui").warning(ExceptionUtil.getRootCause(e).getMessage()); + Logger.getLogger("global").log(Level.SEVERE, "Search failed", e); } } @@ -392,14 +394,14 @@ public abstract class AbstractSearchPanel extends Fi // close tab if no elements were fetched if (task.getCount() <= 0) { - MessageManager.showWarning(info); + Logger.getLogger("ui").warning(info); tab.close(); } } catch (Exception e) { tab.close(); - MessageManager.showWarning(ExceptionUtil.getRootCause(e).getMessage()); - Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e); + Logger.getLogger("ui").warning(ExceptionUtil.getRootCause(e).getMessage()); + Logger.getLogger("global").log(Level.SEVERE, "Fetch failed", e); } tab.setLoading(false); diff --git a/source/net/sourceforge/filebot/ui/MessageManager.java b/source/net/sourceforge/filebot/ui/MessageManager.java deleted file mode 100644 index 8a85ff10..00000000 --- a/source/net/sourceforge/filebot/ui/MessageManager.java +++ /dev/null @@ -1,35 +0,0 @@ - -package net.sourceforge.filebot.ui; - - -import javax.swing.Icon; -import javax.swing.SwingConstants; - -import net.sourceforge.filebot.FileBotUtil; -import net.sourceforge.filebot.ResourceManager; -import net.sourceforge.tuned.ui.notification.MessageNotification; -import net.sourceforge.tuned.ui.notification.NotificationManager; -import net.sourceforge.tuned.ui.notification.QueueNotificationLayout; - - -public class MessageManager { - - private static final int TIMEOUT = 2500; - private static final NotificationManager manager = new NotificationManager(new QueueNotificationLayout(SwingConstants.NORTH, SwingConstants.SOUTH)); - - - public static void showInfo(String message) { - show(message, ResourceManager.getIcon("message.info"), TIMEOUT); - } - - - public static void showWarning(String message) { - show(message, ResourceManager.getIcon("message.warning"), TIMEOUT * 2); - } - - - private static void show(String message, Icon icon, int timeout) { - manager.show(new MessageNotification(FileBotUtil.getApplicationName(), message, icon, timeout)); - } - -} diff --git a/source/net/sourceforge/filebot/ui/NotificationLoggingHandler.java b/source/net/sourceforge/filebot/ui/NotificationLoggingHandler.java new file mode 100644 index 00000000..686653f9 --- /dev/null +++ b/source/net/sourceforge/filebot/ui/NotificationLoggingHandler.java @@ -0,0 +1,72 @@ + +package net.sourceforge.filebot.ui; + + +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.LogRecord; + +import javax.swing.Icon; +import javax.swing.SwingConstants; +import javax.swing.SwingUtilities; + +import net.sourceforge.filebot.FileBotUtil; +import net.sourceforge.filebot.ResourceManager; +import net.sourceforge.tuned.ui.notification.MessageNotification; +import net.sourceforge.tuned.ui.notification.NotificationManager; +import net.sourceforge.tuned.ui.notification.QueueNotificationLayout; + + +public class NotificationLoggingHandler extends Handler { + + public final NotificationManager notificationManager; + public final int timeout = 2500; + + + public NotificationLoggingHandler() { + this(new NotificationManager(new QueueNotificationLayout(SwingConstants.NORTH, SwingConstants.SOUTH))); + } + + + public NotificationLoggingHandler(NotificationManager notificationManager) { + this.notificationManager = notificationManager; + } + + + @Override + public void publish(final LogRecord record) { + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + Level level = record.getLevel(); + + if (level == Level.INFO) { + show(record.getMessage(), ResourceManager.getIcon("message.info"), timeout * 1); + } else if (level == Level.WARNING) { + show(record.getMessage(), ResourceManager.getIcon("message.warning"), timeout * 2); + } else if (level == Level.SEVERE) { + show(record.getMessage(), ResourceManager.getIcon("message.error"), timeout * 3); + } + } + }); + } + + + private void show(String message, Icon icon, int timeout) { + notificationManager.show(new MessageNotification(FileBotUtil.getApplicationName(), message, icon, timeout)); + } + + + @Override + public void close() throws SecurityException { + + } + + + @Override + public void flush() { + + } + +} diff --git a/source/net/sourceforge/filebot/ui/panel/analyze/AnalyzePanel.java b/source/net/sourceforge/filebot/ui/panel/analyze/AnalyzePanel.java index 8dcc5c2c..1fe6c21d 100644 --- a/source/net/sourceforge/filebot/ui/panel/analyze/AnalyzePanel.java +++ b/source/net/sourceforge/filebot/ui/panel/analyze/AnalyzePanel.java @@ -31,8 +31,8 @@ public class AnalyzePanel extends FileBotPanel { setLayout(new MigLayout("insets 0, gapx 50, fill")); - add(fileTreePanel, "grow, sizegroup column"); - add(toolsPanel, "grow, sizegroup column"); + add(fileTreePanel, "grow, sizegroupx column"); + add(toolsPanel, "grow, sizegroupx column"); addTool(new TypeTool()); addTool(new SplitTool()); diff --git a/source/net/sourceforge/filebot/ui/panel/analyze/FileTree.java b/source/net/sourceforge/filebot/ui/panel/analyze/FileTree.java index e4f2c749..c6c5f36b 100644 --- a/source/net/sourceforge/filebot/ui/panel/analyze/FileTree.java +++ b/source/net/sourceforge/filebot/ui/panel/analyze/FileTree.java @@ -32,7 +32,6 @@ import javax.swing.tree.TreePath; import javax.swing.tree.TreeSelectionModel; import net.sourceforge.filebot.ResourceManager; -import net.sourceforge.filebot.ui.MessageManager; import net.sourceforge.tuned.FilterIterator; import net.sourceforge.tuned.TreeIterator; @@ -160,8 +159,8 @@ public class FileTree extends JTree { Desktop.getDesktop().open(file); } } catch (Exception e) { - MessageManager.showWarning(e.getMessage()); - Logger.getLogger("global").log(Level.SEVERE, e.getMessage(), e); + Logger.getLogger("ui").warning(e.getMessage()); + Logger.getLogger("global").log(Level.SEVERE, "Failed to open file", e); } } } diff --git a/source/net/sourceforge/filebot/ui/panel/analyze/Tool.java b/source/net/sourceforge/filebot/ui/panel/analyze/Tool.java index 7dd2be03..434cd20c 100644 --- a/source/net/sourceforge/filebot/ui/panel/analyze/Tool.java +++ b/source/net/sourceforge/filebot/ui/panel/analyze/Tool.java @@ -2,6 +2,8 @@ package net.sourceforge.filebot.ui.panel.analyze; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; import java.io.File; import java.util.List; import java.util.concurrent.Semaphore; @@ -34,18 +36,11 @@ abstract class Tool extends JComponent { } updateTask = new UpdateModelTask(sourceModel); - - updateSemaphore.acquireUninterruptibly(); - setLoading(true); + updateTask.addPropertyChangeListener(loadingListener); updateTask.execute(); } - private void setLoading(boolean loading) { - firePropertyChange(LoadingOverlayPane.LOADING_PROPERTY, !loading, loading); - } - - protected abstract M createModelInBackground(FolderNode sourceModel, Cancellable cancellable); @@ -64,7 +59,22 @@ abstract class Tool extends JComponent { @Override protected M doInBackground() throws Exception { - return createModelInBackground(sourceModel, this); + // acquire semaphore + updateSemaphore.acquireUninterruptibly(); + + try { + M model = null; + + if (!isCancelled()) { + firePropertyChange(LoadingOverlayPane.LOADING_PROPERTY, false, true); + model = createModelInBackground(sourceModel, this); + firePropertyChange(LoadingOverlayPane.LOADING_PROPERTY, true, false); + } + + return model; + } finally { + updateSemaphore.release(); + } } @@ -79,9 +89,6 @@ abstract class Tool extends JComponent { Logger.getLogger("global").log(Level.WARNING, e.toString()); } } - - setLoading(false); - updateSemaphore.release(); } } @@ -111,4 +118,16 @@ abstract class Tool extends JComponent { return folder; } + private final PropertyChangeListener loadingListener = new PropertyChangeListener() { + + @Override + public void propertyChange(PropertyChangeEvent evt) { + // propagate loading events + if (evt.getPropertyName().equals(LoadingOverlayPane.LOADING_PROPERTY)) { + firePropertyChange(evt.getPropertyName(), evt.getOldValue(), evt.getNewValue()); + } + + } + }; + } diff --git a/source/net/sourceforge/filebot/ui/panel/analyze/TypeTool.java b/source/net/sourceforge/filebot/ui/panel/analyze/TypeTool.java index 461fd26e..f4b38133 100644 --- a/source/net/sourceforge/filebot/ui/panel/analyze/TypeTool.java +++ b/source/net/sourceforge/filebot/ui/panel/analyze/TypeTool.java @@ -31,9 +31,9 @@ public class TypeTool extends Tool { setLayout(new MigLayout("insets 0, fill")); - JScrollPane sp = new JScrollPane(tree); - sp.setBorder(BorderFactory.createEmptyBorder()); - add(new LoadingOverlayPane(sp, this), "grow"); + JScrollPane treeScrollPane = new JScrollPane(tree); + treeScrollPane.setBorder(BorderFactory.createEmptyBorder()); + add(new LoadingOverlayPane(treeScrollPane, this), "grow"); tree.setTransferHandler(new DefaultTransferHandler(null, new FileTreeExportHandler())); tree.setDragEnabled(true); diff --git a/source/net/sourceforge/filebot/ui/panel/episodelist/EpisodeListPanel.java b/source/net/sourceforge/filebot/ui/panel/episodelist/EpisodeListPanel.java index f599a603..13c4a1f0 100644 --- a/source/net/sourceforge/filebot/ui/panel/episodelist/EpisodeListPanel.java +++ b/source/net/sourceforge/filebot/ui/panel/episodelist/EpisodeListPanel.java @@ -37,7 +37,6 @@ import net.sourceforge.filebot.ui.FileBotList; import net.sourceforge.filebot.ui.FileBotPanel; import net.sourceforge.filebot.ui.FileBotTab; import net.sourceforge.filebot.ui.HistoryPanel; -import net.sourceforge.filebot.ui.MessageManager; import net.sourceforge.filebot.ui.SelectDialog; import net.sourceforge.filebot.ui.transfer.FileExportHandler; import net.sourceforge.filebot.ui.transfer.SaveAction; @@ -293,7 +292,7 @@ public class EpisodeListPanel extends FileBotPanel { Throwable cause = ExceptionUtil.getRootCause(e); - MessageManager.showWarning(cause.getMessage()); + Logger.getLogger("ui").warning(cause.getMessage()); Logger.getLogger("global").log(Level.WARNING, cause.toString()); return; @@ -317,7 +316,7 @@ public class EpisodeListPanel extends FileBotPanel { selectedResult = select.getSelectedValue(); } else { - MessageManager.showWarning("\"" + task.query + "\" has not been found."); + Logger.getLogger("ui").warning(String.format("\"%s\" has not been found.", task.query)); } if (selectedResult == null) { @@ -383,7 +382,7 @@ public class EpisodeListPanel extends FileBotPanel { Throwable cause = ExceptionUtil.getRootCause(e); - MessageManager.showWarning(cause.getMessage()); + Logger.getLogger("ui").warning(cause.getMessage()); Logger.getLogger("global").log(Level.SEVERE, cause.getMessage(), cause); } } diff --git a/source/net/sourceforge/filebot/ui/panel/list/ListPanel.java b/source/net/sourceforge/filebot/ui/panel/list/ListPanel.java index c9038625..23548f0e 100644 --- a/source/net/sourceforge/filebot/ui/panel/list/ListPanel.java +++ b/source/net/sourceforge/filebot/ui/panel/list/ListPanel.java @@ -6,6 +6,7 @@ import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.text.NumberFormat; import java.util.ArrayList; +import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -24,7 +25,6 @@ import net.sourceforge.filebot.ui.FileBotList; import net.sourceforge.filebot.ui.FileBotListExportHandler; import net.sourceforge.filebot.ui.FileBotPanel; import net.sourceforge.filebot.ui.FileTransferableMessageHandler; -import net.sourceforge.filebot.ui.MessageManager; import net.sourceforge.filebot.ui.transfer.LoadAction; import net.sourceforge.filebot.ui.transfer.SaveAction; import net.sourceforge.tuned.MessageHandler; @@ -99,7 +99,7 @@ public class ListPanel extends FileBotPanel { String pattern = textField.getText(); if (!pattern.contains(INDEX_VARIABLE)) { - MessageManager.showWarning(String.format("Pattern does not contain index variable %s.", INDEX_VARIABLE)); + Logger.getLogger("ui").warning(String.format("Pattern does not contain index variable %s.", INDEX_VARIABLE)); return; } diff --git a/source/net/sourceforge/filebot/ui/panel/rename/RenameAction.java b/source/net/sourceforge/filebot/ui/panel/rename/RenameAction.java index 653bc738..4fa85a7e 100644 --- a/source/net/sourceforge/filebot/ui/panel/rename/RenameAction.java +++ b/source/net/sourceforge/filebot/ui/panel/rename/RenameAction.java @@ -5,12 +5,12 @@ package net.sourceforge.filebot.ui.panel.rename; import java.awt.event.ActionEvent; import java.io.File; import java.util.List; +import java.util.logging.Logger; import javax.swing.AbstractAction; import javax.swing.Action; import net.sourceforge.filebot.ResourceManager; -import net.sourceforge.filebot.ui.MessageManager; import net.sourceforge.filebot.ui.panel.rename.entry.FileEntry; import net.sourceforge.filebot.ui.panel.rename.entry.ListEntry; import net.sourceforge.tuned.FileUtil; @@ -56,9 +56,9 @@ public class RenameAction extends AbstractAction { } if (errors > 0) - MessageManager.showInfo(String.format("%d of %d files renamed.", i - errors, i)); + Logger.getLogger("ui").info(String.format("%d of %d files renamed.", i - errors, i)); else - MessageManager.showInfo(String.format("%d files renamed.", i)); + Logger.getLogger("ui").info(String.format("%d files renamed.", i)); namesList.repaint(); filesList.repaint(); diff --git a/source/net/sourceforge/tuned/ui/LoadingOverlayPane.java b/source/net/sourceforge/tuned/ui/LoadingOverlayPane.java index 73f2a697..1e768bcc 100644 --- a/source/net/sourceforge/tuned/ui/LoadingOverlayPane.java +++ b/source/net/sourceforge/tuned/ui/LoadingOverlayPane.java @@ -18,7 +18,7 @@ public class LoadingOverlayPane extends JComponent { private boolean overlayEnabled = false; - private int millisToOverlay = 500; + private int millisToOverlay = 400; public LoadingOverlayPane(JComponent component, JComponent propertyChangeSource) { @@ -27,15 +27,17 @@ public class LoadingOverlayPane extends JComponent { public LoadingOverlayPane(JComponent component, JComponent animationComponent, JComponent propertyChangeSource) { - setLayout(new MigLayout("fill, insets 0")); + setLayout(new MigLayout("insets 0, fill")); this.animationComponent = animationComponent; - add(animationComponent, "pos visual.x2-pref-18px 8px"); + add(animationComponent, "pos n 8px 100%-18px n"); add(component, "grow"); animationComponent.setVisible(false); - propertyChangeSource.addPropertyChangeListener(LOADING_PROPERTY, loadingListener); + if (propertyChangeSource != null) { + propertyChangeSource.addPropertyChangeListener(LOADING_PROPERTY, loadingListener); + } } diff --git a/source/net/sourceforge/tuned/ui/ProgressIndicator.java b/source/net/sourceforge/tuned/ui/ProgressIndicator.java index 0e8ef356..e8ba2957 100644 --- a/source/net/sourceforge/tuned/ui/ProgressIndicator.java +++ b/source/net/sourceforge/tuned/ui/ProgressIndicator.java @@ -44,7 +44,7 @@ public class ProgressIndicator extends JComponent { public void actionPerformed(ActionEvent e) { repaint(); } - });; + }); public ProgressIndicator() { @@ -82,7 +82,7 @@ public class ProgressIndicator extends JComponent { } - protected void paintShapes(Graphics2D g2d) { + private void paintShapes(Graphics2D g2d) { circle.setFrame(frame); g2d.setStroke(stroke);