diff --git a/source/net/sourceforge/filebot/ui/FileBotList.java b/source/net/sourceforge/filebot/ui/FileBotList.java index 345edd39..aef0e9ab 100644 --- a/source/net/sourceforge/filebot/ui/FileBotList.java +++ b/source/net/sourceforge/filebot/ui/FileBotList.java @@ -32,8 +32,6 @@ public class FileBotList extends JComponent { protected JScrollPane listScrollPane = new JScrollPane(list); - private String title = null; - public FileBotList() { setLayout(new BorderLayout()); @@ -70,6 +68,11 @@ public class FileBotList extends JComponent { } + public JScrollPane getListScrollPane() { + return listScrollPane; + } + + @Override public DefaultTransferHandler getTransferHandler() { return (DefaultTransferHandler) list.getTransferHandler(); @@ -100,18 +103,17 @@ public class FileBotList extends JComponent { public String getTitle() { - return title; + return (String) getClientProperty("title"); } public void setTitle(String title) { - this.title = title; + putClientProperty("title", title); if (getBorder() instanceof TitledBorder) { - TitledBorder titledBorder = (TitledBorder) getBorder(); - titledBorder.setTitle(title); + TitledBorder border = (TitledBorder) getBorder(); + border.setTitle(title); - revalidate(); repaint(); } } diff --git a/source/net/sourceforge/filebot/ui/panel/rename/RenameList.java b/source/net/sourceforge/filebot/ui/panel/rename/RenameList.java index e43ff47c..1f674d20 100644 --- a/source/net/sourceforge/filebot/ui/panel/rename/RenameList.java +++ b/source/net/sourceforge/filebot/ui/panel/rename/RenameList.java @@ -12,7 +12,6 @@ import java.awt.event.MouseEvent; import javax.swing.AbstractAction; import javax.swing.JButton; import javax.swing.JPanel; -import javax.swing.JViewport; import javax.swing.ListSelectionModel; import net.miginfocom.swing.MigLayout; @@ -35,8 +34,6 @@ class RenameList extends FileBotList { list.addMouseListener(dndReorderMouseAdapter); list.addMouseMotionListener(dndReorderMouseAdapter); - getViewPort().setBackground(list.getBackground()); - getRemoveAction().setEnabled(true); JPanel buttonPanel = new JPanel(new MigLayout("insets 1.2mm, nogrid, fill", "align center")); @@ -46,11 +43,8 @@ class RenameList extends FileBotList { buttonPanel.add(new JButton(loadAction), "gap 10px"); add(buttonPanel, BorderLayout.SOUTH); - } - - - public JViewport getViewPort() { - return listScrollPane.getViewport(); + + listScrollPane.getViewport().setBackground(list.getBackground()); } diff --git a/source/net/sourceforge/filebot/ui/panel/rename/RenamePanel.java b/source/net/sourceforge/filebot/ui/panel/rename/RenamePanel.java index 779a16f3..83c1b885 100644 --- a/source/net/sourceforge/filebot/ui/panel/rename/RenamePanel.java +++ b/source/net/sourceforge/filebot/ui/panel/rename/RenamePanel.java @@ -91,7 +91,7 @@ public class RenamePanel extends JComponent { renameModel.useFormatter(File.class, new FileNameFormatter(renameModel.preserveExtension())); // restore custom episode formatter - renameModel.useFormatter(Episode.class, persistentFormatExpression.getValue()); + renameModel.useFormatter(Episode.class, persistentExpressionFormatter.getValue()); RenameListCellRenderer cellrenderer = new RenameListCellRenderer(renameModel); @@ -106,7 +106,7 @@ public class RenamePanel extends JComponent { filesList.getListComponent().setSelectionModel(selectionModel); // synchronize viewports - new ViewPortSynchronizer(namesList.getViewPort(), filesList.getViewPort()); + new ScrollPaneSynchronizer(namesList, filesList); // create Match button JButton matchButton = new JButton(matchAction); @@ -169,7 +169,7 @@ public class RenamePanel extends JComponent { try { EpisodeExpressionFormatter formatter = new EpisodeExpressionFormatter(dialog.getExpression()); renameModel.useFormatter(Episode.class, formatter); - persistentFormatExpression.setValue(formatter); + persistentExpressionFormatter.setValue(formatter); } catch (ScriptException e) { // will not happen because illegal expressions cannot be approved in dialog Logger.getLogger("ui").log(Level.WARNING, e.getMessage(), e); @@ -177,7 +177,7 @@ public class RenamePanel extends JComponent { break; case USE_DEFAULT: renameModel.useFormatter(Episode.class, null); - persistentFormatExpression.remove(); + persistentExpressionFormatter.remove(); break; } } @@ -372,7 +372,7 @@ public class RenamePanel extends JComponent { } } - private final PreferencesEntry persistentFormatExpression = Settings.userRoot().entry("rename.format", new AbstractAdapter() { + private final PreferencesEntry persistentExpressionFormatter = Settings.userRoot().entry("rename.format", new AbstractAdapter() { @Override public EpisodeExpressionFormatter get(Preferences prefs, String key) { diff --git a/source/net/sourceforge/filebot/ui/panel/rename/ScrollPaneSynchronizer.java b/source/net/sourceforge/filebot/ui/panel/rename/ScrollPaneSynchronizer.java new file mode 100644 index 00000000..a6dca5d0 --- /dev/null +++ b/source/net/sourceforge/filebot/ui/panel/rename/ScrollPaneSynchronizer.java @@ -0,0 +1,86 @@ + +package net.sourceforge.filebot.ui.panel.rename; + + +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.BoundedRangeModel; +import javax.swing.Timer; + +import ca.odell.glazedlists.event.ListEvent; +import ca.odell.glazedlists.event.ListEventListener; + + +class ScrollPaneSynchronizer { + + private final RenameList[] components; + + + public ScrollPaneSynchronizer(RenameList... components) { + this.components = components; + + // share vertical and horizontal scrollbar model + BoundedRangeModel horizontalScrollBarModel = components[0].getListScrollPane().getHorizontalScrollBar().getModel(); + BoundedRangeModel verticalScrollBarModel = components[0].getListScrollPane().getVerticalScrollBar().getModel(); + + // recalculate common size on change + ListEventListener resizeListener = new ListEventListener() { + + private final Timer timer = new Timer(50, new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + syncSize(); + + // run only once + timer.stop(); + } + }); + + + @Override + public void listChanged(ListEvent evt) { + // sync size when there are no more events coming in + timer.restart(); + } + }; + + // apply to all components + for (RenameList component : components) { + component.getListScrollPane().getHorizontalScrollBar().setModel(horizontalScrollBarModel); + component.getListScrollPane().getVerticalScrollBar().setModel(verticalScrollBarModel); + + component.getModel().addListEventListener(resizeListener); + } + } + + + public void syncSize() { + Dimension max = new Dimension(); + + for (RenameList component : components) { + // reset preferred size + component.getListComponent().setPreferredSize(null); + + // calculate preferred size based on data and renderer + Dimension preferred = component.getListComponent().getPreferredSize(); + + // update maximum size + if (preferred.width > max.width) + max.width = preferred.width; + if (preferred.height > max.height) + max.height = preferred.height; + } + + for (RenameList component : components) { + // set fixed preferred size + component.getListComponent().setPreferredSize(max); + + // update scrollbars + component.getListScrollPane().revalidate(); + } + } + +} diff --git a/source/net/sourceforge/filebot/ui/panel/rename/ViewPortSynchronizer.java b/source/net/sourceforge/filebot/ui/panel/rename/ViewPortSynchronizer.java deleted file mode 100644 index f36aa4a6..00000000 --- a/source/net/sourceforge/filebot/ui/panel/rename/ViewPortSynchronizer.java +++ /dev/null @@ -1,69 +0,0 @@ - -package net.sourceforge.filebot.ui.panel.rename; - - -import java.awt.Point; - -import javax.swing.JViewport; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; - - -class ViewPortSynchronizer { - - private final JViewport viewport1; - private final JViewport viewport2; - - private final ViewPortSynchronizeListener viewPortSynchronizeListener1; - private final ViewPortSynchronizeListener viewPortSynchronizeListener2; - - - public ViewPortSynchronizer(JViewport viewport1, JViewport viewport2) { - this.viewport1 = viewport1; - this.viewport2 = viewport2; - - viewPortSynchronizeListener1 = new ViewPortSynchronizeListener(viewport2); - viewPortSynchronizeListener2 = new ViewPortSynchronizeListener(viewport1); - - setEnabled(true); - } - - - public void setEnabled(boolean enabled) { - // remove listeners to avoid adding them multiple times - viewport1.removeChangeListener(viewPortSynchronizeListener1); - viewport2.removeChangeListener(viewPortSynchronizeListener2); - - // if enabled add them again - if (enabled) { - viewport1.addChangeListener(viewPortSynchronizeListener1); - viewport2.addChangeListener(viewPortSynchronizeListener2); - } - } - - - private static class ViewPortSynchronizeListener implements ChangeListener { - - private final JViewport target; - - - public ViewPortSynchronizeListener(JViewport target) { - this.target = target; - } - - - @Override - public void stateChanged(ChangeEvent e) { - JViewport source = (JViewport) e.getSource(); - - Point viewPosition = source.getViewPosition(); - - // return if both viewports have the same view position - if (!viewPosition.equals(target.getViewPosition())) { - target.setViewPosition(viewPosition); - target.repaint(); - } - } - } - -}