EditPad.java revision 1384:5beae9dfcdb9
1/*
2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package jdk.nashorn.tools.jjs;
27
28import java.awt.BorderLayout;
29import java.awt.FlowLayout;
30import java.awt.event.KeyEvent;
31import java.awt.event.WindowAdapter;
32import java.awt.event.WindowEvent;
33import java.util.function.Consumer;
34import javax.swing.JButton;
35import javax.swing.JFrame;
36import javax.swing.JPanel;
37import javax.swing.JScrollPane;
38import javax.swing.JTextArea;
39import javax.swing.SwingUtilities;
40
41/**
42 * A minimal Swing editor as a fallback when the user does not specify an
43 * external editor.
44 */
45final class EditPad extends JFrame implements Runnable {
46    private static final long serialVersionUID = 1;
47    private final Consumer<String> errorHandler;
48    private final String initialText;
49    private final boolean[] closeLock;
50    private final Consumer<String> saveHandler;
51
52    EditPad(Consumer<String> errorHandler, String initialText,
53            boolean[] closeLock, Consumer<String> saveHandler) {
54        super("Edit Pad (Experimental)");
55        this.errorHandler = errorHandler;
56        this.initialText = initialText;
57        this.closeLock = closeLock;
58        this.saveHandler = saveHandler;
59    }
60
61    @Override
62    public void run() {
63        addWindowListener(new WindowAdapter() {
64            @Override
65            public void windowClosing(WindowEvent e) {
66                EditPad.this.dispose();
67                notifyClose();
68            }
69        });
70        setLocationRelativeTo(null);
71        setLayout(new BorderLayout());
72        JTextArea textArea = new JTextArea(initialText);
73        add(new JScrollPane(textArea), BorderLayout.CENTER);
74        add(buttons(textArea), BorderLayout.SOUTH);
75
76        setSize(800, 600);
77        setVisible(true);
78    }
79
80    private JPanel buttons(JTextArea textArea) {
81        FlowLayout flow = new FlowLayout();
82        flow.setHgap(35);
83        JPanel buttons = new JPanel(flow);
84        JButton cancel = new JButton("Cancel");
85        cancel.setMnemonic(KeyEvent.VK_C);
86        JButton accept = new JButton("Accept");
87        accept.setMnemonic(KeyEvent.VK_A);
88        JButton exit = new JButton("Exit");
89        exit.setMnemonic(KeyEvent.VK_X);
90        buttons.add(cancel);
91        buttons.add(accept);
92        buttons.add(exit);
93
94        cancel.addActionListener(e -> {
95            close();
96        });
97        accept.addActionListener(e -> {
98            saveHandler.accept(textArea.getText());
99        });
100        exit.addActionListener(e -> {
101            saveHandler.accept(textArea.getText());
102            close();
103        });
104
105        return buttons;
106    }
107
108    private void close() {
109        setVisible(false);
110        dispose();
111        notifyClose();
112    }
113
114    private void notifyClose() {
115        synchronized (closeLock) {
116            closeLock[0] = true;
117            closeLock.notify();
118        }
119    }
120
121    static void edit(Consumer<String> errorHandler, String initialText,
122            Consumer<String> saveHandler) {
123        boolean[] closeLock = new boolean[1];
124        SwingUtilities.invokeLater(
125                new EditPad(errorHandler, initialText, closeLock, saveHandler));
126        synchronized (closeLock) {
127            while (!closeLock[0]) {
128                try {
129                    closeLock.wait();
130                } catch (InterruptedException ex) {
131                    // ignore and loop
132                }
133            }
134        }
135    }
136}
137