summaryrefslogtreecommitdiff
path: root/src/main/java/cuchaz/enigma/gui/dialog
diff options
context:
space:
mode:
authorGravatar Runemoro2020-06-03 13:39:42 -0400
committerGravatar GitHub2020-06-03 18:39:42 +0100
commit0f47403d0220757fed189b76e2071e25b1025cb8 (patch)
tree879bf72c4476f0a5e0d82da99d7ff2b2276bcaca /src/main/java/cuchaz/enigma/gui/dialog
parentFix search dialog hanging for a short time sometimes (#250) (diff)
downloadenigma-fork-0f47403d0220757fed189b76e2071e25b1025cb8.tar.gz
enigma-fork-0f47403d0220757fed189b76e2071e25b1025cb8.tar.xz
enigma-fork-0f47403d0220757fed189b76e2071e25b1025cb8.zip
Split GUI code to separate module (#242)
* Split into modules * Post merge compile fixes Co-authored-by: modmuss50 <modmuss50@gmail.com>
Diffstat (limited to 'src/main/java/cuchaz/enigma/gui/dialog')
-rw-r--r--src/main/java/cuchaz/enigma/gui/dialog/AboutDialog.java69
-rw-r--r--src/main/java/cuchaz/enigma/gui/dialog/ChangeDialog.java50
-rw-r--r--src/main/java/cuchaz/enigma/gui/dialog/ConnectToServerDialog.java82
-rw-r--r--src/main/java/cuchaz/enigma/gui/dialog/CrashDialog.java105
-rw-r--r--src/main/java/cuchaz/enigma/gui/dialog/CreateServerDialog.java65
-rw-r--r--src/main/java/cuchaz/enigma/gui/dialog/JavadocDialog.java159
-rw-r--r--src/main/java/cuchaz/enigma/gui/dialog/ProgressDialog.java109
-rw-r--r--src/main/java/cuchaz/enigma/gui/dialog/SearchDialog.java261
-rw-r--r--src/main/java/cuchaz/enigma/gui/dialog/StatsDialog.java82
9 files changed, 0 insertions, 982 deletions
diff --git a/src/main/java/cuchaz/enigma/gui/dialog/AboutDialog.java b/src/main/java/cuchaz/enigma/gui/dialog/AboutDialog.java
deleted file mode 100644
index 43b8265..0000000
--- a/src/main/java/cuchaz/enigma/gui/dialog/AboutDialog.java
+++ /dev/null
@@ -1,69 +0,0 @@
1/*******************************************************************************
2 * Copyright (c) 2015 Jeff Martin.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the GNU Lesser General Public
5 * License v3.0 which accompanies this distribution, and is available at
6 * http://www.gnu.org/licenses/lgpl.html
7 * <p>
8 * Contributors:
9 * Jeff Martin - initial API and implementation
10 ******************************************************************************/
11
12package cuchaz.enigma.gui.dialog;
13
14import cuchaz.enigma.Constants;
15import cuchaz.enigma.utils.I18n;
16import cuchaz.enigma.gui.util.ScaleUtil;
17import cuchaz.enigma.utils.Utils;
18
19import javax.swing.*;
20import java.awt.*;
21import java.io.IOException;
22
23public class AboutDialog {
24
25 public static void show(JFrame parent) {
26 // init frame
27 final JFrame frame = new JFrame(String.format(I18n.translate("menu.help.about.title"), Constants.NAME));
28 final Container pane = frame.getContentPane();
29 pane.setLayout(new FlowLayout());
30
31 // load the content
32 try {
33 String html = Utils.readResourceToString("/about.html");
34 html = String.format(html, Constants.NAME, Constants.VERSION);
35 JLabel label = new JLabel(html);
36 label.setHorizontalAlignment(JLabel.CENTER);
37 pane.add(label);
38 } catch (IOException ex) {
39 throw new Error(ex);
40 }
41
42 // show the link
43 String html = "<html><a href=\"%s\">%s</a></html>";
44 html = String.format(html, Constants.URL, Constants.URL);
45 JButton link = new JButton(html);
46 link.addActionListener(event -> Utils.openUrl(Constants.URL));
47 link.setBorderPainted(false);
48 link.setOpaque(false);
49 link.setBackground(Color.WHITE);
50 link.setCursor(new Cursor(Cursor.HAND_CURSOR));
51 link.setFocusable(false);
52 JPanel linkPanel = new JPanel();
53 linkPanel.add(link);
54 pane.add(linkPanel);
55
56 // show ok button
57 JButton okButton = new JButton(I18n.translate("menu.help.about.ok"));
58 pane.add(okButton);
59 okButton.addActionListener(arg0 -> frame.dispose());
60
61 // show the frame
62 pane.doLayout();
63 frame.setSize(ScaleUtil.getDimension(400, 220));
64 frame.setResizable(false);
65 frame.setLocationRelativeTo(parent);
66 frame.setVisible(true);
67 frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
68 }
69}
diff --git a/src/main/java/cuchaz/enigma/gui/dialog/ChangeDialog.java b/src/main/java/cuchaz/enigma/gui/dialog/ChangeDialog.java
deleted file mode 100644
index 64219ab..0000000
--- a/src/main/java/cuchaz/enigma/gui/dialog/ChangeDialog.java
+++ /dev/null
@@ -1,50 +0,0 @@
1package cuchaz.enigma.gui.dialog;
2
3import java.awt.BorderLayout;
4import java.awt.event.KeyAdapter;
5import java.awt.event.KeyEvent;
6
7import javax.swing.JButton;
8import javax.swing.JFrame;
9import javax.swing.JLabel;
10import javax.swing.JPanel;
11
12import cuchaz.enigma.gui.Gui;
13import cuchaz.enigma.utils.I18n;
14
15public class ChangeDialog {
16
17 public static void show(Gui gui) {
18 // init frame
19 JFrame frame = new JFrame(I18n.translate("menu.view.change.title"));
20 JPanel textPanel = new JPanel();
21 JPanel buttonPanel = new JPanel();
22 frame.setLayout(new BorderLayout());
23 frame.add(BorderLayout.NORTH, textPanel);
24 frame.add(BorderLayout.SOUTH, buttonPanel);
25
26 // show text
27 JLabel text = new JLabel((I18n.translate("menu.view.change.summary")));
28 text.setHorizontalAlignment(JLabel.CENTER);
29 textPanel.add(text);
30
31 // show ok button
32 JButton okButton = new JButton(I18n.translate("menu.view.change.ok"));
33 buttonPanel.add(okButton);
34 okButton.addActionListener(event -> frame.dispose());
35 okButton.addKeyListener(new KeyAdapter() {
36 @Override
37 public void keyPressed(KeyEvent e) {
38 if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
39 frame.dispose();
40 }
41 }
42 });
43
44 // show the frame
45 frame.pack();
46 frame.setVisible(true);
47 frame.setResizable(false);
48 frame.setLocationRelativeTo(gui.getFrame());
49 }
50}
diff --git a/src/main/java/cuchaz/enigma/gui/dialog/ConnectToServerDialog.java b/src/main/java/cuchaz/enigma/gui/dialog/ConnectToServerDialog.java
deleted file mode 100644
index c5f505c..0000000
--- a/src/main/java/cuchaz/enigma/gui/dialog/ConnectToServerDialog.java
+++ /dev/null
@@ -1,82 +0,0 @@
1package cuchaz.enigma.gui.dialog;
2
3import cuchaz.enigma.network.EnigmaServer;
4import cuchaz.enigma.utils.I18n;
5
6import javax.swing.*;
7import java.awt.Frame;
8
9public class ConnectToServerDialog {
10
11 public static Result show(Frame parentComponent) {
12 JTextField usernameField = new JTextField(System.getProperty("user.name"), 20);
13 JPanel usernameRow = new JPanel();
14 usernameRow.add(new JLabel(I18n.translate("prompt.connect.username")));
15 usernameRow.add(usernameField);
16 JTextField ipField = new JTextField(20);
17 JPanel ipRow = new JPanel();
18 ipRow.add(new JLabel(I18n.translate("prompt.connect.ip")));
19 ipRow.add(ipField);
20 JTextField portField = new JTextField(String.valueOf(EnigmaServer.DEFAULT_PORT), 10);
21 JPanel portRow = new JPanel();
22 portRow.add(new JLabel(I18n.translate("prompt.port")));
23 portRow.add(portField);
24 JPasswordField passwordField = new JPasswordField(20);
25 JPanel passwordRow = new JPanel();
26 passwordRow.add(new JLabel(I18n.translate("prompt.password")));
27 passwordRow.add(passwordField);
28
29 int response = JOptionPane.showConfirmDialog(parentComponent, new Object[]{usernameRow, ipRow, portRow, passwordRow}, I18n.translate("prompt.connect.title"), JOptionPane.OK_CANCEL_OPTION);
30 if (response != JOptionPane.OK_OPTION) {
31 return null;
32 }
33
34 String username = usernameField.getText();
35 String ip = ipField.getText();
36 int port;
37 try {
38 port = Integer.parseInt(portField.getText());
39 } catch (NumberFormatException e) {
40 JOptionPane.showMessageDialog(parentComponent, I18n.translate("prompt.port.nan"), I18n.translate("prompt.connect.title"), JOptionPane.ERROR_MESSAGE);
41 return null;
42 }
43 if (port < 0 || port >= 65536) {
44 JOptionPane.showMessageDialog(parentComponent, I18n.translate("prompt.port.invalid"), I18n.translate("prompt.connect.title"), JOptionPane.ERROR_MESSAGE);
45 return null;
46 }
47 char[] password = passwordField.getPassword();
48
49 return new Result(username, ip, port, password);
50 }
51
52 public static class Result {
53 private final String username;
54 private final String ip;
55 private final int port;
56 private final char[] password;
57
58 public Result(String username, String ip, int port, char[] password) {
59 this.username = username;
60 this.ip = ip;
61 this.port = port;
62 this.password = password;
63 }
64
65 public String getUsername() {
66 return username;
67 }
68
69 public String getIp() {
70 return ip;
71 }
72
73 public int getPort() {
74 return port;
75 }
76
77 public char[] getPassword() {
78 return password;
79 }
80 }
81
82}
diff --git a/src/main/java/cuchaz/enigma/gui/dialog/CrashDialog.java b/src/main/java/cuchaz/enigma/gui/dialog/CrashDialog.java
deleted file mode 100644
index 908b42e..0000000
--- a/src/main/java/cuchaz/enigma/gui/dialog/CrashDialog.java
+++ /dev/null
@@ -1,105 +0,0 @@
1/*******************************************************************************
2 * Copyright (c) 2015 Jeff Martin.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the GNU Lesser General Public
5 * License v3.0 which accompanies this distribution, and is available at
6 * http://www.gnu.org/licenses/lgpl.html
7 * <p>
8 * Contributors:
9 * Jeff Martin - initial API and implementation
10 ******************************************************************************/
11
12package cuchaz.enigma.gui.dialog;
13
14import cuchaz.enigma.Constants;
15import cuchaz.enigma.utils.I18n;
16import cuchaz.enigma.gui.util.ScaleUtil;
17import cuchaz.enigma.utils.Utils;
18
19import javax.swing.*;
20import java.awt.*;
21import java.io.PrintWriter;
22import java.io.StringWriter;
23import java.io.FileWriter;
24import java.io.File;
25import java.io.IOException;
26
27public class CrashDialog {
28
29 private static CrashDialog instance = null;
30
31 private JFrame frame;
32 private JTextArea text;
33
34 private CrashDialog(JFrame parent) {
35 // init frame
36 frame = new JFrame(String.format(I18n.translate("crash.title"), Constants.NAME));
37 final Container pane = frame.getContentPane();
38 pane.setLayout(new BorderLayout());
39
40 JLabel label = new JLabel(String.format(I18n.translate("crash.summary"), Constants.NAME));
41 label.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
42 pane.add(label, BorderLayout.NORTH);
43
44 // report panel
45 text = new JTextArea();
46 text.setTabSize(2);
47 pane.add(new JScrollPane(text), BorderLayout.CENTER);
48
49 // buttons panel
50 JPanel buttonsPanel = new JPanel();
51 buttonsPanel.setLayout(new BoxLayout(buttonsPanel, BoxLayout.LINE_AXIS));
52 JButton exportButton = new JButton(I18n.translate("crash.export"));
53 exportButton.addActionListener(event -> {
54 JFileChooser chooser = new JFileChooser();
55 chooser.setSelectedFile(new File("enigma_crash.log"));
56 if (chooser.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) {
57 try {
58 File file = chooser.getSelectedFile();
59 FileWriter writer = new FileWriter(file);
60 writer.write(instance.text.getText());
61 writer.close();
62 } catch (IOException ex) {
63 ex.printStackTrace();
64 }
65 }
66 });
67 buttonsPanel.add(exportButton);
68 buttonsPanel.add(Box.createHorizontalGlue());
69 buttonsPanel.add(Utils.unboldLabel(new JLabel(I18n.translate("crash.exit.warning"))));
70 JButton ignoreButton = new JButton(I18n.translate("crash.ignore"));
71 ignoreButton.addActionListener(event -> {
72 // close (hide) the dialog
73 frame.setVisible(false);
74 });
75 buttonsPanel.add(ignoreButton);
76 JButton exitButton = new JButton(I18n.translate("crash.exit"));
77 exitButton.addActionListener(event -> {
78 // exit enigma
79 System.exit(1);
80 });
81 buttonsPanel.add(exitButton);
82 pane.add(buttonsPanel, BorderLayout.SOUTH);
83
84 // show the frame
85 frame.setSize(ScaleUtil.getDimension(600, 400));
86 frame.setLocationRelativeTo(parent);
87 frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
88 }
89
90 public static void init(JFrame parent) {
91 instance = new CrashDialog(parent);
92 }
93
94 public static void show(Throwable ex) {
95 // get the error report
96 StringWriter buf = new StringWriter();
97 ex.printStackTrace(new PrintWriter(buf));
98 String report = buf.toString();
99
100 // show it!
101 instance.text.setText(report);
102 instance.frame.doLayout();
103 instance.frame.setVisible(true);
104 }
105}
diff --git a/src/main/java/cuchaz/enigma/gui/dialog/CreateServerDialog.java b/src/main/java/cuchaz/enigma/gui/dialog/CreateServerDialog.java
deleted file mode 100644
index eea1dff..0000000
--- a/src/main/java/cuchaz/enigma/gui/dialog/CreateServerDialog.java
+++ /dev/null
@@ -1,65 +0,0 @@
1package cuchaz.enigma.gui.dialog;
2
3import cuchaz.enigma.network.EnigmaServer;
4import cuchaz.enigma.utils.I18n;
5
6import javax.swing.*;
7import java.awt.*;
8
9public class CreateServerDialog {
10
11 public static Result show(Frame parentComponent) {
12 JTextField portField = new JTextField(String.valueOf(EnigmaServer.DEFAULT_PORT), 10);
13 JPanel portRow = new JPanel();
14 portRow.add(new JLabel(I18n.translate("prompt.port")));
15 portRow.add(portField);
16 JPasswordField passwordField = new JPasswordField(20);
17 JPanel passwordRow = new JPanel();
18 passwordRow.add(new JLabel(I18n.translate("prompt.password")));
19 passwordRow.add(passwordField);
20
21 int response = JOptionPane.showConfirmDialog(parentComponent, new Object[]{portRow, passwordRow}, I18n.translate("prompt.create_server.title"), JOptionPane.OK_CANCEL_OPTION);
22 if (response != JOptionPane.OK_OPTION) {
23 return null;
24 }
25
26 int port;
27 try {
28 port = Integer.parseInt(portField.getText());
29 } catch (NumberFormatException e) {
30 JOptionPane.showMessageDialog(parentComponent, I18n.translate("prompt.port.nan"), I18n.translate("prompt.create_server.title"), JOptionPane.ERROR_MESSAGE);
31 return null;
32 }
33 if (port < 0 || port >= 65536) {
34 JOptionPane.showMessageDialog(parentComponent, I18n.translate("prompt.port.invalid"), I18n.translate("prompt.create_server.title"), JOptionPane.ERROR_MESSAGE);
35 return null;
36 }
37
38 char[] password = passwordField.getPassword();
39 if (password.length > EnigmaServer.MAX_PASSWORD_LENGTH) {
40 JOptionPane.showMessageDialog(parentComponent, I18n.translate("prompt.password.too_long"), I18n.translate("prompt.create_server.title"), JOptionPane.ERROR_MESSAGE);
41 return null;
42 }
43
44 return new Result(port, password);
45 }
46
47 public static class Result {
48 private final int port;
49 private final char[] password;
50
51 public Result(int port, char[] password) {
52 this.port = port;
53 this.password = password;
54 }
55
56 public int getPort() {
57 return port;
58 }
59
60 public char[] getPassword() {
61 return password;
62 }
63 }
64
65}
diff --git a/src/main/java/cuchaz/enigma/gui/dialog/JavadocDialog.java b/src/main/java/cuchaz/enigma/gui/dialog/JavadocDialog.java
deleted file mode 100644
index 7e41441..0000000
--- a/src/main/java/cuchaz/enigma/gui/dialog/JavadocDialog.java
+++ /dev/null
@@ -1,159 +0,0 @@
1/*******************************************************************************
2 * Copyright (c) 2015 Jeff Martin.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the GNU Lesser General Public
5 * License v3.0 which accompanies this distribution, and is available at
6 * http://www.gnu.org/licenses/lgpl.html
7 * <p>
8 * Contributors:
9 * Jeff Martin - initial API and implementation
10 ******************************************************************************/
11
12package cuchaz.enigma.gui.dialog;
13
14import cuchaz.enigma.utils.I18n;
15import cuchaz.enigma.gui.util.ScaleUtil;
16import cuchaz.enigma.utils.Utils;
17
18import javax.swing.*;
19import javax.swing.text.html.HTML;
20
21import java.awt.*;
22import java.awt.event.KeyAdapter;
23import java.awt.event.KeyEvent;
24
25public class JavadocDialog {
26
27 private static JavadocDialog instance = null;
28
29 private JFrame frame;
30
31 private JavadocDialog(JFrame parent, JTextArea text, Callback callback) {
32 // init frame
33 frame = new JFrame(I18n.translate("javadocs.edit"));
34 final Container pane = frame.getContentPane();
35 pane.setLayout(new BorderLayout());
36
37 // editor panel
38 text.setTabSize(2);
39 pane.add(new JScrollPane(text), BorderLayout.CENTER);
40 text.addKeyListener(new KeyAdapter() {
41 @Override
42 public void keyPressed(KeyEvent event) {
43 switch (event.getKeyCode()) {
44 case KeyEvent.VK_ENTER:
45 if (event.isControlDown())
46 callback.closeUi(frame, true);
47 break;
48 case KeyEvent.VK_ESCAPE:
49 callback.closeUi(frame, false);
50 break;
51 default:
52 break;
53 }
54 }
55 });
56
57 // buttons panel
58 JPanel buttonsPanel = new JPanel();
59 FlowLayout buttonsLayout = new FlowLayout();
60 buttonsLayout.setAlignment(FlowLayout.RIGHT);
61 buttonsPanel.setLayout(buttonsLayout);
62 buttonsPanel.add(Utils.unboldLabel(new JLabel(I18n.translate("javadocs.instruction"))));
63 JButton cancelButton = new JButton(I18n.translate("javadocs.cancel"));
64 cancelButton.addActionListener(event -> {
65 // close (hide) the dialog
66 callback.closeUi(frame, false);
67 });
68 buttonsPanel.add(cancelButton);
69 JButton saveButton = new JButton(I18n.translate("javadocs.save"));
70 saveButton.addActionListener(event -> {
71 // exit enigma
72 callback.closeUi(frame, true);
73 });
74 buttonsPanel.add(saveButton);
75 pane.add(buttonsPanel, BorderLayout.SOUTH);
76
77 // tags panel
78 JMenuBar tagsMenu = new JMenuBar();
79
80 // add javadoc tags
81 for (JavadocTag tag : JavadocTag.values()) {
82 JButton tagButton = new JButton(tag.getText());
83 tagButton.addActionListener(action -> {
84 boolean textSelected = text.getSelectedText() != null;
85 String tagText = tag.isInline() ? "{" + tag.getText() + " }" : tag.getText() + " ";
86
87 if (textSelected) {
88 if (tag.isInline()) {
89 tagText = "{" + tag.getText() + " " + text.getSelectedText() + "}";
90 } else {
91 tagText = tag.getText() + " " + text.getSelectedText();
92 }
93 text.replaceSelection(tagText);
94 } else {
95 text.insert(tagText, text.getCaretPosition());
96 }
97
98 if (tag.isInline()) {
99 text.setCaretPosition(text.getCaretPosition() - 1);
100 }
101 text.grabFocus();
102 });
103 tagsMenu.add(tagButton);
104 }
105
106 // add html tags
107 JComboBox<String> htmlList = new JComboBox<String>();
108 htmlList.setPreferredSize(new Dimension());
109 for (HTML.Tag htmlTag : HTML.getAllTags()) {
110 htmlList.addItem(htmlTag.toString());
111 }
112 htmlList.addActionListener(action -> {
113 String tagText = "<" + htmlList.getSelectedItem().toString() + ">";
114 text.insert(tagText, text.getCaretPosition());
115 text.grabFocus();
116 });
117 tagsMenu.add(htmlList);
118
119 pane.add(tagsMenu, BorderLayout.NORTH);
120
121 // show the frame
122 frame.setSize(ScaleUtil.getDimension(600, 400));
123 frame.setLocationRelativeTo(parent);
124 frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
125 }
126
127 public static void init(JFrame parent, JTextArea area, Callback callback) {
128 instance = new JavadocDialog(parent, area, callback);
129 instance.frame.doLayout();
130 instance.frame.setVisible(true);
131 }
132
133 public interface Callback {
134 void closeUi(JFrame frame, boolean save);
135 }
136
137 private enum JavadocTag {
138 CODE(true),
139 LINK(true),
140 LINKPLAIN(true),
141 RETURN(false),
142 SEE(false),
143 THROWS(false);
144
145 private boolean inline;
146
147 private JavadocTag(boolean inline) {
148 this.inline = inline;
149 }
150
151 public String getText() {
152 return "@" + this.name().toLowerCase();
153 }
154
155 public boolean isInline() {
156 return this.inline;
157 }
158 }
159}
diff --git a/src/main/java/cuchaz/enigma/gui/dialog/ProgressDialog.java b/src/main/java/cuchaz/enigma/gui/dialog/ProgressDialog.java
deleted file mode 100644
index e33ae82..0000000
--- a/src/main/java/cuchaz/enigma/gui/dialog/ProgressDialog.java
+++ /dev/null
@@ -1,109 +0,0 @@
1/*******************************************************************************
2 * Copyright (c) 2015 Jeff Martin.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the GNU Lesser General Public
5 * License v3.0 which accompanies this distribution, and is available at
6 * http://www.gnu.org/licenses/lgpl.html
7 * <p>
8 * Contributors:
9 * Jeff Martin - initial API and implementation
10 ******************************************************************************/
11
12package cuchaz.enigma.gui.dialog;
13
14import cuchaz.enigma.Constants;
15import cuchaz.enigma.ProgressListener;
16import cuchaz.enigma.utils.I18n;
17import cuchaz.enigma.gui.util.ScaleUtil;
18import cuchaz.enigma.utils.Utils;
19
20import javax.swing.*;
21import java.awt.*;
22import java.util.concurrent.CompletableFuture;
23
24public class ProgressDialog implements ProgressListener, AutoCloseable {
25
26 private JFrame frame;
27 private JLabel labelTitle;
28 private JLabel labelText;
29 private JProgressBar progress;
30
31 public ProgressDialog(JFrame parent) {
32
33 // init frame
34 this.frame = new JFrame(String.format(I18n.translate("progress.operation"), Constants.NAME));
35 final Container pane = this.frame.getContentPane();
36 FlowLayout layout = new FlowLayout();
37 layout.setAlignment(FlowLayout.LEFT);
38 pane.setLayout(layout);
39
40 this.labelTitle = new JLabel();
41 pane.add(this.labelTitle);
42
43 // set up the progress bar
44 JPanel panel = new JPanel();
45 pane.add(panel);
46 panel.setLayout(new BorderLayout());
47 this.labelText = Utils.unboldLabel(new JLabel());
48 this.progress = new JProgressBar();
49 this.labelText.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0));
50 panel.add(this.labelText, BorderLayout.NORTH);
51 panel.add(this.progress, BorderLayout.CENTER);
52 panel.setPreferredSize(ScaleUtil.getDimension(360, 50));
53
54 // show the frame
55 pane.doLayout();
56 this.frame.setSize(ScaleUtil.getDimension(400, 120));
57 this.frame.setResizable(false);
58 this.frame.setLocationRelativeTo(parent);
59 this.frame.setVisible(true);
60 this.frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
61 }
62
63 public static CompletableFuture<Void> runOffThread(final JFrame parent, final ProgressRunnable runnable) {
64 CompletableFuture<Void> future = new CompletableFuture<>();
65 new Thread(() ->
66 {
67 try (ProgressDialog progress = new ProgressDialog(parent)) {
68 runnable.run(progress);
69 future.complete(null);
70 } catch (Exception ex) {
71 future.completeExceptionally(ex);
72 throw new Error(ex);
73 }
74 }).start();
75 return future;
76 }
77
78 @Override
79 public void close() {
80 this.frame.dispose();
81 }
82
83 @Override
84 public void init(int totalWork, String title) {
85 this.labelTitle.setText(title);
86 this.progress.setMinimum(0);
87 this.progress.setMaximum(totalWork);
88 this.progress.setValue(0);
89 }
90
91 @Override
92 public void step(int numDone, String message) {
93 this.labelText.setText(message);
94 if (numDone != -1) {
95 this.progress.setValue(numDone);
96 this.progress.setIndeterminate(false);
97 } else {
98 this.progress.setIndeterminate(true);
99 }
100
101 // update the frame
102 this.frame.validate();
103 this.frame.repaint();
104 }
105
106 public interface ProgressRunnable {
107 void run(ProgressListener listener) throws Exception;
108 }
109}
diff --git a/src/main/java/cuchaz/enigma/gui/dialog/SearchDialog.java b/src/main/java/cuchaz/enigma/gui/dialog/SearchDialog.java
deleted file mode 100644
index b283a37..0000000
--- a/src/main/java/cuchaz/enigma/gui/dialog/SearchDialog.java
+++ /dev/null
@@ -1,261 +0,0 @@
1/*******************************************************************************
2 * Copyright (c) 2015 Jeff Martin.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the GNU Lesser General Public
5 * License v3.0 which accompanies this distribution, and is available at
6 * http://www.gnu.org/licenses/lgpl.html
7 * <p>
8 * Contributors:
9 * Jeff Martin - initial API and implementation
10 ******************************************************************************/
11
12package cuchaz.enigma.gui.dialog;
13
14import java.awt.BorderLayout;
15import java.awt.Color;
16import java.awt.FlowLayout;
17import java.awt.Font;
18import java.awt.event.*;
19import java.util.Arrays;
20import java.util.Collections;
21import java.util.List;
22
23import javax.swing.*;
24import javax.swing.event.DocumentEvent;
25import javax.swing.event.DocumentListener;
26
27import cuchaz.enigma.gui.Gui;
28import cuchaz.enigma.gui.GuiController;
29import cuchaz.enigma.gui.util.AbstractListCellRenderer;
30import cuchaz.enigma.gui.util.ScaleUtil;
31import cuchaz.enigma.translation.representation.entry.ClassEntry;
32import cuchaz.enigma.utils.I18n;
33import cuchaz.enigma.utils.search.SearchEntry;
34import cuchaz.enigma.utils.search.SearchUtil;
35
36public class SearchDialog {
37
38 private final JTextField searchField;
39 private DefaultListModel<SearchEntryImpl> classListModel;
40 private final JList<SearchEntryImpl> classList;
41 private final JDialog dialog;
42
43 private final Gui parent;
44 private final SearchUtil<SearchEntryImpl> su;
45 private SearchUtil.SearchControl currentSearch;
46
47 public SearchDialog(Gui parent) {
48 this.parent = parent;
49
50 su = new SearchUtil<>();
51
52 dialog = new JDialog(parent.getFrame(), I18n.translate("menu.view.search"), true);
53 JPanel contentPane = new JPanel();
54 contentPane.setBorder(ScaleUtil.createEmptyBorder(4, 4, 4, 4));
55 contentPane.setLayout(new BorderLayout(ScaleUtil.scale(4), ScaleUtil.scale(4)));
56
57 searchField = new JTextField();
58 searchField.getDocument().addDocumentListener(new DocumentListener() {
59
60 @Override
61 public void insertUpdate(DocumentEvent e) {
62 updateList();
63 }
64
65 @Override
66 public void removeUpdate(DocumentEvent e) {
67 updateList();
68 }
69
70 @Override
71 public void changedUpdate(DocumentEvent e) {
72 updateList();
73 }
74
75 });
76 searchField.addKeyListener(new KeyAdapter() {
77 @Override
78 public void keyPressed(KeyEvent e) {
79 if (e.getKeyCode() == KeyEvent.VK_DOWN) {
80 int next = classList.isSelectionEmpty() ? 0 : classList.getSelectedIndex() + 1;
81 classList.setSelectedIndex(next);
82 classList.ensureIndexIsVisible(next);
83 } else if (e.getKeyCode() == KeyEvent.VK_UP) {
84 int prev = classList.isSelectionEmpty() ? classList.getModel().getSize() : classList.getSelectedIndex() - 1;
85 classList.setSelectedIndex(prev);
86 classList.ensureIndexIsVisible(prev);
87 } else if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
88 close();
89 }
90 }
91 });
92 searchField.addActionListener(e -> openSelected());
93 contentPane.add(searchField, BorderLayout.NORTH);
94
95 classListModel = new DefaultListModel<>();
96 classList = new JList<>();
97 classList.setModel(classListModel);
98 classList.setCellRenderer(new ListCellRendererImpl());
99 classList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
100 classList.addMouseListener(new MouseAdapter() {
101 @Override
102 public void mouseClicked(MouseEvent mouseEvent) {
103 if (mouseEvent.getClickCount() >= 2) {
104 int idx = classList.locationToIndex(mouseEvent.getPoint());
105 SearchEntryImpl entry = classList.getModel().getElementAt(idx);
106 openEntry(entry);
107 }
108 }
109 });
110 contentPane.add(new JScrollPane(classList, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER), BorderLayout.CENTER);
111
112 JPanel buttonBar = new JPanel();
113 buttonBar.setLayout(new FlowLayout(FlowLayout.RIGHT));
114 JButton open = new JButton(I18n.translate("prompt.open"));
115 open.addActionListener(event -> openSelected());
116 buttonBar.add(open);
117 JButton cancel = new JButton(I18n.translate("prompt.cancel"));
118 cancel.addActionListener(event -> close());
119 buttonBar.add(cancel);
120 contentPane.add(buttonBar, BorderLayout.SOUTH);
121
122 // apparently the class list doesn't update by itself when the list
123 // state changes and the dialog is hidden
124 dialog.addComponentListener(new ComponentAdapter() {
125 @Override
126 public void componentShown(ComponentEvent e) {
127 classList.updateUI();
128 }
129 });
130
131 dialog.setContentPane(contentPane);
132 dialog.setSize(ScaleUtil.getDimension(400, 500));
133 dialog.setLocationRelativeTo(parent.getFrame());
134 }
135
136 public void show() {
137 su.clear();
138 parent.getController().project.getJarIndex().getEntryIndex().getClasses().parallelStream()
139 .filter(e -> !e.isInnerClass())
140 .map(e -> SearchEntryImpl.from(e, parent.getController()))
141 .map(SearchUtil.Entry::from)
142 .sequential()
143 .forEach(su::add);
144
145 updateList();
146
147 searchField.requestFocus();
148 searchField.selectAll();
149
150 dialog.setVisible(true);
151 }
152
153 private void openSelected() {
154 SearchEntryImpl selectedValue = classList.getSelectedValue();
155 if (selectedValue != null) {
156 openEntry(selectedValue);
157 }
158 }
159
160 private void openEntry(SearchEntryImpl e) {
161 close();
162 su.hit(e);
163 parent.getController().navigateTo(e.obf);
164 if (e.deobf != null) {
165 parent.getDeobfPanel().deobfClasses.setSelectionClass(e.deobf);
166 } else {
167 parent.getObfPanel().obfClasses.setSelectionClass(e.obf);
168 }
169 }
170
171 private void close() {
172 dialog.setVisible(false);
173 }
174
175 // Updates the list of class names
176 private void updateList() {
177 if (currentSearch != null) currentSearch.stop();
178
179 DefaultListModel<SearchEntryImpl> classListModel = new DefaultListModel<>();
180 this.classListModel = classListModel;
181 classList.setModel(classListModel);
182
183 currentSearch = su.asyncSearch(searchField.getText(), (idx, e) -> SwingUtilities.invokeLater(() -> classListModel.insertElementAt(e, idx)));
184 }
185
186 public void dispose() {
187 dialog.dispose();
188 }
189
190 private static final class SearchEntryImpl implements SearchEntry {
191
192 public final ClassEntry obf;
193 public final ClassEntry deobf;
194
195 private SearchEntryImpl(ClassEntry obf, ClassEntry deobf) {
196 this.obf = obf;
197 this.deobf = deobf;
198 }
199
200 @Override
201 public List<String> getSearchableNames() {
202 if (deobf != null) {
203 return Arrays.asList(obf.getSimpleName(), deobf.getSimpleName());
204 } else {
205 return Collections.singletonList(obf.getSimpleName());
206 }
207 }
208
209 @Override
210 public String getIdentifier() {
211 return obf.getFullName();
212 }
213
214 @Override
215 public String toString() {
216 return String.format("SearchEntryImpl { obf: %s, deobf: %s }", obf, deobf);
217 }
218
219 public static SearchEntryImpl from(ClassEntry e, GuiController controller) {
220 ClassEntry deobf = controller.project.getMapper().deobfuscate(e);
221 if (deobf.equals(e)) deobf = null;
222 return new SearchEntryImpl(e, deobf);
223 }
224
225 }
226
227 private static final class ListCellRendererImpl extends AbstractListCellRenderer<SearchEntryImpl> {
228
229 private final JLabel mainName;
230 private final JLabel secondaryName;
231
232 public ListCellRendererImpl() {
233 this.setLayout(new BorderLayout());
234
235 mainName = new JLabel();
236 this.add(mainName, BorderLayout.WEST);
237
238 secondaryName = new JLabel();
239 secondaryName.setFont(secondaryName.getFont().deriveFont(Font.ITALIC));
240 secondaryName.setForeground(Color.GRAY);
241 this.add(secondaryName, BorderLayout.EAST);
242 }
243
244 @Override
245 public void updateUiForEntry(JList<? extends SearchEntryImpl> list, SearchEntryImpl value, int index, boolean isSelected, boolean cellHasFocus) {
246 if (value.deobf == null) {
247 mainName.setText(value.obf.getSimpleName());
248 mainName.setToolTipText(value.obf.getFullName());
249 secondaryName.setText("");
250 secondaryName.setToolTipText("");
251 } else {
252 mainName.setText(value.deobf.getSimpleName());
253 mainName.setToolTipText(value.deobf.getFullName());
254 secondaryName.setText(value.obf.getSimpleName());
255 secondaryName.setToolTipText(value.obf.getFullName());
256 }
257 }
258
259 }
260
261}
diff --git a/src/main/java/cuchaz/enigma/gui/dialog/StatsDialog.java b/src/main/java/cuchaz/enigma/gui/dialog/StatsDialog.java
deleted file mode 100644
index 868eba7..0000000
--- a/src/main/java/cuchaz/enigma/gui/dialog/StatsDialog.java
+++ /dev/null
@@ -1,82 +0,0 @@
1package cuchaz.enigma.gui.dialog;
2
3import java.awt.BorderLayout;
4import java.util.Arrays;
5import java.util.Locale;
6import java.util.Map;
7import java.util.Set;
8import java.util.stream.Collectors;
9
10import javax.swing.JButton;
11import javax.swing.JCheckBox;
12import javax.swing.JFrame;
13import javax.swing.JPanel;
14
15import cuchaz.enigma.gui.Gui;
16import cuchaz.enigma.gui.stats.StatsMember;
17import cuchaz.enigma.gui.util.ScaleUtil;
18import cuchaz.enigma.utils.I18n;
19
20public class StatsDialog {
21
22 public static void show(Gui gui) {
23 // init frame
24 JFrame frame = new JFrame(I18n.translate("menu.file.stats.title"));
25 JPanel checkboxesPanel = new JPanel();
26 JPanel buttonPanel = new JPanel();
27 frame.setLayout(new BorderLayout());
28 frame.add(BorderLayout.NORTH, checkboxesPanel);
29 frame.add(BorderLayout.SOUTH, buttonPanel);
30
31 // show checkboxes
32 Map<StatsMember, JCheckBox> checkboxes = Arrays
33 .stream(StatsMember.values())
34 .collect(Collectors.toMap(m -> m, m -> {
35 JCheckBox checkbox = new JCheckBox(I18n.translate("type." + m.name().toLowerCase(Locale.ROOT)));
36 checkboxesPanel.add(checkbox);
37 return checkbox;
38 }));
39
40 // show generate button
41 JButton button = new JButton(I18n.translate("menu.file.stats.generate"));
42 buttonPanel.add(button);
43 button.setEnabled(false);
44 button.addActionListener(action -> {
45 frame.dispose();
46 generateStats(gui, checkboxes);
47 });
48
49 // add action listener to each checkbox
50 checkboxes.entrySet().forEach(checkbox -> {
51 checkbox.getValue().addActionListener(action -> {
52 if (!button.isEnabled()) {
53 button.setEnabled(true);
54 } else if (checkboxes.entrySet().stream().allMatch(entry -> !entry.getValue().isSelected())) {
55 button.setEnabled(false);
56 }
57 });
58 });
59
60 // show the frame
61 frame.pack();
62 frame.setVisible(true);
63 frame.setSize(ScaleUtil.getDimension(500, 120));
64 frame.setResizable(false);
65 frame.setLocationRelativeTo(gui.getFrame());
66 }
67
68 private static void generateStats(Gui gui, Map<StatsMember, JCheckBox> checkboxes) {
69 // get members from selected checkboxes
70 Set<StatsMember> includedMembers = checkboxes
71 .entrySet()
72 .stream()
73 .filter(entry -> entry.getValue().isSelected())
74 .map(Map.Entry::getKey)
75 .collect(Collectors.toSet());
76
77 // checks if a projet is open
78 if (gui.getController().project != null) {
79 gui.getController().openStats(includedMembers);
80 }
81 }
82}