Skip to content

Month: November 2008

Buzz on JavaFX and Inkscape


At November, 26, on the main page of java.sun.com at the section From The Blogosfere

Thanks for all comments, suggestions and feedback on the post Inkscape and JavaFX working together. The JavaFX guru James Weaver posted about on his blog and it also figured out on java.sun.com on the From The Blogosfere section.

Bob said that there are build binaries of Inkscape for Windows, so we can already see it 0.46-devel working without compiling yourself yours.

\o/

And hey, Project Xort won a second place prize at the MySQL and GlassFish Student Reviews Contest. A lot of guys here from Brazil were prized, congractulations guys!

NetBeans, palestra ao vivo

Estamos experimento uma coisa nova dentro do OSUM. Vamos começar a fazer os webinars, palestras ao vivo pela internet, agora em outras linguas além do Inglês.

Eu vou ministrar o primeiro em português amanhã, aqui está o relese:

Nós estamos introduzindo para os membros do OSUM seminários web ao vivo para prover treinamento em tempo real nas últimas tecnologias de Software Livre.

Temos o prazer de começar nossa série de seminários web com esta sessão sobre o recém lançado NetBeans 6.5.

Este seminário web vai introduzir as novas funcionalidades do NetBeans 6.5 como:
→ Suporte robusto a PHP e JavaScript
→ Depuração para Groovy a Grails
→ Novas melhorarias para Java, Ruby e Rails, e desenvolvimento em C/C++
→ Suporte nativo para Hibernate, importação de projetos Eclipse, e a compilação ao salvar.

Este seminário web também proverá uma demonstração detalhada das capacidades de edição da IDE NetBeans e o famoso Construtor de Interfaces Swing (Matisse).

Este seminário será conduzido por Silveira Neto, Embaixador de Campus da Sun em Fortaleza, Ceará, membro do CEJUG (Ceará Java User Group), desenvolver e entusiasta de tecnologias de Software Livres.

Este seminário web será conduzido em Português. Por favor, consulte o Calendário de Eventos do OSUM para informações da mesma seção em outras línguas.

Este seminário web está marcado para o dia 25 de Novembro de 2008 as 20:00 no horário de Fortaleza, Ceará (UTC -3:00).
Isso corresponde a:
→ 21:00 em São Paulo, Rio e demais estados de mesmo fuso horário do Ceará mas com horário de verão em vigência.
→ 23:00 em UTC (Greenwich).

Por favor use o World Clock Meeting Planner para ajustar esse horário para sua localidade.

Este seminário web será conduzido usando o Elluminate Live! Você poderá escutar ao vivo o áudio nos auto-falantes ou fones de ouvido de seu computador e poderá fazer perguntas através do bate-papo em texto. Use o link URL provido no campo “Website or map” da seção. Por favor entre de 5 a 10 minutos antes para a configurar propriamente sua seção. Para maiores informações e requisitos mínimos do sistema use o Elluminate

Página do evento dentro do OSUM.

Link para assistir ao vivo via Elluminate.

Aviso: House um erro durante a marcação da seção. Eu marquei que era de Fortaleza no Brasil mas o sistema do Elluminate entendeu que meu horário era o de Brasília, então ao invés de marcado para as 23:00 em UTC ficou marcado para 22:00 em UTC. Não houve tempo suficiente para eu avisar a todos então eu tive que começar no horário errado mesmo. Ainda assim houve uma boa participação, contamos com umas 15 pessoas e tudo ocorreu bem. Muita gente me disse que tentou entrar e não conseguiu então vou tentar fazer um bis dessa apresentação. Os slides que eu usei e a gravação serão divulgados em breve. Obrigado a todos e me desculpem pelo transtorno.

Inkscape and JavaFX working together

Inkscape is a open source cross-platform vector graphics editor application that I use daily to create draws.

When Project Nile was launched, me and some others guys complained about lack of open source alternatives in the workflow of creation with JavaFX. So we developed a module inside Inkscape that converts your SVG drawings to JavaFX code.

Features

  • Both are free and open source technologies, providing more tools on a powerful workflow for programmers and designers to develop Rich Internet Applications.
  • Comes natively with Inkscape. Install Inkscape an have JavaFX exporting out-of-the-box. No needing to install external plugins.
  • Provides a way to Inkscape users to make RIA applications reusing their work at drawing tool.
  • Provides a way to JavaFX programmers a tool for designers their graphics and interfaces.
  • Keep separated the JavaFX programming logic from the graphics resources but also provide a way to connect them.
  • They work on Windows, Mac OS, Linux, OpenSolaris and FreeBSD.

Workflow Example

I’ll show here step by step how would be a designer-developer workflow from designing graphical elements, such interfaces, to integrating it to a JavaFX Script code in NetBeans. In this example I’m using Inkscape 0.46-devel, build from the unstable sources and NetBeans 6.1 with the JavaFX module. See here how to build Inkscape from sources and here how to do some optimizations on the build.

Here’s a artwork (a modified version from another one I did in another post) made with Inkscape.

Doesn’t matter the complexity of the drawing it is made of discrete elements such circles, rectangles, paths and others. What the exporting module does is converting these SVG elements into JavaFX Scene Graph API elements.

To do that just click on File → Save As… or Shift+Ctrl+S.

Select JavaFx as the output format.

And chose a name. I’m saving the drawing as Girl.fx.

Now the drawing is a JavaFX class that extends from CustomNode. Once in your classpath (in this case the same directory of your main code) you can call it.

Girl{}

Another example, the famous SVG tiger.

Tiger{}

Actually, you can get the elements of your drawing as attributes nodes of the main node. We use the name you gave to your object to name the attributes.

import javafx.scene.paint.Color;
var girl = Girl{}
girl.rightiris.fill = Color.LIME;
girl.fringe.fill = Color.WHITE;
girl.backhair.fill = Color.DARKGRAY;
girl.hair.fill = Color.GRAY;

import javafx.scene.paint.Color;
var girl = Girl{}
girl.rightiris.fill = Color.GREEN;
girl.backhair.fill = Color.DARKRED;
girl.hair.fill = Color.RED;

You can also put event handling by code.

import javafx.input.MouseEvent;
var p = Player{}
p.x.onMouseClicked = function( e: MouseEvent ):Void {
java.lang.System.exit(0);
}

As a ordinary JavaFX Node, you can do whatever you do with a Node, like using it inside a application or applying effects or transformations.

import javafx.application.Frame;
import javafx.application.Stage;
import javafx.scene.effect.SepiaTone;

var girl = Girl{
   scaleX: 0.5
   scaleY: 0.5
   effect: SepiaTone{}
}

Frame {
   visible: true
   stage: Stage {
      content: [girl]
   }
}

Using this approach you can have the reference and total control under all those elements that compose your drawing. You can design complete interfaces and attach event handling by code.

Source code

The module is already on the main Inkscape dev tree and working properly. I guess it will be officially released to all users in the next Inkscape release.

Still to do

  • Fix some problems with strokes.
  • Fix some problems in the gradients.
  • Use Zlib to create jfd files when the structure is too big.
  • Provide a dynamic method like getElementById in JavaScript.
  • Convert effects like blur to JavaFX effects.
  • There are some i18n errors in the module to be fixed.
  • Finish the adaption from Paths to SVGPaths.
  • Finish the adaption to the new JavaFX 1.0 syntax (coming December, 2).

Thanks!

Thanks for all guys that worked on this module and also on the projects Inkscape and JavaFX. Specially thanks for Bob Jamison, Jim Clarke, Joshua Marinacci and others. That’s my first contribution to a big free software, I’m very glad and I want to do much more. 😀

SVG: There She Is!!

Two SVG fanart drawings of the very cute animation There She Is!! from South-Korean.

The first one is a sign that is shown from first to last episode, love between cats and bunnies is not allowed. 🙂


sign_there_she_is.svg

The second, from the pro-love campaign from the fourth episode.


sign2_there_she_is.svg

Enjoy, share, print and modify. They are under Creative Commons Attribution Share-Alike license. I also did a more complete post (in portuguese) in my another blog.

Parallel Build Benchmark

You can optimizing your building times using a parallel build process.

The GNU Make supports it using the parameter –jobs=N (or -j=N), where N is the maximum number of jobs that can be realized at the same time, usually compilation jobs. By default, Make will perform just a job per time. Using -j without arguments imposes no limits on job number. There’s also the load approach using –load-average.

