diff --git a/src/com/bytezone/diskbrowser/duplicates/CheckBoxActionListener.java b/src/com/bytezone/diskbrowser/duplicates/CheckBoxActionListener.java new file mode 100644 index 0000000..6d66b4e --- /dev/null +++ b/src/com/bytezone/diskbrowser/duplicates/CheckBoxActionListener.java @@ -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 disksSelected; + JButton deleteButton; + JButton clearButton; + + public CheckBoxActionListener (DiskDetails diskDetails, List 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); + } +} \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/duplicates/DuplicatePanel.java b/src/com/bytezone/diskbrowser/duplicates/DuplicatePanel.java new file mode 100644 index 0000000..4c5501f --- /dev/null +++ b/src/com/bytezone/diskbrowser/duplicates/DuplicatePanel.java @@ -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 checkBoxes = new ArrayList (); + List duplicateDisks; + + public DuplicatePanel (List duplicateDisks, int folderNameLength, + List 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 + } +} \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/duplicates/DuplicateWindow.java b/src/com/bytezone/diskbrowser/duplicates/DuplicateWindow.java new file mode 100644 index 0000000..4bbbf0c --- /dev/null +++ b/src/com/bytezone/diskbrowser/duplicates/DuplicateWindow.java @@ -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> 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 disksSelected = new ArrayList (); + List duplicatePanels = new ArrayList (); + + 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 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))); + } +} diff --git a/src/com/bytezone/diskbrowser/duplicates/DuplicateWorker.java b/src/com/bytezone/diskbrowser/duplicates/DuplicateWorker.java new file mode 100644 index 0000000..c151cd8 --- /dev/null +++ b/src/com/bytezone/diskbrowser/duplicates/DuplicateWorker.java @@ -0,0 +1,44 @@ +package com.bytezone.diskbrowser.duplicates; + +import java.util.List; + +import javax.swing.SwingWorker; + +public class DuplicateWorker extends SwingWorker, Void> +{ + List duplicateDisks; + DuplicateWindow owner; + + public DuplicateWorker (List 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 doInBackground () throws Exception + { + long firstChecksum = -1; + for (DiskDetails dd : duplicateDisks) + { + if (firstChecksum < 0) + firstChecksum = dd.getChecksum (); + else + dd.setDuplicate (dd.getChecksum () == firstChecksum); + } + return duplicateDisks; + } +} \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/gui/DuplicateAction.java b/src/com/bytezone/diskbrowser/gui/DuplicateAction.java index a8c298a..4ed8319 100644 --- a/src/com/bytezone/diskbrowser/gui/DuplicateAction.java +++ b/src/com/bytezone/diskbrowser/gui/DuplicateAction.java @@ -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 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 disksSelected = new ArrayList (); - List duplicatePanels = - new ArrayList (); - - 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 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 checkBoxes = new ArrayList (); - List duplicateDisks; - - public DuplicatePanel (List duplicateDisks, int folderNameLength, - List 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 disksSelected; - JButton deleteButton; - JButton clearButton; - - public CheckBoxActionListener (DiskDetails diskDetails, - List 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, Void> - { - List duplicateDisks; - DuplicateWindow owner; - - public DuplicateWorker (List 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 doInBackground () throws Exception - { - long firstChecksum = -1; - for (DiskDetails dd : duplicateDisks) - { - if (firstChecksum < 0) - firstChecksum = dd.getChecksum (); - else - dd.setDuplicate (dd.getChecksum () == firstChecksum); - } - return duplicateDisks; - } - } } \ No newline at end of file