View Javadoc
1   package org.opentrafficsim.editor;
2   
3   import java.rmi.RemoteException;
4   
5   import javax.swing.SwingUtilities;
6   
7   import org.w3c.dom.Document;
8   
9   import de.javagl.treetable.AbstractTreeTableModel;
10  import de.javagl.treetable.JTreeTable;
11  import de.javagl.treetable.TreeTableModel;
12  
13  /**
14   * Defines the columns in the {@code JTreeTable}. Most functionality is forwarded to the tree with {@code XsdTreeNode}'s.
15   * <p>
16   * Copyright (c) 2023-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
17   * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
18   * </p>
19   * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
20   */
21  public class XsdTreeTableModel extends AbstractTreeTableModel
22  {
23  
24      /** Column names. */
25      private static final String[] COLUMN_NAMES = new String[] {"Item", "Id", "Value", "#"};
26  
27      /** Minimum column widths. */
28      private static final int[] MIN_COLUMN_WIDTHS = new int[] {100, 50, 50, 30};
29  
30      /** Preferred column widths. */
31      private static final int[] PREFERRED_COLUMN_WIDTHS = new int[] {600, 200, 200, 30};
32  
33      /** Column classes. */
34      private static final Class<?>[] COLUMN_CLASSES =
35              new Class<?>[] {TreeTableModel.class, String.class, String.class, String.class};
36  
37      /** Tree table, so it can be updated visually when a value has changed. */
38      private JTreeTable treeTable;
39  
40      /**
41       * Constructor.
42       * @param document Document; XSD document.
43       * @throws RemoteException when unable to listen for created nodes.
44       */
45      protected XsdTreeTableModel(final Document document) throws RemoteException
46      {
47          super(document == null ? null : new XsdTreeNodeRoot(new Schema(document)));
48      }
49  
50      /**
51       * Sets the tree table.
52       * @param treeTable JTreeTable; tree table.
53       */
54      public void setTreeTable(final JTreeTable treeTable)
55      {
56          this.treeTable = treeTable;
57      }
58  
59      /** {@inheritDoc} */
60      @Override
61      public int getColumnCount()
62      {
63          return COLUMN_CLASSES.length;
64      }
65  
66      /** {@inheritDoc} */
67      @Override
68      public String getColumnName(final int column)
69      {
70          return COLUMN_NAMES[column];
71      }
72  
73      /** {@inheritDoc} */
74      @Override
75      public Class<?> getColumnClass(final int column)
76      {
77          return COLUMN_CLASSES[column];
78      }
79  
80      /** {@inheritDoc} */
81      @Override
82      public Object getValueAt(final Object node, final int column)
83      {
84          if (column == 0)
85          {
86              return node; // required for tree view of column 0
87          }
88          if (column == 1)
89          {
90              if (((XsdTreeNode) node).isIdentifiable())
91              {
92                  return ((XsdTreeNode) node).getId();
93              }
94              return "";
95          }
96          else if (column == 2)
97          {
98              if (((XsdTreeNode) node).isEditable())
99              {
100                 return ((XsdTreeNode) node).getValue();
101             }
102             return "";
103         }
104         return occurs(((XsdTreeNode) node).minOccurs(), ((XsdTreeNode) node).maxOccurs());
105     }
106 
107     /**
108      * Creates a string to display minOccurs and maxOccurs.
109      * @param minOccurs int; minOccurs.
110      * @param maxOccurs int; maxOccurs.
111      * @return String; string to display minOccurs and maxOccurs.
112      */
113     public String occurs(final int minOccurs, final int maxOccurs)
114     {
115         if (minOccurs == maxOccurs)
116         {
117             return Integer.toString(minOccurs);
118         }
119         return Integer.valueOf(minOccurs) + ".." + (maxOccurs == -1 ? "∞" : Integer.valueOf(maxOccurs));
120     }
121 
122     /** {@inheritDoc} */
123     @Override
124     public Object getChild(final Object parent, final int index)
125     {
126         return ((XsdTreeNode) parent).getChild(index);
127     }
128 
129     /** {@inheritDoc} */
130     @Override
131     public int getChildCount(final Object parent)
132     {
133         return ((XsdTreeNode) parent).getChildCount();
134     }
135 
136     /** {@inheritDoc} */
137     @Override
138     public boolean isCellEditable(final Object node, final int column)
139     {
140         if (column == 0)
141         {
142             return true; // required for tree in column 0
143         }
144         XsdTreeNode treeNode = (XsdTreeNode) node;
145         if (column == 1)
146         {
147             return treeNode.isIdentifiable() && !treeNode.isInclude();
148         }
149         return treeNode.isEditable() && column == 2 && !treeNode.isInclude();
150     }
151 
152     /** {@inheritDoc} */
153     @Override
154     public void setValueAt(final Object aValue, final Object node, final int column)
155     {
156         if (column == 1)
157         {
158             ((XsdTreeNode) node).setId(aValue.toString());
159         }
160         else if (column == 2)
161         {
162             ((XsdTreeNode) node).setValue(aValue.toString());
163         }
164         // invoking directly results in a NullPointerException when clicking on the table during editing of a value in the table
165         SwingUtilities.invokeLater(() -> this.treeTable.updateUI());
166     }
167 
168     /**
169      * Apply the column widths to a newly created tree table.
170      * @param treeTable JTreeTable; tree table.
171      */
172     public static void applyColumnWidth(final JTreeTable treeTable)
173     {
174         for (int i = 0; i < treeTable.getColumnCount(); i++)
175         {
176             treeTable.getColumn(COLUMN_NAMES[i]).setMinWidth(MIN_COLUMN_WIDTHS[i]);
177             treeTable.getColumn(COLUMN_NAMES[i]).setPreferredWidth(PREFERRED_COLUMN_WIDTHS[i]);
178         }
179     }
180 
181 }