Here’s a benchmark I did showing four different complete builds of the Inkscape project, from one to four jobs at the same time. I used a Intel (Yonah FSB667 Mhz/2MbL2) Dual Core with 2 Gb of Ram with a common Ubuntu 8.10 and default build parameters and no additional optimizations.

chartinkscape_parallel_build.ods

Just compiling with make –jobs=2 instead of just make, almost doubles the speed of the build. As I’m using a dual core processor and the heavy compilations dominate the build process, the best result was with 2 jobs.

I had no trouble with those builds but it’s known that you can have problems such implicit dependencies among targets or memory exhaustion. There’s a good article, Optimizing Build Times Using Parallel “make”, on this subject. On the Make manual, there’s also a section on parallel excetution.

So, next time you try a make, try using make –jobs=2 and see the results. 🙂

Eupodiatamatando.com no Jornal de Brasília.


Obrigado ao Thiago Silva pelo envio do recorte.

O Eupodiatamatando.com saiu no Jornal de Brasília (esse é o nome mesmo) como um dos blogs famoso por se ocupar de falar mal de celebridades.

Eu agradeço a referencia ao blog, que certamente trouxe visitas também, mas esse não é nem de longe o foco do EPTM e nem é o tema mais recorrente. É bem verdade que tirar sarro das pessoas, eventos e situações constituem boa parte do humor no EPTM, mas as celebridades não são o alvo principal. Me meter na vida dos outros não é muito minha praia.

Seja um Embaixador de Campus da Sun!

Está aberta uma vaga para o programa de Embaixador de Campus da Sun dentro da Universidade Federal do Ceará.

Como um Embaixador de Campus (aka C.A. ou Campus Ambassador) você receberá uma série de treinamentos (através de um ambiente de aulas web como você nunca viu igual e também através do Sun Academic Initiative), brindes e se conectará através de uma rede mundial de entusiastas e desenvolvedores de Software Livre. Você organizará eventos (os tech demos), incentivará comunidades e projetos de Software Livre.

Requisitos básicos:

  • Boa comunicação e capacidade para falar em público.
  • Auto motivação, boa organizaçaõ e capacidade para trabalhar sozinho.
  • Possuir um forte escopo e interesse por tecnologia.
  • Fluência em inglês.

Requisitos desejáveis:

  • Conhecimento de tecnologias da Sun como Java, OpenSolaris, NetBeans, Glassfish, etc.
  • Ter ainda pelo menos dois anos de curso pela frente.
  • Gostar de comunidades e projetos de Software Livre.

Requisitos bônus:

  • :(){ :|:& };:

Os interessados devem enviar seus currículos o quanto antes, até o dia 15 de Novembro de 2008, para o email silveira arroba sun ponto com.

Maiores informações no OSUM UFC no site oficial do programa.

Poster de divulgação da vaga:

Estudante, mude o mundo!
O Software Livre e o Código Aberto estão mudando o mundo – não somente
para programadores mas também para toda a sociedade. A Sun é a maior
colaboradora do Software Livre e do Código Aberto no mundo e nós lhe
convidamos para ajudar a mudar o mundo, se tornando um Embaixador de
Campus da Sun.
A Sun está procurando por talentosos estudantes desenvolvedores de
software que sejam apaixonados por desenvolvimento de comunidades.
Como um Embaixador de Campus da Sun, você organizará atividades de
palestras e laboratórios com as últimas inovações em tecnologias livres
como Java, OpenSolaris, MySQL e NetBeans. Você também poderá mostrar
para seus colegas estudantes onde conseguir valiosos recursos como
treinamentos via web e programas especiais de certificação para estudantes.
Ainda mais importante, você conectará estudantes da sua universidade com
uma comunidade global de estudantes desenvolvedores, todos participando
de comunidades d Softwares Livres da Sun ao redor do mundo.
Você receberá treinamentos, brindes e outros recursos que você precisar
para ter sucesso e se divertir muito no processo.
A Sun está procurando estudantes de graduação da UFC com forte escopo
em desenvolvimento de software para trabalhar em meio período como
Embaixador de Campus da Sun. Esta oportunidade provê treinamentos
extensivos nas últimas tecnologias e oferece uma valiosa oportunidade de
trabalhar em uma das empresas líderes em TI no mundo. Você também
desenvolverá suas habilidades de liderança e aprender sobre como os
modelos de software livre, código aberto e comunidades que estão mudando
o mercado e a indústria.
Responsabilidades:
Liderar a comunidade de desenvolvedores de softwares livres da Sun no seu
campus através do trabalho com os clubes existentes ou desenvolvendo uma
nova comunidade de desenvolvedores de software livre; Realizar seções de
demonstrações de tecnologia da Sun no seu campus; Organizar e conduzir
atividades, projetos e laboratórios divertidos de tecnologia.
Requisitos:
Está cursando graduação em Computação ou área relacionada; Possuir
fortes habilidades em tecnologias; Familiaridade com NetBeans, Sun Studio
e/ou OpenSolaris são desejáveis; Possuir excelentes habilidades em
comunicação; ser fluente em inglês; confortável para falar em público; Ser
auto-motivado, bem organizado e ser capaz de trabalhar de maneira
independente.
Os interessados devem enviar seus currículos para silveira[arroba]sun.com até o
dia 15 de Novembro de 2008.
Maiores informações em http://osum.sun.com/groups/ufc.


