/** Builds the Network panel. */
  protected JPanel buildNetworkPanel() {
    JGridBagPanel p = new JGridBagPanel();
    p.setBorder(BorderFactory.createEmptyBorder(16, 16, 16, 16));

    JLabel proxyLabel = new JLabel(Resources.getString(PREFERENCE_KEY_LABEL_HTTP_PROXY));
    JLabel hostLabel = new JLabel(Resources.getString(PREFERENCE_KEY_LABEL_HOST));
    JLabel portLabel = new JLabel(Resources.getString(PREFERENCE_KEY_LABEL_PORT));
    JLabel colonLabel = new JLabel(Resources.getString(PREFERENCE_KEY_LABEL_COLON));
    Font f = hostLabel.getFont();
    float size = f.getSize2D() * 0.85f;
    f = f.deriveFont(size);
    hostLabel.setFont(f);
    portLabel.setFont(f);
    host = new JTextField();
    host.setPreferredSize(new Dimension(200, 20));
    port = new JTextField();
    port.setPreferredSize(new Dimension(40, 20));

    p.add(proxyLabel, 0, 0, 1, 1, EAST, NONE, 0, 0);
    p.add(host, 1, 0, 1, 1, WEST, HORIZONTAL, 0, 0);
    p.add(colonLabel, 2, 0, 1, 1, WEST, NONE, 0, 0);
    p.add(port, 3, 0, 1, 1, WEST, HORIZONTAL, 0, 0);
    p.add(hostLabel, 1, 1, 1, 1, WEST, NONE, 0, 0);
    p.add(portLabel, 3, 1, 1, 1, WEST, NONE, 0, 0);

    return p;
  }
  /** Builds the Stylesheet panel. */
  protected JPanel buildStylesheetPanel() {
    JGridBagPanel.InsetsManager im =
        new JGridBagPanel.InsetsManager() {
          protected Insets i1 = new Insets(5, 5, 0, 0);
          protected Insets i2 = new Insets(5, 0, 0, 0);
          protected Insets i3 = new Insets(0, 5, 0, 0);
          protected Insets i4 = new Insets(0, 0, 0, 0);

          public Insets getInsets(int x, int y) {
            if (y >= 1 && y <= 5) {
              return x == 0 ? i2 : i1;
            }
            return x == 0 ? i4 : i3;
          }
        };

    JGridBagPanel p = new JGridBagPanel(im);
    p.setBorder(BorderFactory.createEmptyBorder(16, 16, 16, 16));

    userStylesheetEnabled =
        new JCheckBox(Resources.getString(PREFERENCE_KEY_LABEL_ENABLE_USER_STYLESHEET));
    userStylesheetEnabled.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            boolean b = userStylesheetEnabled.isSelected();
            userStylesheetLabel.setEnabled(b);
            userStylesheet.setEnabled(b);
            userStylesheetBrowse.setEnabled(b);
          }
        });

    userStylesheetLabel = new JLabel(Resources.getString(PREFERENCE_KEY_LABEL_USER_STYLESHEET));
    userStylesheet = new JTextField();
    userStylesheetBrowse = new JButton(Resources.getString(PREFERENCE_KEY_LABEL_BROWSE));
    userStylesheetBrowse.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            File f = null;
            if (Platform.isOSX) {
              FileDialog fileDialog =
                  new FileDialog(
                      (Frame) getOwner(), Resources.getString(PREFERENCE_KEY_BROWSE_TITLE));
              fileDialog.setVisible(true);
              String filename = fileDialog.getFile();
              if (filename != null) {
                String dirname = fileDialog.getDirectory();
                f = new File(dirname, filename);
              }
            } else {
              JFileChooser fileChooser = new JFileChooser(new File("."));
              fileChooser.setDialogTitle(Resources.getString(PREFERENCE_KEY_BROWSE_TITLE));
              fileChooser.setFileHidingEnabled(false);

              int choice = fileChooser.showOpenDialog(PreferenceDialog.this);
              if (choice == JFileChooser.APPROVE_OPTION) {
                f = fileChooser.getSelectedFile();
              }
            }
            if (f != null) {
              try {
                userStylesheet.setText(f.getCanonicalPath());
              } catch (IOException ex) {
              }
            }
          }
        });

    JLabel mediaLabel = new JLabel(Resources.getString(PREFERENCE_KEY_LABEL_CSS_MEDIA_TYPES));
    mediaLabel.setVerticalAlignment(SwingConstants.TOP);
    mediaList = new JList();
    mediaList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    mediaList.setModel(mediaListModel);
    mediaList.addListSelectionListener(
        new ListSelectionListener() {
          public void valueChanged(ListSelectionEvent e) {
            updateMediaListButtons();
          }
        });
    mediaListModel.addListDataListener(
        new ListDataListener() {
          public void contentsChanged(ListDataEvent e) {
            updateMediaListButtons();
          }

          public void intervalAdded(ListDataEvent e) {
            updateMediaListButtons();
          }

          public void intervalRemoved(ListDataEvent e) {
            updateMediaListButtons();
          }
        });
    JScrollPane scrollPane = new JScrollPane();
    scrollPane.setBorder(BorderFactory.createLoweredBevelBorder());
    scrollPane.getViewport().add(mediaList);

    JButton addButton = new JButton(Resources.getString(PREFERENCE_KEY_LABEL_ADD));
    addButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            CSSMediaPanel.AddMediumDialog dialog =
                new CSSMediaPanel.AddMediumDialog(PreferenceDialog.this);
            dialog.pack();
            dialog.setVisible(true);

            if (dialog.getReturnCode() == CSSMediaPanel.AddMediumDialog.CANCEL_OPTION
                || dialog.getMedium() == null) {
              return;
            }

            String medium = dialog.getMedium().trim();
            if (medium.length() == 0 || mediaListModel.contains(medium)) {
              return;
            }

            for (int i = 0; i < mediaListModel.size() && medium != null; ++i) {
              String s = (String) mediaListModel.getElementAt(i);
              int c = medium.compareTo(s);
              if (c == 0) {
                medium = null;
              } else if (c < 0) {
                mediaListModel.insertElementAt(medium, i);
                medium = null;
              }
            }
            if (medium != null) {
              mediaListModel.addElement(medium);
            }
          }
        });

    mediaListRemoveButton = new JButton(Resources.getString(PREFERENCE_KEY_LABEL_REMOVE));
    mediaListRemoveButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            int index = mediaList.getSelectedIndex();
            mediaList.clearSelection();
            if (index >= 0) {
              mediaListModel.removeElementAt(index);
            }
          }
        });

    mediaListClearButton = new JButton(Resources.getString(PREFERENCE_KEY_LABEL_CLEAR));
    mediaListClearButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            mediaList.clearSelection();
            mediaListModel.removeAllElements();
          }
        });

    p.add(userStylesheetEnabled, 1, 0, 2, 1, WEST, NONE, 0, 0);
    p.add(userStylesheetLabel, 0, 1, 1, 1, EAST, NONE, 0, 0);
    p.add(userStylesheet, 1, 1, 1, 1, WEST, HORIZONTAL, 1, 0);
    p.add(userStylesheetBrowse, 2, 1, 1, 1, WEST, HORIZONTAL, 0, 0);
    p.add(mediaLabel, 0, 2, 1, 1, EAST, VERTICAL, 0, 0);
    p.add(scrollPane, 1, 2, 1, 4, WEST, BOTH, 1, 1);
    p.add(new JPanel(), 2, 2, 1, 1, WEST, BOTH, 0, 1);
    p.add(addButton, 2, 3, 1, 1, SOUTHWEST, HORIZONTAL, 0, 0);
    p.add(mediaListRemoveButton, 2, 4, 1, 1, SOUTHWEST, HORIZONTAL, 0, 0);
    p.add(mediaListClearButton, 2, 5, 1, 1, SOUTHWEST, HORIZONTAL, 0, 0);

    return p;
  }
  /** Builds the Security panel. */
  protected JPanel buildSecurityPanel() {
    JGridBagPanel.InsetsManager im =
        new JGridBagPanel.InsetsManager() {
          protected Insets i1 = new Insets(5, 5, 0, 0);
          protected Insets i2 = new Insets(5, 0, 0, 0);
          protected Insets i3 = new Insets(0, 5, 0, 0);
          protected Insets i4 = new Insets(0, 0, 0, 0);

          public Insets getInsets(int x, int y) {
            if (y == 1 || y == 3 || y == 5 || y == 6) {
              return x == 0 ? i2 : i1;
            }
            return x == 0 ? i4 : i3;
          }
        };

    JGridBagPanel p = new JGridBagPanel(im);
    p.setBorder(BorderFactory.createEmptyBorder(16, 16, 16, 16));

    enforceSecureScripting =
        new JCheckBox(Resources.getString(PREFERENCE_KEY_LABEL_ENFORCE_SECURE_SCRIPTING));
    enforceSecureScripting.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            boolean b = enforceSecureScripting.isSelected();
            grantScriptFileAccess.setEnabled(b);
            grantScriptNetworkAccess.setEnabled(b);
          }
        });

    JLabel grantScript =
        new JLabel(Resources.getString(PREFERENCE_KEY_LABEL_GRANT_SCRIPTS_ACCESS_TO));
    grantScript.setVerticalAlignment(SwingConstants.TOP);
    grantScript.setOpaque(true);
    grantScriptFileAccess = new JCheckBox(Resources.getString(PREFERENCE_KEY_LABEL_FILE_SYSTEM));
    grantScriptNetworkAccess = new JCheckBox(Resources.getString(PREFERENCE_KEY_LABEL_ALL_NETWORK));

    JLabel loadScripts = new JLabel(Resources.getString(PREFERENCE_KEY_LABEL_LOAD_SCRIPTS));
    loadScripts.setVerticalAlignment(SwingConstants.TOP);
    loadJava = new JCheckBox(Resources.getString(PREFERENCE_KEY_LABEL_JAVA_JAR_FILES));
    loadEcmascript = new JCheckBox(Resources.getString(PREFERENCE_KEY_LABEL_ECMASCRIPT));

    String[] origins = {
      Resources.getString(PREFERENCE_KEY_LABEL_ORIGIN_ANY),
      Resources.getString(PREFERENCE_KEY_LABEL_ORIGIN_DOCUMENT),
      Resources.getString(PREFERENCE_KEY_LABEL_ORIGIN_EMBEDDED),
      Resources.getString(PREFERENCE_KEY_LABEL_ORIGIN_NONE)
    };
    JLabel scriptOriginLabel =
        new JLabel(Resources.getString(PREFERENCE_KEY_LABEL_ALLOWED_SCRIPT_ORIGIN));
    allowedScriptOrigin = new JComboBox(origins);
    JLabel resourceOriginLabel =
        new JLabel(Resources.getString(PREFERENCE_KEY_LABEL_ALLOWED_RESOURCE_ORIGIN));
    allowedResourceOrigin = new JComboBox(origins);

    p.add(enforceSecureScripting, 1, 0, 1, 1, WEST, NONE, 1, 0);
    p.add(grantScript, 0, 1, 1, 1, EAST, NONE, 1, 0);
    p.add(grantScriptFileAccess, 1, 1, 1, 1, WEST, NONE, 1, 0);
    p.add(grantScriptNetworkAccess, 1, 2, 1, 1, WEST, NONE, 1, 0);
    p.add(loadScripts, 0, 3, 1, 1, EAST, NONE, 1, 0);
    p.add(loadJava, 1, 3, 1, 1, WEST, NONE, 1, 0);
    p.add(loadEcmascript, 1, 4, 1, 1, WEST, NONE, 1, 0);
    p.add(scriptOriginLabel, 0, 5, 1, 1, EAST, NONE, 1, 0);
    p.add(allowedScriptOrigin, 1, 5, 1, 1, WEST, NONE, 1, 0);
    p.add(resourceOriginLabel, 0, 6, 1, 1, EAST, NONE, 1, 0);
    p.add(allowedResourceOrigin, 1, 6, 1, 1, WEST, NONE, 1, 0);

    return p;
  }
  /** Builds the General panel. */
  protected JPanel buildGeneralPanel() {
    JGridBagPanel.InsetsManager im =
        new JGridBagPanel.InsetsManager() {
          protected Insets i1 = new Insets(5, 5, 0, 0);
          protected Insets i2 = new Insets(5, 0, 0, 0);
          protected Insets i3 = new Insets(0, 5, 0, 0);
          protected Insets i4 = new Insets(0, 0, 0, 0);

          public Insets getInsets(int x, int y) {
            if (y == 4 || y == 9) {
              return x == 0 ? i2 : i1;
            }
            return x == 0 ? i4 : i3;
          }
        };

    JGridBagPanel p = new JGridBagPanel(im);
    p.setBorder(BorderFactory.createEmptyBorder(16, 16, 16, 16));

    JLabel renderingLabel = new JLabel(Resources.getString(PREFERENCE_KEY_LABEL_RENDERING_OPTIONS));
    enableDoubleBuffering =
        new JCheckBox(Resources.getString(PREFERENCE_KEY_LABEL_ENABLE_DOUBLE_BUFFERING));
    enableDoubleBuffering.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent evt) {
            showRendering.setEnabled(enableDoubleBuffering.isSelected());
          }
        });
    showRendering = new JCheckBox(Resources.getString(PREFERENCE_KEY_LABEL_SHOW_RENDERING));
    Insets in = showRendering.getMargin();
    showRendering.setMargin(new Insets(in.top, in.left + 24, in.bottom, in.right));
    selectionXorMode = new JCheckBox(Resources.getString(PREFERENCE_KEY_LABEL_SELECTION_XOR_MODE));
    autoAdjustWindow = new JCheckBox(Resources.getString(PREFERENCE_KEY_LABEL_AUTO_ADJUST_WINDOW));
    JLabel animLabel =
        new JLabel(Resources.getString(PREFERENCE_KEY_LABEL_ANIMATION_RATE_LIMITING));
    animationLimitCPU =
        new JRadioButton(Resources.getString(PREFERENCE_KEY_LABEL_ANIMATION_LIMIT_CPU));
    JPanel cpuPanel = new JPanel();
    cpuPanel.setLayout(new FlowLayout(FlowLayout.LEADING, 3, 0));
    cpuPanel.setBorder(BorderFactory.createEmptyBorder(0, 24, 0, 0));
    animationLimitCPUAmount = new JTextField();
    animationLimitCPUAmount.setPreferredSize(new Dimension(40, 20));
    cpuPanel.add(animationLimitCPUAmount);
    animationLimitCPULabel = new JLabel(Resources.getString(PREFERENCE_KEY_LABEL_PERCENT));
    cpuPanel.add(animationLimitCPULabel);
    animationLimitFPS =
        new JRadioButton(Resources.getString(PREFERENCE_KEY_LABEL_ANIMATION_LIMIT_FPS));
    JPanel fpsPanel = new JPanel();
    fpsPanel.setLayout(new FlowLayout(FlowLayout.LEADING, 3, 0));
    fpsPanel.setBorder(BorderFactory.createEmptyBorder(0, 24, 0, 0));
    animationLimitFPSAmount = new JTextField();
    animationLimitFPSAmount.setPreferredSize(new Dimension(40, 20));
    fpsPanel.add(animationLimitFPSAmount);
    animationLimitFPSLabel = new JLabel(Resources.getString(PREFERENCE_KEY_LABEL_FPS));
    fpsPanel.add(animationLimitFPSLabel);
    animationLimitUnlimited =
        new JRadioButton(Resources.getString(PREFERENCE_KEY_LABEL_ANIMATION_LIMIT_UNLIMITED));
    ButtonGroup g = new ButtonGroup();
    g.add(animationLimitCPU);
    g.add(animationLimitFPS);
    g.add(animationLimitUnlimited);
    ActionListener l =
        new ActionListener() {
          public void actionPerformed(ActionEvent evt) {
            boolean b = animationLimitCPU.isSelected();
            animationLimitCPUAmount.setEnabled(b);
            animationLimitCPULabel.setEnabled(b);
            b = animationLimitFPS.isSelected();
            animationLimitFPSAmount.setEnabled(b);
            animationLimitFPSLabel.setEnabled(b);
          }
        };
    animationLimitCPU.addActionListener(l);
    animationLimitFPS.addActionListener(l);
    animationLimitUnlimited.addActionListener(l);
    JLabel otherLabel = new JLabel(Resources.getString(PREFERENCE_KEY_LABEL_OTHER_OPTIONS));
    showDebugTrace = new JCheckBox(Resources.getString(PREFERENCE_KEY_LABEL_SHOW_DEBUG_TRACE));
    isXMLParserValidating =
        new JCheckBox(Resources.getString(PREFERENCE_KEY_LABEL_IS_XML_PARSER_VALIDATING));

    p.add(renderingLabel, 0, 0, 1, 1, EAST, NONE, 0, 0);
    p.add(enableDoubleBuffering, 1, 0, 1, 1, WEST, NONE, 0, 0);
    p.add(showRendering, 1, 1, 1, 1, WEST, NONE, 0, 0);
    p.add(autoAdjustWindow, 1, 2, 1, 1, WEST, NONE, 0, 0);
    p.add(selectionXorMode, 1, 3, 1, 1, WEST, NONE, 0, 0);
    p.add(animLabel, 0, 4, 1, 1, EAST, NONE, 0, 0);
    p.add(animationLimitCPU, 1, 4, 1, 1, WEST, NONE, 0, 0);
    p.add(cpuPanel, 1, 5, 1, 1, WEST, NONE, 0, 0);
    p.add(animationLimitFPS, 1, 6, 1, 1, WEST, NONE, 0, 0);
    p.add(fpsPanel, 1, 7, 1, 1, WEST, NONE, 0, 0);
    p.add(animationLimitUnlimited, 1, 8, 1, 1, WEST, NONE, 0, 0);
    p.add(otherLabel, 0, 9, 1, 1, EAST, NONE, 0, 0);
    p.add(showDebugTrace, 1, 9, 1, 1, WEST, NONE, 0, 0);
    p.add(isXMLParserValidating, 1, 10, 1, 1, WEST, NONE, 0, 0);

    return p;
  }