nl.tudelft.goal.SimpleIDE.FeedbackPanel 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.AWTEvent;
import java.awt.Component;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import javax.swing.JComponent;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import events.Channel;
import goal.core.agent.Agent;
import goal.core.runtime.RuntimeEvent;
import goal.core.runtime.RuntimeEventObserver;
import goal.core.runtime.RuntimeManager;
import goal.preferences.DebugPreferences;
import goal.tools.IDEGOALInterpreter;
import goal.tools.errorhandling.Resources;
import goal.tools.errorhandling.Warning;
import goal.tools.errorhandling.WarningStrings;
import languageTools.program.agent.AgentId;
import nl.tudelft.goal.SimpleIDE.CloseTabbedPane.CloseTabbedPane;
import nl.tudelft.goal.SimpleIDE.CloseTabbedPane.TabCloseListener;
import nl.tudelft.goal.SimpleIDE.preferences.IDEPreferences;
/**
* Shows the console, action, and other user feedback panels. The FeedbackPanel
* is the lower area of the IDE panel holding. Subscribes to the Platform
* Manager in order to show the messages sent by agents.
*/
public class FeedbackPanel extends CloseTabbedPane
implements RuntimeEventObserver, TabCloseListener, PropertyChangeListener, ChangeListener {
/**
*
*/
private static final long serialVersionUID = 8369272852845355060L;
/**
* Main console panel for platform, logging, and error output.
*/
private final ConsoleTextPanel console = new ConsoleTextPanel();
/**
* Panel that displays information about parsing of files.
*/
// private final LogTextTrackingScrollPane parseTab = new
// LogTextTrackingScrollPane(""); //$NON-NLS-1$
private final ParserMessagesPanel parseTab = new ParserMessagesPanel();
/**
* Panel that only records the actions that have been performed by agents.
*/
private final ActionHistoryTextPanel actionLog = new ActionHistoryTextPanel("historyOfActions"); //$NON-NLS-1$
/**
* Debug tracer tabs that are available.
*/
private final ConcurrentHashMap tracers = new ConcurrentHashMap<>();
/**
* Main feedback panel with console, parsing, action history tabs and debug
* tracers.
*/
public FeedbackPanel() {
// Add fixed panes.
add("Console", this.console); //$NON-NLS-1$
add("Parse Info", this.parseTab); //$NON-NLS-1$
add("Action log", this.actionLog); //$NON-NLS-1$
// this.parseTab.subscribeTo(Loggers.getParserLogger());
// Parsing is not done at runtime, so we can immediately print
// everything.
// this.parseTab.setPushLevel(Level.ALL);
// Listen to our own change events (when selected tab changes).
addChangeListener(this);
// Listen to close button.
setCloseListener(this);
// Listen to changes user makes to preferences.
DebugPreferences.addChangeListener(this);
}
/**
* Creates debug tracer tab for an agent.
*
* @param agent
* The agent to be traced in the debug tab.
*/
public void openDebugTracer(final Agent agent) {
if (this.tracers.containsKey(agent.getId())) {
// nothing to do; silently return.
return;
}
// Create new tab.
final DebugTextPanel tracer = new DebugTextPanel(agent);
this.tracers.put(agent.getId(), tracer);
// Add it to this feedback panel.
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
add(agent.getId().toString(), tracer);
}
});
}
// ********************** OBSERVER METHODS ***********************/
/**
* Handles events from {@link RuntimeManager}.
*
* @param observable
* The {@link MonitoringService}.
* @param argument
* A {@link RuntimeEvent} event.
*/
@SuppressWarnings("unchecked")
@Override
public void eventOccured(RuntimeManager, ?> observable, RuntimeEvent event) {
Object source = event.getSource();
Agent agent;
switch (event.getType()) {
case MAS_BORN:
this.actionLog.setText(""); //$NON-NLS-1$
break;
case AGENT_IS_LOCAL_AND_READY:
agent = (Agent) source;
// Check whether we should open a debug tracer for the agent.
if (IDEPreferences.getOpenDebugTraceTabAtAgentLaunch()) {
openDebugTracer(agent);
}
// Subscribe the actionLog panel (only if user wants to see
// actions).
this.actionLog.subscribeToDebugger(agent.getController().getDebugger());
break;
case MAS_DIED:
Set agentIds = this.tracers.keySet();
for (AgentId id : agentIds) {
int i = indexOfTab(id.toString());
closeTab(i);
}
break;
// case SCHEDULER_SELECTED_AGENT:
// ArrayList agents = (ArrayList) source;
// int index = indexOfTab(agents.get(0).getId().getName());
//
// if (agents.size() == 1
// && (index != -1)
// && (agents.get(0).getDebugger().getRunMode() != RunMode.RUNNING)
// && IDEPreferences.getAutoSwitchDebugTab()) {
// /*
// * possible to switch to unique debug pane switch to and make
// * visible corresponding debug pane for agent only switch if
// * agent is not in RUNNING mode and currently selected index is
// * debug pane
// */
// this.setSelectedIndex(index);
// }
// break;
default:
break;
}
}
/**
* Catch changes in preferences in DebugPreferencePanel, so that views can
* be made and removed when necessary. See
* {@link goal.tools.SimpleIDE.preferences.DebugPreferencePane}.
*/
@Override
public void propertyChange(PropertyChangeEvent evt) {
Channel channel = null;
try {
channel = Channel.valueOf(evt.getPropertyName());
} catch (IllegalArgumentException ex) {
// ignore non-channel keys
return;
}
handleChannelViewUpdateEvent(channel, DebugPreferences.getChannelState(channel).canView());
}
/**
* Handles view update event from user related to debug output preferences.
* See DebugPreferencePane.
*
* @param channel
* channel for which user has updated viewing preference.
* @param value
* true if user wants to view channel, false otherwise.
*/
private void handleChannelViewUpdateEvent(Channel channel, boolean value) {
for (DebugTextPanel tracer : this.tracers.values()) {
if (value) {
tracer.addViewChannel(channel);
} else {
tracer.removeViewChannel(channel);
}
}
}
/**
* called back when tab close button is pressed
*/
@Override
public void closeOperation(AWTEvent e, int tabIndex) {
closeTab(tabIndex);
}
/**
* Closes a given tab, but only if it is a debug tracer tab.
*
* @param tabIndex
* Index to find the tab.
*/
private void closeTab(final int tabIndex) {
/**
* Events give us an index, but we need to convert to an object as soon
* as possible because the number of tabs and order may change any time,
* particularly during shutdown.
*/
final Component c = getComponentAt(tabIndex);
if (c instanceof DebugTextPanel) {
this.tracers.values().remove(c);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
((DebugTextPanel) c).cleanUp();
remove(c);
} catch (Exception ex) {
new Warning(Resources.get(WarningStrings.FAILED_TAB_CLOSE), ex).emit();
}
}
});
}
}
@Override
public void stateChanged(ChangeEvent e) {
// this is called whenever this panel changes state.
// that is, whenever another tab is selected, and just before
// this panel is (re)painted.
JComponent tab = (JComponent) getSelectedComponent();
if (tab instanceof MarkedReadable) {
((MarkedReadable) tab).markRead();
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy