Skip to content

Instantly share code, notes, and snippets.

@inaz2
Last active December 4, 2016 03:08
Show Gist options
  • Save inaz2/5f21d9df25e89f5da75496f07a9bcb7b to your computer and use it in GitHub Desktop.
Save inaz2/5f21d9df25e89f5da75496f07a9bcb7b to your computer and use it in GitHub Desktop.
SHA-1 Calculator (Java+Swing)
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingWorker;
import javax.swing.TransferHandler;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableModel;
public class SHA1Calculator extends JFrame {
private JPanel contentPane;
private DefaultTableModel model;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
SHA1Calculator frame = new SHA1Calculator();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public SHA1Calculator() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 600, 300); // expanded default frame size
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);
setTitle("SHA-1 Calculator");
// create scrollable JTable
model = new DefaultTableModel(new String[]{"File Path", "sha1sum"}, 0);
JTable table = new JTable(model);
JScrollPane scrollPane = new JScrollPane(table);
contentPane.add(scrollPane);
// enable file drop
contentPane.setTransferHandler(new DropFileHandler());
}
private class DropFileHandler extends TransferHandler {
@Override
public boolean canImport(TransferSupport support) {
// Check if dropped data is files
return (support.isDrop()
&& support.isDataFlavorSupported(DataFlavor.javaFileListFlavor));
}
@Override
@SuppressWarnings("unchecked")
public boolean importData(TransferSupport support) {
if (!canImport(support)) {
return false;
}
Transferable t = support.getTransferable();
List<File> files = null;
try {
files = (List<File>) t.getTransferData(DataFlavor.javaFileListFlavor);
} catch (UnsupportedFlavorException | IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
for (File file : files) {
String path = file.getAbsolutePath();
model.addRow(new String[]{path, "calculating..."});
ModelUpdater mu = new ModelUpdater(path, model.getRowCount()-1);
mu.execute();
}
return true;
}
}
private class ModelUpdater extends SwingWorker<String, Long> {
private String path;
private Integer rowindex;
public ModelUpdater(String path, Integer rowindex) {
this.path = path;
this.rowindex = rowindex;
}
@Override
public String doInBackground() throws IOException {
MessageDigest md = null;
try {
md = MessageDigest.getInstance("SHA-1");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// update digest with each 8MB chunk
long totalBytes = (new File(path)).length();
long currentBytes = 0;
try (FileInputStream istream = new FileInputStream(path)) {
byte[] buf = new byte[8*1024*1024];
int n;
while ((n = istream.read(buf, 0, buf.length)) != -1) {
md.update(Arrays.copyOf(buf, n));
currentBytes += n;
publish(100*currentBytes/totalBytes);
}
} catch (IOException e) {
e.printStackTrace();
}
byte[] digest = md.digest();
StringBuilder sb = new StringBuilder();
for (byte b : digest) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
@Override
protected void process(List<Long> values) {
// only last one is effective
String message = String.format("calculating %d%%...", values.get(values.size()-1));
model.setValueAt(message, rowindex, 1);
}
@Override
protected void done() {
try {
model.setValueAt(get(), rowindex, 1);
} catch (Exception ignore) {
}
}
}
}
@ykubota
Copy link

ykubota commented Apr 26, 2016

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.List;

public class SHA1Calculator extends JFrame {

    private DefaultTableModel model;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            try {
                SHA1Calculator frame = new SHA1Calculator();
                frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    /**
     * Create the frame.
     */
    public SHA1Calculator() {
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setBounds(100, 100, 600, 300);  // expanded default frame size
        JPanel contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);

        setTitle("SHA-1 Calculator");

        // create scrollable JTable
        model = new DefaultTableModel(new String[]{"File Path", "sha1sum"}, 0);
        JTable table = new JTable(model);
        JScrollPane scrollPane = new JScrollPane(table);
        contentPane.add(scrollPane);

        // enable file drop
        contentPane.setTransferHandler(new DropFileHandler());
    }

    private class DropFileHandler extends TransferHandler {
        @Override
        public boolean canImport(TransferSupport support) {
            // Check if dropped data is files
            return (support.isDrop()
                    && support.isDataFlavorSupported(DataFlavor.javaFileListFlavor));
        }

        @Override
        @SuppressWarnings("unchecked")
        public boolean importData(TransferSupport support) {
            if (!canImport(support)) {
                return false;
            }

            Transferable t = support.getTransferable();
            List<File> files = null;
            try {
                files = (List<File>) t.getTransferData(DataFlavor.javaFileListFlavor);
            } catch (UnsupportedFlavorException | IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }

            for (File file : files) {
                String path = file.getAbsolutePath();
                model.addRow(new String[]{path, "calculating..."});
                ModelUpdater mu = new ModelUpdater(path, model.getRowCount() - 1);
                mu.execute();
            }

            return true;
        }
    }

    private class ModelUpdater extends SwingWorker<String, Long> {
        private String path;
        private Integer rowindex;

        public ModelUpdater(String path, Integer rowindex) {
            this.path = path;
            this.rowindex = rowindex;
        }

        @Override
        public String doInBackground() throws IOException {
            MessageDigest md = null;
            try {
                md = MessageDigest.getInstance("SHA-1");
            } catch (NoSuchAlgorithmException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            // update digest with each 8MB chunk
            // read(buf) は Lambda の Stream 処理には不向き
            try ( FileInputStream istream = new FileInputStream(path); ) {
                long totalBytes = (new File(path)).length();
                long currentBytes = 0;

                byte[] buf = new byte[8 * 1024 * 1024];
                int n;
                while ((n = istream.read(buf, 0, buf.length)) != -1) {
                    md.update(Arrays.copyOf(buf, n));
                    currentBytes += n;
                    publish(100 * currentBytes / totalBytes);
                }
            } catch (IOException ignore) {
            }

            byte[] digest = md.digest();
            // マルチスレッドじゃないならStringBuilderの方が早い
            StringBuffer sb = new StringBuffer();
            for (byte b : digest) {
                sb.append(String.format("%02x", b));
            }
            return sb.toString();
        }

        @Override
        protected void process(List<Long> values) {
            // only last one is effective
            String message = String.format("calculating %d%%...", values.get(values.size() - 1));
            model.setValueAt(message, rowindex, 1);
        }

        @Override
        protected void done() {
            try {
                model.setValueAt(get(), rowindex, 1);
            } catch (Exception ignore) {
            }
        }
    }

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment