package net.sf.orcc.simulators.runtime.system.io.item; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import java.util.ArrayDeque; import java.util.Deque; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.text.DefaultCaret; import net.sf.orcc.simulators.runtime.impl.SystemIO; import net.sf.orcc.util.OrccUtil; public class Console extends SystemIO { private class WindowConsole extends WindowAdapter implements WindowListener, ActionListener, Runnable { private JFrame frame; private JTextArea textArea; private boolean quit; private JTextField jtfInput; private final Deque<String> iStream = new ArrayDeque<String>(); public WindowConsole(String name) { // create all components and add them jtfInput = new JTextField(20); jtfInput.addActionListener(this); frame = new JFrame("Console " + name); Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); Dimension frameSize = new Dimension((int) (screenSize.width / 3), (int) (screenSize.height / 2)); int x = (int) (frameSize.width / 2); int y = (int) (frameSize.height / 2); frame.setBounds(x, y, frameSize.width, frameSize.height); textArea = new JTextArea(); textArea.setEditable(false); DefaultCaret caret = (DefaultCaret) textArea.getCaret(); caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE); frame.getContentPane().setLayout(new BorderLayout()); frame.getContentPane().add(jtfInput, BorderLayout.SOUTH); frame.getContentPane().add(new JScrollPane(textArea), BorderLayout.CENTER); frame.setVisible(true); frame.addWindowListener(this); quit = false; // signals the Threads that they should exit } public synchronized void windowClosed(WindowEvent evt) { quit = true; this.notifyAll(); } public synchronized void windowClosing(WindowEvent evt) { frame.setVisible(false); // default behaviour of JFrame frame.dispose(); } public synchronized void actionPerformed(ActionEvent evt) { try { String text = jtfInput.getText(); iStream.addFirst(text); jtfInput.setText(""); this.notifyAll(); } catch (Exception e) { } } public synchronized void run() { try { while (Thread.currentThread().isAlive()) { try { this.wait(100); } catch (InterruptedException ie) { } if (quit) return; } } catch (Exception e) { textArea.append("\nConsole reports an Internal error."); textArea.append("The error is: " + e); } } public synchronized String read() { iStream.clear(); while (iStream.isEmpty()) { try { wait(); } catch (InterruptedException e) { } } return iStream.getLast(); } public synchronized void write(String v) { textArea.append(v); } } private WindowConsole wConsole; public Console(String id) { wConsole = new WindowConsole(id); } @Override public boolean isConsole() { return true; } public String read() { return wConsole.read(); } public void write(String v) { String unescaped = OrccUtil.getUnescapedString(v); wConsole.write(unescaped); } }