HomeDigital EditionSys-Con RadioSearch Java Cd
Advanced Java AWT Book Reviews/Excerpts Client Server Corba Editorials Embedded Java Enterprise Java IDE's Industry Watch Integration Interviews Java Applet Java & Databases Java & Web Services Java Fundamentals Java Native Interface Java Servlets Java Beans J2ME Libraries .NET Object Orientation Observations/IMHO Product Reviews Scalability & Performance Security Server Side Source Code Straight Talking Swing Threads Using Java with others Wireless XML
 

"The JConfigure Widget"
Volume: 4 Issue: 2, p. 58

Download files assoicated with this article

	

Listing 1: The PersThread Application

public class ConfigureTree extends JTree
{
  public ConfigureTree(ConfigureTreeModel model)
  {
    setPreferredSize(new Dimension(150, 150));
    setShowsRootHandles(true);
    setRootVisible(false);
    setModel(model);
  }
} 

Listing 2.

public class ConfigureTreeModel extends DefaultTreeModel
{
  public ConfigureTreeModel()
  {
    super(new ConfigureTreeNode("properties"));
  }
  
  public void addPath(String path)
  {
    StringTokenizer tokenizer =
      new StringTokenizer(path, ".", false);
    
    ConfigureTreeNode node, next;
    node = (ConfigureTreeNode)getRoot();
    while (tokenizer.hasMoreTokens())
    {
      String name = tokenizer.nextToken();
      next = node.getChild(name);
      if (next == null)
      {
        next = new ConfigureTreeNode(name);
        node.add(next);
      }
      node = next;
    }
  }

  public Vector getPaths()
  {
    Vector vector = new Vector();
    getPaths("", vector, (ConfigureTreeNode)getRoot());
    return vector;
  }

  public void getPaths(String path, Vector vector,
    ConfigureTreeNode node)
  {
    int count = node.getChildCount();
    ConfigureTreeNode child;
    for (int i = 0; i < count; i++)
    {
      child = (ConfigureTreeNode)node.getChildAt(i);
      String next, name = child.getName();
      if (path.length() == 0) next = name; 
      else next = path + "." + name;
      vector.addElement(next);
      getPaths(next, vector, child);
    }
  }
}


Listing 3.
 
public class ConfigureTreeNode extends DefaultMutableTreeNode
{
  public ConfigureTreeNode(String name)
  {
    super(name);
  }

  public String getName()
  {
    return (String)getUserObject();
  }

  public ConfigureTreeNode getChild(String name)
  {
    ConfigureTreeNode node;
    Enumeration enum = children();
    while (enum.hasMoreElements())
    {
      node = (ConfigureTreeNode)enum.nextElement();
      if (node.getName().equals(name)) return node;
    }
    return null;
  }
}

Listing 4.

public class TitleBar extends JLabel
{
  public TitleBar(String text, Icon icon)
  {
    super(text, icon, JLabel.LEFT);
    setFont(new Font(getFont().getName(), Font.PLAIN, 16));
    setPreferredSize(new Dimension(30, 30));
    setBorder(new EmptyBorder(5, 5, 5, 5));
    setBackground(Color.gray);
    setForeground(Color.white);
    setOpaque(true);
  }
}

Listing 5

public class FieldLayout extends AbstractLayout
{
  public FieldLayout() {}
  
  public FieldLayout(int hgap, int vgap)
  {
    super(hgap, vgap);
  }
  
  public Dimension minimumLayoutSize(Container target)
  {
    int left = 0, right = 0, height = 0;
    Insets insets = target.getInsets();
    int ncomponents = target.getComponentCount();
    for (int i = 0; i < ncomponents; i += 2)
    {
      Component label = target.getComponent(i);
      int w1 = label.getMinimumSize().width;
      int h1 = label.getMinimumSize().height;
      if (w1 > left) left = w1;
      if (i + 1 < ncomponents)
      {
        Component field = target.getComponent(i + 1);
        int w2 = field.getMinimumSize().width;
        int h2 = field.getMinimumSize().height;
        if (w2 > right) right = w2;
        height += Math.max(h1, h2) + hgap;
      }
      else height += h1;
    }
    return new Dimension(
      insets.left + insets.right + left + right + vgap,
      insets.top + insets.bottom + height - hgap);
  }

  public Dimension preferredLayoutSize(Container target)
  {
    int left = 0, right = 0, height = 0;
    Insets insets = target.getInsets();
    int ncomponents = target.getComponentCount();
    for (int i = 0; i < ncomponents; i + = 2)
    {
      Component label = target.getComponent(i);
      int w1 = label.getPreferredSize().width;
      int h1 = label.getPreferredSize().height;
      if (w1 > left) left = w1;
      if (i + 1 < ncomponents)
      {
        Component field = target.getComponent(i + 1);
        int w2 = field.getPreferredSize().width;
        int h2 = field.getPreferredSize().height;
        if (w2 > right) right = w2;
        height += Math.max(h1, h2) + hgap;
      }
      else height += h1;
    }
    return new Dimension(
      insets.left + insets.right + left + right + vgap,
      insets.top + insets.bottom + height - hgap);
  }
  
