Added a duplicates window

This commit is contained in:
Denis Molony 2016-12-17 07:45:08 +11:00
parent ee3496309b
commit f025c72d1e
6 changed files with 203 additions and 10 deletions

View File

@ -159,6 +159,8 @@ public class CPMDisk extends AbstractFormattedDisk
text.append (newLine);
}
text.append (line);
if (version != 0)
text.append ("Version: " + version);
return new DefaultAppleFileSource ("CPM Disk ", text.toString (), this);
}

View File

@ -0,0 +1,124 @@
package com.bytezone.diskbrowser.duplicates;
import java.awt.BorderLayout;
import java.awt.Color;
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 javax.swing.*;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableColumnModel;
import com.bytezone.diskbrowser.gui.DuplicateAction.DiskTableSelectionListener;
public class DeleteWindow extends JFrame implements DiskTableSelectionListener
{
private List<DiskDetails> lines = new ArrayList<DiskDetails> ();
private final JButton btnHide = new JButton ("Close");
private final RootFolderData rootFolderData;
private final DeleteTableModel deleteTableModel = new DeleteTableModel ();
private final JTable table = new JTable (deleteTableModel);
public DeleteWindow (RootFolderData rootFolderData)
{
super ("Duplicate Disks");
JScrollPane scrollPane =
new JScrollPane (table, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
table.setFillsViewportHeight (true);
table.setShowGrid (true);
table.setGridColor (Color.LIGHT_GRAY);
add (scrollPane, BorderLayout.CENTER);
JPanel panel = new JPanel ();
panel.add (btnHide);
add (panel, BorderLayout.SOUTH);
btnHide.addActionListener (new ActionListener ()
{
@Override
public void actionPerformed (ActionEvent e)
{
setVisible (false);
}
});
scrollPane.setPreferredSize (new Dimension (700, 400));
setDefaultCloseOperation (HIDE_ON_CLOSE);
this.rootFolderData = rootFolderData;
rootFolderData.listeners.add (this);
int[] columnWidths = { 400, 30, 70, 100 };
TableColumnModel tcm = table.getColumnModel ();
for (int i = 0; i < columnWidths.length; i++)
tcm.getColumn (i).setPreferredWidth (columnWidths[i]);
pack ();
setLocationRelativeTo (null);
}
@Override
public void diskSelected (DiskDetails diskDetails)
{
lines = rootFolderData.listDuplicates (diskDetails.getChecksum ());
deleteTableModel.fireTableDataChanged ();
}
class DeleteTableModel extends AbstractTableModel
{
final String[] headers = { "Name", "Type", "Size", "Checksum", };
@Override
public int getRowCount ()
{
return lines.size ();
}
@Override
public int getColumnCount ()
{
return headers.length;
}
@Override
public String getColumnName (int column)
{
return headers[column];
}
@Override
public Object getValueAt (int rowIndex, int columnIndex)
{
DiskDetails diskDetails = lines.get (rowIndex);
switch (columnIndex)
{
case 0:
return diskDetails.getRootName () + File.separator + diskDetails.getFileName ();
case 1:
return diskDetails.getType ();
case 2:
return diskDetails.getSize ();
case 3:
return diskDetails.getChecksum ();
default:
return "?";
}
}
@Override
public Class<?> getColumnClass (int columnIndex)
{
return lines.isEmpty () ? Object.class : getValueAt (0, columnIndex).getClass ();
}
}
}

View File

@ -5,6 +5,7 @@ import java.util.ArrayList;
import java.util.List;
import com.bytezone.common.ComputeCRC32;
import com.bytezone.diskbrowser.utilities.Utility;
public class DiskDetails
{
@ -12,6 +13,8 @@ public class DiskDetails
private long checksum;
private final String rootName; // full path without the root folder
private final String shortName; // file name in lower case
private final String type;
private final long size;
private final List<DiskDetails> duplicateChecksums = new ArrayList<DiskDetails> ();
private final List<DiskDetails> duplicateNames = new ArrayList<DiskDetails> ();
@ -24,6 +27,8 @@ public class DiskDetails
this.file = file;
this.rootName = rootName;
this.shortName = shortName;
this.type = Utility.getSuffix (shortName);
this.size = file.length ();
if (doChecksum)
checksum = ComputeCRC32.getChecksumValue (file);
@ -79,6 +84,16 @@ public class DiskDetails
return rootName;
}
public String getType ()
{
return type;
}
public long getSize ()
{
return size;
}
public String getShortName ()
{
return shortName;
@ -103,7 +118,7 @@ public class DiskDetails
@Override
public String toString ()
{
return String.format ("%-40s %3d %s %3d %s", rootName, duplicateChecksums.size (),
isDuplicateChecksum, duplicateNames.size (), isDuplicateName);
return String.format ("%3d %1.1s %3d %1.1s %-40s ", duplicateChecksums.size (),
isDuplicateChecksum, duplicateNames.size (), isDuplicateName, rootName);
}
}

View File

@ -5,8 +5,6 @@ import java.util.List;
import javax.swing.table.AbstractTableModel;
import com.bytezone.diskbrowser.utilities.Utility;
public class DiskTableModel extends AbstractTableModel
{
static final String[] headers =
@ -119,7 +117,8 @@ public class DiskTableModel extends AbstractTableModel
shortName = diskDetails.getShortName ();
fileName = diskDetails.getFileName ();
checksum = diskDetails.getChecksum ();
type = Utility.getSuffix (shortName);
// type = Utility.getSuffix (shortName);
type = diskDetails.getType ();
size = diskDetails.getFile ().length ();
String rootName = diskDetails.getRootName ();

View File

@ -7,6 +7,8 @@ import java.awt.FlowLayout;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
@ -26,6 +28,7 @@ public class DisksWindow extends JFrame
private final JTable table;
private final JButton btnExport = new JButton ("Export");
private final JButton btnDelete = new JButton ("Duplicates");
private final JButton btnHide = new JButton ("Close");
private final JButton btnTotals = new JButton ("Totals");
private final JPanel topPanel = new JPanel ();
@ -37,6 +40,7 @@ public class DisksWindow extends JFrame
private DiskTableModel diskTableModel;
private final RootFolderData rootFolderData;
private final DeleteWindow deleteWindow;
public DisksWindow (RootFolderData rootFolderData)
{
@ -59,6 +63,7 @@ public class DisksWindow extends JFrame
panel.add (btnTotals);
panel.add (btnHide);
panel.add (btnExport);
panel.add (btnDelete);
add (panel, BorderLayout.SOUTH);
topPanel.setLayout (new FlowLayout (FlowLayout.LEFT, 10, 5));
@ -85,6 +90,15 @@ public class DisksWindow extends JFrame
}
});
btnDelete.addActionListener (new ActionListener ()
{
@Override
public void actionPerformed (ActionEvent e)
{
deleteWindow.setVisible (true);
}
});
btnExport.addActionListener (new ActionListener ()
{
@Override
@ -96,6 +110,8 @@ public class DisksWindow extends JFrame
scrollPane.setPreferredSize (new Dimension (1200, 700));
setDefaultCloseOperation (HIDE_ON_CLOSE);
deleteWindow = new DeleteWindow (rootFolderData);
}
// called from DuplicateSwingWorker
@ -148,6 +164,16 @@ public class DisksWindow extends JFrame
}
});
table.addMouseListener (new MouseAdapter ()
{
@Override
public void mousePressed (MouseEvent mouseEvent)
{
if (mouseEvent.getClickCount () == 2)
deleteWindow.setVisible (true);
}
});
for (int i = 0; i < Utility.suffixes.size (); i++)
{
int total = rootFolderData.getTotalType (i);
@ -178,6 +204,7 @@ public class DisksWindow extends JFrame
private String getFilterText ()
{
StringBuilder filterText = new StringBuilder ();
for (JCheckBox box : boxes)
if (box.isSelected ())
{

View File

@ -11,7 +11,7 @@ import java.util.Map;
import java.util.TreeMap;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import com.bytezone.diskbrowser.gui.DuplicateAction.DiskTableSelectionListener;
@ -45,7 +45,7 @@ public class RootFolderData
// Progress dialog
ProgressPanel progressPanel;
public JDialog dialogTotals;
public JFrame dialogTotals;
JPanel southPanel;
JButton btnCancel;
JButton btnOK;
@ -57,13 +57,13 @@ public class RootFolderData
btnOK = new JButton ("OK");
progressPanel = new ProgressPanel ();
progressPanel.setPreferredSize (new Dimension (560, 300));
progressPanel.setPreferredSize (new Dimension (560, 340));
dialogTotals = new JDialog (disksWindow);
dialogTotals = new JFrame ("Disk Totals");
dialogTotals.add (progressPanel, BorderLayout.CENTER);
southPanel.add (btnCancel); // needs to be here for the pack()
dialogTotals.add (southPanel, BorderLayout.SOUTH);
dialogTotals.setTitle ("Disk Totals");
// dialogTotals.setTitle ("Disk Totals");
dialogTotals.pack ();
dialogTotals.setLocationRelativeTo (null);
@ -192,6 +192,20 @@ public class RootFolderData
}
}
public List<DiskDetails> listDuplicates (long checksum)
{
List<DiskDetails> list = new ArrayList<DiskDetails> ();
DiskDetails original = checksumMap.get (checksum);
if (original != null)
{
list.add (original);
for (DiskDetails dd : original.getDuplicateChecksums ())
list.add (dd);
}
return list;
}
public int getTotalType (int type)
{
return typeTotals[0][type] + typeTotals[1][type] + typeTotals[2][type];
@ -267,6 +281,18 @@ public class RootFolderData
grandTotal[1], grandTotal[2], grandTotal[3]);
y += 10;
g.drawString (line, x, y);
if (doChecksums)
{
// line = String.format ("Unique checksums: %,7d%n",
// checksumMap.size ());
// y += lineHeight;
// g.drawString (line, x, y);
line = String.format ("duplicates ... %,7d%n",
totalDisks - checksumMap.size ());
y += lineHeight + 10;
g.drawString (line, x, y);
}
}
}
}