* improved scrollpane synchronisation
This commit is contained in:
parent
73273b8b5b
commit
2963baa889
|
@ -32,8 +32,6 @@ public class FileBotList<E> extends JComponent {
|
|||
|
||||
protected JScrollPane listScrollPane = new JScrollPane(list);
|
||||
|
||||
private String title = null;
|
||||
|
||||
|
||||
public FileBotList() {
|
||||
setLayout(new BorderLayout());
|
||||
|
@ -70,6 +68,11 @@ public class FileBotList<E> extends JComponent {
|
|||
}
|
||||
|
||||
|
||||
public JScrollPane getListScrollPane() {
|
||||
return listScrollPane;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public DefaultTransferHandler getTransferHandler() {
|
||||
return (DefaultTransferHandler) list.getTransferHandler();
|
||||
|
@ -100,18 +103,17 @@ public class FileBotList<E> 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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<E> extends FileBotList<E> {
|
|||
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<E> extends FileBotList<E> {
|
|||
buttonPanel.add(new JButton(loadAction), "gap 10px");
|
||||
|
||||
add(buttonPanel, BorderLayout.SOUTH);
|
||||
}
|
||||
|
||||
|
||||
public JViewport getViewPort() {
|
||||
return listScrollPane.getViewport();
|
||||
|
||||
listScrollPane.getViewport().setBackground(list.getBackground());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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<EpisodeExpressionFormatter> persistentFormatExpression = Settings.userRoot().entry("rename.format", new AbstractAdapter<EpisodeExpressionFormatter>() {
|
||||
private final PreferencesEntry<EpisodeExpressionFormatter> persistentExpressionFormatter = Settings.userRoot().entry("rename.format", new AbstractAdapter<EpisodeExpressionFormatter>() {
|
||||
|
||||
@Override
|
||||
public EpisodeExpressionFormatter get(Preferences prefs, String key) {
|
||||
|
|
|
@ -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<Object> resizeListener = new ListEventListener<Object>() {
|
||||
|
||||
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<Object> 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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue