/** * Will select the Mars Messages tab error message that matches the given specifications, if it is * found. Matching is done by constructing a string using the parameter values and searching the * text area for the last occurrance of that string. * * @param fileName A String containing the file path name. * @param line Line number for error message * @param column Column number for error message */ public void selectErrorMessage(String fileName, int line, int column) { String errorReportSubstring = new java.io.File(fileName).getName() + ErrorList.LINE_PREFIX + line + ErrorList.POSITION_PREFIX + column; int textPosition = assemble.getText().lastIndexOf(errorReportSubstring); if (textPosition >= 0) { int textLine = 0; int lineStart = 0; int lineEnd = 0; try { textLine = assemble.getLineOfOffset(textPosition); lineStart = assemble.getLineStartOffset(textLine); lineEnd = assemble.getLineEndOffset(textLine); assemble.setSelectionColor(Color.YELLOW); assemble.select(lineStart, lineEnd); assemble.getCaret().setSelectionVisible(true); assemble.repaint(); } catch (BadLocationException ble) { // If there is a problem, simply skip the selection } } }
/** * Post a message to the assembler display * * @param message String to append to assembler display text */ public void postMarsMessage(String message) { assemble.append(message); // can do some crude cutting here. If the document gets "very large", // let's cut off the oldest text. This will limit scrolling but the limit // can be set reasonably high. if (assemble.getDocument().getLength() > MAXIMUM_SCROLLED_CHARACTERS) { try { assemble.getDocument().remove(0, NUMBER_OF_CHARACTERS_TO_CUT); } catch (BadLocationException ble) { // only if NUMBER_OF_CHARACTERS_TO_CUT > MAXIMUM_SCROLLED_CHARACTERS } } assemble.setCaretPosition(assemble.getDocument().getLength()); setSelectedComponent(assembleTab); }
/** Constructor for the class, sets up two fresh tabbed text areas for program feedback. */ public MessagesPane() { super(); this.setMinimumSize(new Dimension(0, 0)); assemble = new JTextArea(); run = new JTextArea(); assemble.setEditable(false); run.setEditable(false); // Set both text areas to mono font. For assemble // pane, will make messages more readable. For run // pane, will allow properly aligned "text graphics" // DPS 15 Dec 2008 Font monoFont = new Font(Font.MONOSPACED, Font.PLAIN, 12); assemble.setFont(monoFont); run.setFont(monoFont); JButton assembleTabClearButton = new JButton("Clear"); assembleTabClearButton.setToolTipText("Clear the Mars Messages area"); assembleTabClearButton.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { assemble.setText(""); } }); assembleTab = new JPanel(new BorderLayout()); assembleTab.add(createBoxForButton(assembleTabClearButton), BorderLayout.WEST); assembleTab.add( new JScrollPane( assemble, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); assemble.addMouseListener( new MouseAdapter() { public void mouseClicked(MouseEvent e) { String text; int lineStart = 0; int lineEnd = 0; try { int line = assemble.getLineOfOffset(assemble.viewToModel(e.getPoint())); lineStart = assemble.getLineStartOffset(line); lineEnd = assemble.getLineEndOffset(line); text = assemble.getText(lineStart, lineEnd - lineStart); } catch (BadLocationException ble) { text = ""; } if (text.length() > 0) { // If error or warning, parse out the line and column number. if (text.startsWith(ErrorList.ERROR_MESSAGE_PREFIX) || text.startsWith(ErrorList.WARNING_MESSAGE_PREFIX)) { assemble.select(lineStart, lineEnd); assemble.setSelectionColor(Color.YELLOW); assemble.repaint(); int separatorPosition = text.indexOf(ErrorList.MESSAGE_SEPARATOR); if (separatorPosition >= 0) { text = text.substring(0, separatorPosition); } String[] stringTokens = text.split("\\s"); // tokenize with whitespace delimiter String lineToken = ErrorList.LINE_PREFIX.trim(); String columnToken = ErrorList.POSITION_PREFIX.trim(); String lineString = ""; String columnString = ""; for (int i = 0; i < stringTokens.length; i++) { if (stringTokens[i].equals(lineToken) && i < stringTokens.length - 1) lineString = stringTokens[i + 1]; if (stringTokens[i].equals(columnToken) && i < stringTokens.length - 1) columnString = stringTokens[i + 1]; } int line = 0; int column = 0; try { line = Integer.parseInt(lineString); } catch (NumberFormatException nfe) { line = 0; } try { column = Integer.parseInt(columnString); } catch (NumberFormatException nfe) { column = 0; } // everything between FILENAME_PREFIX and LINE_PREFIX is filename. int fileNameStart = text.indexOf(ErrorList.FILENAME_PREFIX) + ErrorList.FILENAME_PREFIX.length(); int fileNameEnd = text.indexOf(ErrorList.LINE_PREFIX); String fileName = ""; if (fileNameStart < fileNameEnd && fileNameStart >= ErrorList.FILENAME_PREFIX.length()) { fileName = text.substring(fileNameStart, fileNameEnd).trim(); } if (fileName != null && fileName.length() > 0) { selectEditorTextLine(fileName, line, column); selectErrorMessage(fileName, line, column); } } } } }); JButton runTabClearButton = new JButton("Clear"); runTabClearButton.setToolTipText("Clear the Run I/O area"); runTabClearButton.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { run.setText(""); } }); runTab = new JPanel(new BorderLayout()); runTab.add(createBoxForButton(runTabClearButton), BorderLayout.WEST); runTab.add( new JScrollPane( run, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); this.addTab("Mars Messages", assembleTab); this.addTab("Run I/O", runTab); this.setToolTipTextAt( 0, "Messages produced by Run menu. Click on assemble error message to select erroneous line"); this.setToolTipTextAt(1, "Simulated MIPS console input and output"); }