Ignore:
Timestamp:
2003-05-27T15:49:22+12:00 (21 years ago)
Author:
mdewsnip
Message:

Fixed tabbing.

Location:
trunk/gli/src/org/greenstone/gatherer/mem
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/gli/src/org/greenstone/gatherer/mem/Attribute.java

    r4293 r4365  
    4444
    4545public class Attribute
    46     implements Comparable {
    47     public String language = null;
    48     public String name = null;
    49     public String value = null;
    50     public String text = null;
    51     private boolean language_specific = false;
    52     public Attribute(String name, String value) {
    53           this.name = name;
    54           this.value = value;
    55     }
    56     public Attribute(String name, String language, String value) {
    57           this.language = language;
    58           this.language_specific = true;
    59           this.name = name;
    60           this.value = value;
    61     }
    62     public int compareTo(Object other) {
    63           return toString().compareTo(other.toString());
    64     }
    65     public boolean equals(Object other) {
    66           return toString().equals(other.toString());
    67     }
    68     public String get(int column) {
    69           switch(column) {
    70           case 0:
    71                 return name;
    72           case 1:
    73                 if(language_specific) {
    74                      return language;
    75                 }
    76           default:
    77                 return value;
    78           }
    79     }
    80     public String toString() {
    81           if(text == null) {
    82                 if(language_specific) {
    83                      text = name + " [" + language + "] = " + value;
    84                 }
    85                 else {
    86                      text = name + " = " + value;
    87                 }
    88           }
    89           return text;
    90     }
     46    implements Comparable {
     47    public String language = null;
     48    public String name = null;
     49    public String value = null;
     50    public String text = null;
     51    private boolean language_specific = false;
     52    public Attribute(String name, String value) {
     53    this.name = name;
     54    this.value = value;
     55    }
     56    public Attribute(String name, String language, String value) {
     57    this.language = language;
     58    this.language_specific = true;
     59    this.name = name;
     60    this.value = value;
     61    }
     62    public int compareTo(Object other) {
     63    return toString().compareTo(other.toString());
     64    }
     65    public boolean equals(Object other) {
     66    return toString().equals(other.toString());
     67    }
     68    public String get(int column) {
     69    switch(column) {
     70    case 0:
     71        return name;
     72    case 1:
     73        if(language_specific) {
     74        return language;
     75        }
     76    default:
     77        return value;
     78    }
     79    }
     80    public String toString() {
     81    if(text == null) {
     82        if(language_specific) {
     83        text = name + " [" + language + "] = " + value;
     84        }
     85        else {
     86        text = name + " = " + value;
     87        }
     88    }
     89    return text;
     90    }
    9191}
  • trunk/gli/src/org/greenstone/gatherer/mem/AttributeTableModel.java

    r4293 r4365  
    4848 */
    4949public class AttributeTableModel
    50     extends AbstractTableModel {
    51     private Attribute last_attribute = null;
    52     private int last_index = -1;
    53     private int longest[] = null;
    54     private int column_zero_width = 0;
    55     private JScrollPane scroll_pane = null;
    56     private JTable table = null;
    57     private String default_value = null;
    58     private String names[] = null;
    59     private TreeSet attributes = null;
    60     static final private int table_width = 550;
    61 
    62     public AttributeTableModel(TreeSet attributes, String one, String two, String default_value) {
    63           super();
    64           this.attributes = attributes;
    65           this.default_value = default_value;
    66           this.longest = new int[2];
    67           this.names = new String[2];
    68           names[0] = one;
    69           names[1] = two;
    70     }
    71 
    72     public AttributeTableModel(TreeSet attributes, String one, String two, String three, String default_value) {
    73           super();
    74           this.attributes = attributes;
    75           this.default_value = default_value;
    76           this.longest = new int[3];
    77           this.names = new String[3];
    78           names[0] = one;
    79           names[1] = two;
    80           names[2] = three;
    81     }
    82     public void add(Attribute attribute) {
    83           attributes.add(attribute);
    84           // Determine the row index
    85           boolean found = false;
    86           int index = 0;
    87           Iterator iterator = attributes.iterator();
    88           for(int i = 0; !found && iterator.hasNext(); i++) {
    89                 if(attribute == iterator.next()) {
    90                      found = true;
    91                      index = i;
    92                 }
    93           }
    94           // Fire event
    95           fireTableRowsInserted(index, index);
    96     }
    97 
    98     public boolean contains(String value, int column) {
    99           boolean result = false;
    100           Iterator iterator = attributes.iterator();
    101           while(iterator.hasNext() && !result) {
    102                 Attribute attribute = (Attribute) iterator.next();
    103                 if(value.equals(attribute.get(column))) {
    104                      result = true;
    105                 }
    106          
    107           return result;
    108     }
    109 
    110     public Attribute getAttribute(int row) {
    111           if(row != last_index) {
    112                 last_index = row;
    113                 last_attribute = null;
     50    extends AbstractTableModel {
     51    private Attribute last_attribute = null;
     52    private int last_index = -1;
     53    private int longest[] = null;
     54    private int column_zero_width = 0;
     55    private JScrollPane scroll_pane = null;
     56    private JTable table = null;
     57    private String default_value = null;
     58    private String names[] = null;
     59    private TreeSet attributes = null;
     60    static final private int table_width = 550;
     61
     62    public AttributeTableModel(TreeSet attributes, String one, String two, String default_value) {
     63    super();
     64    this.attributes = attributes;
     65    this.default_value = default_value;
     66    this.longest = new int[2];
     67    this.names = new String[2];
     68    names[0] = one;
     69    names[1] = two;
     70    }
     71
     72    public AttributeTableModel(TreeSet attributes, String one, String two, String three, String default_value) {
     73    super();
     74    this.attributes = attributes;
     75    this.default_value = default_value;
     76    this.longest = new int[3];
     77    this.names = new String[3];
     78    names[0] = one;
     79    names[1] = two;
     80    names[2] = three;
     81    }
     82    public void add(Attribute attribute) {
     83    attributes.add(attribute);
     84    // Determine the row index
     85    boolean found = false;
     86    int index = 0;
     87    Iterator iterator = attributes.iterator();
     88    for(int i = 0; !found && iterator.hasNext(); i++) {
     89        if(attribute == iterator.next()) {
     90        found = true;
     91        index = i;
     92        }
     93    }
     94    // Fire event
     95    fireTableRowsInserted(index, index);
     96    }
     97
     98    public boolean contains(String value, int column) {
     99    boolean result = false;
     100    Iterator iterator = attributes.iterator();
     101    while(iterator.hasNext() && !result) {
     102        Attribute attribute = (Attribute) iterator.next();
     103        if(value.equals(attribute.get(column))) {
     104        result = true;
     105        }
     106   
     107    return result;
     108    }
     109
     110    public Attribute getAttribute(int row) {
     111    if(row != last_index) {
     112        last_index = row;
     113        last_attribute = null;
    114114                // Retrieve the value from the set using its iterator
    115                 Iterator iterator = attributes.iterator();
    116                 for(int i = 0; i < row && iterator.hasNext(); i++) {
    117                      iterator.next();
    118                 }
    119                 if(iterator.hasNext()) {
    120                      last_attribute = (Attribute) iterator.next();
    121                 }
    122                 iterator = null;
    123           }
    124           return last_attribute;
    125     }
    126 
    127     public int getColumnCount() {
    128           return names.length;
    129     }
    130 
    131     public String getColumnName(int col) {
    132           return names[col];
    133     }
    134 
    135     public int getRowCount() {
    136           int count = 0;
    137           if(attributes != null) {
    138                 count = attributes.size();
    139           }
    140           return count;
    141     }
    142 
    143     public Object getValueAt(int row, int col) {
    144           String value = null;
    145           Attribute attribute = getAttribute(row);
    146           if(attribute != null) {
    147                 value = attribute.get(col);
    148           }
    149           if(value == null) {
    150                 value = default_value;
    151           }
    152           // Update table column width if necessary
    153           if(value.length() > longest[col]) {
    154                 Component component = table.getCellRenderer(row, col).getTableCellRendererComponent(table, value, false, false, 0, 0);
    155                 int width = component.getPreferredSize().width + 10;
    156                 TableColumn column = table.getColumnModel().getColumn(col);
    157                 if(width > column.getPreferredWidth()) {
    158                      // Calculate default column width
    159                      int default_width = 0;
    160                      int total_width = scroll_pane.getSize().width;
    161                      if(names.length == 2) {
    162                           if(col == 0) {
    163                                 default_width = total_width / 3;
    164                           }
    165                           else {
    166                                 default_width = 2 * (total_width / 3);
    167                           }
    168                      }
    169                      else {
    170                           switch(col) {
    171                           case 0:
    172                                 default_width = (2 * total_width) / 9;
    173                                 break;
    174                           case 1:
    175                                 default_width = total_width / 9;
    176                                 break;
    177                           default:
    178                                 default_width = 2 * (total_width / 3);
    179                                 break;
    180                           }
    181                      }
    182                      if(width > default_width) {
    183                           column.setPreferredWidth(width);
    184                      }
    185                      else {
    186                           column.setPreferredWidth(default_width);
    187                      }
    188                 }
    189                 longest[col] = value.length();
    190           }
    191           return Utility.stripNL(value);
    192     }
    193     public void removeRow(final int row) {
    194           ///ystem.err.println("Remove row " + row);
    195           Attribute attribute = getAttribute(row);
    196           if(attribute != null) {
    197                 attributes.remove(attribute);
     115        Iterator iterator = attributes.iterator();
     116        for(int i = 0; i < row && iterator.hasNext(); i++) {
     117        iterator.next();
     118        }
     119        if(iterator.hasNext()) {
     120        last_attribute = (Attribute) iterator.next();
     121        }
     122        iterator = null;
     123    }
     124    return last_attribute;
     125    }
     126
     127    public int getColumnCount() {
     128    return names.length;
     129    }
     130
     131    public String getColumnName(int col) {
     132    return names[col];
     133    }
     134
     135    public int getRowCount() {
     136    int count = 0;
     137    if(attributes != null) {
     138        count = attributes.size();
     139    }
     140    return count;
     141    }
     142
     143    public Object getValueAt(int row, int col) {
     144    String value = null;
     145    Attribute attribute = getAttribute(row);
     146    if(attribute != null) {
     147        value = attribute.get(col);
     148    }
     149    if(value == null) {
     150        value = default_value;
     151    }
     152    // Update table column width if necessary
     153    if(value.length() > longest[col]) {
     154        Component component = table.getCellRenderer(row, col).getTableCellRendererComponent(table, value, false, false, 0, 0);
     155        int width = component.getPreferredSize().width + 10;
     156        TableColumn column = table.getColumnModel().getColumn(col);
     157        if(width > column.getPreferredWidth()) {
     158        // Calculate default column width
     159        int default_width = 0;
     160        int total_width = scroll_pane.getSize().width;
     161        if(names.length == 2) {
     162            if(col == 0) {
     163            default_width = total_width / 3;
     164            }
     165            else {
     166            default_width = 2 * (total_width / 3);
     167            }
     168        }
     169        else {
     170            switch(col) {
     171            case 0:
     172            default_width = (2 * total_width) / 9;
     173            break;
     174            case 1:
     175            default_width = total_width / 9;
     176            break;
     177            default:
     178            default_width = 2 * (total_width / 3);
     179            break;
     180            }
     181        }
     182        if(width > default_width) {
     183            column.setPreferredWidth(width);
     184        }
     185        else {
     186            column.setPreferredWidth(default_width);
     187        }
     188        }
     189        longest[col] = value.length();
     190    }
     191    return Utility.stripNL(value);
     192    }
     193    public void removeRow(final int row) {
     194    ///ystem.err.println("Remove row " + row);
     195    Attribute attribute = getAttribute(row);
     196    if(attribute != null) {
     197        attributes.remove(attribute);
    198198                // Arg... this caused me a headache for hours.
    199                 last_index = -1;
    200                 fireTableRowsDeleted(row, row);
    201           }
    202     }
    203     public void setScrollPane(JScrollPane scroll_pane) {
    204           this.scroll_pane = scroll_pane;
    205     }
    206     public void setTable(JTable table) {
    207           this.table = table;
    208           this.longest = new int[getColumnCount()];
    209     }
     199        last_index = -1;
     200        fireTableRowsDeleted(row, row);
     201    }
     202    }
     203    public void setScrollPane(JScrollPane scroll_pane) {
     204    this.scroll_pane = scroll_pane;
     205    }
     206    public void setTable(JTable table) {
     207    this.table = table;
     208    this.longest = new int[getColumnCount()];
     209    }
    210210}
  • trunk/gli/src/org/greenstone/gatherer/mem/MEMModel.java

    r4293 r4365  
    4646 */
    4747public class MEMModel
    48     extends DefaultTreeModel {
     48    extends DefaultTreeModel {
    4949
    50     public MEMModel() {
    51           super(new MEMNode());
    52     }
     50    public MEMModel() {
     51    super(new MEMNode());
     52    }
    5353
    54     public void add(MEMNode parent, Object object, int type) {
    55           if(parent == null) {
    56                 parent = (MEMNode) root;
    57           }
    58           MEMNode new_node = new MEMNode(type, object, null);
    59           SynchronizedTreeModelTools.insertNodeInto(this, parent, new_node);
    60     }
     54    public void add(MEMNode parent, Object object, int type) {
     55    if(parent == null) {
     56        parent = (MEMNode) root;
     57    }
     58    MEMNode new_node = new MEMNode(type, object, null);
     59    SynchronizedTreeModelTools.insertNodeInto(this, parent, new_node);
     60    }
    6161
    62     public MEMNode getProfileNode() {
    63           MEMNode node = (MEMNode) root;
    64           return (MEMNode) node.getChildAt(node.getChildCount() - 1);
    65     }
     62    public MEMNode getProfileNode() {
     63    MEMNode node = (MEMNode) root;
     64    return (MEMNode) node.getChildAt(node.getChildCount() - 1);
     65    }
    6666
    67     public void remove(String name, int type) {
    68           MEMNode current = (MEMNode) root;
    69           for(int i = 0; i < current.getChildCount(); i++) {
    70                 MEMNode child = (MEMNode) current.getChildAt(i);
    71                 if(child.toString().equals(name) && type == MEMNode.SET) {
    72                      // Place on AWT event thread to avoid errors.
    73                      SynchronizedTreeModelTools.removeNodeFromParent(this, child);
    74                      return;
    75                 }
     67    public void remove(String name, int type) {
     68    MEMNode current = (MEMNode) root;
     69    for(int i = 0; i < current.getChildCount(); i++) {
     70        MEMNode child = (MEMNode) current.getChildAt(i);
     71        if(child.toString().equals(name) && type == MEMNode.SET) {
     72        // Place on AWT event thread to avoid errors.
     73        SynchronizedTreeModelTools.removeNodeFromParent(this, child);
     74        return;
     75        }
    7676                // This may be the profiler root node, in which case we descend into its children if we're looking for collection file matches.
    77                 else if(type == MEMNode.COLLECTION && child.getType() == MEMNode.PROFILER) {
    78                      for(int j = 0; j < child.getChildCount(); j++) {
    79                           MEMNode inner_child = (MEMNode) child.getChildAt(j);
    80                           if(inner_child.toString().equals(name)) {
    81                                 // Place on AWT event thread to avoid errors.
    82                                 SynchronizedTreeModelTools.removeNodeFromParent(this, inner_child);
    83                                 return;
    84                           }
    85                      }
    86                 }
     77        else if(type == MEMNode.COLLECTION && child.getType() == MEMNode.PROFILER) {
     78        for(int j = 0; j < child.getChildCount(); j++) {
     79            MEMNode inner_child = (MEMNode) child.getChildAt(j);
     80            if(inner_child.toString().equals(name)) {
     81            // Place on AWT event thread to avoid errors.
     82            SynchronizedTreeModelTools.removeNodeFromParent(this, inner_child);
     83            return;
     84            }
     85        }
     86        }
    8787                // If this is a set and we are looking for an element, then iterate through its children. Can't really do this recursively.
    88                 else if(type == MEMNode.ELEMENT && child.getType() == MEMNode.SET) {
    89                      for(int j = 0; j < child.getChildCount(); j++) {
    90                           MEMNode inner_child = (MEMNode) child.getChildAt(j);
    91                           if(inner_child.toString().equals(name)) {
    92                                 // Place on AWT event thread to avoid errors.
    93                                 SynchronizedTreeModelTools.removeNodeFromParent(this, inner_child);
    94                                 return;
    95                           }
    96                      }
    97                 }
    98           }
    99     }
     88        else if(type == MEMNode.ELEMENT && child.getType() == MEMNode.SET) {
     89        for(int j = 0; j < child.getChildCount(); j++) {
     90            MEMNode inner_child = (MEMNode) child.getChildAt(j);
     91            if(inner_child.toString().equals(name)) {
     92            // Place on AWT event thread to avoid errors.
     93            SynchronizedTreeModelTools.removeNodeFromParent(this, inner_child);
     94            return;
     95            }
     96        }
     97        }
     98    }
     99    }
    100100}
  • trunk/gli/src/org/greenstone/gatherer/mem/MEMNode.java

    r4293 r4365  
    4949 */
    5050public class MEMNode
    51     extends DefaultMutableTreeNode {
    52     private AttributeTableModel model = null;
    53     private int type = 0;
    54     static final public int COLLECTION = 0;
    55     static final public int ELEMENT    = 1;
    56     static final public int PROFILER   = 2;
    57     static final public int ROOT       = 3;
    58     static final public int SET        = 4;
     51    extends DefaultMutableTreeNode {
     52    private AttributeTableModel model = null;
     53    private int type = 0;
     54    static final public int COLLECTION = 0;
     55    static final public int ELEMENT    = 1;
     56    static final public int PROFILER   = 2;
     57    static final public int ROOT       = 3;
     58    static final public int SET        = 4;
    5959
    60     public MEMNode() {
    61           this.type = ROOT;
    62     }
     60    public MEMNode() {
     61    this.type = ROOT;
     62    }
    6363
    64     public MEMNode(int type, Object object, MEMNode parent) {
    65           this.userObject = object;
    66           this.parent = parent;
    67           this.type = type;
    68     }
     64    public MEMNode(int type, Object object, MEMNode parent) {
     65    this.userObject = object;
     66    this.parent = parent;
     67    this.type = type;
     68    }
    6969
    70     public Enumeration children() {
    71           if(children == null) {
    72                 mapChildren();
    73           }       
    74           return children.elements();
    75     }
     70    public Enumeration children() {
     71    if(children == null) {
     72        mapChildren();
     73    }         
     74    return children.elements();
     75    }
    7676
    77     public boolean getAllowsChildren() {
    78           return true;
    79     }
     77    public boolean getAllowsChildren() {
     78    return true;
     79    }
    8080
    81     public TreeNode getChildAt(int index) {
    82           if(children == null) {
    83                 mapChildren();
    84           }
    85           return (TreeNode) children.get(index);
    86     }
    87     public int getChildCount() {
    88           if(children == null) {
    89                 mapChildren();
    90           }
    91           return children.size();
    92     }
    93     public ElementWrapper getElement() {
    94           ElementWrapper result = null;
    95           if(type == ELEMENT) {
    96                 result = (ElementWrapper) userObject;
    97           }
    98           return result;
    99     }
    100     public int getIndex(TreeNode node) {
    101           if(children == null) {
    102                 mapChildren();
    103           }
    104           return children.indexOf(node);
    105     }
    106     public AttributeTableModel getModel() {
    107           return model;
    108     }
    109     public TreeNode getParent() {
    110           return parent;
    111     }
    112     public MetadataSet getSet() {
    113           MetadataSet result = null;
    114           if(type == SET) {
    115                 result = (MetadataSet) userObject;
    116           }
    117           return result;
    118     }
    119     public int getType() {
    120           return type;
    121     }
    122     public boolean isLeaf() {
    123           if(children == null) {
    124                 mapChildren();
    125           }
    126           return children.size() == 0;
    127     }
    128     public void setModel(AttributeTableModel model) {
    129           this.model = model;
    130     }
    131     public String toString() {
    132           String text = "error";
    133           if(userObject != null) {
    134                 if(userObject instanceof ElementWrapper) {
    135                      text = ((ElementWrapper)userObject).getName();
    136                 }
    137                 else {
    138                      text = userObject.toString();
    139                 }
    140           }
    141           return text;
    142     }
    143     private void mapChildren() {
    144           ///ystem.err.println("Mapping the children of " + this);
    145           children = new Vector();
    146           // How we build children depends on the node type
    147           switch(type) {
    148           case PROFILER: // Add the collections as children
    149                 ArrayList a = Gatherer.c_man.msm.profiler.getCollections();
    150                 for(int i = 0; i < a.size(); i++) {
    151                      children.add(new MEMNode(COLLECTION, a.get(i), this));
    152                 }
    153                 a = null;
    154                 break;
    155           case ROOT:
    156                 Vector v = Gatherer.c_man.msm.getSets();
    157                 for(int i = 0; i < v.size(); i++) {
    158                      children.add(new MEMNode(SET, v.get(i), this));
    159                 }
    160                 v = null;
     81    public TreeNode getChildAt(int index) {
     82    if(children == null) {
     83        mapChildren();
     84    }
     85    return (TreeNode) children.get(index);
     86    }
     87    public int getChildCount() {
     88    if(children == null) {
     89        mapChildren();
     90    }
     91    return children.size();
     92    }
     93    public ElementWrapper getElement() {
     94    ElementWrapper result = null;
     95    if(type == ELEMENT) {
     96        result = (ElementWrapper) userObject;
     97    }
     98    return result;
     99    }
     100    public int getIndex(TreeNode node) {
     101    if(children == null) {
     102        mapChildren();
     103    }
     104    return children.indexOf(node);
     105    }
     106    public AttributeTableModel getModel() {
     107    return model;
     108    }
     109    public TreeNode getParent() {
     110    return parent;
     111    }
     112    public MetadataSet getSet() {
     113    MetadataSet result = null;
     114    if(type == SET) {
     115        result = (MetadataSet) userObject;
     116    }
     117    return result;
     118    }
     119    public int getType() {
     120    return type;
     121    }
     122    public boolean isLeaf() {
     123    if(children == null) {
     124        mapChildren();
     125    }
     126    return children.size() == 0;
     127    }
     128    public void setModel(AttributeTableModel model) {
     129    this.model = model;
     130    }
     131    public String toString() {
     132    String text = "error";
     133    if(userObject != null) {
     134        if(userObject instanceof ElementWrapper) {
     135        text = ((ElementWrapper)userObject).getName();
     136        }
     137        else {
     138        text = userObject.toString();
     139        }
     140    }
     141    return text;
     142    }
     143    private void mapChildren() {
     144    ///ystem.err.println("Mapping the children of " + this);
     145    children = new Vector();
     146    // How we build children depends on the node type
     147    switch(type) {
     148    case PROFILER: // Add the collections as children
     149        ArrayList a = Gatherer.c_man.msm.profiler.getCollections();
     150        for(int i = 0; i < a.size(); i++) {
     151        children.add(new MEMNode(COLLECTION, a.get(i), this));
     152        }
     153        a = null;
     154        break;
     155    case ROOT:
     156        Vector v = Gatherer.c_man.msm.getSets();
     157        for(int i = 0; i < v.size(); i++) {
     158        children.add(new MEMNode(SET, v.get(i), this));
     159        }
     160        v = null;
    161161                // Add the profile set.
    162                 children.add(new MEMNode(PROFILER, Gatherer.dictionary.get("MEM.Profiles"), this));
    163                 break;
    164           case SET: // Add the elements as children
    165                 MetadataSet set = (MetadataSet) userObject;
    166                 NodeList elements = set.getElements();
    167                 set = null;
    168                 for(int i = 0; i < elements.getLength(); i++) {
    169                      children.add(new MEMNode(ELEMENT, new ElementWrapper((Element) elements.item(i)), this));
    170                 }
    171                 elements = null;
    172                 break;
    173           case COLLECTION:
    174           case ELEMENT:
    175           default:
    176           }
    177     }
     162        children.add(new MEMNode(PROFILER, Gatherer.dictionary.get("MEM.Profiles"), this));
     163        break;
     164    case SET: // Add the elements as children
     165        MetadataSet set = (MetadataSet) userObject;
     166        NodeList elements = set.getElements();
     167        set = null;
     168        for(int i = 0; i < elements.getLength(); i++) {
     169        children.add(new MEMNode(ELEMENT, new ElementWrapper((Element) elements.item(i)), this));
     170        }
     171        elements = null;
     172        break;
     173    case COLLECTION:
     174    case ELEMENT:
     175    default:
     176    }
     177    }
    178178}
  • trunk/gli/src/org/greenstone/gatherer/mem/MetadataEditorManager.java

    r4293 r4365  
    6363 */
    6464public class MetadataEditorManager
    65     extends JDialog {
    66     private AddElementActionListener add_element_action_listener = null;
    67     private AddFileActionListener add_file_action_listener = null;
    68     private AddSetActionListener add_set_action_listener = null;
    69     /** The class used to handle add or edit attribute actions has to be globally available so that we can dispose of its dialog properly. */
    70     private AddOrEditAttributeActionListener add_or_edit_attribute_action_listener = null;
    71 /** The class used to handle add or edit value actions has to be globally available so that we can dispose of its dialog properly. */
    72     private AddOrEditValueActionListener add_or_edit_value_action_listener = null;
    73     private boolean ignore = false;
    74     /** A card layout is used to switch between the two differing detail views. */
    75     private CardLayout card_layout = null;
    76     /** Um, the size of the screen I'd guess. */
    77     private Dimension screen_size = null;
    78     private ElementWrapper current_element = null;
    79     private GValueNode current_value_node = null;
    80     /** A reference to ourselves so our inner classes can dispose of us. */
    81     private MetadataEditorManager self = null;
    82     private int current_attribute = -1;
    83     private JButton add_attribute = null;
    84     private JButton add_element = null;
    85     private JButton add_file = null;
    86     private JButton add_set = null;
    87     private JButton add_value = null;
    88     private JButton close = null;
    89     private JButton edit_attribute = null;
    90     private JButton edit_value = null;
    91     private JButton remove_attribute = null;
    92     private JButton remove_element = null;
    93     private JButton remove_file = null;
    94     private JButton remove_set = null;
    95     private JButton remove_value = null;
    96     private JLabel element_name = null;
    97     private JLabel profile_name = null;
    98     private JLabel set_name = null;
    99     private JScrollPane element_attributes_scroll = null;
    100     private JScrollPane profile_attributes_scroll = null;
    101     private JScrollPane set_attributes_scroll = null;
    102     private JPanel details_pane = null;
    103     private MEMModel model = null;
    104     private MEMNode current_node = null;
    105     private MetadataSet current_set = null;
    106     private Object target = null;
    107     private SmarterTable element_attributes = null;
    108     private SmarterTable profile_attributes = null;
    109     private SmarterTable set_attributes = null;
    110     private SmarterTree element_values = null;
    111     /** A tree that represents the current metadata sets associated with this collection. */
    112     private SmarterTree mds_tree = null;
    113     private String current_collection_file = null;
    114     private String dialog_options[] = null;
    115     /** The default size of the editor dialog. */
    116     static final private Dimension ADD_ELEMENT_SIZE = new Dimension(400,125);
    117     static final private Dimension ADD_FILE_SIZE = new Dimension(400,125);
    118     static final private Dimension ADD_SET_SIZE = new Dimension(400,125);
    119     static final private Dimension ADD_OR_EDIT_ATTRIBUTE_SIZE = new Dimension(600,325);
    120     static final private Dimension ADD_OR_EDIT_VALUE_SIZE = new Dimension(600,440);
    121     static final private Dimension LABEL_SIZE = new Dimension(100,30);
    122     static final private Dimension SIZE = new Dimension(800,480);
    123     static final private String BLANK = "blank";
    124     static final private String ELEMENT = "element";
    125     static final private String PROFILE = "profile";
    126     static final private String SET = "set";
    127     /** Constructor. */
    128     public MetadataEditorManager() {
    129           super(Gatherer.g_man);
    130           this.dialog_options = new String[2];
    131           this.screen_size = Gatherer.config.screen_size;
    132           this.self = this;
    133 
    134           dialog_options[0] = Gatherer.dictionary.get("General.OK");
    135           dialog_options[1] = Gatherer.dictionary.get("General.Cancel");
    136           // Creation
    137           setDefaultCloseOperation(DISPOSE_ON_CLOSE);
    138           setModal(true);
    139           setSize(SIZE);
    140           setTitle(get("Title"));
    141           JPanel content_pane = (JPanel) getContentPane();
    142           content_pane.setBackground(Gatherer.config.getColor("coloring.collection_heading_background", false));
    143          
    144           JPanel upper_pane = new JPanel();
    145           upper_pane.setOpaque(false);
    146          
    147           model = new MEMModel();
    148 
    149           JPanel mds_tree_pane = new JPanel();
    150           mds_tree_pane.setOpaque(false);
    151           mds_tree_pane.setPreferredSize(new Dimension(200,500));
    152           mds_tree = new SmarterTree(model);
    153           mds_tree.setCellRenderer(new MEMTreeCellRenderer());
    154           mds_tree.setRootVisible(false);
    155           mds_tree.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
    156           mds_tree.setForeground(Gatherer.config.getColor("coloring.collection_tree_foreground", false));
    157           mds_tree.setSelectionColor(Gatherer.config.getColor("coloring.collection_selection_background", false));
    158           mds_tree.setSelectedTextColor(Gatherer.config.getColor("coloring.collection_selection_foreground", false));
    159 
    160           details_pane = new JPanel();
    161           details_pane.setOpaque(false);
    162           card_layout = new CardLayout();
    163          
    164           JPanel set_details_pane = new JPanel();
    165           set_details_pane.setOpaque(false);
    166          
    167           JPanel set_name_pane = new JPanel();
    168           set_name_pane.setOpaque(false);
    169           JLabel set_name_label = new JLabel(get("Name"));
    170           set_name_label.setOpaque(false);
    171           set_name_label.setPreferredSize(LABEL_SIZE);
    172           set_name = new JLabel();
    173           set_name.setBorder(BorderFactory.createLoweredBevelBorder());
    174           set_name.setOpaque(false);
    175          
    176           JPanel set_attributes_pane = new JPanel();
    177           set_attributes_pane.setOpaque(false);
    178           set_attributes_scroll = new JScrollPane();
    179           set_attributes_scroll.getViewport().setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
    180           set_attributes_scroll.setOpaque(true);
    181           set_attributes = new SmarterTable();
    182           set_attributes.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    183           set_attributes.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
    184           set_attributes.setForeground(Gatherer.config.getColor("coloring.collection_tree_foreground", false));
    185           set_attributes.setHeadingBackground(Gatherer.config.getColor("coloring.collection_heading_background", false));
    186           set_attributes.setHeadingForeground(Gatherer.config.getColor("coloring.collection_heading_foreground", false));
    187           set_attributes.setOpaque(false);
    188           set_attributes.setSelectionColor(Gatherer.config.getColor("coloring.collection_selection_background", false));
    189           set_attributes.setSelectedTextColor(Gatherer.config.getColor("coloring.collection_selection_foreground", false));
    190           set_attributes.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    191          
    192           JPanel element_details_pane = new JPanel();
    193           element_details_pane.setOpaque(false);
    194 
    195           JPanel element_name_pane = new JPanel();
    196           element_name_pane.setOpaque(false);
    197           JLabel element_name_label = new JLabel(get("Name"));
    198           element_name_label.setOpaque(false);
    199           element_name_label.setPreferredSize(LABEL_SIZE);
    200           element_name = new JLabel();
    201           element_name.setBorder(BorderFactory.createLoweredBevelBorder());
    202           element_name.setOpaque(false);
    203          
    204           JPanel element_inner_pane = new JPanel();
    205           element_inner_pane.setOpaque(false);
    206          
    207           JPanel element_attributes_pane = new JPanel();
    208           element_attributes_pane.setOpaque(false);
    209           element_attributes_scroll = new JScrollPane();
    210           element_attributes_scroll.getViewport().setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
    211           element_attributes_scroll.setOpaque(true);
    212           element_attributes = new SmarterTable();
    213           element_attributes.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    214           element_attributes.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
    215           element_attributes.setForeground(Gatherer.config.getColor("coloring.collection_tree_foreground", false));
    216           element_attributes.setHeadingBackground(Gatherer.config.getColor("coloring.collection_heading_background", false));
    217           element_attributes.setHeadingForeground(Gatherer.config.getColor("coloring.collection_heading_foreground", false));
    218           element_attributes.setSelectionColor(Gatherer.config.getColor("coloring.collection_selection_background", false));
    219           element_attributes.setSelectedTextColor(Gatherer.config.getColor("coloring.collection_selection_foreground", false));
    220           element_attributes.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    221 
    222           JPanel element_values_pane = new JPanel();
    223           element_values_pane.setOpaque(false);
    224           element_values = new SmarterTree();
    225           element_values.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
    226           element_values.setForeground(Gatherer.config.getColor("coloring.collection_tree_foreground", false));
    227           element_values.setRootVisible(false);
    228           element_values.setSelectionColor(Gatherer.config.getColor("coloring.collection_selection_background", false));
    229           element_values.setSelectedTextColor(Gatherer.config.getColor("coloring.collection_selection_foreground", false));
    230          
    231           JPanel profile_details_pane = new JPanel();
    232           profile_details_pane.setOpaque(false);
    233           JPanel profile_name_pane = new JPanel();
    234           profile_name_pane.setOpaque(false);
    235           JLabel profile_name_label = new JLabel(get("Name"));
    236           profile_name_label.setOpaque(false);
    237           profile_name_label.setPreferredSize(LABEL_SIZE);
    238           profile_name = new JLabel();
    239           profile_name.setBorder(BorderFactory.createLoweredBevelBorder());
    240           profile_name.setOpaque(false);
    241          
    242           JPanel profile_attributes_pane = new JPanel();
    243           profile_attributes_pane.setOpaque(false);
    244           profile_attributes_scroll = new JScrollPane();
    245           profile_attributes_scroll.getViewport().setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
    246           profile_attributes_scroll.setOpaque(true);
    247           profile_attributes = new SmarterTable();
    248           profile_attributes.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    249           profile_attributes.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
    250           profile_attributes.setForeground(Gatherer.config.getColor("coloring.collection_tree_foreground", false));
    251           profile_attributes.setHeadingBackground(Gatherer.config.getColor("coloring.collection_heading_background", false));
    252           profile_attributes.setHeadingForeground(Gatherer.config.getColor("coloring.collection_heading_foreground", false));
    253           profile_attributes.setSelectionColor(Gatherer.config.getColor("coloring.collection_selection_background", false));
    254           profile_attributes.setSelectedTextColor(Gatherer.config.getColor("coloring.collection_selection_foreground", false));
    255           profile_attributes.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    256 
    257           JPanel button_pane = new JPanel();
    258           button_pane.setOpaque(false);
    259 
    260           JPanel button_label_pane = new JPanel();
    261           button_label_pane.setOpaque(false);
    262           JLabel attribute_label = new JLabel(get("Attribute"));
    263           attribute_label.setOpaque(false);
    264           //attribute_label.setHorizontalAlignment(JLabel.CENTER);
    265           attribute_label.setPreferredSize(LABEL_SIZE);
    266           JLabel element_label = new JLabel(get("Element"));
    267           element_label.setOpaque(false);
    268           //element_label.setHorizontalAlignment(JLabel.CENTER);
    269           element_label.setPreferredSize(LABEL_SIZE);
    270           JLabel file_label = new JLabel(get("File"));
    271           file_label.setOpaque(false);
    272           //element_label.setHorizontalAlignment(JLabel.CENTER);
    273           file_label.setPreferredSize(LABEL_SIZE);
    274           JLabel set_label = new JLabel(get("Set"));
    275           set_label.setOpaque(false);
    276           //set_label.setHorizontalAlignment(JLabel.CENTER);
    277           set_label.setPreferredSize(LABEL_SIZE);
    278           JLabel value_label = new JLabel(get("Value"));
    279           value_label.setOpaque(false);
    280           //value_label.setHorizontalAlignment(JLabel.CENTER);
    281           value_label.setPreferredSize(LABEL_SIZE);
    282 
    283           JPanel inner_button_pane = new JPanel();
    284           inner_button_pane.setOpaque(false);
    285           add_attribute = new JButton(get("Add"));
    286           add_element = new JButton(get("Add"));
    287           add_file = new JButton(get("Add"));
    288           add_set = new JButton(get("Add"));
    289           add_value = new JButton(get("Add"));
    290           edit_attribute = new JButton(get("Edit"));
    291           edit_value = new JButton(get("Edit"));
    292           remove_attribute = new JButton(get("Remove"));
    293           remove_element = new JButton(get("Remove"));
    294           remove_file = new JButton(get("Remove"));
    295           remove_set = new JButton(get("Remove"));
    296           remove_value = new JButton(get("Remove"));
    297           setControls(false, false, false, false, false, false, false, false, false, false, false, false);
    298 
    299           close = new JButton(get("General.Close"));
    300 
    301           add_element_action_listener = new AddElementActionListener();
    302           add_file_action_listener = new AddFileActionListener();
    303           add_set_action_listener = new AddSetActionListener();
    304           add_or_edit_attribute_action_listener = new AddOrEditAttributeActionListener();
    305           add_or_edit_value_action_listener = new AddOrEditValueActionListener();
    306 
    307           // Some blank panel
    308           JPanel blank_pane = new JPanel();
    309           blank_pane.setOpaque(false);
    310           JPanel edit_file_pane = new JPanel();
    311           edit_file_pane.setOpaque(false);
    312           JPanel edit_element_pane = new JPanel();
    313           edit_element_pane.setOpaque(false);
    314           JPanel edit_set_pane = new JPanel();
    315           edit_set_pane.setOpaque(false);
    316           // Connection
    317 
    318           add_attribute.addActionListener(add_or_edit_attribute_action_listener);
    319           add_element.addActionListener(add_element_action_listener);
    320           add_file.addActionListener(add_file_action_listener);
    321           add_set.addActionListener(add_set_action_listener);
    322           add_value.addActionListener(add_or_edit_value_action_listener);
    323           close.addActionListener(new CloseActionListener());
    324           edit_attribute.addActionListener(add_or_edit_attribute_action_listener);
    325           edit_value.addActionListener(add_or_edit_value_action_listener);
    326           remove_attribute.addActionListener(new RemoveAttributeActionListener());
    327           remove_element.addActionListener(new RemoveElementActionListener());
    328           remove_file.addActionListener(new RemoveFileActionListener());
    329           remove_set.addActionListener(new RemoveSetActionListener());
    330           remove_value.addActionListener(new RemoveValueActionListener());
    331           element_attributes.getSelectionModel().addListSelectionListener(new AttributesListSelectionListener(element_attributes));
    332           profile_attributes.getSelectionModel().addListSelectionListener(new AttributesListSelectionListener(profile_attributes));
    333           set_attributes.getSelectionModel().addListSelectionListener(new AttributesListSelectionListener(set_attributes));
    334           element_values.addTreeSelectionListener(new ElementValuesTreeSelectionListener());
    335           mds_tree.addTreeSelectionListener(new MDSTreeSelectionListener());
    336           // Layout
    337           mds_tree_pane.setLayout(new BorderLayout());
    338           mds_tree_pane.add(new JScrollPane(mds_tree), BorderLayout.CENTER);
    339          
    340           set_name_pane.setLayout(new BorderLayout());
    341           set_name_pane.add(set_name_label, BorderLayout.WEST);
    342           set_name_pane.add(set_name, BorderLayout.CENTER);
     65    extends JDialog {
     66    private AddElementActionListener add_element_action_listener = null;
     67    private AddFileActionListener add_file_action_listener = null;
     68    private AddSetActionListener add_set_action_listener = null;
     69    /** The class used to handle add or edit attribute actions has to be globally available so that we can dispose of its dialog properly. */
     70    private AddOrEditAttributeActionListener add_or_edit_attribute_action_listener = null;
     71    /** The class used to handle add or edit value actions has to be globally available so that we can dispose of its dialog properly. */
     72    private AddOrEditValueActionListener add_or_edit_value_action_listener = null;
     73    private boolean ignore = false;
     74    /** A card layout is used to switch between the two differing detail views. */
     75    private CardLayout card_layout = null;
     76    /** Um, the size of the screen I'd guess. */
     77    private Dimension screen_size = null;
     78    private ElementWrapper current_element = null;
     79    private GValueNode current_value_node = null;
     80    /** A reference to ourselves so our inner classes can dispose of us. */
     81    private MetadataEditorManager self = null;
     82    private int current_attribute = -1;
     83    private JButton add_attribute = null;
     84    private JButton add_element = null;
     85    private JButton add_file = null;
     86    private JButton add_set = null;
     87    private JButton add_value = null;
     88    private JButton close = null;
     89    private JButton edit_attribute = null;
     90    private JButton edit_value = null;
     91    private JButton remove_attribute = null;
     92    private JButton remove_element = null;
     93    private JButton remove_file = null;
     94    private JButton remove_set = null;
     95    private JButton remove_value = null;
     96    private JLabel element_name = null;
     97    private JLabel profile_name = null;
     98    private JLabel set_name = null;
     99    private JScrollPane element_attributes_scroll = null;
     100    private JScrollPane profile_attributes_scroll = null;
     101    private JScrollPane set_attributes_scroll = null;
     102    private JPanel details_pane = null;
     103    private MEMModel model = null;
     104    private MEMNode current_node = null;
     105    private MetadataSet current_set = null;
     106    private Object target = null;
     107    private SmarterTable element_attributes = null;
     108    private SmarterTable profile_attributes = null;
     109    private SmarterTable set_attributes = null;
     110    private SmarterTree element_values = null;
     111    /** A tree that represents the current metadata sets associated with this collection. */
     112    private SmarterTree mds_tree = null;
     113    private String current_collection_file = null;
     114    private String dialog_options[] = null;
     115    /** The default size of the editor dialog. */
     116    static final private Dimension ADD_ELEMENT_SIZE = new Dimension(400,125);
     117    static final private Dimension ADD_FILE_SIZE = new Dimension(400,125);
     118    static final private Dimension ADD_SET_SIZE = new Dimension(400,125);
     119    static final private Dimension ADD_OR_EDIT_ATTRIBUTE_SIZE = new Dimension(600,325);
     120    static final private Dimension ADD_OR_EDIT_VALUE_SIZE = new Dimension(600,440);
     121    static final private Dimension LABEL_SIZE = new Dimension(100,30);
     122    static final private Dimension SIZE = new Dimension(800,480);
     123    static final private String BLANK = "blank";
     124    static final private String ELEMENT = "element";
     125    static final private String PROFILE = "profile";
     126    static final private String SET = "set";
     127    /** Constructor. */
     128    public MetadataEditorManager() {
     129    super(Gatherer.g_man);
     130    this.dialog_options = new String[2];
     131    this.screen_size = Gatherer.config.screen_size;
     132    this.self = this;
     133
     134    dialog_options[0] = Gatherer.dictionary.get("General.OK");
     135    dialog_options[1] = Gatherer.dictionary.get("General.Cancel");
     136    // Creation
     137    setDefaultCloseOperation(DISPOSE_ON_CLOSE);
     138    setModal(true);
     139    setSize(SIZE);
     140    setTitle(get("Title"));
     141    JPanel content_pane = (JPanel) getContentPane();
     142    content_pane.setBackground(Gatherer.config.getColor("coloring.collection_heading_background", false));
     143         
     144    JPanel upper_pane = new JPanel();
     145    upper_pane.setOpaque(false);
     146         
     147    model = new MEMModel();
     148
     149    JPanel mds_tree_pane = new JPanel();
     150    mds_tree_pane.setOpaque(false);
     151    mds_tree_pane.setPreferredSize(new Dimension(200,500));
     152    mds_tree = new SmarterTree(model);
     153    mds_tree.setCellRenderer(new MEMTreeCellRenderer());
     154    mds_tree.setRootVisible(false);
     155    mds_tree.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
     156    mds_tree.setForeground(Gatherer.config.getColor("coloring.collection_tree_foreground", false));
     157    mds_tree.setSelectionColor(Gatherer.config.getColor("coloring.collection_selection_background", false));
     158    mds_tree.setSelectedTextColor(Gatherer.config.getColor("coloring.collection_selection_foreground", false));
     159
     160    details_pane = new JPanel();
     161    details_pane.setOpaque(false);
     162    card_layout = new CardLayout();
     163         
     164    JPanel set_details_pane = new JPanel();
     165    set_details_pane.setOpaque(false);
     166         
     167    JPanel set_name_pane = new JPanel();
     168    set_name_pane.setOpaque(false);
     169    JLabel set_name_label = new JLabel(get("Name"));
     170    set_name_label.setOpaque(false);
     171    set_name_label.setPreferredSize(LABEL_SIZE);
     172    set_name = new JLabel();
     173    set_name.setBorder(BorderFactory.createLoweredBevelBorder());
     174    set_name.setOpaque(false);
     175         
     176    JPanel set_attributes_pane = new JPanel();
     177    set_attributes_pane.setOpaque(false);
     178    set_attributes_scroll = new JScrollPane();
     179    set_attributes_scroll.getViewport().setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
     180    set_attributes_scroll.setOpaque(true);
     181    set_attributes = new SmarterTable();
     182    set_attributes.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
     183    set_attributes.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
     184    set_attributes.setForeground(Gatherer.config.getColor("coloring.collection_tree_foreground", false));
     185    set_attributes.setHeadingBackground(Gatherer.config.getColor("coloring.collection_heading_background", false));
     186    set_attributes.setHeadingForeground(Gatherer.config.getColor("coloring.collection_heading_foreground", false));
     187    set_attributes.setOpaque(false);
     188    set_attributes.setSelectionColor(Gatherer.config.getColor("coloring.collection_selection_background", false));
     189    set_attributes.setSelectedTextColor(Gatherer.config.getColor("coloring.collection_selection_foreground", false));
     190    set_attributes.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
     191         
     192    JPanel element_details_pane = new JPanel();
     193    element_details_pane.setOpaque(false);
     194
     195    JPanel element_name_pane = new JPanel();
     196    element_name_pane.setOpaque(false);
     197    JLabel element_name_label = new JLabel(get("Name"));
     198    element_name_label.setOpaque(false);
     199    element_name_label.setPreferredSize(LABEL_SIZE);
     200    element_name = new JLabel();
     201    element_name.setBorder(BorderFactory.createLoweredBevelBorder());
     202    element_name.setOpaque(false);
     203         
     204    JPanel element_inner_pane = new JPanel();
     205    element_inner_pane.setOpaque(false);
     206         
     207    JPanel element_attributes_pane = new JPanel();
     208    element_attributes_pane.setOpaque(false);
     209    element_attributes_scroll = new JScrollPane();
     210    element_attributes_scroll.getViewport().setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
     211    element_attributes_scroll.setOpaque(true);
     212    element_attributes = new SmarterTable();
     213    element_attributes.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
     214    element_attributes.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
     215    element_attributes.setForeground(Gatherer.config.getColor("coloring.collection_tree_foreground", false));
     216    element_attributes.setHeadingBackground(Gatherer.config.getColor("coloring.collection_heading_background", false));
     217    element_attributes.setHeadingForeground(Gatherer.config.getColor("coloring.collection_heading_foreground", false));
     218    element_attributes.setSelectionColor(Gatherer.config.getColor("coloring.collection_selection_background", false));
     219    element_attributes.setSelectedTextColor(Gatherer.config.getColor("coloring.collection_selection_foreground", false));
     220    element_attributes.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
     221
     222    JPanel element_values_pane = new JPanel();
     223    element_values_pane.setOpaque(false);
     224    element_values = new SmarterTree();
     225    element_values.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
     226    element_values.setForeground(Gatherer.config.getColor("coloring.collection_tree_foreground", false));
     227    element_values.setRootVisible(false);
     228    element_values.setSelectionColor(Gatherer.config.getColor("coloring.collection_selection_background", false));
     229    element_values.setSelectedTextColor(Gatherer.config.getColor("coloring.collection_selection_foreground", false));
     230         
     231    JPanel profile_details_pane = new JPanel();
     232    profile_details_pane.setOpaque(false);
     233    JPanel profile_name_pane = new JPanel();
     234    profile_name_pane.setOpaque(false);
     235    JLabel profile_name_label = new JLabel(get("Name"));
     236    profile_name_label.setOpaque(false);
     237    profile_name_label.setPreferredSize(LABEL_SIZE);
     238    profile_name = new JLabel();
     239    profile_name.setBorder(BorderFactory.createLoweredBevelBorder());
     240    profile_name.setOpaque(false);
     241         
     242    JPanel profile_attributes_pane = new JPanel();
     243    profile_attributes_pane.setOpaque(false);
     244    profile_attributes_scroll = new JScrollPane();
     245    profile_attributes_scroll.getViewport().setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
     246    profile_attributes_scroll.setOpaque(true);
     247    profile_attributes = new SmarterTable();
     248    profile_attributes.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
     249    profile_attributes.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
     250    profile_attributes.setForeground(Gatherer.config.getColor("coloring.collection_tree_foreground", false));
     251    profile_attributes.setHeadingBackground(Gatherer.config.getColor("coloring.collection_heading_background", false));
     252    profile_attributes.setHeadingForeground(Gatherer.config.getColor("coloring.collection_heading_foreground", false));
     253    profile_attributes.setSelectionColor(Gatherer.config.getColor("coloring.collection_selection_background", false));
     254    profile_attributes.setSelectedTextColor(Gatherer.config.getColor("coloring.collection_selection_foreground", false));
     255    profile_attributes.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
     256
     257    JPanel button_pane = new JPanel();
     258    button_pane.setOpaque(false);
     259
     260    JPanel button_label_pane = new JPanel();
     261    button_label_pane.setOpaque(false);
     262    JLabel attribute_label = new JLabel(get("Attribute"));
     263    attribute_label.setOpaque(false);
     264    //attribute_label.setHorizontalAlignment(JLabel.CENTER);
     265    attribute_label.setPreferredSize(LABEL_SIZE);
     266    JLabel element_label = new JLabel(get("Element"));
     267    element_label.setOpaque(false);
     268    //element_label.setHorizontalAlignment(JLabel.CENTER);
     269    element_label.setPreferredSize(LABEL_SIZE);
     270    JLabel file_label = new JLabel(get("File"));
     271    file_label.setOpaque(false);
     272    //element_label.setHorizontalAlignment(JLabel.CENTER);
     273    file_label.setPreferredSize(LABEL_SIZE);
     274    JLabel set_label = new JLabel(get("Set"));
     275    set_label.setOpaque(false);
     276    //set_label.setHorizontalAlignment(JLabel.CENTER);
     277    set_label.setPreferredSize(LABEL_SIZE);
     278    JLabel value_label = new JLabel(get("Value"));
     279    value_label.setOpaque(false);
     280    //value_label.setHorizontalAlignment(JLabel.CENTER);
     281    value_label.setPreferredSize(LABEL_SIZE);
     282
     283    JPanel inner_button_pane = new JPanel();
     284    inner_button_pane.setOpaque(false);
     285    add_attribute = new JButton(get("Add"));
     286    add_element = new JButton(get("Add"));
     287    add_file = new JButton(get("Add"));
     288    add_set = new JButton(get("Add"));
     289    add_value = new JButton(get("Add"));
     290    edit_attribute = new JButton(get("Edit"));
     291    edit_value = new JButton(get("Edit"));
     292    remove_attribute = new JButton(get("Remove"));
     293    remove_element = new JButton(get("Remove"));
     294    remove_file = new JButton(get("Remove"));
     295    remove_set = new JButton(get("Remove"));
     296    remove_value = new JButton(get("Remove"));
     297    setControls(false, false, false, false, false, false, false, false, false, false, false, false);
     298
     299    close = new JButton(get("General.Close"));
     300
     301    add_element_action_listener = new AddElementActionListener();
     302    add_file_action_listener = new AddFileActionListener();
     303    add_set_action_listener = new AddSetActionListener();
     304    add_or_edit_attribute_action_listener = new AddOrEditAttributeActionListener();
     305    add_or_edit_value_action_listener = new AddOrEditValueActionListener();
     306
     307    // Some blank panel
     308    JPanel blank_pane = new JPanel();
     309    blank_pane.setOpaque(false);
     310    JPanel edit_file_pane = new JPanel();
     311    edit_file_pane.setOpaque(false);
     312    JPanel edit_element_pane = new JPanel();
     313    edit_element_pane.setOpaque(false);
     314    JPanel edit_set_pane = new JPanel();
     315    edit_set_pane.setOpaque(false);
     316    // Connection
     317
     318    add_attribute.addActionListener(add_or_edit_attribute_action_listener);
     319    add_element.addActionListener(add_element_action_listener);
     320    add_file.addActionListener(add_file_action_listener);
     321    add_set.addActionListener(add_set_action_listener);
     322    add_value.addActionListener(add_or_edit_value_action_listener);
     323    close.addActionListener(new CloseActionListener());
     324    edit_attribute.addActionListener(add_or_edit_attribute_action_listener);
     325    edit_value.addActionListener(add_or_edit_value_action_listener);
     326    remove_attribute.addActionListener(new RemoveAttributeActionListener());
     327    remove_element.addActionListener(new RemoveElementActionListener());
     328    remove_file.addActionListener(new RemoveFileActionListener());
     329    remove_set.addActionListener(new RemoveSetActionListener());
     330    remove_value.addActionListener(new RemoveValueActionListener());
     331    element_attributes.getSelectionModel().addListSelectionListener(new AttributesListSelectionListener(element_attributes));
     332    profile_attributes.getSelectionModel().addListSelectionListener(new AttributesListSelectionListener(profile_attributes));
     333    set_attributes.getSelectionModel().addListSelectionListener(new AttributesListSelectionListener(set_attributes));
     334    element_values.addTreeSelectionListener(new ElementValuesTreeSelectionListener());
     335    mds_tree.addTreeSelectionListener(new MDSTreeSelectionListener());
     336    // Layout
     337    mds_tree_pane.setLayout(new BorderLayout());
     338    mds_tree_pane.add(new JScrollPane(mds_tree), BorderLayout.CENTER);
     339         
     340    set_name_pane.setLayout(new BorderLayout());
     341    set_name_pane.add(set_name_label, BorderLayout.WEST);
     342    set_name_pane.add(set_name, BorderLayout.CENTER);
    343343               
    344           set_attributes_scroll.setViewportView(set_attributes);
    345 
    346           set_attributes_pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder(get("Attributes")), BorderFactory.createEmptyBorder(2,2,2,2)));
    347           set_attributes_pane.setLayout(new BorderLayout());
    348           set_attributes_pane.add(set_attributes_scroll, BorderLayout.CENTER);
     344    set_attributes_scroll.setViewportView(set_attributes);
     345
     346    set_attributes_pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder(get("Attributes")), BorderFactory.createEmptyBorder(2,2,2,2)));
     347    set_attributes_pane.setLayout(new BorderLayout());
     348    set_attributes_pane.add(set_attributes_scroll, BorderLayout.CENTER);
    349349       
    350           set_details_pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder(get("Set_Details")), BorderFactory.createEmptyBorder(2,2,2,2)));
    351           set_details_pane.setLayout(new BorderLayout());
    352           //set_details_pane.add(set_name_pane, BorderLayout.NORTH);
    353           set_details_pane.add(set_attributes_pane, BorderLayout.CENTER);
    354          
    355           element_name_pane.setLayout(new BorderLayout());
    356           element_name_pane.add(element_name_label, BorderLayout.WEST);
    357           element_name_pane.add(element_name, BorderLayout.CENTER);
     350    set_details_pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder(get("Set_Details")), BorderFactory.createEmptyBorder(2,2,2,2)));
     351    set_details_pane.setLayout(new BorderLayout());
     352    //set_details_pane.add(set_name_pane, BorderLayout.NORTH);
     353    set_details_pane.add(set_attributes_pane, BorderLayout.CENTER);
     354         
     355    element_name_pane.setLayout(new BorderLayout());
     356    element_name_pane.add(element_name_label, BorderLayout.WEST);
     357    element_name_pane.add(element_name, BorderLayout.CENTER);
    358358               
    359           element_attributes_scroll.setViewportView(element_attributes);
    360 
    361           element_attributes_pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder(get("Attributes")), BorderFactory.createEmptyBorder(2,2,2,2)));
    362           element_attributes_pane.setLayout(new BorderLayout());
    363           element_attributes_pane.add(element_attributes_scroll, BorderLayout.CENTER);
    364          
    365           element_values_pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder(get("Values")), BorderFactory.createEmptyBorder(2,2,2,2)));
    366           element_values_pane.setLayout(new BorderLayout());
    367           element_values_pane.add(new JScrollPane(element_values), BorderLayout.CENTER);
    368          
    369           element_inner_pane.setLayout(new GridLayout(2,1));
    370           element_inner_pane.add(element_attributes_pane);
    371           element_inner_pane.add(element_values_pane);
    372          
    373           element_details_pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder(get("Element_Details")), BorderFactory.createEmptyBorder(2,2,2,2)));
    374           element_details_pane.setLayout(new BorderLayout());
    375           //element_details_pane.add(element_name_pane, BorderLayout.NORTH);
    376           element_details_pane.add(element_inner_pane, BorderLayout.CENTER);
    377 
    378           profile_name_pane.setLayout(new BorderLayout());
    379           profile_name_pane.add(profile_name_label, BorderLayout.WEST);
    380           profile_name_pane.add(profile_name, BorderLayout.CENTER);
     359    element_attributes_scroll.setViewportView(element_attributes);
     360
     361    element_attributes_pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder(get("Attributes")), BorderFactory.createEmptyBorder(2,2,2,2)));
     362    element_attributes_pane.setLayout(new BorderLayout());
     363    element_attributes_pane.add(element_attributes_scroll, BorderLayout.CENTER);
     364         
     365    element_values_pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder(get("Values")), BorderFactory.createEmptyBorder(2,2,2,2)));
     366    element_values_pane.setLayout(new BorderLayout());
     367    element_values_pane.add(new JScrollPane(element_values), BorderLayout.CENTER);
     368         
     369    element_inner_pane.setLayout(new GridLayout(2,1));
     370    element_inner_pane.add(element_attributes_pane);
     371    element_inner_pane.add(element_values_pane);
     372         
     373    element_details_pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder(get("Element_Details")), BorderFactory.createEmptyBorder(2,2,2,2)));
     374    element_details_pane.setLayout(new BorderLayout());
     375    //element_details_pane.add(element_name_pane, BorderLayout.NORTH);
     376    element_details_pane.add(element_inner_pane, BorderLayout.CENTER);
     377
     378    profile_name_pane.setLayout(new BorderLayout());
     379    profile_name_pane.add(profile_name_label, BorderLayout.WEST);
     380    profile_name_pane.add(profile_name, BorderLayout.CENTER);
    381381               
    382           profile_attributes_scroll.setViewportView(profile_attributes);
    383 
    384           profile_attributes_pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder(get("Profiles")), BorderFactory.createEmptyBorder(2,2,2,2)));
    385           profile_attributes_pane.setLayout(new BorderLayout());
    386           profile_attributes_pane.add(profile_attributes_scroll, BorderLayout.CENTER);
     382    profile_attributes_scroll.setViewportView(profile_attributes);
     383
     384    profile_attributes_pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder(get("Profiles")), BorderFactory.createEmptyBorder(2,2,2,2)));
     385    profile_attributes_pane.setLayout(new BorderLayout());
     386    profile_attributes_pane.add(profile_attributes_scroll, BorderLayout.CENTER);
    387387       
    388           profile_details_pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder(get("Profile_Details")), BorderFactory.createEmptyBorder(2,2,2,2)));
    389           profile_details_pane.setLayout(new BorderLayout());
    390           //profile_details_pane.add(profile_name_pane, BorderLayout.NORTH);
    391           profile_details_pane.add(profile_attributes_pane, BorderLayout.CENTER);
    392          
    393           details_pane.setBorder(BorderFactory.createEmptyBorder(0,5,0,0));
    394           details_pane.setLayout(card_layout);
    395           details_pane.add(blank_pane, BLANK);
    396           details_pane.add(set_details_pane, SET);
    397           details_pane.add(element_details_pane, ELEMENT);
    398           details_pane.add(profile_details_pane, PROFILE);
    399 
    400           upper_pane.setLayout(new BorderLayout());
    401           upper_pane.add(mds_tree_pane, BorderLayout.WEST);
    402           upper_pane.add(details_pane, BorderLayout.CENTER);
    403          
    404           button_label_pane.setLayout(new GridLayout(5,1,0,2));
    405           button_label_pane.add(set_label);
    406           button_label_pane.add(file_label);
    407           button_label_pane.add(element_label);
    408           button_label_pane.add(attribute_label);
    409           button_label_pane.add(value_label);
    410 
    411           inner_button_pane.setLayout(new GridLayout(5,3,0,2));     
    412           inner_button_pane.add(add_set);
    413           inner_button_pane.add(edit_set_pane);
    414           inner_button_pane.add(remove_set);
    415           inner_button_pane.add(add_file);
    416           inner_button_pane.add(edit_file_pane);
    417           inner_button_pane.add(remove_file);
    418           inner_button_pane.add(add_element);
    419           inner_button_pane.add(edit_element_pane);
    420           inner_button_pane.add(remove_element);
    421           inner_button_pane.add(add_attribute);
    422           inner_button_pane.add(edit_attribute);
    423           inner_button_pane.add(remove_attribute);
    424           inner_button_pane.add(add_value);
    425           inner_button_pane.add(edit_value);
    426           inner_button_pane.add(remove_value);
    427          
    428           button_pane.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
    429           button_pane.setLayout(new BorderLayout());
    430           button_pane.add(button_label_pane, BorderLayout.WEST);
    431           button_pane.add(inner_button_pane, BorderLayout.CENTER);
    432           button_pane.add(close, BorderLayout.EAST);
    433 
    434           content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
    435           content_pane.setLayout(new BorderLayout());
    436           content_pane.add(upper_pane, BorderLayout.CENTER);
    437           content_pane.add(button_pane, BorderLayout.SOUTH);
    438 
    439           // Display
    440           setLocation((screen_size.width - SIZE.width) / 2, (screen_size.height - SIZE.height) / 2);
    441           show();
    442     }
     388    profile_details_pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder(get("Profile_Details")), BorderFactory.createEmptyBorder(2,2,2,2)));
     389    profile_details_pane.setLayout(new BorderLayout());
     390    //profile_details_pane.add(profile_name_pane, BorderLayout.NORTH);
     391    profile_details_pane.add(profile_attributes_pane, BorderLayout.CENTER);
     392         
     393    details_pane.setBorder(BorderFactory.createEmptyBorder(0,5,0,0));
     394    details_pane.setLayout(card_layout);
     395    details_pane.add(blank_pane, BLANK);
     396    details_pane.add(set_details_pane, SET);
     397    details_pane.add(element_details_pane, ELEMENT);
     398    details_pane.add(profile_details_pane, PROFILE);
     399
     400    upper_pane.setLayout(new BorderLayout());
     401    upper_pane.add(mds_tree_pane, BorderLayout.WEST);
     402    upper_pane.add(details_pane, BorderLayout.CENTER);
     403         
     404    button_label_pane.setLayout(new GridLayout(5,1,0,2));
     405    button_label_pane.add(set_label);
     406    button_label_pane.add(file_label);
     407    button_label_pane.add(element_label);
     408    button_label_pane.add(attribute_label);
     409    button_label_pane.add(value_label);
     410
     411    inner_button_pane.setLayout(new GridLayout(5,3,0,2));       
     412    inner_button_pane.add(add_set);
     413    inner_button_pane.add(edit_set_pane);
     414    inner_button_pane.add(remove_set);
     415    inner_button_pane.add(add_file);
     416    inner_button_pane.add(edit_file_pane);
     417    inner_button_pane.add(remove_file);
     418    inner_button_pane.add(add_element);
     419    inner_button_pane.add(edit_element_pane);
     420    inner_button_pane.add(remove_element);
     421    inner_button_pane.add(add_attribute);
     422    inner_button_pane.add(edit_attribute);
     423    inner_button_pane.add(remove_attribute);
     424    inner_button_pane.add(add_value);
     425    inner_button_pane.add(edit_value);
     426    inner_button_pane.add(remove_value);
     427         
     428    button_pane.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
     429    button_pane.setLayout(new BorderLayout());
     430    button_pane.add(button_label_pane, BorderLayout.WEST);
     431    button_pane.add(inner_button_pane, BorderLayout.CENTER);
     432    button_pane.add(close, BorderLayout.EAST);
     433
     434    content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
     435    content_pane.setLayout(new BorderLayout());
     436    content_pane.add(upper_pane, BorderLayout.CENTER);
     437    content_pane.add(button_pane, BorderLayout.SOUTH);
     438
     439    // Display
     440    setLocation((screen_size.width - SIZE.width) / 2, (screen_size.height - SIZE.height) / 2);
     441    show();
     442    }
    443443     
    444     public void dispose() {
    445           // Destructor
    446           card_layout = null;
    447           screen_size = null;
    448           self = null;
    449           add_attribute = null;
    450           add_element = null;
    451           add_file = null;
    452           add_set = null;
    453           add_value = null;
    454           close = null;
    455           edit_attribute = null;
    456           edit_value = null;
    457           remove_attribute = null;
    458           remove_element = null;
    459           remove_file = null;
    460           remove_set = null;
    461           remove_value = null;
    462           details_pane = null;
    463           element_attributes = null;
    464           set_attributes = null;
    465           element_name = null;
    466           set_name = null;
    467           element_values = null;
    468           mds_tree = null;
    469           target = null;
    470           // Dispose of inner dialogs
    471           add_element_action_listener.dispose();
    472           add_or_edit_attribute_action_listener.dispose();
    473           add_or_edit_value_action_listener.dispose();
    474           super.dispose();
    475     }
    476 
    477     private String get(String key) {
    478           return get(key, (String[])null);
    479     }
     444    public void dispose() {
     445    // Destructor
     446    card_layout = null;
     447    screen_size = null;
     448    self = null;
     449    add_attribute = null;
     450    add_element = null;
     451    add_file = null;
     452    add_set = null;
     453    add_value = null;
     454    close = null;
     455    edit_attribute = null;
     456    edit_value = null;
     457    remove_attribute = null;
     458    remove_element = null;
     459    remove_file = null;
     460    remove_set = null;
     461    remove_value = null;
     462    details_pane = null;
     463    element_attributes = null;
     464    set_attributes = null;
     465    element_name = null;
     466    set_name = null;
     467    element_values = null;
     468    mds_tree = null;
     469    target = null;
     470    // Dispose of inner dialogs
     471    add_element_action_listener.dispose();
     472    add_or_edit_attribute_action_listener.dispose();
     473    add_or_edit_value_action_listener.dispose();
     474    super.dispose();
     475    }
     476
     477    private String get(String key) {
     478    return get(key, (String[])null);
     479    }
    480480     
    481     private String get(String key, String arg) {
    482           String[] args = new String[1];
    483           args[0] = arg;
    484           return get(key, args);
    485     }
    486 
    487     private String get(String key, String[] args) {
    488           if(key.indexOf(".") == -1) {
    489                 key = "MEM." + key;
    490           }
    491           return Gatherer.dictionary.get(key, args);
    492     }
     481    private String get(String key, String arg) {
     482    String[] args = new String[1];
     483    args[0] = arg;
     484    return get(key, args);
     485    }
     486
     487    private String get(String key, String[] args) {
     488    if(key.indexOf(".") == -1) {
     489        key = "MEM." + key;
     490    }
     491    return Gatherer.dictionary.get(key, args);
     492    }
    493493     
    494     private void setControls(boolean a_s, boolean r_s, boolean a_f, boolean r_f, boolean a_e, boolean r_e, boolean a_a, boolean e_a, boolean r_a, boolean a_v, boolean e_v, boolean r_v) {
    495           add_attribute.setEnabled(a_a);
    496           add_element.setEnabled(a_e);
    497           add_file.setEnabled(true); // Always true
    498           add_set.setEnabled(true); // Always true
    499           add_value.setEnabled(a_v);
    500           edit_attribute.setEnabled(e_a);
    501           edit_value.setEnabled(e_v);
    502           remove_attribute.setEnabled(r_a);
    503           remove_element.setEnabled(r_e);
    504           remove_file.setEnabled(r_f);
    505           remove_set.setEnabled(r_s);
    506           remove_value.setEnabled(r_v);
    507     }
    508 
    509     private class AddOrEditAttributeActionListener
    510           extends JDialog
    511           implements ActionListener {
    512           private boolean add_type = true;
    513           private ComboArea value = null;
    514           private JButton cancel_button = null;
    515           private JButton ok_button = null;
    516           private JComboBox language_box = null;
    517           private GComboBox name = null;
    518           private HashMap name_to_values = null;
    519           private JLabel target = null;
    520           /** Constructor. */
    521           public AddOrEditAttributeActionListener() {
    522                 super(self);
    523                 setModal(true);
    524                 setSize(ADD_OR_EDIT_ATTRIBUTE_SIZE);
    525                 name_to_values = new HashMap();
     494    private void setControls(boolean a_s, boolean r_s, boolean a_f, boolean r_f, boolean a_e, boolean r_e, boolean a_a, boolean e_a, boolean r_a, boolean a_v, boolean e_v, boolean r_v) {
     495    add_attribute.setEnabled(a_a);
     496    add_element.setEnabled(a_e);
     497    add_file.setEnabled(true); // Always true
     498    add_set.setEnabled(true); // Always true
     499    add_value.setEnabled(a_v);
     500    edit_attribute.setEnabled(e_a);
     501    edit_value.setEnabled(e_v);
     502    remove_attribute.setEnabled(r_a);
     503    remove_element.setEnabled(r_e);
     504    remove_file.setEnabled(r_f);
     505    remove_set.setEnabled(r_s);
     506    remove_value.setEnabled(r_v);
     507    }
     508
     509    private class AddOrEditAttributeActionListener
     510    extends JDialog
     511    implements ActionListener {
     512    private boolean add_type = true;
     513    private ComboArea value = null;
     514    private JButton cancel_button = null;
     515    private JButton ok_button = null;
     516    private JComboBox language_box = null;
     517    private GComboBox name = null;
     518    private HashMap name_to_values = null;
     519    private JLabel target = null;
     520    /** Constructor. */
     521    public AddOrEditAttributeActionListener() {
     522        super(self);
     523        setModal(true);
     524        setSize(ADD_OR_EDIT_ATTRIBUTE_SIZE);
     525        name_to_values = new HashMap();
    526526                // Creation
    527                 JPanel content_pane = (JPanel) getContentPane();
    528                 content_pane.setBackground(Gatherer.config.getColor("coloring.collection_heading_background", false));
    529                 JPanel upper_pane = new JPanel();
    530                 upper_pane.setOpaque(false);
    531 
    532                 JPanel target_pane = new JPanel();
    533                 target_pane.setOpaque(false);
    534                 JLabel target_label = new JLabel(get("Target"));
    535                 target_label.setOpaque(false);
    536                 target_label.setPreferredSize(LABEL_SIZE);
    537                 target = new JLabel();
    538                 target.setOpaque(false);
    539 
    540 
    541                 JPanel name_pane = new JPanel();
    542                 name_pane.setOpaque(false);
    543                 JLabel name_label = new JLabel(get("Name"));
    544                 name_label.setOpaque(false);
    545                 name_label.setPreferredSize(LABEL_SIZE);
    546                 name = new GComboBox();
    547                 name.setEditable(true);
    548 
    549                 JPanel language_pane = new JPanel();
    550                 language_pane.setOpaque(false);
    551                 JLabel language_label = new JLabel(get("Language"));
    552                 language_label.setOpaque(false);
    553                 language_label.setPreferredSize(LABEL_SIZE);
    554                 language_box = new JComboBox(Gatherer.g_man.config_pane.getLanguageCodes().toArray());
    555 
    556                 JPanel center_pane = new JPanel();
    557                 center_pane.setOpaque(false);
    558                 value = new ComboArea(get("Values"), LABEL_SIZE);
    559                 value.setOpaque(false);
    560                 JTextArea v_text_area = (JTextArea) value.getTextComponent();
    561                 v_text_area.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
    562                 v_text_area.setForeground(Gatherer.config.getColor("coloring.collection_tree_foreground", false));
    563                 v_text_area.setSelectionColor(Gatherer.config.getColor("coloring.collection_selection_background", false));
    564                 v_text_area.setSelectedTextColor(Gatherer.config.getColor("coloring.collection_selection_foreground", false));
    565                 JPanel button_pane = new JPanel();
    566                 button_pane.setOpaque(false);
    567                 ok_button = new JButton(get("General.OK"));
    568                 cancel_button = new JButton(get("General.Cancel"));
     527        JPanel content_pane = (JPanel) getContentPane();
     528        content_pane.setBackground(Gatherer.config.getColor("coloring.collection_heading_background", false));
     529        JPanel upper_pane = new JPanel();
     530        upper_pane.setOpaque(false);
     531
     532        JPanel target_pane = new JPanel();
     533        target_pane.setOpaque(false);
     534        JLabel target_label = new JLabel(get("Target"));
     535        target_label.setOpaque(false);
     536        target_label.setPreferredSize(LABEL_SIZE);
     537        target = new JLabel();
     538        target.setOpaque(false);
     539
     540
     541        JPanel name_pane = new JPanel();
     542        name_pane.setOpaque(false);
     543        JLabel name_label = new JLabel(get("Name"));
     544        name_label.setOpaque(false);
     545        name_label.setPreferredSize(LABEL_SIZE);
     546        name = new GComboBox();
     547        name.setEditable(true);
     548
     549        JPanel language_pane = new JPanel();
     550        language_pane.setOpaque(false);
     551        JLabel language_label = new JLabel(get("Language"));
     552        language_label.setOpaque(false);
     553        language_label.setPreferredSize(LABEL_SIZE);
     554        language_box = new JComboBox(Gatherer.g_man.config_pane.getLanguageCodes().toArray());
     555
     556        JPanel center_pane = new JPanel();
     557        center_pane.setOpaque(false);
     558        value = new ComboArea(get("Values"), LABEL_SIZE);
     559        value.setOpaque(false);
     560        JTextArea v_text_area = (JTextArea) value.getTextComponent();
     561        v_text_area.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
     562        v_text_area.setForeground(Gatherer.config.getColor("coloring.collection_tree_foreground", false));
     563        v_text_area.setSelectionColor(Gatherer.config.getColor("coloring.collection_selection_background", false));
     564        v_text_area.setSelectedTextColor(Gatherer.config.getColor("coloring.collection_selection_foreground", false));
     565        JPanel button_pane = new JPanel();
     566        button_pane.setOpaque(false);
     567        ok_button = new JButton(get("General.OK"));
     568        cancel_button = new JButton(get("General.Cancel"));
    569569                // Connection
    570                 TextFieldEnabler ok_button_enabler = new TextFieldEnabler(ok_button);
    571                 cancel_button.addActionListener(this);
    572                 name.addActionListener(this);
    573                 ok_button.addActionListener(this);
    574                 ok_button_enabler.add((JTextComponent)name.getEditor()); // Assuming the default editor is a JTextField!
     570        TextFieldEnabler ok_button_enabler = new TextFieldEnabler(ok_button);
     571        cancel_button.addActionListener(this);
     572        name.addActionListener(this);
     573        ok_button.addActionListener(this);
     574        ok_button_enabler.add((JTextComponent)name.getEditor()); // Assuming the default editor is a JTextField!
    575575                // Layout
    576                 target_pane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
    577                 target_pane.setLayout(new BorderLayout());
    578                 target_pane.add(target_label, BorderLayout.WEST);
    579                 target_pane.add(target, BorderLayout.CENTER);
     576        target_pane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
     577        target_pane.setLayout(new BorderLayout());
     578        target_pane.add(target_label, BorderLayout.WEST);
     579        target_pane.add(target, BorderLayout.CENTER);
    580580               
    581                 language_pane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
    582                 language_pane.setLayout(new BorderLayout());
    583                 language_pane.add(language_label, BorderLayout.WEST);
    584                 language_pane.add(language_box, BorderLayout.CENTER);
    585 
    586                 name_pane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
    587                 name_pane.setLayout(new BorderLayout());
    588                 name_pane.add(name_label, BorderLayout.WEST);
    589                 name_pane.add(name, BorderLayout.CENTER);
    590 
    591                 upper_pane.setLayout(new GridLayout(3,1));
    592                 upper_pane.add(target_pane);
    593                 upper_pane.add(name_pane);
    594                 upper_pane.add(language_pane);
    595 
    596                 value.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
    597 
    598                 button_pane.setLayout(new GridLayout(1,2,5,0));
    599                 button_pane.add(ok_button);
    600                 button_pane.add(cancel_button);
    601 
    602                 center_pane.setLayout(new BorderLayout());
    603                 center_pane.add(value, BorderLayout.CENTER);
    604                 center_pane.add(button_pane, BorderLayout.SOUTH);
    605 
    606                 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
    607                 content_pane.setLayout(new BorderLayout());
    608                 content_pane.add(upper_pane, BorderLayout.NORTH);
    609                 content_pane.add(center_pane, BorderLayout.CENTER);
    610 
    611                 setLocation((Gatherer.config.screen_size.width - ADD_OR_EDIT_ATTRIBUTE_SIZE.width) / 2, (Gatherer.config.screen_size.height - ADD_OR_EDIT_ATTRIBUTE_SIZE.height) / 2);
    612           }
    613           /** Any implementation of ActionListener must include this method so that we can be informed when an action as occured on our registered component, allowing us to add a new attribute to the selected set or element.
    614             * @param event An <strong>ActionEvent</strong> containing information about the event.
    615             */
    616           public void actionPerformed(ActionEvent event) {
    617                 Object source = event.getSource();
    618                 if(source == ok_button) {
    619                      boolean cont = true;
    620                      // Now we add the new or improved values, removing old values if this is an edit.
    621                      // Depends on what we are adding the attribute to.
    622                      if(current_collection_file != null) {
    623                           String name_str = name.getSelectedItem().toString();
    624                           String value_str = value.getText();
    625                           AttributeTableModel model = (AttributeTableModel) profile_attributes.getModel();
    626                           // Remove the existing one if this is an edit.
    627                           if(!add_type && current_attribute != -1) {
    628                                 String old_source = (String) profile_attributes.getValueAt(current_attribute, 0);
    629                                 Gatherer.c_man.msm.profiler.removeAction(current_collection_file, old_source);
    630                                 old_source = null;
    631                                 model.removeRow(current_attribute);
    632                           }
    633                           // First thing we check from profiles is that there isn't already an entry for this name.
    634                           if(!model.contains(name_str, 0)) {
    635                                 // Add profile
    636                                 Gatherer.c_man.msm.profiler.addAction(current_collection_file, name_str, value_str);
    637                                 // Update attribute table.
    638                                 model.add(new Attribute(name_str, value_str));
    639                           }
    640                           else {
    641                                 // Show an error message and do not proceed.
    642                                 cont = false;
    643                                 JOptionPane.showMessageDialog(self, get("Attribute_Already_Exists"), get("General.Error"), JOptionPane.ERROR_MESSAGE);
    644                           }
    645                           model = null;
    646                           value_str = null;
    647                           name_str = null;
    648                      }
    649                      else if(current_element != null) {
    650                           // Add the attribute, even if one of the same name already exists. Maybe one day someone would like to enforce the occurance rules but not me and not today.
    651                           String name_str = name.getSelectedItem().toString();
    652                           String language_code = ((Language)language_box.getSelectedItem()).getCode();
    653                           String value_str = value.getText();
    654                           AttributeTableModel model = (AttributeTableModel) element_attributes.getModel();
    655                           // Remove the existing one if this is an edit.
    656                           if(!add_type && current_attribute != -1) {
    657                                 model.removeRow(current_attribute);
    658                           }
    659                           // Add attribute
    660                           current_element.addAttribute(name_str, language_code, value_str);
    661                           // Update the attribute table
    662                           model.add(new Attribute(name_str, language_code, value_str));
    663                           model = null;
    664                           value_str = null;
    665                           language_code = null;
    666                           name_str = null;
    667                      }
    668                      else if(current_set != null) {
    669                           String name_str = name.getSelectedItem().toString();
    670                           String value_str = value.getText();                       
    671                           // First thing we check from profiles is that there isn't already an entry for this name.
    672                           AttributeTableModel model = (AttributeTableModel) set_attributes.getModel();
    673                           // Remove the existing one if this is an edit.
    674                           if(!add_type && current_attribute != -1) {
    675                                 model.removeRow(current_attribute);
    676                           }
    677                           // First thing we check from profiles is that there isn't already an entry for this name.
    678                           if(!model.contains(name_str, 0)) {
    679                                 // Add profile
    680                                 current_set.addAttribute(name_str, value_str);
    681                                 // Update attribute table.
    682                                 model.add(new Attribute(name_str, value_str));
    683                           }
    684                           // Otherwise provide an error message and do not proceed.
    685                           else {
    686                                 cont = false;
    687                                 JOptionPane.showMessageDialog(self, get("Attribute_Already_Exists"), get("General.Error"), JOptionPane.ERROR_MESSAGE);
    688                           }
    689                           model = null;
    690                           value_str = null;
    691                           name_str = null;
    692                      }
    693                      // Hide dialog if we are allowed to continue.
    694                      if(cont) {
    695                           hide();
    696                      }
    697                 }
    698                 else if(source == cancel_button) {
    699                      // Hide dialog
    700                      hide();
    701                 }
    702                 else if(source == name) {
    703                      Object object = name.getSelectedItem();
    704                      if(object != null) {
    705                           java.util.List values = (java.util.List) name_to_values.get(object.toString());
    706                           if(values == null) { // Only for collection files, otherwise values != null && values.size() == 0
    707                                 values = Gatherer.c_man.msm.getElements();
    708                           }
    709                           value.clear();
    710                           for(int i = 0; i < values.size(); i++) {
    711                                 value.add(values.get(i));
    712                           }
    713                      }
    714                 }
    715                 else {
    716                      name_to_values.clear();
    717                      name.clear();
    718                      value.clear();
    719                      value.setText("");
    720                      // Build the correct name_to_values mapping
    721                      // Attributes are slightly tricky as they can come from several sources. Has a collection file been selected...
    722                      if(current_collection_file != null) {
    723                           target.setText(current_collection_file);
    724                           // Name is empty in this one, however values must be the current elements in the collection.                       
    725                           language_box.setEnabled(false);
    726                      }
    727                      // or has an element been selected
    728                      else if(current_element != null) {
    729                           target.setText(current_element.toString());
    730                           // Develop a model for name based on known attributes from all other elements.
    731                           java.util.List elements = Gatherer.c_man.msm.getElements();
    732                           for(int i = 0; i < elements.size(); i++) {
    733                                 ElementWrapper element = (ElementWrapper) elements.get(i);
    734                                 TreeSet attributes = element.getAttributes();
    735                                 for(Iterator attribute_iterator = attributes.iterator(); attribute_iterator.hasNext(); ) {
    736                                     Attribute attribute = (Attribute) attribute_iterator.next();
    737                                     java.util.List values = (java.util.List) name_to_values.get(attribute.name);
    738                                     if(values == null) {
    739                                           values = new ArrayList();
    740                                           name_to_values.put(attribute.name, values);
    741                                     }
    742                                     if(!values.contains(attribute.value)) {
    743                                           values.add(attribute.value);
    744                                     }
    745                                     values = null;
    746                                     attribute = null;
    747                                 }
    748                                 attributes = null;
    749                                 element = null;
    750                           }
    751                           elements = null;
    752                           language_box.setEnabled(true);
    753                      }
    754                      else if(current_set != null) {
    755                           target.setText(current_set.toString());
    756                           // Develop a model for name based on known attributes from all other metadata sets. At the same time build a hashmap mapping attribute name to lists of values.
    757                           java.util.List sets = Gatherer.c_man.msm.getSets();
    758                           for(int i = 0; i < sets.size(); i++) {
    759                                 MetadataSet set = (MetadataSet) sets.get(i);
    760                                 NamedNodeMap attributes = set.getAttributes();
    761                                 for(int j = 0; j < attributes.getLength(); j++) {
    762                                     Attr attribute = (Attr) attributes.item(j);
    763                                     String name_str = attribute.getName();
    764                                     String value_str = attribute.getValue();
    765                                     java.util.List values = (java.util.List) name_to_values.get(name_str);
    766                                     if(values == null) {
    767                                           values = new ArrayList();
    768                                           name_to_values.put(name_str, values);
    769                                     }
    770                                     if(!values.contains(value_str)) {
    771                                           values.add(value_str);
    772                                     }
    773                                     values = null;
    774                                     value_str = null;
    775                                     name_str = null;
    776                                     attribute = null;
    777                                 }
    778                                 attributes = null;
    779                                 set = null;
    780                                 language_box.setEnabled(false);
    781                           }
    782                           sets = null;
    783                           // If this is an add remove all the attributes already present in the current set.
    784                           if(source == add_attribute) {
    785                                 name.setEnabled(true);
    786                                 NamedNodeMap attributes = current_set.getAttributes();
    787                                 for(int i = 0; i < attributes.getLength(); i++) {
    788                                     Attr attribute = (Attr) attributes.item(i);
    789                                     String name_str = attribute.getName();
    790                                     name_to_values.remove(name_str);
    791                                     name_str = null;
    792                                     attribute = null;
    793                                 }
    794                                 attributes = null;
    795                           }
    796                      }
    797                      // Otherwise we actually disable the name combobox
    798                      else {
    799                           name.setEnabled(false);
    800                      }
    801                      // Now name_to_values should contain a list of unique attribute names each mapping to a list of attribute values.
    802                      for(Iterator name_iterator = name_to_values.keySet().iterator(); name_iterator.hasNext(); ) {
    803                           name.add(name_iterator.next());
    804                      }
    805                      // Now pritty up the dialog depending on the action type
    806                      if(source == add_attribute) {
    807                           add_type = true;
    808                           setTitle(get("AddAttribute"));
    809                           if(current_collection_file != null) {
    810                                 // Name is empty in this one, however values must be the current elements in the collection.   
    811                                 java.util.List values = Gatherer.c_man.msm.getElements();
    812                                 for(int i = 0; i < values.size(); i++) {
    813                                     value.add(new NameElementWrapperEntry(values.get(i)));
    814                                 }
    815                                 values = null;
    816                           }
    817                           show();
    818                      }
    819                      else if(current_attribute != -1) {
    820                           add_type = false;
    821                           setTitle(get("EditAttribute"));
    822                           String name_str = (String) profile_attributes.getValueAt(current_attribute, 0);
    823                           String value_str = (String) profile_attributes.getValueAt(current_attribute, 1);
    824                           // Retrieve the appropriate value model
    825                           java.util.List values = (java.util.List) name_to_values.get(name_str);
    826                           // Only possible for collection file selections.
    827                           if(values == null) {
    828                                 values = Gatherer.c_man.msm.getElements();
    829                           }
    830                           name.setSelectedItem(name_str);
    831                           name_str = null;
    832                           for(int i = 0; i < values.size(); i++) {
    833                                 value.add(new NameElementWrapperEntry(values.get(i)));
    834                           }
    835                           values = null;
    836                           value.setSelectedItem(value_str);
    837                           value_str = null;
    838                           show();
    839                      }
    840                 }
    841                 source = null;
    842           }
    843          
    844           public void dispose() {
    845                 cancel_button = null;
    846                 name = null;
    847                 name_to_values = null;
    848                 ok_button = null;
    849                 target = null;
    850                 value = null;
    851           }
    852     }
     581        language_pane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
     582        language_pane.setLayout(new BorderLayout());
     583        language_pane.add(language_label, BorderLayout.WEST);
     584        language_pane.add(language_box, BorderLayout.CENTER);
     585
     586        name_pane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
     587        name_pane.setLayout(new BorderLayout());
     588        name_pane.add(name_label, BorderLayout.WEST);
     589        name_pane.add(name, BorderLayout.CENTER);
     590
     591        upper_pane.setLayout(new GridLayout(3,1));
     592        upper_pane.add(target_pane);
     593        upper_pane.add(name_pane);
     594        upper_pane.add(language_pane);
     595
     596        value.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
     597
     598        button_pane.setLayout(new GridLayout(1,2,5,0));
     599        button_pane.add(ok_button);
     600        button_pane.add(cancel_button);
     601
     602        center_pane.setLayout(new BorderLayout());
     603        center_pane.add(value, BorderLayout.CENTER);
     604        center_pane.add(button_pane, BorderLayout.SOUTH);
     605
     606        content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
     607        content_pane.setLayout(new BorderLayout());
     608        content_pane.add(upper_pane, BorderLayout.NORTH);
     609        content_pane.add(center_pane, BorderLayout.CENTER);
     610
     611        setLocation((Gatherer.config.screen_size.width - ADD_OR_EDIT_ATTRIBUTE_SIZE.width) / 2, (Gatherer.config.screen_size.height - ADD_OR_EDIT_ATTRIBUTE_SIZE.height) / 2);
     612    }
     613    /** Any implementation of ActionListener must include this method so that we can be informed when an action as occured on our registered component, allowing us to add a new attribute to the selected set or element.
     614     * @param event An <strong>ActionEvent</strong> containing information about the event.
     615     */
     616    public void actionPerformed(ActionEvent event) {
     617        Object source = event.getSource();
     618        if(source == ok_button) {
     619        boolean cont = true;
     620        // Now we add the new or improved values, removing old values if this is an edit.
     621        // Depends on what we are adding the attribute to.
     622        if(current_collection_file != null) {
     623            String name_str = name.getSelectedItem().toString();
     624            String value_str = value.getText();
     625            AttributeTableModel model = (AttributeTableModel) profile_attributes.getModel();
     626            // Remove the existing one if this is an edit.
     627            if(!add_type && current_attribute != -1) {
     628            String old_source = (String) profile_attributes.getValueAt(current_attribute, 0);
     629            Gatherer.c_man.msm.profiler.removeAction(current_collection_file, old_source);
     630            old_source = null;
     631            model.removeRow(current_attribute);
     632            }
     633            // First thing we check from profiles is that there isn't already an entry for this name.
     634            if(!model.contains(name_str, 0)) {
     635            // Add profile
     636            Gatherer.c_man.msm.profiler.addAction(current_collection_file, name_str, value_str);
     637            // Update attribute table.
     638            model.add(new Attribute(name_str, value_str));
     639            }
     640            else {
     641            // Show an error message and do not proceed.
     642            cont = false;
     643            JOptionPane.showMessageDialog(self, get("Attribute_Already_Exists"), get("General.Error"), JOptionPane.ERROR_MESSAGE);
     644            }
     645            model = null;
     646            value_str = null;
     647            name_str = null;
     648        }
     649        else if(current_element != null) {
     650            // Add the attribute, even if one of the same name already exists. Maybe one day someone would like to enforce the occurance rules but not me and not today.
     651            String name_str = name.getSelectedItem().toString();
     652            String language_code = ((Language)language_box.getSelectedItem()).getCode();
     653            String value_str = value.getText();
     654            AttributeTableModel model = (AttributeTableModel) element_attributes.getModel();
     655            // Remove the existing one if this is an edit.
     656            if(!add_type && current_attribute != -1) {
     657            model.removeRow(current_attribute);
     658            }
     659            // Add attribute
     660            current_element.addAttribute(name_str, language_code, value_str);
     661            // Update the attribute table
     662            model.add(new Attribute(name_str, language_code, value_str));
     663            model = null;
     664            value_str = null;
     665            language_code = null;
     666            name_str = null;
     667        }
     668        else if(current_set != null) {
     669            String name_str = name.getSelectedItem().toString();
     670            String value_str = value.getText();                     
     671            // First thing we check from profiles is that there isn't already an entry for this name.
     672            AttributeTableModel model = (AttributeTableModel) set_attributes.getModel();
     673            // Remove the existing one if this is an edit.
     674            if(!add_type && current_attribute != -1) {
     675            model.removeRow(current_attribute);
     676            }
     677            // First thing we check from profiles is that there isn't already an entry for this name.
     678            if(!model.contains(name_str, 0)) {
     679            // Add profile
     680            current_set.addAttribute(name_str, value_str);
     681            // Update attribute table.
     682            model.add(new Attribute(name_str, value_str));
     683            }
     684            // Otherwise provide an error message and do not proceed.
     685            else {
     686            cont = false;
     687            JOptionPane.showMessageDialog(self, get("Attribute_Already_Exists"), get("General.Error"), JOptionPane.ERROR_MESSAGE);
     688            }
     689            model = null;
     690            value_str = null;
     691            name_str = null;
     692        }
     693        // Hide dialog if we are allowed to continue.
     694        if(cont) {
     695            hide();
     696        }
     697        }
     698        else if(source == cancel_button) {
     699        // Hide dialog
     700        hide();
     701        }
     702        else if(source == name) {
     703        Object object = name.getSelectedItem();
     704        if(object != null) {
     705            java.util.List values = (java.util.List) name_to_values.get(object.toString());
     706            if(values == null) { // Only for collection files, otherwise values != null && values.size() == 0
     707            values = Gatherer.c_man.msm.getElements();
     708            }
     709            value.clear();
     710            for(int i = 0; i < values.size(); i++) {
     711            value.add(values.get(i));
     712            }
     713        }
     714        }
     715        else {
     716        name_to_values.clear();
     717        name.clear();
     718        value.clear();
     719        value.setText("");
     720        // Build the correct name_to_values mapping
     721        // Attributes are slightly tricky as they can come from several sources. Has a collection file been selected...
     722        if(current_collection_file != null) {
     723            target.setText(current_collection_file);
     724            // Name is empty in this one, however values must be the current elements in the collection.                         
     725            language_box.setEnabled(false);
     726        }
     727        // or has an element been selected
     728        else if(current_element != null) {
     729            target.setText(current_element.toString());
     730            // Develop a model for name based on known attributes from all other elements.
     731            java.util.List elements = Gatherer.c_man.msm.getElements();
     732            for(int i = 0; i < elements.size(); i++) {
     733            ElementWrapper element = (ElementWrapper) elements.get(i);
     734            TreeSet attributes = element.getAttributes();
     735            for(Iterator attribute_iterator = attributes.iterator(); attribute_iterator.hasNext(); ) {
     736                Attribute attribute = (Attribute) attribute_iterator.next();
     737                java.util.List values = (java.util.List) name_to_values.get(attribute.name);
     738                if(values == null) {
     739                values = new ArrayList();
     740                name_to_values.put(attribute.name, values);
     741                }
     742                if(!values.contains(attribute.value)) {
     743                values.add(attribute.value);
     744                }
     745                values = null;
     746                attribute = null;
     747            }
     748            attributes = null;
     749            element = null;
     750            }
     751            elements = null;
     752            language_box.setEnabled(true);
     753        }
     754        else if(current_set != null) {
     755            target.setText(current_set.toString());
     756            // Develop a model for name based on known attributes from all other metadata sets. At the same time build a hashmap mapping attribute name to lists of values.
     757            java.util.List sets = Gatherer.c_man.msm.getSets();
     758            for(int i = 0; i < sets.size(); i++) {
     759            MetadataSet set = (MetadataSet) sets.get(i);
     760            NamedNodeMap attributes = set.getAttributes();
     761            for(int j = 0; j < attributes.getLength(); j++) {
     762                Attr attribute = (Attr) attributes.item(j);
     763                String name_str = attribute.getName();
     764                String value_str = attribute.getValue();
     765                java.util.List values = (java.util.List) name_to_values.get(name_str);
     766                if(values == null) {
     767                values = new ArrayList();
     768                name_to_values.put(name_str, values);
     769                }
     770                if(!values.contains(value_str)) {
     771                values.add(value_str);
     772                }
     773                values = null;
     774                value_str = null;
     775                name_str = null;
     776                attribute = null;
     777            }
     778            attributes = null;
     779            set = null;
     780            language_box.setEnabled(false);
     781            }
     782            sets = null;
     783            // If this is an add remove all the attributes already present in the current set.
     784            if(source == add_attribute) {
     785            name.setEnabled(true);
     786            NamedNodeMap attributes = current_set.getAttributes();
     787            for(int i = 0; i < attributes.getLength(); i++) {
     788                Attr attribute = (Attr) attributes.item(i);
     789                String name_str = attribute.getName();
     790                name_to_values.remove(name_str);
     791                name_str = null;
     792                attribute = null;
     793            }
     794            attributes = null;
     795            }
     796        }
     797        // Otherwise we actually disable the name combobox
     798        else {
     799            name.setEnabled(false);
     800        }
     801        // Now name_to_values should contain a list of unique attribute names each mapping to a list of attribute values.
     802        for(Iterator name_iterator = name_to_values.keySet().iterator(); name_iterator.hasNext(); ) {
     803            name.add(name_iterator.next());
     804        }
     805        // Now pritty up the dialog depending on the action type
     806        if(source == add_attribute) {
     807            add_type = true;
     808            setTitle(get("AddAttribute"));
     809            if(current_collection_file != null) {
     810            // Name is empty in this one, however values must be the current elements in the collection.   
     811            java.util.List values = Gatherer.c_man.msm.getElements();
     812            for(int i = 0; i < values.size(); i++) {
     813                value.add(new NameElementWrapperEntry(values.get(i)));
     814            }
     815            values = null;
     816            }
     817            show();
     818        }
     819        else if(current_attribute != -1) {
     820            add_type = false;
     821            setTitle(get("EditAttribute"));
     822            String name_str = (String) profile_attributes.getValueAt(current_attribute, 0);
     823            String value_str = (String) profile_attributes.getValueAt(current_attribute, 1);
     824            // Retrieve the appropriate value model
     825            java.util.List values = (java.util.List) name_to_values.get(name_str);
     826            // Only possible for collection file selections.
     827            if(values == null) {
     828            values = Gatherer.c_man.msm.getElements();
     829            }
     830            name.setSelectedItem(name_str);
     831            name_str = null;
     832            for(int i = 0; i < values.size(); i++) {
     833            value.add(new NameElementWrapperEntry(values.get(i)));
     834            }
     835            values = null;
     836            value.setSelectedItem(value_str);
     837            value_str = null;
     838            show();
     839        }
     840        }
     841        source = null;
     842    }
     843         
     844    public void dispose() {
     845        cancel_button = null;
     846        name = null;
     847        name_to_values = null;
     848        ok_button = null;
     849        target = null;
     850        value = null;
     851    }
     852    }
    853853     
    854     private class AddElementActionListener
    855           extends JDialog
    856           implements ActionListener {
    857           private JButton cancel_button = null;
    858           private JButton ok_button = null;
    859           private JLabel set_field = null;
    860           private JTextField name_field = null;
    861           public AddElementActionListener() {
    862                 super(self);
    863                 setModal(true);
    864                 setSize(ADD_ELEMENT_SIZE);
     854    private class AddElementActionListener
     855    extends JDialog
     856    implements ActionListener {
     857    private JButton cancel_button = null;
     858    private JButton ok_button = null;
     859    private JLabel set_field = null;
     860    private JTextField name_field = null;
     861    public AddElementActionListener() {
     862        super(self);
     863        setModal(true);
     864        setSize(ADD_ELEMENT_SIZE);
    865865                // Creation
    866                 JPanel content_pane = (JPanel) getContentPane();
    867                 content_pane.setBackground(Gatherer.config.getColor("coloring.collection_heading_background", false));
    868                 JPanel center_pane = new JPanel();
    869                 center_pane.setOpaque(false);
    870                 JPanel set_pane = new JPanel();
    871                 set_pane.setOpaque(false);
    872                 JLabel set_label = new JLabel(get("Set"));
    873                 set_label.setOpaque(false);
    874                 set_label.setPreferredSize(LABEL_SIZE);
    875                 set_field = new JLabel();
    876                 set_field.setOpaque(false);
    877                 JPanel name_pane = new JPanel();
    878                 name_pane.setOpaque(false);
    879                 JLabel name_label = new JLabel(get("Name"));
    880                 name_label.setOpaque(false);
    881                 name_label.setPreferredSize(LABEL_SIZE);
    882                 name_field = new JTextField();
    883                 name_field.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
    884                 name_field.setForeground(Gatherer.config.getColor("coloring.collection_tree_foreground", false));
    885                 name_field.setSelectionColor(Gatherer.config.getColor("coloring.collection_selection_background", false));
    886                 name_field.setSelectedTextColor(Gatherer.config.getColor("coloring.collection_selection_foreground", false));
    887                 JPanel button_pane = new JPanel();
    888                 button_pane.setOpaque(false);
    889                 ok_button = new JButton(get("General.OK"));
    890                 cancel_button = new JButton(get("General.Cancel"));
    891                 TextFieldEnabler ok_button_enabler = new TextFieldEnabler(ok_button);
     866        JPanel content_pane = (JPanel) getContentPane();
     867        content_pane.setBackground(Gatherer.config.getColor("coloring.collection_heading_background", false));
     868        JPanel center_pane = new JPanel();
     869        center_pane.setOpaque(false);
     870        JPanel set_pane = new JPanel();
     871        set_pane.setOpaque(false);
     872        JLabel set_label = new JLabel(get("Set"));
     873        set_label.setOpaque(false);
     874        set_label.setPreferredSize(LABEL_SIZE);
     875        set_field = new JLabel();
     876        set_field.setOpaque(false);
     877        JPanel name_pane = new JPanel();
     878        name_pane.setOpaque(false);
     879        JLabel name_label = new JLabel(get("Name"));
     880        name_label.setOpaque(false);
     881        name_label.setPreferredSize(LABEL_SIZE);
     882        name_field = new JTextField();
     883        name_field.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
     884        name_field.setForeground(Gatherer.config.getColor("coloring.collection_tree_foreground", false));
     885        name_field.setSelectionColor(Gatherer.config.getColor("coloring.collection_selection_background", false));
     886        name_field.setSelectedTextColor(Gatherer.config.getColor("coloring.collection_selection_foreground", false));
     887        JPanel button_pane = new JPanel();
     888        button_pane.setOpaque(false);
     889        ok_button = new JButton(get("General.OK"));
     890        cancel_button = new JButton(get("General.Cancel"));
     891        TextFieldEnabler ok_button_enabler = new TextFieldEnabler(ok_button);
    892892                // Connection
    893                 cancel_button.addActionListener(this);
    894                 ok_button.addActionListener(this);
    895                 ok_button_enabler.add(name_field);
     893        cancel_button.addActionListener(this);
     894        ok_button.addActionListener(this);
     895        ok_button_enabler.add(name_field);
    896896                // Layout
    897                 set_pane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
    898                 set_pane.setLayout(new BorderLayout());
    899                 set_pane.add(set_label, BorderLayout.WEST);
    900                 set_pane.add(set_field, BorderLayout.CENTER);
    901 
    902                 name_pane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
    903                 name_pane.setLayout(new BorderLayout());
    904                 name_pane.add(name_label, BorderLayout.WEST);
    905                 name_pane.add(name_field, BorderLayout.CENTER);
    906 
    907                 center_pane.setLayout(new GridLayout(2,1,0,0));
    908                 center_pane.add(set_pane);
    909                 center_pane.add(name_pane);
    910 
    911                 button_pane.setLayout(new GridLayout(1,2,0,5));
    912                 button_pane.add(ok_button);
    913                 button_pane.add(cancel_button);
    914 
    915                 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
    916                 content_pane.setLayout(new BorderLayout());
    917                 content_pane.add(center_pane, BorderLayout.CENTER);
    918                 content_pane.add(button_pane, BorderLayout.SOUTH);
    919 
    920                 setLocation((Gatherer.config.screen_size.width - ADD_ELEMENT_SIZE.width) / 2, (Gatherer.config.screen_size.height - ADD_ELEMENT_SIZE.height) / 2);
    921           }
    922           /** Any implementation of ActionListener must include this method so that we can be informed when an action as occured on our registered component, allowing us to
    923             * @param event An <strong>ActionEvent</strong> containing information about the event.
    924             */
    925           public void actionPerformed(ActionEvent event) {
    926                 Object source = event.getSource();
    927                 if(source == ok_button) {
    928                      // Add then dispose
    929                      String name_str = name_field.getText();
    930                      // If this element doesn't already exist.
    931                      if(!current_set.containsElement(name_str)) {
    932                           // Add it,
    933                           ElementWrapper element = current_set.addElement(name_str);
    934                           // Then update the tree
    935                           model.add(current_node, element, MEMNode.ELEMENT);
    936                           // Done
    937                           element = null;
    938                           hide();
    939                      }
    940                      // Otherwise show an error message and do not proceed.
    941                      else {
    942                           JOptionPane.showMessageDialog(self, get("Element_Already_Exists"), get("General.Error"), JOptionPane.ERROR_MESSAGE);
    943                      }
    944                      name_str = null;
    945                 }
    946                 else if(source == cancel_button) {
    947                      // Dispose
    948                      hide();
    949                 }
    950                 else {
    951                      if(current_set != null) {
    952                           // You can't manually add elements to the Greenstone metadata set.
    953                           if(!current_set.getNamespace().equals("")) {
    954                                 set_field.setText(current_set.toString());
    955                                 name_field.setText("");
    956                                 // Display
    957                                 show();
    958                           }
    959                           // Warn the user that they can't do that dave.
    960                           else {
    961                                 JOptionPane.showMessageDialog(self, get("Cannot_Add_Elements_To_Greenstone_MDS"), get("General.Error"), JOptionPane.ERROR_MESSAGE);
    962                           }
    963                      }
    964                 }
    965                 source = null;
    966           }
    967 
    968           public void dispose() {
    969                 cancel_button = null;
    970                 ok_button = null;
    971                 name_field = null;
    972                 set_field = null;
    973           }
    974     }
     897        set_pane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
     898        set_pane.setLayout(new BorderLayout());
     899        set_pane.add(set_label, BorderLayout.WEST);
     900        set_pane.add(set_field, BorderLayout.CENTER);
     901
     902        name_pane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
     903        name_pane.setLayout(new BorderLayout());
     904        name_pane.add(name_label, BorderLayout.WEST);
     905        name_pane.add(name_field, BorderLayout.CENTER);
     906
     907        center_pane.setLayout(new GridLayout(2,1,0,0));
     908        center_pane.add(set_pane);
     909        center_pane.add(name_pane);
     910
     911        button_pane.setLayout(new GridLayout(1,2,0,5));
     912        button_pane.add(ok_button);
     913        button_pane.add(cancel_button);
     914
     915        content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
     916        content_pane.setLayout(new BorderLayout());
     917        content_pane.add(center_pane, BorderLayout.CENTER);
     918        content_pane.add(button_pane, BorderLayout.SOUTH);
     919
     920        setLocation((Gatherer.config.screen_size.width - ADD_ELEMENT_SIZE.width) / 2, (Gatherer.config.screen_size.height - ADD_ELEMENT_SIZE.height) / 2);
     921    }
     922    /** Any implementation of ActionListener must include this method so that we can be informed when an action as occured on our registered component, allowing us to
     923     * @param event An <strong>ActionEvent</strong> containing information about the event.
     924     */
     925    public void actionPerformed(ActionEvent event) {
     926        Object source = event.getSource();
     927        if(source == ok_button) {
     928        // Add then dispose
     929        String name_str = name_field.getText();
     930        // If this element doesn't already exist.
     931        if(!current_set.containsElement(name_str)) {
     932            // Add it,
     933            ElementWrapper element = current_set.addElement(name_str);
     934            // Then update the tree
     935            model.add(current_node, element, MEMNode.ELEMENT);
     936            // Done
     937            element = null;
     938            hide();
     939        }
     940        // Otherwise show an error message and do not proceed.
     941        else {
     942            JOptionPane.showMessageDialog(self, get("Element_Already_Exists"), get("General.Error"), JOptionPane.ERROR_MESSAGE);
     943        }
     944        name_str = null;
     945        }
     946        else if(source == cancel_button) {
     947        // Dispose
     948        hide();
     949        }
     950        else {
     951        if(current_set != null) {
     952            // You can't manually add elements to the Greenstone metadata set.
     953            if(!current_set.getNamespace().equals("")) {
     954            set_field.setText(current_set.toString());
     955            name_field.setText("");
     956            // Display
     957            show();
     958            }
     959            // Warn the user that they can't do that dave.
     960            else {
     961            JOptionPane.showMessageDialog(self, get("Cannot_Add_Elements_To_Greenstone_MDS"), get("General.Error"), JOptionPane.ERROR_MESSAGE);
     962            }
     963        }
     964        }
     965        source = null;
     966    }
     967
     968    public void dispose() {
     969        cancel_button = null;
     970        ok_button = null;
     971        name_field = null;
     972        set_field = null;
     973    }
     974    }
    975975     
    976     private class AddFileActionListener
    977           extends JDialog
    978           implements ActionListener {
    979           private JButton cancel_button = null;
    980           private JButton ok_button = null;
    981           private JTextField name_field = null;
    982           public AddFileActionListener() {
    983                 super(self);
    984                 setModal(true);
    985                 setSize(ADD_FILE_SIZE);
     976    private class AddFileActionListener
     977    extends JDialog
     978    implements ActionListener {
     979    private JButton cancel_button = null;
     980    private JButton ok_button = null;
     981    private JTextField name_field = null;
     982    public AddFileActionListener() {
     983        super(self);
     984        setModal(true);
     985        setSize(ADD_FILE_SIZE);
    986986                // Creation
    987                 JPanel content_pane = (JPanel) getContentPane();
    988                 content_pane.setBackground(Gatherer.config.getColor("coloring.collection_heading_background", false));
    989                 JPanel center_pane = new JPanel();
    990                 center_pane.setOpaque(false);
    991                 JPanel profile_pane = new JPanel();
    992                 profile_pane.setOpaque(false);
    993                 JLabel profile_label = new JLabel(get("Profile"));
    994                 profile_label.setOpaque(false);
    995                 profile_label.setPreferredSize(LABEL_SIZE);
    996                 JPanel name_pane = new JPanel();
    997                 name_pane.setOpaque(false);
    998                 JLabel name_label = new JLabel(get("Name"));
    999                 name_label.setOpaque(false);
    1000                 name_label.setPreferredSize(LABEL_SIZE);
    1001                 name_field = new JTextField();
    1002                 name_field.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
    1003                 name_field.setForeground(Gatherer.config.getColor("coloring.collection_tree_foreground", false));
    1004                 name_field.setSelectionColor(Gatherer.config.getColor("coloring.collection_selection_background", false));
    1005                 name_field.setSelectedTextColor(Gatherer.config.getColor("coloring.collection_selection_foreground", false));
    1006                 JPanel button_pane = new JPanel();
    1007                 button_pane.setOpaque(false);
    1008                 ok_button = new JButton(get("General.OK"));
    1009                 cancel_button = new JButton(get("General.Cancel"));
    1010                 TextFieldEnabler ok_button_enabler = new TextFieldEnabler(ok_button);
     987        JPanel content_pane = (JPanel) getContentPane();
     988        content_pane.setBackground(Gatherer.config.getColor("coloring.collection_heading_background", false));
     989        JPanel center_pane = new JPanel();
     990        center_pane.setOpaque(false);
     991        JPanel profile_pane = new JPanel();
     992        profile_pane.setOpaque(false);
     993        JLabel profile_label = new JLabel(get("Profile"));
     994        profile_label.setOpaque(false);
     995        profile_label.setPreferredSize(LABEL_SIZE);
     996        JPanel name_pane = new JPanel();
     997        name_pane.setOpaque(false);
     998        JLabel name_label = new JLabel(get("Name"));
     999        name_label.setOpaque(false);
     1000        name_label.setPreferredSize(LABEL_SIZE);
     1001        name_field = new JTextField();
     1002        name_field.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
     1003        name_field.setForeground(Gatherer.config.getColor("coloring.collection_tree_foreground", false));
     1004        name_field.setSelectionColor(Gatherer.config.getColor("coloring.collection_selection_background", false));
     1005        name_field.setSelectedTextColor(Gatherer.config.getColor("coloring.collection_selection_foreground", false));
     1006        JPanel button_pane = new JPanel();
     1007        button_pane.setOpaque(false);
     1008        ok_button = new JButton(get("General.OK"));
     1009        cancel_button = new JButton(get("General.Cancel"));
     1010        TextFieldEnabler ok_button_enabler = new TextFieldEnabler(ok_button);
    10111011                // Connection
    1012                 cancel_button.addActionListener(this);
    1013                 ok_button.addActionListener(this);
    1014                 ok_button_enabler.add(name_field);
     1012        cancel_button.addActionListener(this);
     1013        ok_button.addActionListener(this);
     1014        ok_button_enabler.add(name_field);
    10151015                // Layout
    1016                 profile_pane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
    1017                 profile_pane.setLayout(new BorderLayout());
    1018                 profile_pane.add(profile_label, BorderLayout.CENTER);
    1019 
    1020                 name_pane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
    1021                 name_pane.setLayout(new BorderLayout());
    1022                 name_pane.add(name_label, BorderLayout.WEST);
    1023                 name_pane.add(name_field, BorderLayout.CENTER);
    1024 
    1025                 center_pane.setLayout(new GridLayout(2,1,0,0));
    1026                 center_pane.add(profile_pane);
    1027                 center_pane.add(name_pane);
    1028 
    1029                 button_pane.setLayout(new GridLayout(1,2,0,5));
    1030                 button_pane.add(ok_button);
    1031                 button_pane.add(cancel_button);
    1032 
    1033                 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
    1034                 content_pane.setLayout(new BorderLayout());
    1035                 content_pane.add(center_pane, BorderLayout.CENTER);
    1036                 content_pane.add(button_pane, BorderLayout.SOUTH);
    1037 
    1038                 setLocation((Gatherer.config.screen_size.width - ADD_FILE_SIZE.width) / 2, (Gatherer.config.screen_size.height - ADD_FILE_SIZE.height) / 2);
    1039           }
    1040           /** Any implementation of ActionListener must include this method so that we can be informed when an action as occured on our registered component, allowing us to
    1041             * @param event An <strong>ActionEvent</strong> containing information about the event.
    1042             */
    1043           public void actionPerformed(ActionEvent event) {
    1044                 Object source = event.getSource();
    1045                 if(source == ok_button) {
    1046                      String name_str = name_field.getText();
    1047                      // Ensure that this source doesn't already exist.
    1048                      if(!Gatherer.c_man.msm.profiler.containsSource(name_str)) {
    1049                           // Add source with empty hashmap of actions.
    1050                           Gatherer.c_man.msm.profiler.addSource(name_str);
    1051                           // Add to tree
    1052                           model.add(model.getProfileNode(), name_str, MEMNode.COLLECTION);
    1053                           hide();
    1054                      }
    1055                      // Otherwise warn the user and don't hide the prompt.
    1056                      else {
    1057                           JOptionPane.showMessageDialog(self, get("File_Already_Exists"), get("General.Error"), JOptionPane.ERROR_MESSAGE);
    1058                      }
    1059                      name_str = null;
    1060                 }
    1061                 else if(source == cancel_button) {
    1062                      hide();
    1063                 }
    1064                 else {
    1065                      name_field.setText("");
    1066                      show();
    1067                 }
    1068                 source = null;
    1069           }
    1070 
    1071           public void dispose() {
    1072                 cancel_button = null;
    1073                 ok_button = null;
    1074                 name_field = null;
    1075           }
    1076     }
    1077 
    1078     private class AddSetActionListener
    1079           extends JDialog
    1080           implements ActionListener {
    1081           private JButton cancel_button = null;
    1082           private JButton ok_button = null;
    1083           private JTextField name_field = null;
    1084           private JTextField namespace_field = null;
    1085           public AddSetActionListener() {
    1086                 super(self);
    1087                 setModal(true);
    1088                 setSize(ADD_SET_SIZE);
    1089                 setTitle(get("AddSet"));
     1016        profile_pane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
     1017        profile_pane.setLayout(new BorderLayout());
     1018        profile_pane.add(profile_label, BorderLayout.CENTER);
     1019
     1020        name_pane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
     1021        name_pane.setLayout(new BorderLayout());
     1022        name_pane.add(name_label, BorderLayout.WEST);
     1023        name_pane.add(name_field, BorderLayout.CENTER);
     1024
     1025        center_pane.setLayout(new GridLayout(2,1,0,0));
     1026        center_pane.add(profile_pane);
     1027        center_pane.add(name_pane);
     1028
     1029        button_pane.setLayout(new GridLayout(1,2,0,5));
     1030        button_pane.add(ok_button);
     1031        button_pane.add(cancel_button);
     1032
     1033        content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
     1034        content_pane.setLayout(new BorderLayout());
     1035        content_pane.add(center_pane, BorderLayout.CENTER);
     1036        content_pane.add(button_pane, BorderLayout.SOUTH);
     1037
     1038        setLocation((Gatherer.config.screen_size.width - ADD_FILE_SIZE.width) / 2, (Gatherer.config.screen_size.height - ADD_FILE_SIZE.height) / 2);
     1039    }
     1040    /** Any implementation of ActionListener must include this method so that we can be informed when an action as occured on our registered component, allowing us to
     1041     * @param event An <strong>ActionEvent</strong> containing information about the event.
     1042     */
     1043    public void actionPerformed(ActionEvent event) {
     1044        Object source = event.getSource();
     1045        if(source == ok_button) {
     1046        String name_str = name_field.getText();
     1047        // Ensure that this source doesn't already exist.
     1048        if(!Gatherer.c_man.msm.profiler.containsSource(name_str)) {
     1049            // Add source with empty hashmap of actions.
     1050            Gatherer.c_man.msm.profiler.addSource(name_str);
     1051            // Add to tree
     1052            model.add(model.getProfileNode(), name_str, MEMNode.COLLECTION);
     1053            hide();
     1054        }
     1055        // Otherwise warn the user and don't hide the prompt.
     1056        else {
     1057            JOptionPane.showMessageDialog(self, get("File_Already_Exists"), get("General.Error"), JOptionPane.ERROR_MESSAGE);
     1058        }
     1059        name_str = null;
     1060        }
     1061        else if(source == cancel_button) {
     1062        hide();
     1063        }
     1064        else {
     1065        name_field.setText("");
     1066        show();
     1067        }
     1068        source = null;
     1069    }
     1070
     1071    public void dispose() {
     1072        cancel_button = null;
     1073        ok_button = null;
     1074        name_field = null;
     1075    }
     1076    }
     1077
     1078    private class AddSetActionListener
     1079    extends JDialog
     1080    implements ActionListener {
     1081    private JButton cancel_button = null;
     1082    private JButton ok_button = null;
     1083    private JTextField name_field = null;
     1084    private JTextField namespace_field = null;
     1085    public AddSetActionListener() {
     1086        super(self);
     1087        setModal(true);
     1088        setSize(ADD_SET_SIZE);
     1089        setTitle(get("AddSet"));
    10901090                // Creation
    1091                 JPanel content_pane = (JPanel) getContentPane();
    1092                 content_pane.setBackground(Gatherer.config.getColor("coloring.collection_heading_background", false));
    1093                 JPanel center_pane = new JPanel();
    1094                 center_pane.setOpaque(false);
    1095 
    1096                 JPanel namespace_pane = new JPanel();
    1097                 namespace_pane.setOpaque(false);
    1098                 JLabel namespace_label = new JLabel(get("Namespace"));
    1099                 namespace_label.setOpaque(false);
    1100                 namespace_label.setPreferredSize(LABEL_SIZE);
    1101                 namespace_field = new JTextField();
    1102                 namespace_field.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
    1103                 namespace_field.setForeground(Gatherer.config.getColor("coloring.collection_tree_foreground", false));
    1104                 namespace_field.setSelectionColor(Gatherer.config.getColor("coloring.collection_selection_background", false));
    1105                 namespace_field.setSelectedTextColor(Gatherer.config.getColor("coloring.collection_selection_foreground", false));
    1106 
    1107                 JPanel name_pane = new JPanel();
    1108                 name_pane.setOpaque(false);
    1109                 JLabel name_label = new JLabel(get("Name"));
    1110                 name_label.setOpaque(false);
    1111                 name_label.setPreferredSize(LABEL_SIZE);
    1112                 name_field = new JTextField();
    1113                 name_field.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
    1114                 name_field.setForeground(Gatherer.config.getColor("coloring.collection_tree_foreground", false));
    1115                 name_field.setSelectionColor(Gatherer.config.getColor("coloring.collection_selection_background", false));
    1116                 name_field.setSelectedTextColor(Gatherer.config.getColor("coloring.collection_selection_foreground", false));
    1117 
    1118                 JPanel button_pane = new JPanel();
    1119                 button_pane.setOpaque(false);
    1120                 ok_button = new JButton(get("General.OK"));
    1121                 ok_button.setEnabled(false);
    1122                 cancel_button = new JButton(get("General.Cancel"));
    1123                 TextFieldEnabler ok_button_enabler = new TextFieldEnabler(ok_button);
     1091        JPanel content_pane = (JPanel) getContentPane();
     1092        content_pane.setBackground(Gatherer.config.getColor("coloring.collection_heading_background", false));
     1093        JPanel center_pane = new JPanel();
     1094        center_pane.setOpaque(false);
     1095
     1096        JPanel namespace_pane = new JPanel();
     1097        namespace_pane.setOpaque(false);
     1098        JLabel namespace_label = new JLabel(get("Namespace"));
     1099        namespace_label.setOpaque(false);
     1100        namespace_label.setPreferredSize(LABEL_SIZE);
     1101        namespace_field = new JTextField();
     1102        namespace_field.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
     1103        namespace_field.setForeground(Gatherer.config.getColor("coloring.collection_tree_foreground", false));
     1104        namespace_field.setSelectionColor(Gatherer.config.getColor("coloring.collection_selection_background", false));
     1105        namespace_field.setSelectedTextColor(Gatherer.config.getColor("coloring.collection_selection_foreground", false));
     1106
     1107        JPanel name_pane = new JPanel();
     1108        name_pane.setOpaque(false);
     1109        JLabel name_label = new JLabel(get("Name"));
     1110        name_label.setOpaque(false);
     1111        name_label.setPreferredSize(LABEL_SIZE);
     1112        name_field = new JTextField();
     1113        name_field.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
     1114        name_field.setForeground(Gatherer.config.getColor("coloring.collection_tree_foreground", false));
     1115        name_field.setSelectionColor(Gatherer.config.getColor("coloring.collection_selection_background", false));
     1116        name_field.setSelectedTextColor(Gatherer.config.getColor("coloring.collection_selection_foreground", false));
     1117
     1118        JPanel button_pane = new JPanel();
     1119        button_pane.setOpaque(false);
     1120        ok_button = new JButton(get("General.OK"));
     1121        ok_button.setEnabled(false);
     1122        cancel_button = new JButton(get("General.Cancel"));
     1123        TextFieldEnabler ok_button_enabler = new TextFieldEnabler(ok_button);
    11241124                // Connection
    1125                 cancel_button.addActionListener(this);
    1126                 ok_button.addActionListener(this);
    1127                 ok_button_enabler.add(name_field);
    1128                 ok_button_enabler.add(namespace_field);
     1125        cancel_button.addActionListener(this);
     1126        ok_button.addActionListener(this);
     1127        ok_button_enabler.add(name_field);
     1128        ok_button_enabler.add(namespace_field);
    11291129                // Layout
    1130                 namespace_pane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
    1131                 namespace_pane.setLayout(new BorderLayout());
    1132                 namespace_pane.add(namespace_label, BorderLayout.WEST);
    1133                 namespace_pane.add(namespace_field, BorderLayout.CENTER);
    1134 
    1135                 name_pane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
    1136                 name_pane.setLayout(new BorderLayout());
    1137                 name_pane.add(name_label, BorderLayout.WEST);
    1138                 name_pane.add(name_field, BorderLayout.CENTER);
    1139 
    1140                 center_pane.setLayout(new GridLayout(2,1));
    1141                 center_pane.add(namespace_pane);
    1142                 center_pane.add(name_pane);
    1143 
    1144                 button_pane.setLayout(new GridLayout(1,2,0,5));
    1145                 button_pane.add(ok_button);
    1146                 button_pane.add(cancel_button);
    1147 
    1148                 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
    1149                 content_pane.setLayout(new BorderLayout());
    1150                 content_pane.add(center_pane, BorderLayout.CENTER);
    1151                 content_pane.add(button_pane, BorderLayout.SOUTH);
    1152 
    1153                 setLocation((Gatherer.config.screen_size.width - ADD_SET_SIZE.width) / 2, (Gatherer.config.screen_size.height - ADD_SET_SIZE.height) / 2);
    1154           }
    1155           /** Any implementation of ActionListener must include this method so that we can be informed when an action as occured on our registered component, allowing us to
    1156             * @param event An <strong>ActionEvent</strong> containing information about the event.
    1157             */
    1158           public void actionPerformed(ActionEvent event) {
    1159                 Object source = event.getSource();
    1160                 if(source == ok_button) {
    1161                      String namespace_str = namespace_field.getText();
    1162                      String name_str = name_field.getText();
    1163                      // Ensure the set doesn't already exist
    1164                      if(Gatherer.c_man.msm.getSet(name_str) == null) {
    1165                           MetadataSet set = Gatherer.c_man.msm.addSet(namespace_str, name_str);
    1166                           // Update tree.
    1167                           model.add(null, set, MEMNode.SET);
    1168                           // Done
    1169                           set = null;
    1170                           hide();
    1171                      }
    1172                      // Otherwise show a warning.
    1173                      else {
    1174                           JOptionPane.showMessageDialog(self, get("Set_Already_Exists"), get("General.Error"), JOptionPane.ERROR_MESSAGE);
    1175                      }
    1176                      name_str = null;
    1177                      namespace_str = null;
    1178                 }
    1179                 else if(source == cancel_button) {
    1180                      hide();
    1181                 }
    1182                 else {
    1183                      name_field.setText("");
    1184                      show();
    1185                 }
    1186           }
    1187          
    1188           public void dispose() {
    1189                 cancel_button = null;
    1190                 ok_button = null;
    1191                 name_field = null;
    1192           }
    1193     }
     1130        namespace_pane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
     1131        namespace_pane.setLayout(new BorderLayout());
     1132        namespace_pane.add(namespace_label, BorderLayout.WEST);
     1133        namespace_pane.add(namespace_field, BorderLayout.CENTER);
     1134
     1135        name_pane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
     1136        name_pane.setLayout(new BorderLayout());
     1137        name_pane.add(name_label, BorderLayout.WEST);
     1138        name_pane.add(name_field, BorderLayout.CENTER);
     1139
     1140        center_pane.setLayout(new GridLayout(2,1));
     1141        center_pane.add(namespace_pane);
     1142        center_pane.add(name_pane);
     1143
     1144        button_pane.setLayout(new GridLayout(1,2,0,5));
     1145        button_pane.add(ok_button);
     1146        button_pane.add(cancel_button);
     1147
     1148        content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
     1149        content_pane.setLayout(new BorderLayout());
     1150        content_pane.add(center_pane, BorderLayout.CENTER);
     1151        content_pane.add(button_pane, BorderLayout.SOUTH);
     1152
     1153        setLocation((Gatherer.config.screen_size.width - ADD_SET_SIZE.width) / 2, (Gatherer.config.screen_size.height - ADD_SET_SIZE.height) / 2);
     1154    }
     1155    /** Any implementation of ActionListener must include this method so that we can be informed when an action as occured on our registered component, allowing us to
     1156     * @param event An <strong>ActionEvent</strong> containing information about the event.
     1157     */
     1158    public void actionPerformed(ActionEvent event) {
     1159        Object source = event.getSource();
     1160        if(source == ok_button) {
     1161        String namespace_str = namespace_field.getText();
     1162        String name_str = name_field.getText();
     1163        // Ensure the set doesn't already exist
     1164        if(Gatherer.c_man.msm.getSet(name_str) == null) {
     1165            MetadataSet set = Gatherer.c_man.msm.addSet(namespace_str, name_str);
     1166            // Update tree.
     1167            model.add(null, set, MEMNode.SET);
     1168            // Done
     1169            set = null;
     1170            hide();
     1171        }
     1172        // Otherwise show a warning.
     1173        else {
     1174            JOptionPane.showMessageDialog(self, get("Set_Already_Exists"), get("General.Error"), JOptionPane.ERROR_MESSAGE);
     1175        }
     1176        name_str = null;
     1177        namespace_str = null;
     1178        }
     1179        else if(source == cancel_button) {
     1180        hide();
     1181        }
     1182        else {
     1183        name_field.setText("");
     1184        show();
     1185        }
     1186    }
     1187         
     1188    public void dispose() {
     1189        cancel_button = null;
     1190        ok_button = null;
     1191        name_field = null;
     1192    }
     1193    }
    11941194     
    1195     private class AddOrEditValueActionListener
    1196           extends JDialog
    1197           implements ActionListener, TreeSelectionListener {
    1198           private boolean add_type = true;
    1199           private boolean ignore = false;
    1200           private GValueNode subject_node = null;
    1201           private JButton cancel_button = null;
    1202           private JButton ok_button = null;
    1203           private JTextArea value = null;
    1204           private JTextField alias = null;
    1205           private SmarterTree subject_tree = null;
    1206 
    1207           /** Constructor. */
    1208           public AddOrEditValueActionListener() {
    1209                 super(self);
    1210                 this.setModal(true);
    1211                 this.setSize(ADD_OR_EDIT_VALUE_SIZE);
     1195    private class AddOrEditValueActionListener
     1196    extends JDialog
     1197    implements ActionListener, TreeSelectionListener {
     1198    private boolean add_type = true;
     1199    private boolean ignore = false;
     1200    private GValueNode subject_node = null;
     1201    private JButton cancel_button = null;
     1202    private JButton ok_button = null;
     1203    private JTextArea value = null;
     1204    private JTextField alias = null;
     1205    private SmarterTree subject_tree = null;
     1206
     1207    /** Constructor. */
     1208    public AddOrEditValueActionListener() {
     1209        super(self);
     1210        this.setModal(true);
     1211        this.setSize(ADD_OR_EDIT_VALUE_SIZE);
    12121212                // Create
    1213                 JPanel content_pane = (JPanel) getContentPane();
    1214                 content_pane.setBackground(Gatherer.config.getColor("coloring.collection_heading_background", false));
    1215                 JPanel center_pane = new JPanel();
    1216                 center_pane.setOpaque(false);
    1217                 JPanel inner_pane = new JPanel();
    1218                 inner_pane.setOpaque(false);
    1219                 JPanel subject_tree_pane = new JPanel();
    1220                 subject_tree_pane.setOpaque(false);
    1221                 JLabel subject_tree_label = new JLabel(get("Subject"));
    1222                 subject_tree_label.setOpaque(false);
    1223                 subject_tree = new SmarterTree();
    1224                 subject_tree.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
    1225                 subject_tree.setForeground(Gatherer.config.getColor("coloring.collection_tree_foreground", false));
    1226                 subject_tree.setSelectionColor(Gatherer.config.getColor("coloring.collection_selection_background", false));
    1227                 subject_tree.setSelectedTextColor(Gatherer.config.getColor("coloring.collection_selection_foreground", false));
    1228                 JPanel value_pane = new JPanel();
    1229                 value_pane.setOpaque(false);
    1230                 JLabel value_label = new JLabel(get("Value"));
    1231                 value_label.setOpaque(false);
    1232                 value = new JTextArea();
    1233                 value.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
    1234                 value.setForeground(Gatherer.config.getColor("coloring.collection_tree_foreground", false));
    1235                 value.setSelectionColor(Gatherer.config.getColor("coloring.collection_selection_background", false));
    1236                 value.setSelectedTextColor(Gatherer.config.getColor("coloring.collection_selection_foreground", false));
    1237                 JPanel alias_pane = new JPanel();
    1238                 alias_pane.setOpaque(false);
    1239                 JLabel alias_label = new JLabel(get("Alias"));
    1240                 alias_label.setOpaque(false);
    1241                 alias_label.setPreferredSize(LABEL_SIZE);
    1242                 alias = new JTextField();
    1243                 alias.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
    1244                 alias.setForeground(Gatherer.config.getColor("coloring.collection_tree_foreground", false));
    1245                 alias.setSelectionColor(Gatherer.config.getColor("coloring.collection_selection_background", false));
    1246                 alias.setSelectedTextColor(Gatherer.config.getColor("coloring.collection_selection_foreground", false));
    1247                 JPanel button_pane = new JPanel();
    1248                 button_pane.setOpaque(false);
    1249                 ok_button = new JButton(get("General.OK"));
    1250                 ok_button.setEnabled(false);
    1251                 cancel_button = new JButton(get("General.Cancel"));
     1213        JPanel content_pane = (JPanel) getContentPane();
     1214        content_pane.setBackground(Gatherer.config.getColor("coloring.collection_heading_background", false));
     1215        JPanel center_pane = new JPanel();
     1216        center_pane.setOpaque(false);
     1217        JPanel inner_pane = new JPanel();
     1218        inner_pane.setOpaque(false);
     1219        JPanel subject_tree_pane = new JPanel();
     1220        subject_tree_pane.setOpaque(false);
     1221        JLabel subject_tree_label = new JLabel(get("Subject"));
     1222        subject_tree_label.setOpaque(false);
     1223        subject_tree = new SmarterTree();
     1224        subject_tree.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
     1225        subject_tree.setForeground(Gatherer.config.getColor("coloring.collection_tree_foreground", false));
     1226        subject_tree.setSelectionColor(Gatherer.config.getColor("coloring.collection_selection_background", false));
     1227        subject_tree.setSelectedTextColor(Gatherer.config.getColor("coloring.collection_selection_foreground", false));
     1228        JPanel value_pane = new JPanel();
     1229        value_pane.setOpaque(false);
     1230        JLabel value_label = new JLabel(get("Value"));
     1231        value_label.setOpaque(false);
     1232        value = new JTextArea();
     1233        value.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
     1234        value.setForeground(Gatherer.config.getColor("coloring.collection_tree_foreground", false));
     1235        value.setSelectionColor(Gatherer.config.getColor("coloring.collection_selection_background", false));
     1236        value.setSelectedTextColor(Gatherer.config.getColor("coloring.collection_selection_foreground", false));
     1237        JPanel alias_pane = new JPanel();
     1238        alias_pane.setOpaque(false);
     1239        JLabel alias_label = new JLabel(get("Alias"));
     1240        alias_label.setOpaque(false);
     1241        alias_label.setPreferredSize(LABEL_SIZE);
     1242        alias = new JTextField();
     1243        alias.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
     1244        alias.setForeground(Gatherer.config.getColor("coloring.collection_tree_foreground", false));
     1245        alias.setSelectionColor(Gatherer.config.getColor("coloring.collection_selection_background", false));
     1246        alias.setSelectedTextColor(Gatherer.config.getColor("coloring.collection_selection_foreground", false));
     1247        JPanel button_pane = new JPanel();
     1248        button_pane.setOpaque(false);
     1249        ok_button = new JButton(get("General.OK"));
     1250        ok_button.setEnabled(false);
     1251        cancel_button = new JButton(get("General.Cancel"));
    12521252                // Connect
    1253                 TextFieldEnabler ok_button_enabler = new TextFieldEnabler(ok_button);
    1254                 cancel_button.addActionListener(this);
    1255                 ok_button.addActionListener(this);
    1256                 subject_tree.addTreeSelectionListener(this);
    1257                 ok_button_enabler.add(value);
     1253        TextFieldEnabler ok_button_enabler = new TextFieldEnabler(ok_button);
     1254        cancel_button.addActionListener(this);
     1255        ok_button.addActionListener(this);
     1256        subject_tree.addTreeSelectionListener(this);
     1257        ok_button_enabler.add(value);
    12581258                // Layout
    1259                 subject_tree_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
    1260                 subject_tree_pane.setLayout(new BorderLayout());
    1261                 subject_tree_pane.add(subject_tree_label, BorderLayout.NORTH);
    1262                 subject_tree_pane.add(new JScrollPane(subject_tree), BorderLayout.CENTER);
    1263 
    1264                 value_pane.setBorder(BorderFactory.createEmptyBorder(0,5,5,5));
    1265                 value_pane.setLayout(new BorderLayout());
    1266                 value_pane.add(value_label, BorderLayout.NORTH);
    1267                 value_pane.add(new JScrollPane(value), BorderLayout.CENTER);
     1259        subject_tree_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
     1260        subject_tree_pane.setLayout(new BorderLayout());
     1261        subject_tree_pane.add(subject_tree_label, BorderLayout.NORTH);
     1262        subject_tree_pane.add(new JScrollPane(subject_tree), BorderLayout.CENTER);
     1263
     1264        value_pane.setBorder(BorderFactory.createEmptyBorder(0,5,5,5));
     1265        value_pane.setLayout(new BorderLayout());
     1266        value_pane.add(value_label, BorderLayout.NORTH);
     1267        value_pane.add(new JScrollPane(value), BorderLayout.CENTER);
    12681268               
    1269                 inner_pane.setLayout(new GridLayout(2,1));
    1270                 inner_pane.add(subject_tree_pane);
    1271                 inner_pane.add(value_pane);
    1272 
    1273                 alias_pane.setBorder(BorderFactory.createEmptyBorder(0,5,5,5));
    1274                 alias_pane.setLayout(new BorderLayout());
    1275                 alias_pane.add(alias_label, BorderLayout.WEST);
    1276                 alias_pane.add(alias, BorderLayout.CENTER);
    1277 
    1278                 center_pane.setLayout(new BorderLayout());
    1279                 center_pane.add(inner_pane, BorderLayout.CENTER);
    1280                 center_pane.add(alias_pane, BorderLayout.SOUTH);
    1281 
    1282                 button_pane.setBorder(BorderFactory.createEmptyBorder(0,5,5,5));
    1283                 button_pane.setLayout(new GridLayout(1,2,5,5));
    1284                 button_pane.add(ok_button);
    1285                 button_pane.add(cancel_button);
    1286 
    1287                 content_pane.setLayout(new BorderLayout());
    1288                 content_pane.add(center_pane, BorderLayout.CENTER);
    1289                 content_pane.add(button_pane, BorderLayout.SOUTH);
    1290                 setLocation((Gatherer.config.screen_size.width - ADD_OR_EDIT_VALUE_SIZE.width) / 2, (Gatherer.config.screen_size.height - ADD_OR_EDIT_VALUE_SIZE.height) / 2);
    1291           }
    1292           /** Any implementation of ActionListener must include this method so that we can be informed when an action as occured on our registered component, allowing us to add a new metadata value to the assigned values tree.
    1293             * @param event An <strong>ActionEvent</strong> containing information about the event.
    1294             */
    1295           public void actionPerformed(ActionEvent event) {
    1296                 Object source = event.getSource();
    1297                 if(source == ok_button) {
    1298                      // Now we action as necessary
    1299                      GValueModel model = Gatherer.c_man.msm.getValueTree(current_element);
    1300                      if(add_type) {
    1301                           // Add this value to the tree.
    1302                           GValueNode parent = null;
    1303                           model.addValue(value.getText(), subject_node, alias.getText());
    1304                           parent = null;
    1305                      }
    1306                      else {
    1307                           // Rewrite this value in the DOM model. Note that this will automatically rewrite all assignments as they are live references.
    1308                           current_value_node.setValue(value.getText());
    1309                           current_value_node.setAlias(alias.getText());
    1310                           // Now insert the node into the currently selected subject, but only if the parent has changed.
    1311                           if(subject_node != current_value_node.getParent()) {
    1312                                 GValueNode old_subject_node = (GValueNode) current_value_node.getParent();
    1313                                 // Find the new values position in subject_nodes children.
    1314                                 GValueNode sibling = null;
    1315                                 int index = 0;
    1316                                 boolean found = false;
    1317                                 while(index < subject_node.getChildCount() && !found) {
    1318                                     sibling = (GValueNode) subject_node.getChildAt(index);
    1319                                     int order = current_value_node.toString().compareToIgnoreCase(sibling.toString());
    1320                                     // If the sibling is 'greater than' or comes after current value then insert.
    1321                                     if(order < 0) {
    1322                                           // Insert. This will coincidently remove from original parent.
    1323                                           Node parent_node = subject_node.getElement();
    1324                                           Node child_node = current_value_node.getElement();
    1325                                           Node sibling_node = sibling.getElement();
    1326                                           parent_node.insertBefore(child_node, sibling_node);
    1327                                           found = true;
    1328                                     }
    1329                                     // The value already exists exactly as is. In theory this case can never happenm but just incase do nothing more.
    1330                                     else if(order == 0) {
    1331                                           found = true;
    1332                                     }
    1333                                     // The sibling is 'less than' or before the current value, keep looking.
    1334                                     else {
    1335                                           index++;
    1336                                     }
    1337                                 }
    1338                                 // If we haven't done so yet, insert the current node. This will coincidently remove from original parent.
    1339                                 if(!found) {
    1340                                     Node parent_node = subject_node.getElement();
    1341                                     Node child_node = current_value_node.getElement();
    1342                                     parent_node.appendChild(child_node);
    1343                                 }
    1344                                 // Inform the tree model what two nodes structures have changed (origin and destination).
    1345                                 subject_node.unmap();
    1346                                 old_subject_node.unmap();
    1347                                 model.nodeStructureChanged(old_subject_node);
    1348                                 model.nodeStructureChanged(subject_node);
    1349                           }
    1350                           // And if a data change was made tell the tree its data model is ka-bluey.
    1351                           else {
    1352                                 model.nodeChanged(current_value_node);
    1353                           }
    1354                      }
    1355                      model = null;
    1356                      // Hide dialog
    1357                      hide();
    1358                 }
    1359                 else if(source == cancel_button) {
    1360                      // Hide dialog
    1361                      hide();
    1362                 }
    1363                 else {
    1364                      // Reset dialog
    1365                      // current_value_node
    1366                      GValueModel model = Gatherer.c_man.msm.getValueTree(current_element);
    1367                      subject_tree.setModel(model);
    1368                      // Task specific
    1369                      if(source == add_value) {
    1370                           add_type = true;
    1371                           if(current_value_node != null) {
    1372                                 subject_node = current_value_node;
    1373                           }
    1374                           else {
    1375                                 subject_node = (GValueNode) model.getRoot();
    1376                           }
    1377                           value.setText("");
    1378                           alias.setText("");
    1379                           setTitle(get("AddValue"));
    1380                      }
    1381                      else {
    1382                           add_type = false;
    1383                           if(current_value_node != null) {
    1384                                 subject_node = (GValueNode) current_value_node.getParent();
    1385                           }
    1386                           else {
    1387                                 subject_node = (GValueNode) model.getRoot();
    1388                           }
    1389                           value.setText(current_value_node.toString());
    1390                           alias.setText(current_value_node.getAlias());
    1391                           setTitle(get("EditValue"));
    1392                      }
    1393                      model = null;
    1394                      if(subject_node != null) {
    1395                           TreePath path = new TreePath(subject_node.getPath());
    1396                           subject_tree.scrollPathToVisible(path);
    1397                           subject_tree.setSelectionPath(path);
    1398                           path = null;
    1399                      }
    1400                      // Display
    1401                      show();
    1402                 }
    1403           }
    1404 
    1405           public void dispose() {
    1406                 alias = null;
    1407                 cancel_button = null;
    1408                 ok_button = null;
    1409                 subject_node = null;
    1410                 subject_tree = null;
    1411                 value = null;
    1412           }
    1413 
    1414           public void valueChanged(TreeSelectionEvent event) {
    1415                 if(subject_tree.getSelectionCount() > 0 && !ignore) {
    1416                      ignore = true;
    1417                      TreePath selected_path = subject_tree.getSelectionPath();
    1418                      GValueNode requested_node = (GValueNode) selected_path.getLastPathComponent();
    1419                      // Ensure the requested node is not a descendant of the current_value_node
    1420                      if(current_value_node != null) {
    1421                           if(!add_type && current_value_node.isNodeDescendant(requested_node)) {
    1422                                 TreePath path = new TreePath(subject_node.getPath());
    1423                                 subject_tree.scrollPathToVisible(path);
    1424                                 subject_tree.setSelectionPath(path);
    1425                           }
    1426                           else {
    1427                                 subject_node = requested_node;
    1428                           }
    1429                      }
    1430                      selected_path = null;
    1431                      ignore = false;
    1432                 }
    1433           }
    1434     }
     1269        inner_pane.setLayout(new GridLayout(2,1));
     1270        inner_pane.add(subject_tree_pane);
     1271        inner_pane.add(value_pane);
     1272
     1273        alias_pane.setBorder(BorderFactory.createEmptyBorder(0,5,5,5));
     1274        alias_pane.setLayout(new BorderLayout());
     1275        alias_pane.add(alias_label, BorderLayout.WEST);
     1276        alias_pane.add(alias, BorderLayout.CENTER);
     1277
     1278        center_pane.setLayout(new BorderLayout());
     1279        center_pane.add(inner_pane, BorderLayout.CENTER);
     1280        center_pane.add(alias_pane, BorderLayout.SOUTH);
     1281
     1282        button_pane.setBorder(BorderFactory.createEmptyBorder(0,5,5,5));
     1283        button_pane.setLayout(new GridLayout(1,2,5,5));
     1284        button_pane.add(ok_button);
     1285        button_pane.add(cancel_button);
     1286
     1287        content_pane.setLayout(new BorderLayout());
     1288        content_pane.add(center_pane, BorderLayout.CENTER);
     1289        content_pane.add(button_pane, BorderLayout.SOUTH);
     1290        setLocation((Gatherer.config.screen_size.width - ADD_OR_EDIT_VALUE_SIZE.width) / 2, (Gatherer.config.screen_size.height - ADD_OR_EDIT_VALUE_SIZE.height) / 2);
     1291    }
     1292    /** Any implementation of ActionListener must include this method so that we can be informed when an action as occured on our registered component, allowing us to add a new metadata value to the assigned values tree.
     1293     * @param event An <strong>ActionEvent</strong> containing information about the event.
     1294     */
     1295    public void actionPerformed(ActionEvent event) {
     1296        Object source = event.getSource();
     1297        if(source == ok_button) {
     1298        // Now we action as necessary
     1299        GValueModel model = Gatherer.c_man.msm.getValueTree(current_element);
     1300        if(add_type) {
     1301            // Add this value to the tree.
     1302            GValueNode parent = null;
     1303            model.addValue(value.getText(), subject_node, alias.getText());
     1304            parent = null;
     1305        }
     1306        else {
     1307            // Rewrite this value in the DOM model. Note that this will automatically rewrite all assignments as they are live references.
     1308            current_value_node.setValue(value.getText());
     1309            current_value_node.setAlias(alias.getText());
     1310            // Now insert the node into the currently selected subject, but only if the parent has changed.
     1311            if(subject_node != current_value_node.getParent()) {
     1312            GValueNode old_subject_node = (GValueNode) current_value_node.getParent();
     1313            // Find the new values position in subject_nodes children.
     1314            GValueNode sibling = null;
     1315            int index = 0;
     1316            boolean found = false;
     1317            while(index < subject_node.getChildCount() && !found) {
     1318                sibling = (GValueNode) subject_node.getChildAt(index);
     1319                int order = current_value_node.toString().compareToIgnoreCase(sibling.toString());
     1320                // If the sibling is 'greater than' or comes after current value then insert.
     1321                if(order < 0) {
     1322                // Insert. This will coincidently remove from original parent.
     1323                Node parent_node = subject_node.getElement();
     1324                Node child_node = current_value_node.getElement();
     1325                Node sibling_node = sibling.getElement();
     1326                parent_node.insertBefore(child_node, sibling_node);
     1327                found = true;
     1328                }
     1329                // The value already exists exactly as is. In theory this case can never happenm but just incase do nothing more.
     1330                else if(order == 0) {
     1331                found = true;
     1332                }
     1333                // The sibling is 'less than' or before the current value, keep looking.
     1334                else {
     1335                index++;
     1336                }
     1337            }
     1338            // If we haven't done so yet, insert the current node. This will coincidently remove from original parent.
     1339            if(!found) {
     1340                Node parent_node = subject_node.getElement();
     1341                Node child_node = current_value_node.getElement();
     1342                parent_node.appendChild(child_node);
     1343            }
     1344            // Inform the tree model what two nodes structures have changed (origin and destination).
     1345            subject_node.unmap();
     1346            old_subject_node.unmap();
     1347            model.nodeStructureChanged(old_subject_node);
     1348            model.nodeStructureChanged(subject_node);
     1349            }
     1350            // And if a data change was made tell the tree its data model is ka-bluey.
     1351            else {
     1352            model.nodeChanged(current_value_node);
     1353            }
     1354        }
     1355        model = null;
     1356        // Hide dialog
     1357        hide();
     1358        }
     1359        else if(source == cancel_button) {
     1360        // Hide dialog
     1361        hide();
     1362        }
     1363        else {
     1364        // Reset dialog
     1365        // current_value_node
     1366        GValueModel model = Gatherer.c_man.msm.getValueTree(current_element);
     1367        subject_tree.setModel(model);
     1368        // Task specific
     1369        if(source == add_value) {
     1370            add_type = true;
     1371            if(current_value_node != null) {
     1372            subject_node = current_value_node;
     1373            }
     1374            else {
     1375            subject_node = (GValueNode) model.getRoot();
     1376            }
     1377            value.setText("");
     1378            alias.setText("");
     1379            setTitle(get("AddValue"));
     1380        }
     1381        else {
     1382            add_type = false;
     1383            if(current_value_node != null) {
     1384            subject_node = (GValueNode) current_value_node.getParent();
     1385            }
     1386            else {
     1387            subject_node = (GValueNode) model.getRoot();
     1388            }
     1389            value.setText(current_value_node.toString());
     1390            alias.setText(current_value_node.getAlias());
     1391            setTitle(get("EditValue"));
     1392        }
     1393        model = null;
     1394        if(subject_node != null) {
     1395            TreePath path = new TreePath(subject_node.getPath());
     1396            subject_tree.scrollPathToVisible(path);
     1397            subject_tree.setSelectionPath(path);
     1398            path = null;
     1399        }
     1400        // Display
     1401        show();
     1402        }
     1403    }
     1404
     1405    public void dispose() {
     1406        alias = null;
     1407        cancel_button = null;
     1408        ok_button = null;
     1409        subject_node = null;
     1410        subject_tree = null;
     1411        value = null;
     1412    }
     1413
     1414    public void valueChanged(TreeSelectionEvent event) {
     1415        if(subject_tree.getSelectionCount() > 0 && !ignore) {
     1416        ignore = true;
     1417        TreePath selected_path = subject_tree.getSelectionPath();
     1418        GValueNode requested_node = (GValueNode) selected_path.getLastPathComponent();
     1419        // Ensure the requested node is not a descendant of the current_value_node
     1420        if(current_value_node != null) {
     1421            if(!add_type && current_value_node.isNodeDescendant(requested_node)) {
     1422            TreePath path = new TreePath(subject_node.getPath());
     1423            subject_tree.scrollPathToVisible(path);
     1424            subject_tree.setSelectionPath(path);
     1425            }
     1426            else {
     1427            subject_node = requested_node;
     1428            }
     1429        }
     1430        selected_path = null;
     1431        ignore = false;
     1432        }
     1433    }
     1434    }
    14351435     
    1436     private class CloseActionListener
    1437         extends JDialog
    1438         implements ActionListener {
    1439         /** Any implementation of ActionListener must include this method so that we can be informed when an action as occured on our registered component, allowing us to close the editor dialog.
    1440         * @param event An <strong>ActionEvent</strong> containing information about the event.
    1441         */
    1442         public void actionPerformed(ActionEvent event) {
    1443             self.dispose();
    1444         }
    1445     }
    1446 
    1447     private class RemoveAttributeActionListener
    1448           implements ActionListener {
    1449           /** Any implementation of ActionListener must include this method so that we can be informed when an action as occured on our registered component, allowing us to
    1450             * @param event An <strong>ActionEvent</strong> containing information about the event.
    1451             */
    1452           public void actionPerformed(ActionEvent event) {
    1453                 if(current_attribute != -1) {
    1454                      int result = JOptionPane.showOptionDialog(self, get("MEM.Confirm_Removal", get("Attribute")), get("Confirm_Removal_Title"), JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, dialog_options, dialog_options[0]);
    1455                      // Remove this attribute
    1456                      if(result == 0) {
    1457                           ignore = true;
    1458                           // Attributes are tricky little beasties, as they can come from several different places and depend upon what other little beasties have been selected
    1459                           // Has a collection file been selected...
    1460                           if(current_collection_file != null) {
    1461                                 // Remove a profile
    1462                                 String source = (String) profile_attributes.getValueAt(current_attribute, 0);
    1463                                 Gatherer.c_man.msm.profiler.removeAction(current_collection_file, source);
    1464                                 source = null;
    1465                                 // Refresh table
    1466                                 ((AttributeTableModel)profile_attributes.getModel()).removeRow(current_attribute);
    1467                           }
    1468                           // or has an element been selected
    1469                           else if(current_element != null) {
    1470                                 // Remove element attribute
    1471                                 String name = (String) element_attributes.getValueAt(current_attribute, 0);
    1472                                 String value = (String) element_attributes.getValueAt(current_attribute, 1);
    1473                                 current_element.removeAttribute(name, value); // Can be multiple authors for instance
    1474                                 // Refresh table
    1475                                 ((AttributeTableModel)element_attributes.getModel()).removeRow(current_attribute);
    1476                           }
    1477                           else if(current_set != null) {
    1478                                 String name = (String) set_attributes.getValueAt(current_attribute, 0);
    1479                                 // Remove set attribute
    1480                                 current_set.removeAttribute(name);
    1481                                 // Refresh table
    1482                                 ((AttributeTableModel)set_attributes.getModel()).removeRow(current_attribute);
    1483                           }
    1484                           // Disable buttons
    1485                           edit_attribute.setEnabled(false);
    1486                           remove_attribute.setEnabled(false);
    1487                           ignore = false;
    1488                      }
    1489                 }
    1490           }
    1491     }
    1492 
    1493     private class RemoveElementActionListener
    1494           implements ActionListener {
    1495           /** Any implementation of ActionListener must include this method so that we can be informed when an action as occured on our registered component, allowing us to provide an editing prompt.
    1496             * @param event An <strong>ActionEvent</strong> containing information about the event.
    1497             */
    1498           public void actionPerformed(ActionEvent event) {
    1499                 if(current_element != null) {
    1500                      int result = JOptionPane.showOptionDialog(self, get("MEM.Confirm_Removal", get("Element")), get("Confirm_Removal_Title"), JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, dialog_options, dialog_options[0]);
    1501                      // Remove this attribute
    1502                      if(result == 0) {
    1503                           ignore = true;
    1504                           Gatherer.c_man.msm.removeElement(current_element);
    1505                           // Clear selection
    1506                           mds_tree.clearSelection();
    1507                           model.remove(current_element.toString(), MEMNode.ELEMENT);
    1508                           // Meanwhile disable/enable controls given we had an element selected, but no longer do.
    1509                           remove_element.setEnabled(false);
    1510                           // Show a blank panel.
    1511                           card_layout.show(details_pane, BLANK);
    1512                           ignore = false;
    1513                      }
    1514                 }
    1515                 else {
    1516                      ///ystem.err.println("No current element selected.");
    1517                 }
    1518           }
    1519     }
    1520 
    1521     private class RemoveFileActionListener
    1522           implements ActionListener {
    1523           /** Any implementation of ActionListener must include this method so that we can be informed when an action as occured on our registered component, allowing us to provide an editing prompt.
    1524             * @param event An <strong>ActionEvent</strong> containing information about the event.
    1525             */
    1526           public void actionPerformed(ActionEvent event) {
    1527                 if(current_collection_file != null) {
    1528                      int result = JOptionPane.showOptionDialog(self, get("MEM.Confirm_Removal", get("File")), get("Confirm_Removal_Title"), JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, dialog_options, dialog_options[0]);
    1529                      // Remove the current collection file profile from the profiler.
    1530                      if(result == 0) {
    1531                           ignore = true;
    1532                           Gatherer.c_man.msm.profiler.removeProfile(current_collection_file);
    1533 // Clear selection
    1534                           mds_tree.clearSelection();
    1535                           model.remove(current_collection_file, MEMNode.COLLECTION);
    1536                           // Meanwhile disable/enable controls given we had a set selected, but no longer do.
    1537                           remove_file.setEnabled(false);
    1538                           // Show a blank panel.
    1539                           card_layout.show(details_pane, BLANK);
    1540                           ignore = false;
    1541                      }
    1542                 }
    1543           }
    1544     }
    1545 
    1546     private class RemoveSetActionListener
    1547           implements ActionListener {
    1548           /** Any implementation of ActionListener must include this method so that we can be informed when an action as occured on our registered component, allowing us to
    1549             * @param event An <strong>ActionEvent</strong> containing information about the event.
    1550             */
    1551           public void actionPerformed(ActionEvent event) {
    1552                 if(current_set != null) {
    1553                      int result = JOptionPane.showOptionDialog(self, get("MEM.Confirm_Removal", get("Set")), get("Confirm_Removal_Title"), JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, dialog_options, dialog_options[0]);
    1554                      // Remove the currently selected set
    1555                      if(result == 0) {
    1556                           ignore = true;
    1557                           Gatherer.c_man.msm.removeSet(current_set);
    1558                           // Clear selection
    1559                           mds_tree.clearSelection();
    1560                           model.remove(current_set.toString(), MEMNode.SET);
    1561                           // Meanwhile disable/enable controls given we had a set selected, but no longer do.
    1562                           remove_set.setEnabled(false);
    1563                           // Show a blank panel.
    1564                           card_layout.show(details_pane, BLANK);
    1565                           ignore = false;
    1566                      }
    1567                 }
    1568           }
    1569     }
    1570     /** This class will remove the currently selected metadata or profile value when any registered control is actioned. Note that removing a value acts differently from the other removes in that if you remove a value which is still assigned somewhere the values are restored next time said assignment is viewed. This turned out far easier and reasonable to code than attempting to remove all remaining values when you delete its reference in the GValueModel. */
    1571     private class RemoveValueActionListener
    1572           implements ActionListener {
    1573           /** Any implementation of ActionListener must include this method so that we can be informed when an action as occured on our registered component, allowing us to
    1574             * @param event An <strong>ActionEvent</strong> containing information about the event.
    1575             */
    1576           public void actionPerformed(ActionEvent event) {
    1577                 if(current_value_node != null) {                 
    1578                      int result = JOptionPane.showOptionDialog(self, get("MEM.Confirm_Removal", get("Value")), get("Confirm_Removal_Title"), JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, dialog_options, dialog_options[0]);
    1579                      // Remove the current selected value
    1580                      if(result == 0) {
    1581                           ignore = true;
    1582                           GValueModel model = (GValueModel) element_values.getModel();
    1583                           model.removeValue(current_value_node);
    1584                           // Meanwhile disable/enable controls given we had a value selected, but no longer do.
    1585                           edit_value.setEnabled(false);
    1586                           remove_value.setEnabled(false);
    1587                           ignore = false;
    1588                      }
    1589                 }
    1590           }
    1591     }
     1436    private class CloseActionListener
     1437    extends JDialog
     1438    implements ActionListener {
     1439    /** Any implementation of ActionListener must include this method so that we can be informed when an action as occured on our registered component, allowing us to close the editor dialog.
     1440    * @param event An <strong>ActionEvent</strong> containing information about the event.
     1441    */
     1442    public void actionPerformed(ActionEvent event) {
     1443        self.dispose();
     1444    }
     1445    }
     1446
     1447    private class RemoveAttributeActionListener
     1448    implements ActionListener {
     1449    /** Any implementation of ActionListener must include this method so that we can be informed when an action as occured on our registered component, allowing us to
     1450     * @param event An <strong>ActionEvent</strong> containing information about the event.
     1451     */
     1452    public void actionPerformed(ActionEvent event) {
     1453        if(current_attribute != -1) {
     1454        int result = JOptionPane.showOptionDialog(self, get("MEM.Confirm_Removal", get("Attribute")), get("Confirm_Removal_Title"), JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, dialog_options, dialog_options[0]);
     1455        // Remove this attribute
     1456        if(result == 0) {
     1457            ignore = true;
     1458            // Attributes are tricky little beasties, as they can come from several different places and depend upon what other little beasties have been selected
     1459            // Has a collection file been selected...
     1460            if(current_collection_file != null) {
     1461            // Remove a profile
     1462            String source = (String) profile_attributes.getValueAt(current_attribute, 0);
     1463            Gatherer.c_man.msm.profiler.removeAction(current_collection_file, source);
     1464            source = null;
     1465            // Refresh table
     1466            ((AttributeTableModel)profile_attributes.getModel()).removeRow(current_attribute);
     1467            }
     1468            // or has an element been selected
     1469            else if(current_element != null) {
     1470            // Remove element attribute
     1471            String name = (String) element_attributes.getValueAt(current_attribute, 0);
     1472            String value = (String) element_attributes.getValueAt(current_attribute, 1);
     1473            current_element.removeAttribute(name, value); // Can be multiple authors for instance
     1474            // Refresh table
     1475            ((AttributeTableModel)element_attributes.getModel()).removeRow(current_attribute);
     1476            }
     1477            else if(current_set != null) {
     1478            String name = (String) set_attributes.getValueAt(current_attribute, 0);
     1479            // Remove set attribute
     1480            current_set.removeAttribute(name);
     1481            // Refresh table
     1482            ((AttributeTableModel)set_attributes.getModel()).removeRow(current_attribute);
     1483            }
     1484            // Disable buttons
     1485            edit_attribute.setEnabled(false);
     1486            remove_attribute.setEnabled(false);
     1487            ignore = false;
     1488        }
     1489        }
     1490    }
     1491    }
     1492
     1493    private class RemoveElementActionListener
     1494    implements ActionListener {
     1495    /** Any implementation of ActionListener must include this method so that we can be informed when an action as occured on our registered component, allowing us to provide an editing prompt.
     1496     * @param event An <strong>ActionEvent</strong> containing information about the event.
     1497     */
     1498    public void actionPerformed(ActionEvent event) {
     1499        if(current_element != null) {
     1500        int result = JOptionPane.showOptionDialog(self, get("MEM.Confirm_Removal", get("Element")), get("Confirm_Removal_Title"), JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, dialog_options, dialog_options[0]);
     1501        // Remove this attribute
     1502        if(result == 0) {
     1503            ignore = true;
     1504            Gatherer.c_man.msm.removeElement(current_element);
     1505            // Clear selection
     1506            mds_tree.clearSelection();
     1507            model.remove(current_element.toString(), MEMNode.ELEMENT);
     1508            // Meanwhile disable/enable controls given we had an element selected, but no longer do.
     1509            remove_element.setEnabled(false);
     1510            // Show a blank panel.
     1511            card_layout.show(details_pane, BLANK);
     1512            ignore = false;
     1513        }
     1514        }
     1515        else {
     1516        ///ystem.err.println("No current element selected.");
     1517        }
     1518    }
     1519    }
     1520
     1521    private class RemoveFileActionListener
     1522    implements ActionListener {
     1523    /** Any implementation of ActionListener must include this method so that we can be informed when an action as occured on our registered component, allowing us to provide an editing prompt.
     1524     * @param event An <strong>ActionEvent</strong> containing information about the event.
     1525     */
     1526    public void actionPerformed(ActionEvent event) {
     1527        if(current_collection_file != null) {
     1528        int result = JOptionPane.showOptionDialog(self, get("MEM.Confirm_Removal", get("File")), get("Confirm_Removal_Title"), JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, dialog_options, dialog_options[0]);
     1529        // Remove the current collection file profile from the profiler.
     1530        if(result == 0) {
     1531            ignore = true;
     1532            Gatherer.c_man.msm.profiler.removeProfile(current_collection_file);
     1533            // Clear selection
     1534            mds_tree.clearSelection();
     1535            model.remove(current_collection_file, MEMNode.COLLECTION);
     1536            // Meanwhile disable/enable controls given we had a set selected, but no longer do.
     1537            remove_file.setEnabled(false);
     1538            // Show a blank panel.
     1539            card_layout.show(details_pane, BLANK);
     1540            ignore = false;
     1541        }
     1542        }
     1543    }
     1544    }
     1545
     1546    private class RemoveSetActionListener
     1547    implements ActionListener {
     1548    /** Any implementation of ActionListener must include this method so that we can be informed when an action as occured on our registered component, allowing us to
     1549     * @param event An <strong>ActionEvent</strong> containing information about the event.
     1550     */
     1551    public void actionPerformed(ActionEvent event) {
     1552        if(current_set != null) {
     1553        int result = JOptionPane.showOptionDialog(self, get("MEM.Confirm_Removal", get("Set")), get("Confirm_Removal_Title"), JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, dialog_options, dialog_options[0]);
     1554        // Remove the currently selected set
     1555        if(result == 0) {
     1556            ignore = true;
     1557            Gatherer.c_man.msm.removeSet(current_set);
     1558            // Clear selection
     1559            mds_tree.clearSelection();
     1560            model.remove(current_set.toString(), MEMNode.SET);
     1561            // Meanwhile disable/enable controls given we had a set selected, but no longer do.
     1562            remove_set.setEnabled(false);
     1563            // Show a blank panel.
     1564            card_layout.show(details_pane, BLANK);
     1565            ignore = false;
     1566        }
     1567        }
     1568    }
     1569    }
     1570    /** This class will remove the currently selected metadata or profile value when any registered control is actioned. Note that removing a value acts differently from the other removes in that if you remove a value which is still assigned somewhere the values are restored next time said assignment is viewed. This turned out far easier and reasonable to code than attempting to remove all remaining values when you delete its reference in the GValueModel. */
     1571    private class RemoveValueActionListener
     1572    implements ActionListener {
     1573    /** Any implementation of ActionListener must include this method so that we can be informed when an action as occured on our registered component, allowing us to
     1574     * @param event An <strong>ActionEvent</strong> containing information about the event.
     1575     */
     1576    public void actionPerformed(ActionEvent event) {
     1577        if(current_value_node != null) {                 
     1578        int result = JOptionPane.showOptionDialog(self, get("MEM.Confirm_Removal", get("Value")), get("Confirm_Removal_Title"), JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, dialog_options, dialog_options[0]);
     1579        // Remove the current selected value
     1580        if(result == 0) {
     1581            ignore = true;
     1582            GValueModel model = (GValueModel) element_values.getModel();
     1583            model.removeValue(current_value_node);
     1584            // Meanwhile disable/enable controls given we had a value selected, but no longer do.
     1585            edit_value.setEnabled(false);
     1586            remove_value.setEnabled(false);
     1587            ignore = false;
     1588        }
     1589        }
     1590    }
     1591    }
    15921592     
    1593     /** Used to enable a certain target component if and only if all the registered text fields contain non-zero length strings. */
    1594     private class TextFieldEnabler
    1595         extends KeyAdapter {
    1596         private Component target = null;
    1597         private JTextComponent[] fields = null;
    1598         public TextFieldEnabler(Component target) {
    1599             super();
    1600             this.target = target;
    1601         }
    1602         public void add(JTextComponent field) {
    1603             field.addKeyListener(this);
    1604             if(fields == null) {
    1605                 fields = new JTextComponent[1];
    1606                 fields[0] = field;
     1593    /** Used to enable a certain target component if and only if all the registered text fields contain non-zero length strings. */
     1594    private class TextFieldEnabler
     1595    extends KeyAdapter {
     1596    private Component target = null;
     1597    private JTextComponent[] fields = null;
     1598    public TextFieldEnabler(Component target) {
     1599        super();
     1600        this.target = target;
     1601    }
     1602    public void add(JTextComponent field) {
     1603        field.addKeyListener(this);
     1604        if(fields == null) {
     1605        fields = new JTextComponent[1];
     1606        fields[0] = field;
     1607        }
     1608        else {
     1609        JTextComponent[] temp = new JTextComponent[fields.length + 1];
     1610        System.arraycopy(fields, 0, temp, 0, fields.length);
     1611        temp[fields.length] = field;
     1612        fields = temp;
     1613        }
     1614    }
     1615    public void keyReleased(KeyEvent event) {
     1616        boolean enable = true;
     1617        for(int i = 0; i < fields.length; i++) {
     1618        enable = enable && fields[i].getText().length() > 0;
     1619        }
     1620        target.setEnabled(enable);
     1621    }
     1622    }
     1623
     1624    private class AttributesListSelectionListener
     1625    implements ListSelectionListener {
     1626    private JTable table = null;
     1627    public AttributesListSelectionListener(JTable table) {
     1628        this.table = table;
     1629    }
     1630    public void valueChanged(ListSelectionEvent event) {
     1631        if((current_attribute = table.getSelectedRow()) != -1) {
     1632        edit_attribute.setEnabled(true);
     1633        remove_attribute.setEnabled(true);
     1634        }
     1635        else {
     1636        current_attribute = -1;
     1637        edit_attribute.setEnabled(false);
     1638        remove_attribute.setEnabled(false);
     1639        }
     1640    }
     1641    }
     1642
     1643    private class ElementValuesTreeSelectionListener
     1644    implements TreeSelectionListener {
     1645    public void valueChanged(TreeSelectionEvent event) {
     1646        if(element_values.getSelectionCount() > 0) {
     1647        // Retrieve the selected value node.
     1648        TreePath selected_path = element_values.getSelectionPath();
     1649        current_value_node = (GValueNode) selected_path.getLastPathComponent();
     1650        edit_value.setEnabled(true);
     1651        remove_value.setEnabled(true);
     1652        }
     1653        else {
     1654        current_value_node = null;
     1655        edit_value.setEnabled(false);
     1656        remove_value.setEnabled(false);
     1657        }
     1658    }
     1659    }
     1660
     1661    private class MDSTreeSelectionListener
     1662    implements TreeSelectionListener {
     1663    public void valueChanged(TreeSelectionEvent event) {
     1664        if(!ignore) {
     1665        // Clear all variables based on previous tree selection
     1666        current_collection_file = null;
     1667        current_element = null;
     1668        current_set = null;
     1669        // Now process the node selected
     1670        TreePath path = event.getPath();
     1671        current_node = (MEMNode)path.getLastPathComponent();
     1672        // What we show depends on the node type...
     1673        AttributeTableModel atm = null;
     1674        TreeSet attributes = null;
     1675        switch(current_node.getType()) {
     1676        case MEMNode.COLLECTION:
     1677            current_collection_file = current_node.toString();
     1678            atm = current_node.getModel();
     1679            if(atm == null) {
     1680            ArrayList sources = Gatherer.c_man.msm.profiler.getSources(current_collection_file);
     1681            attributes = new TreeSet();
     1682            for(int i = 0; i < sources.size(); i++) {
     1683                String source = (String) sources.get(i);
     1684                String action = Gatherer.c_man.msm.profiler.getAction(current_collection_file, source);
     1685                if(action == null) {
     1686                action = get("Ignore");
     1687                }
     1688                attributes.add(new Attribute(source, action));
    16071689            }
    1608             else {
    1609                 JTextComponent[] temp = new JTextComponent[fields.length + 1];
    1610                 System.arraycopy(fields, 0, temp, 0, fields.length);
    1611                 temp[fields.length] = field;
    1612                 fields = temp;
     1690            atm = new AttributeTableModel(attributes, get("Source"), get("Target"), get("Ignore"));
     1691            //current_node.setModel(atm);
     1692            }
     1693            profile_attributes.setModel(atm);
     1694            atm.setScrollPane(profile_attributes_scroll);
     1695            atm.setTable(profile_attributes);
     1696
     1697            card_layout.show(details_pane, PROFILE);
     1698            setControls(true, false, false, true, false, false, true, false, false, false, false, false);
     1699            break;
     1700        case MEMNode.ELEMENT:
     1701            current_element = current_node.getElement();
     1702            atm = current_node.getModel();
     1703            if(atm == null) {
     1704            atm = new AttributeTableModel(current_element.getAttributes(), get("Name"), get("Language_Code"), get("Value"), "");
     1705            //current_node.setModel(atm);
     1706            }
     1707            element_attributes.setModel(atm);
     1708            atm.setScrollPane(element_attributes_scroll);
     1709            atm.setTable(element_attributes);
     1710
     1711            element_values.setModel(Gatherer.c_man.msm.getValueTree(current_element));
     1712            card_layout.show(details_pane, ELEMENT);
     1713            // Meanwhile disable/enable controls depending on this Element selection.
     1714            setControls(true, false, false, false, false, true, true, false, false, true, false, false);
     1715            break;
     1716        case MEMNode.SET:
     1717            current_set = current_node.getSet();
     1718            atm = current_node.getModel();
     1719            if(atm == null) {
     1720            NamedNodeMap temp = current_set.getAttributes();
     1721            attributes = new TreeSet();
     1722            for(int i = 0; i < temp.getLength(); i++) {
     1723                Attr attribute = (Attr) temp.item(i);
     1724                // We don't show the namespace attribute, as it is used as a unique primary key and should never be changed or removed in itself.
     1725                if(!attribute.getName().equals("namespace")) {
     1726                attributes.add(new Attribute(attribute.getName(), attribute.getValue()));
     1727                }
     1728                attribute = null;
    16131729            }
    1614         }
    1615         public void keyReleased(KeyEvent event) {
    1616             boolean enable = true;
    1617             for(int i = 0; i < fields.length; i++) {
    1618                 enable = enable && fields[i].getText().length() > 0;
    1619             }
    1620             target.setEnabled(enable);
    1621         }
    1622     }
    1623 
    1624     private class AttributesListSelectionListener
    1625         implements ListSelectionListener {
    1626          private JTable table = null;
    1627          public AttributesListSelectionListener(JTable table) {
    1628               this.table = table;
    1629          }
    1630          public void valueChanged(ListSelectionEvent event) {
    1631               if((current_attribute = table.getSelectedRow()) != -1) {
    1632                     edit_attribute.setEnabled(true);
    1633                     remove_attribute.setEnabled(true);
    1634               }
    1635               else {
    1636                     current_attribute = -1;
    1637                     edit_attribute.setEnabled(false);
    1638                     remove_attribute.setEnabled(false);
    1639               }
    1640          }
    1641     }
    1642 
    1643     private class ElementValuesTreeSelectionListener
    1644         implements TreeSelectionListener {
    1645          public void valueChanged(TreeSelectionEvent event) {
    1646               if(element_values.getSelectionCount() > 0) {
    1647                     // Retrieve the selected value node.
    1648                     TreePath selected_path = element_values.getSelectionPath();
    1649                     current_value_node = (GValueNode) selected_path.getLastPathComponent();
    1650                     edit_value.setEnabled(true);
    1651                     remove_value.setEnabled(true);
    1652               }
    1653               else {
    1654                     current_value_node = null;
    1655                     edit_value.setEnabled(false);
    1656                     remove_value.setEnabled(false);
    1657               }
    1658          }
    1659     }
    1660 
    1661     private class MDSTreeSelectionListener
    1662         implements TreeSelectionListener {
    1663          public void valueChanged(TreeSelectionEvent event) {
    1664               if(!ignore) {
    1665                     // Clear all variables based on previous tree selection
    1666                     current_collection_file = null;
    1667                     current_element = null;
    1668                     current_set = null;
    1669                     // Now process the node selected
    1670                     TreePath path = event.getPath();
    1671                     current_node = (MEMNode)path.getLastPathComponent();
    1672                     // What we show depends on the node type...
    1673                     AttributeTableModel atm = null;
    1674                     TreeSet attributes = null;
    1675                     switch(current_node.getType()) {
    1676                     case MEMNode.COLLECTION:
    1677                          current_collection_file = current_node.toString();
    1678                          atm = current_node.getModel();
    1679                          if(atm == null) {
    1680                               ArrayList sources = Gatherer.c_man.msm.profiler.getSources(current_collection_file);
    1681                               attributes = new TreeSet();
    1682                               for(int i = 0; i < sources.size(); i++) {
    1683                                     String source = (String) sources.get(i);
    1684                                     String action = Gatherer.c_man.msm.profiler.getAction(current_collection_file, source);
    1685                                     if(action == null) {
    1686                                          action = get("Ignore");
    1687                                     }
    1688                                     attributes.add(new Attribute(source, action));
    1689                               }
    1690                               atm = new AttributeTableModel(attributes, get("Source"), get("Target"), get("Ignore"));
    1691                               //current_node.setModel(atm);
    1692                          }
    1693                          profile_attributes.setModel(atm);
    1694                          atm.setScrollPane(profile_attributes_scroll);
    1695                          atm.setTable(profile_attributes);
    1696 
    1697                          card_layout.show(details_pane, PROFILE);
    1698                          setControls(true, false, false, true, false, false, true, false, false, false, false, false);
    1699                          break;
    1700                     case MEMNode.ELEMENT:
    1701                          current_element = current_node.getElement();
    1702                          atm = current_node.getModel();
    1703                          if(atm == null) {
    1704                               atm = new AttributeTableModel(current_element.getAttributes(), get("Name"), get("Language_Code"), get("Value"), "");
    1705                               //current_node.setModel(atm);
    1706                          }
    1707                          element_attributes.setModel(atm);
    1708                          atm.setScrollPane(element_attributes_scroll);
    1709                          atm.setTable(element_attributes);
    1710 
    1711                          element_values.setModel(Gatherer.c_man.msm.getValueTree(current_element));
    1712                          card_layout.show(details_pane, ELEMENT);
    1713                          // Meanwhile disable/enable controls depending on this Element selection.
    1714                          setControls(true, false, false, false, false, true, true, false, false, true, false, false);
    1715                          break;
    1716                     case MEMNode.SET:
    1717                          current_set = current_node.getSet();
    1718                          atm = current_node.getModel();
    1719                          if(atm == null) {
    1720                               NamedNodeMap temp = current_set.getAttributes();
    1721                               attributes = new TreeSet();
    1722                               for(int i = 0; i < temp.getLength(); i++) {
    1723                                     Attr attribute = (Attr) temp.item(i);
    1724                                     // We don't show the namespace attribute, as it is used as a unique primary key and should never be changed or removed in itself.
    1725                                     if(!attribute.getName().equals("namespace")) {
    1726                                          attributes.add(new Attribute(attribute.getName(), attribute.getValue()));
    1727                                     }
    1728                                     attribute = null;
    1729                               }
    1730                               atm = new AttributeTableModel(attributes, get("Name"), get("Value"), "");
    1731                               //current_node.setModel(atm);
    1732                               temp = null;
    1733                          }
    1734                          set_attributes.setModel(atm);
    1735                          atm.setScrollPane(set_attributes_scroll);
    1736                          atm.setTable(set_attributes);
     1730            atm = new AttributeTableModel(attributes, get("Name"), get("Value"), "");
     1731            //current_node.setModel(atm);
     1732            temp = null;
     1733            }
     1734            set_attributes.setModel(atm);
     1735            atm.setScrollPane(set_attributes_scroll);
     1736            atm.setTable(set_attributes);
    17371737                         
    1738                         card_layout.show(details_pane, SET);
    1739                         attributes = null;
    1740                         // Meanwhile disable/enable controls depending on this Element selection.
    1741                         setControls(true, true, false, false, true, false, true, false, false, false, false, false);
    1742                         break;
    1743                     case MEMNode.PROFILER:
    1744                         // Meanwhile disable/enable controls depending on this Element selection.
    1745                         setControls(true, false, true, false, false, false, false, false, false, false, false, false);
    1746                     default:
    1747                         // Show a blank panel.
    1748                         card_layout.show(details_pane, BLANK);
    1749                     }
    1750                     attributes = null;
    1751                     path = null;
    1752                     atm = null;
    1753               }
    1754          }
    1755     }
    1756 
    1757     private class MEMTreeCellRenderer
    1758           extends DefaultTreeCellRenderer {
    1759           public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
    1760                 super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
    1761                 setToolTipText(value.toString());
    1762                 return this;
    1763           }
    1764     }
    1765 
    1766     /** Wrap a ElementWrapper so we get its name when we ask for toString(), not its identifier. */
    1767     private class NameElementWrapperEntry
    1768           implements Comparable {
    1769           private ElementWrapper element_wrapper = null;
    1770           public NameElementWrapperEntry(Object object) {
    1771                 this.element_wrapper = (ElementWrapper) object;
    1772           }
    1773           public int compareTo(Object object) {
    1774                 return element_wrapper.compareTo(object);
    1775           }
    1776           public boolean equals(Object object) {
    1777                 return element_wrapper.equals(object);
    1778           }
    1779           public String toString() {
    1780                 return element_wrapper.getName();
    1781           }
    1782     }
     1738            card_layout.show(details_pane, SET);
     1739            attributes = null;
     1740            // Meanwhile disable/enable controls depending on this Element selection.
     1741            setControls(true, true, false, false, true, false, true, false, false, false, false, false);
     1742            break;
     1743        case MEMNode.PROFILER:
     1744            // Meanwhile disable/enable controls depending on this Element selection.
     1745            setControls(true, false, true, false, false, false, false, false, false, false, false, false);
     1746        default:
     1747            // Show a blank panel.
     1748            card_layout.show(details_pane, BLANK);
     1749        }
     1750        attributes = null;
     1751        path = null;
     1752        atm = null;
     1753        }
     1754    }
     1755    }
     1756
     1757    private class MEMTreeCellRenderer
     1758    extends DefaultTreeCellRenderer {
     1759    public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
     1760        super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
     1761        setToolTipText(value.toString());
     1762        return this;
     1763    }
     1764    }
     1765
     1766    /** Wrap a ElementWrapper so we get its name when we ask for toString(), not its identifier. */
     1767    private class NameElementWrapperEntry
     1768    implements Comparable {
     1769    private ElementWrapper element_wrapper = null;
     1770    public NameElementWrapperEntry(Object object) {
     1771        this.element_wrapper = (ElementWrapper) object;
     1772    }
     1773    public int compareTo(Object object) {
     1774        return element_wrapper.compareTo(object);
     1775    }
     1776    public boolean equals(Object object) {
     1777        return element_wrapper.equals(object);
     1778    }
     1779    public String toString() {
     1780        return element_wrapper.getName();
     1781    }
     1782    }
    17831783}
    1784 
Note: See TracChangeset for help on using the changeset viewer.