|
What this is
Other links
The source code
/*
* OptionsDialog.java - Tree options dialog
* :tabSize=8:indentSize=8:noTabs=false:
* :folding=explicit:collapseFolds=1:
*
* Copyright (C) 1998, 2003 Slava Pestov
* Portions copyright (C) 1999 mike dillon
*
* This program 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 any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.gjt.sp.jedit.gui;
//{{{ Imports
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import javax.swing.tree.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import org.gjt.sp.jedit.*;
import org.gjt.sp.util.Log;
//}}}
/**
* An abstract tabbed options dialog box.
* @author Slava Pestov
* @version $Id: OptionsDialog.java,v 1.38 2004/06/28 06:45:27 spestov Exp $
*/
public abstract class OptionsDialog extends EnhancedDialog
implements ActionListener, TreeSelectionListener
{
//{{{ OptionsDialog constructor
public OptionsDialog(Frame frame, String name, String pane)
{
super(frame, jEdit.getProperty(name + ".title"), true);
init(name,pane);
} //}}}
//{{{ OptionsDialog constructor
public OptionsDialog(Dialog dialog, String name, String pane)
{
super(dialog, jEdit.getProperty(name + ".title"), true);
init(name,pane);
} //}}}
//{{{ addOptionGroup() method
public void addOptionGroup(OptionGroup group)
{
getDefaultGroup().addOptionGroup(group);
} //}}}
//{{{ addOptionPane() method
public void addOptionPane(OptionPane pane)
{
getDefaultGroup().addOptionPane(pane);
} //}}}
//{{{ ok() method
public void ok()
{
if(currentPane != null)
jEdit.setProperty(name + ".last",currentPane.getName());
ok(true);
} //}}}
//{{{ cancel() method
public void cancel()
{
if(currentPane != null)
jEdit.setProperty(name + ".last",currentPane.getName());
dispose();
} //}}}
//{{{ ok() method
public void ok(boolean dispose)
{
OptionTreeModel m = (OptionTreeModel) paneTree
.getModel();
save(m.getRoot());
/* This will fire the PROPERTIES_CHANGED event */
jEdit.propertiesChanged();
// Save settings to disk
jEdit.saveSettings();
// get rid of this dialog if necessary
if(dispose)
dispose();
} //}}}
//{{{ dispose() method
public void dispose()
{
GUIUtilities.saveGeometry(this,name);
jEdit.setIntegerProperty(name + ".splitter",splitter.getDividerLocation());
super.dispose();
} //}}}
//{{{ actionPerformed() method
public void actionPerformed(ActionEvent evt)
{
Object source = evt.getSource();
if(source == ok)
{
ok();
}
else if(source == cancel)
{
cancel();
}
else if(source == apply)
{
ok(false);
}
} //}}}
//{{{ valueChanged() method
public void valueChanged(TreeSelectionEvent evt)
{
TreePath path = evt.getPath();
if(path == null)
return;
Object lastPathComponent = path.getLastPathComponent();
if(!(lastPathComponent instanceof String
|| lastPathComponent instanceof OptionPane))
{
return;
}
Object[] nodes = path.getPath();
StringBuffer buf = new StringBuffer();
OptionPane optionPane = null;
int lastIdx = nodes.length - 1;
for (int i = paneTree.isRootVisible() ? 0 : 1;
i <= lastIdx; i++)
{
String label;
Object node = nodes[i];
if (node instanceof OptionPane)
{
optionPane = (OptionPane)node;
label = jEdit.getProperty("options."
+ optionPane.getName()
+ ".label");
}
else if (node instanceof OptionGroup)
{
label = ((OptionGroup)node).getLabel();
}
else if (node instanceof String)
{
label = jEdit.getProperty("options."
+ node + ".label");
optionPane = (OptionPane)deferredOptionPanes
.get((String)node);
if(optionPane == null)
{
String propName = "options." + node + ".code";
String code = jEdit.getProperty(propName);
if(code != null)
{
optionPane = (OptionPane)
BeanShell.eval(
jEdit.getActiveView(),
BeanShell.getNameSpace(),
code
);
if(optionPane != null)
{
deferredOptionPanes.put(
node,optionPane);
}
else
continue;
}
else
{
Log.log(Log.ERROR,this,propName
+ " not defined");
continue;
}
}
}
else
{
continue;
}
buf.append(label);
if (i != lastIdx)
buf.append(": ");
}
if(optionPane == null)
return;
setTitle(jEdit.getProperty("options.title-template",
new Object[] { jEdit.getProperty(this.name + ".title"),
buf.toString() }));
try
{
optionPane.init();
}
catch(Throwable t)
{
Log.log(Log.ERROR,this,"Error initializing options:");
Log.log(Log.ERROR,this,t);
}
if(currentPane != null)
stage.remove(currentPane.getComponent());
currentPane = optionPane;
stage.add(BorderLayout.CENTER,currentPane.getComponent());
stage.revalidate();
stage.repaint();
if(!isShowing())
addNotify();
updateSize();
currentPane = optionPane;
} //}}}
//{{{ Protected members
protected abstract OptionTreeModel createOptionTreeModel();
protected abstract OptionGroup getDefaultGroup();
//}}}
//{{{ Private members
//{{{ Instance variables
private String name;
private JSplitPane splitter;
private JTree paneTree;
private JPanel stage;
private JButton ok;
private JButton cancel;
private JButton apply;
private OptionPane currentPane;
private Map deferredOptionPanes;
//}}}
//{{{ init() method
private void init(String name, String pane)
{
this.name = name;
deferredOptionPanes = new HashMap();
JPanel content = new JPanel(new BorderLayout(12,12));
content.setBorder(new EmptyBorder(12,12,12,12));
setContentPane(content);
stage = new JPanel(new BorderLayout());
paneTree = new JTree(createOptionTreeModel());
paneTree.setVisibleRowCount(1);
paneTree.setCellRenderer(new PaneNameRenderer());
// looks bad with the OS X L&F, apparently...
if(!OperatingSystem.isMacOSLF())
paneTree.putClientProperty("JTree.lineStyle", "Angled");
paneTree.setShowsRootHandles(true);
paneTree.setRootVisible(false);
JScrollPane scroller = new JScrollPane(paneTree,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
splitter = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
scroller,stage);
content.add(splitter, BorderLayout.CENTER);
Box buttons = new Box(BoxLayout.X_AXIS);
buttons.add(Box.createGlue());
ok = new JButton(jEdit.getProperty("common.ok"));
ok.addActionListener(this);
buttons.add(ok);
buttons.add(Box.createHorizontalStrut(6));
getRootPane().setDefaultButton(ok);
cancel = new JButton(jEdit.getProperty("common.cancel"));
cancel.addActionListener(this);
buttons.add(cancel);
buttons.add(Box.createHorizontalStrut(6));
apply = new JButton(jEdit.getProperty("common.apply"));
apply.addActionListener(this);
buttons.add(apply);
buttons.add(Box.createGlue());
content.add(buttons, BorderLayout.SOUTH);
// register the Options dialog as a TreeSelectionListener.
// this is done before the initial selection to ensure that the
// first selected OptionPane is displayed on startup.
paneTree.getSelectionModel().addTreeSelectionListener(this);
OptionGroup rootNode = (OptionGroup)paneTree.getModel().getRoot();
for(int i = 0; i < rootNode.getMemberCount(); i++)
{
paneTree.expandPath(new TreePath(
new Object[] { rootNode, rootNode.getMember(i) }));
}
// returns false if no such pane exists; calling with null
// param selects first option pane found
if(!selectPane(rootNode,pane))
selectPane(rootNode,null);
splitter.setDividerLocation(paneTree.getPreferredSize().width
+ scroller.getVerticalScrollBar().getPreferredSize()
.width);
GUIUtilities.loadGeometry(this,name);
int dividerLocation = jEdit.getIntegerProperty(name + ".splitter",-1);
if(dividerLocation != -1)
splitter.setDividerLocation(dividerLocation);
// in case saved geometry is too small
updateSize();
setVisible(true);
} //}}}
//{{{ selectPane() method
private boolean selectPane(OptionGroup node, String name)
{
return selectPane(node,name,new ArrayList());
} //}}}
//{{{ selectPane() method
private boolean selectPane(OptionGroup node, String name, ArrayList path)
{
path.add(node);
Enumeration e = node.getMembers();
while(e.hasMoreElements())
{
Object obj = e.nextElement();
if(obj instanceof OptionGroup)
{
OptionGroup grp = (OptionGroup)obj;
if(grp.getName().equals(name))
{
path.add(grp);
path.add(grp.getMember(0));
TreePath treePath = new TreePath(
path.toArray());
paneTree.scrollPathToVisible(treePath);
paneTree.setSelectionPath(treePath);
return true;
}
else if(selectPane((OptionGroup)obj,name,path))
return true;
}
else if(obj instanceof OptionPane)
{
OptionPane pane = (OptionPane)obj;
if(pane.getName().equals(name)
|| name == null)
{
path.add(pane);
TreePath treePath = new TreePath(
path.toArray());
paneTree.scrollPathToVisible(treePath);
paneTree.setSelectionPath(treePath);
return true;
}
}
else if(obj instanceof String)
{
String pane = (String)obj;
if(pane.equals(name)
|| name == null)
{
path.add(pane);
TreePath treePath = new TreePath(
path.toArray());
paneTree.scrollPathToVisible(treePath);
paneTree.setSelectionPath(treePath);
return true;
}
}
}
path.remove(node);
return false;
} //}}}
//{{{ save() method
private void save(Object obj)
{
if(obj instanceof OptionGroup)
{
OptionGroup grp = (OptionGroup)obj;
Enumeration members = grp.getMembers();
while(members.hasMoreElements())
{
save(members.nextElement());
}
}
else if(obj instanceof OptionPane)
{
try
{
((OptionPane)obj).save();
}
catch(Throwable t)
{
Log.log(Log.ERROR,this,"Error saving options:");
Log.log(Log.ERROR,this,t);
}
}
else if(obj instanceof String)
{
save(deferredOptionPanes.get(obj));
}
} //}}}
//{{{ updateSize() method
private void updateSize()
{
Dimension currentSize = getSize();
Dimension requestedSize = getPreferredSize();
Dimension newSize = new Dimension(
Math.max(currentSize.width,requestedSize.width),
Math.max(currentSize.height,requestedSize.height)
);
if(newSize.width < 300)
newSize.width = 300;
if(newSize.height < 200)
newSize.height = 200;
setSize(newSize);
validate();
} //}}}
//}}}
//{{{ PaneNameRenderer class
class PaneNameRenderer extends DefaultTreeCellRenderer
{
public PaneNameRenderer()
{
paneFont = UIManager.getFont("Tree.font");
if(paneFont == null)
paneFont = jEdit.getFontProperty("metal.secondary.font");
groupFont = paneFont.deriveFont(Font.BOLD);
}
public Component getTreeCellRendererComponent(JTree tree,
Object value, boolean selected, boolean expanded,
boolean leaf, int row, boolean hasFocus)
{
super.getTreeCellRendererComponent(tree,value,
selected,expanded,leaf,row,hasFocus);
String name = null;
if (value instanceof OptionGroup)
{
setText(((OptionGroup)value).getLabel());
this.setFont(groupFont);
}
else if (value instanceof OptionPane)
{
name = ((OptionPane)value).getName();
this.setFont(paneFont);
}
else if (value instanceof String)
{
name = ((String)value);
this.setFont(paneFont);
}
if (name != null)
{
String label = jEdit.getProperty("options." +
name + ".label");
if (label == null)
{
setText("NO LABEL PROPERTY: " + name);
}
else
{
setText(label);
}
}
setIcon(null);
return this;
}
private Font paneFont;
private Font groupFont;
} //}}}
//{{{ OptionTreeModel class
public class OptionTreeModel implements TreeModel
{
public void addTreeModelListener(TreeModelListener l)
{
listenerList.add(TreeModelListener.class, l);
}
public void removeTreeModelListener(TreeModelListener l)
{
listenerList.remove(TreeModelListener.class, l);
}
public Object getChild(Object parent, int index)
{
if (parent instanceof OptionGroup)
{
return ((OptionGroup)parent).getMember(index);
}
else
{
return null;
}
}
public int getChildCount(Object parent)
{
if (parent instanceof OptionGroup)
{
return ((OptionGroup)parent).getMemberCount();
}
else
{
return 0;
}
}
public int getIndexOfChild(Object parent, Object child)
{
if (parent instanceof OptionGroup)
{
return ((OptionGroup)parent)
.getMemberIndex(child);
}
else
{
return -1;
}
}
public Object getRoot()
{
return root;
}
public boolean isLeaf(Object node)
{
return !(node instanceof OptionGroup);
}
public void valueForPathChanged(TreePath path, Object newValue)
{
// this model may not be changed by the TableCellEditor
}
protected void fireNodesChanged(Object source, Object[] path,
int[] childIndices, Object[] children)
{
Object[] listeners = listenerList.getListenerList();
TreeModelEvent modelEvent = null;
for (int i = listeners.length - 2; i >= 0; i -= 2)
{
if (listeners[i] != TreeModelListener.class)
continue;
if (modelEvent == null)
{
modelEvent = new TreeModelEvent(source,
path, childIndices, children);
}
((TreeModelListener)listeners[i + 1])
.treeNodesChanged(modelEvent);
}
}
protected void fireNodesInserted(Object source, Object[] path,
int[] childIndices, Object[] children)
{
Object[] listeners = listenerList.getListenerList();
TreeModelEvent modelEvent = null;
for (int i = listeners.length - 2; i >= 0; i -= 2)
{
if (listeners[i] != TreeModelListener.class)
continue;
if (modelEvent == null)
{
modelEvent = new TreeModelEvent(source,
path, childIndices, children);
}
((TreeModelListener)listeners[i + 1])
.treeNodesInserted(modelEvent);
}
}
protected void fireNodesRemoved(Object source, Object[] path,
int[] childIndices, Object[] children)
{
Object[] listeners = listenerList.getListenerList();
TreeModelEvent modelEvent = null;
for (int i = listeners.length - 2; i >= 0; i -= 2)
{
if (listeners[i] != TreeModelListener.class)
continue;
if (modelEvent == null)
{
modelEvent = new TreeModelEvent(source,
path, childIndices, children);
}
((TreeModelListener)listeners[i + 1])
.treeNodesRemoved(modelEvent);
}
}
protected void fireTreeStructureChanged(Object source,
Object[] path, int[] childIndices, Object[] children)
{
Object[] listeners = listenerList.getListenerList();
TreeModelEvent modelEvent = null;
for (int i = listeners.length - 2; i >= 0; i -= 2)
{
if (listeners[i] != TreeModelListener.class)
continue;
if (modelEvent == null)
{
modelEvent = new TreeModelEvent(source,
path, childIndices, children);
}
((TreeModelListener)listeners[i + 1])
.treeStructureChanged(modelEvent);
}
}
private OptionGroup root = new OptionGroup(null);
private EventListenerList listenerList = new EventListenerList();
} //}}}
}
|
| ... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.