/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
* Copyright (C) 2011-2016 Brian P. Hinz
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*/
package com.tigervnc.vncviewer;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.lang.reflect.*;
import java.text.Format;
import java.text.NumberFormat;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.filechooser.*;
import javax.swing.UIManager.*;
import javax.swing.text.*;
import java.util.*;
import java.util.List;
import java.util.Map.Entry;
import java.util.prefs.*;
import com.tigervnc.rfb.*;
import static java.awt.GridBagConstraints.BOTH;
import static java.awt.GridBagConstraints.CENTER;
import static java.awt.GridBagConstraints.HORIZONTAL;
import static java.awt.GridBagConstraints.LINE_END;
import static java.awt.GridBagConstraints.LINE_START;
import static java.awt.GridBagConstraints.PAGE_START;
import static java.awt.GridBagConstraints.NONE;
import static java.awt.GridBagConstraints.RELATIVE;
import static java.awt.GridBagConstraints.REMAINDER;
import static java.awt.GridBagConstraints.VERTICAL;
import static com.tigervnc.vncviewer.Parameters.*;
class OptionsDialog extends Dialog {
private class IntegerDocument extends PlainDocument {
private int limit;
public IntegerDocument(int max) {
super();
limit = max;
}
public void insertString(int offset, String str, AttributeSet a)
throws BadLocationException {
if (str == null || !str.matches("^[0-9]+$")) return;
if ((getLength() + str.length()) > limit)
Toolkit.getDefaultToolkit().beep();
else
super.insertString(offset, str, a);
}
}
private class IntegerTextField extends JFormattedTextField {
public IntegerTextField(int digits) {
super();
setDocument(new IntegerDocument(digits));
Font f = getFont();
String template = String.format("%0"+digits+"d", 0);
int w = getFontMetrics(f).stringWidth(template) +
getMargin().left + getMargin().right +
getInsets().left + getInsets().right;
int h = getPreferredSize().height;
setPreferredSize(new Dimension(w, h));
}
@Override
protected void processFocusEvent(final FocusEvent e) {
if (e.isTemporary())
return;
if (e.getID() == FocusEvent.FOCUS_LOST)
if (getText() == null || getText().isEmpty())
setValue(null);
super.processFocusEvent(e);
}
}
private static Map<Object, String> callbacks = new HashMap<Object, String>();
/* Compression */
JCheckBox autoselectCheckbox;
ButtonGroup encodingGroup;
JRadioButton tightButton;
JRadioButton zrleButton;
JRadioButton hextileButton;
JRadioButton rawButton;
ButtonGroup colorlevelGroup;
JRadioButton fullcolorButton;
JRadioButton mediumcolorButton;
JRadioButton lowcolorButton;
JRadioButton verylowcolorButton;
JCheckBox compressionCheckbox;
JCheckBox jpegCheckbox;
JComboBox compressionInput;
JComboBox jpegInput;
/* Security */
JCheckBox encNoneCheckbox;
JCheckBox encTLSCheckbox;
JCheckBox encX509Checkbox;
JTextField caInput;
JTextField crlInput;
JButton caChooser;
JButton crlChooser;
JCheckBox authNoneCheckbox;
JCheckBox authVncCheckbox;
JCheckBox authPlainCheckbox;
JCheckBox authIdentCheckbox;
JCheckBox sendLocalUsernameCheckbox;
/* Input */
JCheckBox viewOnlyCheckbox;
JCheckBox acceptClipboardCheckbox;
JCheckBox sendClipboardCheckbox;
JComboBox menuKeyChoice;
/* Screen */
JCheckBox desktopSizeCheckbox;
JTextField desktopWidthInput;
JTextField desktopHeightInput;
ButtonGroup sizingGroup;
JRadioButton remoteResizeButton;
JRadioButton remoteScaleButton;
JComboBox scalingFactorInput;
JCheckBox fullScreenCheckbox;
JCheckBox fullScreenAllMonitorsCheckbox;
/* Misc. */
JCheckBox sharedCheckbox;
JCheckBox dotWhenNoCursorCheckbox;
JCheckBox acceptBellCheckbox;
/* SSH */
JCheckBox tunnelCheckbox;
JCheckBox viaCheckbox;
JTextField viaUserInput;
JTextField viaHostInput;
JTextField viaPortInput;
JCheckBox extSSHCheckbox;
JTextField sshClientInput;
JButton sshClientChooser;
JRadioButton sshArgsDefaultButton;
JRadioButton sshArgsCustomButton;
JTextField sshArgsInput;
JTextField sshConfigInput;
JTextField sshKeyFileInput;
JButton sshConfigChooser;
JButton sshKeyFileChooser;
@SuppressWarnings({"rawtypes","unchecked"})
public OptionsDialog() {
super(true);
setTitle("VNC Viewer Options");
setResizable(false);
getContentPane().setLayout(
new BoxLayout(getContentPane(), BoxLayout.PAGE_AXIS));
JTabbedPane tabPane = new JTabbedPane();
tabPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
encodingGroup = new ButtonGroup();
colorlevelGroup = new ButtonGroup();
// tabPane
tabPane.addTab("Compression", createCompressionPanel());
tabPane.addTab("Security", createSecurityPanel());
tabPane.addTab("Input", createInputPanel());
tabPane.addTab("Screen", createScreenPanel());
tabPane.addTab("Misc", createMiscPanel());
tabPane.addTab("SSH", createSshPanel());
tabPane.setBorder(BorderFactory.createEmptyBorder());
// Resize the tabPane if necessary to prevent scrolling
int minWidth = 0;
Object tpi = UIManager.get("TabbedPane:TabbedPaneTabArea.contentMargins");
if (tpi != null)
minWidth += ((Insets)tpi).left + ((Insets)tpi).right;
for (int i = 0; i < tabPane.getTabCount(); i++)
minWidth += tabPane.getBoundsAt(i).width;
int minHeight = tabPane.getPreferredSize().height;
if (tabPane.getPreferredSize().width < minWidth)
tabPane.setPreferredSize(new Dimension(minWidth, minHeight));
// button pane
JButton okButton = new JButton("OK \u21B5");
okButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
storeOptions();
endDialog();
}
});
JButton cancelButton = new JButton("Cancel");
cancelButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
endDialog();
}
});
JPanel buttonPane = new JPanel(new GridLayout(1, 5, 10, 10));
buttonPane.setBorder(BorderFactory.createEmptyBorder(10, 5, 5, 5));
buttonPane.add(Box.createRigidArea(new Dimension()));
buttonPane.add(Box.createRigidArea(new Dimension()));
buttonPane.add(Box.createRigidArea(new Dimension()));
buttonPane.add(cancelButton);
buttonPane.add(okButton);
this.add(tabPane);
this.add(buttonPane);
addListeners(this);
pack();
}
public static void showDialog(Container c) {
OptionsDialog dialog = new OptionsDialog();
dialog.show(c);
}
public void show(Container c) {
loadOptions();
super.showDialog(c);
}
public static void addCallback(String cb, Object obj)
{
callbacks.put(obj, cb);
}
public static void removeCallback(Object obj)
{
callbacks.remove(obj);
}
public void endDialog() {
super.endDialog();
// Making a new dialog is so cheap that it's not worth keeping
this.dispose();
}
public void setEmbeddedFeatures(boolean s) {
fullScreenCheckbox.setEnabled(s);
fullScreenAllMonitorsCheckbox.setEnabled(s);
scalingFactorInput.setEnabled(s);
Enumeration<AbstractButton> e = sizingGroup.getElements();
while (e.hasMoreElements())
e.nextElement().setEnabled(s);
}
private void loadOptions()
{
/* Compression */
autoselectCheckbox.setSelected(autoSelect.getValue());
int encNum = Encodings.encodingNum(preferredEncoding.getValueStr());
switch (encNum) {
case Encodings.encodingTight:
tightButton.setSelected(true);
break;
case Encodings.encodingZRLE:
zrleButton.setSelected(true);
break;
case Encodings.encodingHextile:
hextileButton.setSelected(true);
break;
case Encodings.encodingRaw:
rawButton.setSelected(true);
break;
}
if (fullColor.getValue())
fullcolorButton.setSelected(true);
else {
switch (lowColorLevel.getValue()) {
case 0:
verylowcolorButton.setSelected(true);
break;
case 1:
lowcolorButton.setSelected(true);
break;
case 2:
mediumcolorButton.setSelected(true);
break;
}
}
int digit = 0;
compressionCheckbox.setSelected(customCompressLevel.getValue());
jpegCheckbox.setSelected(!noJpeg.getValue());
digit = 0 + compressLevel.getValue();
compressionInput.setSelectedItem(digit);
digit = 0 + qualityLevel.getValue();
jpegInput.setSelectedItem(digit);
handleAutoselect();
handleCompression();
handleJpeg();
/* Security */
Security security = new Security(SecurityClient.secTypes);
List<Integer> secTypes;
Iterator<Integer> iter;
List<Integer> secTypesExt;
Iterator<Integer> iterExt;
encNoneCheckbox.setSelected(false);
encTLSCheckbox.setSelected(false);
encX509Checkbox.setSelected(false);
authNoneCheckbox.setSelected(false);
authVncCheckbox.setSelected(false);
authPlainCheckbox.setSelected(false);
authIdentCheckbox.setSelected(false);
sendLocalUsernameCheckbox.setSelected(sendLocalUsername.getValue());
secTypes = security.GetEnabledSecTypes();
for (iter = secTypes.iterator(); iter.hasNext(); ) {
switch ((Integer)iter.next()) {
case Security.secTypeNone:
encNoneCheckbox.setSelected(true);
authNoneCheckbox.setSelected(true);
break;
case Security.secTypeVncAuth:
encNoneCheckbox.setSelected(true);
authVncCheckbox.setSelected(true);
break;
}
}
secTypesExt = security.GetEnabledExtSecTypes();
for (iterExt = secTypesExt.iterator(); iterExt.hasNext(); ) {
switch ((Integer)iterExt.next()) {
case Security.secTypePlain:
encNoneCheckbox.setSelected(true);
authPlainCheckbox.setSelected(true);
break;
case Security.secTypeIdent:
encNoneCheckbox.setSelected(true);
authIdentCheckbox.setSelected(true);
break;
case Security.secTypeTLSNone:
encTLSCheckbox.setSelected(true);
authNoneCheckbox.setSelected(true);
break;
case Security.secTypeTLSVnc:
encTLSCheckbox.setSelected(true);
authVncCheckbox.setSelected(true);
break;
case Security.secTypeTLSPlain:
encTLSCheckbox.setSelected(true);
authPlainCheckbox.setSelected(true);
break;
case Security.secTypeTLSIdent:
encTLSCheckbox.setSelected(true);
authIdentCheckbox.setSelected(true);
break;
case Security.secTypeX509None:
encX509Checkbox.setSelected(true);
authNoneCheckbox.setSelected(true);
break;
case Security.secTypeX509Vnc:
encX509Checkbox.setSelected(true);
authVncCheckbox.setSelected(true);
break;
case Security.secTypeX509Plain:
encX509Checkbox.setSelected(true);
authPlainCheckbox.setSelected(true);
break;
case Security.secTypeX509Ident:
encX509Checkbox.setSelected(true);
authIdentCheckbox.setSelected(true);
break;
}
}
File caFile = new File(CSecurityTLS.X509CA.getValueStr());
if (caFile.exists() && caFile.canRead())
caInput.setText(caFile.getAbsolutePath());
File crlFile = new File(CSecurityTLS.X509CRL.getValueStr());
if (crlFile.exists() && crlFile.canRead())
crlInput.setText(crlFile.getAbsolutePath());
handleX509();
handleSendLocalUsername();
/* Input */
viewOnlyCheckbox.setSelected(viewOnly.getValue());
acceptClipboardCheckbox.setSelected(acceptClipboard.getValue());
sendClipboardCheckbox.setSelected(sendClipboard.getValue());
menuKeyChoice.setSelectedIndex(0);
String menuKeyStr = menuKey.getValueStr();
for (int i = 0; i < menuKeyChoice.getItemCount(); i++)
if (menuKeyStr.equals(menuKeyChoice.getItemAt(i)))
menuKeyChoice.setSelectedIndex(i);
/* Screen */
String width, height;
if (desktopSize.getValueStr().isEmpty() ||
desktopSize.getValueStr().split("x").length != 2) {
desktopSizeCheckbox.setSelected(false);
desktopWidthInput.setText("1024");
desktopHeightInput.setText("768");
} else {
desktopSizeCheckbox.setSelected(true);
width = desktopSize.getValueStr().split("x")[0];
desktopWidthInput.setText(width);
height = desktopSize.getValueStr().split("x")[1];
desktopHeightInput.setText(height);
}
if (remoteResize.getValue())
remoteResizeButton.setSelected(true);
else
remoteScaleButton.setSelected(true);
fullScreenCheckbox.setSelected(fullScreen.getValue());
fullScreenAllMonitorsCheckbox.setSelected(fullScreenAllMonitors.getValue());
scalingFactorInput.setSelectedItem("100%");
String scaleStr = scalingFactor.getValueStr();
if (scaleStr.matches("^[0-9]+$"))
scaleStr = scaleStr.concat("%");
if (scaleStr.matches("^FixedRatio$"))
scaleStr = new String("Fixed Aspect Ratio");
for (int i = 0; i < scalingFactorInput.getItemCount(); i++)
if (scaleStr.equals(scalingFactorInput.getItemAt(i)))
scalingFactorInput.setSelectedIndex(i);
handleDesktopSize();
/* Misc. */
sharedCheckbox.setSelected(shared.getValue());
dotWhenNoCursorCheckbox.setSelected(dotWhenNoCursor.getValue());
acceptBellCheckbox.setSelected(acceptBell.getValue());
/* SSH */
File f;
tunnelCheckbox.setSelected(tunnel.getValue() || !via.getValueStr().isEmpty());
viaCheckbox.setSelected(!via.getValueStr().isEmpty());
if (viaCheckbox.isSelected()) {
viaUserInput.setText(Tunnel.getSshUser());
viaHostInput.setText(Tunnel.getSshHost());
viaPortInput.setText(Integer.toString(Tunnel.getSshPort()));
}
extSSHCheckbox.setSelected(extSSH.getValue());
f = new File(extSSHClient.getValueStr());
if (f.exists() && f.isFile() && f.canExecute())
sshClientInput.setText(f.getAbsolutePath());
if (extSSHArgs.getValueStr().isEmpty()) {
sshArgsDefaultButton.setSelected(true);
} else {
sshArgsCustomButton.setSelected(true);
sshArgsInput.setText(extSSHArgs.getValueStr());
}
f = new File(sshKeyFile.getValueStr());
if (f.exists() && f.isFile() && f.canRead())
sshKeyFileInput.setText(f.getAbsolutePath());
f = new File(sshConfig.getValueStr());
if (f.exists() && f.isFile() && f.canRead())
sshConfigInput.setText(f.getAbsolutePath());
handleTunnel();
handleVia();
handleExtSSH();
handleEmbed();
handleRfbState();
}
private void storeOptions() {
/* Compression */
autoSelect.setParam(autoselectCheckbox.isSelected());
if (tightButton.isSelected())
preferredEncoding.setParam(Encodings.encodingName(Encodings.encodingTight));
else if (zrleButton.isSelected())
preferredEncoding.setParam(Encodings.encodingName(Encodings.encodingZRLE));
else if (hextileButton.isSelected())
preferredEncoding.setParam(Encodings.encodingName(Encodings.encodingHextile));
else if (rawButton.isSelected())
preferredEncoding.setParam(Encodings.encodingName(Encodings.encodingRaw));
fullColor.setParam(fullcolorButton.isSelected());
if (verylowcolorButton.isSelected())
lowColorLevel.setParam(0);
else if (lowcolorButton.isSelected())
lowColorLevel.setParam(1);
else if (mediumcolorButton.isSelected())
lowColorLevel.setParam(2);
customCompressLevel.setParam(compressionCheckbox.isSelected());
noJpeg.setParam(!jpegCheckbox.isSelected());
compressLevel.setParam((Integer)compressionInput.getSelectedItem());
qualityLevel.setParam((Integer)jpegInput.getSelectedItem());
/* Security */
Security security = new Security();
/* Process security types which don't use encryption */
if (encNoneCheckbox.isSelected()) {
if (authNoneCheckbox.isSelected())
security.EnableSecType(Security.secTypeNone);
if (authVncCheckbox.isSelected())
security.EnableSecType(Security.secTypeVncAuth);
if (authPlainCheckbox.isSelected())
security.EnableSecType(Security.secTypePlain);
if (authIdentCheckbox.isSelected())
security.EnableSecType(Security.secTypeIdent);
}
/* Process security types which use TLS encryption */
if (encTLSCheckbox.isSelected()) {
if (authNoneCheckbox.isSelected())
security.EnableSecType(Security.secTypeTLSNone);
if (authVncCheckbox.isSelected())
security.EnableSecType(Security.secTypeTLSVnc);
if (authPlainCheckbox.isSelected())
security.EnableSecType(Security.secTypeTLSPlain);
if (authIdentCheckbox.isSelected())
security.EnableSecType(Security.secTypeTLSIdent);
}
/* Process security types which use X509 encryption */
if (encX509Checkbox.isSelected()) {
if (authNoneCheckbox.isSelected())
security.EnableSecType(Security.secTypeX509None);
if (authVncCheckbox.isSelected())
security.EnableSecType(Security.secTypeX509Vnc);
if (authPlainCheckbox.isSelected())
security.EnableSecType(Security.secTypeX509Plain);
if (authIdentCheckbox.isSelected())
security.EnableSecType(Security.secTypeX509Ident);
}
if (authIdentCheckbox.isSelected() ||
authPlainCheckbox.isSelected()) {
sendLocalUsername.setParam(sendLocalUsernameCheckbox.isSelected());
}
SecurityClient.secTypes.setParam(security.ToString());
File caFile = new File(caInput.getText());
if (caFile.exists() && caFile.canRead())
CSecurityTLS.X509CA.setParam(caFile.getAbsolutePath());
File crlFile = new File(crlInput.getText());
if (crlFile.exists() && crlFile.canRead())
CSecurityTLS.X509CRL.setParam(crlFile.getAbsolutePath());
/* Input */
viewOnly.setParam(viewOnlyCheckbox.isSelected());
acceptClipboard.setParam(acceptClipboardCheckbox.isSelected());
sendClipboard.setParam(sendClipboardCheckbox.isSelected());
String menuKeyStr =
MenuKey.getMenuKeySymbols()[menuKeyChoice.getSelectedIndex()].name;
menuKey.setParam(menuKeyStr);
/* Screen */
if (desktopSizeCheckbox.isSelected() &&
!desktopWidthInput.getText().isEmpty() &&
!desktopHeightInput.getText().isEmpty()) {
String width = desktopWidthInput.getText();
String height = desktopHeightInput.getText();
desktopSize.setParam(width.concat("x").concat(height));
} else {
desktopSize.setParam("");
}
remoteResize.setParam(remoteResizeButton.isSelected());
fullScreen.setParam(fullScreenCheckbox.isSelected());
fullScreenAllMonitors.setParam(fullScreenAllMonitorsCheckbox.isSelected());
String scaleStr =
((String)scalingFactorInput.getSelectedItem()).replace("%", "");
scaleStr.replace("Fixed Aspect Ratio", "FixedRatio");
scalingFactor.setParam(scaleStr);
/* Misc. */
shared.setParam(sharedCheckbox.isSelected());
dotWhenNoCursor.setParam(dotWhenNoCursorCheckbox.isSelected());
acceptBell.setParam(acceptBellCheckbox.isSelected());
/* SSH */
tunnel.setParam(tunnelCheckbox.isSelected());
if (viaCheckbox.isSelected() &&
!viaUserInput.getText().isEmpty() &&
!viaHostInput.getText().isEmpty() &&
!viaPortInput.getText().isEmpty()) {
String sshUser = viaUserInput.getText();
String sshHost = viaHostInput.getText();
String sshPort = viaPortInput.getText();
String viaStr = sshUser.concat("@").concat(sshHost).concat(":").concat(sshPort);
via.setParam(viaStr);
} else {
via.setParam("");
}
extSSH.setParam(extSSHCheckbox.isSelected());
if (!sshClientInput.getText().isEmpty())
extSSHClient.setParam(sshClientInput.getText());
if (sshArgsDefaultButton.isSelected())
if (!sshArgsInput.getText().isEmpty())
extSSHArgs.setParam(sshArgsInput.getText());
if (!sshConfigInput.getText().isEmpty())
sshConfig.setParam(sshConfigInput.getText());
if (!sshKeyFileInput.getText().isEmpty())
sshKeyFile.setParam(sshKeyFileInput.getText());
try {
for (Map.Entry<Object, String> iter : callbacks.entrySet()) {
Object obj = iter.getKey();
Method cb = obj.getClass().getMethod(iter.getValue(), new Class[]{});
if (cb == null)
vlog.info(obj.getClass().getName());
cb.invoke(obj);
}
} catch (NoSuchMethodException e) {
vlog.error("NoSuchMethodException: "+e.getMessage());
} catch (IllegalAccessException e) {
vlog.error("IllegalAccessException: "+e.getMessage());
} catch (InvocationTargetException e) {
vlog.error("InvocationTargetException: "+e.getMessage());
}
}
private JPanel createCompressionPanel() {
JPanel FormatPanel = new JPanel();
FormatPanel.setLayout(new BoxLayout(FormatPanel,
BoxLayout.PAGE_AXIS));
FormatPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 5));
JPanel autoSelectPane = new JPanel();
autoSelectPane.setLayout(new BoxLayout(autoSelectPane,
BoxLayout.LINE_AXIS));
autoSelectPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 0));
autoselectCheckbox = new JCheckBox("Auto Select");
autoselectCheckbox.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
handleAutoselect();
}
});
autoSelectPane.add(autoselectCheckbox);
autoSelectPane.add(Box.createHorizontalGlue());
JPanel encodingPanel = new JPanel(new GridLayout(4, 1));
encodingPanel.setBorder(BorderFactory.createTitledBorder("Preferred encoding"));
tightButton = new GroupedJRadioButton("Tight", encodingGroup, encodingPanel);
zrleButton = new GroupedJRadioButton("ZRLE", encodingGroup, encodingPanel);
hextileButton = new GroupedJRadioButton("Hextile", encodingGroup, encodingPanel);
rawButton = new GroupedJRadioButton("Raw", encodingGroup, encodingPanel);
JPanel colorPanel = new JPanel(new GridLayout(4, 1));
colorPanel.setBorder(BorderFactory.createTitledBorder("Color level"));
fullcolorButton = new GroupedJRadioButton("Full (all available colors)",
colorlevelGroup, colorPanel);
mediumcolorButton = new GroupedJRadioButton("Medium (256 colors)",
colorlevelGroup, colorPanel);
lowcolorButton = new GroupedJRadioButton("Low (64 colors)",
colorlevelGroup, colorPanel);
verylowcolorButton = new GroupedJRadioButton("Very low (8 colors)",
colorlevelGroup, colorPanel);
JPanel encodingPane = new JPanel(new GridLayout(1, 2, 5, 0));
encodingPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 0));
encodingPane.add(encodingPanel);
encodingPane.add(colorPanel);
JPanel tightPanel = new JPanel(new GridBagLayout());
compressionCheckbox = new JCheckBox("Custom Compression Level");
compressionCheckbox.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
handleCompression();
}
});
Object[] compressionLevels = { 1, 2, 3, 4, 5, 6 };
compressionInput = new MyJComboBox(compressionLevels);
((MyJComboBox)compressionInput).setDocument(new IntegerDocument(1));
compressionInput.setPrototypeDisplayValue("0.");
compressionInput.setEditable(true);
JLabel compressionLabel =
new JLabel("Level (1=fast, 6=best [4-6 are rarely useful])");
jpegCheckbox = new JCheckBox("Allow JPEG Compression");
jpegCheckbox.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
handleJpeg();
}
});
Object[] qualityLevels = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
jpegInput = new MyJComboBox(qualityLevels);
jpegInput.setPrototypeDisplayValue("0.");
JLabel qualityLabel = new JLabel("Quality (0=poor, 9=best)");
tightPanel.add(compressionCheckbox,
new GridBagConstraints(0, 0,
REMAINDER, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 0, 0),
NONE, NONE));
int indent = getButtonLabelInset(compressionCheckbox);
tightPanel.add(compressionInput,
new GridBagConstraints(0, 1,
1, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, indent, 0, 0),
NONE, NONE));
tightPanel.add(compressionLabel,
new GridBagConstraints(1, 1,
1, 1,
HEAVY, LIGHT,
LINE_START, HORIZONTAL,
new Insets(0, 5, 0, 0),
NONE, NONE));
tightPanel.add(jpegCheckbox,
new GridBagConstraints(0, 2,
REMAINDER, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(5, 0, 0, 0),
NONE, NONE));
indent = getButtonLabelInset(jpegCheckbox);
tightPanel.add(jpegInput,
new GridBagConstraints(0, 3,
1, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, indent, 0, 0),
NONE, NONE));
tightPanel.add(qualityLabel,
new GridBagConstraints(1, 3,
1, 1,
HEAVY, NONE,
LINE_START, HORIZONTAL,
new Insets(0, 5, 0, 0),
NONE, NONE));
tightPanel.add(Box.createRigidArea(new Dimension(5,0)),
new GridBagConstraints(0, 4,
REMAINDER, REMAINDER,
HEAVY, HEAVY,
LINE_START, BOTH,
new Insets(0, 0, 0, 0),
NONE, NONE));
FormatPanel.add(autoSelectPane);
FormatPanel.add(encodingPane);
FormatPanel.add(tightPanel);
return FormatPanel;
}
private JPanel createSecurityPanel() {
JPanel SecPanel = new JPanel();
SecPanel.setLayout(new BoxLayout(SecPanel,
BoxLayout.PAGE_AXIS));
SecPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 5));
JPanel vencryptPane = new JPanel();
vencryptPane.setLayout(new BoxLayout(vencryptPane,
BoxLayout.LINE_AXIS));
vencryptPane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
JPanel encrPanel = new JPanel(new GridBagLayout());
encrPanel.setBorder(BorderFactory.createTitledBorder("Encryption"));
encNoneCheckbox = new JCheckBox("None");
encTLSCheckbox = new JCheckBox("Anonymous TLS");
encX509Checkbox = new JCheckBox("TLS with X.509 certificates");
encX509Checkbox.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
handleX509();
}
});
JLabel caLabel = new JLabel("X.509 CA Certificate");
caInput = new JTextField();
caChooser = new JButton("Browse");
caChooser.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JComponent c = ((JButton)e.getSource()).getRootPane();
File dflt = new File(CSecurityTLS.X509CA.getValueStr());
FileNameExtensionFilter filter =
new FileNameExtensionFilter("X.509 certificate", "crt", "cer", "pem");
File f = showChooser("Path to X509 CA certificate", dflt, c, filter);
if (f != null && f.exists() && f.canRead())
caInput.setText(f.getAbsolutePath());
}
});
JLabel crlLabel = new JLabel("X.509 CRL file");
crlInput = new JTextField();
crlChooser = new JButton("Browse");
crlChooser.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JComponent c = ((JButton)e.getSource()).getRootPane();
File dflt = new File(CSecurityTLS.X509CRL.getValueStr());
FileNameExtensionFilter filter =
new FileNameExtensionFilter("X.509 CRL", "crl");
File f = showChooser("Path to X509 CRL file", dflt, c, filter);
if (f != null && f.exists() && f.canRead())
crlInput.setText(f.getAbsolutePath());
}
});
encrPanel.add(encNoneCheckbox,
new GridBagConstraints(0, 0,
REMAINDER, 1,
HEAVY, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 4, 0),
NONE, NONE));
encrPanel.add(encTLSCheckbox,
new GridBagConstraints(0, 1,
REMAINDER, 1,
HEAVY, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 4, 0),
NONE, NONE));
encrPanel.add(encX509Checkbox,
new GridBagConstraints(0, 2,
3, 1,
HEAVY, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 0, 0),
NONE, NONE));
int indent = getButtonLabelInset(encX509Checkbox);
encrPanel.add(caLabel,
new GridBagConstraints(0, 3,
1, 1,
LIGHT, LIGHT,
LINE_END, NONE,
new Insets(0, indent, 5, 0),
0, 0));
encrPanel.add(caInput,
new GridBagConstraints(1, 3,
1, 1,
HEAVY, LIGHT,
LINE_START, HORIZONTAL,
new Insets(0, 5, 5, 0),
0, 0));
encrPanel.add(caChooser,
new GridBagConstraints(2, 3,
1, 1,
LIGHT, LIGHT,
LINE_START, VERTICAL,
new Insets(0, 5, 5, 0),
0, 0));
encrPanel.add(crlLabel,
new GridBagConstraints(0, 4,
1, 1,
LIGHT, LIGHT,
LINE_END, NONE,
new Insets(0, indent, 0, 0),
0, 0));
encrPanel.add(crlInput,
new GridBagConstraints(1, 4,
1, 1,
HEAVY, LIGHT,
LINE_START, HORIZONTAL,
new Insets(0, 5, 0, 0),
0, 0));
encrPanel.add(crlChooser,
new GridBagConstraints(2, 4,
1, 1,
LIGHT, LIGHT,
LINE_START, VERTICAL,
new Insets(0, 5, 0, 0),
0, 0));
JPanel authPanel = new JPanel(new GridBagLayout());
authPanel.setBorder(BorderFactory.createTitledBorder("Authentication"));
authNoneCheckbox = new JCheckBox("None");
authVncCheckbox = new JCheckBox("Standard VNC");
authPlainCheckbox = new JCheckBox("Plaintext");
authPlainCheckbox.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
handleSendLocalUsername();
}
});
authIdentCheckbox = new JCheckBox("Ident");
authIdentCheckbox.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
handleSendLocalUsername();
}
});
sendLocalUsernameCheckbox = new JCheckBox("Send Local Username");
authPanel.add(authNoneCheckbox,
new GridBagConstraints(0, 0,
REMAINDER, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 4, 0),
NONE, NONE));
authPanel.add(authVncCheckbox,
new GridBagConstraints(0, 1,
REMAINDER, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 4, 0),
NONE, NONE));
authPanel.add(authPlainCheckbox,
new GridBagConstraints(0, 2,
1, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 2, 0),
NONE, NONE));
authPanel.add(authIdentCheckbox,
new GridBagConstraints(0, 3,
1, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(2, 0, 0, 0),
NONE, NONE));
authPanel.add(sendLocalUsernameCheckbox,
new GridBagConstraints(1, 2,
1, 2,
HEAVY, LIGHT,
LINE_START, NONE,
new Insets(2, 20, 2, 0),
NONE, NONE));
SecPanel.add(vencryptPane,
new GridBagConstraints(0, 0,
REMAINDER, 1,
LIGHT, LIGHT,
LINE_START, HORIZONTAL,
new Insets(0, 0, 4, 0),
NONE, NONE));
SecPanel.add(encrPanel,
new GridBagConstraints(0, 1,
REMAINDER, 1,
LIGHT, LIGHT,
LINE_START, HORIZONTAL,
new Insets(0, 0, 4, 0),
NONE, NONE));
SecPanel.add(authPanel,
new GridBagConstraints(0, 2,
REMAINDER, 1,
LIGHT, LIGHT,
LINE_START, HORIZONTAL,
new Insets(0, 0, 4, 0),
NONE, NONE));
SecPanel.add(Box.createRigidArea(new Dimension(0,0)),
new GridBagConstraints(0, RELATIVE,
REMAINDER, REMAINDER,
HEAVY, HEAVY,
LINE_START, BOTH,
new Insets(0, 0, 0, 0),
NONE, NONE));
return SecPanel;
}
private JPanel createInputPanel() {
JPanel inputPanel = new JPanel(new GridBagLayout());
inputPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 5));
viewOnlyCheckbox = new JCheckBox("View only (ignore mouse and keyboard)");
acceptClipboardCheckbox = new JCheckBox("Accept clipboard from server");
sendClipboardCheckbox = new JCheckBox("Send clipboard to server");
JLabel menuKeyLabel = new JLabel("Menu key");
String[] menuKeys = new String[MenuKey.getMenuKeySymbolCount()];
//String[] menuKeys = new String[MenuKey.getMenuKeySymbolCount()+1];
//menuKeys[0] = "None";
for (int i = 0; i < MenuKey.getMenuKeySymbolCount(); i++)
menuKeys[i] = MenuKey.getKeyText(MenuKey.getMenuKeySymbols()[i]);
//menuKeys[i+1] = MenuKey.getKeyText(MenuKey.getMenuKeySymbols()[i]);
menuKeyChoice = new JComboBox(menuKeys);
inputPanel.add(viewOnlyCheckbox,
new GridBagConstraints(0, 0,
REMAINDER, 1,
HEAVY, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 4, 0),
NONE, NONE));
inputPanel.add(acceptClipboardCheckbox,
new GridBagConstraints(0, 1,
REMAINDER, 1,
HEAVY, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 4, 0),
NONE, NONE));
inputPanel.add(sendClipboardCheckbox,
new GridBagConstraints(0, 2,
REMAINDER, 1,
HEAVY, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 4, 0),
NONE, NONE));
inputPanel.add(menuKeyLabel,
new GridBagConstraints(0, 3,
1, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 0, 0),
NONE, NONE));
inputPanel.add(menuKeyChoice,
new GridBagConstraints(1, 3,
1, 1,
HEAVY, LIGHT,
LINE_START, NONE,
new Insets(0, 5, 0, 0),
NONE, NONE));
inputPanel.add(Box.createRigidArea(new Dimension(5, 0)),
new GridBagConstraints(0, 4,
REMAINDER, REMAINDER,
HEAVY, HEAVY,
LINE_START, BOTH,
new Insets(0, 0, 0, 0),
NONE, NONE));
return inputPanel;
}
private JPanel createScreenPanel() {
JPanel ScreenPanel = new JPanel(new GridBagLayout());
ScreenPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 5));
JPanel SizingPanel = new JPanel(new GridBagLayout());
SizingPanel.setBorder(BorderFactory.createTitledBorder("Desktop Sizing"));
desktopSizeCheckbox = new JCheckBox("Resize remote session on connect");
desktopSizeCheckbox.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
handleDesktopSize();
}
});
desktopWidthInput = new IntegerTextField(5);
desktopHeightInput = new IntegerTextField(5);
JPanel desktopSizePanel =
new JPanel(new FlowLayout(FlowLayout.LEADING, 0, 0));
desktopSizePanel.add(desktopWidthInput);
desktopSizePanel.add(new JLabel(" x "));
desktopSizePanel.add(desktopHeightInput);
sizingGroup = new ButtonGroup();
remoteResizeButton =
new JRadioButton("Resize remote session to the local window");
sizingGroup.add(remoteResizeButton);
remoteScaleButton =
new JRadioButton("Scale remote session to the local window");
sizingGroup.add(remoteScaleButton);
remoteResizeButton.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
handleRemoteResize();
}
});
JLabel scalingFactorLabel = new JLabel("Scaling Factor");
Object[] scalingFactors = {
"Auto", "Fixed Aspect Ratio", "50%", "75%", "95%", "100%", "105%",
"125%", "150%", "175%", "200%", "250%", "300%", "350%", "400%" };
scalingFactorInput = new MyJComboBox(scalingFactors);
scalingFactorInput.setEditable(true);
fullScreenCheckbox = new JCheckBox("Full-screen mode");
fullScreenAllMonitorsCheckbox =
new JCheckBox("Enable full-screen mode over all monitors");
SizingPanel.add(desktopSizeCheckbox,
new GridBagConstraints(0, 0,
REMAINDER, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 0, 0),
NONE, NONE));
int indent = getButtonLabelInset(desktopSizeCheckbox);
SizingPanel.add(desktopSizePanel,
new GridBagConstraints(0, 1,
REMAINDER, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, indent, 0, 0),
NONE, NONE));
SizingPanel.add(remoteResizeButton,
new GridBagConstraints(0, 2,
REMAINDER, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 4, 0),
NONE, NONE));
SizingPanel.add(remoteScaleButton,
new GridBagConstraints(0, 3,
REMAINDER, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 4, 0),
NONE, NONE));
indent = getButtonLabelInset(remoteScaleButton);
SizingPanel.add(scalingFactorLabel,
new GridBagConstraints(0, 4,
1, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, indent, 4, 0),
NONE, NONE));
SizingPanel.add(scalingFactorInput,
new GridBagConstraints(1, 4,
1, 1,
HEAVY, LIGHT,
LINE_START, NONE,
new Insets(0, 5, 4, 0),
NONE, NONE));
ScreenPanel.add(SizingPanel,
new GridBagConstraints(0, 0,
REMAINDER, 1,
LIGHT, LIGHT,
LINE_START, HORIZONTAL,
new Insets(0, 0, 4, 0),
NONE, NONE));
ScreenPanel.add(fullScreenCheckbox,
new GridBagConstraints(0, 1,
REMAINDER, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 4, 0),
NONE, NONE));
indent = getButtonLabelInset(fullScreenCheckbox);
ScreenPanel.add(fullScreenAllMonitorsCheckbox,
new GridBagConstraints(0, 2,
REMAINDER, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, indent, 4, 0),
NONE, NONE));
ScreenPanel.add(Box.createRigidArea(new Dimension(5, 0)),
new GridBagConstraints(0, 3,
REMAINDER, REMAINDER,
HEAVY, HEAVY,
LINE_START, BOTH,
new Insets(0, 0, 0, 0),
NONE, NONE));
return ScreenPanel;
}
private JPanel createMiscPanel() {
JPanel MiscPanel = new JPanel(new GridBagLayout());
MiscPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 5));
sharedCheckbox =
new JCheckBox("Shared (don't disconnect other viewers)");
dotWhenNoCursorCheckbox = new JCheckBox("Show dot when no cursor");
acceptBellCheckbox = new JCheckBox("Beep when requested by the server");
MiscPanel.add(sharedCheckbox,
new GridBagConstraints(0, 0,
1, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 4, 0),
NONE, NONE));
MiscPanel.add(dotWhenNoCursorCheckbox,
new GridBagConstraints(0, 1,
1, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 4, 0),
NONE, NONE));
MiscPanel.add(acceptBellCheckbox,
new GridBagConstraints(0, 2,
1, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 4, 0),
NONE, NONE));
MiscPanel.add(Box.createRigidArea(new Dimension(5, 0)),
new GridBagConstraints(0, 3,
REMAINDER, REMAINDER,
HEAVY, HEAVY,
LINE_START, BOTH,
new Insets(0, 0, 0, 0),
NONE, NONE));
return MiscPanel;
}
private JPanel createSshPanel() {
JPanel sshPanel = new JPanel(new GridBagLayout());
sshPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 5));
ButtonGroup sshArgsGroup = new ButtonGroup();
tunnelCheckbox = new JCheckBox("Tunnel VNC over SSH");
tunnelCheckbox.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
handleTunnel();
}
});
JPanel tunnelPanel = new JPanel(new GridBagLayout());
viaCheckbox = new JCheckBox("Use SSH gateway");
viaCheckbox.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
handleVia();
}
});
JLabel sshUserLabel = new JLabel("Username");
viaUserInput = new JTextField();
JLabel sshUserAtLabel = new JLabel("@");
JLabel sshHostLabel = new JLabel("Hostname (or IP address)");
viaHostInput = new JTextField("");
JLabel sshPortLabel = new JLabel("Port");
viaPortInput = new IntegerTextField(5);
extSSHCheckbox = new JCheckBox("Use external SSH client");
extSSHCheckbox.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
handleExtSSH();
}
});
sshClientInput = new JTextField();
sshClientChooser = new JButton("Browse");
sshClientChooser.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JComponent c = ((JButton)e.getSource()).getRootPane();
File dflt = new File(extSSHClient.getValueStr());
File f = showChooser("Path to external SSH client", dflt, c);
if (f != null && f.exists() && f.isFile() && f.canExecute())
sshClientInput.setText(f.getAbsolutePath());
}
});
JLabel sshConfigLabel = new JLabel("SSH config file");
sshConfigInput = new JTextField();
sshConfigChooser = new JButton("Browse");
sshConfigChooser.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JComponent c = ((JButton)e.getSource()).getRootPane();
File dflt = new File(sshConfig.getValueStr());
File f = showChooser("Path to OpenSSH client config file", dflt, c);
if (f != null && f.exists() && f.isFile() && f.canRead())
sshConfigInput.setText(f.getAbsolutePath());
}
});
JLabel sshKeyFileLabel = new JLabel("SSH identity file");
sshKeyFileInput = new JTextField();
sshKeyFileChooser = new JButton("Browse");
sshKeyFileChooser.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JComponent c = ((JButton)e.getSource()).getRootPane();
File f = showChooser("Path to SSH key file", null, c);
if (f != null && f.exists() && f.isFile() && f.canRead())
sshKeyFileInput.setText(f.getAbsolutePath());
}
});
JPanel sshArgsPanel = new JPanel(new GridBagLayout());
JLabel sshArgsLabel = new JLabel("Arguments:");
sshArgsDefaultButton = new GroupedJRadioButton("Default", sshArgsGroup, sshArgsPanel);
sshArgsDefaultButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
sshArgsInput.setEnabled(sshArgsCustomButton.isSelected());
}
});
sshArgsCustomButton = new GroupedJRadioButton("Custom", sshArgsGroup, sshArgsPanel);
sshArgsCustomButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
sshArgsInput.setEnabled(sshArgsCustomButton.isSelected());
}
});
sshArgsInput = new JTextField();
JPanel gatewayPanel = new JPanel(new GridBagLayout());
gatewayPanel.add(viaCheckbox,
new GridBagConstraints(0, 0,
REMAINDER, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 4, 0),
NONE, NONE));
int indent = getButtonLabelInset(viaCheckbox);
gatewayPanel.add(sshUserLabel,
new GridBagConstraints(0, 1,
1, 1,
LIGHT, LIGHT,
LINE_START, HORIZONTAL,
new Insets(0, indent, 4, 0),
NONE, NONE));
gatewayPanel.add(sshHostLabel,
new GridBagConstraints(2, 1,
1, 1,
HEAVY, LIGHT,
LINE_START, HORIZONTAL,
new Insets(0, 0, 4, 0),
NONE, NONE));
gatewayPanel.add(sshPortLabel,
new GridBagConstraints(3, 1,
1, 1,
LIGHT, LIGHT,
LINE_START, HORIZONTAL,
new Insets(0, 5, 4, 0),
NONE, NONE));
gatewayPanel.add(viaUserInput,
new GridBagConstraints(0, 2,
1, 1,
LIGHT, LIGHT,
LINE_START, HORIZONTAL,
new Insets(0, indent, 0, 0),
NONE, NONE));
gatewayPanel.add(sshUserAtLabel,
new GridBagConstraints(1, 2,
1, 1,
LIGHT, LIGHT,
LINE_START, HORIZONTAL,
new Insets(0, 2, 0, 2),
NONE, NONE));
gatewayPanel.add(viaHostInput,
new GridBagConstraints(2, 2,
1, 1,
HEAVY, LIGHT,
LINE_START, HORIZONTAL,
new Insets(0, 0, 0, 0),
NONE, NONE));
gatewayPanel.add(viaPortInput,
new GridBagConstraints(3, 2,
1, 1,
LIGHT, LIGHT,
LINE_START, HORIZONTAL,
new Insets(0, 5, 0, 0),
NONE, NONE));
JPanel clientPanel = new JPanel(new GridBagLayout());
clientPanel.add(extSSHCheckbox,
new GridBagConstraints(0, 0,
1, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 0, 0),
NONE, NONE));
clientPanel.add(sshClientInput,
new GridBagConstraints(1, 0,
1, 1,
HEAVY, LIGHT,
LINE_START, HORIZONTAL,
new Insets(0, 5, 0, 0),
NONE, NONE));
clientPanel.add(sshClientChooser,
new GridBagConstraints(2, 0,
1, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, 5, 0, 0),
NONE, NONE));
sshArgsPanel.add(sshArgsLabel,
new GridBagConstraints(0, 1,
1, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 0, 0),
NONE, NONE));
sshArgsPanel.add(sshArgsDefaultButton,
new GridBagConstraints(1, 1,
1, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, 5, 0, 0),
NONE, NONE));
sshArgsPanel.add(sshArgsCustomButton,
new GridBagConstraints(2, 1,
1, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, 5, 0, 0),
NONE, NONE));
sshArgsPanel.add(sshArgsInput,
new GridBagConstraints(3, 1,
1, 1,
HEAVY, LIGHT,
LINE_START, HORIZONTAL,
new Insets(0, 5, 0, 0),
NONE, NONE));
indent = getButtonLabelInset(extSSHCheckbox);
clientPanel.add(sshArgsPanel,
new GridBagConstraints(0, 1,
REMAINDER, 1,
LIGHT, LIGHT,
LINE_START, HORIZONTAL,
new Insets(4, indent, 0, 0),
NONE, NONE));
JPanel opensshPanel = new JPanel(new GridBagLayout());
TitledBorder border =
BorderFactory.createTitledBorder("Embedded SSH client configuration");
opensshPanel.setBorder(border);
opensshPanel.add(sshConfigLabel,
new GridBagConstraints(0, 0,
1, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 5, 0),
NONE, NONE));
opensshPanel.add(sshConfigInput,
new GridBagConstraints(1, 0,
1, 1,
HEAVY, LIGHT,
LINE_START, HORIZONTAL,
new Insets(0, 5, 5, 0),
NONE, NONE));
opensshPanel.add(sshConfigChooser,
new GridBagConstraints(2, 0,
1, 1,
LIGHT, LIGHT,
LINE_START, VERTICAL,
new Insets(0, 5, 5, 0),
NONE, NONE));
opensshPanel.add(sshKeyFileLabel,
new GridBagConstraints(0, 1,
1, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 0, 0),
NONE, NONE));
opensshPanel.add(sshKeyFileInput,
new GridBagConstraints(1, 1,
1, 1,
HEAVY, LIGHT,
LINE_START, HORIZONTAL,
new Insets(0, 5, 0, 0),
NONE, NONE));
opensshPanel.add(sshKeyFileChooser,
new GridBagConstraints(2, 1,
1, 1,
LIGHT, LIGHT,
LINE_START, VERTICAL,
new Insets(0, 5, 0, 0),
NONE, NONE));
tunnelPanel.add(gatewayPanel,
new GridBagConstraints(0, 0,
REMAINDER, 1,
HEAVY, LIGHT,
LINE_START, HORIZONTAL,
new Insets(0, 0, 4, 0),
NONE, NONE));
tunnelPanel.add(clientPanel,
new GridBagConstraints(0, 1,
REMAINDER, 1,
HEAVY, LIGHT,
LINE_START, HORIZONTAL,
new Insets(0, 0, 4, 0),
NONE, NONE));
tunnelPanel.add(opensshPanel,
new GridBagConstraints(0, 2,
REMAINDER, 1,
HEAVY, LIGHT,
LINE_START, HORIZONTAL,
new Insets(0, 0, 0, 0),
NONE, NONE));
sshPanel.add(tunnelCheckbox,
new GridBagConstraints(0, 0,
REMAINDER, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 4, 0),
NONE, NONE));
indent = getButtonLabelInset(tunnelCheckbox);
sshPanel.add(tunnelPanel,
new GridBagConstraints(0, 2,
REMAINDER, 1,
LIGHT, LIGHT,
LINE_START, HORIZONTAL,
new Insets(0, indent, 4, 0),
NONE, NONE));
sshPanel.add(Box.createRigidArea(new Dimension(5, 0)),
new GridBagConstraints(0, RELATIVE,
REMAINDER, REMAINDER,
HEAVY, HEAVY,
LINE_START, BOTH,
new Insets(0, 0, 0, 0),
NONE, NONE));
return sshPanel;
}
private void handleAutoselect()
{
ButtonGroup[] groups = { encodingGroup, colorlevelGroup };
for (ButtonGroup grp : groups) {
Enumeration<AbstractButton> elems = grp.getElements();
while (elems.hasMoreElements())
elems.nextElement().setEnabled(!autoselectCheckbox.isSelected());
}
// JPEG setting is also affected by autoselection
jpegCheckbox.setEnabled(!autoselectCheckbox.isSelected());
handleJpeg();
}
private void handleCompression()
{
compressionInput.setEnabled(compressionCheckbox.isSelected());
}
private void handleJpeg()
{
if (jpegCheckbox.isSelected() &&
!autoselectCheckbox.isSelected())
jpegInput.setEnabled(true);
else
jpegInput.setEnabled(false);
}
private void handleX509()
{
caInput.setEnabled(encX509Checkbox.isSelected());
caChooser.setEnabled(encX509Checkbox.isSelected());
crlInput.setEnabled(encX509Checkbox.isSelected());
crlChooser.setEnabled(encX509Checkbox.isSelected());
}
private void handleSendLocalUsername()
{
boolean value = authIdentCheckbox.isSelected() ||
authPlainCheckbox.isSelected();
sendLocalUsernameCheckbox.setEnabled(value);
}
private void handleDesktopSize()
{
desktopWidthInput.setEnabled(desktopSizeCheckbox.isSelected());
desktopHeightInput.setEnabled(desktopSizeCheckbox.isSelected());
}
private void handleRemoteResize()
{
scalingFactorInput.setEnabled(!remoteResizeButton.isSelected());
}
private void handleTunnel()
{
viaCheckbox.setEnabled(tunnelCheckbox.isSelected());
extSSHCheckbox.setEnabled(tunnelCheckbox.isSelected());
if (tunnelCheckbox.isSelected()) {
JComponent[] components = { viaUserInput, viaHostInput, viaPortInput };
for (JComponent c : components)
c.setEnabled(viaCheckbox.isSelected());
sshClientInput.setEnabled(extSSHCheckbox.isSelected());
sshClientChooser.setEnabled(extSSHCheckbox.isSelected());
sshArgsDefaultButton.setEnabled(extSSHCheckbox.isSelected());
sshArgsCustomButton.setEnabled(extSSHCheckbox.isSelected());
sshArgsInput.setEnabled(extSSHCheckbox.isSelected());
sshConfigInput.setEnabled(!extSSHCheckbox.isSelected());
sshConfigChooser.setEnabled(!extSSHCheckbox.isSelected());
sshKeyFileInput.setEnabled(!extSSHCheckbox.isSelected());
sshKeyFileChooser.setEnabled(!extSSHCheckbox.isSelected());
} else {
JComponent[] components = {
viaUserInput, viaHostInput, viaPortInput, sshClientInput,
sshClientChooser, sshArgsDefaultButton, sshArgsCustomButton,
sshArgsInput, sshConfigInput, sshConfigChooser, sshKeyFileInput,
sshKeyFileChooser, };
for (JComponent c : components)
c.setEnabled(false);
}
}
private void handleVia()
{
if (tunnelCheckbox.isSelected()) {
viaUserInput.setEnabled(viaCheckbox.isSelected());
viaHostInput.setEnabled(viaCheckbox.isSelected());
viaPortInput.setEnabled(viaCheckbox.isSelected());
}
}
private void handleExtSSH()
{
if (tunnelCheckbox.isSelected()) {
sshClientInput.setEnabled(extSSHCheckbox.isSelected());
sshClientChooser.setEnabled(extSSHCheckbox.isSelected());
sshArgsDefaultButton.setEnabled(extSSHCheckbox.isSelected());
sshArgsCustomButton.setEnabled(extSSHCheckbox.isSelected());
sshConfigInput.setEnabled(!extSSHCheckbox.isSelected());
sshConfigChooser.setEnabled(!extSSHCheckbox.isSelected());
sshKeyFileInput.setEnabled(!extSSHCheckbox.isSelected());
sshKeyFileChooser.setEnabled(!extSSHCheckbox.isSelected());
if (sshArgsCustomButton.isSelected())
sshArgsInput.setEnabled(extSSHCheckbox.isSelected());
else
sshArgsInput.setEnabled(false);
}
}
private void handleEmbed()
{
if (embed.getValue()) {
desktopSizeCheckbox.setEnabled(false);
desktopWidthInput.setEnabled(false);
desktopHeightInput.setEnabled(false);
remoteResizeButton.setEnabled(false);
remoteScaleButton.setEnabled(false);
fullScreenCheckbox.setEnabled(false);
fullScreenAllMonitorsCheckbox.setEnabled(false);
scalingFactorInput.setEnabled(false);
}
}
private void handleRfbState()
{
CConn cc = VncViewer.cc;
if (cc != null && cc.state() == CConnection.RFBSTATE_NORMAL) {
JComponent[] components = {
encNoneCheckbox, encTLSCheckbox, encX509Checkbox, authNoneCheckbox,
authVncCheckbox, authVncCheckbox, authIdentCheckbox, authPlainCheckbox,
sendLocalUsernameCheckbox, caInput, caChooser, crlInput, crlChooser,
sharedCheckbox, tunnelCheckbox, viaCheckbox, viaUserInput, viaHostInput,
viaPortInput, extSSHCheckbox, sshClientInput, sshClientChooser,
sshArgsDefaultButton, sshArgsCustomButton, sshArgsInput, sshConfigInput,
sshKeyFileInput, sshConfigChooser, sshKeyFileChooser,
};
for (JComponent c : components)
c.setEnabled(false);
}
}
static LogWriter vlog = new LogWriter("OptionsDialog");
}