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