new duplicates package

This commit is contained in:
Denis Molony 2016-12-07 21:56:25 +11:00
parent bd1cea9ab2
commit 499ed1cd20
5 changed files with 296 additions and 262 deletions

View File

@ -0,0 +1,36 @@
package com.bytezone.diskbrowser.duplicates;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JCheckBox;
class CheckBoxActionListener implements ActionListener
{
DiskDetails diskDetails;
List<DiskDetails> disksSelected;
JButton deleteButton;
JButton clearButton;
public CheckBoxActionListener (DiskDetails diskDetails, List<DiskDetails> disksSelected,
JButton deleteButton, JButton clearButton)
{
this.diskDetails = diskDetails;
this.disksSelected = disksSelected;
this.deleteButton = deleteButton;
this.clearButton = clearButton;
}
@Override
public void actionPerformed (ActionEvent e)
{
if (((JCheckBox) e.getSource ()).isSelected ())
disksSelected.add (diskDetails);
else
disksSelected.remove (diskDetails);
deleteButton.setEnabled (disksSelected.size () > 0);
clearButton.setEnabled (disksSelected.size () > 0);
}
}

View File

@ -0,0 +1,50 @@
package com.bytezone.diskbrowser.duplicates;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SpringLayout;
import com.bytezone.input.SpringUtilities;
public class DuplicatePanel extends JPanel
{
List<JCheckBox> checkBoxes = new ArrayList<JCheckBox> ();
List<DiskDetails> duplicateDisks;
public DuplicatePanel (List<DiskDetails> duplicateDisks, int folderNameLength,
List<DiskDetails> disksSelected, JButton deleteButton, JButton clearButton)
{
this.duplicateDisks = duplicateDisks;
setLayout (new SpringLayout ());
setAlignmentX (LEFT_ALIGNMENT);
int count = 0;
for (DiskDetails dd : duplicateDisks)
{
JCheckBox cb = new JCheckBox ();
checkBoxes.add (cb);
cb.addActionListener (
new CheckBoxActionListener (dd, disksSelected, deleteButton, clearButton));
add (cb);
if (++count == 1)
add (new JLabel ("Source disk"));
else
{
String text = dd.isDuplicate () ? "Duplicate" : "OK";
add (new JLabel (text));
}
String checksum = dd.isDuplicate () || count == 1 ? ""
: " (checksum = " + dd.getChecksum () + ")";
add (new JLabel (dd.getAbsolutePath ().substring (folderNameLength) + checksum));
}
SpringUtilities.makeCompactGrid (this, duplicateDisks.size (), 3, //rows, cols
10, 0, //initX, initY
10, 0); //xPad, yPad
}
}

View File

