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}