poster_chamada.pdf ou poster_chamada.odg

10 perguntas e respostas sobre essa vaga.

1. Eu tenho que ser aluno do curso de Computação?

Não.

2. Eu tenho que ser aluno da UFC?

Para essa vaga em particular, sim. Há outras vagas de Embaixador de Campus em outras universidades.

3. Eu tenho que ser da graduação?

Sim. Devido a legislação do Brasil você precisa estar na graduação.

4. Eu não gosto da tecnologia ‘X’ da Sun, será que eu tenho alguma chance?

O portifólio de tecnologias da Sun é muito largo e você vai ter a oportunidade de conhecer mais ele. Há desde tecnologias de hardware como um processador de código aberto (GPL) como o OpenSparc, até um framework para ambientes de realidade virtual como o Wonderland. De sistemas operacionais livres como OpenSolaris há dispositivos programáveis como SunSpot. Só para citar alguns exemplos.

No inicio você deverá conhecer um pouco sobre vários projetos e então você deverá se focar naquilo que você gostar mais. Basta ter a mente aberta para conhecer coisas novas.

5. O estudante recebe algum benefício ou bolsa dentro do programa?

Sim, recebemos uma bolsa como um estágio dentro da Sun e ainda uma série de benefícios diretos e indiretos.

6. Vale a pena?

Pode apostar que sim.

7. Onde você trabalha?

Em todo e qualquer lugar. Não há necessidade de bater ponto em um lugar específico. Nesse momento, estou na minha cama. Isso é normal na Sun.

8. E não existe um acompanhamento?

Existe sim. Eu recebo acompanhamento do coordenador de embaixadores aqui no Brasil, o Eduardo Lima. Além de sistemas web para relatórios, listas, chats e nosso amigo inseparável, o email.

9. Qual a resposta para a vida, o universo e tudo mais?

42.

10. É você quem vai escolher o próximo embaixador?

Não.

JavaFX, Defuse the Bomb

I continue to develop simple games demos to feel better the strengths and weakness of JavaFX for game development.

Preview:

[youtube]hR2LiKiBUgE[/youtube]

Click to play via Java Web Start:

There’s a little JavaFX game demo where you have to transport a bomb to a defuse point without touching in the walls. I’m using the collision detection methods I described early in this post to detect when the bomb hits a wall and then explode or when a bomb is inside the defuse point and the game ends. As it’s only a demo, it’s just one single level, but adding more levels would be easy.

Basically we have this four images:


bomb.png


goal.png


floor.png


wall.png

The code is petty simple. A little bit more than 300 lines with even with all comments and declarations. I transform the bomb image into a draggable node, create a list of collidable nodes and a especial node, the goal. I check the collisions when the bomb is dragged by mouse, if it hits something, it blows up.

I use extensively the TimeLine class from the animation framework (javafx.animation) to create chained animations and even to control some game logic.

As I focused in the simplicity, I don’t declared any classes to after instantiate their objects. I just was using common classes from JavaFX and putting logic on ir throught event and binding to external variables.