@ -0,0 +1,162 @@
package com.bytezone.diskbrowser.duplicates;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.swing.*;
public class DuplicateWindow extends JFrame
{
int unfinishedWorkers;
int folderNameLength;
Map<String, List<DiskDetails>> duplicateDisks;
File rootFolder;
JButton buttonDelete = new JButton ("Delete selected");
JButton buttonCancel = new JButton ("Cancel");
JButton buttonAll = new JButton ("Select all duplicates");
JButton buttonClear = new JButton ("Clear all");
JPanel mainPanel = new JPanel ();
List<DiskDetails> disksSelected = new ArrayList<DiskDetails> ();
List<DuplicatePanel> duplicatePanels = new ArrayList<DuplicatePanel> ();
public DuplicateWindow (File rootFolder)
{
super ("Duplicate Disk Detection - " + rootFolder.getAbsolutePath ());
unfinishedWorkers = duplicateDisks.size ();
folderNameLength = rootFolder.getAbsolutePath ().length ();
mainPanel.setLayout (new BoxLayout (mainPanel, BoxLayout.PAGE_AXIS));
JScrollPane sp =
new JScrollPane (mainPanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
sp.getVerticalScrollBar ().setUnitIncrement (100);
add (sp, BorderLayout.CENTER);
JPanel panel = new JPanel ();
panel.add (buttonClear);
panel.add (buttonAll);
panel.add (buttonDelete);
panel.add (buttonCancel);
add (panel, BorderLayout.SOUTH);
buttonClear.setEnabled (false);
buttonAll.setEnabled (false);
buttonDelete.setEnabled (false);
buttonCancel.setEnabled (false);
buttonAll.addActionListener (new ActionListener ()
{
@Override
public void actionPerformed (ActionEvent e)
{
for (DuplicatePanel dp : duplicatePanels)
{
int count = 0;
for (JCheckBox cb : dp.checkBoxes)
{
if (count > 0 && dp.duplicateDisks.get (count).isDuplicate ())
if (!cb.isSelected ())
{
cb.setSelected (true); // doesn't fire the actionListener!
disksSelected.add (dp.duplicateDisks.get (count));
}
++count;
}
}
buttonDelete.setEnabled (disksSelected.size () > 0);
buttonClear.setEnabled (disksSelected.size () > 0);
}
});
buttonClear.addActionListener (new ActionListener ()
{
@Override
public void actionPerformed (ActionEvent e)
{
for (DuplicatePanel dp : duplicatePanels)
for (JCheckBox cb : dp.checkBoxes)
cb.setSelected (false); // doesn't fire the actionListener!
disksSelected.clear ();
buttonDelete.setEnabled (false);
buttonClear.setEnabled (false);
}
});
buttonCancel.addActionListener (new ActionListener ()
{
@Override
public void actionPerformed (ActionEvent e)
{
DuplicateWindow.this.setVisible (false);
}
});
buttonDelete.addActionListener (new ActionListener ()
{
@Override
public void actionPerformed (ActionEvent e)
{
int totalDeleted = 0;
int totalFailed = 0;
for (DuplicatePanel dp : duplicatePanels)
{
int count = 0;
for (JCheckBox cb : dp.checkBoxes)
{
if (cb.isSelected () && false)
{
DiskDetails dd = dp.duplicateDisks.get (count);
if (dd.delete ())
{
++totalDeleted;
System.out.println ("Deleted : " + dd);
}
else
{
++totalFailed;
System.out.println ("Failed : " + dd);
}
}
++count;
}
}
System.out.printf ("Deleted : %d, Failed : %d%n", totalDeleted, totalFailed);
}
});
setSize (600, 700);
setLocationRelativeTo (null);
setDefaultCloseOperation (HIDE_ON_CLOSE);
setVisible (true);
}
// create a DuplicatePanel based on the updated DiskDetails
public synchronized void addResult (List<DiskDetails> duplicateDisks)
{
// create panel and add it to the window
DuplicatePanel dp = new DuplicatePanel (duplicateDisks, folderNameLength,
disksSelected, buttonDelete, buttonClear);
mainPanel.add (dp);
duplicatePanels.add (dp);
validate ();
if (--unfinishedWorkers == 0)
{
buttonAll.setEnabled (true);
buttonCancel.setEnabled (true);
}
else
mainPanel.add (Box.createRigidArea (new Dimension (0, 20)));
}
}

View File

@ -0,0 +1,44 @@
package com.bytezone.diskbrowser.duplicates;
import java.util.List;
import javax.swing.SwingWorker;
public class DuplicateWorker extends SwingWorker<List<DiskDetails>, Void>
{
List<DiskDetails> duplicateDisks;
DuplicateWindow owner;
public DuplicateWorker (List<DiskDetails> duplicateDisks, DuplicateWindow owner)
{
this.duplicateDisks = duplicateDisks;
this.owner = owner;
}
@Override
protected void done ()
{
try
{
owner.addResult (get ());
}
catch (Exception e)
{
e.printStackTrace ();
}
}
@Override
protected List<DiskDetails> doInBackground () throws Exception
{
long firstChecksum = -1;
for (DiskDetails dd : duplicateDisks)
{
if (firstChecksum < 0)
firstChecksum = dd.getChecksum ();
else
dd.setDuplicate (dd.getChecksum () == firstChecksum);
}
return duplicateDisks;
}
}

View File

@ -1,23 +1,17 @@
package com.bytezone.diskbrowser.gui;
import static javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER;
import static javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.swing.*;
import javax.swing.Action;
import com.bytezone.common.DefaultAction;
import com.bytezone.diskbrowser.duplicates.DiskDetails;
import com.bytezone.diskbrowser.duplicates.DuplicateWindow;
import com.bytezone.diskbrowser.duplicates.DuplicateWorker;
import com.bytezone.diskbrowser.gui.RootDirectoryAction.RootDirectoryListener;
import com.bytezone.input.SpringUtilities;
public class DuplicateAction extends DefaultAction implements RootDirectoryListener
{
@ -64,260 +58,8 @@ public class DuplicateAction extends DefaultAction implements RootDirectoryListe
window.setVisible (true);
return;
}
window = new DuplicateWindow ();
window = new DuplicateWindow (rootFolder);
for (List<DiskDetails> diskList : duplicateDisks.values ())
new DuplicateWorker (diskList, window).execute ();
}
class DuplicateWindow extends JFrame
{
int unfinishedWorkers;
int folderNameLength;
JButton buttonDelete = new JButton ("Delete selected");
JButton buttonCancel = new JButton ("Cancel");
JButton buttonAll = new JButton ("Select all duplicates");
JButton buttonClear = new JButton ("Clear all");
JPanel mainPanel = new JPanel ();
List<DiskDetails> disksSelected = new ArrayList<DiskDetails> ();
List<DuplicatePanel> duplicatePanels =
new ArrayList<DuplicateAction.DuplicatePanel> ();
public DuplicateWindow ()
{
super ("Duplicate Disk Detection - " + rootFolder.getAbsolutePath ());
unfinishedWorkers = duplicateDisks.size ();
folderNameLength = rootFolder.getAbsolutePath ().length ();
mainPanel.setLayout (new BoxLayout (mainPanel, BoxLayout.PAGE_AXIS));
JScrollPane sp = new JScrollPane (mainPanel, VERTICAL_SCROLLBAR_ALWAYS,
HORIZONTAL_SCROLLBAR_NEVER);
sp.getVerticalScrollBar ().setUnitIncrement (100);
add (sp, BorderLayout.CENTER);
JPanel panel = new JPanel ();
panel.add (buttonClear);
panel.add (buttonAll);
panel.add (buttonDelete);
panel.add (buttonCancel);
add (panel, BorderLayout.SOUTH);
buttonClear.setEnabled (false);
buttonAll.setEnabled (false);
buttonDelete.setEnabled (false);
buttonCancel.setEnabled (false);
buttonAll.addActionListener (new ActionListener ()
{
@Override
public void actionPerformed (ActionEvent e)
{
for (DuplicatePanel dp : duplicatePanels)
{
int count = 0;
for (JCheckBox cb : dp.checkBoxes)
{
if (count > 0 && dp.duplicateDisks.get (count).isDuplicate ())
if (!cb.isSelected ())
{
cb.setSelected (true); // doesn't fire the actionListener!
disksSelected.add (dp.duplicateDisks.get (count));
}
++count;
}
}
buttonDelete.setEnabled (disksSelected.size () > 0);
buttonClear.setEnabled (disksSelected.size () > 0);
}
});
buttonClear.addActionListener (new ActionListener ()
{
@Override
public void actionPerformed (ActionEvent e)
{
for (DuplicatePanel dp : duplicatePanels)
for (JCheckBox cb : dp.checkBoxes)
cb.setSelected (false); // doesn't fire the actionListener!
disksSelected.clear ();
buttonDelete.setEnabled (false);
buttonClear.setEnabled (false);
}
});
buttonCancel.addActionListener (new ActionListener ()
{
@Override
public void actionPerformed (ActionEvent e)
{
DuplicateWindow.this.setVisible (false);
}
});
buttonDelete.addActionListener (new ActionListener ()
{
@Override
public void actionPerformed (ActionEvent e)
{
int totalDeleted = 0;
int totalFailed = 0;
for (DuplicatePanel dp : duplicatePanels)
{
int count = 0;
for (JCheckBox cb : dp.checkBoxes)
{
if (cb.isSelected () && false)
{
DiskDetails dd = dp.duplicateDisks.get (count);
if (dd.delete ())
{
++totalDeleted;
System.out.println ("Deleted : " + dd);
}
else
{
++totalFailed;
System.out.println ("Failed : " + dd);
}
}
++count;
}
}
System.out.printf ("Deleted : %d, Failed : %d%n", totalDeleted, totalFailed);
}
});
setSize (600, 700);
setLocationRelativeTo (null);
setDefaultCloseOperation (HIDE_ON_CLOSE);
setVisible (true);
}
// create a DuplicatePanel based on the updated DiskDetails
public synchronized void addResult (List<DiskDetails> duplicateDisks)
{
// create panel and add it to the window
DuplicatePanel dp = new DuplicatePanel (duplicateDisks, folderNameLength,
disksSelected, buttonDelete, buttonClear);
mainPanel.add (dp);
duplicatePanels.add (dp);
validate ();
if (--unfinishedWorkers == 0)
{
buttonAll.setEnabled (true);
buttonCancel.setEnabled (true);
}
else
mainPanel.add (Box.createRigidArea (new Dimension (0, 20)));
}
}
class DuplicatePanel extends JPanel
{
List<JCheckBox> checkBoxes = new ArrayList<JCheckBox> ();
List<DiskDetails> duplicateDisks;
public DuplicatePanel (List<DiskDetails> duplicateDisks, int folderNameLength,
List<DiskDetails> disksSelected, JButton deleteButton, JButton clearButton)
{
this.duplicateDisks = duplicateDisks;
setLayout (new SpringLayout ());
setAlignmentX (LEFT_ALIGNMENT);
int count = 0;
for (DiskDetails dd : duplicateDisks)
{
JCheckBox cb = new JCheckBox ();
checkBoxes.add (cb);
cb.addActionListener (
new CheckBoxActionListener (dd, disksSelected, deleteButton, clearButton));
add (cb);
if (++count == 1)
add (new JLabel ("Source disk"));
else
{
String text = dd.isDuplicate () ? "Duplicate" : "OK";
add (new JLabel (text));
}
String checksum = dd.isDuplicate () || count == 1 ? ""
: " (checksum = " + dd.getChecksum () + ")";
add (new JLabel (dd.getAbsolutePath ().substring (folderNameLength) + checksum));
}
SpringUtilities.makeCompactGrid (this, duplicateDisks.size (), 3, //rows, cols
10, 0, //initX, initY
10, 0); //xPad, yPad
}
}
class CheckBoxActionListener implements ActionListener
{
DiskDetails diskDetails;
List<DiskDetails> disksSelected;
JButton deleteButton;
JButton clearButton;
public CheckBoxActionListener (DiskDetails diskDetails,
List<DiskDetails> disksSelected, JButton deleteButton, JButton clearButton)
{
this.diskDetails = diskDetails;
this.disksSelected = disksSelected;
this.deleteButton = deleteButton;
this.clearButton = clearButton;
}
@Override
public void actionPerformed (ActionEvent e)
{
if (((JCheckBox) e.getSource ()).isSelected ())
disksSelected.add (diskDetails);
else
disksSelected.remove (diskDetails);
deleteButton.setEnabled (disksSelected.size () > 0);
clearButton.setEnabled (disksSelected.size () > 0);
}
}
class DuplicateWorker extends SwingWorker<List<DiskDetails>, Void>
{
List<DiskDetails> duplicateDisks;
DuplicateWindow owner;
public DuplicateWorker (List<DiskDetails> duplicateDisks, DuplicateWindow owner)
{
this.duplicateDisks = duplicateDisks;
this.owner = owner;
}
@Override
protected void done ()
{
try
{
owner.addResult (get ());
}
catch (Exception e)
{
e.printStackTrace ();
}
}
@Override
protected List<DiskDetails> doInBackground () throws Exception
{
long firstChecksum = -1;
for (DiskDetails dd : duplicateDisks)
{
if (firstChecksum < 0)
firstChecksum = dd.getChecksum ();
else
dd.setDuplicate (dd.getChecksum () == firstChecksum);
}
return duplicateDisks;
}
}
}