package com.limegroup.gnutella.gui.options.panes; import java.awt.Insets; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.io.IOException; import javax.swing.JRadioButton; import javax.swing.ButtonGroup; import javax.swing.JPanel; import com.limegroup.gnutella.RouterService; import com.limegroup.gnutella.gui.GUIUtils; import com.limegroup.gnutella.gui.GUIMediator; import com.limegroup.gnutella.gui.SizedWholeNumberField; import com.limegroup.gnutella.gui.WholeNumberField; import com.limegroup.gnutella.settings.ConnectionSettings; import com.limegroup.gnutella.util.NetworkUtils; /** * This class defines the panel in the options window that allows the user * to force their ip address to the specified value. */ //2345678|012345678|012345678|012345678|012345678|012345678|012345678|012345678| public final class ForceIPPaneItem extends AbstractPaneItem { /** * Constant <tt>WholeNumberField</tt> instance that holds the port * to force to. */ private final WholeNumberField PORT_FIELD = new SizedWholeNumberField(); /** * Constant handle to the check box that enables or disables this feature. */ private final ButtonGroup BUTTONS = new ButtonGroup(); private final JRadioButton UPNP = new JRadioButton(GUIMediator.getStringResource("OPTIONS_ROUTER_UPNP")); private final JRadioButton PORT = new JRadioButton(GUIMediator.getStringResource("OPTIONS_ROUTER_PORT")); private final JRadioButton NONE = new JRadioButton(GUIMediator.getStringResource("OPTIONS_ROUTER_NOTHING")); /** * The constructor constructs all of the elements of this * <tt>AbstractPaneItem</tt>. * * @param key the key for this <tt>AbstractPaneItem</tt> that the * superclass uses to generate locale-specific keys */ public ForceIPPaneItem(final String key) { super(key); BUTTONS.add(UPNP); BUTTONS.add(PORT); BUTTONS.add(NONE); PORT.addItemListener(new LocalPortListener()); JPanel panel = new JPanel(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); c.gridwidth = GridBagConstraints.REMAINDER; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(0, 0, 0, 6); panel.add(UPNP, c); c.gridwidth = GridBagConstraints.RELATIVE; panel.add(PORT, c); c.gridwidth = GridBagConstraints.REMAINDER; panel.add(PORT_FIELD, c); panel.add(NONE, c); add(GUIUtils.left(panel)); } private void updateState() { PORT_FIELD.setEnabled(PORT.isSelected()); PORT_FIELD.setEditable(PORT.isSelected()); } /** * Listener class that responds to the checking and the * unchecking of the check box specifying whether or not to * use a local ip configuration. It makes the other fields * editable or not editable depending on the state of the * check box. */ private class LocalPortListener implements ItemListener { public void itemStateChanged(ItemEvent e) { updateState(); } } /** * Defines the abstract method in <tt>AbstractPaneItem</tt>.<p> * * Sets the options for the fields in this <tt>PaneItem</tt> when the * window is shown. */ public void initOptions() { if(ConnectionSettings.FORCE_IP_ADDRESS.getValue() && !ConnectionSettings.UPNP_IN_USE.getValue()) PORT.setSelected(true); else if(ConnectionSettings.DISABLE_UPNP.getValue()) NONE.setSelected(true); else UPNP.setSelected(true); PORT_FIELD.setValue(ConnectionSettings.FORCED_PORT.getValue()); updateState(); } /** * Defines the abstract method in <tt>AbstractPaneItem</tt>.<p> * * Applies the options currently set in this window, displaying an * error message to the user if a setting could not be applied. * * @throws IOException if the options could not be applied for some reason */ public boolean applyOptions() throws IOException { boolean restart = false; boolean oldUPNP = ConnectionSettings.UPNP_IN_USE.getValue(); int oldPort = ConnectionSettings.FORCED_PORT.getValue(); boolean oldForce = ConnectionSettings.FORCE_IP_ADDRESS.getValue(); if(UPNP.isSelected()) { if(!ConnectionSettings.UPNP_IN_USE.getValue()) ConnectionSettings.FORCE_IP_ADDRESS.setValue(false); ConnectionSettings.DISABLE_UPNP.setValue(false); if(!oldUPNP) restart = true; } else if(NONE.isSelected()) { ConnectionSettings.FORCE_IP_ADDRESS.setValue(false); ConnectionSettings.DISABLE_UPNP.setValue(true); } else { // PORT.isSelected() int forcedPort = PORT_FIELD.getValue(); if(!NetworkUtils.isValidPort(forcedPort)) { GUIMediator.showError("ERROR_FORCE_IP_PORT_RANGE"); throw new IOException("bad port: "+forcedPort); } ConnectionSettings.DISABLE_UPNP.setValue(false); ConnectionSettings.FORCE_IP_ADDRESS.setValue(true); ConnectionSettings.UPNP_IN_USE.setValue(false); ConnectionSettings.FORCED_PORT.setValue(forcedPort); } // Notify that the address changed if: // 1) The 'forced address' status changed. // or 2) We're forcing and the ports are different. boolean newForce = ConnectionSettings.FORCE_IP_ADDRESS.getValue(); int newPort = ConnectionSettings.FORCED_PORT.getValue(); if(oldForce != newForce || (newForce && (oldPort != newPort))) RouterService.addressChanged(); return false; } public boolean isDirty() { if(ConnectionSettings.FORCE_IP_ADDRESS.getValue() && !ConnectionSettings.UPNP_IN_USE.getValue()) { if (!PORT.isSelected()) { return true; } } else if(ConnectionSettings.DISABLE_UPNP.getValue()) { if (!NONE.isSelected()) { return true; } } else { if (!UPNP.isSelected()) { return true; } } return PORT.isSelected() && PORT_FIELD.getValue() != ConnectionSettings.FORCED_PORT.getValue(); } }