+ // TODO: support arrays
+ Format fmt = info.getFormat();
+ if (info.isArray()) {
+ fmt = Format.STRING;
+ }
+
+ switch (fmt) {
+ case BOOLEAN:
+ addBooleanField(info, nhgap);
+ break;
+ case COLOR:
+ addColorField(info, nhgap);
+ break;
+ case FILE:
+ addBrowseField(info, nhgap, false);
+ break;
+ case DIRECTORY:
+ addBrowseField(info, nhgap, true);
+ break;
+ case COMBO_LIST:
+ addComboboxField(info, nhgap, true);
+ break;
+ case FIXED_LIST:
+ addComboboxField(info, nhgap, false);
+ break;
+ case INT:
+ addIntField(info, nhgap);
+ break;
+ case PASSWORD:
+ addPasswordField(info, nhgap);
+ break;
+ case STRING:
+ case LOCALE: // TODO?
+ default:
+ addStringField(info, nhgap);
+ break;
+ }
+ }
+
+ private void reload(Object value) {
+ // We consider "" and NULL to be equals
+ if ("".equals(value)) {
+ value = null;
+ }
+ orig = value;
+ }
+
+ private boolean isChanged(Object newValue) {
+ // We consider "" and NULL to be equals
+ if ("".equals(newValue)) {
+ newValue = null;
+ }
+
+ if (newValue == null) {
+ return orig != null;
+ }
+
+ return !newValue.equals(orig);
+ }
+
+ private void addStringField(final MetaInfo<E> info, int nhgap) {
+ final JTextField field = new JTextField();
+ field.setToolTipText(info.getDescription());
+ String value = info.getString(false);
+ reload(value);
+ field.setText(value);
+
+ info.addReloadedListener(new Runnable() {
+ @Override
+ public void run() {
+ String value = info.getString(false);
+ reload(value);
+ field.setText(value);
+ }
+ });
+ info.addSaveListener(new Runnable() {
+ @Override
+ public void run() {
+ String value = field.getText();
+ if (isChanged(value)) {
+ info.setString(value);
+ }
+ }
+ });
+
+ this.add(label(info, nhgap), BorderLayout.WEST);
+ this.add(field, BorderLayout.CENTER);
+
+ setPreferredSize(field);
+ }
+
+ private void addBooleanField(final MetaInfo<E> info, int nhgap) {
+ final JCheckBox field = new JCheckBox();
+ field.setToolTipText(info.getDescription());
+ Boolean state = info.getBoolean(true);
+
+ // Should not happen!
+ if (state == null) {
+ System.err
+ .println("No default value given for BOOLEAN parameter \""
+ + info.getName() + "\", we consider it is FALSE");
+ state = false;
+ }
+
+ reload(state);
+ field.setSelected(state);
+
+ info.addReloadedListener(new Runnable() {
+ @Override
+ public void run() {
+ Boolean state = info.getBoolean(true);
+ if (state == null) {
+ state = false;
+ }
+
+ reload(state);
+ field.setSelected(state);
+ }
+ });
+ info.addSaveListener(new Runnable() {
+ @Override
+ public void run() {
+ boolean state = field.isSelected();
+ if (isChanged(state)) {
+ info.setBoolean(state);
+ }
+ }
+ });
+
+ this.add(label(info, nhgap), BorderLayout.WEST);
+ this.add(field, BorderLayout.CENTER);
+
+ setPreferredSize(field);
+ }
+
+ private void addColorField(final MetaInfo<E> info, int nhgap) {
+ final JTextField field = new JTextField();
+ field.setToolTipText(info.getDescription());
+ String value = info.getString(false);
+ reload(value);
+ field.setText(value);
+
+ info.addReloadedListener(new Runnable() {
+ @Override
+ public void run() {
+ String value = info.getString(false);
+ reload(value);
+ field.setText(value);
+ }
+ });
+ info.addSaveListener(new Runnable() {
+ @Override
+ public void run() {
+ String value = field.getText();
+ if (isChanged(value)) {
+ info.setString(value);
+ }
+ }
+ });
+
+ this.add(label(info, nhgap), BorderLayout.WEST);
+ JPanel pane = new JPanel(new BorderLayout());
+
+ final JButton colorWheel = new JButton();
+ colorWheel.setIcon(getIcon(17, info.getColor(true)));
+ colorWheel.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ Integer icol = info.getColor(true);
+ if (icol == null) {
+ icol = new Color(255, 255, 255, 255).getRGB();
+ }
+ Color initialColor = new Color(icol, true);
+ Color newColor = JColorChooser.showDialog(ConfigItem.this,
+ info.getName(), initialColor);
+ if (newColor != null) {
+ info.setColor(newColor.getRGB());
+ field.setText(info.getString(false));
+ colorWheel.setIcon(getIcon(17, info.getColor(true)));
+ }
+ }
+ });
+ pane.add(colorWheel, BorderLayout.WEST);
+ pane.add(field, BorderLayout.CENTER);
+ this.add(pane, BorderLayout.CENTER);
+
+ setPreferredSize(pane);
+ }
+
+ private void addBrowseField(final MetaInfo<E> info, int nhgap,
+ final boolean dir) {
+ final JTextField field = new JTextField();
+ field.setToolTipText(info.getDescription());
+ String value = info.getString(false);
+ reload(value);
+ field.setText(value);
+
+ info.addReloadedListener(new Runnable() {
+ @Override
+ public void run() {
+ String value = info.getString(false);
+ reload(value);
+ field.setText(value);
+ }
+ });
+ info.addSaveListener(new Runnable() {
+ @Override
+ public void run() {
+ String value = field.getText();
+ if (isChanged(value)) {
+ info.setString(value);
+ }
+ }
+ });
+
+ JButton browseButton = new JButton("...");
+ browseButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ JFileChooser chooser = new JFileChooser();
+ chooser.setCurrentDirectory(null);
+ chooser.setFileSelectionMode(dir ? JFileChooser.DIRECTORIES_ONLY
+ : JFileChooser.FILES_ONLY);
+ if (chooser.showOpenDialog(ConfigItem.this) == JFileChooser.APPROVE_OPTION) {
+ File file = chooser.getSelectedFile();
+ if (file != null) {
+ String value = file.getAbsolutePath();
+ if (isChanged(value)) {
+ info.setString(value);
+ }
+ field.setText(value);
+ }
+ }