101680 Hide environment variable type column in the custom editor; add validation for built-in editor. issue_101067_change_scope_l10n_list_base
authorjqian@netbeans.org
Wed, 30 May 2007 08:38:16 +0000
changeset 5312f34865319d9
parent 530 029dc276e48e
child 532 7c59fc455038
101680 Hide environment variable type column in the custom editor; add validation for built-in editor.
compapp.manager.jbi/src/org/netbeans/modules/sun/manager/jbi/editors/EnvironmentVariablesCustomEditor.java
compapp.manager.jbi/src/org/netbeans/modules/sun/manager/jbi/editors/EnvironmentVariablesEditor.java
compapp.manager.jbi/src/org/netbeans/modules/sun/manager/jbi/editors/SimpleTabularDataCustomEditor.java
compapp.manager.jbi/src/org/netbeans/modules/sun/manager/jbi/editors/SimpleTabularDataEditor.java
     1.1 --- a/compapp.manager.jbi/src/org/netbeans/modules/sun/manager/jbi/editors/EnvironmentVariablesCustomEditor.java	Wed May 30 01:34:17 2007 +0000
     1.2 +++ b/compapp.manager.jbi/src/org/netbeans/modules/sun/manager/jbi/editors/EnvironmentVariablesCustomEditor.java	Wed May 30 08:38:16 2007 +0000
     1.3 @@ -22,13 +22,9 @@
     1.4  import java.awt.Component;
     1.5  import java.io.Serializable;
     1.6  import java.text.NumberFormat;
     1.7 -import java.util.ArrayList;
     1.8 -import java.util.List;
     1.9 +import java.util.HashMap;
    1.10 +import java.util.Map;
    1.11  import java.util.Vector;
    1.12 -import javax.management.openmbean.CompositeData;
    1.13 -import javax.management.openmbean.CompositeType;
    1.14 -import javax.management.openmbean.OpenType;
    1.15 -import javax.management.openmbean.TabularData;
    1.16  import javax.swing.DefaultCellEditor;
    1.17  import javax.swing.JCheckBox;
    1.18  import javax.swing.JComponent;
    1.19 @@ -43,12 +39,16 @@
    1.20  import javax.swing.table.DefaultTableModel;
    1.21  import javax.swing.table.TableCellEditor;
    1.22  import javax.swing.table.TableCellRenderer;
    1.23 +import javax.swing.table.TableColumn;
    1.24 +import javax.swing.table.TableColumnModel;
    1.25  import org.openide.DialogDescriptor;
    1.26  import org.openide.DialogDisplayer;
    1.27  import org.openide.NotifyDescriptor;
    1.28  
    1.29  /**
    1.30   * A custom editor for editing typed environment variables.
    1.31 + * A typed environment variable is a triplet: [Name, Type, Value].
    1.32 + * Four types are supported: STRING, NUMBER, BOOLEAN and PASSWORD.
    1.33   *
    1.34   * @author jqian
    1.35   */
    1.36 @@ -63,23 +63,37 @@
    1.37      public static final int TYPE_COLUMN = 1;
    1.38      public static final int VALUE_COLUMN = 2;
    1.39      
    1.40 +    private static TableCellRenderer stringRenderer = new StringRenderer();
    1.41 +    private static TableCellRenderer doubleRenderer = new DoubleRenderer();
    1.42      private static TableCellRenderer booleanRenderer = new BooleanRenderer();
    1.43 -    private static TableCellRenderer doubleRenderer = new DoubleRenderer();
    1.44 -    private static TableCellRenderer passwordRenderer = new PasswordRenderer();    
    1.45 -    private static TableCellRenderer stringRenderer = new StringRenderer();
    1.46 +    private static TableCellRenderer passwordRenderer = new PasswordRenderer();
    1.47      
    1.48 +    private static TableCellEditor stringEditor = new StringEditor();
    1.49      private static TableCellEditor booleanEditor = new BooleanEditor();
    1.50      private static TableCellEditor doubleEditor = new NumberEditor();
    1.51      private static TableCellEditor passwordEditor = new PasswordEditor();
    1.52 -    private static TableCellEditor stringEditor = new StringEditor();
    1.53      
    1.54 +    private static Map<String, TableCellRenderer> rendererMap = new HashMap<String, TableCellRenderer>();
    1.55 +    private static Map<String, TableCellEditor> editorMap = new HashMap<String, TableCellEditor>();
    1.56 +    
    1.57 +    static {
    1.58 +        rendererMap.put(STRING_TYPE, stringRenderer);
    1.59 +        rendererMap.put(NUMBER_TYPE, doubleRenderer);
    1.60 +        rendererMap.put(BOOLEAN_TYPE, booleanRenderer);
    1.61 +        rendererMap.put(PASSWORD_TYPE, passwordRenderer);
    1.62 +        
    1.63 +        editorMap.put(STRING_TYPE, stringEditor);
    1.64 +        editorMap.put(NUMBER_TYPE, doubleEditor);
    1.65 +        editorMap.put(BOOLEAN_TYPE, booleanEditor);
    1.66 +        editorMap.put(PASSWORD_TYPE, passwordEditor);
    1.67 +    }
    1.68      
    1.69      public EnvironmentVariablesCustomEditor(SimpleTabularDataEditor editor) {
    1.70          super(editor);
    1.71      }
    1.72      
    1.73      @Override
    1.74 -    protected Vector createNewRow() {
    1.75 +    protected Vector createRow() {
    1.76          NewEnvironmentVariableTypeSelectionPanel typeSelectionPanel =
    1.77                  new NewEnvironmentVariableTypeSelectionPanel();
    1.78          
    1.79 @@ -90,7 +104,7 @@
    1.80          
    1.81          if (dd.getValue() == DialogDescriptor.OK_OPTION) {
    1.82              String type = typeSelectionPanel.getTypeChoice();
    1.83 -            Vector row = super.createNewRow();
    1.84 +            Vector row = super.createRow();
    1.85              row.set(TYPE_COLUMN, type);
    1.86              
    1.87              return row;
    1.88 @@ -105,15 +119,14 @@
    1.89          
    1.90          JTable table = new JTable(tableModel) {
    1.91              public TableCellRenderer getCellRenderer(int row, int column) {
    1.92 -                TableCellRenderer renderer = new DefaultTableCellRenderer() {                  
    1.93 -                    
    1.94 +                TableCellRenderer renderer = new DefaultTableCellRenderer() {
    1.95                      public Component getTableCellRendererComponent(JTable table,
    1.96                              Object value,
    1.97                              boolean isSelected,
    1.98                              boolean hasFocus,
    1.99                              int row, int column) {
   1.100                          
   1.101 -                        if (column != 2) {
   1.102 +                        if (column == NAME_COLUMN) {
   1.103                              // Highlight key columns
   1.104                              if (value != null) {
   1.105                                  value = "<html><body><b>" + value + "</b></body></html>";
   1.106 @@ -123,31 +136,18 @@
   1.107                              ((JComponent)component).setBorder(myBorder);
   1.108                              return component;
   1.109                          } else {
   1.110 -                            String type = null;
   1.111 -                            
   1.112 -                            try {
   1.113 -                                DefaultTableModel tableModel = (DefaultTableModel) table.getModel();
   1.114 -                                Vector rowData = (Vector) tableModel.getDataVector().get(row);
   1.115 -                                type = (String) rowData.get(column - 1);
   1.116 -                            } catch (Exception e) {
   1.117 -                            }
   1.118 -                            
   1.119 -                            TableCellRenderer renderer = null;
   1.120 -                            if (type.equals(BOOLEAN_TYPE)) {
   1.121 -                                renderer = booleanRenderer;
   1.122 -                            } else if (type.equals(PASSWORD_TYPE)) {
   1.123 -                                renderer = passwordRenderer;
   1.124 -                            } else if (type.equals(NUMBER_TYPE)) {
   1.125 -                                renderer = doubleRenderer;
   1.126 -                            } else if (type.equals(STRING_TYPE)) {
   1.127 -                                renderer = stringRenderer;
   1.128 -                            } 
   1.129 +                            DefaultTableModel tableModel = (DefaultTableModel) table.getModel();
   1.130 +                            Vector rowData = (Vector) tableModel.getDataVector().get(row);
   1.131 +                            String type = (String) rowData.get(TYPE_COLUMN);
   1.132 +                            TableCellRenderer renderer = rendererMap.get(type);
   1.133                              
   1.134                              if (renderer != null) {
   1.135                                  return renderer.getTableCellRendererComponent(
   1.136                                          table, value, isSelected, hasFocus, row, column);
   1.137                              } else {
   1.138 -                                throw new RuntimeException("Unknown type: " + type);
   1.139 +                                System.err.println("WARNING: Unknown TableCellRenderer for type of \"" + type + "\"");
   1.140 +                                return super.getTableCellRendererComponent(
   1.141 +                                        table, value, isSelected, hasFocus, row, column);
   1.142                              }
   1.143                          }
   1.144                      }
   1.145 @@ -156,27 +156,18 @@
   1.146              }
   1.147              
   1.148              public TableCellEditor getCellEditor(int row, int column) {
   1.149 -                if (column != 2) {
   1.150 +                if (column == NAME_COLUMN) {
   1.151                      return stringEditor;
   1.152                  } else {
   1.153 -                    String type = null;
   1.154 -                    try {
   1.155 -                        DefaultTableModel tableModel = (DefaultTableModel) getModel();
   1.156 -                        Vector rowData = (Vector) tableModel.getDataVector().get(row);
   1.157 -                        type = (String) rowData.get(column - 1);
   1.158 -                    } catch (Exception e) {
   1.159 -                    }
   1.160 -                    
   1.161 -                    if (type.equals(BOOLEAN_TYPE)) {
   1.162 -                        return booleanEditor;
   1.163 -                    } else if (type.equals(PASSWORD_TYPE)) {
   1.164 -                        return passwordEditor;
   1.165 -                    } else if (type.equals(NUMBER_TYPE)) {
   1.166 -                        return doubleEditor;
   1.167 -                    } else if (type.equals(STRING_TYPE)) {
   1.168 +                    DefaultTableModel tableModel = (DefaultTableModel) getModel();
   1.169 +                    Vector rowData = (Vector) tableModel.getDataVector().get(row);
   1.170 +                    String type = (String) rowData.get(TYPE_COLUMN);
   1.171 +                    TableCellEditor editor = editorMap.get(type);
   1.172 +                    if (type != null) {
   1.173 +                        return editor;
   1.174 +                    } else {
   1.175 +                        System.err.println("WARNING: Unknown TableCellEditor for type of \"" + type + "\"");
   1.176                          return stringEditor;
   1.177 -                    } else {
   1.178 -                        throw new RuntimeException("Unknown type: " + type);
   1.179                      }
   1.180                  }
   1.181              }
   1.182 @@ -184,7 +175,31 @@
   1.183          
   1.184          return table;
   1.185      }
   1.186 +    
   1.187 +    @Override
   1.188 +    protected void configureTableColumns(JTable table) {
   1.189 +        super.configureTableColumns(table);
   1.190          
   1.191 +        // Hide the type column in the table
   1.192 +        TableColumnModel columnModel = table.getColumnModel();
   1.193 +        TableColumn typeColumn = columnModel.getColumn(TYPE_COLUMN);
   1.194 +        columnModel.removeColumn(typeColumn);
   1.195 +    }
   1.196 +    
   1.197 +    @Override
   1.198 +    protected TableCellRenderer createTableHeaderRenderer() {
   1.199 +        return new EnvVarTableHeaderRenderer();   
   1.200 +    }
   1.201 +    
   1.202 +    class EnvVarTableHeaderRenderer extends TabularDataTableHeaderRenderer {
   1.203 +        // hide the type column
   1.204 +        protected int getColumnIndex(int column) {
   1.205 +            return column == NAME_COLUMN ? NAME_COLUMN : VALUE_COLUMN;
   1.206 +        }
   1.207 +    }    
   1.208 +    
   1.209 +    //=========================== RENDERERS ====================================
   1.210 +    
   1.211      static class StringRenderer extends DefaultTableCellRenderer {
   1.212          private static final Border myBorder = new EmptyBorder(1, 4, 1, 1);
   1.213          
   1.214 @@ -194,7 +209,7 @@
   1.215          }
   1.216          
   1.217          public Component getTableCellRendererComponent(JTable table, Object value,
   1.218 -                          boolean isSelected, boolean hasFocus, int row, int column) {
   1.219 +                boolean isSelected, boolean hasFocus, int row, int column) {
   1.220              Component component = super.getTableCellRendererComponent(
   1.221                      table, value, isSelected, hasFocus, row, column);
   1.222              setBorder(myBorder);
   1.223 @@ -212,7 +227,7 @@
   1.224          }
   1.225          
   1.226          public Component getTableCellRendererComponent(JTable table, Object value,
   1.227 -                          boolean isSelected, boolean hasFocus, int row, int column) {
   1.228 +                boolean isSelected, boolean hasFocus, int row, int column) {
   1.229              Component component = super.getTableCellRendererComponent(
   1.230                      table, value, isSelected, hasFocus, row, column);
   1.231              setBorder(myBorder);
   1.232 @@ -230,7 +245,7 @@
   1.233                  double d = Double.parseDouble((String)value);
   1.234                  setText(formatter.format(d));
   1.235              }
   1.236 -        }        
   1.237 +        }
   1.238      }
   1.239      
   1.240      static class BooleanRenderer extends JCheckBox implements TableCellRenderer {
   1.241 @@ -250,8 +265,8 @@
   1.242                  setForeground(table.getForeground());
   1.243                  setBackground(table.getBackground());
   1.244              }
   1.245 -                
   1.246 -            setSelected((value != null && value.toString().equalsIgnoreCase("true")));            
   1.247 +            
   1.248 +            setSelected((value != null && value.toString().equalsIgnoreCase("true")));
   1.249              
   1.250              return this;
   1.251          }
   1.252 @@ -289,6 +304,8 @@
   1.253          }
   1.254      }
   1.255      
   1.256 +    //============================= EDITORS ====================================
   1.257 +    
   1.258      static class GenericEditor extends DefaultCellEditor {
   1.259          
   1.260          Class[] argTypes = new Class[]{String.class};
   1.261 @@ -389,7 +406,7 @@
   1.262          }
   1.263          
   1.264          public Object getCellEditorValue() {
   1.265 -            Boolean b = (Boolean) super.getCellEditorValue();            
   1.266 +            Boolean b = (Boolean) super.getCellEditorValue();
   1.267              return b ? "true" : "false";
   1.268          }
   1.269      }
     2.1 --- a/compapp.manager.jbi/src/org/netbeans/modules/sun/manager/jbi/editors/EnvironmentVariablesEditor.java	Wed May 30 01:34:17 2007 +0000
     2.2 +++ b/compapp.manager.jbi/src/org/netbeans/modules/sun/manager/jbi/editors/EnvironmentVariablesEditor.java	Wed May 30 08:38:16 2007 +0000
     2.3 @@ -41,6 +41,8 @@
     2.4      protected String getStringForRowData(CompositeData rowData) {
     2.5          Collection rowValues = rowData.values();
     2.6          
     2.7 +        // Mask out password
     2.8 +        
     2.9          List<String> visibleRowValues = new ArrayList<String>();
    2.10          visibleRowValues.addAll(rowValues);
    2.11          
    2.12 @@ -50,11 +52,69 @@
    2.13          if (type.equals(EnvironmentVariablesCustomEditor.PASSWORD_TYPE)) {
    2.14              String password = (String) visibleRowValues.get(
    2.15                      EnvironmentVariablesCustomEditor.VALUE_COLUMN);
    2.16 -            password = password.replaceAll(".", "*");
    2.17 +            password = password.replaceAll(".", "*"); // NOI18N
    2.18              visibleRowValues.set(
    2.19                      EnvironmentVariablesCustomEditor.VALUE_COLUMN, password);
    2.20          }
    2.21          
    2.22          return visibleRowValues.toString();
    2.23      }
    2.24 +    
    2.25 +    @Override
    2.26 +    protected void validateRowData(String[] rowData) throws Exception {
    2.27 +        if (rowData == null || rowData.length != 3) {
    2.28 +            throw new RuntimeException("Illegal row data: "  + rowData);
    2.29 +        }
    2.30 +        
    2.31 +        String type = rowData[1];
    2.32 +        if (! type.equals(EnvironmentVariablesCustomEditor.STRING_TYPE) &&
    2.33 +                type.equalsIgnoreCase(EnvironmentVariablesCustomEditor.STRING_TYPE)) {
    2.34 +            type = rowData[1] = EnvironmentVariablesCustomEditor.STRING_TYPE;
    2.35 +        } else if (! type.equals(EnvironmentVariablesCustomEditor.NUMBER_TYPE) &&
    2.36 +                type.equalsIgnoreCase(EnvironmentVariablesCustomEditor.NUMBER_TYPE)) {
    2.37 +            type = rowData[1] = EnvironmentVariablesCustomEditor.NUMBER_TYPE;
    2.38 +        } else if (! type.equals(EnvironmentVariablesCustomEditor.BOOLEAN_TYPE) &&
    2.39 +                type.equalsIgnoreCase(EnvironmentVariablesCustomEditor.BOOLEAN_TYPE)) {
    2.40 +            type = rowData[1] = EnvironmentVariablesCustomEditor.BOOLEAN_TYPE;
    2.41 +        } else if (! type.equals(EnvironmentVariablesCustomEditor.PASSWORD_TYPE) &&
    2.42 +                type.equalsIgnoreCase(EnvironmentVariablesCustomEditor.PASSWORD_TYPE)) {
    2.43 +            type = rowData[1] = EnvironmentVariablesCustomEditor.PASSWORD_TYPE;
    2.44 +        }
    2.45 +                
    2.46 +        if (! type.equals(EnvironmentVariablesCustomEditor.STRING_TYPE) &&
    2.47 +                ! type.equals(EnvironmentVariablesCustomEditor.NUMBER_TYPE) &&
    2.48 +                ! type.equals(EnvironmentVariablesCustomEditor.BOOLEAN_TYPE) &&
    2.49 +                ! type.equals(EnvironmentVariablesCustomEditor.PASSWORD_TYPE)) {
    2.50 +            throw new RuntimeException("Illegal environment variable type: " + type + 
    2.51 +                    ". The only supported types are: STRING, NUMBER, BOOLEAN and PASSWORD.");
    2.52 +        }        
    2.53 +        
    2.54 +        String value = rowData[2]; 
    2.55 +        if (type.equals(EnvironmentVariablesCustomEditor.BOOLEAN_TYPE)) {
    2.56 +            if (!value.equalsIgnoreCase(Boolean.TRUE.toString()) && 
    2.57 +                    !value.equalsIgnoreCase(Boolean.FALSE.toString()) ) {
    2.58 +                if (value.equals("0")) { // NOI18N
    2.59 +                    rowData[2] = Boolean.FALSE.toString();
    2.60 +                } else if (value.equals("1")) { // NOI18N
    2.61 +                    rowData[2] = Boolean.TRUE.toString();
    2.62 +                } else {
    2.63 +                    throw new RuntimeException("Illegal boolean value: " + value);
    2.64 +                }
    2.65 +            }
    2.66 +        }
    2.67 +        
    2.68 +        if (type.equals(EnvironmentVariablesCustomEditor.NUMBER_TYPE)) {
    2.69 +            try {                
    2.70 +                Double.parseDouble(value);
    2.71 +            } catch (Exception e) {
    2.72 +                throw new RuntimeException("Invalid number: " + value);
    2.73 +            }
    2.74 +        }
    2.75 +        
    2.76 +        if (type.equals(EnvironmentVariablesCustomEditor.PASSWORD_TYPE)) {
    2.77 +            if (!value.matches("^\\*+$")) {
    2.78 +                throw new RuntimeException("Password is in clear text. Please use the custom editor to set password.");
    2.79 +            }
    2.80 +        }
    2.81 +    }
    2.82  }
     3.1 --- a/compapp.manager.jbi/src/org/netbeans/modules/sun/manager/jbi/editors/SimpleTabularDataCustomEditor.java	Wed May 30 01:34:17 2007 +0000
     3.2 +++ b/compapp.manager.jbi/src/org/netbeans/modules/sun/manager/jbi/editors/SimpleTabularDataCustomEditor.java	Wed May 30 08:38:16 2007 +0000
     3.3 @@ -2,16 +2,16 @@
     3.4   * The contents of this file are subject to the terms of the Common Development
     3.5   * and Distribution License (the License). You may not use this file except in
     3.6   * compliance with the License.
     3.7 - * 
     3.8 + *
     3.9   * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
    3.10   * or http://www.netbeans.org/cddl.txt.
    3.11 - * 
    3.12 + *
    3.13   * When distributing Covered Code, include this CDDL Header Notice in each file
    3.14   * and include the License file at http://www.netbeans.org/cddl.txt.
    3.15   * If applicable, add the following below the CDDL Header, with the fields
    3.16   * enclosed by brackets [] replaced by your own identifying information:
    3.17   * "Portions Copyrighted [year] [name of copyright owner]"
    3.18 - * 
    3.19 + *
    3.20   * The Original Software is NetBeans. The Initial Developer of the Original
    3.21   * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
    3.22   * Microsystems, Inc. All Rights Reserved.
    3.23 @@ -31,6 +31,8 @@
    3.24  import javax.management.openmbean.CompositeData;
    3.25  import javax.management.openmbean.CompositeDataSupport;
    3.26  import javax.management.openmbean.CompositeType;
    3.27 +import javax.management.openmbean.KeyAlreadyExistsException;
    3.28 +import javax.management.openmbean.OpenDataException;
    3.29  import javax.management.openmbean.OpenType;
    3.30  import javax.management.openmbean.TabularData;
    3.31  import javax.management.openmbean.TabularDataSupport;
    3.32 @@ -46,6 +48,7 @@
    3.33  import javax.swing.table.DefaultTableCellRenderer;
    3.34  import javax.swing.table.DefaultTableModel;
    3.35  import javax.swing.table.JTableHeader;
    3.36 +import javax.swing.table.TableCellRenderer;
    3.37  import javax.swing.table.TableColumn;
    3.38  import org.openide.DialogDisplayer;
    3.39  
    3.40 @@ -63,33 +66,35 @@
    3.41      
    3.42      private JTable table;
    3.43      
    3.44 +    private TableCellRenderer headerCellRenderer;
    3.45 +    
    3.46      /** Number of index columns in the tabular data type. */
    3.47 -    protected int indexColumnCount;
    3.48 +    private int indexColumnCount;
    3.49      
    3.50      // all the keys are at the beginning of the array
    3.51 -    protected String[] columnNames;
    3.52 +    private String[] columnNames;
    3.53      
    3.54 -    protected String[] columnDescriptions;
    3.55 -    protected OpenType[] columnTypes;
    3.56 +    private String[] columnDescriptions;
    3.57 +    private OpenType[] columnTypes;
    3.58      
    3.59 -    protected TabularType tabularType;
    3.60 +    private TabularType tabularType;
    3.61      private TabularData tabularData;
    3.62      
    3.63      private JButton addRowButton, deleteRowButton;
    3.64      
    3.65      private static String ADD_ROW = NbBundle.getMessage(SimpleTabularDataCustomEditor.class, "AddRowLabel");
    3.66      private static String DELETE_ROW = NbBundle.getMessage(SimpleTabularDataCustomEditor.class, "DeleteRowLabel");
    3.67 +        
    3.68 +        
    3.69 +    public SimpleTabularDataCustomEditor(SimpleTabularDataEditor editor) {        
    3.70 +        headerCellRenderer = createTableHeaderRenderer(); 
    3.71 +        
    3.72 +        tabularData = (TabularData) editor.getValue();        
    3.73 +        initComponents(tabularData);
    3.74 +    }
    3.75      
    3.76 -    
    3.77 -    public SimpleTabularDataCustomEditor(SimpleTabularDataEditor editor) {
    3.78 -        
    3.79 -        tabularData = (TabularData) editor.getValue();
    3.80 -        
    3.81 -        initComponents(tabularData);
    3.82 -        
    3.83 -//        HelpCtx.setHelpIDString(this, SimpleTabularDataCustomEditor.class.getName());
    3.84 -//        getAccessibleContext().setAccessibleDescription(
    3.85 -//            NbBundle.getBundle(SimpleTabularDataCustomEditor.class).getString("ACSD_SimpleTabularDataCustomEditor"));
    3.86 +    protected TableCellRenderer createTableHeaderRenderer() {
    3.87 +        return new TabularDataTableHeaderRenderer();   
    3.88      }
    3.89      
    3.90      public Object getPropertyValue() throws IllegalStateException {
    3.91 @@ -111,20 +116,28 @@
    3.92                  
    3.93                  // Ignore rows with null keys
    3.94                  boolean nullKeyRow = false;
    3.95 -                //System.out.println("indexCoumnCount is " + indexColumnCount + " first value is " + itemValues[0]);
    3.96                  for (int i = 0; i < indexColumnCount; i++) {
    3.97 -                    if (itemValues[i] == null) {
    3.98 +                    if (itemValues[i] == null ||
    3.99 +                            // the following check is not really required by tabular data
   3.100 +                            ((String)itemValues[i]).trim().length() == 0) {
   3.101                          nullKeyRow = true;
   3.102                          break;
   3.103                      }
   3.104 -                }                
   3.105 +                }
   3.106                  if (!nullKeyRow) {
   3.107                      CompositeData rowData =
   3.108                              new CompositeDataSupport(rowType, columnNames, itemValues);
   3.109                      ret.put(rowData);
   3.110                  }
   3.111              }
   3.112 -        } catch (Exception e) {
   3.113 +        } catch (KeyAlreadyExistsException e) {
   3.114 +            e.printStackTrace();
   3.115 +            
   3.116 +            NotifyDescriptor d = new NotifyDescriptor.Message(e.getMessage(), NotifyDescriptor.ERROR_MESSAGE);
   3.117 +            DialogDisplayer.getDefault().notify(d);
   3.118 +            
   3.119 +            ret = tabularData;  // if anything wrong, just return the old value
   3.120 +        } catch (OpenDataException e) {
   3.121              e.printStackTrace();
   3.122              
   3.123              NotifyDescriptor d = new NotifyDescriptor.Message(e.getMessage(), NotifyDescriptor.ERROR_MESSAGE);
   3.124 @@ -142,7 +155,7 @@
   3.125      }
   3.126      
   3.127      protected JTable createTable(DefaultTableModel tableModel) {
   3.128 -         JTable table = new JTable(tableModel) {           
   3.129 +        JTable table = new JTable(tableModel) {
   3.130              public Class getColumnClass(int column) {
   3.131                  OpenType columnType = columnTypes[column];
   3.132                  String className = columnType.getClassName();
   3.133 @@ -160,22 +173,21 @@
   3.134          
   3.135          return table;
   3.136      }
   3.137 -    
   3.138 -    protected int getColumnCount() {
   3.139 -        return columnNames.length;
   3.140 +        
   3.141 +    protected void configureTableColumns(JTable table) {
   3.142 +        for (int i = 0; i < columnNames.length; i++) {
   3.143 +            TableColumn col = table.getColumnModel().getColumn(i);
   3.144 +            col.setHeaderRenderer(headerCellRenderer);
   3.145 +        }
   3.146      }
   3.147      
   3.148      private void initComponents(TabularData tabularData) {
   3.149          DefaultTableModel tableModel = initTableModel(tabularData);
   3.150          
   3.151          table = createTable(tableModel);
   3.152 -               
   3.153          table.getTableHeader().setReorderingAllowed(false);
   3.154          
   3.155 -        for (int i = 0; i < getColumnCount(); i++) {
   3.156 -            TableColumn col = table.getColumnModel().getColumn(i);
   3.157 -            col.setHeaderRenderer(new MyTableHeaderRenderer());
   3.158 -        }
   3.159 +        configureTableColumns(table);
   3.160          
   3.161          table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
   3.162              public void valueChanged(ListSelectionEvent e) {
   3.163 @@ -208,7 +220,7 @@
   3.164          table.getParent().setBackground(Color.white);
   3.165      }
   3.166      
   3.167 -    protected DefaultTableModel initTableModel(TabularData tabularData) {
   3.168 +    private DefaultTableModel initTableModel(TabularData tabularData) {
   3.169          
   3.170          tabularType = tabularData.getTabularType();
   3.171          CompositeType rowType = tabularType.getRowType();
   3.172 @@ -253,13 +265,17 @@
   3.173              columnIdentifiers.addElement(columnNames[i]);
   3.174          }
   3.175          
   3.176 -        DefaultTableModel tableModel = new DefaultTableModel();
   3.177 +        DefaultTableModel tableModel = createTableModel();
   3.178          tableModel.setDataVector(dataVector, columnIdentifiers);
   3.179          
   3.180          return tableModel;
   3.181      }
   3.182      
   3.183 -    protected Vector createNewRow() {
   3.184 +    protected DefaultTableModel createTableModel() {
   3.185 +        return new DefaultTableModel();
   3.186 +    }
   3.187 +    
   3.188 +    protected Vector createRow() {
   3.189          Vector row = new Vector();
   3.190          for (int i = 0; i < columnNames.length; i++) {
   3.191              row.addElement(null);
   3.192 @@ -267,7 +283,7 @@
   3.193          return row;
   3.194      }
   3.195      
   3.196 -    private void addNewRow(Vector row) {        
   3.197 +    private void addRow(Vector row) {
   3.198          Vector dataVector = getDataVector();
   3.199          dataVector.addElement(row);
   3.200          table.addNotify();
   3.201 @@ -286,10 +302,10 @@
   3.202          table.addNotify();
   3.203          
   3.204          table.getSelectionModel().clearSelection();
   3.205 -//        if (rowIndices.length > 0) {
   3.206 -//            int newSelectedRowIndex = rowIndices[0] - 1;
   3.207 -//            table.getSelectionModel().setSelectionInterval(newSelectedRowIndex, newSelectedRowIndex);
   3.208 -//        }
   3.209 +        //        if (rowIndices.length > 0) {
   3.210 +        //            int newSelectedRowIndex = rowIndices[0] - 1;
   3.211 +        //            table.getSelectionModel().setSelectionInterval(newSelectedRowIndex, newSelectedRowIndex);
   3.212 +        //        }
   3.213      }
   3.214      
   3.215      private Vector getDataVector() {
   3.216 @@ -300,21 +316,21 @@
   3.217          if (table.isEditing()) {
   3.218              table.getCellEditor().stopCellEditing();
   3.219          }
   3.220 -         
   3.221 +        
   3.222          JButton source = (JButton) event.getSource();
   3.223          String actionCommand = source.getActionCommand();
   3.224          
   3.225          if (actionCommand.equals(ADD_ROW)) {
   3.226 -            Vector row = createNewRow();
   3.227 +            Vector row = createRow();
   3.228              if (row != null) {
   3.229 -                addNewRow(row);
   3.230 +                addRow(row);
   3.231              }
   3.232          } else if (actionCommand.equals(DELETE_ROW)) {
   3.233              deleteSelectedRows();
   3.234          }
   3.235 -    }
   3.236 +    }    
   3.237      
   3.238 -    public class MyTableHeaderRenderer extends DefaultTableCellRenderer {
   3.239 +    class TabularDataTableHeaderRenderer extends DefaultTableCellRenderer {
   3.240          // This method is called each time a column header
   3.241          // using this renderer needs to be rendered.
   3.242          public Component getTableCellRendererComponent(JTable table, Object value,
   3.243 @@ -327,13 +343,17 @@
   3.244                      setFont(header.getFont());
   3.245                  }
   3.246              }
   3.247 -            String myValue = (value == null) ? "" : 
   3.248 +            String myValue = (value == null) ? "" :
   3.249                  "<html><body><b>" + value.toString().toUpperCase() + "</b></body></html>";
   3.250              setText(myValue);
   3.251 -            setToolTipText(columnDescriptions[colIndex]);
   3.252 +            setToolTipText(columnDescriptions[getColumnIndex(colIndex)]); 
   3.253              setBorder(UIManager.getBorder("TableHeader.cellBorder"));
   3.254              setHorizontalAlignment(JLabel.CENTER);
   3.255              return this;
   3.256          }
   3.257 +        
   3.258 +        protected int getColumnIndex(int column) {
   3.259 +            return column;
   3.260 +        }
   3.261      }
   3.262  }
     4.1 --- a/compapp.manager.jbi/src/org/netbeans/modules/sun/manager/jbi/editors/SimpleTabularDataEditor.java	Wed May 30 01:34:17 2007 +0000
     4.2 +++ b/compapp.manager.jbi/src/org/netbeans/modules/sun/manager/jbi/editors/SimpleTabularDataEditor.java	Wed May 30 08:38:16 2007 +0000
     4.3 @@ -19,8 +19,11 @@
     4.4  
     4.5  package org.netbeans.modules.sun.manager.jbi.editors;
     4.6  
     4.7 +
     4.8  import java.beans.PropertyEditorSupport;
     4.9 +import java.util.ArrayList;
    4.10  import java.util.Collection;
    4.11 +import java.util.List;
    4.12  import java.util.StringTokenizer;
    4.13  import javax.management.openmbean.CompositeData;
    4.14  import javax.management.openmbean.CompositeDataSupport;
    4.15 @@ -28,6 +31,8 @@
    4.16  import javax.management.openmbean.TabularData;
    4.17  import javax.management.openmbean.TabularDataSupport;
    4.18  import javax.management.openmbean.TabularType;
    4.19 +import org.openide.DialogDisplayer;
    4.20 +import org.openide.NotifyDescriptor;
    4.21  
    4.22  
    4.23  /**
    4.24 @@ -79,17 +84,21 @@
    4.25              String[] columnNames = (String[]) rowType.keySet().toArray(new String[] {});
    4.26              
    4.27              if (text != null) {
    4.28 -                String dataString = text.trim().replaceFirst("\\{\\s*\\[", "").replaceAll("\\]\\s*\\[", "\n").replaceFirst("\\]\\s*\\}", ""); // NOI18N
    4.29 +                String dataString = text.trim().replaceFirst("\\{\\s*\\[", ""). // NOI18N
    4.30 +                        replaceAll("\\]\\s*\\[", "\n").replaceFirst("\\]\\s*\\}", ""); // NOI18N
    4.31                  StringTokenizer stringTokenizer = new StringTokenizer(dataString, "\n"); // NOI18N
    4.32                  while (stringTokenizer.hasMoreTokens()) {
    4.33                      String rowString = stringTokenizer.nextToken();
    4.34                      
    4.35 -                    String[] itemValues = new String[columnNames.length];
    4.36 -                    int index = 0;
    4.37 +                    List<String> itemList = new ArrayList<String>();
    4.38                      StringTokenizer rowStringTokenizer = new StringTokenizer(rowString, ","); // NOI18N
    4.39                      while (rowStringTokenizer.hasMoreTokens()) {
    4.40 -                        itemValues[index++] = rowStringTokenizer.nextToken().trim();
    4.41 +                        itemList.add(rowStringTokenizer.nextToken().trim());
    4.42                      }
    4.43 +                    String[] itemValues = itemList.toArray(new String[itemList.size()]);
    4.44 +                    
    4.45 +                    validateRowData(itemValues);
    4.46 +                    
    4.47                      CompositeData rowData =
    4.48                              new CompositeDataSupport(rowType, columnNames, itemValues);
    4.49                      tabularData.put(rowData);
    4.50 @@ -99,9 +108,15 @@
    4.51              setValue(tabularData);
    4.52              
    4.53          } catch (Exception e) {
    4.54 -            throw new java.lang.IllegalArgumentException(e.getMessage());
    4.55 +            NotifyDescriptor d = new NotifyDescriptor.Message(e.getMessage(),
    4.56 +                    NotifyDescriptor.ERROR_MESSAGE);
    4.57 +            DialogDisplayer.getDefault().notify(d);
    4.58          }
    4.59      }
    4.60 +    
    4.61 +    protected void validateRowData(String[] rowData) throws Exception {
    4.62 +        ; // no-op
    4.63 +    }
    4.64  
    4.65      @Override    
    4.66      public void setValue(Object v) {