aboutsummaryrefslogtreecommitdiff
path: root/src/main/ui/gui/widgets/UIUtils.java
blob: bb09a7210b57b9d97b4ac78e87e4111ce89416ec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
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;
    }
}