Package de.tuhrig.thofu.gui

Source Code of de.tuhrig.thofu.gui.ThoFuUi

package de.tuhrig.thofu.gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.util.Locale;

import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JSeparator;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
import javax.swing.event.MenuEvent;
import javax.swing.event.MenuListener;

import org.apache.log4j.Logger;
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
import org.jdesktop.swingx.JXMultiSplitPane;
import org.jdesktop.swingx.MultiSplitLayout;

import de.tuhrig.thofu.Interpreter;
import de.tuhrig.thofu.Util;
import de.tuhrig.thofu.interfaces.IDebugger;
import de.tuhrig.thofu.interfaces.IInterpreter;
import de.tuhrig.thofu.parser.DefaultParser;
import de.tuhrig.thofu.parser.ProceduralParser;

/**
* The GUI.
*
* @author Thomas Uhrig (tuhrig.de)
*/
public class ThoFuUi extends JFrame {

  static ThoFuUi gui;    // not private because of unit tests that set this value
 
  public static ThoFuUi instance() {
   
    if(gui == null)
      gui = new ThoFuUi();
   
    return gui;
  }
 
  private static final long serialVersionUID = 1L;

  private static Logger logger = Logger.getLogger(ThoFuUi.class);

  private final Repl repl = new Repl();

  private final Inspector inspector = new Inspector();

  private final Editor editor = new Editor();

  private final Status status = new Status();

  private final static Running running = new Running();
 
  private final static HistoryView history = new HistoryView();
 
  private final static Debugger debugger = new Debugger();
 
  private final JFileChooser fc = new JFileChooser();

  private boolean grubby = true;

  private JMenuItem start;

  private JMenuItem reset;

  private IInterpreter interpreter;

