public class GroovySwingLogger extends JFrame { private DefaultTreeModel treeModel = null; private DefaultSwingScriptLogger logger = null; private final Map<TreeElement, TreeElement> elements = new HashMap<>(); private final Map<TreeElement, DefaultMutableTreeNode> elementToNode = new HashMap<>(); private JTree tree = null; public GroovySwingLogger() { super("Groovy SwingLogger"); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setup(); } private void setup() { JMenuBar mbar = new JMenuBar(); this.setJMenuBar(mbar); JMenu fileMenu = new JMenu("File"); mbar.add(fileMenu); AbstractAction exitAction = new AbstractAction("Exit") { @Override public void actionPerformed(ActionEvent e) { System.exit(0); } }; fileMenu.add(exitAction); createContent(); } private void populateTree(DefaultMutableTreeNode root) { TreeElement element = new TreeElement("http:/my.site", "element1"); elements.put(element, element); DefaultMutableTreeNode node = new DefaultMutableTreeNode(element); root.add(node); elementToNode.put(element, node); element = new TreeElement("http:/mysite", "element2"); elements.put(element, element); node = new DefaultMutableTreeNode(element); root.add(node); elementToNode.put(element, node); element = new TreeElement("http:/mysite2", "element3"); elements.put(element, element); node = new DefaultMutableTreeNode(element); root.add(node); elementToNode.put(element, node); } private void createContent() { Container pane = this.getContentPane(); pane.setLayout(new BorderLayout()); DefaultMutableTreeNode root = new DefaultMutableTreeNode("root"); populateTree(root); treeModel = new DefaultTreeModel(root); tree = new JTree(treeModel); tree.setBorder(BorderFactory.createEmptyBorder(5, 5, 10, 10)); pane.add(tree, BorderLayout.CENTER); } public static void main(String[] args) { GroovySwingLogger groovyTest = new GroovySwingLogger(); groovyTest.pack(); groovyTest.setVisible(true); } }The
TreeElement
class which is used in the tree maintains a namespace
and a name
and has the following code:public class TreeElement { public final String namespace; public final String name; public TreeElement(String namespace, String name) { this.namespace = namespace; this.name = name; } @Override public String toString() { return namespace + ":" + name; } @Override public int hashCode() { int hash = 7; hash = 79 * hash + Objects.hashCode(this.namespace); hash = 79 * hash + Objects.hashCode(this.name); return hash; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final TreeElement other = (TreeElement) obj; return true; } }We have the following GUI:
public interface Script { public void process(TreeElement element); }
public class GroovySwingLogger extends JFrame { private ScriptWrapper<Script> wrapper = null; private DefaultTreeModel treeModel = null; private final Map<TreeElement, TreeElement> elements = new HashMap<>(); private final Map<TreeElement, DefaultMutableTreeNode> elementToNode = new HashMap<>(); private JTree tree = null; public GroovySwingLogger() { super("Groovy SwingLogger"); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setup(); } private void setup() { JMenuBar mbar = new JMenuBar(); this.setJMenuBar(mbar); JMenu fileMenu = new JMenu("File"); mbar.add(fileMenu); AbstractAction openAction = new AbstractAction("Open Script") { @Override public void actionPerformed(ActionEvent e) { createScriptObject(); } }; fileMenu.add(openAction); AbstractAction exitAction = new AbstractAction("Exit") { @Override public void actionPerformed(ActionEvent e) { System.exit(0); } }; fileMenu.add(exitAction); createContent(); } private void populateTree(DefaultMutableTreeNode root) { ... } private void createContent() { ... } public static void main(String[] args) { GroovySwingLogger groovyTest = new GroovySwingLogger(); groovyTest.pack(); groovyTest.setVisible(true); } private boolean createScriptObject() { ... } private File openScript() { JFileChooser chooser = new JFileChooser("Open Script"); chooser.setCurrentDirectory(new File(System.getProperty("user.dir"))); chooser.setDialogType(JFileChooser.OPEN_DIALOG); chooser.setFileSelectionMode(JFileChooser.FILES_ONLY); int ret = chooser.showOpenDialog(null); if (ret == JFileChooser.APPROVE_OPTION) { return chooser.getSelectedFile(); } else { return null; } } }
private boolean createScriptObject() { File file = openScript(); // there is nothing specific in this code if (file == null) { return false; } // we create the groovy script wrapper with our script interface wrapper = new GroovyScriptWrapper<Script>() { }; wrapper.logExceptions(true); SwingExceptionListener listener = new SwingExceptionListener(); listener.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); wrapper.installScript(file); executeScript(); return true; } private File openScript() { JFileChooser chooser = new JFileChooser("Open Script"); chooser.setCurrentDirectory(new File(System.getProperty("user.dir"))); chooser.setDialogType(JFileChooser.OPEN_DIALOG); chooser.setFileSelectionMode(JFileChooser.FILES_ONLY); int ret = chooser.showOpenDialog(null); if (ret == JFileChooser.APPROVE_OPTION) { return chooser.getSelectedFile(); } else { return null; } } private void executeScript() { ... }But for the logger to be visible, we must add it explictly:
public class GroovySwingLogger extends JFrame { private DefaultSwingScriptLogger logger = null; private boolean createScriptObject() { File file = openScript(); // there is nothing specific in this code if (file == null) { return false; } // we create the groovy script wrapper with our script interface wrapper = new GroovyScriptWrapper<Script>() { }; wrapper.logExceptions(true); logger = new DefaultSwingScriptLogger(); wrapper.setScriptLogger(logger); SwingExceptionListener listener = new SwingExceptionListener(); listener.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); wrapper.installScript(file); executeScript(); return true; } }And now we will code the script execution: we will iterate on all the
TreeElement
s in our tree:private void executeScript() { logger.setVisible(true); // we must make the logger area visible at the start of the script Script script = wrapper.getScript(); Iterator<TreeElement> it = elements.values().iterator(); while (it.hasNext()) { TreeElement element = it.next(); script.process(element); } }Also we need to import the
TreeElement
classpath in our script:private boolean createScriptObject() { File file = openScript(); // there is nothing specific in this code if (file == null) { return false; } // we create the groovy script wrapper with our script interface wrapper = new GroovyScriptWrapper<Script>() { }; wrapper.logExceptions(true); logger = new DefaultSwingScriptLogger(); wrapper.setScriptLogger(logger); SwingExceptionListener listener = new SwingExceptionListener(); wrapper.addImports(TreeElement.class); listener.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); wrapper.installScript(file); executeScript(); return true; }
public void process(TreeElement element) { logger.append(element.toString()); }We have the following result:
namespace
and the name
of the TreeElement
to convert to and from a link ID:public class GroovySwingLogger extends JFrame implements LinkIndexConverter<TreeElement> { private boolean createScriptObject() { File file = openScript(); // there is nothing specific in this code if (file == null) { return false; } // we create the groovy script wrapper with our script interface wrapper = new GroovyScriptWrapper<Script>() { }; wrapper.logExceptions(true); logger = new DefaultSwingScriptLogger(); logger.registerLinkIndexConverter(this); wrapper.setScriptLogger(logger); SwingExceptionListener listener = new SwingExceptionListener(); wrapper.addImports(TreeElement.class); listener.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); wrapper.installScript(file); executeScript(); return true; } @Override public String getLinkFromObject(TreeElement element) { return element.namespace + "$" + element.name; } @Override public TreeElement getObjectFromLink(String linkID) { int index = linkID.indexOf("$"); if (index != -1) { String namespace = linkID.substring(0, index); String name = linkID.substring(index + 1); TreeElement key = new TreeElement(namespace, name); if (elements.containsKey(key)) { return elements.get(key); } else { return null; } } else { return null; } } }
public class GroovySwingLogger extends JFrame implements LinkIndexConverter<TreeElement>, ScriptLoggerHyperLinkListener<TreeElement> { private boolean createScriptObject() { File file = openScript(); // there is nothing specific in this code if (file == null) { return false; } // we create the groovy script wrapper with our script interface wrapper = new GroovyScriptWrapper<Script>() { }; wrapper.logExceptions(true); logger = new DefaultSwingScriptLogger(); logger.registerLinkIndexConverter(this); logger.registerHyperLinkListener(this); wrapper.setScriptLogger(logger); SwingExceptionListener listener = new SwingExceptionListener(); wrapper.addImports(TreeElement.class); listener.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); wrapper.installScript(file); executeScript(); return true; } } @Override public void visitHyperLink(TreeElement element) { if (elements.containsKey(element)) { DefaultMutableTreeNode node = elementToNode.get(element); TreePath path = new TreePath(node.getPath()); tree.setSelectionPath(path); } }
public void process(TreeElement element) { HyperlinkElement linkElt = new HyperlinkElement(element.name, element); logger.appendObjectLink(linkElt); }We have the following result:
public void process(TreeElement element) { HyperlinkElement linkElt = new HyperlinkElement(element.name, element); logger.appendObjectLinks("The element is %1", linkElt); }We have the following result:
Copyright 2019-2020 Herve Girod. All Rights Reserved. Documentation and source under the BSD licence