Package net.sf.robocode.ui.editor

Source Code of net.sf.robocode.ui.editor.EditWindow

/**
* Copyright (c) 2001-2014 Mathew A. Nelson and Robocode contributors
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://robocode.sourceforge.net/license/epl-v10.html
*/
package net.sf.robocode.ui.editor;


import net.sf.robocode.io.FileUtil;
import net.sf.robocode.io.Logger;
import net.sf.robocode.repository.IRepositoryManager;
import net.sf.robocode.ui.editor.theme.EditorThemeProperties;
import net.sf.robocode.ui.editor.theme.EditorThemePropertiesManager;
import net.sf.robocode.ui.editor.theme.EditorThemePropertyChangeAdapter;

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.InternalFrameAdapter;
import javax.swing.event.InternalFrameEvent;
import javax.swing.filechooser.FileFilter;

import java.awt.Font;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.StringTokenizer;


/**
* @author Mathew A. Nelson (original)
* @author Flemming N. Larsen (contributor)
* @author Matthew Reeder (contributor)
*/
@SuppressWarnings("serial")
public class EditWindow extends JInternalFrame {

  private String fileName;
  private String robotName;
  public boolean modified;
  private final RobocodeEditor editor;
  private final IRepositoryManager repositoryManager;
  private final File robotsDirectory;
  private EditorPanel editorPanel;
  private EditorPane editorPane;

  public EditWindow(IRepositoryManager repositoryManager, RobocodeEditor editor, File robotsDirectory) {
    super("Edit Window", true, true, true, true);
    this.editor = editor;
    this.robotsDirectory = robotsDirectory;
    this.repositoryManager = repositoryManager;
    initialize();
  }

