/**
* Main frame of the IDE with a dragable toolbar, a projectlist, code editor,
* output area and some popups
*/
package GUI;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.KeyEventDispatcher;
import java.awt.KeyboardFocusManager;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JEditorPane;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextPane;
import javax.swing.JToolBar;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.filechooser.FileFilter;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.Highlighter;
import observer.PseucoObservable;
import observer.PseucoObserver;
import jsyntaxpane.DefaultSyntaxKit;
import Start.Start;
import Compiler.DeadlockCheck;
import Compiler.Pseuco;
public class GUI extends JFrame implements PseucoObserver {
private static final long serialVersionUID = 4041669962276471260L;
private JToolBar toolBar;
private JSplitPane splitPaneCode, splitPaneWorkspace;
private JTextPane output;
private JEditorPane input;
private JPopupMenu popupMenu;
private JMenuItem popUpRefresh, popUpOpen, popUpDelete, popUpRun, popUpNew, popUpRename;
private JButton menuOpen, menuRun, menuDebug, menuNew, menuSave, menuExport, menuStop, menuCheck, menuHelp, menuExportOnline;
private JLabel threadCount;
private FileList list;
private Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
private static String currentProject = "";
/**
* Launch the application.
*/
public GUI () {
setTitle("PseuCo IDE "+Start.version);
setIconImage(Toolkit.getDefaultToolkit().getImage(getClass().getResource("/resources/logo.png")));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds((d.width / 8), (d.height / 8), (d.width * 3 / 4),(d.height * 3 / 4));
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new MyDispatcher());
setupView();
setupPopup();
setupToolbar();
setVisible(true);
loadExample();
loadInfo();
input.requestFocusInWindow();
Pseuco.debugger.registerObserver(this);
}
private void changeFontSize(int size, boolean reset) {
if (!reset) {
// changeFontSize(toolBar, size);
changeFontSize(output, size);
changeFontSize(input, size);
// changeFontSize(popupMenu, size);
// changeFontSize(popUpRefresh, size); changeFontSize(popUpOpen, size);
// changeFontSize(popUpDelete, size); changeFontSize(popUpRun, size);
// changeFontSize(popUpNew, size); changeFontSize(popUpRename, size);
// changeFontSize(menuOpen, size); changeFontSize(menuRun, size);
// changeFontSize(menuDebug, size); changeFontSize(menuNew, size);
// changeFontSize(menuSave, size); changeFontSize(menuExport, size);
// changeFontSize(menuStop, size); changeFontSize(menuHelp, size);
// changeFontSize(threadCount, size);
// changeFontSize(list, size);
}
else {
// resetFontSize(toolBar, size);
resetFontSize(output, size);
resetFontSize(input, size);
// resetFontSize(popupMenu, size);
// resetFontSize(popUpRefresh, size); resetFontSize(popUpOpen, size);
// resetFontSize(popUpDelete, size); resetFontSize(popUpRun, size);
// resetFontSize(popUpNew, size); resetFontSize(popUpRename, size);
// resetFontSize(menuOpen, size); resetFontSize(menuRun, size);
// resetFontSize(menuDebug, size); resetFontSize(menuNew, size);
// resetFontSize(menuSave, size); resetFontSize(menuExport, size);
// resetFontSize(menuStop, size); resetFontSize(menuHelp, size);
// resetFontSize(threadCount, size);
// resetFontSize(list, size);
}
}
private void changeFontSize(Component c, int size) {
c.setFont(new Font(c.getFont().getFontName(), Font.PLAIN, c.getFont().getSize()+size));
}
private void resetFontSize(Component c, int size) {
c.setFont(new Font(c.getFont().getFontName(), Font.PLAIN, size));
}
/**
* Toolbar
*/
private void setupToolbar() {
toolBar = new JToolBar();
getContentPane().add(toolBar, BorderLayout.NORTH);
newBtn();
openBtn();
saveBtn();
exportBtn();
toolBar.addSeparator();
runBtn();
debugBtn();
stopBtn();
toolBar.addSeparator();
verifyBtn();
toolBar.addSeparator();
exportOnlineBtn();
toolBar.addSeparator();
helpBtn();
Pseuco.setOnProgramFinished(new Runnable() {
@Override
public void run() {
menuStop.setEnabled(false);
menuRun.setEnabled(true);
menuCheck.setEnabled(true);
//menuDebug.setEnabled(true);
popUpRun.setEnabled(true);
}
});
Pseuco.setOnProgramStarted(new Runnable() {
@Override
public void run() {
output.setText("");
menuStop.setEnabled(true);
menuRun.setEnabled(false);
menuCheck.setEnabled(false);
//menuDebug.setEnabled(false);
popUpRun.setEnabled(false);
}
});
}
private void newBtn() {
Action action = new AbstractAction() {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
savePseuCo(Start.workspace+System.getProperty("file.separator")+currentProject+".pseuco");
String name = JOptionPane.showInputDialog(null, "Enter project name", "New project", JOptionPane.PLAIN_MESSAGE);
if (name != null) {
if (!name.replaceAll(" ", "").equals("")) {
currentProject = name;
File f = new File(Start.workspace+System.getProperty("file.separator")+currentProject+".pseuco");
try {
f.createNewFile();
} catch (IOException e1) {
if (Start.debug) e1.printStackTrace();
}
list.setSelectedValue(currentProject, true);
setTitle("PseuCo IDE "+Start.version+" - "+currentProject);
input.setText("");
output.setText("");
}
else
JOptionPane.showMessageDialog(null, "Please enter valid name(No whitespaces or empty names allowed)!");
}
list.setFiles();
}
};
action.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("control N"));
menuNew = new JButton(action);
menuNew.getActionMap().put("New project", action);
menuNew.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put((KeyStroke) action.getValue(Action.ACCELERATOR_KEY), "New project");
helpItem(menuNew, "Create a new PseuCo-File (Ctrl+N)", "/resources/new");
}
private void openBtn() {
Action action = new AbstractAction() {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
JFileChooser fc = new JFileChooser(Start.workspace);
fc.setFileFilter(new FileFilter() {
@Override
public boolean accept(File f) {
return f.getName().endsWith(".pseuco") || f.isDirectory();
}
@Override
public String getDescription() {
return "PseuCo-File(*.pseuco)";
}
});
if (JFileChooser.APPROVE_OPTION == fc.showOpenDialog(getContentPane())) {
int res = JOptionPane.showConfirmDialog(null, "Do you want to save your project before opening another?", "Save project", JOptionPane.YES_NO_CANCEL_OPTION);
if (res == JOptionPane.YES_OPTION) {
savePseuCo(Start.workspace+System.getProperty("file.separator")+currentProject+".pseuco");
}
if (res != JOptionPane.CANCEL_OPTION || res != JOptionPane.CLOSED_OPTION) {
openPseuCo(fc.getSelectedFile().getAbsolutePath());
DefaultSyntaxKit.initKit();
input = new JEditorPane();
input.setContentType("text/pseuco");
if (!menuRun.isEnabled() && !menuStop.isEnabled()) {
menuStop.setEnabled(false);
menuRun.setEnabled(true);
menuCheck.setEnabled(true);
popUpRun.setEnabled(true);
}
}
}
}
};
action.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("control O"));
menuOpen = new JButton(action);
menuOpen.getActionMap().put("Open project", action);
menuOpen.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put((KeyStroke) action.getValue(Action.ACCELERATOR_KEY), "Open project");
helpItem(menuOpen, "Open a PseuCo-file (Ctrl+O)", "/resources/open");
}
private void saveBtn() {
Action action = new AbstractAction() {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
File f = new File(Start.workspace+System.getProperty("file.separator")+currentProject+".pseuco");
if (!f.exists() || currentProject.isEmpty()) {
JFileChooser fc = new JFileChooser(Start.workspace);
fc.setFileFilter(new FileFilter() {
@Override
public boolean accept(File f) {
return f.getName().toLowerCase().endsWith(".pseuco") || f.isDirectory();
}
@Override
public String getDescription() {
return "PseuCo-File(*.pseuco)";
}
});
if (JFileChooser.APPROVE_OPTION == fc.showSaveDialog(getContentPane())) {
currentProject = fc.getSelectedFile().getName();
savePseuCo(Start.workspace+System.getProperty("file.separator")+currentProject+".pseuco");
}
}
else {
savePseuCo(Start.workspace+System.getProperty("file.separator")+currentProject+".pseuco");
}
list.setFiles();
}
};
action.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("control S"));
menuSave = new JButton(action);
menuSave.getActionMap().put("Save project", action);
menuSave.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put((KeyStroke) action.getValue(Action.ACCELERATOR_KEY), "Save project");
helpItem(menuSave, "Save your current program as a PseuCo-file (Ctrl+S)", "/resources/save");
}
private void exportBtn() {
Action action = new AbstractAction() {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
if (!checkCurrentProject()) return;
JFileChooser fc = new JFileChooser(Start.workspace);
fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
fc.setAcceptAllFileFilterUsed(false);
if (fc.showOpenDialog(getContentPane()) == JFileChooser.APPROVE_OPTION) {
output.setText("");
savePseuCo(Start.workspace+System.getProperty("file.separator")+currentProject+".pseuco");
if (new File(fc.getSelectedFile().getAbsolutePath()).listFiles().length > 0) {
int result = JOptionPane.showConfirmDialog(getContentPane(),
"It seems that this directory already contains files. Exporting will delete them. Are you sure about this?");
if (result == JOptionPane.NO_OPTION || result == JOptionPane.CANCEL_OPTION || result == JOptionPane.CLOSED_OPTION) {
return;
}
}
Pseuco.export(Start.workspace+ System.getProperty("file.separator") + currentProject + ".pseuco",fc.getSelectedFile().getAbsolutePath());
}
}
};
action.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("control E"));
menuExport = new JButton(action);
menuExport.getActionMap().put("Export project", action);
menuExport.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put((KeyStroke) action.getValue(Action.ACCELERATOR_KEY), "Export project");
helpItem(menuExport, "Export to java program (Ctrl+E)", "/resources/export");
}
private void runBtn() {
Action action = new AbstractAction() {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
if (!checkCurrentProject()) return;
savePseuCo(Start.workspace+System.getProperty("file.separator")+currentProject+".pseuco");
Pseuco.run(Start.workspace+System.getProperty("file.separator")+currentProject+".pseuco");
}
};
action.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("F5"));
menuRun = new JButton(action);
menuRun.getActionMap().put("Run", action);
menuRun.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put((KeyStroke) action.getValue(Action.ACCELERATOR_KEY), "Run");
helpItem(menuRun, "Run/Test your program (F5)", "/resources/run");
}
private void debugBtn() {
Action action = new AbstractAction() {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
if (Pseuco.debugging && !menuRun.isEnabled()){
Pseuco.debugger.makeFrame();
return;
}
if (!checkCurrentProject()) return;
savePseuCo(Start.workspace+System.getProperty("file.separator")+currentProject+".pseuco");
Pseuco.debug(Start.workspace+System.getProperty("file.separator")+currentProject+".pseuco");
}
};
action.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("control F5"));
menuDebug = new JButton(action);
menuDebug.getActionMap().put("Debug", action);
menuDebug.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put((KeyStroke) action.getValue(Action.ACCELERATOR_KEY), "Debug");
helpItem(menuDebug, "Run your program and watch the agents (Ctrl+F5)", "/resources/debug");
}
private void stopBtn() {
Action action = new AbstractAction() {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
Pseuco.stop();
}
};
action.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("F6"));
menuStop = new JButton(action);
menuStop.getActionMap().put("Stop", action);
menuStop.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put((KeyStroke) action.getValue(Action.ACCELERATOR_KEY), "Stop");
helpItem(menuStop, "Stop the execution (F6)", "/resources/stop");
menuStop.setEnabled(false);
}
private void helpBtn() {
Action action = new AbstractAction() {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
new HelpDialog();
}
};
action.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("F1"));
menuHelp = new JButton(action);
menuHelp.getActionMap().put("Help", action);
menuHelp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put((KeyStroke) action.getValue(Action.ACCELERATOR_KEY), "Help");
helpItem(menuHelp, "Open the readme (F1)", "/resources/help");
}
private void helpItem(JButton item, String toolTip, String iconPath) {
item.setBackground(null);
item.setBorder(null);
item.setOpaque(false);
item.setBorderPainted(false);
item.setToolTipText(toolTip);
item.setIcon(new ImageIcon(GUI.class.getResource(iconPath+".png")));
toolBar.add(item);
}
private void verifyBtn() {
Action action = new AbstractAction() {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
synchronized (this) {
if (!checkCurrentProject()) return;
savePseuCo(Start.workspace+System.getProperty("file.separator")+currentProject+".pseuco");
DeadlockCheck.run(Start.workspace+System.getProperty("file.separator")+currentProject+".pseuco");
}
}
};
action.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("F8"));
menuCheck = new JButton(action);
menuCheck.getActionMap().put("Check", action);
menuCheck.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put((KeyStroke) action.getValue(Action.ACCELERATOR_KEY), "Check");
helpItem(menuCheck, "Check for deadlocks (F8)", "/resources/verified");
menuCheck.setEnabled(true);
}
private void exportOnlineBtn() {
Action action = new AbstractAction(){
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent arg0) {
// Warn the user
if (!Start.config.containsKey("AllowOnline") || !Start.config.get("AllowOnline").equals("true")){
if (JOptionPane.showConfirmDialog(GUI.this, "If you continue, the file will be uploaded to the server, "+
"and temporarily published under a random id. \nAnyone knowing or guessing this id, and the server operators, "+
"can read your file. \nYour IP address might be logged if you upload files. Your file will only be stored on the server for a few minutes."+
"\nBy continuing, you agree with this conditions.\n\nDo you want to continue?",
"pseuco.com", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) != JOptionPane.YES_OPTION)
return;
Start.config.put("AllowOnline", "true");
Start.saveConfig();
}
// submit the project
String filename = currentProject;
if (!filename.isEmpty())
filename = new File(filename).getName();
new ExportOnlineDialog(filename, input.getText()).startExport();
}
};
action.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("F9"));
menuExportOnline = new JButton(action);
menuExportOnline.getActionMap().put("Export online", action);
menuExportOnline.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put((KeyStroke) action.getValue(Action.ACCELERATOR_KEY), "Export online");
helpItem(menuExportOnline, "Sends the file to pseuco.com (F9)", "/resources/external_link");
}
/**
* Code View
*/
private void setupView() {
splitPaneWorkspace = new JSplitPane();
splitPaneWorkspace.setOrientation(JSplitPane.HORIZONTAL_SPLIT);
getContentPane().add(splitPaneWorkspace, BorderLayout.CENTER);
File filePath = new File(Start.workspace);
if (!filePath.exists())
filePath.mkdir();
list = new FileList(filePath.getAbsolutePath());
list.setToolTipText("Doubleclick to open file");
list.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e ) {
if (e.getClickCount() == 2) {
String newProject = (String) list.getSelectedValue();
if (!currentProject.equals(newProject)) {
try {
String in = input.getText().replaceAll("\\s", ""), tmp = "", line;
if (!currentProject.equals("")) {
BufferedReader reader = new BufferedReader(new FileReader(Start.workspace+System.getProperty("file.separator")+currentProject+".pseuco"));
while ((line = reader.readLine()) != null)
tmp += line;
reader.close();
}
tmp = tmp.replaceAll("\\s", "");
int result = -10;
if (!in.equals(tmp) && !in.equals("")) {
result = JOptionPane.showConfirmDialog(null, "Do you want to save your project before opening another?", "Save project", JOptionPane.YES_NO_CANCEL_OPTION);
if (result == JOptionPane.YES_OPTION) {
savePseuCo(Start.workspace+System.getProperty("file.separator")+currentProject+".pseuco");
}
}
if (result != JOptionPane.CANCEL_OPTION) {
currentProject = newProject;
openPseuCo(Start.workspace+System.getProperty("file.separator")+newProject+".pseuco");
}
if (!menuRun.isEnabled() && !menuStop.isEnabled()) {
menuStop.setEnabled(false);
menuRun.setEnabled(true);
menuCheck.setEnabled(true);
popUpRun.setEnabled(true);
}
} catch (IOException e1) {
if (Start.debug) e1.printStackTrace();
}
}
}
}
});
JScrollPane projectList = new JScrollPane(list);
projectList.setPreferredSize(new Dimension(splitPaneWorkspace.getLeftComponent().getWidth(), 512));
splitPaneWorkspace.setLeftComponent(projectList);
threadCount = new JLabel();
add(threadCount, BorderLayout.SOUTH);
threadCount.setPreferredSize(new Dimension(list.getWidth(), 25));
setupInOut();
splitPaneWorkspace.setDividerLocation(d.height/6);
}
private void setupInOut() {
splitPaneCode = new JSplitPane();
splitPaneCode.setOrientation(JSplitPane.VERTICAL_SPLIT);
splitPaneWorkspace.setRightComponent(splitPaneCode);
DefaultSyntaxKit.initKit();
input = new JEditorPane();
JScrollPane inputPane = new JScrollPane(input);
splitPaneCode.setLeftComponent(inputPane);
input.setContentType("text/pseuco");
output = new JTextPane();
JScrollPane outputPane = new JScrollPane(output);
output.setEditable(false);
splitPaneCode.setRightComponent(outputPane);
splitPaneCode.setDividerLocation(d.height/2);
Output.conout = new OutputStream(output, OutputType.NORMAL);
Output.conerr = new OutputStream(output, OutputType.ERROR);
Output.con = new OutputStream(output, OutputType.CONSOLE);
Output.setStreams();
}
/**
* Creates a popup menu for the project list
*/
private void setupPopup() {
popupMenu = new JPopupMenu();
popupMenu.setToolTipText("");
addPopup(list, popupMenu);
pNewBtn();
pOpenBtn();
pRunBtn();
pDeleteBtn();
pRenameBtn();
pRefreshBtn();
}
/**
* Popup button: Creates a new project when clicked
*/
private void pNewBtn() {
popUpNew = new JMenuItem("New");
popUpNew.setIcon(new ImageIcon(GUI.class.getResource("/resources/new_small.png")));
popUpNew.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
savePseuCo(Start.workspace+System.getProperty("file.separator")+currentProject+".pseuco");
String name = JOptionPane.showInputDialog(null, "Enter project name", "New project", JOptionPane.PLAIN_MESSAGE);
if (name != null) {
if (!name.replaceAll(" ", "").equals("")) {
currentProject = name;
File f = new File(Start.workspace+System.getProperty("file.separator")+currentProject+".pseuco");
try {
f.createNewFile();
} catch (IOException e1) {
if (Start.debug) e1.printStackTrace();
}
list.setSelectedValue(currentProject, true);
setTitle("PseuCo IDE "+Start.version+" - "+currentProject);
input.setText("");
output.setText("");
}
else
JOptionPane.showMessageDialog(null, "Please enter valid name(No whitespaces or empty names allowed)!");
}
list.setFiles();
}
});
popupMenu.add(popUpNew);
}
/**
* Popup button: Opens a project when clicked
*/
private void pOpenBtn() {
popUpOpen = new JMenuItem("Open");
popUpOpen.setIcon(new ImageIcon(GUI.class.getResource("/resources/open_small.png")));
popUpOpen.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JFileChooser fc = new JFileChooser(Start.workspace);
fc.setFileFilter(new FileFilter() {
@Override
public boolean accept(File f) {
return f.getName().endsWith(".pseuco") || f.isDirectory();
}
@Override
public String getDescription() {
return "PseuCo-File(*.pseuco)";
}
});
if (JFileChooser.APPROVE_OPTION == fc.showOpenDialog(getContentPane())) {
if (JOptionPane.showConfirmDialog(null, "Do you want to save your project before opening another?", "Save project", JOptionPane.YES_NO_CANCEL_OPTION) == JOptionPane.YES_OPTION) {
savePseuCo(Start.workspace+System.getProperty("file.separator")+currentProject+".pseuco");
}
openPseuCo(fc.getSelectedFile().getAbsolutePath());
if (!menuRun.isEnabled() && !menuStop.isEnabled()) {
menuStop.setEnabled(false);
menuRun.setEnabled(true);
menuCheck.setEnabled(true);
popUpRun.setEnabled(true);
}
}
}
});
popupMenu.add(popUpOpen);
}
/**
* Popup button: Run the current project when clicked
*/
private void pRunBtn() {
popUpRun = new JMenuItem("Run current project");
popUpRun.setIcon(new ImageIcon(GUI.class.getResource("/resources/run_small.png")));
popUpRun.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
output.setText("");
savePseuCo(Start.workspace+System.getProperty("file.separator")+currentProject+".pseuco");
Pseuco.run(Start.workspace+System.getProperty("file.separator")+currentProject+".pseuco");
}
});
popupMenu.add(popUpRun);
}
/**
* Popup button: Delete the selected project when clicked
*/
private void pDeleteBtn() {
popUpDelete = new JMenuItem("Delete");
popUpDelete.setIcon(new ImageIcon(GUI.class.getResource("/resources/delete_small.png")));
popUpDelete.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String file = Start.workspace+System.getProperty("file.separator")+(String) list.getSelectedValue()+".pseuco";
if (JOptionPane.showConfirmDialog(null, "Do you really want to delete "+file+"?", "Delete", JOptionPane.YES_NO_CANCEL_OPTION) == JOptionPane.YES_OPTION) {
File f = new File (file);
if (f.exists() || f.canWrite()) {
f.delete();
if (((String) list.getSelectedValue()).equals(currentProject)) {
currentProject = "";
input.setText("");
menuStop.setEnabled(false);
menuRun.setEnabled(false);
menuCheck.setEnabled(false);
popUpRun.setEnabled(false);
}
list.setFiles();
}
}
}
});
popupMenu.add(popUpDelete);
}
/**
* Popup button: Rename the selected file
*/
private void pRenameBtn() {
popUpRename = new JMenuItem("Rename");
popUpRename.setIcon(new ImageIcon(GUI.class.getResource("/resources/rename_small.png")));
popUpRename.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
File f = new File(Start.workspace+System.getProperty("file.separator")+(String) list.getSelectedValue()+".pseuco");
String newName = JOptionPane.showInputDialog(getContentPane(), "Please enter the new name:", "Rename project", JOptionPane.PLAIN_MESSAGE);
String newFilePath = f.getAbsolutePath().replace(f.getName(), "") + newName + ".pseuco";
if (newName != null && !newName.trim().equals("")) {
f.renameTo(new File(newFilePath));
list.setFiles();
}
}
});
popupMenu.add(popUpRename);
}
/**
* Popup button: Refreshes the project list when clicked
*/
private void pRefreshBtn() {
popUpRefresh = new JMenuItem("Refresh");
popUpRefresh.setIcon(new ImageIcon(GUI.class.getResource("/resources/refresh_small.png")));
popUpRefresh.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
list.setFiles();
}
});
popupMenu.add(popUpRefresh);
}
/**
* Popup actions for the project list
* @param component
* @param popup
*/
private static void addPopup(Component component, final JPopupMenu popup) {
component.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
if (e.isPopupTrigger()) {
showMenu(e);
}
}
@Override
public void mouseReleased(MouseEvent e) {
if (e.isPopupTrigger()) {
showMenu(e);
}
}
private void showMenu(MouseEvent e) {
popup.show(e.getComponent(), e.getX(), e.getY());
}
});
}
/**
* Creates a new thread to gather informations about the number
* of running threads and the used memory and prints it onto a JLabel
*/
private void loadInfo() {
Thread info = new Thread(){
@Override
public void run() {
Runnable r = new Runnable() {
@Override
public void run() {
long usedmemory = (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / 1024 / 1024;
threadCount.setText(String.format("Currently running agents: %d | Used memory: %dMB",Pseuco.getActiveThreadCount(),usedmemory));
}
};
while (true) {
try {
Thread.sleep(500);
SwingUtilities.invokeAndWait(r);
} catch (Exception e) {
if (Start.debug) e.printStackTrace();
}
}
}
};
info.setDaemon(true);
info.start();
}
/**
* Take a path string to open a project file and load it into the working area
* @param path
*/
private void openPseuCo(String path) {
try {
input.setText("");
output.setText("");
File project = new File(path);
BufferedReader reader = new BufferedReader(new FileReader(path));
String line;
while ((line=reader.readLine())!=null)
input.getDocument().insertString(input.getDocument().getLength(), line+"\n", null);
reader.close();
currentProject = project.getName().substring(0, project.getName().lastIndexOf("."));
list.setSelectedValue(currentProject, true);
setTitle("PseuCo IDE "+Start.version+" - "+currentProject);
} catch (IOException | BadLocationException e) {
if (Start.debug) e.printStackTrace();
}
}
/**
* Take a path string to save the current project to a file *.pseuco
* @param path
*/
private void savePseuCo(String path) {
try {
if (!path.endsWith(".pseuco"))
path += ".pseuco";
BufferedWriter writer = new BufferedWriter(new FileWriter(path));
writer.write(input.getText());
writer.close();
} catch (IOException e1) {
if (Start.debug) e1.printStackTrace();
}
}
/**
* Loads an example program into the IDE
*/
private void loadExample() {
try {
BufferedReader reader = new BufferedReader(new FileReader(Start.workspace+System.getProperty("file.separator")+"exampleCount_1.pseuco"));
String line;
while ((line=reader.readLine())!=null)
input.getDocument().insertString(input.getDocument().getLength(), line+"\n", null);
reader.close();
currentProject = "exampleCount_1";
list.setSelectedValue(currentProject, true);
setTitle("PseuCo IDE "+Start.version+" - "+currentProject);
} catch (IOException | BadLocationException e2) {
//if (Start.debug) e2.printStackTrace();
}
}
/**
* Get the name of the current loaded project
* @return current projects name as string
*/
public static String getCurrentProject() {
return currentProject;
}
private class MyDispatcher implements KeyEventDispatcher {
@Override
public boolean dispatchKeyEvent(KeyEvent e) {
if (e.getID() == KeyEvent.KEY_PRESSED && e.isControlDown()) {
if (e.getKeyCode() == KeyEvent.VK_PLUS || e.getKeyCode() == KeyEvent.VK_ADD) {
changeFontSize(1, false);
}
else if (e.getKeyCode() == KeyEvent.VK_MINUS || e.getKeyCode() == KeyEvent.VK_SUBTRACT) {
changeFontSize(-1, false);
}
else if (e.getKeyCode() == KeyEvent.VK_0 || e.getKeyCode() == KeyEvent.VK_NUMPAD0) {
changeFontSize(12, true);
}
}
return false;
}
}
/**
* Checks if the current project exists.
* If not, it shows a warning to the user.
* @return true if the current project has been saved.
*/
protected boolean checkCurrentProject() {
if (! currentProject.isEmpty()) return true;
JOptionPane.showMessageDialog(this, "You have to save your file first, before you can compile it.", "Error", JOptionPane.INFORMATION_MESSAGE);
return false;
}
@Override
public void update(PseucoObservable obj, Object ... args) {
Highlighter hLiter= input.getHighlighter();
Highlighter.HighlightPainter painter= new DefaultHighlighter.DefaultHighlightPainter(Color.GREEN);
input.getHighlighter().removeAllHighlights();
String file= (String) args[0];
int line= (int) args[1];
int startPos= 0, endPos= 0;
String text= input.getText();
if (line == -1 || file == null)
return;
for (int i= 0; i < line; i++) {
startPos= text.indexOf('\n', startPos) + 1;
}
endPos= text.indexOf('\n', startPos) + 1;
try {
hLiter.addHighlight(startPos, endPos, painter);
} catch (BadLocationException e) {
// ignore it, but clear everything. This has to do with
// not knowing the actual pseuco file
input.getHighlighter().removeAllHighlights();
}
}
}