private void initGui() {
    Container pane = getContentPane();
    pane.setLayout(new BorderLayout());

    biblatexMode = Globals.prefs.getBoolean("biblatexMode");

    JPanel main = new JPanel(), buttons = new JPanel(), right = new JPanel();
    main.setLayout(new BorderLayout());
    right.setLayout(new GridLayout(biblatexMode ? 2 : 1, 2));

    java.util.List<String> entryTypes = new ArrayList<String>();
    for (String s : BibtexEntryType.ALL_TYPES.keySet()) {
      entryTypes.add(s);
    }

    typeComp = new EntryTypeList(entryTypes);
    typeComp.addListSelectionListener(this);
    typeComp.addAdditionActionListener(this);
    typeComp.addDefaultActionListener(new DefaultListener());
    typeComp.setListSelectionMode(ListSelectionModel.SINGLE_SELECTION);

    // typeComp.setEnabled(false);
    reqComp =
        new FieldSetComponent(
            Globals.lang("Required fields"), new ArrayList<String>(), preset, true, true);
    reqComp.setEnabled(false);
    reqComp.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
    ListDataListener dataListener = new DataListener();
    reqComp.addListDataListener(dataListener);
    optComp =
        new FieldSetComponent(
            Globals.lang("Optional fields"), new ArrayList<String>(), preset, true, true);
    optComp.setEnabled(false);
    optComp.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
    optComp.addListDataListener(dataListener);
    right.add(reqComp);
    right.add(optComp);

    if (biblatexMode) {
      optComp2 =
          new FieldSetComponent(
              Globals.lang("Optional fields") + " 2", new ArrayList<String>(), preset, true, true);
      optComp2.setEnabled(false);
      optComp2.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
      optComp2.addListDataListener(dataListener);
      right.add(new JPanel());
      right.add(optComp2);
    }

    // right.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(),
    // Globals.lang("Fields")));
    right.setBorder(BorderFactory.createEtchedBorder());
    ok = new JButton("Ok");
    cancel = new JButton(Globals.lang("Cancel"));
    apply = new JButton(Globals.lang("Apply"));
    ok.addActionListener(this);
    apply.addActionListener(this);
    cancel.addActionListener(this);
    ButtonBarBuilder bb = new ButtonBarBuilder(buttons);
    buttons.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
    bb.addGlue();
    bb.addButton(ok);
    bb.addButton(apply);
    bb.addButton(cancel);
    bb.addGlue();

    AbstractAction closeAction =
        new AbstractAction() {

          @Override
          public void actionPerformed(ActionEvent e) {
            dispose();
          }
        };
    ActionMap am = main.getActionMap();
    InputMap im = main.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
    im.put(Globals.prefs.getKey("Close dialog"), "close");
    am.put("close", closeAction);

    // con.fill = GridBagConstraints.BOTH;
    // con.weightx = 0.3;
    // con.weighty = 1;
    // gbl.setConstraints(typeComp, con);
    main.add(typeComp, BorderLayout.WEST);
    main.add(right, BorderLayout.CENTER);
    main.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
    pane.add(main, BorderLayout.CENTER);
    pane.add(buttons, BorderLayout.SOUTH);
    pack();
  }
  private void applyChanges() {
    valueChanged(new ListSelectionEvent(new JList(), 0, 0, false));
    // Iterate over our map of required fields, and list those types if necessary:

    List<String> types = typeComp.getFields();
    for (Map.Entry<String, List<String>> stringListEntry : reqLists.entrySet()) {
      if (!types.contains(stringListEntry.getKey())) {
        continue;
      }

      List<String> reqFields = stringListEntry.getValue();
      List<String> optFields = optLists.get(stringListEntry.getKey());
      List<String> opt2Fields = opt2Lists.get(stringListEntry.getKey());
      String[] reqStr = new String[reqFields.size()];
      reqStr = reqFields.toArray(reqStr);
      String[] optStr = new String[optFields.size()];
      optStr = optFields.toArray(optStr);
      String[] opt2Str;
      if (opt2Fields != null) {
        opt2Str = opt2Fields.toArray(new String[opt2Fields.size()]);
      } else {
        opt2Str = new String[0];
      }

      // If this type is already existing, check if any changes have
      // been made
      boolean changesMade = true;

      if (defaulted.contains(stringListEntry.getKey())) {
        // This type should be reverted to its default setup.
        // System.out.println("Defaulting: "+typeName);
        String nm = StringUtil.nCase(stringListEntry.getKey());
        BibtexEntryType.removeType(nm);

        updateTypesForEntries(nm);
        continue;
      }

      BibtexEntryType oldType = BibtexEntryType.getType(stringListEntry.getKey());
      if (oldType != null) {
        String[] oldReq = oldType.getRequiredFields(), oldOpt = oldType.getOptionalFields();
        if (biblatexMode) {
          String[] priOpt = oldType.getPrimaryOptionalFields();
          String[] secOpt = Util.getRemainder(oldOpt, priOpt);
          if (equalArrays(oldReq, reqStr)
              && equalArrays(oldOpt, optStr)
              && equalArrays(secOpt, opt2Str)) {
            changesMade = false;
          }
        } else if (equalArrays(oldReq, reqStr) && equalArrays(oldOpt, optStr)) {
          changesMade = false;
        }
      }

      if (changesMade) {
        // System.out.println("Updating: "+typeName);
        CustomEntryType typ =
            biblatexMode
                ? new CustomEntryType(
                    StringUtil.nCase(stringListEntry.getKey()), reqStr, optStr, opt2Str)
                : new CustomEntryType(StringUtil.nCase(stringListEntry.getKey()), reqStr, optStr);

        BibtexEntryType.ALL_TYPES.put(stringListEntry.getKey().toLowerCase(), typ);
        updateTypesForEntries(typ.getName());
      }
    }

    Set<Object> toRemove = new HashSet<Object>();
    for (String o : BibtexEntryType.ALL_TYPES.keySet()) {
      if (!types.contains(o)) {
        toRemove.add(o);
      }
    }

    // Remove those that should be removed:
    if (!toRemove.isEmpty()) {
      for (Object aToRemove : toRemove) {
        typeDeletion((String) aToRemove);
      }
    }

    updateTables();
  }