Log in Help
Print
Homereleasesgate-8.4-build5748-ALLpluginsGroovysrcgategroovygui 〉 ScriptPREditor.java
 
/*
 * ScriptPREditor
 * 
 * Copyright (c) 2011, The University of Sheffield.
 * 
 * This file is part of GATE (see http://gate.ac.uk/), and is free software,
 * licenced under the GNU Library General Public License, Version 3, June 2007
 * (in the distribution as file licence.html, and also available at
 * http://gate.ac.uk/gate/licence.html).
 * 
 * Mark A. Greenwood, 20/05/2011
 */
package gate.groovy.gui;

import gate.Resource;
import gate.creole.AbstractVisualResource;
import gate.creole.metadata.CreoleResource;
import gate.creole.metadata.GuiType;
import gate.event.ProgressListener;
import gate.groovy.ScriptPR;
import gate.gui.MainFrame;
import gate.util.Files;
import gate.util.GateRuntimeException;
import groovy.ui.ConsoleTextEditor;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileWriter;

import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

/**
 * A VR for viewing and editing the script behind a Groovy Scripting PR
 * 
 * @author Mark A. Greenwood
 */
@CreoleResource(name = "Script Editor", comment = "Editor for the Groovy script behind this PR", guiType = GuiType.LARGE, mainViewer = true, resourceDisplayed = "gate.groovy.ScriptPR")
public class ScriptPREditor extends AbstractVisualResource implements
                                                          ProgressListener,
                                                          DocumentListener {

  private static final long serialVersionUID = -3397858340190887863L;

  private ConsoleTextEditor editor;

  private ScriptPR pr;

  private File file;

  private JButton btnSave, btnRevert;

  public Resource init() {
    initGuiComponents();

    return this;
  }

  protected void initGuiComponents() {
    setLayout(new BorderLayout());

    // create a Groovy source code editor, register to listen for changes to the
    // source code and then add it as the main component of the VR
    editor = new ConsoleTextEditor();
    editor.getTextEditor().getDocument().addDocumentListener(this);
    add(editor, BorderLayout.CENTER);

    // create the "Save and Reinitialize" button
    btnSave =
            new JButton("Save and Reinitialize",
                    MainFrame.getIcon("crystal-clear-app-download-manager"));
    btnSave.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent e) {
        try {
          // when the save button is clicked write the contents of the editor
          // out into the script file the PR is backed by and then...
          FileWriter out = new FileWriter(file);
          out.write(editor.getTextEditor().getText());
          out.flush();
          out.close();

          // re-init the PR so the script is reloaded
          pr.reInit();

          // we have reloaded so there won't be any changes that can be
          // saved/reverted so disable the buttons
          btnRevert.setEnabled(false);
          btnSave.setEnabled(false);
        } catch(Exception ioe) {
          ioe.printStackTrace();
        }
      }
    });

    // create the "Revert Changes" button
    btnRevert =
            new JButton("Revert Changes",
                    MainFrame.getIcon("crystal-clear-action-reload"));
    btnRevert.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        // when the button is clicked just set the source back to that storred
        // in the PR instance
        editor.getTextEditor().setText(pr.getGroovySrc());

        // we have reverted so there won't be any changes that can be
        // saved/reverted so disable the buttons
        btnRevert.setEnabled(false);
        btnSave.setEnabled(false);
      }
    });

    // add both buttons to a toolbar at the top of the VR
    JToolBar toolbar = new JToolBar(JToolBar.HORIZONTAL);
    toolbar.setFloatable(false);
    toolbar.add(btnSave);
    toolbar.add(Box.createHorizontalStrut(5));
    toolbar.add(btnRevert);
    add(toolbar, BorderLayout.NORTH);
  }

  public void setTarget(Object target) {

    // make sure we are being given a target that we know how to display
    if(target == null) return;
    if(!(target instanceof ScriptPR)) { throw new GateRuntimeException(this
            .getClass().getName()
            + " can only be used to display "
            + ScriptPR.class.getName()
            + "\n"
            + target.getClass().getName()
            + " is not a " + ScriptPR.class.getName() + "!"); }

    // if this VR is being reused then stop listening to changes from the
    // previous target
    if(pr != null) {
      pr.removeProgressListener(this);
    }

    // store the PR we are displaying so we can keep refering to it
    pr = (ScriptPR)target;

    // get the script file or null if loaded from a non-file url
    try {
      file = Files.fileFromURL(pr.getScriptURL());
    } catch(Exception e) {
      file = null;
    }

    // get the editor to display the script
    editor.getTextEditor().setText(pr.getGroovySrc());

    // disable editing if we loaded from a URL
    editor.getTextEditor().setEditable(file != null);
    btnSave.setEnabled(false);
    btnRevert.setEnabled(false);

    // listen out for updates to the PR so we can keep in sync
    pr.addProgressListener(this);
  }

  public void progressChanged(int i) {
    // do nothing and wait until the progress has finished
  }

  public void processFinished() {
    SwingUtilities.invokeLater(new Thread() {
      public void run() {
        setTarget(pr);
      }
    });    
  }

  public void changedUpdate(DocumentEvent e) {
    // ignore these events
  }

  public void insertUpdate(DocumentEvent e) {
    // the script has changed so enable the toolbar buttons
    btnRevert.setEnabled(true);
    btnSave.setEnabled(file != null);
  }

  public void removeUpdate(DocumentEvent e) {
    // the script has changed so enable the toolbar buttons
    btnRevert.setEnabled(true);
    btnSave.setEnabled(file != null);
  }
}