Wednesday, June 29, 2011

JavaFX 2.0 "Avoid The Red Balls"

In a comment to my article „JavaFX avoid the red balls“ i was pointed to JavaFX 2.0. The greatest difference between JavaFX 1.x and 2.0 is that in 2.0 you can write your applications now in Java. The support for JavaFX-Script has been completely dropped. Therefore I ported my application from 1.x to 2.0.

JavaFX is very powerful in creating user interfaces with emphasis on look and feel and design. I was able to port my App without any greater issues. Most of the code was usable as it was I just had to change the syntax. The greatest difference was the use of “AnimationTimer“ instead of “timeline”. The new version and the source code (as a netbeans project) is available here. Here is the JavaFX 2.0 code:
/*
 * Copyright 2011, Benny Gächter
 *
 * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package jfxtest;

import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.scene.input.MouseEvent;
import java.util.Random;
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventType;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.effect.BoxBlur;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.StrokeType;
import javafx.stage.Stage;

/**
 *
 * @author Benny Gächter
 */
public class JFXTest extends Application implements EventHandler {

    static int APP_WIDTH = 800;
    static int APP_HEIGHT = 600;
    double mouseX = 0.0;
    double mouseY = 0.0;
    Random random = new java.util.Random();
    int state = 1;
    int counter = 0;
    double currentRuntime;
    Rectangle player;
    long lastUpdate = 0;
    long startTime = 0;
    final Group balls = new Group();
    Group root = null;
    AnimationTimer timer = null;

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
 Application.launch(JFXTest.class, args);
    }

    @Override
    public void start(Stage primaryStage) {
 primaryStage.setTitle("Red Balls JavaFX 2.0");
 lastUpdate = System.currentTimeMillis();

 root = new Group();
 Scene scene = new Scene(root, APP_WIDTH, APP_HEIGHT, Color.WHITE);
 scene.addEventHandler(EventType.ROOT, this);

 player = new Rectangle(20, 20, Color.BLACK);

 root.getChildren().add(player);


 for (int i = 0; i < 15; i++) {
     MyCircle ball = new MyCircle(15, Color.RED);
     ball.setStrokeType(StrokeType.OUTSIDE);
     ball.setStroke(Color.DARKRED);
     ball.setStrokeWidth(4);
     ball.setCenterX(random.nextInt(APP_WIDTH - 15));
     ball.setCenterY(random.nextInt(APP_HEIGHT - 15));

     if (random.nextInt(100) % 2 == 0) {
  ball.setVx(1);
     }
     if (random.nextInt(100) % 2 == 0) {
  ball.setVy(1);
     }
     balls.getChildren().add(ball);
     balls.setEffect(new BoxBlur(2, 2, 1));
 }

 root.getChildren().add(balls);
 startTime = System.currentTimeMillis();

 final Label time = new Label("Time :");
 time.setLayoutX(50);
 time.setLayoutY(20);
 time.setScaleX(2);
 time.setScaleY(2);
 time.setScaleZ(2);
 root.getChildren().add(time);

 timer = new AnimationTimer() {

     @Override
     public void handle(long l) {
  if (state == 1) {
      if (System.currentTimeMillis() > lastUpdate + 20) {
   lastUpdate = System.currentTimeMillis();
   time.setText("Time : " + (System.currentTimeMillis() - startTime) / 1000 + " s");
   for (Node ball : balls.getChildren()) {
       MyCircle AI = (MyCircle) ball;

       //bounce from walls
       if (AI.getCenterX() + AI.getVx() < 15) {
    AI.vx = -AI.vx;
       }
       if (AI.getCenterX() + AI.vx > APP_WIDTH - 15) {
    AI.vx = -AI.vx;
       }

       if (AI.getCenterY() + AI.vy < 15) {
    AI.vy = -AI.vy;
       }
       if (AI.getCenterY() + AI.vy > APP_HEIGHT - 15) {
    AI.vy = -AI.vy;
       }


       if (AI.getCenterX() >= mouseX && AI.getCenterX() <= mouseX + 10) {
    if (AI.getCenterY() + 15 >= mouseY - 10
     && AI.getCenterY() - 15 <= mouseY) {
        AI.vy = -AI.vy;
        state = 2;
    }
       } else if (AI.getCenterY() >= mouseY - 10
        && AI.getCenterY() <= mouseY) {
    if (AI.getCenterX() + 15 >= mouseX
     && AI.getCenterX() - 15 <= mouseX + 10) {
        AI.vx = -AI.vx;
        state = 2;

    }
       }
       //calculate new position
       AI.setCenterX(AI.getCenterX() + AI.vx);
       AI.setCenterY(AI.getCenterY() + AI.vy);

       //increase speed
       AI.vx = AI.vx * 1.002;
       AI.vy = AI.vy * 1.002;
   }
      }
  } else {
      this.stop();
      setGameoverScreen();
  }
     }
 };
 timer.start();

 primaryStage.setScene(scene);

 primaryStage.setVisible(true);

    }

    public void setGameoverScreen() {
 final Button restart = new Button();
 restart.setText("Restart");
 restart.setLayoutX(APP_WIDTH / 2);
 restart.setLayoutY(APP_HEIGHT / 2);
 restart.setScaleZ(4);
 restart.setScaleX(4);
 restart.setScaleY(4);
 root.getChildren().add(restart);

 restart.setOnAction(new EventHandler() {

     @Override
     public void handle(ActionEvent e) {
  for (Node ball : balls.getChildren()) {
      MyCircle buf = (MyCircle) ball;
      buf.setCenterX(random.nextInt(APP_WIDTH - 15));
      buf.setCenterY(random.nextInt(APP_HEIGHT - 15));

      if (random.nextInt(100) % 2 == 0) {
   buf.setVx(1);
      } else {
   buf.setVx(-1);
      }
      if (random.nextInt(100) % 2 == 0) {
   buf.setVy(1);
      } else {
   buf.setVy(-1);
      }
  }

  root.getChildren().remove(restart);
  state = 1;
  timer.start();
  startTime = System.currentTimeMillis();

     }
 });
    }

    public void handle(Event event) {
 if (event instanceof MouseEvent) {
     MouseEvent e = (MouseEvent) event;
     mouseX = e.getX();
     mouseY = e.getY();

     if (mouseX > APP_WIDTH - 20) {
  mouseX = APP_WIDTH - 20;
     }
     if (mouseY > APP_HEIGHT - 20) {
  mouseY = APP_HEIGHT - 20;
     }
     if (mouseX < 0) {
  mouseX = 1;
     }
     if (mouseY < 0) {
  mouseY = 1;
     }

     player.setX(mouseX);
     player.setY(mouseY);
 }
    }

    class MyCircle extends Circle {

 public double vy;
 public double vx;

 public MyCircle(double centerX, double centerY, double radius, Paint fill) {
     super(centerX, centerY, radius, fill);
     setVel();
 }

 public MyCircle(double centerX, double centerY, double radius) {
     super(centerX, centerY, radius);
     setVel();
 }

 public MyCircle() {
     setVel();
 }

 public MyCircle(double radius, Paint fill) {
     super(radius, fill);
     setVel();
 }

 public MyCircle(double radius) {
     super(radius);
     setVel();
 }

 public double getVx() {
     return vx;
 }

 public void setVx(int vx) {
     this.vx = vx;
 }

 public double getVy() {
     return vy;
 }

 public void setVy(int vy) {
     this.vy = vy;
 }

 private void setVel() {
     vx = -1;
     vy = -1;
 }
    }
}