  public void layoutContainer(Container target)
  {
    int left = 0;
    int height = 0;
    Insets insets = target.getInsets();
    int ncomponents = target.getComponentCount();
    // Pre-calculate left position
    for (int i = 0; i < ncomponents; i += 2)
    {
      Component label = target.getComponent(i);
      int w = label.getPreferredSize().width;
      if (w > left) left = w;
    }
    int right = target.getSize().width - left
      - insets.left - insets.right - hgap;
    int vpos = insets.top;
    for (int i = 0; i < ncomponents; i += 2)
    {
      Component label = target.getComponent(i);
      int h1 = label.getPreferredSize().height;
      int h2 = 0;
      Component field = null;
      if (i + 1 < ncomponents)
      {
        field = target.getComponent(i + 1);
        h2 = field.getPreferredSize().height;
      }
      int h = Math.max(h1, h2);
      label.setBounds(insets.left, vpos, left, h);
      if (field != null)
        field.setBounds(insets.left + left + hgap, vpos, right, h);
      vpos += h + hgap;
    }
  }
}

Listing 6.

public class FieldPanel extends JPanel
{
  protected String path;
  
  public FieldPanel(String path)
  {
    this.path = path;
    setLayout(new FieldLayout(4, 4));
    setBorder(new EmptyBorder(4, 4, 4, 4));
  }
  
  public void addEntry(String prompt, String value)
  {
    add(new JLabel(prompt));
    add(new JTextField(value));
  }

  public void addEntry(String prompt, Component comp)
  {
    add(new JLabel(prompt));
    add(comp);
  }
  
  public String[] getFieldNames()
  {
    int count = getComponentCount() / 2;
    String[] list = new String[count];
    JLabel label;
    for (int i = 0; i < count; i++)
    {
      label = (JLabel)getComponent(i * 2);
      list[i] = label.getText();
    }
    return list;
  }

  public String[] getFieldValues()
  {
    int count = getComponentCount() / 2;
    String[] list = new String[count];
    for (int i = 0; i < count; i++)
    {
      Component component = getComponent(i * 2 + 1);
      if (component instanceof PropertyField)
      {
        PropertyField field = (PropertyField)component;
        list[i] = field.getValue();
      }
      else
      {
        JTextField field = (JTextField)component;
        list[i] = field.getText();
      }
    }
    return list;
  }
}

Listing 7.

public interface PropertyField
{
  public String getValue();
  public void setValue(String value);
}

Listing 8.

public class PropertyTextField extends JTextField
  implements PropertyField
{
  public PropertyTextField()
  {
    super();
  }
  
  public String getValue()
  {
    return getText();
  }
  
  public void setValue(String value)
  {
    setText(value);
  }
}

Listing 9.

public class PropertyBooleanField extends JComboBox
  implements PropertyField
{
  private static String[] list = {"true", "false"};
  
  public PropertyBooleanField()
  {
    super(list);
  }
  
  public String getValue()
  {
    return (String)getSelectedItem();
  }
  
  public void setValue(String value)
  {
    setSelectedItem(value);
  }
}

Listing 10.

public class PropertyRectangleField extends JPanel
  implements PropertyField
{
  JTextField left, top, width, height;
  
  public PropertyRectangleField()
  {
    setBorder(new EtchedBorder());
    setLayout(new GridLayout(2, 4));
    add(new JLabel("Left: ", JLabel.RIGHT));
    add(left = new JTextField(3));
    add(new JLabel("Top: ", JLabel.RIGHT));
    add(top = new JTextField(3));
    add(new JLabel("Width: ", JLabel.RIGHT));
    add(width = new JTextField(3));
    add(new JLabel("Height: ", JLabel.RIGHT));
    add(height = new JTextField(3));
  }
  
  public String getValue()
  {
    return left.getText() + "," +
      top.getText() + "," +
      width.getText() + "," +
      height.getText();
  }
  
  public void setValue(String value)
  {
    StringTokenizer tokenizer =
      new StringTokenizer(value, ",", false);
    left.setText(tokenizer.nextToken());
    top.setText(tokenizer.nextToken());
    width.setText(tokenizer.nextToken());
    height.setText(tokenizer.nextToken());
  }
}

Listing 11.

