Package org.jdraw

Source Code of org.jdraw.MainWindow$TextAreaListener

/*
   Copyright 2012 Shane Phillips

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
package org.jdraw;

import java.awt.BorderLayout;
import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowFocusListener;
import java.awt.event.WindowListener;
import java.awt.event.WindowStateListener;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.logging.ConsoleHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.prefs.Preferences;

import javax.imageio.ImageIO;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.border.EtchedBorder;

import org.jdraw.swing.TaggedMenuItem;
import org.jdraw.utils.Dialogs;
import org.jdraw.utils.FileExtensionFilters;
import org.jdraw.utils.FileIO;
import org.jdraw.utils.RecentFiles;
import org.jdraw.utils.Dialogs.FileSelectionMode;

public class MainWindow extends JFrame {

  private static final long serialVersionUID = 1L;

  private JPanel contentPane, statusBar;
  private JMenuBar menuBar;
  private JMenu menuFile, menuCanvas, menuRecentFiles, menuHelp;
  private DrawingPanel drawingPanel;
  private JSplitPane splitPane;
  private JTextArea textArea;
  private JLabel statusLabel;
  // File Menu
  private JMenuItem miFileNew, miFileOpen, miFileSave, miFileSaveAs, miClose;
  // Canvas Menu
  private JMenuItem miRefresh, miExportImage;
  // Help Menu
  private JMenuItem miReference;
  JScrollPane panelScrollPane;
  private MenuActionListener menuActionListener;

  private ResourceBundle rb;
  private Locale locale;
  private Logger log;

  private boolean fileModified;
  private File currentFile;
  private String jsCode = "";

  private ScriptEngineManager sem;
  private ScriptEngine se;
  private Canvas canvas;
  private RecentFiles recentFiles;

  private int top, left, width, height, state;
  private final int RECENT_FILE_COUNT = 10;

  /**
   * Application entry point
   */
  public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
      public void run() {
        try {
          MainWindow frame = new MainWindow();
          frame.setVisible(true);
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    });
  }

  /**
   * Constructor for the MainWindow
   */
  public MainWindow() {
    setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
    loadPreferences();
    setExtendedState(state);
    setBounds(left, top, width, height);

    MainWindowListener windowListener = new MainWindowListener();
    addWindowListener(windowListener);
    addWindowStateListener(windowListener);
    addComponentListener(windowListener);

    // Misc stuff
    locale = Locale.getDefault();
    rb = ResourceBundle.getBundle("resources", locale);
    log = Logger.getLogger(this.getClass().getName());

    // TODO: move this to configuration
    log.setUseParentHandlers(false);
    Handler consoleHandler = new ConsoleHandler();
    consoleHandler.setLevel(Level.FINE);
    log.addHandler(consoleHandler);
    log.setLevel(Level.FINE);

    // SE
    sem = new ScriptEngineManager();
    se = sem.getEngineByExtension("js");
    canvas = new Canvas();
    se.put("canvas", canvas);

    // Components
    menuBar = new JMenuBar();
    setJMenuBar(menuBar);

    menuFile = new JMenu(rb.getString("menu.file"));
    menuBar.add(menuFile);

    miFileNew = new JMenuItem(rb.getString("menu.file.new"));
    miFileNew.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N,
        InputEvent.CTRL_MASK));
    menuFile.add(miFileNew);
    miFileOpen = new JMenuItem(rb.getString("menu.file.open"));
    miFileOpen.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O,
        InputEvent.CTRL_MASK));
    menuFile.add(miFileOpen);
    miFileSave = new JMenuItem(rb.getString("menu.file.save"));
    miFileSave.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S,
        InputEvent.CTRL_MASK));
    miFileSave.setEnabled(false);
    menuFile.add(miFileSave);

    miFileSaveAs = new JMenuItem(rb.getString("menu.file.saveas"));
    menuFile.add(miFileSaveAs);

    JSeparator sep = new JSeparator();
    menuFile.add(sep);

    menuRecentFiles = new JMenu(rb.getString("menu.file.recent"));
    menuFile.add(menuRecentFiles);

    JSeparator sep2 = new JSeparator();
    menuFile.add(sep2);

    miClose = new JMenuItem(rb.getString("menu.file.close"));
    menuFile.add(miClose);

    menuCanvas = new JMenu(rb.getString("menu.canvas"));
    menuBar.add(menuCanvas);

    miRefresh = new JMenuItem(rb.getString("menu.canvas.refresh"));
    miRefresh.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F5, 0));
    menuCanvas.add(miRefresh);

    miExportImage = new JMenuItem(rb.getString("menu.canvas.export"));
    miExportImage.setEnabled(false);
    menuCanvas.add(miExportImage);

    menuHelp = new JMenu(rb.getString("menu.help"));

    miReference = new JMenuItem(rb.getString("menu.help.online"));
    menuHelp.add(miReference);

    menuBar.add(menuHelp);

    contentPane = new JPanel();
    contentPane.setLayout(new BorderLayout(0, 0));
    setContentPane(contentPane);

    statusBar = new JPanel();
    contentPane.add(statusBar, BorderLayout.SOUTH);
    statusBar.setBorder(new EtchedBorder(3));

    splitPane = new JSplitPane();
    splitPane.setResizeWeight(0.8);
    splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
    contentPane.add(splitPane, BorderLayout.CENTER);

    drawingPanel = new DrawingPanel();
    panelScrollPane = new JScrollPane(drawingPanel);
    panelScrollPane
        .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
    panelScrollPane
        .setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);

    // splitPane.setLeftComponent(drawingPanel);
    splitPane.setLeftComponent(panelScrollPane);

    textArea = new JTextArea();
    Font font = new Font(Font.MONOSPACED, Font.PLAIN, 14);
    textArea.setFont(font);
    textArea.setEditable(true);
    textArea.addKeyListener(new TextAreaListener());
    JScrollPane scrollPane = new JScrollPane(textArea);
    scrollPane
        .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
    splitPane.setRightComponent(scrollPane);

    statusLabel = new JLabel();
    statusBar.add(statusLabel, 0);
    statusLabel.setFont(font);

    setFileModified(false);
    setCurrentFile(null);

    menuActionListener = new MenuActionListener();
    addMenuActionListeners();
    refreshRecentFiles();

    String labelText = String.format(
        rb.getString("label.status.canvas.size"), canvas.getWidth(),
        canvas.getHeight());
    statusLabel.setText(labelText);
  }

  // Getters / Setters
  public boolean isFileModified() {
    return fileModified;
  }

  public void setFileModified(boolean fileModified) {
    if (fileModified == this.fileModified) {
      return;
    }
    this.fileModified = fileModified;
    miFileSave.setEnabled(fileModified);
    miRefresh.setEnabled(true);
    if (fileModified) {
      String title = String.format(rb.getString("window.main.title"),
          rb.getString("document.untitled") + "*");
      if (currentFile != null) {
        title = String.format(rb.getString("window.main.title"),
            currentFile.getAbsolutePath() + "*");
      }

      setTitle(title);
    }
  }

  public File getCurrentFile() {
    return currentFile;
  }

  public void setCurrentFile(File currentFile) {
    this.currentFile = currentFile;
    if (currentFile != null) {
      String title = String.format(rb.getString("window.main.title"),
          currentFile.getAbsolutePath());
      setTitle(title);
      miFileSaveAs.setEnabled(true);
      miRefresh.setEnabled(true);
    } else {
      String title = String.format(rb.getString("window.main.title"),
          rb.getString("document.untitled"));
      setTitle(title);
      miFileSaveAs.setEnabled(false);
      miRefresh.setEnabled(false);
    }
    setFileModified(false);
    jsCode = textArea.getText();
    if (currentFile != null) {
      recentFiles.put(currentFile);
    }
    refreshRecentFiles();
  }

  // Methods

  private void addMenuActionListeners() {
    for (int menuCount = 0; menuCount < menuBar.getMenuCount(); menuCount++) {
      JMenu menu = menuBar.getMenu(menuCount);
      for (int item = 0; item < menu.getItemCount(); item++) {
        if (menu.getItem(item) != null
            && !TaggedMenuItem.class.isInstance(menu.getItem(item))) {
          menu.getItem(item).addActionListener(menuActionListener);
        }
      }
    }

  }

  private boolean newFile() {
    if (isFileModified()) {
      if (Dialogs.showSavePrompt(rb.getString("prompt.save.changes"))) {
        if (!saveFile(false)) {
          return false;
        }

      }
    }
    setCurrentFile(null);
    textArea.setText(null);
    jsCode = "";
    refreshCanvas();
    miExportImage.setEnabled(false);
    return true;
  }

  private boolean saveFile(boolean saveAs) {
    byte[] buffer = textArea.getText().getBytes();
    File tempFile = null;

    if (currentFile != null) {
      tempFile = new File(currentFile.getAbsolutePath());
    }

    if (saveAs || currentFile == null) {
      try {
        tempFile = Dialogs.selectFile(
            FileExtensionFilters.getJSFileFilter(),
            FileSelectionMode.SAVE);
        if (tempFile == null) {
          return false;
        }

        if (FileIO.getFileExtension(tempFile.getName()) == null) {
          tempFile = new File(tempFile.getAbsolutePath() + ".js");
        }

        if (tempFile.exists()) {
          String message = String.format(
              rb.getString("warning.file.exists"),
              tempFile.getAbsolutePath());
          if (JOptionPane.showConfirmDialog(null, message, null,
              JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION) {
            return false;
          }
        }
      } catch (Exception ex) {
        return false;
      }
    }

    try {
      FileIO.save(tempFile, buffer);
    } catch (IOException ex) {
      String message = String.format(rb.getString("error.file.save"),
          ex.getMessage());
      Dialogs.showError(rb.getString("error.title"), message);
      return false;
    }
    setCurrentFile(tempFile);
    return true;
  }

  private boolean openFile(String fileName) {
    if (isFileModified()) {
      if (Dialogs.showSavePrompt(rb.getString("prompt.save.changes"))) {
        if (!saveFile(false)) {
          return false;
        }
      }
    }

    File f = null;
    if (fileName == null) {
      try {
        f = Dialogs.selectFile(FileExtensionFilters.getJSFileFilter(),
            FileSelectionMode.OPEN);
        if (f == null) {
          return false;
        }
      } catch (Exception ex) {
        return false;
      }
    } else {
      f = new File(fileName);
    }

    if (!f.exists()) {
      String message = String.format(
          rb.getString("error.file.not.found"), f.getAbsolutePath());
      Dialogs.showError(rb.getString("error.title"), message);
      return false;
    }

    try {
      byte[] buffer = FileIO.read(f);
      textArea.setText(new String(buffer));
    } catch (IOException ex) {
      String message = String.format(rb.getString(f.getAbsolutePath()),
          ex.getMessage());
      Dialogs.showError(rb.getString("error.title"), message);
      return false;
    }

    setCurrentFile(f);
    return true;
  }

  private void refreshCanvas() {
    try {
      canvas.reset();
      se.eval(textArea.getText());
      drawingPanel.setPreferredSize(new Dimension(
          (int) canvas.getWidth(), (int) canvas.getHeight()));
      drawingPanel.setImage(canvas.getImage());
      drawingPanel.repaint();
      String labelText = String.format(
          rb.getString("label.status.canvas.size"),
          canvas.getWidth(), canvas.getHeight());
      statusLabel.setText(labelText);
      miExportImage.setEnabled(true);
    } catch (Exception ex) {
      miExportImage.setEnabled(false);
      String exceptionMessage = null;
      if (ex.getCause() != null) {
        exceptionMessage = ex.getCause().getMessage();
      } else {
        exceptionMessage = ex.getMessage();
      }
      String message = String.format(rb.getString("error.script"),
          exceptionMessage);
      log.warning(message);
      Dialogs.showError(rb.getString("error.title"), message);
    }
  }

  private void loadPreferences() {
    Preferences prefs = Preferences.userNodeForPackage(this.getClass());
    top = prefs.getInt("window.top", 100);
    left = prefs.getInt("window.left", 100);
    width = prefs.getInt("window.width", 640);
    height = prefs.getInt("window.height", 480);
    state = prefs.getInt("window.state", 0);
    String r = prefs.get("recent.files", null);
    recentFiles = new RecentFiles(RECENT_FILE_COUNT);
    if (r != null && r.length() > 0) {
      String[] ra = r.split(";");
      for (int i = ra.length - 1; i >= 0; i--) {
        recentFiles.put(new File(ra[i]));
      }
    }
  }

  private void savePreferences() {
    Preferences prefs = Preferences.userNodeForPackage(this.getClass());
    prefs.putInt("window.state", state);
    if (state == JFrame.MAXIMIZED_BOTH) {
      top = 100;
      left = 100;
      width = 640;
      height = 480;
    }

    prefs.putInt("window.top", top);
    prefs.putInt("window.left", left);
    prefs.putInt("window.width", width);
    prefs.putInt("window.height", height);

    String rf = "";

    for (File f : recentFiles.getRecentFiles()) {
      if (!rf.equals("")) {
        rf += ";";
      }
      rf += f.getAbsolutePath();
    }

    prefs.put("recent.files", rf);
  }

  private void refreshRecentFiles() {
    log.fine("refreshRecentFiles()");
    menuRecentFiles.removeAll();
    if (recentFiles.getRecentFiles().size() > 0) {
      for (File f : recentFiles.getRecentFiles()) {
        TaggedMenuItem mi = new TaggedMenuItem();
        mi.setTag(f);
        mi.setText(f.getName());
        mi.setToolTipText(f.getAbsolutePath());
        mi.addActionListener(menuActionListener);
        menuRecentFiles.add(mi);
      }
    }
  }

  private void exportImage() {
    File imageFile = Dialogs.selectFile(
        FileExtensionFilters.getPNGFilter(), FileSelectionMode.SAVE);

    if (imageFile == null) {
      return;
    }
    try {
      if (FileIO.getFileExtension(imageFile.getName()) == null) {
        imageFile = new File(imageFile.getAbsolutePath() + ".png");
      }

      if (imageFile.exists()) {
        String message = String.format(
            rb.getString("warning.file.exists"),
            imageFile.getAbsolutePath());
        if (JOptionPane.showConfirmDialog(null, message, null,
            JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION) {
          return;
        }
      }

      log.fine("Exporting image to: " + imageFile.getAbsolutePath());
      ImageIO.write(canvas.getImage(), "png", imageFile);
    } catch (IOException ex) {
      log.warning("exportImage(): " + ex.getMessage());
      String message = String.format(rb.getString("error.image.export"),
          ex.getMessage());
      Dialogs.showError(rb.getString("error.title"), message);
    }
  }

  private void launchBrowser() {
    try {
      Desktop deskTop = Desktop.getDesktop();
      deskTop.browse(new URI(rb.getString("help.url")));
    } catch (Exception ex) {
      Dialogs.showError(rb.getString("error.title"), ex.getMessage());
    }

  }

  class MenuActionListener implements ActionListener {

    @Override
    public void actionPerformed(ActionEvent event) {
      log.fine("Menu Action: " + event.getActionCommand());
      if (event.getActionCommand()
          .equals(rb.getString("menu.file.close"))) {
        WindowEvent closingEvent = new WindowEvent(MainWindow.this,
            WindowEvent.WINDOW_CLOSING);
        Toolkit.getDefaultToolkit().getSystemEventQueue()
            .postEvent(closingEvent);
      } else if (event.getActionCommand().equals(
          rb.getString("menu.file.new"))) {
        log.fine("New File: " + newFile());
      }

      else if (event.getActionCommand().equals(
          rb.getString("menu.file.open"))) {
        log.fine("Open File: " + openFile(null));
      }

      else if (event.getActionCommand().equals(
          rb.getString("menu.file.save"))) {
        saveFile(false);
      }

      else if (event.getActionCommand().equals(
          rb.getString("menu.file.saveas"))) {
        saveFile(true);
      }

      else if (event.getActionCommand().equals(
          rb.getString("menu.canvas.refresh"))) {
        refreshCanvas();
      }

      else if (event.getActionCommand().equals(
          rb.getString("menu.canvas.export"))) {
        exportImage();
      }

      else if (event.getActionCommand().equals(
          rb.getString("menu.help.online"))) {
        launchBrowser();
      }

      else if (TaggedMenuItem.class.isInstance(event.getSource())) {
        TaggedMenuItem mi = (TaggedMenuItem) event.getSource();
        openFile(((File) mi.getTag()).getAbsolutePath());
      }
    }
  }

  class TextAreaListener implements KeyListener {

    @Override
    public void keyPressed(KeyEvent event) {

    }

    @Override
    public void keyReleased(KeyEvent event) {
      if (!textArea.getText().equals(jsCode)) {
        setFileModified(true);
      }
    }

    @Override
    public void keyTyped(KeyEvent event) {

    }

  }

  class MainWindowListener implements WindowStateListener, WindowListener,
      WindowFocusListener, ComponentListener {

    @Override
    public void windowStateChanged(WindowEvent e) {
      log.fine("New state: " + e.getNewState());
      state = e.getNewState();
    }

    @Override
    public void windowActivated(WindowEvent e) {

    }

    @Override
    public void windowClosed(WindowEvent e) {

    }

    @Override
    public void windowClosing(WindowEvent e) {
      log.fine("Window Closing");
      savePreferences();
      if (isFileModified()) {
        if (Dialogs.showSavePrompt(rb.getString("prompt.save.changes"))) {
          if (!saveFile(false)) {
            return;
          }
          log.fine("File saved during close");
        } else {
          log.fine("File changes abandoned by user during close");
        }
      }
      System.exit(0);
    }

    @Override
    public void windowDeactivated(WindowEvent e) {

    }

    @Override
    public void windowDeiconified(WindowEvent e) {

    }

    @Override
    public void windowIconified(WindowEvent e) {

    }

    @Override
    public void windowOpened(WindowEvent e) {

    }

    @Override
    public void windowGainedFocus(WindowEvent e) {

    }

    @Override
    public void windowLostFocus(WindowEvent e) {

    }

    @Override
    public void componentHidden(ComponentEvent e) {

    }

    @Override
    public void componentMoved(ComponentEvent e) {
      width = getWidth();
      height = getHeight();
      top = (int) getBounds().getY();
      left = (int) getBounds().getX();
    }

    @Override
    public void componentResized(ComponentEvent e) {

    }

    @Override
    public void componentShown(ComponentEvent e) {

    }

  }

}
TOP

Related Classes of org.jdraw.MainWindow$TextAreaListener

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.