1 33 34 package edu.rice.cs.drjava.ui; 35 36 import javax.swing.*; 37 import javax.swing.event.*; 38 import javax.swing.text.JTextComponent ; 39 import javax.swing.text.Keymap ; 40 import java.awt.*; 41 import java.awt.event.*; 42 import java.util.List ; 43 import java.util.ArrayList ; 44 import java.util.StringTokenizer ; 45 import java.util.NoSuchElementException ; 46 47 import edu.rice.cs.drjava.DrJava; 48 import edu.rice.cs.drjava.config.OptionConstants; 49 import edu.rice.cs.drjava.model.ClipboardHistoryModel; 50 import edu.rice.cs.util.Lambda; 51 52 53 public class ClipboardHistoryFrame extends JFrame { 54 57 public static interface CloseAction extends Lambda<Object , String > { 58 public Object apply(String selected); 59 } 60 61 62 public static class FrameState { 63 private Dimension _dim; 64 private Point _loc; 65 public FrameState(Dimension d, Point l) { 66 _dim = d; 67 _loc = l; 68 } 69 public FrameState(String s) { 70 StringTokenizer tok = new StringTokenizer (s); 71 try { 72 int x = Integer.valueOf(tok.nextToken()); 73 int y = Integer.valueOf(tok.nextToken()); 74 _dim = new Dimension(x, y); 75 x = Integer.valueOf(tok.nextToken()); 76 y = Integer.valueOf(tok.nextToken()); 77 _loc = new Point(x, y); 78 } 79 catch(NoSuchElementException nsee) { 80 throw new IllegalArgumentException ("Wrong FrameState string: " + nsee); 81 } 82 catch(NumberFormatException nfe) { 83 throw new IllegalArgumentException ("Wrong FrameState string: " + nfe); 84 } 85 } 86 public FrameState(ClipboardHistoryFrame comp) { 87 _dim = comp.getSize(); 88 _loc = comp.getLocation(); 89 } 90 public String toString() { 91 final StringBuilder sb = new StringBuilder (); 92 sb.append((int)_dim.getWidth()); 93 sb.append(' '); 94 sb.append((int)_dim.getHeight()); 95 sb.append(' '); 96 sb.append(_loc.x); 97 sb.append(' '); 98 sb.append(_loc.y); 99 return sb.toString(); 100 } 101 public Dimension getDimension() { return _dim; } 102 public Point getLocation() { return _loc; } 103 } 104 105 106 private ClipboardHistoryModel _chm; 107 108 109 private int _buttonPressed; 110 111 112 private JButton _okButton; 113 114 115 private JButton _cancelButton; 116 117 118 private JList _historyList; 119 120 121 private JTextArea _previewArea; 122 123 124 private FrameState _lastState = null; 125 126 127 private MainFrame _mainFrame; 128 129 130 private CloseAction _okAction, _cancelAction; 131 132 139 public ClipboardHistoryFrame(MainFrame owner, String title, ClipboardHistoryModel chm, 140 CloseAction okAction, CloseAction cancelAction) { 141 super(title); 142 _chm = chm; 143 _mainFrame = owner; 144 _okAction = okAction; 145 _cancelAction = cancelAction; 146 init(); 147 } 148 149 152 public FrameState getFrameState() { return _lastState; } 153 154 157 public void setFrameState(FrameState ds) { 158 _lastState = ds; 159 if (_lastState!=null) { 160 setSize(_lastState.getDimension()); 161 setLocation(_lastState.getLocation()); 162 validate(); 163 } 164 } 165 166 169 public void setFrameState(String s) { 170 try { _lastState = new FrameState(s); } 171 catch(IllegalArgumentException e) { _lastState = null; } 172 if (_lastState!=null) { 173 setSize(_lastState.getDimension()); 174 setLocation(_lastState.getLocation()); 175 validate(); 176 } 177 else { 178 Dimension parentDim = (_mainFrame!=null)?(_mainFrame.getSize()):getToolkit().getScreenSize(); 179 int xs = (int)parentDim.getWidth()/3; 180 int ys = (int)parentDim.getHeight()/4; 181 setSize(Math.max(xs,400), Math.max(ys, 400)); 182 MainFrame.setPopupLoc(this, _mainFrame); 183 } 184 } 185 186 190 public int getButtonPressed() { 191 return _buttonPressed; 192 } 193 194 196 private void init() { 197 addWindowListener(new java.awt.event.WindowAdapter () { 198 public void windowClosing(WindowEvent winEvt) { 199 cancelButtonPressed(); 200 } 201 }); 202 addComponentListener(new java.awt.event.ComponentAdapter () { 203 public void componentResized(ComponentEvent e) { 204 validate(); 205 _historyList.ensureIndexIsVisible(_historyList.getSelectedIndex()); 206 } 207 }); 208 209 JRootPane rootPane = this.getRootPane(); 210 InputMap iMap = rootPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); 211 iMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "escape"); 212 213 ActionMap aMap = rootPane.getActionMap(); 214 aMap.put("escape", new AbstractAction() { 215 public void actionPerformed(ActionEvent e) { 216 cancelButtonPressed(); 217 } 218 }); 219 220 _historyList = new JList(); 221 _historyList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 222 _historyList.addListSelectionListener(new ListSelectionListener() { 223 public void valueChanged(ListSelectionEvent e) { 224 updatePreview(); 225 } 226 }); 227 _historyList.setFont(DrJava.getConfig().getSetting(OptionConstants.FONT_MAIN)); 228 _historyList.setCellRenderer(new DefaultListCellRenderer() { 229 public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { 230 Component c = super.getListCellRendererComponent(list,value,index,isSelected,cellHasFocus); 231 c.setForeground(DrJava.getConfig().getSetting(OptionConstants.DEFINITIONS_NORMAL_COLOR)); 232 return c; 233 } 234 }); 235 _historyList.addFocusListener(new FocusListener() { 236 public void focusGained(FocusEvent e) { 237 } 238 239 public void focusLost(FocusEvent e) { 240 if ((e.getOppositeComponent()!=_previewArea) && 241 (e.getOppositeComponent()!=_okButton) && 242 (e.getOppositeComponent()!=_cancelButton)) { 243 _historyList.requestFocus(); 244 } 245 } 246 }); 247 248 _okButton = new JButton("OK"); 250 _okButton.addActionListener(new ActionListener() { 251 public void actionPerformed(ActionEvent e) { 252 okButtonPressed(); 253 } 254 }); 255 256 _cancelButton = new JButton("Cancel"); 257 _cancelButton.addActionListener(new ActionListener() { 258 public void actionPerformed(ActionEvent e) { 259 cancelButtonPressed(); 260 } 261 }); 262 263 Container contentPane = getContentPane(); 265 266 GridBagLayout layout = new GridBagLayout(); 267 contentPane.setLayout(layout); 268 269 GridBagConstraints c = new GridBagConstraints(); 270 c.anchor = GridBagConstraints.NORTHWEST; 271 c.weightx = 1.0; 272 c.weighty = 0.0; 273 c.gridwidth = GridBagConstraints.REMAINDER; c.insets.top = 2; 275 c.insets.left = 2; 276 c.insets.bottom = 2; 277 c.insets.right = 2; 278 279 c.fill = GridBagConstraints.BOTH; 280 c.weighty = 1.0; 281 contentPane.add(new JScrollPane(_historyList, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, 282 JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED), 283 c); 284 285 _previewArea = new JTextArea(""); 286 _previewArea.setEditable(false); 287 _previewArea.setDragEnabled(false); 288 _previewArea.setEnabled(false); 289 _previewArea.setFont(DrJava.getConfig().getSetting(OptionConstants.FONT_MAIN)); 290 _previewArea.setDisabledTextColor(DrJava.getConfig().getSetting(OptionConstants.DEFINITIONS_NORMAL_COLOR)); 291 c.weighty = 2.0; 292 contentPane.add(new JScrollPane(_previewArea, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, 293 JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED), 294 c); 295 296 c.anchor = GridBagConstraints.SOUTH; 297 298 JPanel buttonPanel = new JPanel(new GridBagLayout()); 299 GridBagConstraints bc = new GridBagConstraints(); 300 bc.insets.left = 2; 301 bc.insets.right = 2; 302 buttonPanel.add(_okButton, bc); 303 buttonPanel.add(_cancelButton, bc); 304 305 c.weighty = 0.0; 306 contentPane.add(buttonPanel, c); 307 308 Dimension parentDim = (_mainFrame!=null)?(_mainFrame.getSize()):getToolkit().getScreenSize(); 309 int xs = (int)parentDim.getWidth()/3; 310 int ys = (int)parentDim.getHeight()/4; 311 setSize(Math.max(xs,400), Math.max(ys, 300)); 312 MainFrame.setPopupLoc(this, _mainFrame); 313 314 updateView(); 315 } 316 317 320 public void setVisible(boolean b) { 321 assert EventQueue.isDispatchThread(); 322 validate(); 323 super.setVisible(b); 324 if (b) { 325 _mainFrame.hourglassOn(); 326 updateView(); 327 _historyList.requestFocus(); 328 } 329 else { 330 _mainFrame.hourglassOff(); 331 _mainFrame.toFront(); 332 } 333 } 334 335 336 private void updateView() { 337 List <String > strs = _chm.getStrings(); 338 ListItem[] arr = new ListItem[strs.size()]; 339 for(int i=0; i<strs.size(); ++i) arr[strs.size()-i-1] = new ListItem(strs.get(i)); 340 _historyList.setListData(arr); 341 if (_historyList.getModel().getSize()>0) { 342 _historyList.setSelectedIndex(0); 343 getRootPane().setDefaultButton(_okButton); 344 _okButton.setEnabled(true); 345 } 346 else { 347 getRootPane().setDefaultButton(_cancelButton); 348 _okButton.setEnabled(false); 349 } 350 updatePreview(); 351 } 352 353 354 private void updatePreview() { 355 String text = ""; 356 if (_historyList.getModel().getSize()>0) { 357 int index = _historyList.getSelectedIndex(); 358 if (index!=-1) { 359 text = ((ListItem)_historyList.getModel().getElementAt(_historyList.getSelectedIndex())).getFull(); 360 } 361 } 362 363 _previewArea.setText(text); 364 _previewArea.setCaretPosition(0); 365 } 366 367 368 private void okButtonPressed() { 369 _lastState = new FrameState(ClipboardHistoryFrame.this); 370 setVisible(false); 371 if (_historyList.getModel().getSize()>0) { 372 _buttonPressed = JOptionPane.OK_OPTION; 373 String s = ((ListItem)_historyList.getModel().getElementAt(_historyList.getSelectedIndex())).getFull(); 374 _chm.put(s); 375 _okAction.apply(s); 376 } 377 else { 378 _buttonPressed = JOptionPane.CANCEL_OPTION; 379 Toolkit.getDefaultToolkit().beep(); 380 _cancelAction.apply(null); 381 } 382 } 383 384 385 private void cancelButtonPressed() { 386 _buttonPressed = JOptionPane.CANCEL_OPTION; 387 _lastState = new FrameState(ClipboardHistoryFrame.this); 388 setVisible(false); 389 _cancelAction.apply(null); 390 } 391 392 393 private static class ListItem { 394 private String full, display; 395 public ListItem(String s) { 396 full = s; 397 int index1 = s.indexOf('\n'); 398 if (index1==-1) index1 = s.length(); 399 int index2 = s.indexOf(System.getProperty("line.separator")); 400 if (index2==-1) index2 = s.length(); 401 display = s.substring(0, Math.min(index1, index2)); 402 } 403 public String getFull() { return full; } 404 public String toString() { return display; } 405 public boolean equals(Object o) { 406 if ((o==null) || !(o instanceof ListItem)) return false; 407 return full.equals(((ListItem)o).full); 408 } 409 } 410 } 411 | Popular Tags |