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