|
What this is
Other links
The source code
/*
* 08/15/2001 - 14:05:44
*
* XTree.java - A tree used for XInsert system
* Copyright (C) 1999-2000 Romain Guy
* Portion copyright (C) 2000 Richard Lowe
* romain.guy@jext.org
* http://www.jext.org
*
* 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.jext.xinsert;
import java.io.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.tree.*;
import javax.swing.event.*;
import javax.swing.text.Document;
import javax.swing.text.BadLocationException;
import org.jext.*;
import org.jext.dawn.*;
import org.jext.event.*;
import org.jext.scripting.dawn.Run;
import org.jext.gui.JextCheckBox;
import org.jext.gui.JextHighlightButton;
import org.jext.misc.Indent;
import org.jext.xml.XInsertReader;
public class XTree extends JPanel implements TreeSelectionListener, ActionListener, Runnable,
JextListener
{
private static Vector inserts;
private String file, currentMode;
private JTree tree;
private JextFrame parent;
/**
* This contains the complete content of the files. It's never associated to the JTree:
* associateXTreeToMode reads it and chooses the right nodes.
* @see associateXTreeToMode
*/
private DefaultTreeModel treeModel;
private JextHighlightButton expand, collapse, reload;
private JextCheckBox carriageReturn, executeScript, textSurrounding;
// nested submenus
private int rootIndex;
private XTreeNode root;
private Stack menuStack = null;
private XTreeObject xtreeObj = null;
public void addMenu(String nodeName, String modes)
{
xtreeObj = new XTreeObject(new XTreeNode(nodeName, modes), 0);
if (menuStack.empty())
{
treeModel.insertNodeInto(xtreeObj.getXTreeNode(), root, rootIndex);
rootIndex++;
} else {
XTreeObject obj = (XTreeObject) menuStack.peek();
treeModel.insertNodeInto(xtreeObj.getXTreeNode(), obj.getXTreeNode(), obj.getIndex());
obj.incrementIndex();
}
menuStack.push(xtreeObj);
}
public void closeMenu()
{
try
{
xtreeObj = (XTreeObject) menuStack.pop();
} catch (Exception e) {
xtreeObj = null;
}
}
public void addInsert(String nodeName, String content, int type)
{
inserts.addElement(new XTreeItem(content, type));
XTreeNode node = new XTreeNode(nodeName, null, inserts.size());
if (xtreeObj == null)
{
treeModel.insertNodeInto(node, root, rootIndex);
++rootIndex;
} else {
XTreeObject obj = (XTreeObject) menuStack.peek();
treeModel.insertNodeInto(node, obj.getXTreeNode(), obj.getIndex());
obj.incrementIndex();
}
}
public XTree(JextFrame parent, String file)
{
super();
this.parent = parent;
parent.addJextListener(this);
setLayout(new BorderLayout());
root = new XTreeNode("XInsert");
treeModel = new DefaultTreeModel(root);
tree = new JTree(treeModel);
tree.addTreeSelectionListener(this);
tree.putClientProperty("JTree.lineStyle", "Angled");
if (!Jext.getBooleanProperty("useSkin"))
tree.setCellRenderer(new XTreeCellRenderer());
init(file);
String icons = Jext.getProperty("jext.look.icons");
JToolBar pane = new JToolBar();//new BorderLayout());
pane.setFloatable(false);
pane.add(collapse = new JextHighlightButton(Jext.getProperty("xtree.collapse.button"),
Utilities.getIcon("images/button_collapse" + icons + ".gif", Jext.class)));//,
//BorderLayout.NORTH);
collapse.setMnemonic(Jext.getProperty("xtree.collapse.mnemonic").charAt(0));
collapse.addActionListener(this);
pane.add(expand = new JextHighlightButton(Jext.getProperty("xtree.expand.button"),
Utilities.getIcon("images/button_expand" + icons + ".gif", Jext.class)));//,
//BorderLayout.CENTER);
expand.setMnemonic(Jext.getProperty("xtree.expand.mnemonic").charAt(0));
expand.addActionListener(this);
pane.add(reload = new JextHighlightButton(Jext.getProperty("xtree.reload.button"),
Utilities.getIcon("images/menu_reload" + icons + ".gif", Jext.class)));//,
//BorderLayout.SOUTH);
reload.setMnemonic(Jext.getProperty("xtree.reload.mnemonic").charAt(0));
reload.addActionListener(this);
add(pane, BorderLayout.NORTH);
JScrollPane s = new JScrollPane(tree);
s.setBorder(null);
add(s, BorderLayout.CENTER);
JPanel optionPane = new JPanel(new BorderLayout());
optionPane.add(carriageReturn = new JextCheckBox(Jext.getProperty("xtree.carriage.label")), BorderLayout.NORTH);
carriageReturn.setSelected(Jext.getBooleanProperty("carriage"));
carriageReturn.addActionListener(this);
optionPane.add(executeScript = new JextCheckBox(Jext.getProperty("xtree.execute.label")), BorderLayout.CENTER);
executeScript.setSelected(Jext.getBooleanProperty("execute"));
if (Jext.getProperty("execute") == null)
executeScript.setSelected(true);
executeScript.addActionListener(this);
optionPane.add(textSurrounding = new JextCheckBox(Jext.getProperty("xtree.surrounding.label")), BorderLayout.SOUTH);
textSurrounding.setSelected(Jext.getBooleanProperty("surrounding"));
if (Jext.getProperty("surrounding") == null)
textSurrounding.setSelected(true);
textSurrounding.addActionListener(this);
add(optionPane, BorderLayout.SOUTH);
}
private void init(String file)
{
init(file, true);
}
private void init(String file, boolean useThread)
{
this.file = file;
if (useThread)
{
Thread x = new Thread(this, "--XTree builder thread");
x.start();
} else
run();
}
public void stop() { }
//this loads the main file, while loadLocalFiles thinks to local files.
public void run()
{
inserts = new Vector(200);
menuStack = new Stack();
rootIndex = 0;
if (XInsertReader.read(this, Jext.class.getResourceAsStream(file), file)) {
loadLocalFiles();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
associateXTreeToMode(false);
tree.expandRow(0);
tree.setRootVisible(false);
tree.setShowsRootHandles(true);
file = null;
}
});
}
}
private void loadLocalFiles()
{
String dir = Jext.SETTINGS_DIRECTORY + "xinsert" + File.separator;
String inserts[] = Utilities.getWildCardMatches(dir, "*.insert.xml", false);
if (inserts == null)
return;
try
{
String fileName;
for (int i = 0; i < inserts.length; i++)
{
fileName = dir + inserts[i];
if (XInsertReader.read(this, new FileInputStream(fileName), fileName))
{
String[] args = { inserts[i] };
System.out.println(Jext.getProperty("xtree.loaded", args));
}
}
} catch (FileNotFoundException fnfe) { }
}
public void jextEventFired(JextEvent evt)
{
int what = evt.getWhat();
if (what == JextEvent.SYNTAX_MODE_CHANGED || what == JextEvent.TEXT_AREA_SELECTED ||
what == JextEvent.OPENING_WINDOW)
{
associateXTreeToMode();
}
}
private void associateXTreeToMode()
{
associateXTreeToMode(true);
}
/**
* This method builds a copy of treeModel containing only nodes relevant to current
* mode, and then uses the new TreeModel for the tree.
* Must be called by the event-dispatching thread!
*/
private void associateXTreeToMode(boolean checkColorizingMode)
{
JextTextArea textArea = parent.getTextArea();
if (textArea == null)
return;
String mode = textArea.getColorizingMode();
//if we must reload(at user's request or when loading is finished), we do this even when
//mode has not changed.
if (checkColorizingMode && mode.equals(currentMode))
return;
int index = 0;
XTreeNode _root = new XTreeNode("XInsert");
DefaultTreeModel _model = new DefaultTreeModel(_root);
for (int i = 0; i < root.getChildCount(); i++)
{
XTreeNode child = (XTreeNode) root.getChildAt(i);
if (child.isAssociatedToMode(mode))
{
child.setParent(null);
if (child.isPermanent())
_root.add(child);
else
{
if (child.toString().equalsIgnoreCase(mode))
_root.insert(child, 0);
else
_root.insert(child, index);
index++;
}
}
}
tree.setModel(_model); //so we need to be in the event-dispatching thread.
tree.expandRow(0);
currentMode = mode;
}
public void valueChanged(TreeSelectionEvent tse)
{
JTree source = (JTree) tse.getSource();
if (source.isSelectionEmpty())
return;
XTreeNode node = (XTreeNode) source.getSelectionPath().getLastPathComponent();
if (node.getIndex() == -1)
{
parent.getTextArea().grabFocus();
return;
}
try
{
insert(node.getIndex() - 1);
} catch (Exception e) { }
source.setSelectionPath(source.getPathForRow(-1));
}
public void reload(DefaultTreeModel model)
{
// tree.setModel(model);
this.treeModel = model;
}
public void actionPerformed(ActionEvent evt)
{
Object o = evt.getSource();
if (o == expand)
{
for (int i = 0; i < tree.getRowCount(); i++)
tree.expandRow(i);
} else if (o == collapse) {
for (int i = tree.getRowCount(); i >= 0; i--)
tree.collapseRow(i);
} else if (o == reload) {
root.removeAllChildren();
treeModel.reload();
init("jext.insert.xml", false);
associateXTreeToMode(false);
ArrayList instances = Jext.getInstances();
for (int i = 0; i < instances.size(); i++)
{
JextFrame instance = (JextFrame) instances.get(i);
if (instance != parent)
{
instance.getXTree().reload(treeModel);
instance.getXTree().associateXTreeToMode(false);
}
}
} else if (o == carriageReturn)
Jext.setProperty("carriage", carriageReturn.isSelected() ? "on" : "off");
else if (o == executeScript)
Jext.setProperty("execute", executeScript.isSelected() ? "on" : "off");
else if (o == textSurrounding)
Jext.setProperty("surrounding", textSurrounding.isSelected() ? "on" : "off");
}
private void insert(int index) throws BadLocationException
{
char c = '\0';
XTreeItem item = (XTreeItem) inserts.elementAt(index);
String data = item.getContent();
boolean script = item.isScript();
boolean mixed = item.isMixed();
StringBuffer _buf = new StringBuffer(data.length());
for (int i = 0; i < data.length(); i++)
{
if( (c = data.charAt(i)) == '\\' && i < data.length() - 1)
{
switch (data.charAt(i + 1))
{
case 'n':
i++;
_buf.append('\n');
break;
case 't':
i++;
_buf.append('\t');
break;
case '\\':
i++;
_buf.append('\\');
break;
}
} else
_buf.append(c);
}
data = _buf.toString();
JextTextArea textArea = parent.getTextArea();
if (script && executeScript.isSelected())
{
Run.execute(data, parent);
} else {
textArea.beginProtectedCompoundEdit();
boolean indent = textArea.getEnterIndent();
Document doc = textArea.getDocument();
String surroundText = "";
if (textArea.getSelectionStart() != textArea.getSelectionEnd())
{
surroundText = textArea.getSelectedText();
textArea.setSelectedText("");
}
_buf = new StringBuffer(data.length());
int caretState = 0;
int insertPos = 0;
int lastBreak = -1;
int wordStart = textArea.getCaretPosition();
int caret = data.length();
StringBuffer mixedScript = new StringBuffer(30);
boolean parsing = false;
boolean onFirstLine = true, wasFirstLine = false;
out: for (int i = 0 ; i < data.length(); i++)
{
switch (c = data.charAt(i))
{
case '|':
if (parsing)
mixedScript.append('|');
else
{
if (i < data.length() - 1 && data.charAt(i + 1) == '|')
{
i++;
_buf.append('|');
} else {
if (caretState == 0)
{
caret = insertPos + _buf.length();
caretState = 1;
if (onFirstLine)
wasFirstLine = true;
}
}
}
break;
case '\n':
if (parsing)
{
mixedScript.append('\n');
break;
}
if (indent && !onFirstLine)
{
doc.insertString(wordStart + insertPos, _buf.toString(), null);
insertPos += _buf.length();
_buf = new StringBuffer(data.length() - _buf.length());
int tempLen = doc.getLength();
Indent.indent(textArea, textArea.getCaretLine(), true, true);
int indentLen = doc.getLength() - tempLen;
if (caretState == 1)
{
if (!wasFirstLine)
caret += indentLen;
caretState = 2;
}
insertPos += indentLen;
wasFirstLine = false;
}
_buf.append('\n');
onFirstLine = false;
lastBreak = i;
break;
case '%':
if (mixed)
{
if (i < data.length() - 1 && data.charAt(i + 1) == '%')
{
i++;
(parsing ? mixedScript : _buf).append('%');
} else if (parsing) {
parsing = false;
try
{
if (!DawnParser.isInitialized())
{
DawnParser.init();
DawnParser.installPackage(Jext.class, "dawn-jext.scripting");
}
DawnParser parser = new DawnParser(new StringReader(mixedScript.toString()));
parser.setProperty("JEXT.JEXT_FRAME", parent);
parser.exec();
if (!parser.getStack().isEmpty())
_buf.append(parser.popString());
} catch (DawnRuntimeException dre) {
JOptionPane.showMessageDialog(parent, dre.getMessage(),
Jext.getProperty("dawn.script.error"),
JOptionPane.ERROR_MESSAGE);
}
mixedScript = new StringBuffer(30);
} else {
parsing = true;
}
break;
}
default:
(parsing ? mixedScript : _buf).append(c);
}
}
doc.insertString(wordStart + insertPos, _buf.toString(), null);
if (!onFirstLine)
{
int tempLen = doc.getLength();
Indent.indent(textArea, textArea.getCaretLine(), true, true);
if (lastBreak < caret && caretState <= 1)
caret += doc.getLength() - tempLen;
}
int caretPos = wordStart + caret;
int tempLen = doc.getLength();
if (caretPos > tempLen)
caretPos = tempLen;
if (surroundText.length() > 0 && textSurrounding.isSelected())
doc.insertString(caretPos, surroundText, null);
textArea.setCaretPosition(caretPos);
textArea.endProtectedCompoundEdit();
}
textArea.grabFocus();
}
private static final ImageIcon[] leaves =
{
Utilities.getIcon("images/tree_leaf.gif", Jext.class),
Utilities.getIcon("images/tree_leaf_script.gif", Jext.class),
Utilities.getIcon("images/tree_leaf_mixed.gif", Jext.class)
};
class XTreeCellRenderer extends DefaultTreeCellRenderer
{
XTreeCellRenderer()
{
super();
openIcon = Utilities.getIcon("images/tree_open.gif", Jext.class);
closedIcon = Utilities.getIcon("images/tree_close.gif", Jext.class);
textSelectionColor = Color.red;
borderSelectionColor = tree.getBackground();
backgroundSelectionColor = tree.getBackground();
}
public Component getTreeCellRendererComponent(JTree source, Object value, boolean sel,
boolean expanded, boolean leaf, int row,
boolean hasFocus)
{
if (leaf)
{
TreePath path = source.getPathForRow(row);
if (path != null)
{
XTreeNode node = (XTreeNode) path.getLastPathComponent();
int index = node.getIndex();
if (index != -1)
{
leafIcon = leaves[((XTreeItem) inserts.elementAt(index - 1)).getType()];
}
}
}
return super.getTreeCellRendererComponent(source, value, sel, expanded, leaf, row, hasFocus);
}
}
}
// End of XTree.java
|
| ... 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.