* fixed potential EDT deadlock in Tool

* display messages via ui logger
* maybe fix layout bug (component gets very small) for LoadingOverlayPane
This commit is contained in:
Reinhard Pointner 2008-12-28 20:04:13 +00:00
parent 931efbdd06
commit 1dfa8abcfd
14 changed files with 163 additions and 89 deletions

View File

@ -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;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -134,6 +134,10 @@ public abstract class AbstractSearchPanel<S, E, T extends JComponent> 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<S, E, T extends JComponent> 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<S, E, T extends JComponent> 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<S, E, T extends JComponent> 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);

View File

@ -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));
}
}

View File

@ -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() {
}
}

View File

@ -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());

View File

@ -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);
}
}
}

View File

@ -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<M> 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<M> 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<M> extends JComponent {
Logger.getLogger("global").log(Level.WARNING, e.toString());
}
}
setLoading(false);
updateSemaphore.release();
}
}
@ -111,4 +118,16 @@ abstract class Tool<M> 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());
}
}
};
}

View File

@ -31,9 +31,9 @@ public class TypeTool extends Tool<TreeModel> {
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);

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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();

View File

@ -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,16 +27,18 @@ 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);
if (propertyChangeSource != null) {
propertyChangeSource.addPropertyChangeListener(LOADING_PROPERTY, loadingListener);
}
}
@Override

View File

@ -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);