W12:Labs:lab04

From 56wiki

Jump to: navigation, search

CS56—Advanced Applications Programming—W12

W12:Exams
 
W12:Homework
 
W12:Labs
 
W12:Calendar
and Lecture Notes
W12:Syllabus
 
W12:Choice
 
lab00 lab01 lab02 lab03 lab04 lab05 lab06 lab07 lab08
You may start!

Contents

[hide]

lab04: Open Source, JFrame, JWS, Simple Graphics,

Tip

If you find typos, note them on the discussion page. This lab is "locked down" for edits only by the instructor and the TA until after the due date has passed.


assigned due
Wed 02/09 Fri 02/17, 5pm STRICT
Strict, because of the code reviews.

Overview

This lab will build on the material we introduced about Ant and JUnit in lab01 and lab02

Previously we learned how to use an Ant build.xml file to:

  • generate and deploy Javadoc directly to a website
  • build a JAR file containing your classes and copy that to a website

We also learned about:

  • the practice of separating source files and the generated .class files.
  • how to run code from someone else's JAR file from your build.xml (invoking the Java Security Manager, if appropriate, to reduce the risk of malware attacks.)

In this lab, we'll add a step that allows us to

  • generate a "tarball" and/or "zip file" of your source and copy those to a website.
  • work with "packages" in our Java code and our build.xml file.
  • use a technology called Java Web Start, which allows you to launch a Java program directly from a website, but run it directly on the JVM of your PC, Mac or Linux system (not as an applet.)


In this lab we will also

  • see our first Java GUIs (a simple JFrame)
  • learn how to do simple, low-level awt-based graphics in that JFrame

Actually, while GUI stands for "Graphical User Interface", there won't actually be that much user interaction with our program this week. We'll learn more about user interaction (i.e. widgets such as buttons, menus, text fields, etc.) in future labs.

Step-by-Step

Step 1: Preliminaries

(1a) Create a ~/cs56/lab04 directory.

(1b) Copy the build.xml from your lab03 directory into your lab04 directory, and change the projectName property.

(1c) Create a ~/cs56/lab04/src directory

(1d) Copy the following file into your src directory:

http://www.cs.ucsb.edu/~pconrad/cs56/12W/labs/lab04/code/SimpleGui/SimpleGui1.java

You can copy these:

  • using a cp command from ~pconrad/public_html/cs56/12W/labs/lab04/code/SimpleGui/SimpleGui1.java
  • using a wget command on each file's URL
  • doing a "save as" from the web browser, if your web browser is running on CSIL

