Mercurial > hg > Applications > tvnjviewer
comparison src/viewer_swing/java/com/glavsoft/viewer/swing/gui/ConnectionView.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.viewer.mvp.View; | |
28 import com.glavsoft.viewer.swing.ConnectionParams; | |
29 import com.glavsoft.viewer.ConnectionPresenter; | |
30 import com.glavsoft.viewer.swing.Utils; | |
31 import com.glavsoft.viewer.swing.WrongParameterException; | |
32 | |
33 import javax.swing.*; | |
34 import javax.swing.border.Border; | |
35 import javax.swing.border.EmptyBorder; | |
36 import java.awt.*; | |
37 import java.awt.event.*; | |
38 import java.util.LinkedList; | |
39 | |
40 /** | |
41 * Dialog window for connection parameters get from. | |
42 */ | |
43 @SuppressWarnings("serial") | |
44 public class ConnectionView extends JPanel implements View { | |
45 private static final int PADDING = 4; | |
46 public static final int COLUMNS_HOST_FIELD = 30; | |
47 public static final int COLUMNS_PORT_USER_FIELD = 13; | |
48 public static final String CLOSE = "Close"; | |
49 public static final String CANCEL = "Cancel"; | |
50 private WindowListener appWindowListener; | |
51 private final boolean hasSshSupport; | |
52 private final JTextField serverPortField; | |
53 private JCheckBox useSshTunnelingCheckbox; | |
54 private final JComboBox serverNameCombo; | |
55 private JTextField sshUserField; | |
56 private JTextField sshHostField; | |
57 private JTextField sshPortField; | |
58 private JLabel sshUserLabel; | |
59 private JLabel sshHostLabel; | |
60 private JLabel sshPortLabel; | |
61 private JLabel ssUserWarningLabel; | |
62 private JButton clearHistoryButton; | |
63 private JButton connectButton; | |
64 private final JFrame view; | |
65 private final ConnectionPresenter presenter; | |
66 private final StatusBar statusBar; | |
67 private boolean connectionInProgress; | |
68 private JButton closeCancelButton; | |
69 | |
70 public ConnectionView(final WindowListener appWindowListener, | |
71 final ConnectionPresenter presenter, boolean useSsh) { | |
72 this.appWindowListener = appWindowListener; | |
73 this.hasSshSupport = useSsh; | |
74 this.presenter = presenter; | |
75 | |
76 setLayout(new BorderLayout(0, 0)); | |
77 JPanel optionsPane = new JPanel(new GridBagLayout()); | |
78 add(optionsPane, BorderLayout.CENTER); | |
79 optionsPane.setBorder(new EmptyBorder(PADDING, PADDING, PADDING, PADDING)); | |
80 | |
81 setLayout(new GridBagLayout()); | |
82 | |
83 int gridRow = 0; | |
84 | |
85 serverNameCombo = new JComboBox(); | |
86 initConnectionsHistoryCombo(); | |
87 serverNameCombo.addItemListener(new ItemListener() { | |
88 @Override | |
89 public void itemStateChanged(ItemEvent e) { | |
90 Object item = serverNameCombo.getSelectedItem(); | |
91 if (item instanceof ConnectionParams) { | |
92 presenter.populateFromHistoryItem((ConnectionParams) item); | |
93 } | |
94 } | |
95 }); | |
96 | |
97 addFormFieldRow(optionsPane, gridRow, new JLabel("Remote Host:"), serverNameCombo, true); | |
98 ++gridRow; | |
99 | |
100 serverPortField = new JTextField(COLUMNS_PORT_USER_FIELD); | |
101 | |
102 addFormFieldRow(optionsPane, gridRow, new JLabel("Port:"), serverPortField, false); | |
103 ++gridRow; | |
104 | |
105 if (this.hasSshSupport) { | |
106 gridRow = createSshOptions(optionsPane, gridRow); | |
107 } | |
108 | |
109 JPanel buttonPanel = createButtons(); | |
110 | |
111 GridBagConstraints cButtons = new GridBagConstraints(); | |
112 cButtons.gridx = 0; cButtons.gridy = gridRow; | |
113 cButtons.weightx = 100; cButtons.weighty = 100; | |
114 cButtons.gridwidth = 2; cButtons.gridheight = 1; | |
115 optionsPane.add(buttonPanel, cButtons); | |
116 | |
117 view = new JFrame("New TightVNC Connection"); | |
118 view.add(this, BorderLayout.CENTER); | |
119 statusBar = new StatusBar(); | |
120 view.add(statusBar, BorderLayout.SOUTH); | |
121 | |
122 view.getRootPane().setDefaultButton(connectButton); | |
123 view.addWindowListener(appWindowListener); | |
124 // view.setResizable(false); | |
125 Utils.decorateDialog(view); | |
126 Utils.centerWindow(view); | |
127 } | |
128 | |
129 private void initConnectionsHistoryCombo() { | |
130 serverNameCombo.setEditable(true); | |
131 | |
132 new AutoCompletionComboEditorDocument(serverNameCombo); // use autocompletion feature for ComboBox | |
133 serverNameCombo.setRenderer(new HostnameComboboxRenderer()); | |
134 | |
135 ConnectionParams prototypeDisplayValue = new ConnectionParams(); | |
136 prototypeDisplayValue.hostName = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXŠ§Š§"; | |
137 serverNameCombo.setPrototypeDisplayValue(prototypeDisplayValue); | |
138 } | |
139 | |
140 public void showReconnectDialog(final String title, final String message) { | |
141 JOptionPane reconnectPane = new JOptionPane(message + "\nTry another connection?", | |
142 JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_OPTION); | |
143 final JDialog reconnectDialog = reconnectPane.createDialog(ConnectionView.this, title); | |
144 Utils.decorateDialog(reconnectDialog); | |
145 reconnectDialog.setVisible(true); | |
146 if (reconnectPane.getValue() == null || | |
147 (Integer)reconnectPane.getValue() == JOptionPane.NO_OPTION) { | |
148 presenter.setNeedReconnection(false); | |
149 closeView(); | |
150 view.dispose(); | |
151 closeApp(); | |
152 } else { | |
153 // TODO return when allowInteractive, close window otherwise | |
154 // forceConnectionDialog = allowInteractive; | |
155 } | |
156 } | |
157 | |
158 public void setConnectionInProgress(boolean enable) { | |
159 if (enable) { | |
160 connectionInProgress = true; | |
161 closeCancelButton.setText(CANCEL); | |
162 connectButton.setEnabled(false); | |
163 } else { | |
164 connectionInProgress = false; | |
165 closeCancelButton.setText(CLOSE); | |
166 connectButton.setEnabled(true); | |
167 } | |
168 } | |
169 | |
170 private JPanel createButtons() { | |
171 JPanel buttonPanel = new JPanel(); | |
172 | |
173 closeCancelButton = new JButton(CLOSE); | |
174 closeCancelButton.addActionListener(new ActionListener() { | |
175 @Override | |
176 public void actionPerformed(ActionEvent e) { | |
177 if (connectionInProgress) { | |
178 presenter.cancelConnection(); | |
179 setConnectionInProgress(false); | |
180 } else { | |
181 closeView(); | |
182 closeApp(); | |
183 } | |
184 } | |
185 }); | |
186 | |
187 connectButton = new JButton("Connect"); | |
188 buttonPanel.add(connectButton); | |
189 connectButton.addActionListener(new ActionListener() { | |
190 @Override | |
191 public void actionPerformed(ActionEvent e) { | |
192 setMessage(""); | |
193 Object item = serverNameCombo.getSelectedItem(); | |
194 String hostName = item instanceof ConnectionParams ? | |
195 ((ConnectionParams) item).hostName : | |
196 (String) item; | |
197 try { | |
198 setConnectionInProgress(true); | |
199 presenter.submitConnection(hostName); | |
200 } catch (WrongParameterException wpe) { | |
201 if (ConnectionPresenter.PROPERTY_HOST_NAME.equals(wpe.getPropertyName())) { | |
202 serverNameCombo.requestFocusInWindow(); | |
203 } | |
204 if (ConnectionPresenter.PROPERTY_RFB_PORT_NUMBER.equals(wpe.getPropertyName())) { | |
205 serverPortField.requestFocusInWindow(); | |
206 } | |
207 showConnectionErrorDialog(wpe.getMessage()); | |
208 setConnectionInProgress(false); | |
209 } | |
210 } | |
211 }); | |
212 | |
213 JButton optionsButton = new JButton("Options..."); | |
214 buttonPanel.add(optionsButton); | |
215 optionsButton.addActionListener(new ActionListener() { | |
216 @Override | |
217 public void actionPerformed(ActionEvent e) { | |
218 OptionsDialog od = new OptionsDialog(view); | |
219 od.initControlsFromSettings(presenter.getRfbSettings(), presenter.getUiSettings(), true); | |
220 od.setVisible(true); | |
221 view.toFront(); | |
222 } | |
223 }); | |
224 | |
225 clearHistoryButton = new JButton("Clear history"); | |
226 clearHistoryButton.setToolTipText("Clear connections history"); | |
227 buttonPanel.add(clearHistoryButton); | |
228 clearHistoryButton.addActionListener(new ActionListener() { | |
229 @Override | |
230 public void actionPerformed(ActionEvent e) { | |
231 presenter.clearHistory(); | |
232 clearHistoryButton.setEnabled(false); | |
233 view.toFront(); | |
234 } | |
235 }); | |
236 buttonPanel.add(closeCancelButton); | |
237 return buttonPanel; | |
238 } | |
239 | |
240 private int createSshOptions(JPanel pane, int gridRow) { | |
241 GridBagConstraints cUseSshTunnelLabel = new GridBagConstraints(); | |
242 cUseSshTunnelLabel.gridx = 0; cUseSshTunnelLabel.gridy = gridRow; | |
243 cUseSshTunnelLabel.weightx = 100; cUseSshTunnelLabel.weighty = 100; | |
244 cUseSshTunnelLabel.gridwidth = 2; cUseSshTunnelLabel.gridheight = 1; | |
245 cUseSshTunnelLabel.anchor = GridBagConstraints.LINE_START; | |
246 cUseSshTunnelLabel.ipadx = PADDING; | |
247 cUseSshTunnelLabel.ipady = 10; | |
248 useSshTunnelingCheckbox = new JCheckBox("Use SSH tunneling"); | |
249 pane.add(useSshTunnelingCheckbox, cUseSshTunnelLabel); | |
250 ++gridRow; | |
251 | |
252 sshHostLabel = new JLabel("SSH Server:"); | |
253 sshHostField = new JTextField(COLUMNS_HOST_FIELD); | |
254 addFormFieldRow(pane, gridRow, sshHostLabel, sshHostField, true); | |
255 ++gridRow; | |
256 | |
257 sshPortLabel = new JLabel("SSH Port:"); | |
258 sshPortField = new JTextField(COLUMNS_PORT_USER_FIELD); | |
259 addFormFieldRow(pane, gridRow, sshPortLabel, sshPortField, false); | |
260 ++gridRow; | |
261 | |
262 sshUserLabel = new JLabel("SSH User:"); | |
263 sshUserField = new JTextField(COLUMNS_PORT_USER_FIELD); | |
264 JPanel sshUserFieldPane = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); | |
265 sshUserFieldPane.add(sshUserField); | |
266 ssUserWarningLabel = new JLabel(" (will be asked if not specified)"); | |
267 sshUserFieldPane.add(ssUserWarningLabel); | |
268 addFormFieldRow(pane, gridRow, sshUserLabel, sshUserFieldPane, false); | |
269 ++gridRow; | |
270 | |
271 useSshTunnelingCheckbox.addItemListener(new ItemListener() { | |
272 @Override | |
273 public void itemStateChanged(ItemEvent e) { | |
274 final boolean useSsh = e.getStateChange() == ItemEvent.SELECTED; | |
275 setUseSsh(useSsh); | |
276 presenter.setUseSsh(useSsh); | |
277 } | |
278 }); | |
279 | |
280 return gridRow; | |
281 } | |
282 | |
283 private void addFormFieldRow(JPanel pane, int gridRow, JLabel label, JComponent field, boolean fill) { | |
284 GridBagConstraints cLabel = new GridBagConstraints(); | |
285 cLabel.gridx = 0; cLabel.gridy = gridRow; | |
286 cLabel.weightx = 0; | |
287 cLabel.weighty = 100; | |
288 cLabel.gridwidth = cLabel.gridheight = 1; | |
289 cLabel.anchor = GridBagConstraints.LINE_END; | |
290 cLabel.ipadx = PADDING; | |
291 cLabel.ipady = 10; | |
292 pane.add(label, cLabel); | |
293 | |
294 GridBagConstraints cField = new GridBagConstraints(); | |
295 cField.gridx = 1; cField.gridy = gridRow; | |
296 cField.weightx = 0; cField.weighty = 100; | |
297 cField.gridwidth = cField.gridheight = 1; | |
298 cField.anchor = GridBagConstraints.LINE_START; | |
299 if (fill) cField.fill = GridBagConstraints.HORIZONTAL; | |
300 pane.add(field, cField); | |
301 } | |
302 | |
303 /* | |
304 * Implicit View interface | |
305 */ | |
306 public void setMessage(String message) { | |
307 statusBar.setMessage(message); | |
308 } | |
309 | |
310 @SuppressWarnings("UnusedDeclaration") | |
311 public void setPortNumber(int portNumber) { | |
312 serverPortField.setText(String.valueOf(portNumber)); | |
313 } | |
314 | |
315 @SuppressWarnings("UnusedDeclaration") | |
316 public String getPortNumber() { | |
317 return serverPortField.getText(); | |
318 } | |
319 | |
320 @SuppressWarnings("UnusedDeclaration") | |
321 public void setSshHostName(String sshHostName) { | |
322 if (hasSshSupport) { | |
323 sshHostField.setText(sshHostName); | |
324 } | |
325 } | |
326 | |
327 @SuppressWarnings("UnusedDeclaration") | |
328 public String getSshHostName() { | |
329 if (hasSshSupport) { | |
330 return sshHostField.getText(); | |
331 } else { return ""; } | |
332 } | |
333 | |
334 @SuppressWarnings("UnusedDeclaration") | |
335 public void setSshPortNumber(int sshPortNumber) { | |
336 if (hasSshSupport) { | |
337 sshPortField.setText(String.valueOf(sshPortNumber)); | |
338 } | |
339 } | |
340 | |
341 @SuppressWarnings("UnusedDeclaration") | |
342 public String getSshPortNumber() { | |
343 if (hasSshSupport) { | |
344 return sshPortField.getText(); | |
345 } else { return ""; } | |
346 } | |
347 | |
348 @SuppressWarnings("UnusedDeclaration") | |
349 public void setSshUserName(String sshUserName) { | |
350 if (hasSshSupport) { | |
351 sshUserField.setText(sshUserName); | |
352 } | |
353 } | |
354 | |
355 @SuppressWarnings("UnusedDeclaration") | |
356 public String getSshUserName() { | |
357 if (hasSshSupport) { | |
358 return sshUserField.getText(); | |
359 } else { return ""; } | |
360 } | |
361 | |
362 @SuppressWarnings("UnusedDeclaration") | |
363 public void setUseSsh(boolean useSsh) { | |
364 if (hasSshSupport) { | |
365 useSshTunnelingCheckbox.setSelected(useSsh); | |
366 sshUserLabel.setEnabled(useSsh); | |
367 sshUserField.setEnabled(useSsh); | |
368 ssUserWarningLabel.setEnabled(useSsh); | |
369 sshHostLabel.setEnabled(useSsh); | |
370 sshHostField.setEnabled(useSsh); | |
371 sshPortLabel.setEnabled(useSsh); | |
372 sshPortField.setEnabled(useSsh); | |
373 } | |
374 } | |
375 | |
376 @SuppressWarnings("UnusedDeclaration") | |
377 public boolean getUseSsh() { | |
378 return useSshTunnelingCheckbox.isSelected(); | |
379 } | |
380 | |
381 @SuppressWarnings("UnusedDeclaration") | |
382 public void setConnectionsList(LinkedList<ConnectionParams> connections) { | |
383 serverNameCombo.removeAllItems(); | |
384 for (ConnectionParams cp : connections) { | |
385 serverNameCombo.addItem(new ConnectionParams(cp)); | |
386 } | |
387 serverNameCombo.setPopupVisible(false); | |
388 clearHistoryButton.setEnabled(serverNameCombo.getItemCount() > 0); | |
389 } | |
390 /* | |
391 * /Implicit View interface | |
392 */ | |
393 | |
394 @Override | |
395 public void showView() { | |
396 view.setVisible(true); | |
397 view.toFront(); | |
398 view.repaint(); | |
399 } | |
400 | |
401 @Override | |
402 public void closeView() { | |
403 view.setVisible(false); | |
404 } | |
405 | |
406 public void showConnectionErrorDialog(final String message) { | |
407 JOptionPane errorPane = new JOptionPane(message, JOptionPane.ERROR_MESSAGE); | |
408 final JDialog errorDialog = errorPane.createDialog(view, "Connection error"); | |
409 Utils.decorateDialog(errorDialog); | |
410 errorDialog.setVisible(true); | |
411 if ( ! presenter.allowInteractive()) { | |
412 presenter.cancelConnection(); | |
413 closeApp(); | |
414 } | |
415 } | |
416 | |
417 public void closeApp() { | |
418 appWindowListener.windowClosing(null); | |
419 } | |
420 | |
421 public JFrame getFrame() { | |
422 return view; | |
423 } | |
424 | |
425 } | |
426 | |
427 class StatusBar extends JPanel { | |
428 | |
429 private JLabel messageLabel; | |
430 | |
431 public StatusBar() { | |
432 setLayout(new BorderLayout()); | |
433 setPreferredSize(new Dimension(10, 23)); | |
434 | |
435 messageLabel = new JLabel(""); | |
436 final Font f = messageLabel.getFont(); | |
437 messageLabel.setFont(f.deriveFont(f.getStyle() & ~Font.BOLD)); | |
438 add(messageLabel, BorderLayout.CENTER); | |
439 | |
440 JPanel rightPanel = new JPanel(new BorderLayout()); | |
441 rightPanel.setOpaque(false); | |
442 | |
443 | |
444 add(rightPanel, BorderLayout.EAST); | |
445 setBorder(new Border() { | |
446 @Override | |
447 public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { | |
448 Color oldColor = g.getColor(); | |
449 g.translate(x, y); | |
450 g.setColor(c.getBackground().darker()); | |
451 g.drawLine(0, 0, width -1, 0); | |
452 g.setColor(c.getBackground().brighter()); | |
453 g.drawLine(0, 1, width -1, 1); | |
454 g.translate(-x, -y); | |
455 g.setColor(oldColor); | |
456 } | |
457 @Override | |
458 public Insets getBorderInsets(Component c) { | |
459 return new Insets(2, 2, 2, 2); | |
460 } | |
461 @Override | |
462 public boolean isBorderOpaque() { | |
463 return false; | |
464 } | |
465 }); | |
466 } | |
467 | |
468 public void setMessage(String message) { | |
469 messageLabel.setText(message); | |
470 } | |
471 } |