private void resetButtonActionPerformed(ActionEvent evt) {
   Map<String, Field> rfields = Configuration.getConfigurationFields();
   for (Entry<String, Field> entry : rfields.entrySet()) {
     String name = entry.getKey();
     Field field = entry.getValue();
     try {
       ConfigurationItem item = (ConfigurationItem) field.get(null);
       item.unset();
     } catch (IllegalArgumentException | IllegalAccessException ex) {
       // Reflection exceptions. This should never happen
       throw new Error(ex.getMessage());
     }
   }
   Configuration.saveConfig();
   setVisible(false);
   showRestartConfirmDialod();
 }
  @SuppressWarnings("unchecked")
  private void okButtonActionPerformed(ActionEvent evt) {
    boolean modified = false;
    Map<String, Field> fields = Configuration.getConfigurationFields();
    Map<String, Object> values = new HashMap<>();
    for (String name : fields.keySet()) {
      Component c = componentsMap.get(name);
      Object value = null;

      ParameterizedType listType = (ParameterizedType) fields.get(name).getGenericType();
      java.lang.reflect.Type itemType2 = listType.getActualTypeArguments()[0];
      if (!(itemType2 instanceof Class<?>)) {
        continue;
      }

      Class itemType = (Class<?>) itemType2;
      if (name.equals("gui.skin")) {
        value = ((SkinSelect) ((JComboBox<SkinSelect>) c).getSelectedItem()).className;
      } else if (itemType == String.class) {
        value = ((JTextField) c).getText();
      }
      if (itemType == Boolean.class) {
        value = ((JCheckBox) c).isSelected();
      }

      if (itemType == Calendar.class) {
        Calendar cal = Calendar.getInstance();
        try {
          cal.setTime(new SimpleDateFormat().parse(((JTextField) c).getText()));
        } catch (ParseException ex) {
          c.requestFocusInWindow();
          return;
        }
        value = cal;
      }

      if (itemType.isEnum()) {
        String stringValue = (String) ((JComboBox<String>) c).getSelectedItem();
        value = Enum.valueOf(itemType, stringValue);
      }

      try {
        if (itemType == Integer.class) {
          value = Integer.parseInt(((JTextField) c).getText());
        }
        if (itemType == Long.class) {
          value = Long.parseLong(((JTextField) c).getText());
        }
        if (itemType == Double.class) {
          value = Double.parseDouble(((JTextField) c).getText());
        }
        if (itemType == Float.class) {
          value = Float.parseFloat(((JTextField) c).getText());
        }
      } catch (NumberFormatException nfe) {
        if (!((JTextField) c).getText().isEmpty()) {
          c.requestFocusInWindow();
          return;
        } // else null
      }
      values.put(name, value);
    }

    for (String name : fields.keySet()) {
      Component c = componentsMap.get(name);
      Object value = values.get(name);

      Field field = fields.get(name);
      ConfigurationItem item = null;
      try {
        item = (ConfigurationItem) field.get(null);
      } catch (IllegalArgumentException | IllegalAccessException ex) {
        // Reflection exceptions. This should never happen
        throw new Error(ex.getMessage());
      }
      if (item.get() == null || !item.get().equals(value)) {
        if (item.hasValue() || value != null) {
          item.set(value);
          modified = true;
        }
      }
    }
    Configuration.saveConfig();
    setVisible(false);
    if (modified) {
      showRestartConfirmDialod();
    }
  }
  public static void getCategories(
      Map<String, Component> componentsMap,
      Map<String, Component> tabs,
      JComboBox<?> skinComboBox,
      ResourceBundle resourceBundle) {
    Map<String, Map<String, Field>> categorized = new HashMap<>();

    Map<String, Field> fields = Configuration.getConfigurationFields();
    String[] keys = new String[fields.size()];
    keys = fields.keySet().toArray(keys);
    Arrays.sort(keys);

    for (String name : keys) {
      Field field = fields.get(name);
      ConfigurationCategory cat = field.getAnnotation(ConfigurationCategory.class);
      String scat = cat == null ? "other" : cat.value();
      if (!categorized.containsKey(scat)) {
        categorized.put(scat, new HashMap<>());
      }

      categorized.get(scat).put(name, field);
    }

    for (String cat : categorized.keySet()) {
      JPanel configPanel = new JPanel(new SpringLayout());
      int itemCount = 0;
      for (String name : categorized.get(cat).keySet()) {
        Field field = categorized.get(cat).get(name);

        String locName = resourceBundle.getString("config.name." + name);

        try {
          ConfigurationItem item = (ConfigurationItem) field.get(null);

          ParameterizedType listType = (ParameterizedType) field.getGenericType();
          java.lang.reflect.Type itemType2 = listType.getActualTypeArguments()[0];
          if (!(itemType2 instanceof Class<?>)) {
            continue;
          }

          Class itemType = (Class<?>) itemType2;

          String description = resourceBundle.getString("config.description." + name);

          Object defaultValue = Configuration.getDefaultValue(field);
          if (name.equals("gui.skin")) {
            Class c;
            try {
              c = Class.forName((String) defaultValue);
              defaultValue = c.getField("NAME").get(c);
            } catch (ClassNotFoundException | NoSuchFieldException | SecurityException ex) {
              Logger.getLogger(AdvancedSettingsDialog.class.getName()).log(Level.SEVERE, null, ex);
            }
          }

          if (defaultValue != null) {
            description += " (" + resourceBundle.getString("default") + ": " + defaultValue + ")";
          }

          JLabel l = new JLabel(locName, JLabel.TRAILING);
          l.setToolTipText(description);
          configPanel.add(l);
          Component c = null;
          if (name.equals("gui.skin")) {
            skinComboBox.setToolTipText(description);
            skinComboBox.setMaximumSize(
                new Dimension(Integer.MAX_VALUE, skinComboBox.getPreferredSize().height));
            c = skinComboBox;
          } else if ((itemType == String.class)
              || (itemType == Integer.class)
              || (itemType == Long.class)
              || (itemType == Double.class)
              || (itemType == Float.class)
              || (itemType == Calendar.class)) {
            JTextField tf = new JTextField();
            Object val = item.get();
            if (val == null) {
              val = "";
            }
            if (itemType == Calendar.class) {
              tf.setText(new SimpleDateFormat().format(((Calendar) item.get()).getTime()));
            } else {
              tf.setText(val.toString());
            }
            tf.setToolTipText(description);
            tf.setMaximumSize(new Dimension(Integer.MAX_VALUE, tf.getPreferredSize().height));
            c = tf;
          } else if (itemType == Boolean.class) {
            JCheckBox cb = new JCheckBox();
            cb.setSelected((Boolean) item.get());
            cb.setToolTipText(description);
            c = cb;
          } else if (itemType.isEnum()) {
            JComboBox<String> cb = new JComboBox<>();
            @SuppressWarnings("unchecked")
            EnumSet enumValues = EnumSet.allOf(itemType);
            String stringValue = null;
            for (Object enumValue : enumValues) {
              String enumValueStr = enumValue.toString();
              if (stringValue == null) {
                stringValue = enumValueStr;
              }
              cb.addItem(enumValueStr);
            }
            if (item.get() != null) {
              stringValue = item.get().toString();
            }
            cb.setToolTipText(description);
            cb.setSelectedItem(stringValue);
            cb.setMaximumSize(new Dimension(Integer.MAX_VALUE, cb.getPreferredSize().height));
            c = cb;
          } else {
            throw new UnsupportedOperationException(
                "Configuration ttem type '" + itemType.getName() + "' is not supported");
          }

          componentsMap.put(name, c);
          l.setLabelFor(c);
          configPanel.add(c);
        } catch (IllegalArgumentException | IllegalAccessException ex) {
          // Reflection exceptions. This should never happen
          throw new Error(ex.getMessage());
        }

        itemCount++;
      }

      SpringUtilities.makeCompactGrid(
          configPanel,
          itemCount,
          2, // rows, cols
          6,
          6, // initX, initY
          6,
          6); // xPad, yPad
      tabs.put(cat, new JScrollPane(configPanel));
    }
  }