nl.tudelft.goal.SimpleIDE.SimpleIDE Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of simpleidemodules Show documentation
Show all versions of simpleidemodules Show documentation
An IDE for GOAL based on JEdit.
The newest version!
/**
* GOAL interpreter that facilitates developing and executing GOAL multi-agent
* programs. Copyright (C) 2011 K.V. Hindriks, W. Pasman
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see .
*/
package nl.tudelft.goal.SimpleIDE;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.security.Permission;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
import javax.swing.WindowConstants;
import javax.swing.event.CaretListener;
import events.Channel;
import events.Channel.ChannelState;
import goal.OSXAdapter;
import goal.core.runtime.RuntimeManager;
import goal.preferences.DebugPreferences;
import goal.preferences.LoggingPreferences;
import goal.preferences.Preferences;
import goal.tools.BreakpointManager;
import goal.tools.DebugRun;
import goal.tools.IDEGOALInterpreter;
import goal.tools.debugger.IDEDebugger;
import goal.tools.errorhandling.Resources;
import goal.tools.errorhandling.Warning;
import goal.tools.errorhandling.WarningStrings;
import goal.tools.logging.InfoLog;
import goal.tools.logging.Loggers;
import goal.util.Observer;
import nl.tudelft.goal.SimpleIDE.actions.QuitAction;
import nl.tudelft.goal.SimpleIDE.filenodes.AbstractFileNode;
import nl.tudelft.goal.SimpleIDE.menu.IDEMenuBar;
import nl.tudelft.goal.SimpleIDE.preferences.IDEPreferences;
import nl.tudelft.goal.SimpleIDE.prefgui.GUIandFilePreferencePanel;
/**
*
* SimpleIDE is a simple integrated development environment. Contains either a
* simple text editor or an advanced one (jEdit) and additional tools for agent
* introspection and e.g. a message sniffer.
*
*
*/
@SuppressWarnings("serial")
public class SimpleIDE extends JFrame implements IDEfunctionality, IDEState {
private final static Object[][] debugPrefs = { { Channel.ACTIONCOMBO_END, ChannelState.NONE },
{ Channel.ACTIONCOMBO_START, ChannelState.NONE }, { Channel.ACTION_END, ChannelState.NONE },
{ Channel.ACTION_EXECUTED_BUILTIN, ChannelState.NONE },
{ Channel.ACTION_EXECUTED_MESSAGING, ChannelState.NONE },
{ Channel.ACTION_EXECUTED_USERSPEC, ChannelState.VIEW },
{ Channel.ACTION_POSTCOND_EVALUATION, ChannelState.VIEWPAUSE },
{ Channel.ACTION_PRECOND_EVALUATION, ChannelState.VIEWPAUSE }, { Channel.ACTION_START, ChannelState.NONE },
{ Channel.ADOPT_END, ChannelState.NONE }, { Channel.ADOPT_START, ChannelState.NONE },
{ Channel.BB_UPDATES, ChannelState.VIEW }, { Channel.BREAKPOINTS, ChannelState.HIDDENPAUSE },
{ Channel.CALL_ACTION_OR_MODULE, ChannelState.VIEWPAUSE }, { Channel.CLEARSTATE, ChannelState.HIDDEN },
{ Channel.DB_QUERY_END, ChannelState.NONE }, { Channel.DB_QUERY_START, ChannelState.NONE },
{ Channel.DELETE_END, ChannelState.NONE }, { Channel.DELETE_START, ChannelState.NONE },
{ Channel.DROP_END, ChannelState.NONE }, { Channel.DROP_START, ChannelState.NONE },
{ Channel.GB_CHANGES, ChannelState.VIEW }, { Channel.GB_UPDATES, ChannelState.VIEW },
{ Channel.GOAL_ACHIEVED, ChannelState.VIEWPAUSE },
{ Channel.HIDDEN_RULE_CONDITION_EVALUATION, ChannelState.HIDDEN },
{ Channel.INSERT_END, ChannelState.NONE }, { Channel.INSERT_START, ChannelState.NONE },
{ Channel.MAILS, ChannelState.NONE }, { Channel.MAILS_CONDITIONAL_VIEW, ChannelState.CONDITIONALVIEW },
{ Channel.MODULE_ENTRY, ChannelState.VIEWPAUSE }, { Channel.MODULE_EXIT, ChannelState.NONE },
{ Channel.MSQUERY_END, ChannelState.NONE }, { Channel.MSQUERY_START, ChannelState.NONE },
{ Channel.NONE, ChannelState.HIDDEN }, { Channel.PERCEPTS, ChannelState.NONE },
{ Channel.PERCEPTS_CONDITIONAL_VIEW, ChannelState.CONDITIONALVIEW },
{ Channel.PRINT, ChannelState.HIDDENVIEW }, { Channel.REASONING_CYCLE_SEPARATOR, ChannelState.VIEW },
{ Channel.RULE_CONDITIONAL_VIEW, ChannelState.CONDITIONALVIEW },
{ Channel.RULE_CONDITION_EVALUATION, ChannelState.VIEWPAUSE },
{ Channel.RULE_EVAL_CONDITION_DONE, ChannelState.NONE }, { Channel.RULE_EXIT, ChannelState.NONE },
{ Channel.RULE_START, ChannelState.NONE }, { Channel.RUNMODE, ChannelState.HIDDEN },
{ Channel.SLEEP, ChannelState.VIEW }, { Channel.TESTFAILURE, ChannelState.HIDDENPAUSE },
{ Channel.WARNING, ChannelState.HIDDENVIEW } };
// GUI elements
private final IDEMainPanel mainPanel;
private StatusBar statusBar = null;
/**
* Needed for the editor to allow changes in the breakpoints while running.
*/
private final BreakpointManager breakpointManager = new BreakpointManager(IdeFiles.getInstance().getFileRegistry());
/**
* The IDEState observers
*/
private final Set> stateObservers = new HashSet<>();
/**
* The current {@link DebugRun}, or null if nothing is running.
*/
private DebugRun runner = null;
/**
* main function to start the GOAL IDE
*/
public static void main(final String[] args) {
try {
new SimpleIDE();
} catch (final Throwable e) {
e.printStackTrace();
JOptionPane.showMessageDialog(null, Resources.get(WarningStrings.FAILED_IDE_LAUNCH) + e.getMessage() + "\n" //$NON-NLS-1$
+ e.getStackTrace()[0]);
Preferences.initializeAllPrefs(); // try to fix the problem...
}
}
/**
* Creates the IDE interface and related services.
*/
public SimpleIDE() throws ReflectiveOperationException {
// Do not use InfoLog; nothing is subscribed yet.
System.out.println("Launching IDE"); //$NON-NLS-1$
blockSystemExitCall();
DebugPreferences.setDefault(getDefaultPrefs());
/**
* Checks whether logs should be rerouted to console as well. Set to false by
* default. Only to be used for debugging purposes by developers; change via
* settings file.
*/
if (LoggingPreferences.getShowLogsInConsole()) {
Loggers.addConsoleLogger();
}
// Initialize the action factory.
ActionFactory.init(this, this);
// Set look and feel.
setLookAndFeel();
/**
* Set size first, otherwise it is not clear how the fractional values e.g. for
* setDividerLocation work out.
*/
setSize(IDEPreferences.getWinWidth(), IDEPreferences.getWinHeight());
if (IDEPreferences.getRememberWinPos()) {
setLocation(IDEPreferences.getWinX(), IDEPreferences.getWinY());
}
setTitle("GOAL IDE"); //$NON-NLS-1$
setLayout(new BorderLayout());
// Add center panel; do this before adding tool bar which depends on it
// for initialization of buttons.
this.mainPanel = new IDEMainPanel(this);
add(this.mainPanel, BorderLayout.CENTER);
this.statusBar = new StatusBar();
add(this.statusBar, BorderLayout.SOUTH);
// Add menu.
setJMenuBar(new IDEMenuBar());
// Add tool bar.
add(new ToolBar(), BorderLayout.PAGE_START);
setVisible(true);
if (System.getProperty("os.name").equals("Mac OS X")) {
OSXAdapter.setQuitHandler(() -> {
try {
ActionFactory.getAction(QuitAction.class).Execute(null, null);
} catch (final Exception e) {
e.printStackTrace();
}
});
}
// Disable default close operation and install quit "button" handler.
setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(final WindowEvent e) {
try {
ActionFactory.getAction(QuitAction.class).Execute(null, null);
} catch (final Exception er) {
System.out.println("BUG: QUIT FAILED"); //$NON-NLS-1$
er.printStackTrace();
}
}
});
addComponentListener(new ComponentAdapter() {
@Override
public void componentMoved(final ComponentEvent e) {
IDEPreferences.setLastWinPos(getLocation());
}
@Override
public void componentResized(final ComponentEvent e) {
IDEPreferences.setLastWinSize(getSize());
}
});
// Set initial content of file panel.
// TODO move application logic to platform manager.
if (IDEPreferences.getReopenMASs()) {
reopenMASs();
}
if (IDEPreferences.getReopenSpurious()) {
reopenSpurious();
}
// IDE state has been configured. Broadcast the info.
ActionFactory.broadcastStateChange();
}
private Map getDefaultPrefs() {
final Map map = new HashMap<>();
for (final Object[] keyvalue : debugPrefs) {
map.put(keyvalue[0].toString(), keyvalue[1].toString());
}
return map;
}
/**
* Blocks calls to System.exit()
*/
private void blockSystemExitCall() {
final SecurityManager securityManager = new SecurityManager() {
@Override
public void checkPermission(final Permission permission) {
if (permission.getName().startsWith("exitVM")) {
throw new SecurityException("Thread " + Thread.currentThread() + " attempted to call System.exit");
}
}
@Override
public void checkPermission(final Permission perm, final Object context) {
checkPermission(perm);
}
};
System.setSecurityManager(securityManager);
}
/**
* re-open spurious files that were open last time.
*/
private void reopenSpurious() {
new InfoLog("Re-opening other files...").emit();
for (final String path : IDEPreferences.getOtherFiles()) {
IdeFiles.getInstance().add(new File(path));
}
}
/**
* Initialize the content of the {@link FilePanel} by re-opening the saved MAS
* project files.
*/
private void reopenMASs() {
new InfoLog("Re-opening MAS projects...").emit();
for (final String mas : IDEPreferences.getMASs()) {
IdeFiles.getInstance().add(new File(mas));
}
}
/**
* Sets look and feel. Gets preference settings from
* {@link GUIandFilePreferencePanel}.
*/
private void setLookAndFeel() {
try {
switch (IDEPreferences.getLAF()) {
case "Nimbus":
UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
break;
case "System":
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
break;
default:
break;
}
} catch (final Exception e) {
new Warning(Resources.get(WarningStrings.FAILED_LAF_NIMBUS), e).emit();
}
UIManager.put("TextArea.font",
UIManager.getFont("TextArea.font").deriveFont((float) IDEPreferences.getConsoleFontSize()));
}
@Override
public IDEMainPanel getMainPanel() {
return this.mainPanel;
}
@Override
public CaretListener getStatusBar() {
return this.statusBar;
}
@Override
public String toString() {
return "SimpleIDE[" + getName() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
}
@Override
public JFrame getFrame() {
return this;
}
/************************************************/
/************ implements IDEState ***************/
/************************************************/
@Override
public Component getRootComponent() {
return this;
}
@Override
public int getViewMode() {
if (this.mainPanel == null) {
return 0;
}
return this.mainPanel.getView();
}
@Override
public RuntimeManager getRuntime() {
if (this.runner == null) {
return null;
}
return this.runner.getManager();
}
@Override
public void setRuntime(final DebugRun run) {
if (this.runner != null) {
this.runner.cleanup();
}
this.runner = run;
}
@Override
public BreakpointManager getBreakpointManager() {
return this.breakpointManager;
}
@Override
public List extends IDENode> getSelectedProcessNodes() {
return this.mainPanel.getProcessPanel().getSelectedNodes();
}
@Override
public List extends AbstractFileNode> getSelectedFileNodes() {
return this.mainPanel.getFilePanel().getSelectedNodes();
}
@Override
public void addObserver(final Observer observer) {
this.stateObservers.add(observer);
}
@Override
public void removeObserver(final Observer observer) {
this.stateObservers.remove(observer);
}
@Override
public void notifyObservers(final IDEState src, final Object obj) {
for (final Observer obs : this.stateObservers) {
try {
obs.eventOccured(src, null);
} catch (final Exception e) {
e.printStackTrace(); // how to report?
}
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy