From d67e112c3b2740bed60e41ca1d30a7519c263841 Mon Sep 17 00:00:00 2001 From: Reinhard Pointner Date: Wed, 30 Jul 2014 18:44:18 +0000 Subject: [PATCH] + 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) --- source/net/filebot/ui/rename/RenameList.java | 97 ++++++++++++------- source/net/filebot/ui/rename/RenamePanel.java | 12 --- 2 files changed, 63 insertions(+), 46 deletions(-) diff --git a/source/net/filebot/ui/rename/RenameList.java b/source/net/filebot/ui/rename/RenameList.java index ec3fb128..ad4cd638 100644 --- a/source/net/filebot/ui/rename/RenameList.java +++ b/source/net/filebot/ui/rename/RenameList.java @@ -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,94 +22,122 @@ import net.filebot.ui.transfer.TransferablePolicy; import net.miginfocom.swing.MigLayout; import ca.odell.glazedlists.EventList; - class RenameList extends FileBotList { - + private JPanel buttonPanel; - - + public RenameList(EventList 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); - + getRemoveAction().setEnabled(true); - + buttonPanel = new JPanel(new MigLayout("insets 1.2mm, nogrid, fill", "align center")); - + buttonPanel.add(new JButton(downAction), "gap 10px"); buttonPanel.add(new JButton(upAction), "gap 0"); buttonPanel.add(new JButton(loadAction), "gap 10px"); - + add(buttonPanel, BorderLayout.SOUTH); - + 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")) { - + public void actionPerformed(ActionEvent e) { int index = getListComponent().getSelectedIndex(); - + if (index > 0) { swap(model, index, index - 1); getListComponent().setSelectedIndex(index - 1); } } }; - + private final AbstractAction downAction = new AbstractAction(null, ResourceManager.getIcon("action.down")) { - + public void actionPerformed(ActionEvent e) { int index = getListComponent().getSelectedIndex(); - + if (index < model.size() - 1) { swap(model, index, index + 1); getListComponent().setSelectedIndex(index + 1); } } }; - + private final MouseAdapter dndReorderMouseAdapter = new MouseAdapter() { - + private int lastIndex = -1; - - + @Override public void mousePressed(MouseEvent m) { lastIndex = getListComponent().getSelectedIndex(); } - - + @Override public void mouseDragged(MouseEvent m) { int currentIndex = getListComponent().getSelectedIndex(); - + if (currentIndex != lastIndex && lastIndex >= 0 && currentIndex >= 0) { swap(model, lastIndex, currentIndex); lastIndex = currentIndex; } } }; - + } diff --git a/source/net/filebot/ui/rename/RenamePanel.java b/source/net/filebot/ui/rename/RenamePanel.java index f91dd331..49599a0c 100644 --- a/source/net/filebot/ui/rename/RenamePanel.java +++ b/source/net/filebot/ui/rename/RenamePanel.java @@ -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); - } - } - }