aboutsummaryrefslogtreecommitdiff
path: root/src/main/ui/gui/widgets/UIUtils.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/ui/gui/widgets/UIUtils.java')
-rw-r--r--src/main/ui/gui/widgets/UIUtils.java168
1 files changed, 168 insertions, 0 deletions
diff --git a/src/main/ui/gui/widgets/UIUtils.java b/src/main/ui/gui/widgets/UIUtils.java
new file mode 100644
index 0000000..bb09a72
--- /dev/null
+++ b/src/main/ui/gui/widgets/UIUtils.java
@@ -0,0 +1,168 @@
+package ui.gui.widgets;
+
+import model.asn1.exceptions.ParseException;
+import ui.Utils;
+
+import javax.swing.*;
+import javax.swing.filechooser.FileNameExtensionFilter;
+import java.awt.*;
+import java.awt.event.ActionListener;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
+import java.util.stream.IntStream;
+
+import static java.awt.GridBagConstraints.BOTH;
+import static java.awt.GridBagConstraints.HORIZONTAL;
+import static javax.swing.JOptionPane.*;
+
+/**
+ * Useful utilities for building GUI.
+ */
+public class UIUtils {
+ /**
+ * EFFECTS: Create a horizontal actions pane:
+ * -----------------------------------------------------------
+ * | | Button1 | Button2 | Button3 | ButtonN |
+ * -----------------------------------------------------------
+ * REQUIRES: buttons != null
+ */
+ public static JPanel createActionsPane(JButton... buttons) {
+ final JPanel panelAct = new JPanel();
+ panelAct.setLayout(new GridBagLayout());
+ IntStream.range(0, buttons.length)
+ .forEach(i -> panelAct.add(buttons[i],
+ new GCBuilder().gridXY(i + 1, 1).fill(HORIZONTAL).build()));
+ panelAct.add(new JPanel(), new GCBuilder().expandXY().fill(BOTH).build());
+ return panelAct;
+ }
+
+ /**
+ * EFFECTS: Show / hide default text for a card layout container.
+ * MODIFIES: cardLayoutPanel
+ * REQUIRES: cardLayoutPanel must have a card layout; it must have CardContent and CardDefault cards.
+ */
+ public static void setContentVisible(Container cardLayoutPanel, boolean showContent) {
+ switchTo(cardLayoutPanel, showContent ? "CardContent" : "CardDefault");
+ }
+
+ /**
+ * EFFECTS: Switch to the card for a card layout panel.
+ * MODIFIES: cardLayoutPanel
+ * REQUIRES: cardLayoutPanel must have a card layout; it must have "card" card.
+ */
+ public static void switchTo(Container cardLayoutPanel, String card) {
+ ((CardLayout) cardLayoutPanel.getLayout()).show(cardLayoutPanel, card);
+ }
+
+ /**
+ * EFFECTS: Show an error message based on {@link Throwable#getMessage()}
+ * REQUIRES: component must have a frame.
+ */
+ public static void alert(Component component, String title, Throwable e) {
+ alert(component, title, e.getMessage());
+ }
+
+ /**
+ * EFFECTS: Show an error message.
+ * REQUIRES: component must have a frame.
+ */
+ public static void alert(Component component, String title, String message) {
+ showMessageDialog(getFrameForComponent(component),
+ message,
+ title,
+ ERROR_MESSAGE);
+ }
+
+ /**
+ * EFFECTS: Show a file chooser with the given filter title and list of extensions. Starting from cwd.
+ * Return null if cancelled.
+ */
+ public static Path chooseFile(Component component, String filterTitle, String... extensions) {
+ final JFileChooser fc = new JFileChooser();
+ fc.setFileFilter(new FileNameExtensionFilter(filterTitle, extensions));
+ fc.setCurrentDirectory(Paths.get("").toAbsolutePath().toFile());
+ if (fc.showOpenDialog(getFrameForComponent(component)) == JFileChooser.APPROVE_OPTION) {
+ return fc.getSelectedFile().toPath();
+ }
+ return null;
+ }
+
+ /**
+ * EFFECTS: Create a JPanel with CardLayout that has CardDefault set to component and CardContent set to a JLabel
+ * with the default text.
+ */
+ public static JPanel defView(Component component, String defaultText) {
+ final JPanel panel = new JPanel();
+ panel.setLayout(new CardLayout(0, 0));
+
+ JLabel labelDefault = new JLabel(defaultText);
+ labelDefault.setHorizontalAlignment(0);
+ panel.add(labelDefault, "CardDefault");
+ panel.add(component, "CardContent");
+
+ return panel;
+ }
+
+ /**
+ * EFFECTS: Create a JScrollPane-wrapped JTable.
+ * MODIFIES: table
+ */
+ public static JScrollPane scrTbl(JTable table) {
+ final JScrollPane scrollPane = new JScrollPane();
+ table.setFillsViewportHeight(true);
+ scrollPane.setViewportView(table);
+ return scrollPane;
+ }
+
+ /**
+ * EFFECTS: Parse the given path and automatically determine if it is a DER binary or a PEM. Automatically decode
+ * PEM.
+ * Throws {@link IOException} if it cannot be read.
+ * Throws {@link ParseException} if the PEM is invalid.
+ */
+ public static Byte[] openDERorPEM(Path path, String tag) throws IOException, ParseException {
+ final InputStream fd = Files.newInputStream(path, StandardOpenOption.READ);
+ Byte[] bs = Utils.byteToByte(fd.readAllBytes());
+ fd.close();
+ if (bs.length < 1) {
+ throw new ParseException("Invalid file: too short");
+ }
+ if (bs[0] == '-') {
+ bs = Utils.parsePEM(bs, tag);
+ }
+ return bs;
+ }
+
+ /**
+ * EFFECTS: Create a button with the given label and click listener.
+ */
+ public static JButton btn(String string, ActionListener onClick) {
+ final JButton btn = new JButton(string);
+ btn.addActionListener(onClick);
+ return btn;
+ }
+
+ /**
+ * EFFECTS: Create a button with the given label, mnemonic, and click listener.
+ */
+ public static JButton btn(String string, char m, ActionListener onClick) {
+ final JButton btn = new JButton(string);
+ btn.setMnemonic(m);
+ btn.setDisplayedMnemonicIndex(0);
+ btn.addActionListener(onClick);
+ return btn;
+ }
+
+ /**
+ * EFFECTS: Create a button with the given label, mnemonic, icon, and click listener.
+ */
+ public static JButton btn(String string, String icon, ActionListener onClick) {
+ final JButton btn = new JButton(string, new ImageIcon(UIUtils.class.getResource("/" + icon)));
+ btn.addActionListener(onClick);
+ return btn;
+ }
+}