1 /* NetworkSettingsPanel.java -- Sets proxy settings for network. 2 Copyright (C) 2010 Red Hat 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 2 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, but 10 WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program; if not, write to the Free Software 16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 */ 18 19 package net.sourceforge.jnlp.controlpanel; 20 21 import java.awt.BorderLayout; 22 import java.awt.CardLayout; 23 import java.awt.Component; 24 import java.awt.Dimension; 25 import java.awt.FlowLayout; 26 import java.awt.GridBagConstraints; 27 import java.awt.GridBagLayout; 28 import java.awt.GridLayout; 29 import java.awt.event.ActionEvent; 30 import java.awt.event.ActionListener; 31 import java.awt.event.ItemEvent; 32 import java.awt.event.ItemListener; 33 import java.util.ArrayList; 34 35 import javax.swing.Box; 36 import javax.swing.ButtonGroup; 37 import javax.swing.JButton; 38 import javax.swing.JCheckBox; 39 import javax.swing.JLabel; 40 import javax.swing.JOptionPane; 41 import javax.swing.JPanel; 42 import javax.swing.JRadioButton; 43 import javax.swing.JTextField; 44 import javax.swing.text.AttributeSet; 45 import javax.swing.text.BadLocationException; 46 import javax.swing.text.PlainDocument; 47 48 import net.sourceforge.jnlp.config.DeploymentConfiguration; 49 import net.sourceforge.jnlp.runtime.Translator; 50 51 /** 52 * This is the pane used with creating a JDialog version. This allows changing 53 * the network configuration: Proxy 54 * 55 * @author Andrew Su (asu@redhat.com, andrew.su@utoronto.ca) 56 * 57 */ 58 @SuppressWarnings("serial") 59 public class NetworkSettingsPanel extends JPanel implements ActionListener { 60 61 private final DeploymentConfiguration config; 62 63 private JPanel description; 64 private final ArrayList<JPanel> proxyPanels = new ArrayList<>(); // The stuff with editable fields 65 66 /** List of properties used by this panel */ 67 public static String[] properties = { 68 DeploymentConfiguration.KEY_PROXY_TYPE, 69 DeploymentConfiguration.KEY_PROXY_HTTP_HOST, 70 DeploymentConfiguration.KEY_PROXY_HTTP_PORT, 71 DeploymentConfiguration.KEY_PROXY_BYPASS_LOCAL, 72 DeploymentConfiguration.KEY_PROXY_AUTO_CONFIG_URL 73 }; 74 75 /** 76 * Creates a new instance of the network settings panel. 77 * 78 * @param config 79 * Loaded DeploymentConfiguration file. 80 */ NetworkSettingsPanel(DeploymentConfiguration config)81 public NetworkSettingsPanel(DeploymentConfiguration config) { 82 super(); 83 this.config = config; 84 setLayout(new BorderLayout()); 85 86 addComponents(); 87 } 88 89 /** 90 * This adds the components to the panel. 91 */ addComponents()92 protected void addComponents() { 93 JPanel settingPanel = new NamedBorderPanel(Translator.R("CPHeadNetworkSettings")); 94 settingPanel.setLayout(new GridBagLayout()); 95 GridBagConstraints c = new GridBagConstraints(); 96 c.fill = GridBagConstraints.BOTH; 97 c.weightx = 1; 98 c.weighty = 1; 99 c.gridx = 0; 100 101 JLabel networkDesc = new JLabel("<html>" + Translator.R("CPNetworkSettingsDescription") + "<hr /></html>"); 102 103 JLabel[] description = { new JLabel("<html>" + Translator.R("NSDescription-1") + "</html>"), 104 new JLabel("<html>" + Translator.R("NSDescription0") + "</html>"), 105 new JLabel("<html>" + Translator.R("NSDescription1") + "</html>"), 106 new JLabel("<html>" + Translator.R("NSDescription2") + "</html>"), 107 new JLabel("<html>" + Translator.R("NSDescription3") + "</html>") }; 108 109 this.description = new JPanel(new CardLayout()); 110 for (int i = 0; i < description.length; i++) 111 this.description.add(description[i], String.valueOf(i - 1)); 112 113 // Settings for selecting Proxy Server 114 JPanel proxyServerPanel = new JPanel(new GridLayout(0, 1)); 115 JPanel proxyLocationPanel = new JPanel(new GridBagLayout()); 116 JPanel proxyBypassPanel = new JPanel(new FlowLayout(FlowLayout.LEADING)); 117 118 JLabel addressLabel = new JLabel(Translator.R("NSAddress") + ":"); 119 JLabel portLabel = new JLabel(Translator.R("NSPort") + ":"); 120 final JTextField addressField = new JTextField(config.getProperty(properties[1]), 10); 121 addressField.getDocument().addDocumentListener(new DocumentAdapter(config, properties[1])); 122 123 final JTextField portField = new JTextField(5); 124 portField.setDocument(NetworkSettingsPanel.getPortNumberDocument()); 125 portField.getDocument().addDocumentListener(new DocumentAdapter(config, properties[2])); 126 portField.setText(config.getProperty(properties[2])); 127 128 // Create the button which allows setting of other types of proxy. 129 JButton advancedProxyButton = new JButton(Translator.R("NSAdvanced") + "..."); 130 advancedProxyButton.addActionListener(new ActionListener() { 131 @Override 132 public void actionPerformed(ActionEvent e) { 133 AdvancedProxySettingsDialog.showAdvancedProxySettingsDialog(config); 134 addressField.setText(config.getProperty(properties[1])); 135 portField.setText(config.getProperty(properties[2])); 136 } 137 }); 138 139 JCheckBox bypassCheckBox = new JCheckBox(Translator.R("NSBypassLocal"), Boolean.parseBoolean(config.getProperty(properties[3]))); 140 bypassCheckBox.addItemListener(new ItemListener() { 141 @Override 142 public void itemStateChanged(ItemEvent e) { 143 config.setProperty(properties[3], String.valueOf(e.getStateChange() == ItemEvent.SELECTED)); 144 } 145 }); 146 c.gridy = 0; 147 c.gridx = GridBagConstraints.RELATIVE; 148 c.weightx = 0; 149 proxyLocationPanel.add(Box.createHorizontalStrut(20), c); 150 proxyLocationPanel.add(addressLabel, c); 151 c.weightx = 1; 152 proxyLocationPanel.add(addressField, c); 153 c.weightx = 0; 154 proxyLocationPanel.add(portLabel, c); 155 c.weightx = 1; 156 proxyLocationPanel.add(portField, c); 157 c.weightx = 0; 158 proxyLocationPanel.add(advancedProxyButton, c); 159 proxyBypassPanel.add(Box.createHorizontalStrut(5)); 160 proxyBypassPanel.add(bypassCheckBox); 161 162 proxyServerPanel.add(proxyLocationPanel); 163 proxyServerPanel.add(proxyBypassPanel); 164 165 JRadioButton directConnection = new JRadioButton(Translator.R("NSDirectConnection"), config.getProperty(properties[0]).equals("0")); 166 directConnection.setActionCommand("0"); 167 directConnection.addActionListener(this); 168 169 JRadioButton useProxyServer = new JRadioButton(Translator.R("NSManualProxy"), config.getProperty(properties[0]).equals("1")); 170 useProxyServer.setActionCommand("1"); 171 useProxyServer.addActionListener(this); 172 173 JRadioButton useAutoProxyConfigScript = new JRadioButton(Translator.R("NSAutoProxy"), config.getProperty(properties[0]).equals("2")); 174 useAutoProxyConfigScript.setActionCommand("2"); 175 useAutoProxyConfigScript.addActionListener(this); 176 177 JRadioButton useBrowserSettings = new JRadioButton(Translator.R("NSBrowserProxy"), config.getProperty(properties[0]).equals("3")); 178 useBrowserSettings.setActionCommand("3"); 179 useBrowserSettings.addActionListener(this); 180 181 ButtonGroup modeSelect = new ButtonGroup(); 182 modeSelect.add(useBrowserSettings); 183 modeSelect.add(useProxyServer); 184 modeSelect.add(useAutoProxyConfigScript); 185 modeSelect.add(directConnection); 186 187 // Settings for Automatic Proxy Configuration Script 188 JPanel proxyAutoPanel = new JPanel(new GridBagLayout()); 189 JLabel locationLabel = new JLabel(Translator.R("NSScriptLocation") + ":"); 190 final JTextField locationField = new JTextField(config.getProperty(properties[4]), 20); 191 locationField.getDocument().addDocumentListener(new DocumentAdapter(config, properties[4])); 192 193 c.gridx = 0; 194 proxyAutoPanel.add(Box.createHorizontalStrut(20), c); 195 c.gridx = GridBagConstraints.RELATIVE; 196 proxyAutoPanel.add(locationLabel, c); 197 c.weightx = 1; 198 proxyAutoPanel.add(locationField, c); 199 200 c.weighty = 0; 201 c.gridx = 0; 202 c.gridy = 0; 203 settingPanel.add(networkDesc, c); 204 c.gridy = 1; 205 settingPanel.add(this.description, c); 206 c.gridy = 2; 207 settingPanel.add(directConnection, c); 208 c.gridy = 3; 209 settingPanel.add(useBrowserSettings, c); 210 c.gridy = 4; 211 settingPanel.add(useProxyServer, c); 212 c.gridy = 5; 213 settingPanel.add(proxyServerPanel, c); 214 proxyPanels.add(proxyServerPanel); 215 c.gridy = 6; 216 settingPanel.add(useAutoProxyConfigScript, c); 217 c.gridy = 7; 218 settingPanel.add(proxyAutoPanel, c); 219 proxyPanels.add(proxyAutoPanel); 220 221 // Filler to pack the bottom of the panel. 222 Component filler = Box.createRigidArea(new Dimension(1, 1)); 223 c.gridy++; 224 c.weighty = 1; 225 settingPanel.add(filler, c); 226 227 setState(); // depending on default setting we will enable or disable 228 229 add(settingPanel, BorderLayout.CENTER); 230 231 } 232 233 /** 234 * Enable/Disable the panel and all its children recursively. 235 * 236 * @param panel 237 * JPanel which needs to be enabled or disabled. 238 * @param enable 239 * true if the panel and its children are to be enabled, false 240 * otherwise. 241 */ enablePanel(JPanel panel, boolean enable)242 private void enablePanel(JPanel panel, boolean enable) { 243 // This will be used to enable all components in this panel recursively. 244 // Ridiculously slow if lots of nested panels. 245 for (Component c : panel.getComponents()) { 246 if (c instanceof JPanel) { 247 enablePanel((JPanel) c, enable); 248 } 249 c.setEnabled(enable); 250 } 251 } 252 253 @Override actionPerformed(ActionEvent e)254 public void actionPerformed(ActionEvent e) { 255 config.setProperty(properties[0], e.getActionCommand()); 256 setState(); 257 } 258 259 /** 260 * This enables and disables the appropriate panels. 261 */ setState()262 private void setState() { 263 ((CardLayout) this.description.getLayout()).show(this.description, config.getProperty(properties[0])); 264 switch (config.getProperty(properties[0])) { 265 case "0": 266 for (JPanel panel : proxyPanels) 267 enablePanel(panel, false); 268 break; 269 case "1": 270 enablePanel(proxyPanels.get(1), false); 271 enablePanel(proxyPanels.get(0), true); 272 break; 273 case "2": 274 enablePanel(proxyPanels.get(0), false); 275 enablePanel(proxyPanels.get(1), true); 276 break; 277 case "3": 278 for (JPanel panel : proxyPanels) 279 enablePanel(panel, false); 280 break; 281 } 282 } 283 284 /** 285 * Creates a PlainDocument that only take numbers if it will create a valid port number. 286 * @return PlainDocument which will ensure numeric values only and is a valid port number. 287 */ getPortNumberDocument()288 public static PlainDocument getPortNumberDocument(){ 289 return new PlainDocument(){ 290 @Override 291 public void insertString(int offs, String str, AttributeSet a) throws BadLocationException { 292 if (str != null) { 293 try { 294 Integer.valueOf(str); 295 int val = Integer.valueOf(this.getText(0, this.getLength()) + str); 296 if (val < 1 || val > 65535) { // Invalid port number if true 297 throw new NumberFormatException("Invalid port number"); 298 } 299 super.insertString(offs, str, a); 300 } catch (Exception e) { 301 JOptionPane.showMessageDialog(null, Translator.R("CPInvalidPort"), Translator.R("CPInvalidPortTitle") 302 , JOptionPane.WARNING_MESSAGE); 303 } 304 } 305 } 306 }; 307 } 308 } 309