+ Optimize for large lists by automatically setting prototypeValue to the longest (String value) item (boost performance by 1000x when loading large lists of files / episodes)

This commit is contained in:
Reinhard Pointner 2014-07-30 18:44:18 +00:00
parent af000a2026
commit d67e112c3b
2 changed files with 63 additions and 46 deletions

View File

@ -1,7 +1,5 @@
package net.filebot.ui.rename;
import static java.util.Collections.*;
import java.awt.BorderLayout;
@ -12,7 +10,10 @@ import java.awt.event.MouseEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.ListModel;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import net.filebot.ResourceManager;
import net.filebot.ui.FileBotList;
@ -21,19 +22,52 @@ import net.filebot.ui.transfer.TransferablePolicy;
import net.miginfocom.swing.MigLayout;
import ca.odell.glazedlists.EventList;
class RenameList<E> extends FileBotList<E> {
private JPanel buttonPanel;
public RenameList(EventList<E> model) {
// replace default model with given model
setModel(model);
list.setFixedCellHeight(28); // need a fixed cell high for high performance scrolling
// disable multi-selection for the sake of simplicity
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
// need a fixed cell size for high performance scrolling
list.setFixedCellHeight(28);
list.getModel().addListDataListener(new ListDataListener() {
private int longestItem = -1;
@Override
public void intervalRemoved(ListDataEvent evt) {
// reset prototype value
ListModel<?> m = (ListModel<?>) evt.getSource();
if (m.getSize() == 0) {
list.setPrototypeCellValue(null);
longestItem = -1;
}
}
@Override
public void intervalAdded(ListDataEvent evt) {
contentsChanged(evt);
}
@Override
public void contentsChanged(ListDataEvent evt) {
ListModel<?> m = (ListModel<?>) evt.getSource();
for (int i = evt.getIndex0(); i <= evt.getIndex1() && i < m.getSize(); i++) {
Object item = m.getElementAt(i);
int itemLength = item.toString().length();
if (itemLength > longestItem) {
list.setPrototypeCellValue(item);
longestItem = itemLength;
}
}
}
});
list.addMouseListener(dndReorderMouseAdapter);
list.addMouseMotionListener(dndReorderMouseAdapter);
@ -50,19 +84,16 @@ class RenameList<E> extends FileBotList<E> {
listScrollPane.getViewport().setBackground(list.getBackground());
}
public JPanel getButtonPanel() {
return buttonPanel;
}
@Override
public void setTransferablePolicy(TransferablePolicy transferablePolicy) {
super.setTransferablePolicy(transferablePolicy);
loadAction.putValue(LoadAction.TRANSFERABLE_POLICY, transferablePolicy);
}
private final LoadAction loadAction = new LoadAction(null);
private final AbstractAction upAction = new AbstractAction(null, ResourceManager.getIcon("action.up")) {
@ -93,13 +124,11 @@ class RenameList<E> extends FileBotList<E> {
private int lastIndex = -1;
@Override
public void mousePressed(MouseEvent m) {
lastIndex = getListComponent().getSelectedIndex();
}
@Override
public void mouseDragged(MouseEvent m) {
int currentIndex = getListComponent().getSelectedIndex();

View File

@ -155,9 +155,6 @@ public class RenamePanel extends JComponent {
@Override
public void actionPerformed(ActionEvent e) {
// lock cell with once user starts deleting cells (performance hack)
setFixedCellWidth(true);
RenameList list = null;
boolean deleteCell;
@ -529,9 +526,6 @@ public class RenamePanel extends JComponent {
} else {
renameModel.clear();
}
// lock cell with once user starts deleting cells (performance hack)
setFixedCellWidth(false);
}
};
@ -684,10 +678,4 @@ public class RenamePanel extends JComponent {
}
}
public void setFixedCellWidth(boolean fixed) {
for (RenameList<?> it : new RenameList[] { namesList, filesList }) {
it.getListComponent().setFixedCellWidth(fixed ? (int) it.getListComponent().getPreferredSize().getWidth() : -1);
}
}
}