/*
* 2014 - removed SAVE ALL button and command since it was not working
*/
package edu.princeton.toy;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import edu.princeton.swing.*;
import edu.princeton.swing.text.*;
import edu.princeton.toy.lang.*;
public class TFrame extends JFrame implements ActionListener, ChangeListener, TextListener,
ListSelectionListener,
TVirtualMachine.ExecutionController
{
private static final String CLASS_STRING = TFrame.class.toString();
/**
* The displacement in the x direction between cascaded windows.
*/
public static final int CASCADE_X = 24;
/**
* The displacement in the y direction between cascaded windows.
*/
public static final int CASCADE_Y = 24;
public static final String NEW_COMMAND = CLASS_STRING + "#newCommand";
public static final String OPEN_COMMAND = CLASS_STRING + "#openCommand";
public static final String OPEN_EXAMPLE_COMMAND = CLASS_STRING + "#openExampleCommand";
public static final String CLOSE_COMMAND = CLASS_STRING + "#closeCommand";
public static final String REVERT_COMMAND = CLASS_STRING + "#revertCommand";
public static final String SAVE_COMMAND = CLASS_STRING + "#saveCommand";
// public static final String SAVE_ALL_COMMAND = CLASS_STRING + "#saveAllCommand";
public static final String SAVE_AS_COMMAND = CLASS_STRING + "#saveAsCommand";
public static final String QUIT_COMMAND = CLASS_STRING + "#quitCommand";
public static final String EDIT_MODE_COMMAND = CLASS_STRING + "#editModeCommand";
public static final String DEBUG_MODE_COMMAND = CLASS_STRING + "#debugModeCommand";
public static final String SIM_MODE_COMMAND = CLASS_STRING + "#simModeCommand";
public static final String LOOK_COMMAND = CLASS_STRING + "#lookCommand";
public static final String LOAD_COMMAND = CLASS_STRING + "#loadCommand";
public static final String RESET_COMMAND = CLASS_STRING + "#resetCommand";
public static final String STEP_COMMAND = CLASS_STRING + "#stepCommand";
public static final String RUN_COMMAND = CLASS_STRING + "#runCommand";
public static final String INTERRUPT_COMMAND = CLASS_STRING + "#interruptCommand";
public static final String ENTER_COMMAND = CLASS_STRING + "#enterCommand";
public static final String OPEN_STDIN_COMMAND = CLASS_STRING + "#openStdinCommand";
public static final String SAVE_STDIN_COMMAND = CLASS_STRING + "#saveStdinCommand";
public static final String SAVE_STDOUT_COMMAND = CLASS_STRING + "#saveStdoutCommand";
public static final String SAVE_MEM_DUMP_COMMAND = CLASS_STRING + "#saveMemDumpCommand";
public static final String SAVE_CORE_DUMP_COMMAND = CLASS_STRING + "#saveCoreDumpCommand";
public static final String WORKSPACE_COMMAND = CLASS_STRING + "#workspaceCommand";
public static final String CHECK_SYNTAX_COMMAND = CLASS_STRING + "#checkSyntaxCommand";
public static final String FUNCTION_COMMAND = CLASS_STRING + "#functionCommand";
public static final String CHANGE_EXECUTION_COMMAND = CLASS_STRING + "#changeExecutionCommand";
public static final String CLEAR_ODOMETER_COMMAND = CLASS_STRING + "#clearOdometerCommand";
public static final String CHANGE_CHECKING_COMMAND = CLASS_STRING + "#changeCheckingCommand";
public static final String HIDE_WARNINGS_COMMAND = CLASS_STRING + "#hideWarningsCommand";
private static final List FRAMES = new ArrayList();
private static Object FRAMES_ARRAY[] = new Object[20];
private static final Runner RUNNER = new Runner();
private static final Toolkit TOOLKIT = Toolkit.getDefaultToolkit();
private static final ExtensionFileFilter TOY_FILE_FILTER =
new ExtensionFileFilter("toy", "Toy Program File");
private static final ExtensionFileFilter TXT_FILE_FILTER =
new ExtensionFileFilter("txt", "Text File");
private static final ListModel BLANK_LIST_MODEL = new DefaultListModel();
private static final Border PADDING_BORDER = new EmptyBorder(2, 2, 2, 2);
private TFrameAction newAction, openAction, openExampleAction, closeAction, revertAction,
saveAction, saveAsAction, saveAllAction, quitAction;
private TFrameAction editModeAction, debugModeAction, simModeAction, lookAction, loadAction,
resetAction, stepAction, runAction, interruptAction, enterAction;
private TFrameAction openStdinAction, saveStdinAction, saveStdoutAction, saveMemDumpAction,
saveCoreDumpAction;
private TFrameAction checkSyntaxAction, functionAction;
private boolean isNew;
private TProgramDocument program;
private boolean programChanged;
private String oldTitle;
private boolean wasSaved;
private File file;
private String savedText;
private ArrayList warningSelectionDots, warningSelectionMarks;
private boolean hasFatalError;
private TVirtualMachine virtualMachine;
private TWordBuffer tempBuffer;
private ActionedUndoManager undoManager;
private TProgramDocument.WarningInfoStruct previousWarnings;
private TProgramDocument.WarningInfoStruct currentWarnings;
private String mode;
private ButtonModel menuEditModeButtonModel;
private ButtonModel menuDebugModeButtonModel;
private ButtonModel menuSimModeButtonModel;
private ButtonGroup menuModeButtonGroup;
private JMenu workspaceMenu;
private int workspaceIndex;
private JPanel cardPanel;
private CardLayout cardLayout;
private JSplitPane editPane;
private JSplitPane leftEditPane;
private JPanel bottomLeftEditPane;
private PHighlightedTextArea editTextArea;
private TReferencePane editReferencePane;
private TStdinPane editStdinPane;
private PScrollablePanel warningListPanel;
private PWrappedList warningList;
private PList warningTallyList;
private JSplitPane debugPane;
private PHighlightedTextArea debugTextArea;
private Object odometerLock;
private PTextField stepsTakenTextField;
private int stepsTaken;
private PTextField elapsedTimeTextField;
private int elapsedTime;
private JTabbedPane rightDebugPane;
private TReferencePane debugReferencePane;
private TStdinPane debugStdinPane;
private TStdoutPane debugStdoutPane;
private TCorePane debugCorePane;
private JSplitPane simPane;
private JSplitPane leftSimPane;
private TSimMachinePane simMachinePane;
private TSimDetailPane simDetailPane;
private JTabbedPane rightSimPane;
private TSimMemPane simMemPane;
private TSimStdinPane simStdinPane;
private TSimStdoutPane simStdoutPane;
private TSimStdin2Pane simStdin2Pane;
private TSimStdout2Pane simStdout2Pane;
private JPanel simPanel;
public TFrame()
{
this(new TProgramDocument(), null);
isNew = true;
}
public TFrame(TProgramDocument program)
{
this(program, null);
}
public TFrame(TProgramDocument program, File file)
{
super();
if (program == null)
throw new NullPointerException();
isNew = false;
wasSaved = false;
this.file = file;
savedText = program.getText();
warningSelectionDots = new ArrayList();
warningSelectionMarks = new ArrayList();
this.program = program;
program.addTextListener(this);
mode = EDIT_MODE_COMMAND;
previousWarnings = new TProgramDocument.WarningInfoStruct();
currentWarnings = new TProgramDocument.WarningInfoStruct();
virtualMachine = new TVirtualMachine();
program.reset(virtualMachine);
virtualMachine.addChangeListener(this);
tempBuffer = new TWordBuffer();
odometerLock = new Object();
stepsTaken = 0;
elapsedTime = 0;
setIconImage(TMain.getFrameIcon());
// Prepare the undoManager
undoManager = new ActionedUndoManager();
program.addUndoableEditListener(undoManager);
// Prepare the actions
int menuShortcutKeyMask = TOOLKIT.getMenuShortcutKeyMask();
newAction = new TFrameAction(
"New",
TImageManager.getIcon(
TImageManager.REGULAR_UNSCALED_IMAGE_GROUP,
TImageManager.REGULAR_UNSCALED_NEW_ICON
),
KeyEvent.VK_N,
KeyStroke.getKeyStroke(KeyEvent.VK_N, menuShortcutKeyMask),
NEW_COMMAND
);
openAction = new TFrameAction(
"Open...",
TImageManager.getIcon(
TImageManager.REGULAR_UNSCALED_IMAGE_GROUP,
TImageManager.REGULAR_UNSCALED_OPEN_ICON
),
KeyEvent.VK_O,
KeyStroke.getKeyStroke(KeyEvent.VK_O, menuShortcutKeyMask),
OPEN_COMMAND
);
openExampleAction = new TFrameAction(
"Open Example Program...",
TImageManager.getIcon(
TImageManager.REGULAR_UNSCALED_IMAGE_GROUP,
TImageManager.REGULAR_UNSCALED_OPEN_EXAMPLE_ICON
),
KeyEvent.VK_E,
KeyStroke.getKeyStroke(KeyEvent.VK_E, menuShortcutKeyMask),
OPEN_EXAMPLE_COMMAND
);
closeAction = new TFrameAction(
"Close",
null,
KeyEvent.VK_C,
null,
CLOSE_COMMAND
);
revertAction = new TFrameAction(
"Revert",
null,
KeyEvent.VK_R,
null,
REVERT_COMMAND
);
saveAction = new TFrameAction(
"Save",
TImageManager.getIcon(
TImageManager.REGULAR_UNSCALED_IMAGE_GROUP,
TImageManager.REGULAR_UNSCALED_SAVE_ICON
),
KeyEvent.VK_S,
KeyStroke.getKeyStroke(KeyEvent.VK_S, menuShortcutKeyMask),
SAVE_COMMAND
);
saveAsAction = new TFrameAction(
"Save As...",
TImageManager.getIcon(
TImageManager.REGULAR_UNSCALED_IMAGE_GROUP,
TImageManager.REGULAR_UNSCALED_SAVE_AS_ICON
),
KeyEvent.VK_S,
KeyStroke.getKeyStroke(KeyEvent.VK_S, menuShortcutKeyMask | ActionEvent.SHIFT_MASK),
SAVE_AS_COMMAND
);
/* saveAllAction = new TFrameAction(
"Save All",
TImageManager.getIcon(
TImageManager.REGULAR_UNSCALED_IMAGE_GROUP,
TImageManager.REGULAR_UNSCALED_SAVE_ALL_ICON
),
KeyEvent.VK_S,
null,
SAVE_ALL_COMMAND
);
*/
quitAction = new TFrameAction(
"Quit",
null,
KeyEvent.VK_Q,
KeyStroke.getKeyStroke(KeyEvent.VK_Q, menuShortcutKeyMask),
QUIT_COMMAND
);
editModeAction = new TFrameAction(
"Edit Mode",
TImageManager.getIcon(
TImageManager.REGULAR_UNSCALED_IMAGE_GROUP,
TImageManager.REGULAR_UNSCALED_EDIT_MODE_ICON_ON
),
KeyEvent.VK_E,
null,
EDIT_MODE_COMMAND
);
debugModeAction = new TFrameAction(
"Debug Mode",
TImageManager.getIcon(
TImageManager.REGULAR_UNSCALED_IMAGE_GROUP,
TImageManager.REGULAR_UNSCALED_DEBUG_MODE_ICON_OFF
),
KeyEvent.VK_D,
null,
DEBUG_MODE_COMMAND
);
simModeAction = new TFrameAction(
"Sim Mode",
TImageManager.getIcon(
TImageManager.REGULAR_UNSCALED_IMAGE_GROUP,
TImageManager.REGULAR_UNSCALED_SIM_MODE_ICON_OFF
),
KeyEvent.VK_S,
null,
SIM_MODE_COMMAND
);
lookAction = new TFrameAction(
"Look",
null,
KeyEvent.VK_L,
null,
LOOK_COMMAND
);
lookAction.setEnabled(false);
loadAction = new TFrameAction(
"Load",
null,
KeyEvent.VK_L,
null,
LOAD_COMMAND
);
loadAction.setEnabled(false);
resetAction = new TFrameAction(
"Reset",
TImageManager.getIcon(
TImageManager.REGULAR_UNSCALED_IMAGE_GROUP,
TImageManager.REGULAR_UNSCALED_RESET_ICON
),
KeyEvent.VK_R,
null,
RESET_COMMAND
);
resetAction.setEnabled(false);
stepAction = new TFrameAction(
"Step",
TImageManager.getIcon(
TImageManager.REGULAR_UNSCALED_IMAGE_GROUP,
TImageManager.REGULAR_UNSCALED_STEP_ICON
),
KeyEvent.VK_S,
null,
STEP_COMMAND
);
stepAction.setEnabled(false);
runAction = new TFrameAction(
"Run",
TImageManager.getIcon(
TImageManager.REGULAR_UNSCALED_IMAGE_GROUP,
TImageManager.REGULAR_UNSCALED_RUN_ICON
),
KeyEvent.VK_R,
null,
RUN_COMMAND
);
runAction.setEnabled(false);
interruptAction = new TFrameAction(
"Interrupt",
TImageManager.getIcon(
TImageManager.REGULAR_UNSCALED_IMAGE_GROUP,
TImageManager.REGULAR_UNSCALED_INTERRUPT_ICON
),
KeyEvent.VK_I,
null,
INTERRUPT_COMMAND
);
interruptAction.setEnabled(false);
enterAction = new TFrameAction(
"Enter",
null,
KeyEvent.VK_E,
null,
ENTER_COMMAND
);
enterAction.setEnabled(false);
openStdinAction = new TFrameAction(
"Load File to Stdin...",
null,
KeyEvent.VK_L,
null,
OPEN_STDIN_COMMAND
);
saveStdinAction = new TFrameAction(
"Save Stdin to File...",
null,
KeyEvent.VK_I,
null,
SAVE_STDIN_COMMAND
);
saveStdoutAction = new TFrameAction(
"Save Stdout to File...",
null,
KeyEvent.VK_O,
null,
SAVE_STDOUT_COMMAND
);
saveStdoutAction.setEnabled(false);
saveMemDumpAction = new TFrameAction(
"Save Memory Dump to File...",
null,
KeyEvent.VK_M,
null,
SAVE_MEM_DUMP_COMMAND
);
saveMemDumpAction.setEnabled(false);
saveCoreDumpAction = new TFrameAction(
"Save Core to File...",
null,
KeyEvent.VK_C,
null,
SAVE_CORE_DUMP_COMMAND
);
saveCoreDumpAction.setEnabled(false);
checkSyntaxAction = new TFrameAction(
"Check Syntax",
TImageManager.getIcon(
TImageManager.REGULAR_UNSCALED_IMAGE_GROUP,
TImageManager.REGULAR_UNSCALED_CHECK_SYNTAX_ICON
),
KeyEvent.VK_C,
KeyStroke.getKeyStroke(KeyEvent.VK_C, menuShortcutKeyMask | ActionEvent.SHIFT_MASK),
CHECK_SYNTAX_COMMAND,
Boolean.TRUE
);
functionAction = new TFrameAction(
"Insert Function Comment",
null,
KeyEvent.VK_F,
KeyStroke.getKeyStroke(KeyEvent.VK_F, menuShortcutKeyMask),
FUNCTION_COMMAND
);
// Prepare the menu
JMenuBar menuBar;
JMenu menu;
JMenuItem menuItem;
// Create the menu bar.
menuBar = new JMenuBar();
setJMenuBar(menuBar);
// Build the file menu.
{
menu = new JMenu("File");
menu.setMnemonic(KeyEvent.VK_F);
menuBar.add(menu);
menu.add(newAction.createMenuItem());
menu.add(openAction.createMenuItem());
menu.add(openExampleAction.createMenuItem());
menu.add(closeAction.createMenuItem());
menu.add(revertAction.createMenuItem());
menu.addSeparator();
menu.add(saveAction.createMenuItem());
menu.add(saveAsAction.createMenuItem());
//menu.add(saveAllAction.createMenuItem());
menu.addSeparator();
for (int ctr = 0; ctr < TOptionsFrame.FILE_HISTORY_SIZE; ctr++) {
menuItem = TOptionsFrame.FILE_HISTORY_ACTIONS[ctr].createMenuItem();
menu.add(menuItem);
}
menu.addSeparator();
menu.add(quitAction.createMenuItem());
}
{
// Build the edit menu
menu = new JMenu("Edit");
menu.setMnemonic(KeyEvent.VK_E);
menuBar.add(menu);
menu.add(undoManager.getUndoAction().createMenuItem());
menu.add(undoManager.getRedoAction().createMenuItem());
menu.addSeparator();
menu.add(ClipboardTargetManager.CUT_ACTION.createMenuItem());
menu.add(ClipboardTargetManager.COPY_ACTION.createMenuItem());
menu.add(ClipboardTargetManager.PASTE_ACTION.createMenuItem());
menu.addSeparator();
menu.add(ClipboardTargetManager.SELECT_ALL_ACTION.createMenuItem());
}
{
// Build the mode menu
menu = new JMenu("Mode");
menu.setMnemonic(KeyEvent.VK_M);
menuBar.add(menu);
menuModeButtonGroup = new ButtonGroup();
JRadioButtonMenuItem rbMenuItem;
rbMenuItem = new JRadioButtonMenuItem(editModeAction);
rbMenuItem.setAccelerator(editModeAction.getAccelerator());
rbMenuItem.setSelected(true);
menuEditModeButtonModel = rbMenuItem.getModel();
menuModeButtonGroup.add(rbMenuItem);
menu.add(rbMenuItem);
rbMenuItem = new JRadioButtonMenuItem(debugModeAction);
rbMenuItem.setAccelerator(debugModeAction.getAccelerator());
menuDebugModeButtonModel = rbMenuItem.getModel();
menuModeButtonGroup.add(rbMenuItem);
menu.add(rbMenuItem);
rbMenuItem = new JRadioButtonMenuItem(simModeAction);
rbMenuItem.setAccelerator(simModeAction.getAccelerator());
menuSimModeButtonModel = rbMenuItem.getModel();
menuModeButtonGroup.add(rbMenuItem);
menu.add(rbMenuItem);
menu.addSeparator();
menu.add(resetAction.createMenuItem());
menu.add(stepAction.createMenuItem());
menu.add(runAction.createMenuItem());
menu.add(interruptAction.createMenuItem());
menu.addSeparator();
menu.add(openStdinAction.createMenuItem());
menu.add(saveStdinAction.createMenuItem());
menu.add(saveStdoutAction.createMenuItem());
menu.add(saveMemDumpAction.createMenuItem());
menu.add(saveCoreDumpAction.createMenuItem());
}
{
// Build a tentative workspace menu
menu = new JMenu("Workspace");
menu.setMnemonic(KeyEvent.VK_W);
menuBar.add(menu);
workspaceMenu = menu;
}
{
// Build a tools menu
menu = new JMenu("Tools");
menu.setMnemonic(KeyEvent.VK_T);
menuBar.add(menu);
menu.add(checkSyntaxAction.createMenuItem());
menu.add(functionAction.createMenuItem());
menu.addSeparator();
menu.add(TOptionsFrame.OPTIONS_ACTION.createMenuItem());
}
getContentPane().setLayout(new BorderLayout());
{ // Prepare the toolbar
JToolBar toolbar = new JToolBar();
toolbar.add(newAction).setToolTipText("New");
toolbar.add(openAction).setToolTipText("Open...");
toolbar.add(openExampleAction).setToolTipText("Open Example...");
toolbar.add(saveAction).setToolTipText("Save");
toolbar.add(saveAsAction).setToolTipText("Save As...");
//toolbar.add(saveAllAction).setToolTipText("Save All");
toolbar.addSeparator();
toolbar.add(ClipboardTargetManager.CUT_ACTION).setToolTipText("Cut");
toolbar.add(ClipboardTargetManager.COPY_ACTION).setToolTipText("Copy");
toolbar.add(ClipboardTargetManager.PASTE_ACTION).setToolTipText("Paste");
toolbar.add(ClipboardTargetManager.SELECT_ALL_ACTION).setToolTipText("Select All");
toolbar.addSeparator();
toolbar.add(undoManager.getUndoAction()).setToolTipText("Undo");
toolbar.add(undoManager.getRedoAction()).setToolTipText("Redo");
toolbar.addSeparator();
toolbar.add(editModeAction).setToolTipText("Edit Mode");
toolbar.add(debugModeAction).setToolTipText("Debug Mode");
toolbar.add(simModeAction).setToolTipText("Sim Mode");
toolbar.addSeparator();
toolbar.add(checkSyntaxAction).setToolTipText("Check Syntax");
getContentPane().add(toolbar, BorderLayout.NORTH);
}
{ // Prepare the card panel
cardLayout = new CardLayout();
cardPanel = new JPanel(cardLayout);
cardPanel.setBorder(new EmptyBorder(2, 2, 2, 2));
{ // Prepare the edit pane
editPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
{ // Prepare the left edit pane
leftEditPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
if (leftEditPane.getBorder() == null)
{
leftEditPane.setBorder(PADDING_BORDER);
}
else {
leftEditPane.setBorder(
new CompoundBorder(
PADDING_BORDER,
leftEditPane.getBorder()
)
);
}
{ // Prepare the text area
editTextArea = new PHighlightedTextArea(
program,
25,
TProgramDocument.OUTSIDE_MARGIN_COLUMN + 2
);
TOptionsFrame.registerComponent(
editTextArea,
TOptionsFrame.PROGRAM_AREA_INDEX
);
TOptionsFrame.registerHighlightedTextArea(editTextArea);
int columnMarkers[] = new int[3];
columnMarkers[0] = 8;
columnMarkers[1] = TProgramDocument.COMMENT_COLUMN;
columnMarkers[2] = TProgramDocument.OUTSIDE_MARGIN_COLUMN;
editTextArea.setColumnMarkers(columnMarkers);
JPopupMenu popupMenu = editTextArea.getPopupMenu();
popupMenu.removeAll();
popupMenu.add(undoManager.getUndoAction().createMenuItem());
popupMenu.add(undoManager.getRedoAction().createMenuItem());
popupMenu.addSeparator();
popupMenu.add(ClipboardTargetManager.CUT_ACTION.createMenuItem());
popupMenu.add(ClipboardTargetManager.COPY_ACTION.createMenuItem());
popupMenu.add(ClipboardTargetManager.PASTE_ACTION.createMenuItem());
popupMenu.addSeparator();
popupMenu.add(ClipboardTargetManager.SELECT_ALL_ACTION.createMenuItem());
popupMenu.addSeparator();
popupMenu.add(checkSyntaxAction.createMenuItem());
popupMenu.add(functionAction.createMenuItem());
leftEditPane.setTopComponent(editTextArea);
}
{ // Prepare the bottom left pane
bottomLeftEditPane = new JPanel(new GridBagLayout());
bottomLeftEditPane.add(
new JLabel("Warnings"),
new GridBagConstraints(
0, 0, 1, 1,
1.0, 0.0,
GridBagConstraints.WEST,
GridBagConstraints.NONE,
new Insets(2, 2, 2, 2),
0, 0
)
);
PHyperlink hyperlink = new PHyperlink(
"Change Settings...",
null,
PHyperlink.METAL_STYLE
);
hyperlink.setActionCommand(CHANGE_CHECKING_COMMAND);
hyperlink.addActionListener(this);
bottomLeftEditPane.add(
hyperlink,
new GridBagConstraints(
1, 0, 1, 1,
0.0, 0.0,
GridBagConstraints.WEST,
GridBagConstraints.NONE,
new Insets(2, 2, 2, 2),
0, 0
)
);
hyperlink = new PHyperlink(
"Hide Warnings",
null,
PHyperlink.METAL_STYLE
);
hyperlink.setActionCommand(HIDE_WARNINGS_COMMAND);
hyperlink.addActionListener(this);
bottomLeftEditPane.add(
hyperlink,
new GridBagConstraints(
2, 0, 1, 1,
0.0, 0.0,
GridBagConstraints.WEST,
GridBagConstraints.NONE,
new Insets(2, 2, 2, 2),
0, 0
)
);
{ // Create a concatenation of lists
warningListPanel = new PScrollablePanel(new GridBagLayout());
warningListPanel.setFont(null);
warningListPanel.setWidthTrackingPolicy(
PScrollablePanel.TRACKING_POLICY_ALWAYS
);
TOptionsFrame.registerComponent(
warningListPanel,
TOptionsFrame.WARNING_AREA_INDEX
);
{ // Prepare the warning list
warningList = new PWrappedList();
warningList.setFont(null);
warningList.setVisibleRowCount(10);
warningList.addListSelectionListener(this);
warningListPanel.add(
warningList,
new GridBagConstraints(
0, 0, 1, 1,
1.0, 0.0,
GridBagConstraints.NORTHWEST,
GridBagConstraints.BOTH,
new Insets(0, 0, 0, 0),
0, 0
)
);
}
{ // Prepare the warning list
warningTallyList = new PWrappedList();
warningTallyList.setFont(null);
warningTallyList.setEnabled(false);
warningListPanel.add(
warningTallyList,
new GridBagConstraints(
0, 1, 1, 1,
1.0, 1.0,
GridBagConstraints.NORTHWEST,
GridBagConstraints.BOTH,
new Insets(0, 0, 0, 0),
0, 0
)
);
}
bottomLeftEditPane.add(
new JScrollPane(
warningListPanel,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER
),
new GridBagConstraints(
0, 1, 3, 1,
1.0, 1.0,
GridBagConstraints.CENTER,
GridBagConstraints.BOTH,
new Insets(2, 2, 2, 2),
0, 0
)
);
}
leftEditPane.setBottomComponent(bottomLeftEditPane);
}
leftEditPane.setOneTouchExpandable(true);
leftEditPane.setResizeWeight(0.8);
editPane.setLeftComponent(leftEditPane);
}
{ // Prepare the right edit pane
JTabbedPane rightEditPane = new JTabbedPane(
JTabbedPane.TOP
);
{
editReferencePane = new TReferencePane();
TOptionsFrame.registerComponent(
editReferencePane,
TOptionsFrame.REFERENCE_AREA_INDEX
);
rightEditPane.addTab("Reference", editReferencePane);
}
{
editStdinPane = new TStdinPane(
virtualMachine,
openStdinAction,
saveStdinAction,
false
);
TOptionsFrame.registerComponent(
editStdinPane,
TOptionsFrame.STDIN_AREA_INDEX
);
rightEditPane.addTab("Stdin", editStdinPane);
}
editPane.setRightComponent(rightEditPane);
}
editPane.setOneTouchExpandable(true);
editPane.setResizeWeight(0.9);
cardPanel.add(editPane, EDIT_MODE_COMMAND);
}
{ // Prepare the debug pane
debugPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
{ // Prepare the left side of the debug pane
JPanel debugLeftPane = new JPanel(new GridBagLayout());
{ // Prepare the text area
debugTextArea = new PHighlightedTextArea(
program,
25,
TProgramDocument.OUTSIDE_MARGIN_COLUMN + 2
);
TOptionsFrame.registerComponent(
debugTextArea,
TOptionsFrame.PROGRAM_AREA_INDEX
);
TOptionsFrame.registerHighlightedTextArea(debugTextArea);
debugTextArea.setEditable(false);
int columnMarkers[] = new int[3];
columnMarkers[0] = 8;
columnMarkers[1] = TProgramDocument.COMMENT_COLUMN;
columnMarkers[2] = TProgramDocument.OUTSIDE_MARGIN_COLUMN;
debugTextArea.setColumnMarkers(columnMarkers);
debugLeftPane.add(
debugTextArea,
new GridBagConstraints(
0, 0, 2, 1,
1.0, 1.0,
GridBagConstraints.NORTHWEST,
GridBagConstraints.BOTH,
new Insets(2, 2, 2, 2),
0, 0
)
);
}
{ // Prepare the stats panel
JPanel statsPanel = new JPanel(new GridBagLayout());
JTextField textField;
PHyperlink hyperlink;
statsPanel.add(
new JLabel("Steps Taken"),
new GridBagConstraints(
0, 0, 1, 1,
0.0, 0.0,
GridBagConstraints.WEST,
GridBagConstraints.NONE,
new Insets(2, 2, 2, 2),
0, 0
)
);
stepsTakenTextField = new PTextField(12);
stepsTakenTextField.setEditable(false);
stepsTakenTextField.setBackground(null);
stepsTakenTextField.setDisabledTextColor(Color.black);
stepsTakenTextField.setText("0");
stepsTakenTextField.setMinimumSize(stepsTakenTextField.getPreferredSize());
statsPanel.add(
stepsTakenTextField,
new GridBagConstraints(
1, 0, 1, 1,
0.0, 1.0,
GridBagConstraints.WEST,
GridBagConstraints.BOTH,
new Insets(2, 2, 2, 2),
00, 0
)
);
hyperlink = new PHyperlink("Clear", null, PHyperlink.METAL_STYLE);
hyperlink.setActionCommand(CLEAR_ODOMETER_COMMAND);
hyperlink.addActionListener(this);
statsPanel.add(
hyperlink,
new GridBagConstraints(
2, 0, 2, 1,
1.0, 0.0,
GridBagConstraints.WEST,
GridBagConstraints.NONE,
new Insets(2, 2, 2, 2),
0, 0
)
);
statsPanel.add(
new JLabel("Elapsed Time"),
new GridBagConstraints(
0, 1, 1, 1,
0.0, 0.0,
GridBagConstraints.WEST,
GridBagConstraints.NONE,
new Insets(2, 2, 2, 2),
0, 0
)
);
elapsedTimeTextField = new PTextField(12);
elapsedTimeTextField.setEditable(false);
elapsedTimeTextField.setBackground(null);
elapsedTimeTextField.setDisabledTextColor(Color.black);
elapsedTimeTextField.setText("0.000 s");
elapsedTimeTextField.setMinimumSize(
elapsedTimeTextField.getPreferredSize()
);
statsPanel.add(
elapsedTimeTextField,
new GridBagConstraints(
1, 1, 1, 1,
0.0, 1.0,
GridBagConstraints.WEST,
GridBagConstraints.HORIZONTAL,
new Insets(2, 2, 2, 2),
0, 0
)
);
statsPanel.add(
new JLabel("Refresh Rate"),
new GridBagConstraints(
0, 2, 1, 1,
0.0, 0.0,
GridBagConstraints.WEST,
GridBagConstraints.NONE,
new Insets(2, 2, 2, 2),
0, 0
)
);
textField = new JTextField(12);
textField.setEnabled(false);
textField.setBackground(null);
textField.setDisabledTextColor(Color.black);
textField.setDocument(TOptionsFrame.getRefreshRateDocument());
textField.setMinimumSize(textField.getPreferredSize());
statsPanel.add(
textField,
new GridBagConstraints(
1, 2, 1, 1,
0.0, 1.0,
GridBagConstraints.WEST,
GridBagConstraints.HORIZONTAL,
new Insets(2, 2, 2, 2),
0, 0
)
);
hyperlink = new PHyperlink(
"Change Settings...",
null,
PHyperlink.METAL_STYLE
);
hyperlink.setActionCommand(CHANGE_EXECUTION_COMMAND);
hyperlink.addActionListener(this);
statsPanel.add(
hyperlink,
new GridBagConstraints(
2, 2, 2, 1,
1.0, 0.0,
GridBagConstraints.WEST,
GridBagConstraints.NONE,
new Insets(2, 2, 2, 2),
0, 0
)
);
statsPanel.add(
new JLabel("Target Clock Period"),
new GridBagConstraints(
0, 3, 1, 1,
0.0, 1.0,
GridBagConstraints.WEST,
GridBagConstraints.NONE,
new Insets(2, 2, 2, 2),
0, 0
)
);
textField = new JTextField(12);
textField.setEnabled(false);
textField.setBackground(null);
textField.setDisabledTextColor(Color.black);
textField.setDocument(TOptionsFrame.getClockPeriodDocument());
textField.setMinimumSize(textField.getPreferredSize());
statsPanel.add(
textField,
new GridBagConstraints(
1, 3, 1, 1,
0.0, 1.0,
GridBagConstraints.WEST,
GridBagConstraints.HORIZONTAL,
new Insets(2, 2, 2, 2),
0, 0
)
);
debugLeftPane.add(
statsPanel,
new GridBagConstraints(
0, 1, 1, 1,
1.0, 0.0,
GridBagConstraints.NORTHWEST,
GridBagConstraints.HORIZONTAL,
new Insets(2, 2, 2, 2),
0, 0
)
);
}
{ // Prepare the button panel
JPanel buttonPanel = new JPanel(new GridLayout(2, 2, 4, 4));
buttonPanel.add(new JButton(stepAction));
buttonPanel.add(new JButton(runAction));
buttonPanel.add(new JButton(resetAction));
buttonPanel.add(new JButton(interruptAction));
debugLeftPane.add(
buttonPanel,
new GridBagConstraints(
1, 1, 1, 1,
0.0, 0.0,
GridBagConstraints.NORTHEAST,
GridBagConstraints.NONE,
new Insets(2, 2, 2, 2),
0, 0
)
);
}
debugPane.setLeftComponent(debugLeftPane);
}
{ // Prepare the right debug pane
rightDebugPane = new JTabbedPane(JTabbedPane.TOP);
{
debugReferencePane = new TReferencePane();
TOptionsFrame.registerComponent(
debugReferencePane,
TOptionsFrame.REFERENCE_AREA_INDEX
);
rightDebugPane.addTab("Reference", debugReferencePane);
}
{
debugStdinPane = new TStdinPane(
virtualMachine,
openStdinAction,
saveStdinAction,
true
);
TOptionsFrame.registerComponent(
debugStdinPane,
TOptionsFrame.STDIN_AREA_INDEX
);
rightDebugPane.addTab("Stdin", debugStdinPane);
}
{
debugStdoutPane = new TStdoutPane(
virtualMachine,
saveStdoutAction
);
TOptionsFrame.registerComponent(
debugStdoutPane,
TOptionsFrame.STDOUT_AREA_INDEX
);
rightDebugPane.addTab("Stdout", debugStdoutPane);
}
{
debugCorePane = new TCorePane(
virtualMachine,
saveMemDumpAction,
saveCoreDumpAction
);
TOptionsFrame.registerComponent(
debugCorePane,
TOptionsFrame.CORE_AREA_INDEX
);
rightDebugPane.addTab("Core", debugCorePane);
}
debugPane.setRightComponent(rightDebugPane);
}
debugPane.setOneTouchExpandable(true);
debugPane.setResizeWeight(0.9);
cardPanel.add(debugPane, DEBUG_MODE_COMMAND);
}
{ // Prepare the sim pane
simPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
{ // Prepare the left sim pane
leftSimPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
simMachinePane = new TSimMachinePane(
virtualMachine,
loadAction,
lookAction,
stepAction,
runAction,
enterAction,
interruptAction,
resetAction
);
leftSimPane.setTopComponent(simMachinePane);
simDetailPane = new TSimDetailPane(virtualMachine, simMachinePane);
leftSimPane.setBottomComponent(simDetailPane);
int machinePanePreferredHeight = simMachinePane.getPreferredSize().height;
int detailPanePreferredHeight = simDetailPane.getPreferredSize().height;
leftSimPane.setOneTouchExpandable(true);
leftSimPane.setResizeWeight(
(float)machinePanePreferredHeight /
(machinePanePreferredHeight + detailPanePreferredHeight)
);
simPane.setLeftComponent(leftSimPane);
}
{ // Prepare the right sim pane
rightSimPane = new JTabbedPane(JTabbedPane.TOP);
simMemPane = new TSimMemPane(virtualMachine);
rightSimPane.add(
new JScrollPane(
simMemPane,
JScrollPane.VERTICAL_SCROLLBAR_NEVER,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS
),
"Memory"
);
simStdinPane = new TSimStdinPane(virtualMachine);
rightSimPane.add(
new JScrollPane(
simStdinPane,
JScrollPane.VERTICAL_SCROLLBAR_NEVER,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS
),
"Stdin"
);
simStdoutPane = new TSimStdoutPane(virtualMachine);
rightSimPane.add(
new JScrollPane(
simStdoutPane,
JScrollPane.VERTICAL_SCROLLBAR_NEVER,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS
),
"Stdout"
);
simStdin2Pane = new TSimStdin2Pane(virtualMachine);
rightSimPane.add(
new JScrollPane(
simStdin2Pane,
JScrollPane.VERTICAL_SCROLLBAR_NEVER,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS
),
"Stdin'"
);
simStdout2Pane = new TSimStdout2Pane(virtualMachine);
rightSimPane.add(
new JScrollPane(
simStdout2Pane,
JScrollPane.VERTICAL_SCROLLBAR_NEVER,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS
),
"Stdout'"
);
simPane.setRightComponent(rightSimPane);
}
simPane.setOneTouchExpandable(true);
simPane.setResizeWeight(0.9);
cardPanel.add(simPane, SIM_MODE_COMMAND);
}
getContentPane().add(
cardPanel,
BorderLayout.CENTER
);
}
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
synchronized (FRAMES)
{
FRAMES.add(this);
updateTitle();
}
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
doCommand(CHECK_SYNTAX_COMMAND, Boolean.FALSE);
pack();
}
/**
* Override this method to prevent unclean disposals.
*/
public void dispose()
{
doCommand(CLOSE_COMMAND, null);
}
/**
* Updates the title of this window as well as the title in all of the workspace menus.
*/
private void updateTitle()
{
if (file != null)
program.setTitle(file.getName());
String newTitle = program.getTitle();
boolean titleChanged = !newTitle.equals(oldTitle);
boolean isSaved = program.getText().equals(savedText); // possible problem
if (titleChanged || (isSaved != wasSaved))
{
if (isSaved)
setTitle(newTitle + " - Visual X-TOY");
else
setTitle(newTitle + "* - Visual X-TOY");
}
if (titleChanged)
updateAllWorkspaceMenus();
oldTitle = new String(newTitle); // make a copy so comparison will work
wasSaved = isSaved;
}
/**
* Updates all workspace menus to reflect
*/
private static void updateAllWorkspaceMenus()
{
synchronized (FRAMES)
{
int length = FRAMES.size();
FRAMES_ARRAY = FRAMES.toArray(FRAMES_ARRAY);
Object framesArray[] = FRAMES_ARRAY;
String titles[] = new String[length];
for (int frameCtr = 0; frameCtr < length; frameCtr++)
titles[frameCtr] = ((TFrame)framesArray[frameCtr]).program.getTitle();
for (int frameCtr = 0; frameCtr < length; frameCtr++)
{
TFrame frame = (TFrame)framesArray[frameCtr];
JMenu menu = frame.workspaceMenu;
int menuItemCount = frame.workspaceMenu.getItemCount();
frame.workspaceIndex = frameCtr;
// Make sure the workspaceMenu has enough menuItems
for (int ctr = menuItemCount; ctr < length; ctr++)
{
WorkspaceMenuItem menuItem = new WorkspaceMenuItem(ctr);
menuItem.setActionCommand(WORKSPACE_COMMAND);
menuItem.addActionListener(frame);
menu.add(menuItem);
}
for (int ctr = menuItemCount; ctr > length; ctr--)
{
menu.remove(ctr - 1);
}
// Update the titles on the menu items
for (int ctr = 0; ctr < length; ctr++)
{
WorkspaceMenuItem menuItem = (WorkspaceMenuItem)menu.getItem(ctr);
menuItem.setText(titles[ctr]);
menuItem.getModel().setSelected(ctr == frameCtr);
}
}
}
}
/**
* Starts or stops the auto-syntax-check runner.
*
* @param autoCheck Wheter or not the auto-syntax-check runner should be running.
*/
public static void setAutoCheck(boolean autoCheck)
{
synchronized (RUNNER)
{
if (autoCheck)
{
if (RUNNER.runningThread == null)
{
RUNNER.runningThread = new Thread(RUNNER);
RUNNER.runningThread.start();
}
}
else {
RUNNER.runningThread = null;
}
}
}
/**
* Creates the first frame, initializing locations and bounds from the TOptionFrame's memory
* of the last closed TFrame. The frame is also shown and broght to the front.
*
* @return The frame that was instantiated.
*/
public static TFrame createInitialFrame()
{
TFrame frame = new TFrame();
frame.setBounds(TOptionsFrame.getLastFrameBounds());
frame.validate();
frame.simPane.setDividerLocation(TOptionsFrame.getLastVerticalDividerLocation());
frame.leftSimPane.setDividerLocation(
TOptionsFrame.getLastSimHorizontalDividerLocation()
);
frame.editPane.setDividerLocation(TOptionsFrame.getLastVerticalDividerLocation());
frame.leftEditPane.setDividerLocation(
TOptionsFrame.getLastEditHorizontalDividerLocation()
);
frame.validate();
frame.doCommand(EDIT_MODE_COMMAND, null);
frame.setVisible(true);
frame.requestFocus();
frame.toFront();
return frame;
}
/**
* Performs a command based on the argument.
*
* @param command A string representing the command. Note that pointer equality (not string
* equality) is tested here, so it is important to use the string constants defined in this
* class. TFrame.WORKSPACE_COMMAND requires an integer to be appended to it in order to
* distinguish between the arbitrarily large number of other workspaces. An
* IllegalArgumentException will be thrown if the argument is invalid.
* @param extraInfo Any extra information necessary. This is specific to the command:
*
* - TFrame.WORKSPACE_COMMAND needs an Integer object to decide which workspace to launch.
*
- TFrame.OPEN_COMMAND and TFrame.SAVE_AS_COMMAND can take a java.io.File object to read
* from. If null is passed, a JFileDialog will be used to obtain the file to save to.
*
* @return True iff the command was executed sucessfully.
*/
public boolean doCommand(String command, Object extraInfo)
{
////////////////////////////////////////////////////////////////////////////////////////////
if (command == NEW_COMMAND)
{
int x = getX();
int y = getY();
int width = getWidth();
int height = getHeight();
Dimension screenSize = TOOLKIT.getScreenSize();
if (width + CASCADE_X * 3 < screenSize.width &&
height + CASCADE_Y * 3 < screenSize.height)
{
x += CASCADE_X;
y += CASCADE_Y;
if (x + width > screenSize.width || y + height > screenSize.height)
{
x = 0;
y = 0;
}
}
TFrame frame = new TFrame();
frame.setBounds(x, y, width, height);
int dividerLocation;
if (mode == EDIT_MODE_COMMAND)
dividerLocation = editPane.getDividerLocation();
else if (mode == DEBUG_MODE_COMMAND)
dividerLocation = debugPane.getDividerLocation();
else
dividerLocation = simPane.getDividerLocation();
frame.validate();
frame.simPane.setDividerLocation(dividerLocation);
frame.leftSimPane.setDividerLocation(leftSimPane.getDividerLocation());
frame.editPane.setDividerLocation(dividerLocation);
frame.leftEditPane.setDividerLocation(leftEditPane.getDividerLocation());
frame.validate();
frame.setVisible(true);
frame.requestFocus();
frame.toFront();
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////
if (command == OPEN_COMMAND)
{
// Grab the text from the file
File files[];
if (extraInfo == null)
{
JFileChooser chooser = new JFileChooser();
File currentDirectory = TOptionsFrame.getCurrentDirectory();
if (currentDirectory != null)
chooser.setCurrentDirectory(currentDirectory);
chooser.setAcceptAllFileFilterUsed(true);
// This doesn't work in jdk1.3- chooser.setDragEnabled(true);
chooser.addChoosableFileFilter(TOY_FILE_FILTER);
chooser.setFileHidingEnabled(true);
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
chooser.setMultiSelectionEnabled(true);
if (chooser.showOpenDialog(this) != JFileChooser.APPROVE_OPTION)
return false;
currentDirectory = chooser.getCurrentDirectory();
if (currentDirectory != null)
TOptionsFrame.setCurrentDirectory(currentDirectory);
files = chooser.getSelectedFiles();
}
else {
files = new File[1];
files[0] = (File)extraInfo;
}
if (files.length == 0)
return false;
int x = getX();
int y = getY();
int width = getWidth();
int height = getHeight();
Dimension screenSize = TOOLKIT.getScreenSize();
boolean cascade = (width + CASCADE_X * 3 < screenSize.width &&
height + CASCADE_Y * 3 < screenSize.height);
for (int ctr = 0; ctr < files.length; ctr++)
{
StringBuffer buffer = new StringBuffer();
try
{
FileReader fileReader = new FileReader(files[ctr]);
int readChars;
char array[] = new char[100];
do
{
readChars = fileReader.read(array, 0, array.length);
if (readChars != -1)
buffer.append(array, 0, readChars);
}
while (readChars != -1);
fileReader.close();
}
catch (Exception e)
{
e.printStackTrace();
JOptionPane.showMessageDialog(
this,
"An error occurred when reading from the file \"" + files[ctr] + "\".",
"File I/O Error",
JOptionPane.ERROR_MESSAGE
);
return false;
}
// Decide wheter or not to reuse this window
if (files.length == 1 && !virtualMachine.isRunning() &&
program.getText().equals(savedText) ||
ctr == 0 && isNew && !virtualMachine.isRunning() &&
program.getText().equals(savedText))
{
String text = buffer.toString();
isNew = false;
program.setText(text);
savedText = program.getText();
file = files[ctr];
undoManager.discardAllEdits();
updateTitle();
if (mode == EDIT_MODE_COMMAND)
doCommand(CHECK_SYNTAX_COMMAND, Boolean.FALSE);
else
doCommand(RESET_COMMAND, null);
}
else {
TProgramDocument program = new TProgramDocument(buffer.toString());
TFrame frame = new TFrame(program, files[ctr]);
if (cascade)
{
x += CASCADE_X;
y += CASCADE_Y;
if (x + width > screenSize.width || y + height > screenSize.height)
{
x = 0;
y = 0;
}
}
frame.setBounds(x, y, width, height);
int dividerLocation;
if (mode == EDIT_MODE_COMMAND)
dividerLocation = editPane.getDividerLocation();
else if (mode == DEBUG_MODE_COMMAND)
dividerLocation = debugPane.getDividerLocation();
else
dividerLocation = simPane.getDividerLocation();
frame.validate();
frame.simPane.setDividerLocation(dividerLocation);
frame.leftSimPane.setDividerLocation(leftSimPane.getDividerLocation());
frame.editPane.setDividerLocation(dividerLocation);
frame.leftEditPane.setDividerLocation(leftEditPane.getDividerLocation());
frame.validate();
frame.doCommand(mode, null);
frame.setVisible(true);
frame.requestFocus();
frame.toFront();
}
//program.autocomment();
TOptionsFrame.putFileIntoHistory(files[ctr]);
}
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////
if (command == OPEN_EXAMPLE_COMMAND)
{
// Grab the text from the Example Dialog
String exampleText[] = TExampleDialog.showExampleDialog(this);
if (exampleText == null)
return false;
int x = getX();
int y = getY();
int width = getWidth();
int height = getHeight();
Dimension screenSize = TOOLKIT.getScreenSize();
boolean cascade = (width + CASCADE_X * 3 < screenSize.width &&
height + CASCADE_Y * 3 < screenSize.height);
for (int ctr = 0; ctr < exampleText.length; ctr++)
{
// Decide wheter or not to reuse this window
if (exampleText.length == 1 && !virtualMachine.isRunning() &&
program.getText().equals(savedText) ||
ctr == 0 && isNew && !virtualMachine.isRunning() &&
program.getText().equals(savedText))
{
isNew = false;
program.setText(exampleText[ctr]);
savedText = program.getText();
file = null;
undoManager.discardAllEdits();
updateTitle();
if (mode == EDIT_MODE_COMMAND)
doCommand(CHECK_SYNTAX_COMMAND, Boolean.FALSE);
else
doCommand(RESET_COMMAND, null);
}
else {
TProgramDocument program = new TProgramDocument(exampleText[ctr]);
TFrame frame = new TFrame(program, null);
if (cascade)
{
x += CASCADE_X;
y += CASCADE_Y;
if (x + width > screenSize.width || y + height > screenSize.height)
{
x = 0;
y = 0;
}
}
frame.setBounds(x, y, width, height);
int dividerLocation;
if (mode == EDIT_MODE_COMMAND)
dividerLocation = editPane.getDividerLocation();
else if (mode == DEBUG_MODE_COMMAND)
dividerLocation = debugPane.getDividerLocation();
else
dividerLocation = simPane.getDividerLocation();
frame.validate();
frame.simPane.setDividerLocation(dividerLocation);
frame.leftSimPane.setDividerLocation(leftSimPane.getDividerLocation());
frame.editPane.setDividerLocation(dividerLocation);
frame.leftEditPane.setDividerLocation(leftEditPane.getDividerLocation());
frame.validate();
frame.doCommand(mode, null);
frame.setVisible(true);
frame.requestFocus();
frame.toFront();
}
}
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////
if (command == CLOSE_COMMAND)
{
virtualMachine.interrupt();
if (!savedText.equals(program.getText()))
{
boolean done = false;
while (!done)
{
int result = JOptionPane.showConfirmDialog(
this,
"The program \"" + program.getTitle() + "\" has been modified since it was " +
"last saved.\nDo you wish to save before closing the window?",
"Confirm Close Command",
JOptionPane.YES_NO_CANCEL_OPTION,
JOptionPane.WARNING_MESSAGE
);
if (result == JOptionPane.CANCEL_OPTION)
{
return false;
}
else if (result == JOptionPane.YES_OPTION)
{
done = doCommand(SAVE_COMMAND, null);
}
else {
done = true;
}
}
}
setVisible(false);
TOptionsFrame.setLastFrameBounds(getBounds());
if (mode == EDIT_MODE_COMMAND)
TOptionsFrame.setLastVerticalDividerLocation(editPane.getDividerLocation());
else if (mode == DEBUG_MODE_COMMAND)
TOptionsFrame.setLastVerticalDividerLocation(debugPane.getDividerLocation());
else
TOptionsFrame.setLastVerticalDividerLocation(simPane.getDividerLocation());
cardLayout.show(cardPanel, EDIT_MODE_COMMAND);
TOptionsFrame.setLastEditHorizontalDividerLocation(leftEditPane.getDividerLocation());
cardLayout.show(cardPanel, SIM_MODE_COMMAND);
TOptionsFrame.setLastSimHorizontalDividerLocation(leftSimPane.getDividerLocation());
TOptionsFrame.unregisterComponent(
editTextArea,
TOptionsFrame.PROGRAM_AREA_INDEX
);
TOptionsFrame.unregisterHighlightedTextArea(editTextArea);
TOptionsFrame.unregisterComponent(
warningListPanel,
TOptionsFrame.WARNING_AREA_INDEX
);
TOptionsFrame.unregisterComponent(
editReferencePane,
TOptionsFrame.REFERENCE_AREA_INDEX
);
TOptionsFrame.unregisterComponent(
editStdinPane,
TOptionsFrame.STDIN_AREA_INDEX
);
TOptionsFrame.unregisterComponent(
debugTextArea,
TOptionsFrame.PROGRAM_AREA_INDEX
);
TOptionsFrame.unregisterHighlightedTextArea(debugTextArea);
TOptionsFrame.unregisterComponent(
debugReferencePane,
TOptionsFrame.REFERENCE_AREA_INDEX
);
TOptionsFrame.unregisterComponent(
debugStdinPane,
TOptionsFrame.STDIN_AREA_INDEX
);
TOptionsFrame.unregisterComponent(
debugStdoutPane,
TOptionsFrame.STDOUT_AREA_INDEX
);
TOptionsFrame.unregisterComponent(
debugCorePane,
TOptionsFrame.CORE_AREA_INDEX
);
super.dispose();
synchronized (FRAMES)
{
FRAMES.remove(this);
if (FRAMES.size() == 0)
System.exit(0);
updateAllWorkspaceMenus();
}
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////
if (command == REVERT_COMMAND)
{
int result = JOptionPane.showConfirmDialog(
this,
"Reverting to the saved text will cause all of your changes to be lost.\n" +
"Are you sure you wish to do this?",
"Confirm Revert Command",
JOptionPane.YES_NO_OPTION,
JOptionPane.WARNING_MESSAGE
);
if (result == JOptionPane.YES_OPTION)
{
String newText = null;
// Attempt to reload the file if possible
if (file != null)
{
try
{
FileReader fileReader = new FileReader(file);
StringBuffer buffer = new StringBuffer();
int readChars;
char array[] = new char[100];
do
{
readChars = fileReader.read(array, 0, array.length);
if (readChars != -1)
buffer.append(array, 0, readChars);
}
while (readChars != -1);
fileReader.close();
newText = buffer.toString();
}
catch (Exception e)
{
e.printStackTrace();
JOptionPane.showMessageDialog(
this,
"An error occurred when reading from the file \"" + file + "\".\n" +
"Visual X-TOY will load the saved text from its own cache.",
"File I/O Error",
JOptionPane.ERROR_MESSAGE
);
}
}
// If that fails, then use the frame's memory to get the text.
if (newText == null)
newText = savedText;
program.setText(newText);
savedText = program.getText();
updateTitle();
}
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////
if (command == SAVE_COMMAND && file != null)
{
try
{
FileWriter fileWriter = new FileWriter(file);
String text = program.getText();
fileWriter.write(text);
fileWriter.close();
savedText = text;
updateTitle();
}
catch (Exception e)
{
e.printStackTrace();
JOptionPane.showMessageDialog(
this,
"An error occurred when writing to the file \"" + file + "\".",
"File I/O Error",
JOptionPane.ERROR_MESSAGE
);
}
isNew = false;
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////
/* if (command == SAVE_ALL_COMMAND)
{
boolean abort = false;
synchronized (FRAMES)
{
Object array[] = FRAMES.toArray();
int ctr = 0;
while (!abort && ctr < array.length)
{
if (!((TFrame)array[ctr]).doCommand(SAVE_COMMAND, null))
abort = true;
}
}
return !abort;
}
*/
////////////////////////////////////////////////////////////////////////////////////////////
if (command == SAVE_AS_COMMAND || command == SAVE_COMMAND && file == null)
{
if (extraInfo == null)
{
JFileChooser chooser = new JFileChooser();
File currentDirectory = TOptionsFrame.getCurrentDirectory();
if (currentDirectory != null)
chooser.setCurrentDirectory(currentDirectory);
if (file != null)
{
chooser.setSelectedFile(file);
}
else {
char array[] = program.getTitle().toCharArray();
boolean needsWhitespace = false;
StringBuffer buffer = new StringBuffer(array.length);
for (int ctr = 0; ctr < array.length; ctr++)
{
char ch = array[ctr];
if (ch >= 'a' && ch <= 'z' || ch >= '0' && ch <= '9' || ch == '-' ||
ch == '.')
{
buffer.append(ch);
needsWhitespace = true;
}
else if (ch >= 'A' && ch <= 'Z')
{
buffer.append((char)(ch - 'A' + 'a'));
needsWhitespace = true;
}
else if (Character.isWhitespace(ch) || ch == '_')
{
if (needsWhitespace)
{
buffer.append('_');
needsWhitespace = false;
}
}
}
int bufferLength = buffer.length();
if (!needsWhitespace && bufferLength > 0)
buffer.setLength(bufferLength - 1);
buffer.append(".toy");
chooser.setSelectedFile(
new File(
chooser.getCurrentDirectory(),
buffer.toString()
)
);
}
chooser.setAcceptAllFileFilterUsed(true);
// This doesn't work in jdk1.3- chooser.setDragEnabled(true);
chooser.addChoosableFileFilter(TOY_FILE_FILTER);
chooser.setFileHidingEnabled(true);
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
chooser.setMultiSelectionEnabled(false);
if (chooser.showSaveDialog(this) != JFileChooser.APPROVE_OPTION)
return false;
currentDirectory = chooser.getCurrentDirectory();
if (currentDirectory != null)
TOptionsFrame.setCurrentDirectory(currentDirectory);
file = chooser.getSelectedFile();
if (file.exists())
{
int result = JOptionPane.showConfirmDialog(
this,
"The file \"" + file + "\" already exists.\n" +
"Are you sure you want to save over it?",
"Confirm Save As Command",
JOptionPane.YES_NO_OPTION,
JOptionPane.WARNING_MESSAGE
);
if (result != JOptionPane.YES_OPTION)
return false;
}
}
else {
file = (File)extraInfo;
}
try
{
FileWriter fileWriter = new FileWriter(file);
String text = program.getText();
fileWriter.write(text);
fileWriter.close();
savedText = text;
updateTitle();
}
catch (Exception e)
{
file = null;
e.printStackTrace();
JOptionPane.showMessageDialog(
this,
"An error occurred when writing to the file \"" + file + "\".",
"File I/O error",
JOptionPane.ERROR_MESSAGE
);
}
isNew = false;
TOptionsFrame.putFileIntoHistory(file);
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////
if (command == QUIT_COMMAND)
{
boolean abort = false;
synchronized (FRAMES)
{
while (!abort)
{
TFrame frame = (TFrame)FRAMES.get(0);
if (!frame.doCommand(CLOSE_COMMAND, null))
abort = true;
}
}
return !abort;
}
////////////////////////////////////////////////////////////////////////////////////////////
if (command == EDIT_MODE_COMMAND)
{
if (mode == EDIT_MODE_COMMAND || virtualMachine.isRunning())
{
return false;
}
cardLayout.show(cardPanel, EDIT_MODE_COMMAND);
if (mode == DEBUG_MODE_COMMAND)
{
editPane.setDividerLocation(debugPane.getDividerLocation());
}
else if (mode == SIM_MODE_COMMAND)
{
editPane.setDividerLocation(simPane.getDividerLocation());
}
menuModeButtonGroup.setSelected(menuEditModeButtonModel, true);
editModeAction.setSmallIcon(
TImageManager.getIcon(
TImageManager.REGULAR_UNSCALED_IMAGE_GROUP,
TImageManager.REGULAR_UNSCALED_EDIT_MODE_ICON_ON
)
);
debugModeAction.setSmallIcon(
TImageManager.getIcon(
TImageManager.REGULAR_UNSCALED_IMAGE_GROUP,
TImageManager.REGULAR_UNSCALED_DEBUG_MODE_ICON_OFF
)
);
simModeAction.setSmallIcon(
TImageManager.getIcon(
TImageManager.REGULAR_UNSCALED_IMAGE_GROUP,
TImageManager.REGULAR_UNSCALED_SIM_MODE_ICON_OFF
)
);
mode = EDIT_MODE_COMMAND;
checkSyntaxAction.setEnabled(true);
functionAction.setEnabled(true);
doCommand(RESET_COMMAND, null);
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////
if (command == DEBUG_MODE_COMMAND)
{
if (mode == DEBUG_MODE_COMMAND || virtualMachine.isRunning())
return false;
if (mode == EDIT_MODE_COMMAND)
{
doCommand(CHECK_SYNTAX_COMMAND, Boolean.FALSE);
if (hasFatalError)
{
JOptionPane.showMessageDialog(
this,
"Your program contains fatal errors. Please correct these before\n" +
"leaving edit mode.",
"Action Blocked",
JOptionPane.ERROR_MESSAGE
);
menuModeButtonGroup.setSelected(menuEditModeButtonModel, true);
return false;
}
program.setInitialStdin(virtualMachine.getUnconsumedStdin());
}
cardLayout.show(cardPanel, DEBUG_MODE_COMMAND);
if (mode == EDIT_MODE_COMMAND)
{
debugPane.setDividerLocation(editPane.getDividerLocation());
}
else if (mode == SIM_MODE_COMMAND)
{
debugPane.setDividerLocation(simPane.getDividerLocation());
}
menuModeButtonGroup.setSelected(menuDebugModeButtonModel, true);
editModeAction.setSmallIcon(
TImageManager.getIcon(
TImageManager.REGULAR_UNSCALED_IMAGE_GROUP,
TImageManager.REGULAR_UNSCALED_EDIT_MODE_ICON_OFF
)
);
debugModeAction.setSmallIcon(
TImageManager.getIcon(
TImageManager.REGULAR_UNSCALED_IMAGE_GROUP,
TImageManager.REGULAR_UNSCALED_DEBUG_MODE_ICON_ON
)
);
simModeAction.setSmallIcon(
TImageManager.getIcon(
TImageManager.REGULAR_UNSCALED_IMAGE_GROUP,
TImageManager.REGULAR_UNSCALED_SIM_MODE_ICON_OFF
)
);
mode = DEBUG_MODE_COMMAND;
checkSyntaxAction.setEnabled(false);
functionAction.setEnabled(false);
// We allow the user to select which exceptions can be thrown in Debug mode
virtualMachine.setExceptionHandler(TOptionsFrame.getExceptionHandler());
doCommand(RESET_COMMAND, null);
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////
if (command == SIM_MODE_COMMAND)
{
if (mode == SIM_MODE_COMMAND || virtualMachine.isRunning())
return false;
if (mode == EDIT_MODE_COMMAND)
{
doCommand(CHECK_SYNTAX_COMMAND, Boolean.FALSE);
if (hasFatalError)
{
JOptionPane.showMessageDialog(
this,
"Your program contains fatal errors. Please correct these before\n" +
"leaving edit mode.",
"Action Blocked",
JOptionPane.ERROR_MESSAGE
);
menuModeButtonGroup.setSelected(menuEditModeButtonModel, true);
return false;
}
program.setInitialStdin(virtualMachine.getUnconsumedStdin());
}
cardLayout.show(cardPanel, SIM_MODE_COMMAND);
if (mode == EDIT_MODE_COMMAND)
{
simPane.setDividerLocation(editPane.getDividerLocation());
}
else if (mode == DEBUG_MODE_COMMAND)
{
simPane.setDividerLocation(debugPane.getDividerLocation());
}
menuModeButtonGroup.setSelected(menuSimModeButtonModel, true);
editModeAction.setSmallIcon(
TImageManager.getIcon(
TImageManager.REGULAR_UNSCALED_IMAGE_GROUP,
TImageManager.REGULAR_UNSCALED_EDIT_MODE_ICON_OFF
)
);
debugModeAction.setSmallIcon(
TImageManager.getIcon(
TImageManager.REGULAR_UNSCALED_IMAGE_GROUP,
TImageManager.REGULAR_UNSCALED_DEBUG_MODE_ICON_OFF
)
);
simModeAction.setSmallIcon(
TImageManager.getIcon(
TImageManager.REGULAR_UNSCALED_IMAGE_GROUP,
TImageManager.REGULAR_UNSCALED_SIM_MODE_ICON_ON
)
);
mode = SIM_MODE_COMMAND;
checkSyntaxAction.setEnabled(false);
functionAction.setEnabled(false);
// We don't allow exceptions to be thrown in sim mode
virtualMachine.setExceptionHandler(TExceptionHandler.PROMISCUOUS_EXCEPTION_HANDLER);
doCommand(RESET_COMMAND, null);
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////
if (command == WORKSPACE_COMMAND)
{
try
{
int index = ((Integer)extraInfo).intValue();
if (index != workspaceIndex)
{
// Uncheck the radio button
JRadioButtonMenuItem menuItem =
(JRadioButtonMenuItem)workspaceMenu.getItem(index);
menuItem.getModel().setSelected(false);
// Bring the appropriate frame to the front and give it focus
synchronized (FRAMES)
{
TFrame frame = (TFrame)FRAMES.get(index);
frame.requestFocus();
frame.toFront();
}
}
}
catch (Exception e)
{
e.printStackTrace();
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////
if (command == CHECK_SYNTAX_COMMAND)
{
long startTime = System.currentTimeMillis();
programChanged = false;
{ // Swap the previous warnings and curent warnings
TProgramDocument.WarningInfoStruct tempWarningInfo = previousWarnings;
previousWarnings = currentWarnings;
currentWarnings = tempWarningInfo;
}
program.getWarnings(
currentWarnings,
TOptionsFrame.getIgnoreWarnings()
);
hasFatalError = currentWarnings.hasFatalError;
int length = currentWarnings.warningCount;
DefaultListModel model = null;
// Ensure that the List model is of the right type
if (warningList.getModel() instanceof DefaultListModel)
{
if (!previousWarnings.warningsEqual(currentWarnings))
{
model = (DefaultListModel)warningList.getModel();
warningList.setModel(BLANK_LIST_MODEL);
model.clear();
}
}
else {
model = new DefaultListModel();
}
// Fill up the list model
if (model != null)
{
model.ensureCapacity(length);
for (int ctr = 0; ctr < length; ctr++)
model.addElement(currentWarnings.warnings[ctr]);
warningList.setModel(model);
}
// Update as many positions as possible (we'll create more later)
if (warningSelectionDots.size() > 0)
{
int end = Math.min(length, warningSelectionDots.size());
Iterator dotIterator = warningSelectionDots.iterator();
Iterator markIterator = warningSelectionMarks.iterator();
for (int ctr = 0; ctr < end; ctr++)
{
((HighlightedDocument.Position)dotIterator.next()).setOffset(
currentWarnings.selectionStart[ctr]
);
((HighlightedDocument.Position)markIterator.next()).setOffset(
currentWarnings.selectionEnd[ctr]
);
}
if (dotIterator.hasNext())
{
((HighlightedDocument.Position)dotIterator.next()).setOffset(0);
((HighlightedDocument.Position)markIterator.next()).setOffset(0);
}
}
// Ensure that we have enough positions (also ensure that we don't have way too many,
// since positions tend to slow things down)
if (warningSelectionDots.size() < length)
{
warningSelectionDots.ensureCapacity(length);
warningSelectionMarks.ensureCapacity(length);
for (int ctr = warningSelectionDots.size(); ctr < length; ctr++)
{
warningSelectionDots.add(
program.createPosition(
currentWarnings.selectionStart[ctr]
)
);
warningSelectionMarks.add(
program.createPosition(
currentWarnings.selectionEnd[ctr]
)
);
}
}
if (warningTallyList.getModel() instanceof DefaultListModel)
{
model = (DefaultListModel)warningTallyList.getModel();
if (model.size() > 1)
model.clear();
}
else {
model = new DefaultListModel();
warningTallyList.setModel(model);
}
int elapsedTime = (int)(System.currentTimeMillis() - startTime);
String string = "Syntax check complete: " + (length - (hasFatalError?1:0)) +
" warning(s), " + (hasFatalError?1:0) + " error(s), " + (elapsedTime / 1000) +
"." + ((elapsedTime % 1000) / 10) + " ms.";
if (model.size() == 0)
model.addElement(string);
else
model.set(0, string);
if (((Boolean)extraInfo).booleanValue() &&
leftEditPane.getDividerLocation() >= leftEditPane.getMaximumDividerLocation())
{
leftEditPane.setDividerLocation(0.8);
}
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////
if (command == FUNCTION_COMMAND)
{
int selectionStart = editTextArea.getSelectionStart();
int selectionEnd = editTextArea.getSelectionEnd();
program.replace(
selectionStart,
selectionEnd - selectionStart,
"function Unnamed\n" +
"// Input: \n" +
"// Return address: \n" +
"// Output: \n" +
"// Temporary variables: ",
false
);
editTextArea.select(selectionStart + 9, selectionStart + 16, selectionStart + 16);
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////
if (command == LOAD_COMMAND)
{
if (virtualMachine.isRunning())
return false;
TWord addr = simMachinePane.getAddr();
virtualMachine.setProgramCtr(addr);
virtualMachine.setMem(addr.getValue(), simMachinePane.getData());
simMemPane.scrollToPc();
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////
if (command == LOOK_COMMAND)
{
if (virtualMachine.isRunning())
return false;
virtualMachine.setProgramCtr(simMachinePane.getAddr());
simMemPane.scrollToPc();
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////
if (command == STEP_COMMAND)
{
long startTime = System.currentTimeMillis();
stepsTaken += virtualMachine.step();
if (mode == DEBUG_MODE_COMMAND)
{
elapsedTime += (int)(System.currentTimeMillis() - startTime);
if (virtualMachine.needsInput())
rightDebugPane.setSelectedComponent(debugStdinPane);
else if (virtualMachine.hasEncounteredError())
rightDebugPane.setSelectedComponent(debugStdoutPane);
stepsTakenTextField.setText(String.valueOf(stepsTaken));
int elapsedTimeSec = elapsedTime / 1000;
int elapsedTimeRem = elapsedTime % 1000;
if (elapsedTimeRem >= 100)
elapsedTimeTextField.setText(elapsedTimeSec + "." + elapsedTimeRem + " s");
else if (elapsedTimeRem >= 100)
elapsedTimeTextField.setText(elapsedTimeSec + ".0" + elapsedTimeRem + " s");
else
elapsedTimeTextField.setText(elapsedTimeSec + ".00" + elapsedTimeRem + " s");
}
else {
simMemPane.scrollToPc();
}
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////
if (command == RUN_COMMAND)
{
virtualMachine.run(this);
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////
if (command == ENTER_COMMAND)
{
if (virtualMachine.isRunning())
return false;
TWord data = simMachinePane.getData();
virtualMachine.getUnconsumedStdin(tempBuffer);
tempBuffer.add(data);
virtualMachine.setStdin(null, tempBuffer);
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////
if (command == INTERRUPT_COMMAND)
{
virtualMachine.interrupt();
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////
if (command == RESET_COMMAND)
{
if (virtualMachine.isRunning())
return false;
program.reset(virtualMachine);
if (mode == DEBUG_MODE_COMMAND)
{
synchronized (odometerLock)
{
stepsTaken = 0;
elapsedTime = 0;
stepsTakenTextField.setText("0");
elapsedTimeTextField.setText("0.000 s");
}
}
else if (mode == SIM_MODE_COMMAND)
{
simStdinPane.scrollToFrontier(true);
}
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////
if (command == OPEN_STDIN_COMMAND)
{
// Grab the text from the file
JFileChooser chooser = new JFileChooser();
File currentDirectory = TOptionsFrame.getCurrentDirectory();
if (currentDirectory != null)
chooser.setCurrentDirectory(currentDirectory);
chooser.setAcceptAllFileFilterUsed(true);
// This doesn't work in jdk1.3- chooser.setDragEnabled(true);
chooser.addChoosableFileFilter(TXT_FILE_FILTER);
chooser.setFileHidingEnabled(true);
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
chooser.setMultiSelectionEnabled(false);
if (chooser.showOpenDialog(this) != JFileChooser.APPROVE_OPTION)
return false;
currentDirectory = chooser.getCurrentDirectory();
if (currentDirectory != null)
TOptionsFrame.setCurrentDirectory(currentDirectory);
File file = chooser.getSelectedFile();
StringBuffer buffer = new StringBuffer();
try
{
FileReader fileReader = new FileReader(file);
int readChars;
char array[] = new char[100];
do
{
readChars = fileReader.read(array, 0, array.length);
if (readChars != -1)
buffer.append(array, 0, readChars);
}
while (readChars != -1);
fileReader.close();
}
catch (Exception e)
{
e.printStackTrace();
JOptionPane.showMessageDialog(
this,
"An error occurred when reading from the file \"" + file + "\".",
"File I/O Error",
JOptionPane.ERROR_MESSAGE
);
return false;
}
TWordBuffer unconsumedStdin = virtualMachine.getUnconsumedStdin();
int length = buffer.length();
int charCtr = 0;
while (charCtr < length)
{
char ch = buffer.charAt(charCtr);
if (TWord.isHexDigit(ch))
{
int peekCtr = charCtr + 1;
while (peekCtr < length && peekCtr < charCtr + 4 &&
TWord.isHexDigit(buffer.charAt(peekCtr)))
peekCtr++;
try
{
unconsumedStdin.add(
TWord.parseWord(
buffer.substring(charCtr, peekCtr),
16
)
);
}
catch (NumberFormatException e)
{
e.printStackTrace();
}
charCtr = peekCtr;
}
else {
charCtr++;
}
}
virtualMachine.setStdin(null, unconsumedStdin);
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////
if (command == SAVE_STDIN_COMMAND)
{
JFileChooser chooser = new JFileChooser();
File currentDirectory = TOptionsFrame.getCurrentDirectory();
if (currentDirectory != null)
chooser.setCurrentDirectory(currentDirectory);
chooser.setSelectedFile(new File(chooser.getCurrentDirectory(), "toy_stdin.txt"));
chooser.setAcceptAllFileFilterUsed(true);
// This doesn't work in jdk1.3- chooser.setDragEnabled(true);
chooser.addChoosableFileFilter(TXT_FILE_FILTER);
chooser.setFileHidingEnabled(true);
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
chooser.setMultiSelectionEnabled(false);
if (chooser.showSaveDialog(this) != JFileChooser.APPROVE_OPTION)
return false;
currentDirectory = chooser.getCurrentDirectory();
if (currentDirectory != null)
TOptionsFrame.setCurrentDirectory(currentDirectory);
File file = chooser.getSelectedFile();
if (file.exists())
{
int result = JOptionPane.showConfirmDialog(
this,
"The file \"" + file + "\" already exists.\n" +
"Are you sure you want to save over it?",
"Confirm Save As Command",
JOptionPane.YES_NO_OPTION,
JOptionPane.WARNING_MESSAGE
);
if (result != JOptionPane.YES_OPTION)
return false;
}
TWordBuffer stdin = virtualMachine.getConsumedStdin();
StringBuffer buffer = new StringBuffer();
int size = stdin.getSize();
for (int ctr = 0; ctr < size; ctr++)
{
buffer.append(stdin.getWord(ctr).toHexString(false));
buffer.append('\n');
}
virtualMachine.getUnconsumedStdin(stdin);
size = stdin.getSize();
for (int ctr = 0; ctr < size; ctr++)
{
buffer.append(stdin.getWord(ctr).toHexString(false));
buffer.append('\n');
}
try
{
FileWriter fileWriter = new FileWriter(file);
fileWriter.write(buffer.toString());
fileWriter.close();
}
catch (Exception e)
{
file = null;
e.printStackTrace();
JOptionPane.showMessageDialog(
this,
"An error occurred when writing to the file \"" + file + "\".",
"File I/O error",
JOptionPane.ERROR_MESSAGE
);
}
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////
if (command == SAVE_STDOUT_COMMAND)
{
JFileChooser chooser = new JFileChooser();
File currentDirectory = TOptionsFrame.getCurrentDirectory();
if (currentDirectory != null)
chooser.setCurrentDirectory(currentDirectory);
chooser.setSelectedFile(new File(chooser.getCurrentDirectory(), "toy_stdout.txt"));
chooser.setAcceptAllFileFilterUsed(true);
// This doesn't work in jdk1.3- chooser.setDragEnabled(true);
chooser.addChoosableFileFilter(TXT_FILE_FILTER);
chooser.setFileHidingEnabled(true);
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
chooser.setMultiSelectionEnabled(false);
if (chooser.showSaveDialog(this) != JFileChooser.APPROVE_OPTION)
return false;
currentDirectory = chooser.getCurrentDirectory();
if (currentDirectory != null)
TOptionsFrame.setCurrentDirectory(currentDirectory);
File file = chooser.getSelectedFile();
if (file.exists())
{
int result = JOptionPane.showConfirmDialog(
this,
"The file \"" + file + "\" already exists.\n" +
"Are you sure you want to save over it?",
"Confirm Save As Command",
JOptionPane.YES_NO_OPTION,
JOptionPane.WARNING_MESSAGE
);
if (result != JOptionPane.YES_OPTION)
return false;
}
TWordBuffer stdout = virtualMachine.getStdout();
StringBuffer buffer = new StringBuffer();
int size = stdout.getSize();
for (int ctr = 0; ctr < size; ctr++)
{
buffer.append(stdout.getWord(ctr).toHexString(false));
buffer.append('\n');
}
try
{
FileWriter fileWriter = new FileWriter(file);
fileWriter.write(buffer.toString());
fileWriter.close();
}
catch (Exception e)
{
file = null;
e.printStackTrace();
JOptionPane.showMessageDialog(
this,
"An error occurred when writing to the file \"" + file + "\".",
"File I/O error",
JOptionPane.ERROR_MESSAGE
);
}
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////
if (command == SAVE_CORE_DUMP_COMMAND)
{
JFileChooser chooser = new JFileChooser();
File currentDirectory = TOptionsFrame.getCurrentDirectory();
if (currentDirectory != null)
chooser.setCurrentDirectory(currentDirectory);
chooser.setSelectedFile(new File(chooser.getCurrentDirectory(), "toy_core.txt"));
chooser.setAcceptAllFileFilterUsed(true);
// This doesn't work in jdk1.3- chooser.setDragEnabled(true);
chooser.addChoosableFileFilter(TXT_FILE_FILTER);
chooser.setFileHidingEnabled(true);
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
chooser.setMultiSelectionEnabled(false);
if (chooser.showSaveDialog(this) != JFileChooser.APPROVE_OPTION)
return false;
currentDirectory = chooser.getCurrentDirectory();
if (currentDirectory != null)
TOptionsFrame.setCurrentDirectory(currentDirectory);
File file = chooser.getSelectedFile();
if (file.exists())
{
int result = JOptionPane.showConfirmDialog(
this,
"The file \"" + file + "\" already exists.\n" +
"Are you sure you want to save over it?",
"Confirm Save As Command",
JOptionPane.YES_NO_OPTION,
JOptionPane.WARNING_MESSAGE
);
if (result != JOptionPane.YES_OPTION)
return false;
}
try
{
FileWriter fileWriter = new FileWriter(file);
fileWriter.write(virtualMachine.getCoreDump());
fileWriter.close();
}
catch (Exception e)
{
file = null;
e.printStackTrace();
JOptionPane.showMessageDialog(
this,
"An error occurred when writing to the file \"" + file + "\".",
"File I/O error",
JOptionPane.ERROR_MESSAGE
);
}
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////
if (command == SAVE_MEM_DUMP_COMMAND)
{
JFileChooser chooser = new JFileChooser();
File currentDirectory = TOptionsFrame.getCurrentDirectory();
if (currentDirectory != null)
chooser.setCurrentDirectory(currentDirectory);
chooser.setSelectedFile(new File(chooser.getCurrentDirectory(), "toy_memory.txt"));
chooser.setAcceptAllFileFilterUsed(true);
// This doesn't work in jdk1.3- chooser.setDragEnabled(true);
chooser.addChoosableFileFilter(TXT_FILE_FILTER);
chooser.setFileHidingEnabled(true);
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
chooser.setMultiSelectionEnabled(false);
if (chooser.showSaveDialog(this) != JFileChooser.APPROVE_OPTION)
return false;
currentDirectory = chooser.getCurrentDirectory();
if (currentDirectory != null)
TOptionsFrame.setCurrentDirectory(currentDirectory);
File file = chooser.getSelectedFile();
if (file.exists())
{
int result = JOptionPane.showConfirmDialog(
this,
"The file \"" + file + "\" already exists.\n" +
"Are you sure you want to save over it?",
"Confirm Save As Command",
JOptionPane.YES_NO_OPTION,
JOptionPane.WARNING_MESSAGE
);
if (result != JOptionPane.YES_OPTION)
return false;
}
try
{
FileWriter fileWriter = new FileWriter(file);
fileWriter.write(virtualMachine.getMemDump());
fileWriter.close();
}
catch (Exception e)
{
file = null;
e.printStackTrace();
JOptionPane.showMessageDialog(
this,
"An error occurred when writing to the file \"" + file + "\".",
"File I/O error",
JOptionPane.ERROR_MESSAGE
);
}
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////
if (command == CHANGE_EXECUTION_COMMAND)
{
TOptionsFrame.show(TOptionsFrame.EXECUTION_PERFORMANCE_NODE);
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////
if (command == CLEAR_ODOMETER_COMMAND)
{
synchronized (odometerLock)
{
stepsTaken = 0;
elapsedTime = 0;
stepsTakenTextField.setText("0");
elapsedTimeTextField.setText("0.000 s");
}
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////
if (command == CHANGE_CHECKING_COMMAND)
{
TOptionsFrame.show(TOptionsFrame.EDITING_CHECKING_NODE);
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////
if (command == HIDE_WARNINGS_COMMAND)
{
leftEditPane.setDividerLocation(1.0);
return true;
}
throw new IllegalArgumentException();
}
/**
* Implement ActionListener to pass the command onto doCommand().
*
* @see #doCommand(String, Object)
*/
public void actionPerformed(ActionEvent e)
{
if (e.getActionCommand() == WORKSPACE_COMMAND)
{
doCommand(WORKSPACE_COMMAND, ((WorkspaceMenuItem)e.getSource()).getIndex());
}
else if (e.getActionCommand() == CHECK_SYNTAX_COMMAND)
{
doCommand(CHECK_SYNTAX_COMMAND, Boolean.TRUE);
}
else {
doCommand(e.getActionCommand(), null);
}
}
/**
* Implement TextListener to update the other components when the document changes.
*/
public void textValueChanged(TextEvent e)
{
updateTitle();
programChanged = true;
}
/**
* Implement ListSelectionListener to update the editTextArea selection when the list's selection
* changes.
*/
public void valueChanged(ListSelectionEvent e)
{
int selectedIndex = warningList.getSelectedIndex();
if (selectedIndex != -1)
{
editTextArea.select(
((HighlightedDocument.Position)warningSelectionDots.get(
selectedIndex
)).getOffset(),
((HighlightedDocument.Position)warningSelectionMarks.get(
selectedIndex
)).getOffset()
);
}
}
/**
* Implement ChangeListener to listen to changes in the state of the virtual machine.
*/
public void stateChanged(ChangeEvent e)
{
boolean editMode = (mode == EDIT_MODE_COMMAND);
boolean simMode = (mode == SIM_MODE_COMMAND);
boolean isRunning = virtualMachine.isRunning();
boolean canGo = !isRunning && !virtualMachine.isDone() && !virtualMachine.needsInput();
editModeAction.setEnabled(!isRunning);
debugModeAction.setEnabled(!isRunning);
simModeAction.setEnabled(!isRunning);
lookAction.setEnabled(simMode && !isRunning);
loadAction.setEnabled(simMode && !isRunning);
enterAction.setEnabled(simMode && !isRunning);
resetAction.setEnabled(!editMode && !isRunning);
stepAction.setEnabled(!editMode && canGo);
runAction.setEnabled(!editMode && canGo);
interruptAction.setEnabled(!editMode && isRunning);
openStdinAction.setEnabled(!isRunning);
saveStdinAction.setEnabled(!isRunning);
saveStdoutAction.setEnabled(!editMode && !isRunning);
saveMemDumpAction.setEnabled(!editMode && !isRunning);
saveCoreDumpAction.setEnabled(!editMode && !isRunning);
if (mode == DEBUG_MODE_COMMAND)
{
int lineDefined = program.getLineDefined(
virtualMachine.getProgramCtr().getValue() & 0xFF,
true
);
if (debugTextArea.getHighlightedLine() != lineDefined)
{
debugTextArea.setHighlightedLine(lineDefined);
debugTextArea.scrollToCaret();
}
}
}
/**
* This function is called by the TVirtualMachine's runner when it has completed the
* previous batch of steps.
*
* @param virtualMachine The virtual machine whose status is being reported.
* @param n The number of steps taken since the last update.
* @param elapsedTime The number of milliseconds between the lastUpdate and the present.
* @param willStop Wheter or not the TVirtualMachine will stop after this status update.
* @return The number of additional steps to take before fireing more ChangeEvents and
* producing another status update. If this is 0, the virtualMachine will stop. If this
* is negative, a stack trace will be written to stderr and the virtualMachine will stop.
*/
public int statusUpdate(TVirtualMachine virtualMachine, int n, int elapsedTime,
boolean willStop)
{
if (mode == DEBUG_MODE_COMMAND)
{
stepsTaken += n;
this.elapsedTime += elapsedTime;
if (virtualMachine.needsInput())
rightDebugPane.setSelectedComponent(debugStdinPane);
else if (virtualMachine.hasEncounteredError())
rightDebugPane.setSelectedComponent(debugStdoutPane);
stepsTakenTextField.setText(String.valueOf(stepsTaken));
int elapsedTimeSec = this.elapsedTime / 1000;
int elapsedTimeRem = this.elapsedTime % 1000;
if (elapsedTimeRem >= 100)
elapsedTimeTextField.setText(elapsedTimeSec + "." + elapsedTimeRem + " s");
else if (elapsedTimeRem >= 10)
elapsedTimeTextField.setText(elapsedTimeSec + ".0" + elapsedTimeRem + " s");
else
elapsedTimeTextField.setText(elapsedTimeSec + ".00" + elapsedTimeRem + " s");
}
else {
simMemPane.scrollToPc();
}
return TOptionsFrame.getRefreshRate();
}
/**
* This function is called by the TVirtualMachine's runner after it has recieved an order
* for a batch of steps to be run. The next status update will not occur until after n *
* getClockPeriod() milliseconds, where n was the number of steps taken. If the preferred
* clock period is too fast, the next status update will occur as soon the batch of steps
* is completed.
*
* @return The preferred number of milliseconds each step should take.
*/
public int getClockPeriod()
{
return TOptionsFrame.getClockPeriod();
}
/**
* Intercept WindowEvents to pick up WINDOW_CLOSING events.
*/
protected void processWindowEvent(WindowEvent e)
{
if (e.getID() == WindowEvent.WINDOW_CLOSING)
{
doCommand(CLOSE_COMMAND, null);
}
super.processWindowEvent(e);
}
/**
* TFrameAction is a generalizable action for the TFrame; basically, it relays all ActionEvents
* to the doCommand() method.
*
* @author btsang
* @version 7.1
*/
protected class TFrameAction extends AbstractAction2
{
/**
* Creates a new TFrameAction.
*/
protected TFrameAction(String name, Icon icon, int mnemonic, KeyStroke accelerator,
String command)
{
this(name, icon, mnemonic, accelerator, command, null);
}
/**
* Creates a new TFrameAction.
*/
protected TFrameAction(String name, Icon icon, int mnemonic, KeyStroke accelerator,
String command, Object extraInfo)
{
super(name, icon);
if (name == null || command == null)
throw new NullPointerException();
setMnemonic(mnemonic);
setAccelerator(accelerator);
setActionCommand(command);
setExtraInfo(extraInfo);
}
/**
* Implements ActionListener to perform the redo operation.
*/
public void actionPerformed(ActionEvent e)
{
doCommand(getActionCommand(), getExtraInfo());
}
}
/**
* TWorkspaceMenuItem is a simple subclass of JRadioButtonMenuItem which keeps an index
* property.
*
* @author btsang
* @version 7.1
*/
public static class WorkspaceMenuItem extends JRadioButtonMenuItem
{
private Integer index;
/**
* Constructs a new WorkspaceMenuItem.
*/
public WorkspaceMenuItem(int index)
{
super();
this.index = new Integer(index);
}
/**
* Returns the index of the WorkspaceMenuItem.
*
* @return The Integer object corresponding to the int that this WorkspaceMenuItem was
* constructed with.
*/
public Integer getIndex()
{
return index;
}
}
/**
* Runner is the implementation of Runnable which updates the warnings of all TFrames (if the
* program had changed since the last syntax check). It is started and stopped by
* TFrame.setAutoCheck() which is called by TOptionFrame when the user applies changes.
*
* @author btsang
* @version 7.1
*/
protected static class Runner implements Runnable
{
protected Thread runningThread;
protected Runner()
{
}
public void run()
{
Thread currentThread = Thread.currentThread();
while (runningThread == currentThread)
{
synchronized (FRAMES)
{
int length = FRAMES.size();
FRAMES_ARRAY = FRAMES.toArray(FRAMES_ARRAY);
Object framesArray[] = FRAMES_ARRAY;
for (int ctr = 0; runningThread == currentThread && ctr < length; ctr++)
{
TFrame frame = (TFrame)framesArray[ctr];
if (frame.programChanged)
frame.doCommand(CHECK_SYNTAX_COMMAND, Boolean.FALSE);
}
}
if (runningThread == currentThread)
{
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
runningThread = null;
e.printStackTrace();
}
}
}
}
}
}