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