  public EditorPane getEditorPane() {
    if (editorPane == null) {
      editorPane = editorPanel.getEditorPane();
      InputMap im = editorPane.getInputMap();

      // FIXME: Replace hack with better solution than using 'ctrl H'
      im.put(KeyStroke.getKeyStroke("ctrl H"), editor.getReplaceAction());
   
    return editorPane;
  }

  public String getFileName() {
    return fileName;
  }

  public String getRobotName() {
    return robotName;
  }

  private void initialize() {
    try {
      addInternalFrameListener(new InternalFrameAdapter() {
        @Override
        public void internalFrameClosing(InternalFrameEvent e) {
          if (!modified || fileSave(true)) {
            editor.setLineStatus(-1);
            dispose();
          }
          editor.removeFromWindowMenu(EditWindow.this);
        }

        @Override
        public void internalFrameDeactivated(InternalFrameEvent e) {
          editor.setLineStatus(-1);
        }

        @Override
        public void internalFrameIconified(InternalFrameEvent e) {
          editor.setLineStatus(-1);
        }
      });
      setFrameIcon(new ImageIcon(EditWindow.class.getResource("/net/sf/robocode/ui/icons/robocode-icon.png")));
      setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);

      setSize(750, 500);

      editor.addToWindowMenu(this);

      editorPanel = new EditorPanel();
      setContentPane(editorPanel);

      EditorThemeProperties currentThemeProps = EditorThemePropertiesManager.getCurrentEditorThemeProperties();
      Font font = currentThemeProps.getFont();
      editorPanel.setFont(font);

      // Make sure the source editor window gets focus with a blinking cursor
      SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
          editorPanel.getEditorPane().requestFocus();
        }
      });

      EditorThemePropertiesManager.addListener(new EditorThemePropertyChangeAdapter() {
        @Override
        public void onFontChanged(Font newFont) {
          editorPanel.setFont(newFont);
        }
      });

      final JavaDocument document = (JavaDocument) editorPanel.getEditorPane().getDocument();

      document.addDocumentListener(new DocumentListener() {
        public void removeUpdate(DocumentEvent e) {
          updateModificationState();
        }

        public void insertUpdate(DocumentEvent e) {
          updateModificationState();
        }

        public void changedUpdate(DocumentEvent e) {
          // Fixes problem, where document is not initialized as being unsaved
          setModified(true);
        }

        // Bug-361 Problem in the text editor related with the .java file modification
        private void updateModificationState() {
          setModified(editorPanel.getEditorPane().isModified());
        }
      });
    } catch (Throwable e) {
      Logger.logError(e);
    }
  }

  public void setFileName(String newFileName) {
    fileName = newFileName;
  }

  public void setModified(boolean modified) {
    boolean updated = (modified != this.modified);

    if (updated) {
      this.modified = modified;

      StringBuffer titleBuf = new StringBuffer("Editing");
      if (fileName != null) {
        titleBuf.append(" - ").append(fileName);
      } else if (robotName != null) {
        titleBuf.append(" - ").append(robotName);
      }
      if (modified) {
        titleBuf.append(" *");
      }
      setTitle(titleBuf.toString());
    }
    editor.setSaveFileMenuItemsEnabled(modified);
  }

  public void setRobotName(String newRobotName) {
    robotName = newRobotName;
  }

  public void compile() {
    if (!fileSave(true, true)) {
      error("You must save before compiling.");
      return;
    }
    if (editor.getCompiler() != null) {
      // The compiler + refresh of the repository is done in a thread in order to avoid the compiler
      // window hanging while compiling. The SwingUtilities.invokeLater() does not do a good job here
      // (window is still hanging). Hence, a real thread running beside the EDT is used, which does a
      // great job, where each each new print from the compiler is written out as soon as it is ready
      // in the output stream.
      new Thread(new Runnable() {
        public void run() {
          if (fileName == null) {
            error("You must save before compiling.");
            return;
          }
          editor.getCompiler().compile(getRobotDir(), fileName);
          repositoryManager.refresh(fileName);
        }
      }).start();
    } else {
      JOptionPane.showMessageDialog(editor, "No compiler installed.", "Error", JOptionPane.ERROR_MESSAGE);
    }
  }

  private void error(String msg) {
    Object[] options = {
      "OK"
    };

    JOptionPane.showOptionDialog(this, msg, "Error", JOptionPane.DEFAULT_OPTION, JOptionPane.ERROR_MESSAGE, null,
        options, options[0]);
  }

  public boolean fileSave(boolean confirm) {
    return fileSave(confirm, false);
  }

  private boolean fileSave(boolean confirm, boolean mustSave) {
    if (confirm) {
      if (!modified) {
        return true;
      }
      String s = fileName;

      if (s == null) {
        s = robotName;
      }
      if (s == null) {
        s = "This file";
      }
      int ok = JOptionPane.showConfirmDialog(this, s + " has been modified.  Do you wish to save it?",
          "Modified file", JOptionPane.YES_NO_CANCEL_OPTION);

      if (ok == JOptionPane.NO_OPTION) {
        return !mustSave;
      }
      if (ok == JOptionPane.CANCEL_OPTION) {
        return false;
      }
    }
    String fileName = getFileName();

    if (fileName == null) {
      return fileSaveAs();
    }

    String reasonableFilename = getReasonableFilename();

    if (reasonableFilename != null) {
      try {
        String a = new File(reasonableFilename).getCanonicalPath();
        String b = new File(fileName).getCanonicalPath();

        if (!a.equals(b)) {
          int ok = JOptionPane.showConfirmDialog(this,
              fileName + " should be saved in: \n" + reasonableFilename
              + "\n  Would you like to save it there instead?",
              "Name has changed",
              JOptionPane.YES_NO_CANCEL_OPTION);

          if (ok == JOptionPane.CANCEL_OPTION) {
            return false;
          }
          if (ok == JOptionPane.YES_OPTION) {
            return fileSaveAs();
          }
        }
      } catch (IOException e) {
        Logger.logError("Unable to check reasonable filename: ", e);
      }
    }

    BufferedWriter bufferedWriter = null;
    OutputStreamWriter outputStreamWriter = null;
    FileOutputStream fileOutputStream = null;

    try {
      fileOutputStream = new FileOutputStream(fileName);
      outputStreamWriter = new OutputStreamWriter(fileOutputStream, "UTF8");
      bufferedWriter = new BufferedWriter(outputStreamWriter);

      getEditorPane().write(bufferedWriter);
      setModified(false);
    } catch (IOException e) {
      error("Cannot write file: " + e);
      return false;
    } finally {
      FileUtil.cleanupStream(bufferedWriter);
    }
    return true;
  }

  private String getRobotDir() {
    String saveDir = robotsDirectory.getPath() + File.separatorChar;

    String text = getEditorPane().getText();
    int pIndex = text.indexOf("package ");

    if (pIndex >= 0) {
      int pEIndex = text.indexOf(";", pIndex);

      if (pEIndex > 0) {
        String packageTree = text.substring(pIndex + 8, pEIndex) + File.separatorChar;

        packageTree = packageTree.replace('.', File.separatorChar);

        saveDir += packageTree;
      }
    }
    return saveDir;
  }
 
  public boolean fileSaveAs() {
    String javaFileName = null;
    String saveDir = getRobotDir();

    String text = getEditorPane().getText();

    int pIndex = text.indexOf("public class ");

    if (pIndex >= 0) {
      int pEIndex = text.indexOf(" ", pIndex + 13);

      if (pEIndex > 0) {
        int pEIndex2 = text.indexOf("\n", pIndex + 13);

        if (pEIndex2 > 0 && pEIndex2 < pEIndex) {
          pEIndex = pEIndex2;
        }
        javaFileName = text.substring(pIndex + 13, pEIndex).trim() + ".java";
      } else {
        pEIndex = text.indexOf("\n", pIndex + 13);
        if (pEIndex > 0) {
          javaFileName = text.substring(pIndex + 13, pEIndex).trim() + ".java";
        }
      }
    }

    File f = new File(saveDir);

    if (!f.exists()) {
      int ok = JOptionPane.showConfirmDialog(this,
          "Your robot should be saved in the directory: " + saveDir
          + "\nThis directory does not exist, would you like to create it?",
          "Create Directory",
          JOptionPane.YES_NO_CANCEL_OPTION);

      if (ok == JOptionPane.YES_OPTION) {
        if (!f.exists() && !f.mkdirs()) {
          Logger.logError("Cannot create: " + f);
        }
        f = new File(saveDir);
      }
      if (ok == JOptionPane.CANCEL_OPTION) {
        return false;
      }
    }

    JFileChooser chooser;

    chooser = new JFileChooser(f);
    chooser.setCurrentDirectory(f);

    FileFilter filter = new FileFilter() {
      @Override
      public boolean accept(File pathname) {
        if (pathname.isDirectory()) {
          return true;
        }
        String fn = pathname.getName();
        int idx = fn.lastIndexOf('.');
        String extension = "";

        if (idx >= 0) {
          extension = fn.substring(idx);
        }
        return extension.equalsIgnoreCase(".java");
      }

      @Override
      public String getDescription() {
        return "Robots";
      }
    };

    chooser.setFileFilter(filter);

    boolean done = false;

    while (!done) {
      done = true;
      if (javaFileName != null) {
        chooser.setSelectedFile(new File(f, javaFileName));
      }
      int rv = chooser.showSaveDialog(this);
      String robotFileName;

      if (rv == JFileChooser.APPROVE_OPTION) {
        robotFileName = chooser.getSelectedFile().getPath();
        File outFile = new File(robotFileName);

        if (outFile.exists()) {
          int ok = JOptionPane.showConfirmDialog(this,
              robotFileName + " already exists.  Are you sure you want to replace it?", "Warning",
              JOptionPane.YES_NO_CANCEL_OPTION);

          if (ok == JOptionPane.NO_OPTION) {
            done = false;
            continue;
          }
          if (ok == JOptionPane.CANCEL_OPTION) {
            return false;
          }
        }
        setFileName(robotFileName);
        fileSave(false);
      } else {
        return false;
      }
    }

    return true;
  }

  public String getPackage() {
    String text = getEditorPane().getText();
    int pIndex = text.indexOf("package ");

    if (pIndex >= 0) {
      int pEIndex = text.indexOf(";", pIndex);

      if (pEIndex > 0) {
        return text.substring(pIndex + 8, pEIndex);
      }
    }
    return "";
  }

  private String getReasonableFilename() {
    StringBuffer fileName = new StringBuffer(robotsDirectory.getPath()).append(File.separatorChar);
    String javaFileName;
    String packageTree = null;

    String text = getEditorPane().getText();
    StringTokenizer tokenizer = new StringTokenizer(text, " \t\r\n;");
    String token;
    boolean inComment = false;

    while (tokenizer.hasMoreTokens()) {
      token = tokenizer.nextToken();
      if (!inComment && (token.equals("/*") || token.equals("/**"))) {
        inComment = true;
      }
      if (inComment && (token.equals("*/") || token.equals("**/"))) {
        inComment = false;
      }
      if (inComment) {
        continue;
      }

      if (packageTree == null && token.equals("package")) {
        packageTree = tokenizer.nextToken();
        if (packageTree == null || packageTree.length() == 0) {
          return null;
        }
        packageTree = packageTree.replace('.', File.separatorChar);
        packageTree += File.separator;
        fileName.append(packageTree);
      }
      if (token.equals("class")) {
        javaFileName = tokenizer.nextToken() + ".java";
        fileName.append(javaFileName);
        return fileName.toString();
      }
    }
    return null;
  }
}
TOP

Related Classes of net.sf.robocode.ui.editor.EditWindow

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.