1 /* ---------------------------------------------------------------------------------------------- */
2 /* MHash-384 - Language bindings for Java */
3 /* Copyright(c) 2016 LoRd_MuldeR <mulder2@gmx.de> */
5 /* Permission is hereby granted, free of charge, to any person obtaining a copy of this software */
6 /* and associated documentation files (the "Software"), to deal in the Software without */
7 /* restriction, including without limitation the rights to use, copy, modify, merge, publish, */
8 /* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the */
9 /* Software is furnished to do so, subject to the following conditions: */
11 /* The above copyright notice and this permission notice shall be included in all copies or */
12 /* substantial portions of the Software. */
14 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING */
15 /* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
16 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, */
17 /* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, */
18 /* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
20 package mhash.example;
22 import java.awt.BorderLayout;
23 import java.awt.Component;
24 import java.awt.Container;
25 import java.awt.FlowLayout;
26 import java.awt.GridLayout;
27 import java.awt.Insets;
28 import java.awt.event.ActionEvent;
29 import java.awt.event.ActionListener;
30 import java.awt.event.WindowEvent;
31 import java.awt.event.WindowListener;
32 import java.io.BufferedInputStream;
34 import java.io.FileInputStream;
35 import java.io.FileNotFoundException;
36 import java.io.IOException;
37 import java.util.List;
39 import javax.swing.JButton;
40 import javax.swing.JFileChooser;
41 import javax.swing.JFrame;
42 import javax.swing.JLabel;
43 import javax.swing.JOptionPane;
44 import javax.swing.JPanel;
45 import javax.swing.JProgressBar;
46 import javax.swing.JTextField;
47 import javax.swing.SwingWorker;
48 import javax.swing.border.EmptyBorder;
50 import mhash.MHash384;
52 public class ExampleApp extends JFrame {
54 private static final long serialVersionUID = -3576679013210278556L;
59 addWindowListener(new WindowListener() {
61 public void windowOpened(WindowEvent e) {
63 final MHash384.Version version = MHash384.getVersion();
64 setTitle(String.format("MHashJava384 - Example App v%d.%d.%d", version.major, version.minor, version.patch));
66 catch (UnsatisfiedLinkError err) {
67 err.printStackTrace();
68 JOptionPane.showMessageDialog(ExampleApp.this, "Failed to load native MHash384 library!\n\nDETAILS:\n" + err.getMessage(), err.getClass().getName(), JOptionPane.ERROR_MESSAGE);
71 catch (Throwable err) {
72 err.printStackTrace();
73 JOptionPane.showMessageDialog(ExampleApp.this, err.getMessage(), err.getClass().getName(), JOptionPane.ERROR_MESSAGE);
78 @Override public void windowClosing(WindowEvent e) {}
79 @Override public void windowClosed(WindowEvent e) {}
80 @Override public void windowIconified(WindowEvent e) {}
81 @Override public void windowDeiconified(WindowEvent e) {}
82 @Override public void windowActivated(WindowEvent e) {}
83 @Override public void windowDeactivated(WindowEvent e) {}
87 private void initUI() {
88 setDefaultCloseOperation(EXIT_ON_CLOSE);
89 setTitle("MHashJava384 - Example App [Launching]");
91 setMinimumSize(getSize());
92 setLocationRelativeTo(null);
94 final JTextField editFile = new JTextField();
95 final JTextField editHash = new JTextField();
96 editFile.setEditable(false);
97 editHash.setEditable(false);
99 final JProgressBar progressBar = new JProgressBar();
100 progressBar.setMinimum(0);
101 progressBar.setMaximum(100);
102 progressBar.setValue(0);
104 final JButton buttonBrowse = new JButton("Choose File");
105 buttonBrowse.addActionListener(new ActionListener() {
107 public void actionPerformed(ActionEvent e) {
108 browseForFile(editFile, editHash);
112 final JButton buttonExecute = new JButton("Compute Hash");
113 buttonExecute.addActionListener(new ActionListener() {
115 public void actionPerformed(ActionEvent e) {
116 computeHashAsync(editFile.getText().trim(), editHash, progressBar, new JButton[] { buttonBrowse, buttonExecute });
120 final JPanel body = new JPanel();
121 body.setLayout(new GridLayout(8, 1));
122 body.setBorder(new EmptyBorder(new Insets(12,12,12,12)));
123 body.add(new JLabel("Input File:"));
125 body.add(new JPanel());
126 body.add(new JLabel("File Digest:"));
128 body.add(new JPanel());
129 body.add(new JPanel());
130 body.add(progressBar);
132 final JPanel buttonBar = new JPanel();
133 buttonBar.setLayout(new FlowLayout(FlowLayout.RIGHT, 12, 12));
134 buttonBar.add(buttonBrowse);
135 buttonBar.add(buttonExecute);
137 final Container content = getContentPane();
138 content.setLayout(new BorderLayout());
139 content.add(body, BorderLayout.NORTH);
140 content.add(buttonBar, BorderLayout.SOUTH);
143 private void browseForFile(final JTextField editFile, final JTextField editHash) {
144 final JFileChooser chooser = new JFileChooser();
145 if(chooser.showOpenDialog(ExampleApp.this) == JFileChooser.APPROVE_OPTION) {
147 editFile.setText(chooser.getSelectedFile().getCanonicalPath());
148 editHash.setText("");
150 catch (Throwable err) {
151 err.printStackTrace();
152 JOptionPane.showMessageDialog(ExampleApp.this, err.getMessage(), err.getClass().getName(), JOptionPane.WARNING_MESSAGE);
157 private void computeHashAsync(final String path, final JTextField editHash, final JProgressBar progress, final JButton[] buttons) {
159 final File inputFile = new File(path);
160 if(!(inputFile.exists() && inputFile.isFile())) {
161 JOptionPane.showMessageDialog(ExampleApp.this, "Input file could not be found!", "Not Found", JOptionPane.WARNING_MESSAGE);
164 final HashWorker worker = createHashWorker(editHash, progress, buttons, inputFile);
165 for(final JButton button : buttons) {
166 button.setEnabled(false);
170 catch (Throwable err) {
171 err.printStackTrace();
172 JOptionPane.showMessageDialog(ExampleApp.this, err.getMessage(), err.getClass().getName(), JOptionPane.WARNING_MESSAGE);
176 private HashWorker createHashWorker(final JTextField editHash, final JProgressBar progress, final JButton[] buttons, final File inputFile) {
177 return new HashWorker(this, inputFile)
180 protected void done()
183 editHash.setText(this.get());
185 catch (Exception err) {
186 err.printStackTrace();
187 editHash.setText(err.getMessage());
190 for(final JButton button : buttons) {
191 button.setEnabled(true);
197 protected void process(List<Integer> chunks)
199 progress.setValue(maxValue(chunks));
204 private static class HashWorker extends SwingWorker<String, Integer> {
205 private final File inputFile;
206 private final Component parent;
208 public HashWorker(final Component parent, File inputFile) {
209 this.parent = parent;
210 this.inputFile = inputFile;
214 protected String doInBackground() throws FileNotFoundException, IOException {
216 final double totalSize = inputFile.length();
217 try(BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(inputFile))) {
218 try(final MHash384 digest = new MHash384()) {
220 final byte[] buffer = new byte[4096];
223 count = inputStream.read(buffer);
225 digest.update(buffer, 0, count);
227 publish((int)Math.round((((double)processed) / totalSize) * 100.0));
230 while(count == buffer.length);
231 return bytesToHex(digest.result());
235 catch(Throwable err) {
236 err.printStackTrace();
237 JOptionPane.showMessageDialog(parent, err.getMessage(), err.getClass().getName(), JOptionPane.WARNING_MESSAGE);
243 private static int maxValue(final List<Integer> chunks) {
244 int result = Integer.MIN_VALUE;
245 for(final Integer value : chunks) {
246 result = Math.max(result, value.intValue());
251 private static String bytesToHex(final byte[] bytes) {
252 final StringBuilder sb = new StringBuilder();
253 for (final byte b : bytes) {
254 sb.append(String.format("%02X", b));
256 return sb.toString();