001package com.ganteater.ae.desktop.ui;
002
003import java.awt.BorderLayout;
004import java.awt.Component;
005import java.awt.Dimension;
006import java.awt.EventQueue;
007import java.awt.Frame;
008import java.awt.Toolkit;
009import java.awt.datatransfer.Clipboard;
010import java.awt.datatransfer.DataFlavor;
011import java.awt.datatransfer.Transferable;
012import java.awt.datatransfer.UnsupportedFlavorException;
013import java.awt.event.ActionEvent;
014import java.awt.event.ActionListener;
015import java.awt.event.KeyAdapter;
016import java.awt.event.KeyEvent;
017import java.awt.event.MouseAdapter;
018import java.awt.event.MouseEvent;
019import java.io.File;
020import java.io.IOException;
021import java.io.InputStream;
022import java.net.URL;
023import java.util.Arrays;
024import java.util.regex.Matcher;
025import java.util.regex.Pattern;
026
027import javax.swing.ImageIcon;
028import javax.swing.JComboBox;
029import javax.swing.JComponent;
030import javax.swing.JDialog;
031import javax.swing.JEditorPane;
032import javax.swing.JLabel;
033import javax.swing.JOptionPane;
034import javax.swing.JPanel;
035import javax.swing.JPasswordField;
036import javax.swing.JScrollPane;
037import javax.swing.JTextField;
038import javax.swing.SwingUtilities;
039
040import org.apache.commons.lang.StringUtils;
041
042import com.ganteater.ae.TaskCancelingException;
043import com.ganteater.ae.desktop.InputDialogType;
044import com.ganteater.ae.desktop.util.SoundManager;
045import com.ganteater.ae.desktop.util.UIUtils;
046
047public class OptionPane {
048
049        private static final String SKIP = "Skip";
050
051        private static final String OK = "OK";
052
053        protected static final String[] OPTIONS = new String[] { OK, SKIP };
054
055        private OptionPane() {
056                super();
057        }
058
059        public static int showOptionDialog(Component parentComponent, Object message, String title, int messageType) {
060                return showOptionDialog(parentComponent, message, title, messageType, false, OPTIONS);
061        }
062
063        public static int showOptionDialog(Component parentComponent, Object message, String title, int messageType,
064                        boolean modal, Object[] options) {
065                int result = 0;
066
067                ImageIcon icon = null;
068                if (messageType > 3) {
069                        icon = AEFrame.getIcon("logo.png");
070                }
071
072                JOptionPane pane = new JOptionPane(message, JOptionPane.QUESTION_MESSAGE, JOptionPane.CANCEL_OPTION, icon,
073                                options);
074
075                if (messageType <= 3) {
076                        pane.setMessageType(messageType);
077                }
078
079                JDialog dialog = pane.createDialog(parentComponent, title);
080                dialog.setModal(modal);
081
082                if (!parentComponent.isVisible()) {
083                        dialog.setAlwaysOnTop(true);
084                }
085
086                if (!UIUtils.applyPreferedView(dialog, title)) {
087                        dialog.pack();
088                }
089
090                if (message instanceof JPanel) {
091                        JPanel panel = (JPanel) message;
092                        if (panel.getComponentCount() > 2) {
093                                try {
094                                        Component component = panel.getComponent(2);
095                                        if (component instanceof CheckPointBox) {
096                                                component = panel.getComponent(1);
097                                        }
098                                        if (component instanceof JTextField) {
099                                                JTextField field = (JTextField) component;
100                                                field.addKeyListener(new KeyAdapter() {
101                                                        @Override
102                                                        public void keyPressed(KeyEvent e) {
103                                                                switch (e.getKeyCode()) {
104                                                                case KeyEvent.VK_ENTER:
105                                                                        pane.setValue(OK);
106                                                                        break;
107                                                                case KeyEvent.VK_ESCAPE:
108                                                                        pane.setValue(SKIP);
109                                                                        break;
110                                                                default:
111                                                                }
112                                                        }
113                                                });
114                                                field.addMouseListener(new MouseAdapter() {
115                                                        @Override
116                                                        public void mouseClicked(MouseEvent e) {
117                                                                if (e.getButton() == MouseEvent.BUTTON3) {
118                                                                        Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
119                                                                        Transferable contents = clipboard.getContents(null);
120                                                                        if (contents != null && contents.isDataFlavorSupported(DataFlavor.stringFlavor)) {
121                                                                                try {
122                                                                                        String text = (String) contents.getTransferData(DataFlavor.stringFlavor);
123                                                                                        field.setText(text);
124                                                                                } catch (UnsupportedFlavorException | IOException e1) {
125                                                                                        //
126                                                                                }
127                                                                        }
128                                                                }
129                                                        }
130                                                });
131                                                EventQueue.invokeLater(() -> {
132                                                        field.grabFocus();
133                                                        field.requestFocusInWindow();
134                                                        field.requestFocus();
135                                                        field.selectAll();
136                                                });
137                                                dialog.pack();
138                                        } else if (component instanceof JComboBox) {
139                                                @SuppressWarnings("unchecked")
140                                                JComboBox<String> combo = (JComboBox<String>) component;
141                                                combo.getEditor().addActionListener(new ActionListener() {
142                                                        @Override
143                                                        public void actionPerformed(ActionEvent e) {
144                                                                pane.setValue(OK);
145                                                        }
146                                                });
147
148                                                SwingUtilities.invokeLater(() -> {
149                                                        combo.grabFocus();
150                                                        combo.requestFocus();
151                                                });
152                                                dialog.pack();
153                                        } else {
154                                                dialog.setResizable(true);
155                                        }
156                                } catch (ArrayIndexOutOfBoundsException e) {
157                                        e.printStackTrace();
158                                }
159                        } else {
160                                dialog.setResizable(true);
161                        }
162                }
163
164                dialog.setVisible(true);
165
166                Object value = null;
167                do {
168                        value = pane.getValue();
169                        try {
170                                Thread.sleep(100);
171                        } catch (InterruptedException e) {
172                                Thread.currentThread().interrupt();
173                        }
174                } while (value == "uninitializedValue");
175
176                UIUtils.saveDialogPreferedView(dialog, title);
177                dialog.dispose();
178
179                if (value == null) {
180                        result = -1;
181                } else if (SKIP.equals(value)) {
182                        result = JOptionPane.CANCEL_OPTION;
183                } else if (OK.equals(value)) {
184                        result = JOptionPane.OK_OPTION;
185                } else if (value instanceof Integer) {
186                        result = (int) value;
187                } else {
188                        result = Arrays.binarySearch(options, value);
189                }
190
191                SoundManager.stop();
192                return result;
193        }
194
195        public static int showConfirmDialog(Frame frame, JComponent panel, String title) {
196                return showOptionDialog(frame, panel, title, JOptionPane.QUESTION_MESSAGE);
197        }
198
199        public static String showInputDialog(Component rootPane, String message, String title, Object[] list,
200                        String newValueTitle) {
201                JPanel panel = new JPanel(new BorderLayout());
202                JLabel label = new JLabel(message);
203                panel.add(label, BorderLayout.NORTH);
204                @SuppressWarnings({ "rawtypes", "unchecked" })
205                JComboBox inputField = new JComboBox(list);
206
207                inputField.setEditable(true);
208                inputField.setSelectedItem(newValueTitle);
209
210                panel.add(inputField, BorderLayout.CENTER);
211
212                CheckPointBox vip = new CheckPointBox(title, null, InputDialogType.VAR);
213                panel.add(vip, BorderLayout.SOUTH);
214                int showOptionDialog = showOptionDialog(rootPane, panel, title, 3, true, OPTIONS);
215                if (showOptionDialog == -1) {
216                        throw new TaskCancelingException();
217                }
218                return showOptionDialog == 2 ? null : (String) inputField.getSelectedItem();
219        }
220
221        public static String showInputPasswordDialog(String description, String aValue, Component southComp,
222                        int messageType, Object[] options) {
223                String result = null;
224                JPanel panel = new JPanel(new BorderLayout(4, 4));
225                JLabel label = new JLabel(description);
226                JPasswordField pass = new JPasswordField();
227                pass.putClientProperty("JPasswordField.cutCopyAllowed", true);
228
229                pass.setText(aValue);
230
231                panel.add(label, BorderLayout.NORTH);
232                panel.add(pass, BorderLayout.CENTER);
233
234                if (southComp != null) {
235                        panel.add(southComp, BorderLayout.SOUTH);
236                }
237
238                Frame rootFrame = JOptionPane.getRootFrame();
239
240                int option = OptionPane.showOptionDialog(rootFrame, panel, "Input a password", messageType, false, options);
241
242                switch (option) {
243                case JOptionPane.OK_OPTION:
244                        char[] password = pass.getPassword();
245                        result = new String(password);
246                        break;
247                case JOptionPane.CANCEL_OPTION:
248                case JOptionPane.NO_OPTION:
249                        result = null;
250                        break;
251                case JOptionPane.CLOSED_OPTION:
252                        throw new TaskCancelingException();
253                default:
254                        result = Integer.toString(option);
255                }
256                return result;
257        }
258
259        public static void showMessageDialog(AEFrame frame, String text, String title, int type) {
260                JEditorPane textPane = new JEditorPane();
261                textPane.setContentType("text/html");
262
263                if (!StringUtils.startsWith(text, "<html><body>")) {
264                        Pattern pattern = Pattern.compile("\"(.*?)\"");
265                        Matcher matcher = pattern.matcher(text);
266                        while (matcher.find()) {
267                                String group = matcher.group();
268
269                                boolean enable = true;
270                                group = StringUtils.substring(group, 1, group.length() - 1);
271                                group = group.replace("file:", "");
272                                
273                                File file = new File(group);
274                                if (!file.exists()) {
275                                        try (InputStream openStream = new URL(group).openStream()) {
276                                        } catch (IOException e) {
277                                                enable = false;
278                                        }
279                                }
280
281                                if (enable) {
282                                        text = text.replace(group, "<a href=" + group + ">" + group + "</a>");
283                                }
284                        }
285                        textPane.setText(text.replace("\n", "<br/>"));
286                }
287
288                textPane.addHyperlinkListener(new HyperlinkAdapter(frame.getWorkspace()));
289
290                textPane.setOpaque(false);
291                textPane.setEditable(false);
292
293                JOptionPane pane = new JOptionPane(new JScrollPane(textPane), type);
294                JDialog dialog = pane.createDialog(pane, title);
295                dialog.setResizable(true);
296                dialog.setPreferredSize(new Dimension(600, 300));
297
298                if (!UIUtils.applyPreferedView(dialog, title)) {
299                        dialog.pack();
300                }
301
302                dialog.setVisible(true);
303
304                Object value = null;
305                do {
306                        value = pane.getValue();
307                        try {
308                                Thread.sleep(100);
309                        } catch (InterruptedException e) {
310                                Thread.currentThread().interrupt();
311                        }
312                } while (value == "uninitializedValue");
313
314                UIUtils.saveDialogPreferedView(dialog, title);
315                dialog.dispose();
316
317        }
318
319}