(For now, ignore the the other files/directories under ~pconrad/public_html/cs56/12W/labs/lab04/code—we won't need them until a later step.)

(1e) Create a ~/cs56/lab04/html directory. Copy the index.html from last weeks lab into this directory, and edit the file to reflect that this is lab04 (changing the names if needed).

(1f) Change the project property in the build.xml from lab03 to lab04, and make any other similar changes (e.g. to your name/date, etc.)

Step 2: Ant targets for distributing our source code

In lab02, we covered how to create a JAR file so that we can distribute a "binary" version of our running code as a single file (even if our software consists of multiple classes.)

In this lab, we want to take this one step further: we are going to distribute our source code as well.

Source is typically distributed in one of two ways:

  • as a tarball (an archive created with the Unix "tar" program, then compressed with the "gzip" compression scheme)
  • as a zip file (an archive compressed with the "zip" compression scheme.)

Typically, these are found by following a web page link labelled "download".

We'll add a few Ant targets that allow us to automatically create these files from our source, and publish them to the web, then we'll make our existing ant publish target invoke these targets (by making the publish target "depend" on them), and then we'll make the publish target copy these files to the web.


Step 2a: An ant target to create a zip file and a tarball

Here's an ant target called download that makes both a zip file and a tarball that contains our build.xml file and our src subdirectory.

This is a long target, but by now, if you've been actually reading (and not just mindlessly copying and pasting!) you should be able to read through this and get a sense of what is happening. That is an exercise worth doing, because in future labs, I'll ask you to work with Ant build.xml files with a lot less hand holding than you are getting this week.

Add this into your build.xml:

<target name="download" depends="">                                          

  <!-- delete everything under the "temp" and "download" subdirectories 
          In Ant, **/* means "all files under any number of directory levels" -->
                                                                                  
  <delete quiet="true">                                                           
     <fileset dir="temp" includes="**/*" />                                       
     <fileset dir="download" includes="**/*" />                                    
  </delete>                                                                       
                                                               
  <!-- create the directories we'll need to stage the zip file and tarballs -->
                   
  <mkdir dir="download" />                                                         
  <mkdir dir="temp" />                                                            
  <mkdir dir="temp/${projectName}" />                                             
                                                                                  
  <!-- copy everything from the current directory that we want to put in the zip file/tarball into the
          temp subdirectory.   Exclude things we do NOT want to include in the tarball/zip file -->

  <copy todir="temp/${projectName}">                                              
    <fileset dir="."                                                              
     excludes="build/**, javadoc/**, **/*~, temp/**, dist/**, download/**"/>       
  </copy>                                                                         
                                                                                  
  <!-- create the tar file from the temp directory -->

  <tar destfile="temp/${projectName}.tar"                                         
       basedir="temp"                                                             
       includes="${projectName}/**"                                               
   />                                                                             
  
 <!-- compress the tar file into a tarball (using "gzip") -->
                                                                                
  <gzip zipfile="download/${projectName}.tgz"                                      
        src="temp/${projectName}.tar" />                                          
 
 <!-- create a zip file -->
                                                 
 <zip destfile="download/${projectName}.zip"                                      
       basedir="temp"                                                             
       includes="${projectName}/**"                                               
  />                           

  <!-- Now we have the tarball and zip file in the download 
          subdirectory, so we are finished with the temp directory -->                                                   
                                                                                  
  <delete quiet="true">                                                           
     <fileset dir="temp" includes="**/*"/>                                        
  </delete>                                                                       
                                                                                  
 </target>     

Step 2b: Fix the clean target to get rid or download and temp directories

We should also add two lines into our clean target that get rid of the download and temp directories:

  <delete dir="download" quiet="true" />                                         
  <delete dir="temp" quiet="true" />      

Step 2c: Test our new ant download target

Now, to test, we run ant download and see what happens:

-bash-4.1$ ant download
Buildfile: build.xml

clean:

download:
    [mkdir] Created dir: /cs/faculty/pconrad/cs56/lab04/download
    [mkdir] Created dir: /cs/faculty/pconrad/cs56/lab04/temp
    [mkdir] Created dir: /cs/faculty/pconrad/cs56/lab04/temp/lab04
     [copy] Copying 4 files to /cs/faculty/pconrad/cs56/lab04/temp/lab04
      [tar] Building tar: /cs/faculty/pconrad/cs56/lab04/temp/lab04.tar
     [gzip] Building: /cs/faculty/pconrad/cs56/lab04/download/lab04.tgz
      [zip] Building zip: /cs/faculty/pconrad/cs56/lab04/download/lab04.zip

BUILD SUCCESSFUL
Total time: 0 seconds
-bash-4.1$ ls download/
lab04.tgz  lab04.zip
-bash-4.1$ 

As you can see, if we are successful, we now have two files called lab04.tgz (that's the tarball) and lab04.zip (that's the zip file.)

But do those files contain the right stuff? The next step allows us to check that.

Step 2d: Checking the zip file and tarball

To make sure that the .zip file and the tarball actually contain our source, we can try a little test, something like this.

  • go up a directory (cd .. )
  • create a directory called tryit and cd into it
  • copy all the files from ~/cs56/lab04/download into that new directory
  • try inflating the tarball to see if it contains what it is supposed to (tar -zxvf lab04.tgz)
  • remove the lab04 directory completely (rm -rf lab04) (MAKE SURE YOU ARE DELETING THE TEMPORARY ONE, NOT THE REAL ONE!)
  • try inflating the zip file to see if it contains what it is supposed to (unzip lab04.zip)
  • again, remove the lab04 directory that we just created (the temporary copy.)

Try these commands for yourself, but be very careful about the delete steps that you know what you are deleting! (Remember pwd and ls)

-bash-4.1$ cd ..
-bash-4.1$ ls
lab00 lab01  lab02  lab03 lab04
-bash-4.1$ mkdir tryit
-bash-4.1$ cd tryit
-bash-4.1$ cp ~/cs56/lab04/download/* .
-bash-4.1$ ls
lab04.tgz  lab04.zip
-bash-4.1$ tar -zxvf lab04.tgz 
lab04/
lab04/src/
lab04/build.xml
.
. (etc....)
.
-bash-4.1$ rm -rf lab04
-bash-4.1$ unzip lab04.zip 
Archive:  lab04.zip
   creating: lab04/
   creating: lab04/src/
  inflating: lab04/build.xml         
.
.
.
-bash-4.1$ cd ..
-bash-4.1$ ls
lab00 lab01 lab02 lab03 lab04  tryit
-bash-4.1$ rm -rf tryit
-bash-4.1$ 

Step 2e: Putting everything on the web

In lab02 and lab03, part of our ant publish target was the publishing of a web page with links to our jar file and javadoc.

We want to modify that in two ways:

  • add a link to that web page so that it also has a link at which we can browse the source
  • modify the build.xml file so that the tarball and zip file are copied into the download directory (along with the jar file.)

In the ~/cs56/lab04/html directory, you should already have an index.html file.

Modify it so that it has an additional link for browsing your source, as shown below:

<!DOCTYPE html>
<html>
 <head>
   <title>cs56, w12, lab04, YOUR NAME(S) HERE</title>
 </head>
 <body>
   <h1>cs56, w12, lab04, YOUR NAME(S) HERE</h1>
   <ul>
     <li><a href="download">download</a></li>
     <li><a href="browse">browse</a></li>
     <li><a href="javadoc">javadoc</a></li>
   </ul>
 </body>
</html>

Then, modify your "ant publish" target so that we populate the javadoc, browse, and download directories.

(Note that to populate the javadoc directory, all that is necessary is to make this step depend on the javadoc target.)

<target name="publish" depends="jar,javadoc,download">                           
   <mkdir dir="${webRoot}/${projectName}" />                                      
                                                                                  
   <delete dir="${webRoot}/${projectName}/browse" />                              
   <mkdir dir="${webRoot}/${projectName}/browse" />                               
                                                                                  
   <delete dir="${webRoot}/${projectName}/download" />                            
   <mkdir dir="${webRoot}/${projectName}/download" />                             
                                                                                  
   <copy file="html/index.html" todir="${webRoot}/${projectName}"/>               
                                                                                  
   <copy todir="${webRoot}/${projectName}/download" >                             
     <fileset dir="download"/>                                                    
     <fileset dir="dist" />                                                       
   </copy>                                                                        
                                                                                  
   <copy file="build.xml" todir="${webRoot}/${projectName}/browse"/>              
                                                                                  
   <copy todir="${webRoot}/${projectName}/browse/src" >                           
     <fileset dir="src"/>                                                         
   </copy>                                                                        
                                                                                  
   <chmod dir="${webRoot}/${projectName}"                                         
          perm="755" type="both" includes="**/*"/>                                
                                                                                  
   <echo>Project published to ${webBaseUrl}/${projectName}</echo>                 
 </target>           

Try running "ant publish". If it works, you should be able to go to http://www.cs.ucsb.edu/~YOURUSERNAMEHERE/cs56/lab04 and see something like this (with your name and username in place of mine (note w12 instead of W11, lab04 instead of lab03):

File:W11_Labs_lab03_sampleWebpage.png

And, furthermore, if you click on the links, reasonable things should happen:

  • the download link allows you to see links where you can download the .tar.gz, the .zip or the .jar file
  • the javadoc link shows you the javadoc
  • the source link allows you to browse the source code and the build.xml file
    • (Keep in mind that when viewing a build.xml file in a browser, it may not look right unless you do a "view source" on it. That just comes with the territory when it comes to XML files on the web.)

If you got that to come up, you are ready to move on to the next step!


Step 3: build.xml changes (fork="true", a mainClass property)

cd to ~/cs56/lab04, and edit the build.xml file in the following ways:

(1) Adjust the names if you are working with a different pair partner (or switched between working alone and working in a pair)

(2) In your run target, change the java task inside the run target to add the attribute fork="true". This indicates that we are going to fork a new process to run the class in a new instance of the JVM. This is necessary when doing ant run for GUI code—otherwise, the program exits immediately and you never see the graphics pop up.

For example, if you have something like this:

 <java classname="MyClassName" classpath="build"  />                

change it to this:

 <java classname="MyClassName" classpath="build" fork="true" />                


(4) If you don't already have one, add a property near the top of the file like this one:

  <property name="mainClass" value="SimpleGui1" />


(5) In your run target, change the line that says something like:

 <java classname="MyClassName" classpath="build" fork="true" />                

to this:

 <java classname="${mainClass}" classpath="build" fork="true" />                

so that it uses the value of the mainClass property.

(6) Make a similar change to the jar task, so that the main class in the manifest is set properly, changing the hardcoded class name to a reference to the mainClass property value.

(I'm not spelling out how to do this in detail—you should be able to figure it out from the previous instructions. Note that you need to understand what writing ${mainClass} means, and figure out what part of the hardcoded part of the jar task needs to be changed. In the first instance of this course (Winter 2011), most students got this right, but a significant fraction did not, because they didn't really think through what they were doing. See if you do better than they did.)

Ok... now, some Java!


Step 4: Create a simple class that makes a JFrame

cd into your src directory, and take a look at the file SimpleGui1.java that you copied into your account back in step 1.



—the code comes from HFJ page 355 (On Campus Off Campus). It may be helpful to read pages 354 and 355 again (you previously read them for homework) to review what this code is doing.

Change your build.xml file so that SimpleGui1 is the main that is run when you type ant run.

import javax.swing.*;

/** SimpleGui1 comes from Head First Java 2nd Edition p. 355.
      It illustrates a simple GUI with a Button that doesn't do anything yet.

     @author Head First Java, 2nd Edition p. 355
     @author P. Conrad (who only typed it in and added the Javadoc comments)
     @version CS56, Winter 2012, UCSB
*/

public class SimpleGui1 {

    /** main method to fire up a JFrame on the screen  
          @param args not used
     */

    public static void main (String[] args) {
       JFrame frame = new JFrame() ;
       JButton button = new JButton("click me") ;
       frame. setDefaultCloseOperation(JFrame. EXIT_ON_CLOSE) ;
       frame. getContentPane() . add(button) ;
       frame. setSize(300,300) ;
       frame. setVisible(true) ;
    }
}

Compile and run this file. (You should be able to do this with ant run if you modified your build.xml file correctly.

There may be some lag, but what you hope to see is a window like the one below. (If you get an error about DISPLAY, see the tip right after the image below.)

Clicking the button won't do anything (except perhaps "flash" a little bit)—because, duh, we didn't write any code to tell it what to do. That comes later in the lab.

So, the only thing you can do is click the red X (what it looks like will be different on Windows, Mac or Linux) to close the window.

File:W11_Labs_lab06_SimpleGui1.png


Tip

NOTE: if you are not in CSIL (i.e. you are working from your PC or Mac), you might get the following error:

Exception in thread "main" java.awt.HeadlessException: 
No X11 DISPLAY variable was set, but this program performed an operation which requires it.

The way to fix depends on whether you are using Windows, Mac or Linux:

  • On Windows, you need to download some X11 Server software. The most popular one among UCSB students seems to be XMing used in combination with PuTTY. You can find some information on how to download and use XMing here: XMing
  • On Mac or Linux, you need to use the -Y command line option along with your ssh command, e.g.
    • GOOD: ssh -Y username@csil.cs.ucsb.edu
    • WON'T WORK FOR GRAPHICS: ssh username@csil.cs.ucsb.edu

In addition (and this is true for Windows, Mac and Linux) it is helpful to use one of the specific machines in CSIL rather than csil.cs.ucsb.edu—for example, instead of specifying csil.cs.ucsb.edu, specify marge.cs.ucsb.edu, or cartman.cs.ucsb.edu, etc. Pretty much any cartoon character you can think of. After you login, type who and see how many people are logged in. If its "lots", then choose another machine—if its just you and one other person, you are golden. A map of all the machines can be found here: CSIL:Map

If the GUI came up, you are ready for the next step.

Step 5: Setting up Java Web Start

Step 5a: Setting up the jws directory

Inside your lab04 directory, create a new directory called jws.

Into that directory, put the following files:

(1) SimpleGui1.jnlp

That file should contain the following. Be sure to change where it says "yourusername" in two different places to be actually YOUR username.

<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="0.2 1.0" codebase="http://www.cs.ucsb.edu/~yourusername/cs56/lab04/jws" href="SimpleGui1.jnlp">
 <information>
   <title>UCSB CS56 S11 lab04 *your name and pair partners name here* SimpleGui1</title>
   <vendor>UCSB CS56</vendor>
   <homepage href="." />
   <description>A simple GUI</description>
  <icon href="cs56.png" />
  <offline-allowed />
 </information>
 <resources>
  <j2se version="1.3+" />
  <jar href="lab04.jar" />
 </resources>
 <application-desc main-class="SimpleGui1"/>
</jnlp>

(2) cs56.png, an image that that you can simply copy from my directory, like this:

cp /cs/faculty/pconrad/public_html/cs56/images/cs56.png .

(3) index.html

NOTE:

  • This is a DIFFERENT index.html from the one you've edited before—this one is ~/cs56/lab04/jws/index.html
  • The other index.html is ~/cs56/lab04/html/index.html
  • You need both
<!DOCTYPE html>
<html>
<head>
 <title>JWS for lab04, *your name and partner's name here* for CS56, S11</title>
</head>
<body>
 <h1>JWS for lab04</h1>
 <p>*your name and partner's name here* for CS56, W11</p>
 <p>Start the <a href="SimpleGui1.jnlp">SimpleGui1</a>.</p>
</body>
</html>

(4) .htaccess, a hidden file that sets the MIME type for .jnlp files for the Apache web server.

This step is needed so that the web server puts the correct headers on the HTTP response that contains the .jnlp file, and so that in turn the web browser knows what to do with it (i.e. to fire up Java Web Start).

AddType application/x-java-jnlp-file .jnlp

So double check: under ~/cs56/lab04/jws, you should now have:

  • SimpleGui1.jnlp
  • index.html
  • cs56.png
  • .htaccess

You will need to use ls -al to see the .htaccess file; a normal ls command will not show it. That's because files that start with a . under Unix are "hidden files". The -al on the ls command indicates to show "all files, with a long listing".

Step 5b: Modifying build.xml for JWS

Now, modify your build.xml to add the jws step, like this:

(1) Add the following property definitions near the top, after the definitions of webRoot and webBaseUrl:

  <property name="jwsDest" value="${webRoot}/${projectName}/jws" /> 
  <property name="jwsURL" value="${webBaseUrl}/${projectName}/jws" /> 

(2) Double check that your projectName property is lab04 (you should have already done that in a previous step.)

(3) Put the following new target near the bottom of your build.xml

 <target name="jws" depends="compile,jar">

   <delete dir="${webRoot}/${projectName}/jws" />
   <mkdir dir="${webRoot}/${projectName}/jws" />

   <copy todir="${jwsDest}" file="dist/${projectName}.jar" />
   <copy todir="${jwsDest}" >
       <fileset dir="jws" includes="*.html"/>
       <fileset dir="jws" includes="*.jnlp"/>
       <fileset dir="jws" includes="*.png"/>
       <fileset dir="jws" includes=".htaccess"/>
   </copy>
   <echo>Java web start at ${jwsURL}</echo>
 </target>

(4) Modify the publish target so that it depends on the jws target by adding it to the depends attribute of the publish target open tag, like this:

  • Before: <target name="publish" depends="jar,javadoc,download">
  • After: <target name="publish" depends="jar,javadoc,download,jws">

(5) In your lab04/html, edit the index.html file to add one more line like this after the other similar <li> elements:

  <li><a href="jws">jws</a></li>

Step 5c: Testing JWS

Now you should be able to test this by doing the following:

(1) Go to the directory where your build.xml file is (i.e. ~/cs56/lab04). Then run:

  • ant jws
    • If there are any errors, fix what is wrong
  • ant publish
    • If there are any errors, fix what is wrong


(2) Navigate to the URL http://www.cs.ucsb.edu/~yourusername/cs56/lab04

There should be a link for jws. If there isn't, go back and read through the instructions to find what you skipped over.

If there is a jws link, click on it. It should take you to ANOTHER web page, the link:

http://www.cs.ucsb.edu/~yourusername/cs56/lab04/jws


(3) Now here, there should be a link for SimpleGui1.

Click on it.

Your browser should try to download and open the file with Java Web Start (or in CSIL, "Ice Tea Web Start", or something like that.)

If you are in CSIL or Cooper, then you'll need to do a couple of things to coax Java Web Start into opening the file. By default, it may want to open it with gedit instead of Java Web Start. Here's what to do:

First, as shown here, click on the pull down menu beside where it says "gedit", and select "Other".

jwsStep1.png

Then, as shown here, click on the pencil at upper left, then enter the full path for the Java Web Start utility in the little box: /usr/bin/javaws

jwsStep2.png


Eventually, you should see the simple GUI pop up. If not, you can try to debug that now, or you can come back to it later---there are more steps you can try below that don't depend on this working correctly.

If it isn't working, check all of the following are taken care of:

  • The directory that corresponds to the URL---does it contain a .jnlp file, a .jar file and a .htaccess file?
    • If not, there may be a problem in your build.xml jws target.
  • Look at the contents of the .jnlp file---are all the right values there?
    • Make sure you modified the URL and the package name correctly, as well as the name of the JAR file.

Tip

The XML syntax of the .jnlp file is very specific, and must be followed precisely. This is where a pair-partner is really helpful. Even if you are working alone, if you have trouble with this step, get a temporary pair-partner to help you look through your .jnlp file. It is OK for this assignment—encouraged even—to compare your .jnlp file, line by line, character by character, with that of someone else in the class if yours is not working properly. Do that first before asking the Instructor or TA for help.

You may also want to review Chapter 17 of your textbook, pages 596 (On Campus Off Campus) to 601. lab04

If the JWS comes up, then you are ready to move on to the next step.

Step 6: Moving your code into a package

Now, we are going to move the SimpleGui1 code into a package.

Tip

We can hope that you did your homework and read Chapter 17, so you understand why packages are important. But in case you've forgotten—packages help us prevent name conflicts.

Later in this lab, you'll be developing a class with methods that can draw an object using the Java 2D graphics routines. And in a later lab still, you'll be using one another's graphics routines, combining yours with those of other folks in the class, to create interesting pictures. At that point, there is the real potential for naming conflicts. So packaging will become very important to ensure that names don't conflict.

Initially, packages are a pain, because they result in huge directory trees that you are constantly having to cd your way around. However, we'll show you a few tricks to make it less painful.

Finally, the biggest reason to learn packages is that REAL WORLD CODE USES THEM. So its important to get used to them and how they work if you want to do REAL WORLD java development (e.g. at an internship or job.)

The package you are going to move your code into is:

edu.ucsb.cs56.W12.yourCSILusernamehere.lab04


To move your code into a package, do these steps:

(1) cd into the src subdirectory

(2) Create the directory path under your src directory. Fortunately, you can do this with one command. (The ${USER} will be automatically replaced by the shell with your username.)

mkdir -p edu/ucsb/cs56/W12/${USER}/lab04

(3) Move all your source code from the top of the src subdirectory down to the bottom with this command:

mv *.java edu/ucsb/cs56/W12/${USER}/lab04

(4) To make it easier to move around, define an environment variable called T like this. First, cd back up out of the src subdirectory (i.e. cd .. or cd ~/cs56/lab04.

Then use this command:

export T=`pwd`

Tip

Note the special quote marks—we call them "backticks". This symbol might be at the upper left hand corner of the keyboard, under the ~, or somewhere else. It is not the same as the quotation mark—it points the other way. The meaning of backticks is to take the output of a Unix command (e.g. the pwd command) and insert it at that point on the shell's command line.

What the command export T=`pwd` does is to define the environment variable T, give it the value of whatever your working directory (the output of pwd) happens to be at this very moment. Any time you want to go there, just type cd $T—in fact, try that now:

cd $T

Now, define B (for bottom) as the botton of the place where your source lives, like this:

export B=${T}/src/edu/ucsb/cs56/W12/${USER}/lab04

Now, whenever you want to move into that directory, you can just type cd $B. Try it now!

And, one more thing. You probably want to "hang out" in the directory at the top of your project, i.e. cd $T because that's the place you have to be when you type ant compile, etc.

But when you want to edit, you need to edit files that are down in the directory $B. No problem—hang out in $T, but to edit, use commands like:

emacs $B/SimpleGui1.java

or

 vim $B/SimpleGui1.java

That way, you don't have to type those long terrible path names that Java packages require you to use—the $T and $B variables are saving you from having to do that.

Tip

Note that you'll have to redefine $T and $B for each login session, and each separate terminal window (well, each separate shell, actually.) If you want them to stick around between logins, put the export command in one of your bash startup files.

Finally, another way to do this is just to have two Terminal windows open—one that stays in the $T directory, where you do all your ant commands, and another down in the $B directory where you do all your editing.

(5) Next, use emacs $B/SimpleGui1.java or vim $B/SimpleGui1.java to add this line of code as the very first line of your SimpleGui1.java file:

package edu.ucsb.cs56.W12.yourCSILusernamehere.lab04;


Note that you MUST actually type out your CSIL username in place of yourCSILusernamehere—the Java compiler, unlike Ant and the shell, does not recognize ${USER} as a valid construct. So it will be something like one of the following:

package edu.ucsb.cs56.W12.cdiaz.lab04;
package edu.ucsb.cs56.W12.jlopez.lab04;
package edu.ucsb.cs56.W12.johnchu.lab04;


Tip

There is nothing special about the choices of the letters T and B. I picked them because they are easy to type, and because T stands for Top and B stands for bottom. If you want to use R for root, and S for source, that's ok too---or pretty much any other letter or environment variable name you want. Don't use PATH, USER, or HOME though—those have special meaning. In general, before defining an environment variable, its good to type env at the shell prompt and see which ones are already in use—and use one that isn't already being used.

(6) Adjust your build.xml file for the new package stuff

cd $T and then edit build.xml

Adjust the test target as follows:

replace:

<include name="*Test.java"/>     

with

 <include name="**/*Test.java"/>     

The extra **/ means "look under all the subdirectories" recursively for files. Before, we only looked at the top level of the src tree.

(7) Still in build.xml: finally, everywhere that you have a classname, e.g. in the Ant tasks that run code, you need to change that class name to the fully qualified class name.

For example, instead of SimpleGui1 you now need something like:

edu.ucsb.cs56.W12.yourUserNameHere.lab04.SimpleGui1

(8) You also must make this change in your .jnlp files in order for Java Web Start to work properly. Find the place that the SimpleGui1 class is referred to, and change it to the full name:

edu.ucsb.cs56.W12.yourUserNameHere.lab04.SimpleGui1

Figuring that out is left as an exercise to you.

(9) Now, retest EVERYTHING and make sure that everything still works, including at least the following:

  • ant compile
  • ant javadoc
  • ant jws
  • ant publish

And check the generated web pages to make sure the Javadoc is there, and the JWS file still works.


Once you are satisfied that it does, you are ready to move on to the next step.

Step 7: Simple Drawings

Now cd to your lab04 src directory, and make a new directory for a different package. Here, we really, really do want pconrad hardcoded (not your own username.)

mkdir -p ~/cs56/lab04/src/edu/ucsb/cs56/W12/pconrad/lab04

Then cd into this directory. After you do, you may want to temporarily redefine B as this directory, since we'll be working in here for the next step.

export B=`pwd`

Copy some source files into this directory as follows:

 cp /cs/faculty/pconrad/public_html/cs56/12W/labs/lab04/code/SimpleDrawings/*.java .

Tip

Note: 12W in the web pages paths for the code you are copying from, but W12 in the package names and in the directory that's part of your src tree. Sorry for the inconsistency. Life is just like that sometimes.


Then, open up your build.xml and add a second property value after the definition of mainClass:

  <property name="mainClassPV" value="edu.ucsb.cs56.W12.pconrad.lab04.PictureViewer" />                   

and a second run target called runpv, like this:

 <target name="runpv" depends="compile">
     <java classname="${mainClassPV}" fork="true" classpath="build" />
 </target>         

Then, try ant runpv. You should see a JFrame like this one pop up:

File:W11_Labs_lab06_PictureViewer_init.png

Step 8: Fix the snowman

Your next task is to fix the snowman so he has a head. Go into the code for PictureComponent, and add code to draw a circle on top of the snowman's head.

Read the comment, and refer to the material in Chapter 12 of the textbook about using 2D graphics in Java (which you read for homework, right!?!)

When the snowman has a head, you are ready for the next step.

Look also at the code that draws the house, and figure out how it works. See if you can understand the code for drawing lines and circles, and based on that, decide on something YOU can draw with the 2D graphics primitives that Java provides.

Step 9: A more complicated set of drawing routines

Tip

The following "more complicated" routines were the subject of lecture on 02/09/2012, so if you missed that, you missed something important. Do the best you can to try to read through the code and figure out what is happening. You may want to review the sections in the textbook on inheritance and on implementing interfaces, even if you DID attend that lecture.

Now, copy some additional code into the ~/cs56/lab04/src/edu/ucsb/cs56/W12/pconrad/lab04 directory.

The code we are going to copy in comes from:

After you copy this code, we are going to take a look at a few of the files.

Start with this one:

http://www.cs.ucsb.edu/~pconrad/cs56/12W/labs/lab04/code/GeneralPathDrawings/House.java

This code illustrates how we can make a line drawing of a house that extends GeneralPathWrapper and implements Shape interface.

The reason that we want to be able to implement the Shape interface, is that doing so allows us to do arbitary transformations on the shapes we draw. Look for example at the code in the drawPicture1 method of:

http://www.cs.ucsb.edu/~pconrad/cs56/12W/labs/lab04/code/GeneralPathDrawings/AllMyPictures.java

Here we are using the House.java class to draw some houses, and also do some translation, scaling, and rotation.

Next, look at:

http://www.cs.ucsb.edu/~pconrad/cs56/12W/labs/lab04/code/GeneralPathDrawings/HouseWithWindows.java

This shows how we can use inheritance to build on a drawing we've already made, and just add something new to it.


Next look at:

http://www.cs.ucsb.edu/~pconrad/cs56/12W/labs/lab04/code/GeneralPathDrawings/CoffeeCup.java

This shows how we can start with a "hard coded" drawing, i.e. one that has absolute coordinates drawn on graph paper, and end up with a routine that will produce a drawing at any size, and at any location on the screen.

You can find uses of the CoffeeCup in the other methods of:

http://www.cs.ucsb.edu/~pconrad/cs56/12W/labs/lab04/code/GeneralPathDrawings/AllMyPictures.java

Once you've looked over this code a bit, you are ready for the next step... the most fun one of all.

Step 10: Decide on something that you can draw

Now, decide on something that you can draw with JUST lines, circles and ellipses. It may be something very simple: an ice-cream cone, a lollipop, a set of railroad tracks. Don't get too fancy—for now we want to keep it relatively simple. (Fancy will come later.)

Tip

IMPORTANT: Stick for the moment with just lines, and circles and one color per object.

For now NO FILLS, and no MULTIPLE colors per object. (Again, we WILL get to do all the fancy stuff, including FILLS---just not in THIS lab.)

We need to stick to line drawings for now, because we are going to use them as an example of working with interfaces and inheritance in Java. If you have multiple colors, or do anything beyond a simple connection of lines and circles, the inheritance/implement thing we are going to do isn't going to work, and you won't be able to use the techniques given here for translation/rotation/scaling of your objects.

In a later lab, we'll show how to use BufferedImage methods so that you translate, rotate and scale arbitrary graphics, but that's for a LATER LAB. :-)

One catch: what you draw must be different from what everyone else in the class is drawing. There is a Gauchospace forum where you can register what you want to draw: that's right here:

  https://gauchospace.ucsb.edu/courses/mod/forum/view.php?id=124017


A very important thing is that for whatever you draw, rather than drawing it in a hardcoded fashion, you should create a method to do the drawing—one that takes parameters for the location and size of the drawing, and that extends GeneralPathWrapper and implements Shape.

As an example, the code you copied has a hard-coded house, and a hard coded (almost finished) snowman.

So instead of a hard coded house like this:

      Rectangle house = new Rectangle(100, 200, 100, 100);
      g2.draw( house);

       // lroof and rroof are the left and right sides of the roof,
       Line2D.Double lroof = new Line2D.Double(100, 200, 150, 150);
       Line2D.Double rroof = new Line2D.Double(150,150, 200,200);
       
       g2.draw(lroof);
       g2.draw(rroof);

We'd like to see instead something like the code in the following file (compare the two).

http://www.cs.ucsb.edu/~pconrad/cs56/12W/labs/lab04/code/GeneralPathDrawings/House.java

So, you will end up creating two new classes. Create those in YOUR package:

edu.ucsb.cs56.12W.yourusernamehere.lab04

But before we do that, let's set up things so that you can test the code you copied in to the package

edu.ucsb.cs56.12W.pconrad.lab04

Step 11: build.xml adjustments for the PictureViewer classes

Now, we want to set things up so that:

  • JWS works for
    • edu.ucsb.cs56.W12.pconrad.lab04.PictureViewer
  • ant works for:
    • edu.ucsb.cs56.W12.pconrad.lab04.PictureViewer01
    • edu.ucsb.cs56.W12.pconrad.lab04.PictureViewer02
    • edu.ucsb.cs56.W12.pconrad.lab04.PictureViewer03


Step 11a: Setting up JWS for edu.ucsb.cs56.W12.pconrad.lab04.PictureViewer

The purpose of doing this is so that the TA can easily check that you put the head on the Snowman correctly just by clicking on your JWS web link.

This will be easier than before. We only have to do the following steps:

(1) Create a second .jnlp file in the same jws subdirectory that we created earlier. Just copy from SimpleGui1.jnlp to PictureViewer.jnlp.

Edit the contents, changing what needs to be changed.

  • On the jnlp open tag, the codebase stays the same, but the href needs to change to PictureViewer.jnlp
  • The title and description should change to something appropriate
  • The jar file can stay the same (lab04.jar)
  • The main-class attribute on the application-desc element has to change to edu.ucsb.cs56.W12.pconrad.lab04.PictureViewer

(2) Add a link in the lab06/jws/index.html file:

Before:

 <p>Start the <a href="SimpleGui1.jnlp">SimpleGui1</a>.</p>

After:

 <p>Start the <a href="SimpleGui1.jnlp">SimpleGui1</a>.</p>
 <p>Start the <a href="PictureViewer.jnlp">PictureViewer</a>.</p>

That should be all you need to do so that JWS works on the PictureViewer as well. Try it and make sure it works.

Step 11b: Making Ant work for PictureViewer1, 2, 3

The purpose of these is so that you can try running the example code, so that you can experiment with it before writing your own code.

Back in a previous step, you made these changes:

In your build.xml, you added a second property value after the definition of mainClass:

  <property name="mainClassPV" value="edu.ucsb.cs56.W12.pconrad.lab04.PictureViewer" />                   

and a second run target called runpv, like this:

 <target name="runpv" depends="compile">
     <java classname="${mainClassPV}" fork="true" classpath="build" />
 </target>         

Your job now is to add three more properties like this:

  <property name="mainClassPV1" value="edu.ucsb.cs56.W12.pconrad.lab04.PictureViewer01" />                   
  <property name="mainClassPV2" value="edu.ucsb.cs56.W12.pconrad.lab04.PictureViewer02" />                   
  <property name="mainClassPV3" value="edu.ucsb.cs56.W12.pconrad.lab04.PictureViewer03" />                   

And three more targets, runpv1, runpv2, and runpv3 that work just like runpv.

Then, try these targets and make sure they work:

  • ant runpv1
  • ant runpv2
  • ant runpv3

Step 12: Working with WritePictureToFile.java

One more thing we want to do before we launch into writing our own picture drawing code—we want to see if we can draw into an image file (e.g. a gif, png, or jpeg.)

Look at the code in WritePictureToFile.java.

Then, add a target called samplePic to the build.xml file that runs the WritePictureToFile program with the argument "samplePic", so it produces samplePic.png

This week I'm not going to spell out how to do this completely: I'm only going to give you some hints:

  • The target name is samplePic
  • The task you'll put inside is a java task, i.e. one that runs a program
  • You'll need to specify the classpath in a way similar to what you did in other places where you ran a Java task
  • You'll also need to specify a command line argument. If you look online (i.e. do a web search) for examples of command line arguments for the "java" task in Ant, you'll see how to do this. It ends up being another XML element that is nested inside the java task.

When you are done, you should be able to run "ant samplePic" and the file samplePic.png will be placed in your directory.

Step 13: Actually making your own drawing code

Now we are ready to actually start drawing something.

Step 13a: Getting Started: Setting up Source Files

Now, set B to the directory ~/cs56/lab04/src/edu/ucsb/cs56/W12/yournamehere/lab04, and cd into that directory.

cd ~/cs56/lab04/src/edu/ucsb/cs56/W12/yournamehere/lab04
export B=`pwd`

In that directory, create a java source file for the first object you are going to draw. You may want to copy either House.java or CoffeeCup.java as a model.

First, change the package line at the top to be:

package edu.ucsb.cs56.W12.yournamehere.lab04;

To get the code to compile, you will also need to have the following at the top of your file:

import edu.ucsb.cs56.W12.pconrad.lab04.GeneralPathWrapper;

And, if you use the Circle class, you'll also need:

import edu.ucsb.cs56.W12.pconrad.lab04.Circle;

There may be additional imports from edu.ucsb.cs56.W12.pconrad.lab04 that you will need—I'm leaving you to discover those on your own. That will be an valuable Java learning experience for you!

Edit the rest of the file as needed to draw your object.

To test your drawing, create a new files in the ~/cs56/lab04/src/edu/ucsb/cs56/W12/yournamehere/lab04 directory as follows:


  • AllMyOwnDrawings.java based on AllMyDrawings.java.
    • This one should have at least one method, drawPicture1, that draws your items at various sizes and locations, and shows translation, scaling, and rotation.
  • MyPictureViewer01.java, based on PictureViewer01.java.


  • MyPictureComponent01.java, based on PictureComponent01.java.
  • WriteMyPictureToFile.java based on WritePictureToFile.java. It should use

In each one, change the package name as needed, and add import statements as needed.

Step 13a: Compiling, Running

You'll be able to compile with ant compile, but to run your code, you'll need to add these targets to build.xml:

  • ant runmpv1— a target to run your MyPictureViewer01 class
  • ant mypic1— a target to run WriteMyPictureToFile with an argument of mypic, so that mypic.png is created

Step 13b: Putting mypic1.png file on the web automatically

The next step is to add a line to your html/index.html that will bring up this image on the web. That can be done like this (put this code right before the </body> close tag, for example:

<p>Here is an example of a picture I drew with my Java Code</p>
<p><img src="mypic1.png" alt="A Picture that I drew with Java" />

Now, that will not show the image unless the image is copied into the html directory when you run the publish target.

So to cause that to happen, modify your build.xml file in two additional ways:

  1. Make the publish target depend on the pic1 target so that WriteMyPictureToFile is always run first to produce the mypic1.png file
  2. Add code into the publish target so that in addition to copying the file index.html into the web destination file, you ALSO copy mypic1.png

When you can type ant publish and the result is that the picture you drew appears on the web page at the URL shown by the output of ant publish, you are ready for the next step.

Step 13c: Making both the picture and the code beautiful!

Now, just work on your code in the following places until your drawing is beautiful:

  • your two classes that extend GeneralPathWrapper and implement Shape to draw two interesting objects
  • your code in AllMyOwnDrawings, in the drawPicture1 method that demonstrates drawing the objects

To test, use

  • ant runmpv1 to see the image on the screen
  • ant publish (which should invoke ant mypic1 as a dependency) to see the image on the web.

Be sure that all the files you create have good Javadoc in them, and have beautiful code. This is the code that we are going to be using for the first round of code reviews. So you want to be sure that it really looks nice.

Include nice internal explanatory comments as well as the Javadoc comments, and choose nice variable names. Make your code clear and beautiful.

When your picture is beautiful, and your code is beautiful, you are ready to do your final check over, and then submit!


Step 14: checking over your code

Before you proceed further, check over the items in the rubric at the end of this lab file to ensure that you didn't leave anything out that would cause you to lose points!

  • It is best to do this in pair-programming fashion, with one partner reading the checklist, and the other checking the code.
  • Even if you "solo programmed" this lab, you may want to see if you can find someone in the lab that also solo programmed, and ask him/her to be a "rubric buddy" with whom you can take turns doing this checklist step.

Note that it is ok if you have stuff in your build.xml file that we aren't using this week such as the following items. Leave them in, because they'll be useful in future labs.

Do the "ant publish" step and make sure that your links work for the javadoc, jar file, zip file, tarball, browseable source, and jws.

Step 15: ant clean, then turnin

Note: Remember to do an ant clean before doing your turnin.

From the ~/cs56 directory, the turnin command is:

turnin lab04@cs56 lab04

Then, after you do the turnin, do the ant publish step one more time and check the web just to ensure everything is online and up-to-date.

Grading Rubric: Total Points: 300

Partial credit may be awarded for each step at the discretion of the TA/Instructor.

Mechanics

  • (5 pts) Executing the turnin step on a directory called lab04
  • (5 pts) Having a correct src tree in the submission with a correct package structure, with code under both src/edu/ucsb/cs56/W12/pconrad/lab04, and src/edu/ucsb/cs56/W12/yournamehere/lab04
  • (5 pts) No build subdirectory is present in the submission, because you did a clean first before submitting
  • (5 pts) There is a build.xml file in your submission
  • (5 pts) There is an html subdirectory that contains an index.html file, as well as a jws subdirectory that contains the four required items.

Two Classes that Draw Objects

  • (10 pts) Two classes to draw objects should be in the edu.ucsb.cs56.W12.yournamehere.lab04 package also:
  • (10 pts) The two classes that draw objects should each extend GeneralPathWrapper and implement Shape.
  • (50 pts) Each of them should have a constructor that initializes the encapsulated GeneralPath object so that it can be drawn.
  • (50 pts) The objects drawn should be recognizable as what they claim to be (i.e. a skateboard should look like a skateboard.)

Support Classes

These files should be in the edu.ucsb.cs56.W12.yournamehere.lab04 package also, and should do their jobs properly

  • (10 pts) AllMyOwnDrawings.java
  • (10 pts) MyPictureViewer01.java
  • (10 pts) MyPictureComponent01.java
  • (10 pts) WriteMyPictureToFile.java


Build.xml

To get full credit for any item in this list, the item must be present, AND must do its job correctly.

  • (30 pts) build.xml file has all elements required in instructions

Web page and JWS

  • (35 pts) Web page and JWS have all elements required in instructions.

General Good Practices

  • (30 pts) Following Instructions
    • If there is anything that you should have done that was in the instructions but isn't already covered elsewhere in the grading rubric, these points are the ones that are "at risk" for those items.
    • Late submissions ALWAYS lose all of these points--and are subject to receiving a zero if the TA has already finished grading the assignment before the submission is received. TO ENSURE THAT YOU GET CREDIT, SUBMIT BEFORE THE DEADLINE.
  • (20 pts) Coding Style
    • By this point in your programming career, you should know about things like using good variable names, indenting properly, factoring out common code into a subroutine, etc. Anything that is an obvious defect in your code is something that TAs have discretion to deduct points for, up to the amount specified for this item.

Due Date

You should do your best to complete this within the assigned lab time during week 5 of the quarter.

If that is not possible, then you should complete the assignment and execute the turnin command no later than 5pm Friday of week 4 of this quarter. This gives you one full week to seek help during office hours from both the instructor and the TAs, plus one additional lab period to ask the TAs for additional help.

Submissions turned in after that time are subject to receiving zero credit.

Personal tools