  private ThoFuUi() {

    // Create the components of the GUI
    final FileBrowser browser = new FileBrowser();
    final Log log = new Log();
   
    // editor area (middle)
    JSplitPane editorArea = new JSplitPane(JSplitPane.VERTICAL_SPLIT, this.editor, this.repl);
    editorArea.setOneTouchExpandable(true);
    editorArea.setName("Editor area");

    // main area
    JPanel inner = new JPanel();
    inner.setLayout(new BorderLayout(3, 3));
    inner.setBorder(new EmptyBorder(5, 5, 5, 5));
    inner.add(editorArea);

    // tools (right)
    JTabbedPane tools = new JTabbedPane();
    tools.addTab("Debugger", SwingFactory.create("icons/Appointment Urgent.png", 24, 24), debugger);
    tools.addTab("Inspector", SwingFactory.create("icons/inspect.png", 24, 24), inspector);
    tools.addTab("History", SwingFactory.create("icons/tree.png", 24, 24), history);
   
    // multi split pane
    JXMultiSplitPane msp = new JXMultiSplitPane();

    String layoutDef =
        "(COLUMN " +
            "(ROW weight=0.8" +
              "(LEAF name=left.top weight=0.25) " +
              "(LEAF name=left.middle weight=0.5)" +
              "(LEAF name=editor weight=0.25))" +
            "(LEAF name=bottom weight=0.2))";

    MultiSplitLayout.Node modelRoot = MultiSplitLayout.parseModel(layoutDef);
    msp.getMultiSplitLayout().setModel(modelRoot);
   
    msp.add(browser, "left.top");
    msp.add(inner, "left.middle");
    msp.add(tools, "editor");
    msp.add(log, "bottom");
   
    msp.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));

    // some size settings
    browser.setPreferredSize(new Dimension(100, 100));
    log.setPreferredSize(new Dimension(100, 200));
    tools.setPreferredSize(new Dimension(100, 100));   
   
    // menu
    JMenuItem exit = SwingFactory.createItem("Exit", "icons/Remove.png");
    start = SwingFactory.createItem("Start Script", "icons/Play.png");
    JMenuItem stop = SwingFactory.createItem("Stop", "icons/Stop.png")
    reset = SwingFactory.createItem("Reset Interpreter", "icons/Play All.png")
   
    JMenuItem save = SwingFactory.createItem("Save", "icons/User.png")
    JMenuItem saveAll = SwingFactory.createItem("Save All", "icons/Users.png")
    JMenuItem saveAs = SwingFactory.createItem("Save as...", "icons/Add.png")
   
    JMenuItem close = SwingFactory.createItem("Close", "icons/Pause.png")
    JMenuItem closeAll = SwingFactory.createItem("Close All", "icons/Pause All.png");   
   
    JMenuItem open = SwingFactory.createItem("Open", "icons/New Document.png");
    JMenuItem about = SwingFactory.createItem("About", "icons/iChat Alt.png");
    JMenuItem newFile = SwingFactory.createItem("New", "icons/Document.png");
   
    start.addActionListener(new ActionListener() {

      @Override
      public void actionPerformed(ActionEvent arg0) {
 
        logger.warn("================================================");
        logger.warn("Started Script");
        logger.warn("================================================");

        editor.execute();

        repl.focus();
       
        markFresh();
      }
    });

    close.addActionListener(new ActionListener() {

      @Override
      public void actionPerformed(ActionEvent arg0) {

        editor.close();
      }
    });
   
    closeAll.addActionListener(new ActionListener() {

      @Override
      public void actionPerformed(ActionEvent arg0) {

        editor.closeAll();
      }
    });
   
    reset.addActionListener(new ActionListener() {

      @Override
      public void actionPerformed(ActionEvent arg0) {

        debugger.setDebugg(false);
       
        setInterpreter(new Interpreter());
       
        if(editor.openFiles())
          markGrubby();
        else
          markFresh();
      }
    });

    save.addActionListener(new ActionListener() {

      @Override
      public void actionPerformed(ActionEvent arg0) {

        editor.save();
      }
    });

    saveAs.addActionListener(new ActionListener() {

      @Override
      public void actionPerformed(ActionEvent arg0) {

        int returnVal = fc.showSaveDialog(ThoFuUi.this);

        if (returnVal == JFileChooser.APPROVE_OPTION) {

          editor.saveAs(fc.getSelectedFile());
        }
      }
    });

    open.addActionListener(new ActionListener() {

      @Override
      public void actionPerformed(ActionEvent arg0) {
       
        int returnVal = fc.showOpenDialog(ThoFuUi.this);

        if (returnVal == JFileChooser.APPROVE_OPTION) {

          open(fc.getSelectedFile());
        }
      }
    });
   
    newFile.addActionListener(new ActionListener() {

      @Override
      public void actionPerformed(ActionEvent arg0) {

        int returnVal = fc.showSaveDialog(ThoFuUi.this);

        if (returnVal == JFileChooser.APPROVE_OPTION) {

          open(fc.getSelectedFile());
        }
      }
    });

    about.addActionListener(new ActionListener() {

      @Override
      public void actionPerformed(ActionEvent arg0) {

        String content = new Util().read(getClass(), "README.md");

        new HtmlViewer(content)
      }
    });
   
    exit.addActionListener(new ActionListener() {

      @Override
      public void actionPerformed(ActionEvent arg0) {

        promptUnsavedWarningIfDirty();
             
        System.exit(0);
      }
    });

    JMenu file = SwingFactory.createMenu("File", "icons/Write Document.png");
    file.add(newFile);
    file.add(open);
    file.add(new JSeparator());
    file.add(save);
    file.add(saveAll);
    file.add(saveAs);
    file.add(new JSeparator());
    file.add(close);
    file.add(closeAll);
    file.add(new JSeparator());
    file.add(exit);
   
    final JMenu syntax = new JMenu("Syntax");
    SwingFactory.setIcon(syntax, "icons/Rename Document.png");

    JRadioButtonMenuItem defaultSyntax = new JRadioButtonMenuItem("Default");
    SwingFactory.setIcon(defaultSyntax, "icons/Purple Ball.png");
   
    JRadioButtonMenuItem proceduralSyntax = new JRadioButtonMenuItem("Procedural");
    SwingFactory.setIcon(proceduralSyntax, "icons/Orange Ball.png");

    ButtonGroup group = new ButtonGroup();
    group.add(defaultSyntax);
    group.add(proceduralSyntax);
   
    syntax.add(defaultSyntax);
    syntax.add(proceduralSyntax);
   
    defaultSyntax.addActionListener(new ActionListener() {
     
      @Override
      public void actionPerformed(ActionEvent e) {
     
        interpreter.setParser(new DefaultParser());
       
        repl.setSyntax(SyntaxConstants.SYNTAX_STYLE_LISP);
        editor.setSyntax(SyntaxConstants.SYNTAX_STYLE_LISP);
       
        log.log("Default syntax");
      }
    });
   
    defaultSyntax.setSelected(true);
   
    proceduralSyntax.addActionListener(new ActionListener() {
     
      @Override
      public void actionPerformed(ActionEvent e) {
     
        interpreter.setParser(new ProceduralParser());
     
        repl.setSyntax(SyntaxConstants.SYNTAX_STYLE_JAVASCRIPT);
        editor.setSyntax(SyntaxConstants.SYNTAX_STYLE_JAVASCRIPT);
       
        log.log("Procedural syntax");
      }
    });
   
    final JMenu edit = SwingFactory.createMenu("Edit", "icons/Menu.png");

    edit.addMenuListener(new MenuListener() {
     
      @Override
      public void menuSelected(MenuEvent arg0) {
       
          edit.removeAll();

          JMenu editorMenu = SwingFactory.createMenu("Editor", "icons/editor.png", editor.getPopupMenu());
          edit.add(editorMenu);
         
        if(editor.getPopupMenu() == null) {

          editorMenu.setEnabled(false);
        }
       
        JMenu replMenu = SwingFactory.createMenu("Console", "icons/console.png", repl.getPopupMenu());
        edit.add(replMenu);
       
        edit.add(syntax);
      }
     
      @Override
      public void menuDeselected(MenuEvent arg0) {}
     
      @Override
      public void menuCanceled(MenuEvent arg0) {}
    });
   
   

    JMenu run = SwingFactory.createMenu("Run", "icons/Gear Alt.png");
    run.add(start);
    run.add(reset);
    run.add(stop);
   
    JMenu info = SwingFactory.createMenu("More", "icons/Add.png");
    info.add(about);
   
    JMenuBar menubar = SwingFactory.createMenuBar();
    menubar.add(file);
    menubar.add(edit);
    menubar.add(run);
    menubar.add(info);

    this.setJMenuBar(menubar);

    this.addWindowListener(new WindowAdapter() {

      @Override
      public void windowClosing(WindowEvent e) {

        promptUnsavedWarningIfDirty();       
      }
    });
   
    this.markFresh();
    this.setInterpreter(new Interpreter());
    this.getContentPane().add(status, BorderLayout.NORTH);
    this.getContentPane().add(msp, BorderLayout.CENTER);
    this.getContentPane().add(running, BorderLayout.SOUTH);
   
    this.setExtendedState(Frame.MAXIMIZED_BOTH);
    this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    this.setTitle("Thomas' Functional Interpreter - ThoFu!");
    this.setLocationRelativeTo(null);
    this.setSize(new Dimension(1000, 800));
   
    logger.info("GUI started");
  }

  protected void open(File file) {

    editor.open(file);

    markGrubby();
  }

  private void promptUnsavedWarningIfDirty() {

    if (editor.isDirty()) {
     
      int confirmed = JOptionPane.showConfirmDialog(null, "Save all files?", "Unsaved edits", JOptionPane.YES_NO_OPTION);
 
      if (confirmed == JOptionPane.YES_OPTION) {

        editor.saveAll();
      }
    }
  }

  private void setInterpreter(IInterpreter interpreter) {

    editor.setInterpreter(interpreter);
    repl.setInterpreter(interpreter);

    repl.reset(interpreter.getEnvironment());
    inspector.reset(interpreter.getEnvironment());

    interpreter.addHistoryListener(history);
    interpreter.addEnvironmentListener(inspector);
    interpreter.addEnvironmentListener(repl);
    interpreter.addEnvironmentListener(editor);
   
    this.interpreter = interpreter;
  }

  void markGrubby() {

    if (!grubby) {

      grubby = true;

      status.setMessage("Definitions have changed! Start Script!");
      status.setColor(Color.RED);
    }
  }

  void markFresh() {

    if (grubby) {

      grubby = false;

      status.setMessage("Ready");
      status.setColor(Color.GREEN);
    }
  }

  public void stop() {

    editor.setEnabled(false);
    repl.setEnabled(false);
   
    running.stop();
  }

  public void start() {

    editor.setEnabled(true);
    repl.setEnabled(false);
   
    running.start();
  }

  public int showSaveDialog() {

    return fc.showSaveDialog(this);
  }
 
  public File getSelectedFile() {

    return fc.getSelectedFile();
  }
 
  public void setCurrentDirectory(File file) {

    fc.setCurrentDirectory(file);
  }
 
  public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException, InterruptedException {

    UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
   
//    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

    Locale.setDefault(Locale.ENGLISH);

    SwingUtilities.invokeLater(new Runnable() {

      public void run() {

        instance().setVisible(true);
        instance().repl.focus();
      }
    });
  }

  public void enableControls(boolean b) {

    repl.setEnabled(b);
    start.setEnabled(b);
    reset.setEnabled(b);
  }

  public static IDebugger getDebugger() {

    return debugger;
  }
}
TOP

Related Classes of de.tuhrig.thofu.gui.ThoFuUi

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.