You will find out what are the differences between using this library in C or C++.
In the first tutorial the only thing the user could do was resizing and closing the window. In this tutorial we will see how the user could interact a little bit more with your application by using the Turtle Graphic.
We will create a Frame an draw two squares on it. When the user clicks on the Frame, we will check, if he clicked into a square and display a message.
In this tutorial we will have to initialize the Java Virtual Machine and the Frame by our self. In Tutorial 1: Simple Turtle this was done by the Simple Turtle library for us.
For the user interaction we need to get informed about the events the user causes. Therefore we will register callback functions to get informed about these events.
We have to program the following for this example:
To initialize the JVM you need a Jvm structure and the path of the "grubc.jar" file:
For the callback functions you need normal functions which will be registered as listeners:
... void mouseListener(jint event, jobject source, jint x, jint y, jint button, jint clickCount) { if (event == CB_MOUSE_CLICKED) { do something } } ... Frame frame; jobject ml; ... ml = frame.addMouseListener(&mouseListener); ... frame.removeMouseListener(ml); ...
Now you should know everything you need. The other functions you need can be found in the documentation.
#include "grubc/turtle/turtlegraphic.h" /* Define the position, side length and color of square 1. */ #define S1_X_POS 100 #define S1_Y_POS 100 #define S1_LENGTH 100 #define S1_COLOR BLUE /* Define the position, side length and color of square 2. */ #define S2_X_POS 300 #define S2_Y_POS 100 #define S2_LENGTH 100 #define S2_COLOR RED /* Declare the needed variables. */ Jvm jvm; Frame frame; TurtleGraphic tg; jboolean exitprg = JNI_FALSE; /* Declare the needed listener callback functions. */ void windowListener(jint event, Window window); void mouseListener(jint event, Component source, jint x, jint y, jint button, jint clickCount); /* Declare additional functions. */ void drawSquares(); void drawSquare(jfloat x, jfloat y, jfloat length, Color c); int main(int argc, char *argv[]) { WindowListener wl; /* WindowListener Object. */ MouseListener ml; /* MouseListener Object. */ initJvm(&jvm, "./grubc.jar"); /* Initialize the JVM. */ createFrame(&frame); /* Create the frame. */ /* Register the callback functions as listeners. */ wl = frame.addWindowListener(&frame, &windowListener); ml = frame.addMouseListener(&frame, &mouseListener); /* Create the Turtle Graphic by passing the frame to draw on. */ createTurtleGraphic(&tg, &frame); /* Set the title, size and location of the frame. */ frame.setTitle(&frame, "Tutorial 2"); frame.setLocation(&frame, 100, 100); frame.setSize(&frame, 500, 300); frame.show(&frame); /* Display the frame. */ drawSquares(); /* Draw the squares. */ /* Wait until exitprg is true. */ WAIT_UNTIL_TRUE(exitprg); frame.close(&frame); /* Close the frame. */ /* Deregister the callback functions. */ frame.removeWindowListener(&frame, wl); frame.removeMouseListener(&frame, ml); /* Cleanup */ deleteTurtleGraphic(&tg); deleteFrame(&frame); return 0; } void drawSquares() { drawSquare(S1_X_POS, S1_Y_POS, S1_LENGTH, S1_COLOR); drawSquare(S2_X_POS, S2_Y_POS, S2_LENGTH, S2_COLOR); } void drawSquare(jfloat x, jfloat y, jfloat length, Color c) { int i; tg.setDraw(&tg, JNI_FALSE); /* Disable drawing. */ tg.moveTo(&tg, x, y); /* Move to start point. */ tg.setColor(&tg, c); /* Set the color. */ tg.setDraw(&tg, JNI_TRUE); /* Enable drawing. */ for (i = 0; i <= 3; i++) { /* Draw the suqare. */ tg.forward(&tg, length); tg.right(&tg, 90); } } void windowListener(jint event, Window window) { if (frame.isSameWindow(&frame, window)) { switch (event) { case CB_WINDOW_OPENED: break; case CB_WINDOW_CLOSING: exitprg = JNI_TRUE; /* Frame should be closed. */ break; case CB_WINDOW_CLOSED: break; case CB_WINDOW_ICONIFIED: break; case CB_WINDOW_DEICONIFIED: break; case CB_WINDOW_ACTIVATED: break; case CB_WINDOW_DEACTIVATED: break; } } } void mouseListener(jint event, Component source, jint x, jint y, jint button, jint clickCount) { switch (event) { case CB_MOUSE_CLICKED: tg.clearScreen(&tg); /* Clear the frame. */ tg.setDraw(&tg, JNI_FALSE); tg.setColor(&tg, BLACK); /* Set the color. */ tg.moveTo(&tg, 50, 250); /* Move to the position to write the text. */ /* Clicked into a square??? */ if (x >= S1_X_POS && x <= S1_X_POS + S1_LENGTH && y >= S1_Y_POS && y <= S1_Y_POS + S1_LENGTH) { tg.printText(&tg, "You clicked into square 1!"); } else if (x >= S2_X_POS && x <= S2_X_POS + S2_LENGTH && y >= S2_Y_POS && y <= S2_Y_POS + S2_LENGTH) { tg.printText(&tg, "You clicked into square 2!"); } tg.setDraw(&tg, JNI_TRUE); drawSquares(); /* Draw the squares. */ break; case CB_MOUSE_PRESSED: break; case CB_MOUSE_RELEASED: break; case CB_MOUSE_ENTERED: break; case CB_MOUSE_EXITED: break; } }
#include "grubc/turtle/turtlegraphic.h" /* Define the position, side length and color of square 1. */ #define S1_X_POS 100 #define S1_Y_POS 100 #define S1_LENGTH 100 #define S1_COLOR BLUE /* Define the position, side length and color of square 2. */ #define S2_X_POS 300 #define S2_Y_POS 100 #define S2_LENGTH 100 #define S2_COLOR RED /* Declare the needed variables. */ Jvm jvm; Frame frame; TurtleGraphic tg; jboolean exitprg = JNI_FALSE; /* Declare the needed listener callback functions. */ void windowListener(jint event, Window window); void mouseListener(jint event, Component source, jint x, jint y, jint button, jint clickCount); /* Declare additional functions. */ void drawSquares(); void drawSquare(jfloat x, jfloat y, jfloat length, Color c); int main(int argc, char *argv[]) { WindowListener wl; /* WindowListener Object. */ MouseListener ml; /* MouseListener Object. */ initJvm(&jvm, "./grubc.jar"); /* Initialize the JVM. */ createFrame(&frame); /* Create the frame. */ /* Register the callback functions as listeners. */ wl = frame.addWindowListener(&windowListener); ml = frame.addMouseListener(&mouseListener); /* Create the Turtle Graphic by passing the frame to draw on. */ createTurtleGraphic(&tg, &frame); /* Set the title, size and location of the frame. */ frame.setTitle("Tutorial 2"); frame.setLocation(100, 100); frame.setSize(500, 300); frame.show(); /* Display the frame. */ drawSquares(); /* Draw the squares. */ /* Wait until exitprg is true. */ WAIT_UNTIL_TRUE(exitprg); frame.close(); /* Close the frame. */ /* Deregister the callback functions. */ frame.removeWindowListener(wl); frame.removeMouseListener(ml); /* Cleanup */ deleteTurtleGraphic(&tg); deleteFrame(&frame); return 0; } void drawSquares() { drawSquare(S1_X_POS, S1_Y_POS, S1_LENGTH, S1_COLOR); drawSquare(S2_X_POS, S2_Y_POS, S2_LENGTH, S2_COLOR); } void drawSquare(jfloat x, jfloat y, jfloat length, Color c) { tg.setDraw(JNI_FALSE); /* Disable drawing. */ tg.moveTo(x, y); /* Move to start point. */ tg.setColor(c); /* Set the color. */ tg.setDraw(JNI_TRUE); /* Enable drawing. */ for (int i = 0; i <= 3; i++) { /* Draw the suqare. */ tg.forward(length); tg.right(90); } } void windowListener(jint event, Window window) { if (frame.isSameWindow(window)) { switch (event) { case CB_WINDOW_OPENED: break; case CB_WINDOW_CLOSING: exitprg = JNI_TRUE; /* Frame should be closed. */ break; case CB_WINDOW_CLOSED: break; case CB_WINDOW_ICONIFIED: break; case CB_WINDOW_DEICONIFIED: break; case CB_WINDOW_ACTIVATED: break; case CB_WINDOW_DEACTIVATED: break; } } } void mouseListener(jint event, Component source, jint x, jint y, jint button, jint clickCount) { switch (event) { case CB_MOUSE_CLICKED: tg.clearScreen(); /* Clear the frame. */ tg.setDraw(JNI_FALSE); tg.setColor(BLACK); /* Set the color. */ tg.moveTo(50, 250); /* Move to the position to write the text. */ /* Clicked into a square??? */ if (x >= S1_X_POS && x <= S1_X_POS + S1_LENGTH && y >= S1_Y_POS && y <= S1_Y_POS + S1_LENGTH) { tg.printText("You clicked into square 1!"); } else if (x >= S2_X_POS && x <= S2_X_POS + S2_LENGTH && y >= S2_Y_POS && y <= S2_Y_POS + S2_LENGTH) { tg.printText("You clicked into square 2!"); } tg.setDraw(JNI_TRUE); drawSquares(); /* Draw the squares. */ break; case CB_MOUSE_PRESSED: break; case CB_MOUSE_RELEASED: break; case CB_MOUSE_ENTERED: break; case CB_MOUSE_EXITED: break; } }
When you execute this program you will get a window which looks like this:
In C:
frame.setTitle(&frame, "Title");
In C++:
frame.setTitle("Title");
The functions you can register as callback functions must have a certain signature, depending on which events you are interested in. For example the functions you can register as window listeners must look like this:
void functionname(jint event, jobject window)
More information about listeners can be found here: listeners.c