Back
HelloPsychophysicist - Pure Java version
This section explains line by line the pure java version of the
HelloPsychophysicist project (source:
HelloPsychophysicist.java). This example
demonstrates how to develop java projects using psychWithJava
package in general.
There are seven common steps to writing a java program using the
psychWithJava package
-
Import the necessary classes/packages
First place import lines in the beginning of your Java code,
including the necessary classes from psychWithJava package.
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import psychWithJava.FullScreen;
Alternatively you can import all classes from a package, for example
After importing classes you will no more have to explicitly type the full
path of these classes in your code.
Declare a public class that inherits from
FullScreen and Runnable, and create a main method
The name of the public class must be the same as the first part
(the part before .java) of the file name
public class HelloPsychophysicist extends FullScreen implements Runnable {
public static void main(String[] args) {
To execute a Java file, you must have a main method in the public class.
The syntax of the main method is important, it has to be exactly as shown
above.
extends and implements keywords are used for inheritance.
This syntax means that HelloPsychophysicist is a class that
inherits from another
class called FullScreen. FullScreen, the most important class of the
psychWithJava package, provides
many of the methods needed for the Psychophysics experiments.
By inheriting from that class HelloPsychophysicist
becomes a FullScreen
class and more. That is, it has all the methods of FullScreen
available. HelloPsychophysicist also inherits from an interface
(a sort of class with no method definitions) called Runnable. We do
this because a new Thread can be created by using a Runnable object.
Threads are useful because multiple of them can run concurrently by the
CPU, and we will take advantage of this fact in many of our
examples.
-
Create an instance of the HelloPsychophysicist class
In the main method, create a HelloPsychophysicist object fs as follows
HelloPsychophysicist fs = new HelloPsychophysicist();
Recall that HelloPsychophysicist is FullScreen, therefore constructing
a HelloPsychophysicist is nearly equivalent to constructing a FullScreen
object. See also FullScreen().
-
Initialize certain aspects of your object
There are a few adjustments you can make for your FullScreen object.
For example, here let's set the number of video buffers to 2, which
by default is 1
If double buffering doesn't work on your system, try using single
buffer (setNBuffers(1) ).
See also setNBuffers(int).
Create a new Thread with your object
and start it
Thread experiment = new Thread(fs);
experiment.start();
You can construct a Thread with
a Runnable object. Remember that HelloPsychophysicist is a
Runnable object, as
well as a FullScreen object.
Provide the run() method
A class that implements Runnable
interface must have a public method called run(). This method is
automatically invoked when you start your Thread.
the method should be declared exactly as above.
-
Place the experiment/animation inside run(),
use try-catch-finally
public void run(){
try{
\\your methods for animation
} catch(){
\\catch the exceptions, that is, if something goes wrong
} finally {
\\in the end clean up and return the resources used
closeScreen();
}
The program will try to perform the statements inside the
try{} part, if anything goes wrong, the execution jumps
to the catch{} part. If nothing goes wrong the
try{} part is completed and catch{} is skipped.
In either case the finally{} part is always executed.
You must always invoke closeScreen() method inside finally{}.
Above 7 steps are going to be nearly identical in all examples, except
the names of files and corresponding public classes. If you use
an IDE, such as Eclipse, it will assist you with most of the steps.
For instance you won't need to remember which classes to import. IDEs
usually determine your import needs and place them in the beginning
of your file. They will also warn you that you should have a public
method called run() since your class inherits from Runnable interface.
They will assist for catching the Exceptions, as well.
The experiment/animation, inside the run() method
This is the part that will vary depending on your experiment.
I explain the run() method of the HelloPsychophysicist class below.
- Display text, wait for a while
Display some text, draw it actually on the screen and wait for
2 seconds without doing anything
try{
displayText("Hello Psychophysicist (pure Java)");
updateScreen();
Thread.sleep(2000);
displayText(String) method displays the text stored in a String
object at the center of the video buffer. It is overloaded, you can
define the position where you want to place the upper left
corner of the text on your screen by invoking
displayText(int,int,String).
Next you have to invoke
updateScreen() method. Because although you invoked
displayText()
method, you only painted the text on a back video buffer. To actually
display on the computer screen this back buffer should be brought to
front by updateScreen().
sleep(long) is a static method of Thread class. It causes the
thread stop execution for the given amount of time (in milliseconds).
This method throws an InterruptedException,
which means that something may go wrong. You have to take care of
this, that is,
you have to catch that exception and preferably do something
catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
this will clear the interrupted status of the thread.
In principle, you could just
catch the exception and don't do anything, but it is not
a proper way of handling exceptions and should not be
done.
Instead invoke the interrupt() method to clear the interrupted
status.
- Blank the screen, hide the cursor
blankScreen();
hideCursor();
If you don't blank the screen (back buffer), you will paint over
the existing screen. This is useful for animations when you
want to update only a portion of the screen. But in this example
we need to clean it first. (try and see what happens if you don't
do that.)
See
blankScreen()
and hideCursor()
- Read in and display an image
BufferedImage bi1 = ImageIO.read(
HelloPsychophysicist.class.getResource("psychophysik.png"));
displayImage(bi1);
updateScreen();
There are many ways of reading an image from a file. The way
shown above is useful because it works when you package your
applications in a single jar file. If you don't have to prepare
jar files then you can use the following simpler version
BufferedImage bi1 = ImageIO.read(new File("psychophysik.png"));
Currently Java Core API can
read png, jpeg and gif image types. But you can find/implement
non-standard classes that extend this capability. ImageIO.read()
method throws an IOException, you have to catch it and decide what
to do
catch (IOException e) {
System.err.println("Image File not found");
e.printStackTrace();
}
this will only warn the client but not prevent the termination
of the program.
displayImage(BufferedImage) method displays an image at the center
of the screen. As before, you should invoke updateScreen() method
to actually bring the back buffer front.
displayImage() is overloaded
displays the image at the upper left corner.
See the entire code of HelloPsychophysicist.java
Back
|