Monday, June 27, 2011

MySQL Database network access

It’s not very difficult to configure your MySQL Database to listen to other machines in the network but it obviously leads to confusion sometimes. There are basically two options which allow your Database to listen to TCP/IP connections. They need to be done in the my.cnf file (usually located in /etc/mysql/my.cnf).
#SkipNetworking
bind-address 0.0.0.0
If you set bind-address to 0.0.0.0 your server will accept connections from any client. You can also specify a single client by replacing 0.0.0.0 by an address (for example 192.168.1.100). To disable external TCP/IP connections set bind-address to 127.0.0.1. The server will now only accept connections from the local host. If you uncomment SkipNetworking the server won't accept TCP/IP connections at all.

Thursday, June 16, 2011

Multimedia support for Scientific Linux 6, / RHEL 6

I just tried out Scientific Linux 6 on my home machine. Scientific Linux is a customized and unbranded Red Hat Enterprise Linux made by CERN and Fermilab. Therefore it's very stable and made to work. But even for working it's nice to play mp3 music oder view mpeg films.
To do so you have to enable the RPMForge repository by installing a package. Go to System => Administration => Add/Remove Software and install the package:

After this you can install the following packages for full multimedia support:
yum install ffmpeg libdvdcss libdvdread libdvdnav libdvdplay lsdvd mplayer gxine gstreamer-plugins-good gstreamer-plugins-bad-free-extras gstreamer-plugins-ugly libcdaudio w3m libx264 mjpegtools libsidplay libquicktime libkate automake autoconf jna gc libid3tag amrwb gstreamer-java-swt gstreamer-java gstreamer-ffmpeg gstreamer-vaapi

If you want to install vlc keep in mind that vlc doesn't work with libmodplug from epel repository. You have to add the follwoing line to your /etc/yum.repo.d/epe.repo and epel.testing.repo:
exclude=libmodplug

Tuesday, June 14, 2011

Find file duplicates using a bash script

This script is based on a script found in this blog. It searches recursively through the current directory and creates a script to remove all duplicate files. The script compares the md5 check sums of the files so it's able to compare binary files. It's a shell script therefore it will run on any machine with a bash shell (it might work with any other shell as well i didn't test it...).

#! /bin/sh
echo "scanning ..."
OUTF=rem-duplicates.sh;
echo "#! /bin/sh" > $OUTF;
echo "#"$OUTF >> $OUTF;
echo "" >> $OUTF;
find "$@" -type f -exec md5sum {} \; |
 sort --key=1,32 | uniq -w 32 -d --all-repeated=separate |
 sed -r 's/^[0-9a-f]*( )*//;s/([^a-zA-Z0-9./_-])/\\\1/g;s/(.+)/#rm \1/' >> $OUTF ;
chmod a+x $OUTF;
if [ -n "${EDITOR+x}" ];then
    $EDITOR $OUTF
else
    nano $OUTF
fi
echo "Do you want to execute the script? [y/n]?"
read answer
if [ $answer == "y" ]; then
    ./$OUTF
fi