A graphical Console component for your game

our research over Java gaming technology leads us to formally log our output at a higher stage of the development. this is one reason for developing our self-made products, beyond editors and custom graphics. Here’s one of our most advanced tool, the Console interafce tat can be impl. for logging or even command-line exuction processes.
First part, the Console class, that can get as many inputs as we like, sampled with the newInputStream() callback :


    / * returns a new PrintStream to print on loggin' stack.
     * it is simply a 32bits packet atream read from the printStream that will be sent to the InputListeners.
     * NOTICE: after this method you MUST send a PRINT_RESUME event to the console otherwise the returned PrintStream will stay inactive.
     *
     * @return new buffered PrintStream instance ready to be used as an input and it associated "long" ID.
     * That is, when you get the map Map<String, Object>:<pre>
     *      long id = (Long)map.get("id");
     *      PrintStream ps = (PrintStream)map.get("ps");
     *      // assign the PrintStream ps somewhere
     *      // and send a PRINT_RESUME to start writing to the console.
     *      console.sendConsoleEvent(Console.PRINT_RESUME);
     * </pre>
     * @see #sendConsoleEvent(int)
     * @see #PRINT_RESUME
     * @see ErrorListener
     * @see #input
     * @see InputLogListener#newLogPacket(String)
     * @param l Output listener to the printStream
     * @throws java.io.IOException
     */
    protected synchronized Map<String, Object> newPrintStream(ErrorListener l) throws IOException {
        addErrorListener(l);
        PipedOutputStream pipedOutputStream = new PipedOutputStream();
        final long id = System.currentTimeMillis();
        final PrintStream ps;
        in.put(id, ps = new PrintStream(new BufferedOutputStream(pipedOutputStream), true));
        final BufferedInputStream pis = new BufferedInputStream(new PipedInputStream(pipedOutputStream));
        Thread t = new Thread(outputMonitor, new Runnable() {

            public void run() {
                try {
                    if(debug)
                        System.out.println("a new PrintStream " + id + " is startin'...");
                    byte[] b = new byte[128];
                    int r;
                    boolean wait = true;
                    boolean stop = false;
                    do {
                        while (wait) {
                            switch (readConsoleEvent(id)) {
                                case Console.PRINT_WAIT:
                                    wait = true;
                                    break;
                                case Console.PRINT_STOP:
                                    stop = true;
                                case Console.PRINT_RESUME:
                                    wait = false;
                                    break;
                                default:
                                    break;
                            }
                        }
                        if (stop) {
                            break;
                        }
                        if(pis.available() <= 0) { Thread.sleep(250); } // THAT'S THE POINT
                        if ((r = pis.read(b)) != -1) {
                            final String s = new String(b);
                            notifyInput(s);
                            try {
                                append(s);
                            } catch (IOException ex) {
                                ex.printStackTrace();
                                notifyError(PRINT_ERROR, ex);
                            }
                        } 
                       b = new byte[128]; // THAT'S THE OTHER POINT
                    } while (r != -1);
                    if(debug)
                        System.out.println("PrintStream " + id + " is terminating...");
                    pis.close();
                } catch (IOException ex) {
                    notifyError(PRINT_ERROR, ex);
                } finally {
                    removePrintStream(id);
                }
            }
        }, "T-PrintStream-" + id);
        t.setPriority(Thread.MAX_PRIORITY);
        t.setDaemon(true);
        outputMonitor.addThread(t);
        t.start();
        if(debug)
            System.out.println("The new PrintStream " + id + " is waiting for a startup delivery...");
            Map<String, Object> map = Collections.synchronizedMap(new HashMap<String, Object>());
            map.put("id", id);
            map.put("ps", ps);
            return map;
        }

Next and last part is the Graphics Component, coming out soon. :slight_smile:

The above Console class leads then to a extended JComponent that draws the lines-buffer on Graphics. Here’s a sample of the draw() method used in paintComponent() :

/** draws the contents to the given Graphics. This method is already synchronized with the buffer.
     * @param g2 the graphics instance to use for drawing onto
     * @param obs the observer to use
     * @return true or false whether the painting was complete or not*/
    public boolean draw(Component obs, Graphics2D g2) throws InterruptedException {
        boolean complete = true;
        Composite cps = g2.getComposite();
        g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
        GraphicsJAI off = Sprite.createGraphicsJAI(g2, obs);
        Color c = off.getColor();
        off.setColor(getBackground());
        off.setClip(0, 0, getWidth(), getHeight());
        off.fillRect(0, 0, getWidth(), getHeight());
        off.setColor(c);
        Hashtable<String, Object> args = new Hashtable<String, Object>();
        args.put(PROPS_LASTOUTPUTPX, lastOutputPX = new Point(0, 0));
        args.put(PROPS_VALIGN, valign);
        args.put(PROPS_ALIGN, align);
        args.put(PROPS_OUTPUTROWPX_PAD, outputRowPX_pad);
        args.put(PROPS_OUTPUTCOLPX_PAD, outputColPX_pad);
        args.put(PROPS_SIZE, off.getClipBounds().getSize());
        _drawNewLine(args,
                off,
                new StringBuffer("CONSOLE GUI " + _getCharsResolution(off, (Integer)args.get(PROPS_OUTPUTROWPX_PAD), (Integer)args.get(PROPS_OUTPUTCOLPX_PAD))));
        drawScreenBuffer(args, off, System.currentTimeMillis());
        off.translate(lastOutputPX.x, lastOutputPX.y - cursor.getHeight());
        cursor.play();
        cursor.validate();
        complete = complete && cursor.draw(obs, off);
        off.translate(-lastOutputPX.x, -(lastOutputPX.y - cursor.getHeight()));
        g2.setComposite(cps);
        return complete;
    }
    private PrintStream printStream = console.getNewPrintStream(new ErrorListener() {

        public void printStreamError(IOException e) {
            e.printStackTrace();
        }
    });

All this source code can be fetched at sf.net/projects/sf3jswing with the API JIGAXtended. ;D

https://sourceforge.net/dbimage.php?id=162856

Don’t forget to precise that JIGAXtended is not fully cross platform.