/** * If the model is deadlocked, report the deadlock if parameter "SuppressDeadlockReporting" is not * set to boolean true, and return false. Otherwise, return true. Deadlock occurs if the number of * blocked threads equals the number of active threads. * * @return False if deadlock occurred, true otherwise. * @exception IllegalActionException If thrown while getting the "SuppressDeadlockReporting" * token. */ protected synchronized boolean _resolveInternalDeadlock() throws IllegalActionException { if (_getBlockedThreadsCount() == _getActiveThreadsCount()) { // Report deadlock. Parameter suppress = (Parameter) getContainer().getAttribute("SuppressDeadlockReporting", Parameter.class); if ((suppress == null) || !(suppress.getToken() instanceof BooleanToken) || !((BooleanToken) suppress.getToken()).booleanValue()) { MessageHandler.message( "Model ended with a deadlock " + "(this may be normal for this model).\n" + "A parameter with name SuppressDeadlockReporting and " + "value true will suppress this message."); } return false; } return true; }
/** * Process this event. If the mode is {@link Mode#ERROR}, a message is shown in an error dialog. * If the mode is {@link Mode#EXCEPTION}, a message is shown in the form of an exception. If the * mode is {@link Mode#MESSAGE}, a message is shown in a message dialog. If the mode is {@link * Mode#TABLEAU}, a tableau is opened to show the message. The default tableau is the one defined * in the {@link #tableau} parameter. However, if {@link #referredTableau} is not an empty string, * its value is interpreted as the name of the tableau parameter in the model, whose tableau * should be used instead of the default one. If the mode is {@link Mode#WARNING}, a message is * shown in a warning dialog. If the mode is {@link Mode#YES_OR_NO}, a query dialog is shown with * the message, which allows the user to answer with yes or no. The answer is stored in {@link * #response}. * * @param arguments The arguments used to process this event, which must be either an ArrayToken * or a RecordToken. * @return A refiring data structure that contains a non-negative double number if refire() should * be called after that amount of model time, or null if refire() need not be called. * @exception IllegalActionException If the tableau cannot be used, or if thrown by the * superclass. */ public RefiringData fire(Token arguments) throws IllegalActionException { RefiringData data = super.fire(arguments); Mode choice = (Mode) mode.getChosenValue(); String text = message.stringValue(); MessageHandler oldHandler; switch (choice) { case ERROR: oldHandler = MessageHandler.getMessageHandler(); try { MessageHandler.setMessageHandler(_MESSAGE_HANDLER); MessageHandler.error(text); } finally { MessageHandler.setMessageHandler(oldHandler); } break; case MESSAGE: oldHandler = MessageHandler.getMessageHandler(); try { MessageHandler.setMessageHandler(_MESSAGE_HANDLER); MessageHandler.message(text); } finally { MessageHandler.setMessageHandler(oldHandler); } break; case EXCEPTION: throw new RuntimeException(text); case TABLEAU: Effigy effigy = EventUtils.findToplevelEffigy(this); if (effigy == null) { // The effigy may be null if the model is closed. return data; } Tableau tableau = EventUtils.getTableau(this, referredTableau, this.tableau); if (tableau != null && !(tableau.getFrame() instanceof TextEditor)) { EventUtils.setTableau(this, referredTableau, this.tableau, null); EventUtils.closeTableau(tableau); tableau = null; } boolean openNewWindow = true; String previousText = null; if (tableau != null) { JFrame frame = tableau.getFrame(); if (frame instanceof TextEditor) { TextEditor editor = (TextEditor) frame; if (editor.getEffigy() == null) { previousText = editor.text.getText(); } else { openNewWindow = false; } } } TextEditor frame; if (openNewWindow) { TextEffigy textEffigy; try { textEffigy = TextEffigy.newTextEffigy(effigy, ""); } catch (Exception e) { throw new IllegalActionException(this, e, "Unable to " + "create effigy."); } try { tableau = new Tableau(textEffigy, "tableau"); } catch (NameDuplicationException e) { throw new IllegalActionException(this, e, "Unable to " + "create tableau."); } frame = new TextEditor(tableau.getTitle(), textEffigy.getDocument()); frame.text.setColumns(((IntToken) columnsDisplayed.getToken()).intValue()); frame.text.setRows(((IntToken) rowsDisplayed.getToken()).intValue()); tableau.setFrame(frame); frame.setTableau(tableau); EventUtils.setTableau(this, referredTableau, this.tableau, tableau); frame.pack(); frame.setVisible(true); if (previousText != null) { frame.text.setText(previousText); } } else { frame = (TextEditor) tableau.getFrame(); } frame.text.append(text + "\n"); try { int lineOffset = frame.text.getLineStartOffset(frame.text.getLineCount() - 1); frame.text.setCaretPosition(lineOffset); } catch (BadLocationException ex) { // Ignore ... worst case is that the scrollbar // doesn't move. } break; case WARNING: try { oldHandler = MessageHandler.getMessageHandler(); try { MessageHandler.setMessageHandler(_MESSAGE_HANDLER); MessageHandler.warning(text); } finally { MessageHandler.setMessageHandler(oldHandler); } response.setToken(BooleanToken.TRUE); } catch (CancelException e) { response.setToken(BooleanToken.FALSE); } break; case YES_OR_NO: oldHandler = MessageHandler.getMessageHandler(); boolean success = false; boolean answer; try { MessageHandler.setMessageHandler(_MESSAGE_HANDLER); answer = MessageHandler.yesNoQuestion(text); success = true; } finally { MessageHandler.setMessageHandler(oldHandler); } if (success) { response.setToken(BooleanToken.getInstance(answer)); } break; default: throw new IllegalActionException( "Unrecognized mode choice \"" + mode.getExpression() + "\"."); } return data; }