/* Copyright (C) 2006 Christian Schneider
*
* This file is part of Nomad.
*
* Nomad is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Nomad is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Nomad; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.sf.nmedit.nomad.core.forms;
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JSplitPane;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import net.sf.nmedit.nomad.core.swing.explorer.ContainerNode;
import net.sf.nmedit.nomad.core.swing.explorer.ExplorerTree;
public class PropertyDialogForm extends JPanel implements TreeSelectionListener
{
/**
*
*/
private static final long serialVersionUID = -1138963228471158691L;
private ExplorerTree propertiesTree;
private JPanel dialogPane ;
protected JPanel buttonPane;
protected JLabel titleLabel;
protected JComponent editor;
public PropertyDialogForm()
{
propertiesTree = new ExplorerTree();
dialogPane = new JPanel();
buttonPane = new JPanel();
setLayout(new BorderLayout());
JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, new JScrollPane(propertiesTree),
dialogPane);
split.setResizeWeight(0);
split.setDividerLocation(160);
JPanel titlePane = new JPanel();
titleLabel = new JLabel();
titleLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 4, 0));
titleLabel.setFont(new Font("sansserif", Font.BOLD, 12));
titlePane.setLayout(new BoxLayout(titlePane, BoxLayout.Y_AXIS));
titlePane.add(titleLabel);
titlePane.add(new JSeparator(JSeparator.HORIZONTAL));
titlePane.setBorder(BorderFactory.createEmptyBorder(0, 0, 4, 0));
dialogPane.setLayout(new BorderLayout());
dialogPane.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
dialogPane.add(titlePane, BorderLayout.NORTH);
add(split, BorderLayout.CENTER);
add(buttonPane, BorderLayout.SOUTH);
buttonPane.setLayout(new BoxLayout(buttonPane, BoxLayout.LINE_AXIS));
buttonPane.add(Box.createHorizontalGlue());
buttonPane.setBorder(BorderFactory.createEmptyBorder(4,4,4,4));
propertiesTree.addTreeSelectionListener(this);
}
public boolean setSelectedPath(String path)
{
TreeNode e = getEntry(path, false);
if (e == null)
return false;
List<Object> c = new LinkedList<Object>();
while (e != null)
{
c.add(0, e);
e = e.getParent();
}
propertiesTree.setSelectionPath(new TreePath(c.toArray()));
TreePath s = propertiesTree.getSelectionPath();
return s != null && s.getLastPathComponent() == e;
}
public JPanel getButtonPane()
{
return buttonPane;
}
public JComponent getEditor()
{
return editor;
}
public void setEditor(JComponent c)
{
if (this.editor == c)
return;
if (this.editor != null)
dialogPane.remove(this.editor);
this.editor = c;
if (this.editor != null)
dialogPane.add(this.editor, BorderLayout.CENTER);
dialogPane.revalidate();
dialogPane.invalidate();
dialogPane.repaint();
}
public void addButton(Action a)
{
buttonPane.add(new JButton(a));
}
public void addActionListener(ActionListener l)
{
listenerList.add(ActionListener.class, l);
}
public void removeActionListener(ActionListener l)
{
listenerList.add(ActionListener.class, l);
}
protected void fireEntrySelectedEvent(String path)
{
ActionEvent actionEvent = null;
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners[i]==ActionListener.class) {
// Lazily create the event:
if (actionEvent == null)
actionEvent = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, path);
((ActionListener)listeners[i+1]).actionPerformed(actionEvent);
}
}
}
private Map<String, Entry> paths = new HashMap<String, Entry>();
protected Entry getEntry(String path, boolean create)
{
Entry e = paths.get(path);
if (e == null && create)
{
int slash = path.lastIndexOf('/');
if (slash >= 0)
{
String parentPath = path.substring(0, slash);
Entry parent = getEntry(parentPath, true);
e = new Entry(parent, path);
parent.addChild(e);
paths.put(path, e);
}
else
{
e = new Entry(propertiesTree.getRoot(), path);
propertiesTree.getRoot().add(e);
paths.put(path, e);
}
}
return e;
}
public String getTitleAt(String path)
{
Entry e = getEntry(path, false);
return e == null ? null : e.getTitle();
}
public void setTitleAt(String path, String title)
{
Entry e = getEntry(path, false);
if (e != null)
e.setTitle(title);
}
public Icon getIconAt(String path)
{
Entry e = getEntry(path, false);
return e == null ? null : e.getIcon();
}
public void setIconAt(String path, Icon icon)
{
Entry e = getEntry(path, false);
if (e != null)
e.setIcon(icon);
}
public Entry addEntry(String path, String title)
{
Entry e = getEntry(path, true);
e.setTitle(title);
propertiesTree.fireNodeStructureChanged(e.getParent());
return e;
}
public static void main(String[] args)
{
final JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setBounds(10, 10, 400, 360);
final PropertyDialogForm pdf = new PropertyDialogForm();
pdf.addEntry("file/info", "Info");
pdf.addEntry("file/info2", "Info2");
pdf.addEntry("somewhere/info3", "Info3");
pdf.addEntry("somewhere", "SOME");
pdf.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
pdf.setEditor(new JLabel(e.getActionCommand()));
}});
Action c = new AbstractAction()
{
/**
*
*/
private static final long serialVersionUID = -1632392266734922822L;
public void actionPerformed(ActionEvent e)
{
f.setVisible(false);
f.dispose();
}
};
c.putValue(Action.NAME, "Close");
pdf.addButton(c);
f.getContentPane().setLayout(new BorderLayout());
f.getContentPane().add(pdf, BorderLayout.CENTER);
f.setVisible(true);
}
protected static class Entry extends ContainerNode
{
private String path;
public Entry(TreeNode parent, String path)
{
super(parent, null);
this.path = path;
int slash = path.lastIndexOf('/');
if (slash>=0)
setTitle(path.substring(slash));
else
setTitle(path);
}
}
public void valueChanged(TreeSelectionEvent e)
{
Entry entry = null;
TreePath path = e.getPath();
if (path != null)
{
Object c = path.getLastPathComponent();
if (c != null && c instanceof Entry)
entry = (Entry) c;
}
selectionChanged(entry);
}
private void selectionChanged(Entry entry)
{
if (entry != null)
{
titleLabel.setText(entry.getTitle());
setEditor(null);
fireEntrySelectedEvent(entry.path);
}
else
{
setEditor(null);
titleLabel.setText("");
}
}
public void dispose()
{
}
}