public class JConfigure extends JPanel
  implements TreeSelectionListener
{
  protected JTree tree;
  protected JLabel title;
  protected JPanel deck;
  protected String filename;
  protected DeckLayout layout = new DeckLayout();
  protected Hashtable decks = new Hashtable();
  protected ConfigureTreeModel model;
  protected Properties template = new Properties();
  
  public JConfigure(String filename)
    throws IOException
  {
    this.filename = filename;
    ImageIcon icon = new ImageIcon("Task.gif");
    UIManager.put("Tree.leafIcon", icon);
    Border border = new BevelBorder(BevelBorder.LOWERED,
      getBackground().brighter(), getBackground(),
      getBackground().darker(), getBackground());
      
    setLayout(new BorderLayout());
    setBorder(new EmptyBorder(5, 5, 5, 5));
    model = new ConfigureTreeModel();
    
    deck = new JPanel();
    deck.setLayout(layout);
    
    File templateFile = new File(
      filename.substring(0, filename.lastIndexOf('.')) +
      ".template");
    if (templateFile.exists())
      readTemplate(templateFile.getName());
    readProperties(model, filename);
    
    tree = new ConfigureTree(model);
    tree.addTreeSelectionListener(this);
    add("West", new JScrollPane(tree));
    
    title = new TitleBar("Properties", icon);
    
    JPanel content = new JPanel();
    content.setLayout(new BorderLayout());
    content.add("Center", new JScrollPane(deck));
    
    JPanel panel = new JPanel();
    panel.setLayout(new BorderLayout());
    panel.setBorder(new EmptyBorder(0, 5, 0, 0));
    panel.add("North", title);
    panel.add("Center", content);
    add("Center", panel);
  }

  public void readTemplate(String filename)
    throws IOException
  {
    InputStream input = new FileInputStream(filename);
    template.load(input);
    input.close();
  }
  
  public void save() throws IOException
  {
    String prevfile = filename.substring(0,
      filename.lastIndexOf('.')) + ".previous";
    File prev = new File(prevfile);
    if (prev.exists()) prev.delete();
    File file = new File(filename);
    if (file.exists()) file.renameTo(prev);
    writeProperties(model, filename);
  }
  
  public void save(String filename) throws IOException
  {
    writeProperties(model, filename);
  }
  
  private void writeProperties(ConfigureTreeModel tree,
    String filename) throws IOException
  {
    Vector paths = model.getPaths();
    int count = paths.size();
    
    BufferedWriter writer =
      new BufferedWriter(new FileWriter(filename));
    
    writer.write("# Saved by JConfigure on " +
      DateFormat.getDateTimeInstance(
        DateFormat.SHORT, DateFormat.SHORT).
        format(new Date(System.currentTimeMillis())));
    writer.newLine();
    
    for (int i = 0; i < count; i++)
    {
      String path = paths.elementAt(i).toString();
      if (decks.containsKey(path))
      {
        FieldPanel card = (FieldPanel)decks.get(path);
        String[] names = card.getFieldNames();
        String[] values = card.getFieldValues();
        for (int j = 0; j < names.length; j++)
        {
          writer.write(path + "." +
            names[j].substring(0,
              names[j].length() - 1)
             + "=" + values[j]);
          writer.newLine();   
        }
        
      }
    }
    writer.close();
  }

  private void readProperties(ConfigureTreeModel tree,
    String filename) throws IOException
  {
    BufferedReader reader =
      new BufferedReader(new FileReader(filename));
    String line;
    while ((line = reader.readLine()) != null)
    {
      processLine(tree, line);
    }
    reader.close();
  }

  private void processLine(ConfigureTreeModel tree, String line)
  {
    if (line.charAt(0) == '#') return;
    String prop = line.substring(0, line.indexOf('='));
    String path = prop.substring(0, prop.lastIndexOf('.'));
    String name = prop.substring(path.length() + 1);
    String value = line.substring(prop.length() + 1);
    tree.addPath(path);
    addField(path, name, value);
  }  

  public void addField(String path, String name, String value)
  {
    FieldPanel card;
    if (decks.containsKey(path))
    {
      card = (FieldPanel)decks.get(path);
    }
    else
    {
      card = new FieldPanel(path);
      decks.put(path, card);
      deck.add(path, card);
    }
    try
    {
      String className = "PropertyTextField";
      String prop = path + "." + name;
      if (template.containsKey(prop))
        className = (String)template.get(prop);
      PropertyField field = (PropertyField)
        Class.forName(className).newInstance();
      field.setValue(value);
      card.addEntry(name + ":", (Component)field);
    }
    catch (InstantiationException e)
    {
      System.out.println(e);
    }
    catch (ClassNotFoundException e)
    {
      System.out.println(e);
    }
    catch (IllegalAccessException e)
    {
      System.out.println(e);
    }
  }

  public void valueChanged(TreeSelectionEvent event)
  {
    Object obj = tree.getLastSelectedPathComponent();
    if (obj == null) return;
    ConfigureTreeNode node = (ConfigureTreeNode)obj;
    if (node.isLeaf())
    {
      title.setText(node.getName() + " properties");
      String path = treePath(tree.getSelectionPath());
      layout.show(deck, path);
      deck.repaint();
    }
  }
  
  public String treePath(TreePath treePath)
  {
    ConfigureTreeNode node;
    Object[] list = treePath.getPath();
    StringBuffer path = new StringBuffer();
    for (int i = 1; i < list.length; i++)
    {
      node = (ConfigureTreeNode)list[i];
      if (i > 1) path.append(".");
      path.append(node.getName());
    }
    return path.toString();
  }
}




 
      
 

All Rights Reserved
Copyright ©  2004 SYS-CON Media, Inc.
  E-mail: [email protected]

Java and Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. SYS-CON Publications, Inc. is independent of Sun Microsystems, Inc.