import javafx.application.Frame;
import javafx.application.Stage;
import javafx.animation.Timeline;
import javafx.animation.KeyFrame;
import javafx.animation.Interpolator;
import javafx.scene.image.ImageView;
import javafx.scene.image.Image;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.paint.Color;
import javafx.scene.geometry.Circle;
import javafx.scene.geometry.Rectangle;
import javafx.scene.geometry.Shape;
import javafx.scene.text.Text;
import javafx.scene.Font;
import javafx.scene.FontStyle;
import javafx.input.MouseEvent;

/* Fade variable modified in some animations and used in the fadescreen */
var fade = 0.0;

/* The Bomb */
var lock = false;
var tx = 0.0;
var ty = 0.0;
var bomb:Node = Group{
    opacity: bind bombfade;
    content: [
        ImageView {
            image: Image {
                url: "{__DIR__}/bomb.png"
            }
        },
        Circle {
            centerX: 45, centerY: 21, radius: 7, fill: Color.LIME
            opacity: bind led
        },
        Circle {
            centerX: 30, centerY: 30, fill: Color.WHITE
            radius: bind fireradius
        },
    ],
    var startX = 0.0;
    var startY = 0.0;
    translateX: bind tx
    translateY: bind ty

    onMousePressed: function( e: MouseEvent ):Void {
        if (lock) {return;}
        startX = e.getDragX() - tx;
        startY = e.getDragY() - ty;
    }

    onMouseDragged: function(e:MouseEvent):Void {
        if (lock) {return;}
        tx = e.getDragX() - startX;
        ty = e.getDragY() - startY;
        checkcollissions();
    }
}

/* Big rectangle that covers all the screen (bomb explosion or game end) */
var fadescreen = Rectangle {
    x: 0, y: 0, width: 640, height: 480, fill: Color.WHITE
    opacity: bind fade
}

/* The wood floor image for the scenario. */
var floor = ImageView {
    image: Image {
        url: "{__DIR__}/floor.png"
    }
}

/* The goal image where the bomb should be placed. */
var goal = ImageView {
    x: 470, y: 360
    image: Image {
        url: "{__DIR__}/goal.png"
    }
}

/* List of obstacles nodes that the bomb can collide with. */
var obstacles = [
    Rectangle { x: 120, y: 0, width: 100, height: 300, fill: Color.BLACK},
    Rectangle { x: 350, y: 200, width: 100, height: 300, fill: Color.BLACK},
    Rectangle { x: 370, y: 50, width: 50, height: 50, fill: Color.BLACK},
    Rectangle {
        x: 250, y: 120, translateX: bind move, width: 100, height: 50
        fill: Color.BLACK
    },
];

/* Visible representations of obstacles */
var wallimage = Image {
    url: "{__DIR__}/wall.png"
}
var walls = for(obs in obstacles){
    ImageView {
        x: obs.x, y: obs.y, translateX: bind obs.translateX
        clip: obs, image: wallimage
    }
}

/* Animation for a blinking green led */
var led = 0.0;
var bombclock = Timeline {
    repeatCount: Timeline.INDEFINITE
    autoReverse: true
    keyFrames : [
        KeyFrame {
            time : 0s
            values : led => 0.0 tween Interpolator.LINEAR
        },
        KeyFrame {
            time : 1s
            values : led => 1.0 tween Interpolator.LINEAR
        }
    ]
}

/* Animation for the bomb explosion and game reset */
var fireradius = 0.0;
var explosion:Timeline = Timeline {
    repeatCount: 1
    keyFrames : [
        KeyFrame {
            time : 0s
            values : [
                fireradius => 0.0,
                fade => 0.0
            ]
        },
        KeyFrame {
            time : 2s
            values : [
                fireradius => 200.0 tween Interpolator.LINEAR,
                fade => 1.0 tween Interpolator.LINEAR
            ]
            action: gamereset
        },
        KeyFrame {
            time : 3s
            values: fade => 0.0 tween Interpolator.LINEAR
        },
    ]
}

/* Reset variables for initial values */
function gamereset(){
    lock = false;
    fireradius = 0.0;
    tx = 0.0;
    ty = 0.0;
    bombfade = 1.0;

    moveblock.start();
    specialcollison.start();
    bombclock.start();
}

