Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
BEGIN LICENSE BLOCK ***** Version: CPL 1.0/GPL 2.0/LGPL 2.1 The contents of this file are subject to the Common Public License Version 1.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.eclipse.org/legal/cpl-v10.html Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. Copyright (C) 2007 Charles Nutter <charles.o.nutter@sun.com> Copyright (C) 2008 MenTaLguY <mental@rydia.net> Alternatively, the contents of this file may be used under the terms of either of the GNU General Public License Version 2 or later (the "GPL"), or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), in which case the provisions of the GPL or the LGPL are applicable instead of those above. If you wish to allow use of your version of this file only under the terms of either the GPL or the LGPL, and not to allow others to use your version of this file under the terms of the CPL, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the GPL or the LGPL. If you do not delete the provisions above, a recipient may use your version of this file under the terms of any one of the CPL, the GPL or the LGPL. END LICENSE BLOCK ***
 
 package org.jruby;
 
 import java.awt.Color;
 import java.awt.Font;
 import java.net.URL;
 
 
 

Author(s):
MenTaLguY The JRubyApplet class provides a simple way to write Java applets using JRuby without needing to create a custom Java applet class. At applet initialization time, JRubyApplet starts up a JRuby runtime, then evaluates the scriptlet given as the "eval" applet parameter. The Java applet instance is available to the Ruby script as JRUBY_APPLET; the script can define callbacks for applet start, stop, and destroy by passing blocks to JRUBY_APPLET.on_start, JRUBY_APPLET.on_stop, and JRUBY_APPLET.on_destroy, respectively. Ruby code can install a custom paint callback using JRUBY_APPLET.on_paint (the Graphics2D object is passed as an argument to the callback). By default, JRubyApplet painting is double-buffered, but you can select single-buffered painting via JRUBY_APPLET.double_buffered = false. The applet's background color can be set via JRUBY_APPLET.background_color=. You may want to set it to nil if you're not using double-buffering, so that no background color will be drawn (your own paint code is then responsible for filling the area). Beyond these things, you should be able to use JRuby's Java integration to do whatever you would do in Java with the applet instance.
 
 public class JRubyApplet extends Applet {
     private Ruby runtime;
     private boolean doubleBuffered = true;
     private Color backgroundColor = .;
     private RubyProc startProc;
     private RubyProc stopProc;
     private RubyProc destroyProc;
     private RubyProc paintProc;
     private Graphics priorGraphics;
     private IRubyObject wrappedGraphics;
     private VolatileImage backBuffer;
     private Graphics backBufferGraphics;
    private Facade facade;
    private interface Facade {
        public InputStream getInputStream();
        public PrintStream getOutputStream();
        public PrintStream getErrorStream();
        public void attach(Ruby runtimeApplet applet);
        public void destroy();
    }
    private static RubyProc blockToProc(Ruby runtimeBlock block) {
        if (block.isGiven()) {
            RubyProc proc = block.getProcObject();
            if (proc == null) {
                proc = RubyProc.newProc(runtimeblockblock.type);
            }
            return proc;
        } else {
            return null;
        }
    }
    private boolean getBooleanParameter(String nameboolean defaultValue) {
        String value = getParameter(name);
        if ( value != null ) {
            return value.equals("true");
        } else {
            return defaultValue;
        }
    }
    
    
Return Ruby language version from the applet parameter

Parameters:
compat - name of the parameter handed to the applet
defaultVersion
Returns:
Ruby language version; CompatVersion.RUBY1_9 if parameter is exactly "1.9". Otherwise, return defaultVersion
    private CompatVersion getCompatVersionParameter(String compatCompatVersion defaultVersion) {
        CompatVersion compatVersion = defaultVersion;
        if (getParameter(compat).equals("1.9")) compatVersion = .;
        return compatVersion;
    }
    private InputStream getCodeResourceAsStream(String name) {
        if (name == null) {
            return null;
        }
        try {
            final URL directURL = new URL(getCodeBase(), name);
            return directURL.openStream();
        } catch (IOException e) {
        }
        return JRubyApplet.class.getClassLoader().getResourceAsStream(name);
    }
    private static void safeInvokeAndWait(Runnable runnablethrows InvocationTargetExceptionInterruptedException {
        if (EventQueue.isDispatchThread()) {
            try {
                runnable.run();
            } catch (Exception e) {
                throw new InvocationTargetException(e);
            }
        } else {
            EventQueue.invokeAndWait(runnable);
        }
    }
    public static class RubyMethods {
        @JRubyMethod
        public static IRubyObject on_start(IRubyObject recvBlock block) {
            JRubyApplet applet = (JRubyApplet) JavaEmbedUtils.rubyToJava(recv);
            synchronized (applet) {
                applet.startProc = blockToProc(applet.runtimeblock);
            }
            return recv;
        }
        @JRubyMethod
        public static IRubyObject on_stop(IRubyObject recvBlock block) {
            JRubyApplet applet = (JRubyApplet) JavaEmbedUtils.rubyToJava(recv);
            synchronized (applet) {
                applet.stopProc = blockToProc(applet.runtimeblock);
            }
            return recv;
        }
        @JRubyMethod
        public static IRubyObject on_destroy(IRubyObject recvBlock block) {
            JRubyApplet applet = (JRubyApplet) JavaEmbedUtils.rubyToJava(recv);
            synchronized (applet) {
                applet.destroyProc = blockToProc(applet.runtimeblock);
            }
            return recv;
        }
        @JRubyMethod
        public static IRubyObject on_paint(IRubyObject recvBlock block) {
            JRubyApplet applet = (JRubyApplet) JavaEmbedUtils.rubyToJava(recv);
            synchronized (applet) {
                applet.paintProc = blockToProc(applet.runtimeblock);
                applet.repaint();
            }
            return recv;
        }
    }
    @Override
    public void init() {
        super.init();
        if (getBooleanParameter("jruby.console"false)) {
             = new ConsoleFacade(getParameter("jruby.banner"));
        } else {
             = new TrivialFacade();
        }
        synchronized (this) {
            if ( != null) {
                return;
            }
            final RubyInstanceConfig config = new RubyInstanceConfig() {{
                setInput(.getInputStream());
                setOutput(.getOutputStream());
                setError(.getErrorStream());
                setObjectSpaceEnabled(getBooleanParameter("jruby.objectspace"false));
                setCompatVersion(getCompatVersionParameter("jruby.compat".));
            }};
            Ruby.setSecurityRestricted(true);
             = Ruby.newInstance(config);
        }
        final String scriptName = getParameter("jruby.script");
        final InputStream scriptStream = getCodeResourceAsStream(scriptName);
        final String evalString = getParameter("jruby.eval");
        try {
            final JRubyApplet applet = this;
            safeInvokeAndWait(new Runnable() {
                public void run() {
                    applet.setLayout(new BorderLayout());
                    applet.facade.attach(applet.runtimeapplet);
                    if (scriptStream != null) {
                        applet.runtime.runFromMain(scriptStreamscriptName);
                    }
                    if (evalString != null) {
                        applet.runtime.evalScriptlet(evalString);
                    }
                }
            });
        } catch (InterruptedException e) {
        } catch (InvocationTargetException e) {
            throw new RuntimeException("Error running script"e.getCause());
        }
    }
    private void invokeCallback(final RubyProc procfinal IRubyObject[] args) {
        if (proc == null) {
            return;
        }
        final Ruby ruby = this.;
        try {
            safeInvokeAndWait(new Runnable() {
                public void run() {
                    proc.call(ruby.getCurrentContext(), args);
                }
            });
        } catch (InterruptedException e) {
        } catch (InvocationTargetException e) {
            throw new RuntimeException("Ruby callback failed"e.getCause());
        }
    }
    public synchronized void setBackgroundColor(Color color) {
         = color;
        repaint();
    }
    public synchronized Color getBackgroundColor() {
        return ;
    }
    @Override
    public synchronized boolean isDoubleBuffered() {
        return ;
    }
    public synchronized void setDoubleBuffered(boolean shouldBuffer) {
         = shouldBuffer;
        repaint();
    }
    @Override
    public synchronized void start() {
        super.start();
        invokeCallback(new IRubyObject[] {});
    }
    @Override
    public synchronized void stop() {
        invokeCallback(new IRubyObject[] {});
        super.stop();
    }
    @Override
    public synchronized void destroy() {
        try {
            invokeCallback(new IRubyObject[] {});
        } finally {
            .destroy();
            final Ruby ruby = this.;
            this. = null;
             = null;
             = null;
             = null;
             = null;
             = null;
             = null;
            ruby.tearDown();
            super.destroy();
        }
    }
    @Override
    public void update(Graphics g) {
        paint(g);
    }
    @Override
    public synchronized void paint(Graphics g) {
        if () {
            paintBuffered(g);
        } else {
            paintUnbuffered(g);
        }
    }
    private synchronized void paintBuffered(Graphics g) {
        do {
            GraphicsConfiguration config = getGraphicsConfiguration();
            int width = getWidth();
            int height = getHeight();
            if ( == null || width != .getWidth() || height != .getHeight() || .validate(config) == .) {
                if ( != null) {
                    .dispose();
                     = null;
                    .flush();
                     = null;
                }
                 = config.createCompatibleVolatileImage(widthheight);
                 = .createGraphics();
            }
            .setClip(g.getClip());
            paintUnbuffered();
            g.drawImage(, 0, 0, this);
        } while (.contentsLost());
    }
    private synchronized void paintUnbuffered(Graphics g) {
        if ( != null) {
            g.setColor();
            g.fillRect(0, 0, getWidth(), getHeight());
        }
        if ( != null) {
            if ( != g) {
                 = JavaUtil.convertJavaToUsableRubyObject(g);
                 = g;
            }
            ThreadContext context = .getCurrentContext();
            .call(contextnew IRubyObject[] {});
        }
        super.paint(g);
    }
    private static class TrivialFacade implements Facade {
        public TrivialFacade() {}
        public InputStream getInputStream() { return .; }
        public PrintStream getOutputStream() { return .; }
        public PrintStream getErrorStream() { return .; }
        public void attach(Ruby runtimeApplet applet) {
            final IRubyObject wrappedApplet = JavaEmbedUtils.javaToRuby(runtimeapplet);
            runtime.defineGlobalConstant("JRUBY_APPLET"wrappedApplet);
            wrappedApplet.getMetaClass().defineAnnotatedMethods(RubyMethods.class);
        }
        public void destroy() {}
    }
    private static class ConsoleFacade implements Facade {
        private JTextPane textPane;
        private JScrollPane scrollPane;
        private TextAreaReadline adaptor;
        private InputStream inputStream;
        private PrintStream outputStream;
        private PrintStream errorStream;
        
        public ConsoleFacade(String bannerText) {
             = new JTextPane();
	    .setMargin(new Insets(4, 4, 0, 4));
            .setCaretColor(new Color(0xa4, 0x00, 0x00));
            .setBackground(new Color(0xf2, 0xf2, 0xf2));
            .setForeground(new Color(0xa4, 0x00, 0x00));
            Font font = findFont("Monospaced"., 14,
                                 new String[] {"Monaco""Andale Mono"});
            .setFont(font);
             = new JScrollPane();
            .setDoubleBuffered(true);
            if ( bannerText != null ) {
                bannerText = "  " + bannerText + "  \n\n";
            }
             = new TextAreaReadline(bannerText);
             = .getInputStream();
             = new PrintStream(.getOutputStream());
             = new PrintStream(.getOutputStream());
        }
        public InputStream getInputStream() { return ; }
        public PrintStream getOutputStream() { return ; }
        public PrintStream getErrorStream() { return ; }
        public void attach(Ruby runtimeApplet applet) {
            .hookIntoRuntime(runtime);
            applet.add();
            applet.validate();
        }
        public void destroy() {
            Container parent = .getParent();
            .shutdown();
            if (parent != null) {
                parent.remove();
            }
        }
        private Font findFont(String otherwiseint styleint sizeString[] families) {
            String[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
            Arrays.sort(fonts);
            for (int i = 0; i < families.lengthi++) {
                if (Arrays.binarySearch(fontsfamilies[i]) >= 0) {
                    return new Font(families[i], stylesize);
                }
            }
            return new Font(otherwisestylesize);
        }
    }
New to GrepCode? Check out our FAQ X