Mercurial > hg > Applications > tvnjviewer
comparison src/viewer_swing/java/com/glavsoft/viewer/swing/gui/OptionsDialog.java @ 0:daa24f8a557b
TightVNC original
author | YU |
---|---|
date | Thu, 11 Sep 2014 07:30:03 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:daa24f8a557b |
---|---|
1 // Copyright (C) 2010, 2011, 2012, 2013 GlavSoft LLC. | |
2 // All rights reserved. | |
3 // | |
4 //------------------------------------------------------------------------- | |
5 // This file is part of the TightVNC software. Please visit our Web site: | |
6 // | |
7 // http://www.tightvnc.com/ | |
8 // | |
9 // This program is free software; you can redistribute it and/or modify | |
10 // it under the terms of the GNU General Public License as published by | |
11 // the Free Software Foundation; either version 2 of the License, or | |
12 // (at your option) any later version. | |
13 // | |
14 // This program is distributed in the hope that it will be useful, | |
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 // GNU General Public License for more details. | |
18 // | |
19 // You should have received a copy of the GNU General Public License along | |
20 // with this program; if not, write to the Free Software Foundation, Inc., | |
21 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
22 //------------------------------------------------------------------------- | |
23 // | |
24 | |
25 package com.glavsoft.viewer.swing.gui; | |
26 | |
27 import com.glavsoft.rfb.encoding.EncodingType; | |
28 import com.glavsoft.rfb.protocol.LocalPointer; | |
29 import com.glavsoft.rfb.protocol.ProtocolSettings; | |
30 import com.glavsoft.viewer.swing.LocalMouseCursorShape; | |
31 import com.glavsoft.viewer.UiSettings; | |
32 | |
33 import javax.swing.*; | |
34 import java.awt.*; | |
35 import java.awt.event.*; | |
36 import java.util.HashMap; | |
37 import java.util.Map; | |
38 | |
39 /** | |
40 * Options dialog | |
41 */ | |
42 @SuppressWarnings("serial") | |
43 public class OptionsDialog extends JDialog { | |
44 private JSlider jpegQuality; | |
45 private JSlider compressionLevel; | |
46 private JCheckBox viewOnlyCheckBox; | |
47 private ProtocolSettings settings; | |
48 private UiSettings uiSettings; | |
49 private JCheckBox sharedSession; | |
50 | |
51 private RadioButtonSelectedState<LocalPointer> mouseCursorTrackSelected; | |
52 private Map<LocalPointer, JRadioButton> mouseCursorTrackMap; | |
53 private JCheckBox useCompressionLevel; | |
54 private JCheckBox useJpegQuality; | |
55 private JLabel jpegQualityPoorLabel; | |
56 private JLabel jpegQualityBestLabel; | |
57 private JLabel compressionLevelFastLabel; | |
58 private JLabel compressionLevelBestLabel; | |
59 private JCheckBox allowCopyRect; | |
60 private JComboBox encodings; | |
61 private JCheckBox disableClipboardTransfer; | |
62 private JComboBox colorDepth; | |
63 private RadioButtonSelectedState<LocalMouseCursorShape> mouseCursorShapeSelected; | |
64 private HashMap<LocalMouseCursorShape, JRadioButton> mouseCursorShapeMap; | |
65 | |
66 public OptionsDialog(Window owner) { | |
67 super(owner, "Connection Options", ModalityType.DOCUMENT_MODAL); | |
68 final WindowAdapter onClose = new WindowAdapter() { | |
69 @Override | |
70 public void windowClosing(WindowEvent e) { | |
71 setVisible(false); | |
72 } | |
73 }; | |
74 addWindowListener(onClose); | |
75 | |
76 JPanel optionsPane = new JPanel(new GridLayout(0, 2)); | |
77 add(optionsPane, BorderLayout.CENTER); | |
78 | |
79 optionsPane.add(createLeftPane()); | |
80 optionsPane.add(createRightPane()); | |
81 | |
82 addButtons(onClose); | |
83 | |
84 pack(); | |
85 } | |
86 | |
87 public void initControlsFromSettings(ProtocolSettings settings, UiSettings uiSettings, boolean isOnConnect) { | |
88 this.settings = settings; | |
89 this.uiSettings = uiSettings; | |
90 | |
91 viewOnlyCheckBox.setSelected(settings.isViewOnly()); | |
92 | |
93 int i = 0; boolean isNotSetEncoding = true; | |
94 while ( encodings.getItemAt(i) != null) { | |
95 EncodingType item = ((EncodingSelectItem)encodings.getItemAt(i)).type; | |
96 if (item.equals(settings.getPreferredEncoding())) { | |
97 encodings.setSelectedIndex(i); | |
98 isNotSetEncoding = false; | |
99 break; | |
100 } | |
101 ++i; | |
102 } | |
103 if (isNotSetEncoding) { | |
104 encodings.setSelectedItem(0); | |
105 } | |
106 | |
107 sharedSession.setSelected(settings.isShared()); | |
108 sharedSession.setEnabled(isOnConnect); | |
109 | |
110 mouseCursorTrackMap.get(settings.getMouseCursorTrack()).setSelected(true); | |
111 mouseCursorTrackSelected.setSelected(settings.getMouseCursorTrack()); | |
112 mouseCursorShapeMap.get(uiSettings.getMouseCursorShape()).setSelected(true); | |
113 mouseCursorShapeSelected.setSelected(uiSettings.getMouseCursorShape()); | |
114 | |
115 int depth = settings.getColorDepth(); | |
116 i = 0; boolean isNotSet = true; | |
117 while ( colorDepth.getItemAt(i) != null) { | |
118 int itemDepth = ((ColorDepthSelectItem)colorDepth.getItemAt(i)).depth; | |
119 if (itemDepth == depth) { | |
120 colorDepth.setSelectedIndex(i); | |
121 isNotSet = false; | |
122 break; | |
123 } | |
124 ++i; | |
125 } | |
126 if (isNotSet) { | |
127 colorDepth.setSelectedItem(0); | |
128 } | |
129 | |
130 useCompressionLevel.setSelected(settings.getCompressionLevel() > 0); | |
131 compressionLevel.setValue(Math.abs(settings.getCompressionLevel())); | |
132 setCompressionLevelPaneEnable(); | |
133 | |
134 useJpegQuality.setSelected(settings.getJpegQuality() > 0); | |
135 jpegQuality.setValue(Math.abs(settings.getJpegQuality())); | |
136 setJpegQualityPaneEnable(); | |
137 | |
138 allowCopyRect.setSelected(settings.isAllowCopyRect()); | |
139 disableClipboardTransfer.setSelected( ! settings.isAllowClipboardTransfer()); | |
140 } | |
141 | |
142 private void setSettingsFromControls() { | |
143 settings.setViewOnly(viewOnlyCheckBox.isSelected()); | |
144 settings.setPreferredEncoding(((EncodingSelectItem)encodings.getSelectedItem()).type); | |
145 | |
146 settings.setSharedFlag(sharedSession.isSelected()); | |
147 settings.setMouseCursorTrack(mouseCursorTrackSelected.getSelected()); | |
148 uiSettings.setMouseCursorShape(mouseCursorShapeSelected.getSelected()); | |
149 | |
150 settings.setColorDepth(((ColorDepthSelectItem) colorDepth.getSelectedItem()).depth); | |
151 | |
152 settings.setCompressionLevel(useCompressionLevel.isSelected() ? | |
153 compressionLevel.getValue() : | |
154 - Math.abs(settings.getCompressionLevel())); | |
155 settings.setJpegQuality(useJpegQuality.isSelected() ? | |
156 jpegQuality.getValue() : | |
157 - Math.abs(settings.getJpegQuality())); | |
158 settings.setAllowCopyRect(allowCopyRect.isSelected()); | |
159 settings.setAllowClipboardTransfer( ! disableClipboardTransfer.isSelected()); | |
160 settings.fireListeners(); | |
161 } | |
162 | |
163 private Component createLeftPane() { | |
164 Box box = Box.createVerticalBox(); | |
165 box.setAlignmentX(LEFT_ALIGNMENT); | |
166 | |
167 box.add(createEncodingsPanel()); | |
168 | |
169 box.add(Box.createVerticalGlue()); | |
170 return box; | |
171 } | |
172 | |
173 private Component createRightPane() { | |
174 Box box = Box.createVerticalBox(); | |
175 box.setAlignmentX(LEFT_ALIGNMENT); | |
176 | |
177 box.add(createRestrictionsPanel()); | |
178 box.add(createMouseCursorPanel()); | |
179 box.add(createLocalShapePanel()); | |
180 | |
181 sharedSession = new JCheckBox("Request shared session"); | |
182 box.add(new JPanel(new FlowLayout(FlowLayout.LEFT)).add(sharedSession)); | |
183 | |
184 box.add(Box.createVerticalGlue()); | |
185 return box; | |
186 } | |
187 | |
188 private JPanel createRestrictionsPanel() { | |
189 JPanel restrictionsPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); | |
190 restrictionsPanel.setBorder( | |
191 BorderFactory.createTitledBorder( | |
192 BorderFactory.createEtchedBorder(), "Restrictions")); | |
193 | |
194 Box restrictionsBox = Box.createVerticalBox(); | |
195 restrictionsBox.setAlignmentX(LEFT_ALIGNMENT); | |
196 restrictionsPanel.add(restrictionsBox); | |
197 viewOnlyCheckBox = new JCheckBox("View only (inputs ignored)"); | |
198 viewOnlyCheckBox.setAlignmentX(LEFT_ALIGNMENT); | |
199 restrictionsBox.add(viewOnlyCheckBox); | |
200 | |
201 disableClipboardTransfer = new JCheckBox("Disable clipboard transfer"); | |
202 disableClipboardTransfer.setAlignmentX(LEFT_ALIGNMENT); | |
203 restrictionsBox.add(disableClipboardTransfer); | |
204 | |
205 return restrictionsPanel; | |
206 } | |
207 | |
208 private JPanel createEncodingsPanel() { | |
209 JPanel encodingsPanel = new JPanel(); | |
210 encodingsPanel.setAlignmentX(LEFT_ALIGNMENT); | |
211 encodingsPanel.setLayout(new BoxLayout(encodingsPanel, BoxLayout.Y_AXIS)); | |
212 encodingsPanel.setBorder( | |
213 BorderFactory.createTitledBorder( | |
214 BorderFactory.createEtchedBorder(), "Format and Encodings")); | |
215 | |
216 JPanel encPane = new JPanel(new FlowLayout(FlowLayout.LEFT)); | |
217 encPane.setAlignmentX(LEFT_ALIGNMENT); | |
218 encPane.add(new JLabel("Preferred encoding: ")); | |
219 | |
220 encodings = new JComboBox(); | |
221 encodings.addItem(new EncodingSelectItem(EncodingType.TIGHT)); | |
222 encodings.addItem(new EncodingSelectItem(EncodingType.HEXTILE)); | |
223 | |
224 // encodings.addItem(new EncodingSelectItem(EncodingType.RRE)); | |
225 // encodings.addItem(new EncodingSelectItem(EncodingType.ZLIB)); | |
226 | |
227 encodings.addItem(new EncodingSelectItem(EncodingType.ZRLE)); | |
228 encodings.addItem(new EncodingSelectItem(EncodingType.RAW_ENCODING)); | |
229 encPane.add(encodings); | |
230 encodingsPanel.add(encPane); | |
231 | |
232 encodingsPanel.add(createColorDepthPanel()); | |
233 | |
234 addCompressionLevelPane(encodingsPanel); | |
235 addJpegQualityLevelPane(encodingsPanel); | |
236 | |
237 allowCopyRect = new JCheckBox("Allow CopyRect encoding"); | |
238 allowCopyRect.setAlignmentX(LEFT_ALIGNMENT); | |
239 encodingsPanel.add(allowCopyRect); | |
240 | |
241 return encodingsPanel; | |
242 } | |
243 | |
244 private static class EncodingSelectItem { | |
245 final EncodingType type; | |
246 public EncodingSelectItem(EncodingType type) { | |
247 this.type = type; | |
248 } | |
249 @Override | |
250 public String toString() { | |
251 return type.getName(); | |
252 } | |
253 } | |
254 | |
255 private static class ColorDepthSelectItem { | |
256 final int depth; | |
257 final String title; | |
258 public ColorDepthSelectItem(int depth, String title) { | |
259 this.depth = depth; | |
260 this.title = title; | |
261 } | |
262 @Override | |
263 public String toString() { | |
264 return title; | |
265 } | |
266 } | |
267 | |
268 private JPanel createColorDepthPanel() { | |
269 JPanel colorDepthPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); | |
270 colorDepthPanel.setAlignmentX(LEFT_ALIGNMENT); | |
271 colorDepthPanel.add(new JLabel("Color format: ")); | |
272 | |
273 colorDepth = new JComboBox(); | |
274 colorDepth.addItem(new ColorDepthSelectItem(ProtocolSettings.COLOR_DEPTH_SERVER_SETTINGS, | |
275 "Server's default")); | |
276 colorDepth.addItem(new ColorDepthSelectItem(ProtocolSettings.COLOR_DEPTH_24, | |
277 "16 777 216 colors")); | |
278 colorDepth.addItem(new ColorDepthSelectItem(ProtocolSettings.COLOR_DEPTH_16, | |
279 "65 536 colors")); | |
280 colorDepth.addItem(new ColorDepthSelectItem(ProtocolSettings.COLOR_DEPTH_8, | |
281 "256 colors")); | |
282 colorDepth.addItem(new ColorDepthSelectItem(ProtocolSettings.COLOR_DEPTH_6, | |
283 "64 colors")); | |
284 colorDepth.addItem(new ColorDepthSelectItem(ProtocolSettings.COLOR_DEPTH_3, | |
285 "8 colors")); | |
286 | |
287 colorDepthPanel.add(colorDepth); | |
288 colorDepth.addItemListener(new ItemListener() { | |
289 @Override | |
290 public void itemStateChanged(ItemEvent e) { | |
291 setJpegQualityPaneEnable(); | |
292 } | |
293 }); | |
294 return colorDepthPanel; | |
295 } | |
296 | |
297 private void addJpegQualityLevelPane(JPanel encodingsPanel) { | |
298 useJpegQuality = new JCheckBox("Allow JPEG, set quality level:"); | |
299 useJpegQuality.setAlignmentX(LEFT_ALIGNMENT); | |
300 encodingsPanel.add(useJpegQuality); | |
301 | |
302 JPanel jpegQualityPane = new JPanel(); | |
303 jpegQualityPane.setAlignmentX(LEFT_ALIGNMENT); | |
304 jpegQualityPoorLabel = new JLabel("poor"); | |
305 jpegQualityPane.add(jpegQualityPoorLabel); | |
306 jpegQuality = new JSlider(1, 9, 9); | |
307 jpegQualityPane.add(jpegQuality); | |
308 jpegQuality.setPaintTicks(true); | |
309 jpegQuality.setMinorTickSpacing(1); | |
310 jpegQuality.setMajorTickSpacing(1); | |
311 jpegQuality.setPaintLabels(true); | |
312 jpegQuality.setSnapToTicks(true); | |
313 jpegQuality.setFont( | |
314 jpegQuality.getFont().deriveFont((float) 8)); | |
315 jpegQualityBestLabel = new JLabel("best"); | |
316 jpegQualityPane.add(jpegQualityBestLabel); | |
317 encodingsPanel.add(jpegQualityPane); | |
318 | |
319 jpegQualityPoorLabel.setFont(jpegQualityPoorLabel.getFont().deriveFont((float) 10)); | |
320 jpegQualityBestLabel.setFont(jpegQualityBestLabel.getFont().deriveFont((float) 10)); | |
321 | |
322 useJpegQuality.addActionListener(new ActionListener() { | |
323 @Override | |
324 public void actionPerformed(ActionEvent e) { | |
325 setJpegQualityPaneEnable(); | |
326 } | |
327 }); | |
328 } | |
329 | |
330 protected void setJpegQualityPaneEnable() { | |
331 if (useJpegQuality != null && colorDepth != null) { | |
332 int depth = ((ColorDepthSelectItem)colorDepth.getSelectedItem()).depth; | |
333 setEnabled(whetherJpegQualityPaneBeEnabled(depth), useJpegQuality); | |
334 setEnabled(useJpegQuality.isSelected() && whetherJpegQualityPaneBeEnabled(depth), | |
335 jpegQuality, jpegQualityPoorLabel, jpegQualityBestLabel); | |
336 } | |
337 } | |
338 | |
339 private boolean whetherJpegQualityPaneBeEnabled(int depth) { | |
340 return ProtocolSettings.COLOR_DEPTH_16 == depth || | |
341 ProtocolSettings.COLOR_DEPTH_24 == depth || | |
342 ProtocolSettings.COLOR_DEPTH_SERVER_SETTINGS == depth; | |
343 } | |
344 | |
345 private void addCompressionLevelPane(JPanel encodingsPanel) { | |
346 useCompressionLevel = new JCheckBox("Custom compression level:"); | |
347 useCompressionLevel.setAlignmentX(LEFT_ALIGNMENT); | |
348 encodingsPanel.add(useCompressionLevel); | |
349 | |
350 JPanel compressionLevelPane = new JPanel(); | |
351 compressionLevelPane.setAlignmentX(LEFT_ALIGNMENT); | |
352 compressionLevelFastLabel = new JLabel("fast"); | |
353 compressionLevelPane.add(compressionLevelFastLabel); | |
354 compressionLevel = new JSlider(1, 9, 1); | |
355 compressionLevelPane.add(compressionLevel); | |
356 compressionLevel.setPaintTicks(true); | |
357 compressionLevel.setMinorTickSpacing(1); | |
358 compressionLevel.setMajorTickSpacing(1); | |
359 compressionLevel.setPaintLabels(true); | |
360 compressionLevel.setSnapToTicks(true); | |
361 compressionLevel.setFont(compressionLevel.getFont().deriveFont((float) 8)); | |
362 compressionLevelBestLabel = new JLabel("best"); | |
363 compressionLevelPane.add(compressionLevelBestLabel); | |
364 encodingsPanel.add(compressionLevelPane); | |
365 | |
366 compressionLevelFastLabel.setFont(compressionLevelFastLabel.getFont().deriveFont((float) 10)); | |
367 compressionLevelBestLabel.setFont(compressionLevelBestLabel.getFont().deriveFont((float) 10)); | |
368 | |
369 useCompressionLevel.addActionListener(new ActionListener() { | |
370 @Override | |
371 public void actionPerformed(ActionEvent e) { | |
372 setEnabled(useCompressionLevel.isSelected(), | |
373 compressionLevel, compressionLevelFastLabel, compressionLevelBestLabel); | |
374 } | |
375 }); | |
376 setCompressionLevelPaneEnable(); | |
377 } | |
378 | |
379 protected void setCompressionLevelPaneEnable() { | |
380 setEnabled(useCompressionLevel.isSelected(), | |
381 compressionLevel, compressionLevelFastLabel, compressionLevelBestLabel); | |
382 } | |
383 private void setEnabled(boolean isEnabled, JComponent ... comp) { | |
384 for (JComponent c : comp) { | |
385 c.setEnabled(isEnabled); | |
386 } | |
387 } | |
388 | |
389 private JPanel createLocalShapePanel() { | |
390 JPanel localCursorShapePanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); | |
391 // localCursorShapePanel.setLayout(new BoxLayout(localCursorShapePanel, BoxLayout.Y_AXIS)); | |
392 localCursorShapePanel.setBorder( | |
393 BorderFactory.createTitledBorder( | |
394 BorderFactory.createEtchedBorder(), "Local cursor shape")); | |
395 Box localCursorShapeBox = Box.createVerticalBox(); | |
396 localCursorShapePanel.add(localCursorShapeBox); | |
397 | |
398 ButtonGroup mouseCursorShapeTrackGroup = new ButtonGroup(); | |
399 mouseCursorShapeSelected = new RadioButtonSelectedState<LocalMouseCursorShape>(); | |
400 mouseCursorShapeMap = new HashMap<LocalMouseCursorShape, JRadioButton>(); | |
401 | |
402 addRadioButton("Dot cursor", LocalMouseCursorShape.DOT, | |
403 mouseCursorShapeSelected, mouseCursorShapeMap, localCursorShapeBox, | |
404 mouseCursorShapeTrackGroup); | |
405 | |
406 addRadioButton("Small dot cursor", LocalMouseCursorShape.SMALL_DOT, | |
407 mouseCursorShapeSelected, mouseCursorShapeMap, localCursorShapeBox, | |
408 mouseCursorShapeTrackGroup); | |
409 | |
410 addRadioButton("System default cursor", LocalMouseCursorShape.SYSTEM_DEFAULT, | |
411 mouseCursorShapeSelected, mouseCursorShapeMap, localCursorShapeBox, | |
412 mouseCursorShapeTrackGroup); | |
413 | |
414 addRadioButton("No local cursor", LocalMouseCursorShape.NO_CURSOR, | |
415 mouseCursorShapeSelected, mouseCursorShapeMap, localCursorShapeBox, | |
416 mouseCursorShapeTrackGroup); | |
417 | |
418 return localCursorShapePanel; | |
419 } | |
420 | |
421 private JPanel createMouseCursorPanel() { | |
422 JPanel mouseCursorPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); | |
423 mouseCursorPanel.setBorder( | |
424 BorderFactory.createTitledBorder( | |
425 BorderFactory.createEtchedBorder(), "Mouse Cursor")); | |
426 Box mouseCursorBox = Box.createVerticalBox(); | |
427 mouseCursorPanel.add(mouseCursorBox); | |
428 | |
429 ButtonGroup mouseCursorTrackGroup = new ButtonGroup(); | |
430 | |
431 mouseCursorTrackSelected = new RadioButtonSelectedState<LocalPointer>(); | |
432 mouseCursorTrackMap = new HashMap<LocalPointer, JRadioButton>(); | |
433 | |
434 addRadioButton("Track remote cursor locally", LocalPointer.ON, | |
435 mouseCursorTrackSelected, mouseCursorTrackMap, mouseCursorBox, | |
436 mouseCursorTrackGroup); | |
437 addRadioButton("Let remote server deal with mouse cursor", | |
438 LocalPointer.OFF, | |
439 mouseCursorTrackSelected, mouseCursorTrackMap, mouseCursorBox, | |
440 mouseCursorTrackGroup); | |
441 addRadioButton("Don't show remote cursor", LocalPointer.HIDE, | |
442 mouseCursorTrackSelected, mouseCursorTrackMap, mouseCursorBox, | |
443 mouseCursorTrackGroup); | |
444 return mouseCursorPanel; | |
445 } | |
446 | |
447 private static class RadioButtonSelectedState<T> { | |
448 private T state; | |
449 | |
450 public void setSelected(T state) { | |
451 this.state = state; | |
452 } | |
453 | |
454 public T getSelected() { | |
455 return state; | |
456 } | |
457 | |
458 } | |
459 | |
460 private <T> JRadioButton addRadioButton(String text, final T state, | |
461 final RadioButtonSelectedState<T> selected, | |
462 Map<T, JRadioButton> state2buttonMap, JComponent component, ButtonGroup group) { | |
463 JRadioButton radio = new JRadioButton(text); | |
464 radio.addActionListener(new ActionListener() { | |
465 @Override | |
466 public void actionPerformed(ActionEvent e) { | |
467 selected.setSelected(state); | |
468 } | |
469 }); | |
470 component.add(radio); | |
471 group.add(radio); | |
472 state2buttonMap.put(state, radio); | |
473 return radio; | |
474 } | |
475 | |
476 private void addButtons(final WindowListener onClose) { | |
477 JPanel buttonPanel = new JPanel(); | |
478 JButton loginButton = new JButton("Ok"); | |
479 buttonPanel.add(loginButton); | |
480 loginButton.addActionListener(new ActionListener() { | |
481 @Override | |
482 public void actionPerformed(ActionEvent e) { | |
483 setSettingsFromControls(); | |
484 setVisible(false); | |
485 } | |
486 }); | |
487 | |
488 JButton closeButton = new JButton("Cancel"); | |
489 buttonPanel.add(closeButton); | |
490 closeButton.addActionListener(new ActionListener() { | |
491 @Override | |
492 public void actionPerformed(ActionEvent e) { | |
493 onClose.windowClosing(null); | |
494 } | |
495 }); | |
496 add(buttonPanel, BorderLayout.SOUTH); | |
497 } | |
498 | |
499 } |