Disk filter

This commit is contained in:
Denis Molony 2016-12-13 10:46:09 +11:00
parent e08edfcab7
commit 7526a81176
7 changed files with 192 additions and 92 deletions

View File

@ -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<Void, ProgressState>
{
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<Void, ProgressState>
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<Void, ProgressState>
{
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<Void, ProgressState>
@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<Void, ProgressState>
@Override
protected void process (List<ProgressState> chunks)
{
progressPanel.repaint ();
}
class ProgressPanel extends JPanel
{
@Override
protected void paintComponent (Graphics graphics)
{
super.paintComponent (graphics);
rootFolderData.progressState.paintComponent (graphics);
}
rootFolderData.progressPanel.repaint ();
}
}

View File

@ -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<JCheckBox> boxes = new ArrayList<JCheckBox> ();
private TableRowSorter<DiskTableModel> sorter;
private final CheckBoxActionListener checkBoxActionListener =
new CheckBoxActionListener ();
private final List<DiskTableSelectionListener> listeners;
public DuplicateWindow (File rootFolder,
List<DuplicateAction.DiskTableSelectionListener> 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<DiskTableModel> sorter =
new TableRowSorter<DiskTableModel> ((DiskTableModel) table.getModel ());
sorter = new TableRowSorter<DiskTableModel> ((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<DiskTableModel, Object> rf = null;
try
{
rf = RowFilter.regexFilter (getFilterText (), 2);
}
catch (java.util.regex.PatternSyntaxException exception)
{
return;
}
sorter.setRowFilter (rf);
}
}
}

View File

@ -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<Long, DiskDetails> checksumMap = new HashMap<Long, DiskDetails> ();
@ -13,8 +25,35 @@ public class RootFolderData
public final Map<String, DiskDetails> fileNameMap = new TreeMap<String, DiskDetails> ();
public final ProgressState progressState = new ProgressState ();
public final ProgressPanel progressPanel;
// public RootFolderData ()
// {
// }
public DuplicateWindow window;
public final List<DiskTableSelectionListener> listeners =
new ArrayList<DiskTableSelectionListener> ();
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);
}
}
}

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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<DiskTableSelectionListener> listeners =
new ArrayList<DiskTableSelectionListener> ();
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

View File

@ -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)
{