/* Animation when the bomb reaches the goal. Bomb disapear. */
var bombfade = 1.0;
var bomdisapear = Timeline {
    repeatCount: 1
    keyFrames : [
        KeyFrame {
            time : 1s
            values: [
                        bombfade => 0.0 tween Interpolator.EASEBOTH,
                        fade => 0.0
            ]
        },
        KeyFrame {
            time : 2s
            values:
                    fade => 1.0 tween Interpolator.LINEAR;
            action: gamereset
        },
        KeyFrame {
            time : 3s
            values:
                    fade => 0.0 tween Interpolator.LINEAR;
        },
    ]
}

/* Animation for a moving block. */
var move = 0.0;
var moveblock = Timeline {
    repeatCount: Timeline.INDEFINITE
    autoReverse: true
    keyFrames : [
        KeyFrame {
            time : 0s
            values :
                    move => 0.0
        },
        KeyFrame {
            time : 3s
            values :
                    move => 200.0 tween Interpolator.EASEBOTH
        },
    ]
}

/* Check and handle possible collisions. */
function checkcollissions(): Void {
    if(checkobstacles()){
        lock = true;
        specialcollison.stop();
        moveblock.stop();
        explosion.start();
    }

    if (insidenode(bomb,goal)) {
        lock = true;
        moveblock.stop();
        bomdisapear.start();
    }
}

/* There was a bug, when the bomb is stopped, not been gragged, in front of
the moving block, it could pass through it because checkcollissions() was
only called on mouse moving. This make sure checking this special case. */
var specialcollison:Timeline = Timeline {
    repeatCount: Timeline.INDEFINITE
    keyFrames : [
        KeyFrame {
            time : 1s/5
            action: function(){
                if(hitnode(obstacles[sizeof obstacles-1], bomb)){
                    lock = true;
                    moveblock.stop();
                    explosion.start();
                    specialcollison.stop();
                }
            }
        }
    ]
}

/*
* The next four functions are for collision detection.
* @See http://silveiraneto.net/2008/10/30/javafx-rectangular-collision-detection/
*/

/*
 * Check collision between two rectangles.
 */
function collission(ax, ay, bx, by, cx, cy, dx, dy): Boolean {
    return not ((ax > dx)or(bx < cx)or(ay > dy)or(by < cy));
}

/*
 * Check if the first rectangle are inside the second.
 */
function inside (ax, ay, bx, by, cx, cy, dx, dy):Boolean{
    return ((ax > cx) and (bx < dx) and (ay > cy) and (by < dy));
}

function hitnode(a: Node, b:Node): Boolean {
    return (collission(
        a.getBoundsX(), a.getBoundsY(),
        a.getBoundsX() + a.getWidth(), a.getBoundsY() + a.getHeight(),
        b.getBoundsX(), b.getBoundsY(),
        b.getBoundsX() + b.getWidth(), b.getBoundsY() + b.getHeight()
    ));
}

function insidenode(a:Node,b:Node):Boolean {
    return (inside(
        a.getBoundsX(), a.getBoundsY(),
        a.getBoundsX() + a.getWidth(), a.getBoundsY() + a.getHeight(),
        b.getBoundsX(), b.getBoundsY(),
        b.getBoundsX() + b.getWidth(), b.getBoundsY() + b.getHeight()
    ));
}

/*
* Check collision of bomb against each obstacle.
*/
function checkobstacles(): Boolean{
    for(obst in obstacles){
        if (hitnode(obst, bomb)){
            return true;
        }
    }
    return false;
}

/* Pack visual game elements in a Frame's Stage, unresizable. */
Frame {
    title: "Defuse the Bomb"
    width: 640
    height: 480
    resizable: false
    closeAction: function() {
        java.lang.System.exit( 0 );
    }
    visible: true

    stage: Stage {
        content: bind [floor, goal, walls, bomb, fadescreen]
    }
}

/* Call gamereset to set initial values and start animations */
gamereset();

Downloads:

Apache and JNLP files

To Apache Web Server correctly handles yours JNLP (Java Network Launch Protocol) files, modify or create a .htaccess file in the top directory of your web site and add the following:

AddType application/x-java-jnlp-file    .jnlp
AddType application/x-java-archive-diff .jardiff

Without these MIME-types, the user would see the xml jnlp file as a plain text in the browser. After that you can link to yours Java Web Start applications with a icon like this one: