From 7526a81176d797326cd1b90db452e6d18c1cac98 Mon Sep 17 00:00:00 2001 From: Denis Molony Date: Tue, 13 Dec 2016 10:46:09 +1100 Subject: [PATCH] Disk filter --- .../duplicates/DuplicateSwingWorker.java | 60 ++++---------- .../duplicates/DuplicateWindow.java | 78 ++++++++++++++----- .../duplicates/RootFolderData.java | 45 ++++++++++- .../diskbrowser/gui/CountDisksAction.java | 52 +++++++++++++ .../bytezone/diskbrowser/gui/DiskBrowser.java | 7 +- .../diskbrowser/gui/DuplicateAction.java | 31 ++++---- .../bytezone/diskbrowser/gui/MenuHandler.java | 11 ++- 7 files changed, 192 insertions(+), 92 deletions(-) create mode 100644 src/com/bytezone/diskbrowser/gui/CountDisksAction.java diff --git a/src/com/bytezone/diskbrowser/duplicates/DuplicateSwingWorker.java b/src/com/bytezone/diskbrowser/duplicates/DuplicateSwingWorker.java index 17bb4f2..2de6748 100644 --- a/src/com/bytezone/diskbrowser/duplicates/DuplicateSwingWorker.java +++ b/src/com/bytezone/diskbrowser/duplicates/DuplicateSwingWorker.java @@ -1,50 +1,24 @@ package com.bytezone.diskbrowser.duplicates; -import java.awt.Dimension; -import java.awt.Graphics; import java.io.File; import java.util.List; -import javax.swing.JDialog; -import javax.swing.JPanel; import javax.swing.SwingWorker; import com.bytezone.diskbrowser.utilities.Utility; public class DuplicateSwingWorker extends SwingWorker { - private final File rootFolder; private final int rootFolderNameLength; - // private final ProgressState progressState = new ProgressState (); - private final DuplicateWindow owner; - private final JDialog dialog; - private final ProgressPanel progressPanel; - private final boolean doChecksums; private final RootFolderData rootFolderData; - public DuplicateSwingWorker (File rootFolder, DuplicateWindow owner, - boolean doChecksums) + public DuplicateSwingWorker (RootFolderData rootFolderData) { - this.rootFolder = rootFolder; - this.owner = owner; - this.doChecksums = doChecksums; - rootFolderNameLength = rootFolder.getAbsolutePath ().length (); + this.rootFolderData = rootFolderData; + rootFolderNameLength = rootFolderData.rootFolder.getAbsolutePath ().length (); - rootFolderData = new RootFolderData (); - - dialog = new JDialog (owner); - progressPanel = new ProgressPanel (); - progressPanel.setPreferredSize (new Dimension (485, 300)); - dialog.add (progressPanel); - dialog.setTitle ("Reading disks"); - dialog.pack (); - dialog.setLocationRelativeTo (null); - dialog.setVisible (true); - } - - File getRootFolder () - { - return rootFolder; + rootFolderData.dialog.setLocationRelativeTo (null); + rootFolderData.dialog.setVisible (true); } private void traverse (File directory) @@ -80,14 +54,15 @@ public class DuplicateSwingWorker extends SwingWorker private void checkDuplicates (File file, String filename) { String rootName = file.getAbsolutePath ().substring (rootFolderNameLength); - DiskDetails diskDetails = new DiskDetails (file, rootName, filename, doChecksums); + DiskDetails diskDetails = + new DiskDetails (file, rootName, filename, rootFolderData.doChecksums); if (rootFolderData.fileNameMap.containsKey (filename)) rootFolderData.fileNameMap.get (filename).addDuplicateName (diskDetails); else rootFolderData.fileNameMap.put (filename, diskDetails); - if (doChecksums) + if (rootFolderData.doChecksums) { long checksum = diskDetails.getChecksum (); if (rootFolderData.checksumMap.containsKey (checksum)) @@ -102,8 +77,9 @@ public class DuplicateSwingWorker extends SwingWorker { try { - dialog.setVisible (false); - owner.setTableData (rootFolderData); + if (!rootFolderData.showTotals) + rootFolderData.dialog.setVisible (false); + rootFolderData.window.setTableData (rootFolderData); } catch (Exception e) { @@ -114,7 +90,7 @@ public class DuplicateSwingWorker extends SwingWorker @Override protected Void doInBackground () throws Exception { - traverse (rootFolder); + traverse (rootFolderData.rootFolder); rootFolderData.progressState.print (); return null; } @@ -122,16 +98,6 @@ public class DuplicateSwingWorker extends SwingWorker @Override protected void process (List chunks) { - progressPanel.repaint (); - } - - class ProgressPanel extends JPanel - { - @Override - protected void paintComponent (Graphics graphics) - { - super.paintComponent (graphics); - rootFolderData.progressState.paintComponent (graphics); - } + rootFolderData.progressPanel.repaint (); } } \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/duplicates/DuplicateWindow.java b/src/com/bytezone/diskbrowser/duplicates/DuplicateWindow.java index 83d56ac..3545bbc 100644 --- a/src/com/bytezone/diskbrowser/duplicates/DuplicateWindow.java +++ b/src/com/bytezone/diskbrowser/duplicates/DuplicateWindow.java @@ -7,7 +7,7 @@ import java.awt.FlowLayout; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.io.File; +import java.util.ArrayList; import java.util.List; import javax.swing.*; @@ -17,7 +17,6 @@ import javax.swing.table.JTableHeader; import javax.swing.table.TableColumnModel; import javax.swing.table.TableRowSorter; -import com.bytezone.diskbrowser.gui.DuplicateAction; import com.bytezone.diskbrowser.gui.DuplicateAction.DiskTableSelectionListener; import com.bytezone.diskbrowser.utilities.NumberRenderer; import com.bytezone.diskbrowser.utilities.Utility; @@ -28,18 +27,16 @@ public class DuplicateWindow extends JFrame private final JButton btnExport = new JButton ("Export"); private final JButton btnHide = new JButton ("Close"); - private final JLabel lblTotalDisks = new JLabel (); - // private final ButtonGroup grpFileType = new ButtonGroup (); + // private final JLabel lblTotalDisks = new JLabel (); private final JPanel topPanel = new JPanel (); + private final List boxes = new ArrayList (); + private TableRowSorter sorter; + private final CheckBoxActionListener checkBoxActionListener = + new CheckBoxActionListener (); - private final List listeners; - - public DuplicateWindow (File rootFolder, - List listeners) + public DuplicateWindow (RootFolderData rootFolderData) { - super ("Duplicate Disk Detection - " + rootFolder.getAbsolutePath ()); - - this.listeners = listeners; + super ("Disk List - " + rootFolderData.rootFolder.getAbsolutePath ()); table = new JTable (); JScrollPane scrollPane = @@ -60,8 +57,6 @@ public class DuplicateWindow extends JFrame add (panel, BorderLayout.SOUTH); topPanel.setLayout (new FlowLayout (FlowLayout.LEFT, 10, 5)); - topPanel.add (new JLabel ("Total disks:")); - topPanel.add (lblTotalDisks); add (topPanel, BorderLayout.NORTH); btnHide.setEnabled (true); @@ -72,7 +67,7 @@ public class DuplicateWindow extends JFrame @Override public void actionPerformed (ActionEvent e) { - DuplicateWindow.this.setVisible (false); + setVisible (false); } }); @@ -81,11 +76,11 @@ public class DuplicateWindow extends JFrame } // called from DuplicateSwingWorker - public void setTableData (RootFolderData rootFolderData) + public void setTableData (final RootFolderData rootFolderData) { DiskTableModel diskTableModel = new DiskTableModel (rootFolderData); table.setModel (diskTableModel); - lblTotalDisks.setText (diskTableModel.getRowCount () + ""); + // lblTotalDisks.setText (diskTableModel.getRowCount () + ""); int[] columnWidths = { 300, 300, 30, 40, 40, 40, 100 }; TableColumnModel tcm = table.getColumnModel (); @@ -94,8 +89,7 @@ public class DuplicateWindow extends JFrame tcm.getColumn (3).setCellRenderer (NumberRenderer.getIntegerRenderer ()); - final TableRowSorter sorter = - new TableRowSorter ((DiskTableModel) table.getModel ()); + sorter = new TableRowSorter ((DiskTableModel) table.getModel ()); table.setRowSorter (sorter); ListSelectionModel listSelectionModel = table.getSelectionModel (); @@ -119,7 +113,7 @@ public class DuplicateWindow extends JFrame DiskTableModel diskTableModel = (DiskTableModel) table.getModel (); DiskDetails diskDetails = diskTableModel.lines.get (actualRow).diskDetails; - for (DiskTableSelectionListener listener : listeners) + for (DiskTableSelectionListener listener : rootFolderData.listeners) listener.diskSelected (diskDetails); } }); @@ -130,10 +124,15 @@ public class DuplicateWindow extends JFrame JCheckBox btn = new JCheckBox (String.format ("%s (%,d)", Utility.suffixes.get (i), total)); topPanel.add (btn); + boxes.add (btn); if (total > 0) + { btn.setSelected (true); - // grpFileType.add (btn); + btn.addActionListener (checkBoxActionListener); + } + else + btn.setEnabled (false); } JTableHeader header = table.getTableHeader (); @@ -141,6 +140,43 @@ public class DuplicateWindow extends JFrame pack (); setLocationRelativeTo (null); - setVisible (true); + + if (!rootFolderData.showTotals) + setVisible (true); + } + + private String getFilterText () + { + StringBuilder filterText = new StringBuilder (); + for (JCheckBox box : boxes) + if (box.isSelected ()) + { + String text = box.getText (); + int pos = text.indexOf (' '); + filterText.append (text.substring (0, pos) + "|"); + } + + if (filterText.length () > 0) + filterText.deleteCharAt (filterText.length () - 1); + + return filterText.toString (); + } + + class CheckBoxActionListener implements ActionListener + { + @Override + public void actionPerformed (ActionEvent e) + { + RowFilter rf = null; + try + { + rf = RowFilter.regexFilter (getFilterText (), 2); + } + catch (java.util.regex.PatternSyntaxException exception) + { + return; + } + sorter.setRowFilter (rf); + } } } \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/duplicates/RootFolderData.java b/src/com/bytezone/diskbrowser/duplicates/RootFolderData.java index 5a237fb..12a7144 100644 --- a/src/com/bytezone/diskbrowser/duplicates/RootFolderData.java +++ b/src/com/bytezone/diskbrowser/duplicates/RootFolderData.java @@ -1,11 +1,23 @@ package com.bytezone.diskbrowser.duplicates; +import java.awt.Dimension; +import java.awt.Graphics; +import java.io.File; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.TreeMap; +import javax.swing.JDialog; +import javax.swing.JPanel; + +import com.bytezone.diskbrowser.gui.DuplicateAction.DiskTableSelectionListener; + public class RootFolderData { + public File rootFolder; + // list of checksum -> DiskDetails public final Map checksumMap = new HashMap (); @@ -13,8 +25,35 @@ public class RootFolderData public final Map fileNameMap = new TreeMap (); public final ProgressState progressState = new ProgressState (); + public final ProgressPanel progressPanel; - // public RootFolderData () - // { - // } + public DuplicateWindow window; + + public final List listeners = + new ArrayList (); + + public boolean doChecksums; + public boolean showTotals; + + public JDialog dialog; + + public RootFolderData () + { + dialog = new JDialog (window); + progressPanel = new ProgressPanel (); + progressPanel.setPreferredSize (new Dimension (485, 300)); + dialog.add (progressPanel); + dialog.setTitle ("Disk Totals"); + dialog.pack (); + } + + class ProgressPanel extends JPanel + { + @Override + protected void paintComponent (Graphics graphics) + { + super.paintComponent (graphics); + progressState.paintComponent (graphics); + } + } } \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/gui/CountDisksAction.java b/src/com/bytezone/diskbrowser/gui/CountDisksAction.java new file mode 100644 index 0000000..c9de522 --- /dev/null +++ b/src/com/bytezone/diskbrowser/gui/CountDisksAction.java @@ -0,0 +1,52 @@ +package com.bytezone.diskbrowser.gui; + +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; +import java.io.File; + +import javax.swing.Action; +import javax.swing.KeyStroke; + +import com.bytezone.common.DefaultAction; +import com.bytezone.diskbrowser.duplicates.DuplicateSwingWorker; +import com.bytezone.diskbrowser.duplicates.DuplicateWindow; +import com.bytezone.diskbrowser.duplicates.RootFolderData; +import com.bytezone.diskbrowser.gui.RootDirectoryAction.RootDirectoryChangeListener; + +public class CountDisksAction extends DefaultAction implements RootDirectoryChangeListener +{ + RootFolderData rootFolderData; + + public CountDisksAction (RootFolderData rootFolderData) + { + super ("Count disks...", "Display a window showing disk totals"); + + this.rootFolderData = rootFolderData; + + int mask = Toolkit.getDefaultToolkit ().getMenuShortcutKeyMask (); + putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke (KeyEvent.VK_I, mask)); + setEnabled (rootFolderData.rootFolder != null); + } + + @Override + public void actionPerformed (ActionEvent e) + { + if (rootFolderData.window == null) + { + rootFolderData.showTotals = true; + rootFolderData.window = new DuplicateWindow (rootFolderData); + new DuplicateSwingWorker (rootFolderData).execute (); + } + else + rootFolderData.dialog.setVisible (true); + } + + @Override + public void rootDirectoryChanged (File rootFolder) + { + rootFolderData.rootFolder = rootFolder; + setEnabled (rootFolder != null); + rootFolderData.window = null; + } +} \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/gui/DiskBrowser.java b/src/com/bytezone/diskbrowser/gui/DiskBrowser.java index 0213460..f87999d 100755 --- a/src/com/bytezone/diskbrowser/gui/DiskBrowser.java +++ b/src/com/bytezone/diskbrowser/gui/DiskBrowser.java @@ -11,6 +11,7 @@ import com.bytezone.common.Platform; import com.bytezone.common.QuitAction; import com.bytezone.common.QuitAction.QuitListener; import com.bytezone.common.State; +import com.bytezone.diskbrowser.duplicates.RootFolderData; public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitListener { @@ -53,11 +54,14 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi addPanel (diskLayoutPanel, "Disk layout", BorderLayout.EAST); // create actions - DuplicateAction duplicateAction = new DuplicateAction (); + RootFolderData rootFolderData = new RootFolderData (); + DuplicateAction duplicateAction = new DuplicateAction (rootFolderData); + CountDisksAction countDisksAction = new CountDisksAction (rootFolderData); RootDirectoryAction rootDirectoryAction = new RootDirectoryAction (catalogPanel.getRootDirectory ()); rootDirectoryAction.addListener (catalogPanel); rootDirectoryAction.addListener (duplicateAction); + rootDirectoryAction.addListener (countDisksAction); RefreshTreeAction refreshTreeAction = new RefreshTreeAction (catalogPanel); // PreferencesAction preferencesAction = new PreferencesAction (this, prefs); @@ -116,6 +120,7 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi menuHandler.showLayoutItem.setAction (hideLayoutAction); menuHandler.showFreeSectorsItem.setAction (showFreeAction); menuHandler.duplicateItem.setAction (duplicateAction); + menuHandler.countDisksItem.setAction (countDisksAction); menuHandler.closeTabItem.setAction (closeTabAction); final QuitAction quitAction = Platform.setQuit (this, prefs, menuHandler.fileMenu); diff --git a/src/com/bytezone/diskbrowser/gui/DuplicateAction.java b/src/com/bytezone/diskbrowser/gui/DuplicateAction.java index f124166..4ac185d 100644 --- a/src/com/bytezone/diskbrowser/gui/DuplicateAction.java +++ b/src/com/bytezone/diskbrowser/gui/DuplicateAction.java @@ -4,8 +4,6 @@ import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.io.File; -import java.util.ArrayList; -import java.util.List; import javax.swing.Action; import javax.swing.JOptionPane; @@ -15,39 +13,39 @@ import com.bytezone.common.DefaultAction; import com.bytezone.diskbrowser.duplicates.DiskDetails; import com.bytezone.diskbrowser.duplicates.DuplicateSwingWorker; import com.bytezone.diskbrowser.duplicates.DuplicateWindow; +import com.bytezone.diskbrowser.duplicates.RootFolderData; import com.bytezone.diskbrowser.gui.RootDirectoryAction.RootDirectoryChangeListener; public class DuplicateAction extends DefaultAction implements RootDirectoryChangeListener { - private File rootFolder; - private DuplicateWindow window; - private final List listeners = - new ArrayList (); + RootFolderData rootFolderData; - public DuplicateAction () + public DuplicateAction (RootFolderData rootFolderData) { super ("List disks...", "Display a sortable list of disks", "/com/bytezone/diskbrowser/icons/"); + this.rootFolderData = rootFolderData; + setIcon (Action.SMALL_ICON, "save_delete_16.png"); setIcon (Action.LARGE_ICON_KEY, "save_delete_32.png"); int mask = Toolkit.getDefaultToolkit ().getMenuShortcutKeyMask (); putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke (KeyEvent.VK_L, mask)); - setEnabled (false); + setEnabled (rootFolderData.rootFolder != null); } @Override public void rootDirectoryChanged (File rootFolder) { - this.rootFolder = rootFolder; + rootFolderData.rootFolder = rootFolder; setEnabled (rootFolder != null); - window = null; + rootFolderData.window = null; } @Override public void actionPerformed (ActionEvent arg0) { - if (window == null) + if (rootFolderData.window == null) { Object[] options = { "Generate checksums", "Disk names only", "Cancel" }; int option = JOptionPane.showOptionDialog (null, @@ -59,18 +57,19 @@ public class DuplicateAction extends DefaultAction implements RootDirectoryChang JOptionPane.QUESTION_MESSAGE, null, options, options[1]); // just disk names if (option < 2) { - window = new DuplicateWindow (rootFolder, listeners); - new DuplicateSwingWorker (rootFolder, window, option == 0).execute (); + rootFolderData.doChecksums = option == 0; + rootFolderData.window = new DuplicateWindow (rootFolderData); + new DuplicateSwingWorker (rootFolderData).execute (); } } else - window.setVisible (true); + rootFolderData.window.setVisible (true); } public void addTableSelectionListener (DiskTableSelectionListener listener) { - if (!listeners.contains (listener)) - listeners.add (listener); + if (!rootFolderData.listeners.contains (listener)) + rootFolderData.listeners.add (listener); } public interface DiskTableSelectionListener diff --git a/src/com/bytezone/diskbrowser/gui/MenuHandler.java b/src/com/bytezone/diskbrowser/gui/MenuHandler.java index 8c64c05..864dcbe 100755 --- a/src/com/bytezone/diskbrowser/gui/MenuHandler.java +++ b/src/com/bytezone/diskbrowser/gui/MenuHandler.java @@ -46,6 +46,7 @@ public class MenuHandler JMenuItem dbItem = new JMenuItem (new CreateDatabaseAction ()); JMenuItem closeTabItem = new JMenuItem (); JMenuItem duplicateItem = new JMenuItem (); + JMenuItem countDisksItem = new JMenuItem (); FontAction fontAction; // Format menu items @@ -99,7 +100,9 @@ public class MenuHandler fileMenu.add (createDiskFileItem); fileMenu.add (dbItem); } + fileMenu.add (duplicateItem); + fileMenu.add (countDisksItem); formatMenu.add (lineWrapItem); formatMenu.add (showCatalogItem); @@ -152,11 +155,11 @@ public class MenuHandler try { if (functionName.equals ("about")) - OSXAdapter.setAboutHandler (action, action.getClass () - .getDeclaredMethod (functionName, (Class[]) null)); + OSXAdapter.setAboutHandler (action, + action.getClass ().getDeclaredMethod (functionName, (Class[]) null)); else if (functionName.equals ("prefs")) - OSXAdapter.setPreferencesHandler (action, action.getClass () - .getDeclaredMethod (functionName, (Class[]) null)); + OSXAdapter.setPreferencesHandler (action, + action.getClass ().getDeclaredMethod (functionName, (Class[]) null)); } catch (Exception e) {