Titol Java applet for the MPEG-7 annotation of rectangular regions

Document Sample
scope of work template
							Diego Cant                                        Java applet for the MPEG-7
                                                  annotation of rectangular
                                                  regions in still images




             Titol: “Java applet for the MPEG-7 annotation of rectangular

                  regions in still images”

             Alumne: Diego Cant

             Director: Xavier Giró i Nieto

             Department: EUETIT

             Data: Spring 2007
Table of Contents
 1 Introduction................................................................................................................................ 4
 2 Requirements ............................................................................................................................ 7
 3 State of the Art............................................................................................................................ 9
   3.1 Existing Annotation Tools and Formats.............................................................................. 9
      3.1.1 Introduction................................................................................................................. 9
           Metadata......................................................................................................................... 9
            a.1 What is metadata?................................................................................................. 9
            a.2 Use of metadata .................................................................................................. 10
         b XML........................................................................................................................... 11
            b.1 Introduction......................................................................................................... 11
      3.1.2 Mpeg-7...................................................................................................................... 12
         a Introduction................................................................................................................ 12
         b Overview of all MPEG-standards............................................................................... 12
         c Why MPEG-7............................................................................................................. 14
         d What is MPEG-7........................................................................................................ 15
      3.1.3 Existing Annotation Tools......................................................................................... 16
         a What is an Annotation Tool........................................................................................ 17
         b The Common Aim...................................................................................................... 17
         c Different Approaches to Image Annotation................................................................. 17
         d Examples.................................................................................................................... 19
            d.1 FOTOTAGGER................................................................................................. 19
            d.2 MUSCLE ANNOTATE..................................................................................... 20
            d.3 VIDEOTATER .................................................................................................. 22
            d.4 LABELME......................................................................................................... 23
   3.2 Java-Applets...................................................................................................................... 25
      3.2.1 What is a Java Applet................................................................................................ 25
      3.2.2 Advantages of Applets............................................................................................... 26
      3.2.3 Disadvantages of applets........................................................................................... 27
   3.3 Open Source Development using Eclipse and SVN........................................................... 28
      3.3.1 What is 'open source'?................................................................................................ 28
      3.3.2 What is SVN?........................................................................................................... 28
      3.3.3 SVN-Techniques....................................................................................................... 29
         a Lock-Modify-Unlock.................................................................................................. 29
         b Copy-Modify-Merge................................................................................................... 30
 4 Implementation ........................................................................................................................ 31
   4.1 Applet............................................................................................................................... 31
      4.1.1 Architecture............................................................................................................... 31
         a UML-SCHEME.......................................................................................................... 31
         b Description of Classes................................................................................................. 33
            b.1 Annotator.class.................................................................................................... 33
            b.2 FileSelector class................................................................................................. 33
            b.3 Textfile.class....................................................................................................... 34
      4.1.2 MPEG-7.................................................................................................................... 34
         a MPEG-7 Scheme........................................................................................................ 34
         b Created Classes........................................................................................................... 35
      4.1.3 Creation of Jar-file..................................................................................................... 36
         a Creation of a Jar-File.................................................................................................. 36

                                                                                                                              Page 2 of 87
     4.1.4 Applet Signature........................................................................................................ 37
        a Keytool....................................................................................................................... 38
        b Jarsigner..................................................................................................................... 39
     4.1.5 How to put an Applet Online?................................................................................... 39
        a HTML-Code............................................................................................................... 39
        b Comments................................................................................................................... 40
  4.2 Development..................................................................................................................... 40
     4.2.1 Creation and Configuration of an Eclipse project....................................................... 40
        a Create a New Project.................................................................................................. 40
        b Packages..................................................................................................................... 41
           b.1 Introduction......................................................................................................... 41
           b.2 Creation of a package in Eclipse......................................................................... 42
        c Creation of a New Class.............................................................................................. 43
        d Configure Classpath.................................................................................................... 44
     4.2.2 SVN Repository Access With SubEclipse.................................................................. 45
        a Installation of SubEclipse............................................................................................ 45
        b Configuring Eclipse to Connect with the repository.................................................... 46
5 Results...................................................................................................................................... 50
  5.1 Example of annotation, starting from Eclipse.................................................................... 50
        a Run the Project in Eclipse........................................................................................... 50
        b Select an Image from your hard drive......................................................................... 51
        c The Image Loads and Selection of a Rectangular Region............................................ 51
        d The 'send coordinates' button....................................................................................... 53
     5.1.2 Example of Annotation, starting in a Web Browser................................................... 55
6 Future Work............................................................................................................................. 56
7 Conclusion................................................................................................................................ 58




                                                                                                                               Page 3 of 87
1 Introduction



       The amount of multimedia documents have faced an exponential increase during the past ten

years, promoted by Internet and an-ever advancing technology. Today, everyone has a camera and

wants to publish pictures. It is however difficult to retrieve desired documents (image, audio, video and

so on) or contents.




       Nowadays, libraries and other organizations use annotations to index these contents. They put

metadata on a document which describes its contents with keywords. This allows retrieval programs to

work with simple queries, so they easily can search their databases. Existing software for indexing

these multimedia documents can be found on the internet, and a few of them are discussed in the “State

of the Art” chapter.




       The main goal of this Java applet is to save the coordinates of a rectangle in a MPEG-7-file; the

applet must be available on a web server so that the user can run it embedded in his/her web browser.

The MPEG-7-file is meant to be used in a future applications in order to detect objects in this

rectangular area of the image.




                                                                                            Page 4 of 87
        This thesis is organized as follows: “The State of the Art” starts with an introduction on MPEG-

7, followed by examples of existing image annotation tools which are found on the internet. In the end

we discuss applet technology in general, with a detailed description of the advantages and

disadvantages of the use of it.The “ Implementations” chapter first gives a detailed description on the

Java-applet itself (



architecture of the source code, MPEG-7-scheme, JAR-file,...). Then section on 'development' explains

the eclipse in general and its specific configuration in order to access the repository with Subversion.In

the next chapter (“Results”) we give a detailed example to explain the usage and the working of the

applet. Every step of the annotation of an image gets discussed in order to give the reader of this

document a complete view on the results of the project.




        “Java applet for the MPEG-7 annotation of rectangular regions in still images” is the title of this

diplome thesis written by Diego Cant and supervised by Xavier Giró i Nieto, professor of the “Signal

Theory and Communications Department (TSC)” of the Technical University of Catalonia (UPC).




                                                                                             Page 5 of 87
Chapter 2                                                                                   Requirements




2 Requirements

       The most important requirement was to create an annotation tool for still images, which can

capture the coordinates from a rectangular region in an image through the mouse. The applet had to

show the image on screen and mark the rectangular boundaries of the region through a click & drag

operation.




       The next demand was to develop it as a web-based Java applet usable from any platform

(GNU/Linux, MacOSX and Microsoft Windows) and browser (Firefox, Safari and Microsoft Internet

Explorer). As the applet had to access the local file system, it needed to be signed with a valid digital

signature provided by the TSC department. The applet has to be publicly available for demo from the

TSC department webserver in the Terrassa laboratori.




In a first stage, the coordinates had to be written in a text-file in the hard disk. User should be able to

browse through the local filesystem to select the desired path and filename.




       In a second stage, the output format had to be able to accessible to other programs or software

using the MPEG-7 textual-based format. This MPEG-7 gets saved in the same location as the text-file,

with the same name, but with an mp7 extension.


                                                                                             Page 6 of 87
Chapter 2                                                                              Requirements




       In order to be used by other software and developers, the final source code had to be publicly

available in the repository from the Càtedra de Programari Lliure de la UPC and released under a GPL

license. The same repository will provide a SVN version tracking system to allow a fluid

communication and testing between student and advisor.




                                                                                        Page 7 of 87
Chapter 3                                                                                State Of the Art




3 State of the Art

To understand how annotation tools work, we will first give an introduction on metadata and XML,

which is needed to be able to comprehend the next paragraph: MPEG-7. In the end of this chapter, I

discuss the most important and existing annotation tools at the current time.




3.1 Existing Annotation Tools and Formats

3.1.1 Introduction
   Metadata

    a.1      What is metadata?


           Metadata is data on data, in that metadata gives us information about a certain piece of data.

For example you receive the message:

   1. 037755506

   2. 133

   3. Perstraat

    ....

This message has absolutely no meaning if you have no knowledge of the format used to pass data. In


                                                                                            Page 8 of 87
Chapter 3                                                                                  State Of the Art

this example it was;

   1. telephone number

   2. street number

   3. street

    ....




    a.2      Use of metadata


           Metadata has many different applications, this section lists some of the most common ones.

Metadata is used to speed up and enrich searching for resources[WIK]. In general, search queries using

metadata can save users from performing more complex filter operations manually. It is now common

for web browsers (with the exception of Mozilla Firefox, P2P applications and media management

software) to automatically download and locally cache metadata, to improve the speed at which files

can be accessed and searched.




           Metadata provide additional information to users of the data it describes. This information may

be descriptive ("These pictures were taken by children in the school's third grade class.") or algorithmic

("Checksum=139F").




           Metadata helps to close the semantic-gap. It explains to the computer how data items are related

to each other and how these relations can be processed automatically, it makes it possible to process

even more complex filter and search operations. For example, if a search engine understands that

"ronaldo" was a "football player", it can respond to a search query on "Football Players" with a link to

                                                                                              Page 9 of 87
Chapter 3                                                                               State Of the Art

a web page about Ronaldo, even though the exact words "Football Player" never occur on that page.




          Certain metadata is developed to improve lossy compression algorithms. For example, if a

video has metadata that allows a computer to make difference between foreground and background,

the latter can be compressed more raw to achieve a higher compression rate.




          Some metadata is meant to enable variable content presentation. For example, if a picture has

metadata that indicates the most important region — the one where there is a person — an image

viewed on a small screen, such as on a mobile phone, can narrow the picture to that region and thus

show the user the most interesting details. This is, essentially , the goal of the annotation tool that I

made in this project: to pick out a certain part of an image, so that a next program can put the focus

onto this part.



   b   XML

    b.1     Introduction


          The extensible Markup Language, or XML, is a portable, human-readable format for

exchanging text or data between programs [XML2]. XML is derived from the parent standard SGML.

Also HTML, the language used on web pages worldwide, comes from SGML. IBM's GML (General

Markup Language) on his turn is the parent of SGML. Also, there is MIF (Maker Interchange Format)

from Adobe, also derived from GML, but different from SGML [XML1].




                                                                                          Page 10 of 87
Chapter 3                                                                               State Of the Art




                                     Figure 3.1 XML's Ancestors,[XML1]



       It can be said that XML is an improved version of HTML, consolidated, and that you can

define your own tags. In other words, XML is a general interchange format for things such as human-

editable description of things and is as diverse as word-processing files and Java documents.




3.1.2 Mpeg-7

   a   Introduction

       The value of information often depends on how easily it can be found, retrieved, accessed and

managed. In case of audiovisual archives, it is impossible to find a certain archive if everybody uses a

different metadata scheme. MPEG-7 delivers a solution, by describing multimedia content in a

standardized way, and thus enabling easier archiving, accessing, locating,....audiovisual information.

Later, a more detailed chapter on MPEG-7 follows. [MPOV]



   b   Overview of all MPEG-standards

       MPEG (Motion Picture Expert Group) is a working group of ISO/IEC since the end of the 80's.

The aim of MPEG is to develop international standards for compression, decompression and processing

of audio and video. They already developed several MPEG-standards [MP7W].




                                                                                          Page 11 of 87
Chapter 2                                                                               Requirements

       The MPEG-1 compression standard dates from 1992. It design was meant for digital storage of

videos up to about 1.5MBit/sec, which is approximately the quality as on TV. The goal was to allow

Video transmission on low bandwidth networks like telephone cables [MP7HP].




       MPEG-2 was a standard for digital television. MPEG-2 was released two years later then

MPEG-1, and enhances MPEG-1. Its aim is to become a standard for digital television with high data

rates, up to 80MBit/sec. The common known digital versatile disk (DVD) is a realization of MPEG-2.




       MPEG-4 was developed as a standard for Multimedia applications [MPWP]. It is a context

based approach for exchange, management and production of digital content. It does not define new

compression standards for video, but offers a toolbox of advanced compression algorithms for audio

and visual data. MPEG-4 has JavaScript as internal script language. It provides a Java interface layer

(MPEG-J layer) that allows the use of Java classes within MPEG-4 content, in order to communicate

with external programs like players.




       Finally, the MPEG-7-standard which is the most important for us.         It is also known as

“Multimedia Content Description Interface”. The aim of MPEG-7 is to describe a wide area of

Multimedia content:

   - Broadcast media selection. (radio channels, TV channels)

   - Multimedia directory services. (yellow pages)

   - Audiovisual databases can be organized and searched with MPEG-7

   - digital libraries to describe images, videos and song catalogs



                                                                                        Page 12 of 87
Chapter 2                                                                                  Requirements

   - ....




       It is able to describe still pictures, graphics, 3D models, audio, speech, video and their

combination [MP7HP]. Even content which is not audio or visual can be described, like taste or smell.

It is possible to use it independent of other MPEG standards, on an analogue movie,...




       There is a relation between MPEG-4 and MPEG-7 though. The way of representing data in

MPEG-4 can be seen as the basic process of categorizing and separating data which MPEG-7 uses.

MPEG-7 descriptions can improve the functionalities of the previous standards.




       At this moment, the MPEG-team works on MPEG-21, the Multimedia framework. It extends

the other MPEG standards with a Multimedia framework that allows transporting Multimedia content

over a wide range of networks and users.




   c   Why MPEG-7

       The latest 10 years, the amount of multimedia on the Internet has grown a lot. If you try to

imagine how many movies you can find on YouTube ( www.youtube.com ) for example, you should

get a proper idea of it. In the next years, users will be confronted with such a large number of contents

provided by multiple sources, that efficient and accurate access to this almost infinite amount of content

seems impossible today. However the fact that users have increasing access to these resources,

identifying and managing them efficiently is becoming more difficult, because of the huge volume.




                                                                                           Page 13 of 87
Chapter 2                                                                                 Requirements

       This is why MPEG-7 is developed. It offers a solution, however, more correct would be, it is an

improvement. MPEG-7 offers a set of audiovisual Description Tools, to create descriptions, which will

form the basis for applications enabling the needed effective and efficient access to multimedia content

[MPOV]. Although, it must be made clear that the requirements for the development of MPEG-7 are

derived from analyzing a wide range of potential applications that could use MPEG-7 tools.




       MPEG-7 is not aimed at any one application in particular, rather, the elements that MPEG-7

standardizes support as broad a range of applications as possible. For example, in this project, we use

MPEG-7 to parse the coordinates of a square in an image to another program.




   d   What is MPEG-7

       The three main elements[MPOV] of the MPEG-7 standard are: Description Tools, Description

Definition Language (DDL), and System tools.

       Description Tools, or Descriptors (D), define the syntax and the semantics of each feature

(metadata element), and Description Schemes (DS) specify the structure and semantics of the

relationships between their components.

       Description Definition Language defines the syntax of the MPEG-7 Description Tools, and

allows the creation of new Description Schemes and Descriptors. They also allow the extension and

modification of existing Description Schemes.

       System tools support binary coded representation for efficient storage and transmission,

transmission mechanisms, etc.




       In the figure on the next page, the general situation of the usage of MPEG-7 is represented.

                                                                                         Page 14 of 87
Chapter 2                                                                                  Requirements

The applet of this project does the Description generation. The program which will use the coordinates

does the Description Consumption.




                                      Figure 3.2 Scope of MPEG-7 [MPOV]




       The next figure summarizes the above paragraphs.             As you can see, left you have the

descriptors, collected in a sort of library. In the right group they use those descriptors, put them in a

structure among others, descriptors and descriptor schemes get mixed and represent a new Description

Scheme. Finally this gets instantiated in textual format (XML). Further in this paper is a detailed

example which explains all what is written above.




                                      Figure 3.3 MPEG-7 main elements [MPOV]




3.1.3 Existing Annotation Tools

   a   What is an Annotation Tool


                                                                                          Page 15 of 87
Chapter 2                                                                                 Requirements

        In general, annotation could be explained as “extra information with a particular point in a

document or other piece of information.” For example, when you add comments to source code, then

you annotate the source-code without affecting its functionality.




        In this subject, digital imaging, the term annotation is commonly used for visible meta-data

superimposed on an image without changing the underlying raster image. When you talk about

'Automatic Image Annotation', then the computer system automatically assigns meta-data in the form

of captioning or keywords to a digital image.



    b   The Common Aim

        For most image annotation tools, the goal is the ability to comprehensively describe content of

an image. This way, search engines can recognize in some way what is shown on the picture in order to

find the desired image. At the same time, human users should be also provided with complete

information about the image content so the could retrieve maximum knowledge of the image.




    c   Different Approaches to Image Annotation

        In this section a few different approaches get explained, but we don't go into detail with this.

The aim of this section is to show that there are more then one option in annotation, and to make clear

which one we chosen [ftggr].




•   Text Over Image: Clear identification can be provided by labeling an image with textual notes

    placed directly on an image.

         •   Merged annotation: Here you put the annotations on the picture itself, the disadvantage of



                                                                                          Page 16 of 87
Chapter 2                                                                                Requirements

            this is that the picture will contain the annotation permanently.

        •   Separated annotation: Here you save the meta-data in a separate file, meaning you retain

            the original picture without annotations in case of future needs. The annotations are just

            like another layer, on top of the picture. This also has some disadvantages, for example,

            transferability. The annotations will be only visible when you use a certain application,

            and if the meta-data file is present.

•

       The Text over Image annotation with separate file is the one we will use. In our case the text

will be the coordinates of the square we select. The separate file will be an MPEG-7-file, which

contains all the information. More about this will follow in a later chapter. In the two figures below,

we have two screenshots of these kinds of annotations. Figure 3.4 demonstrates merged annotation,

whilst Figure 3.5 demonstrates separated annotation.




                                                Figure 3.4 Merged Annotation




                                                                                         Page 17 of 87
Chapter 2                                                                                    Requirements




                                                  Figure 3.5 Separate Annotation


   d   Examples


    d.1     FOTOTAGGER



          Fototagger [ftggr] is a comprehensive example. It is used to put tags on pictures, for example to

point to people and highlight who they actually are. The next two pictures will give a clear idea.




                                        Figure 3.6 Annotated Picture in original state




                                                                                            Page 18 of 87
Chapter 2                                                                                 Requirements




                                      Figure 3.7 Annotated picture with XML-file loaded



The annotations are separate, as previously discussed. So there is an XML-file which contains the

information.




    d.2     MUSCLE ANNOTATE


          This is a pure experimental annotation tool, only developed for research[MSCL]. They use an

extension (an added segmentation section) of the XML annotation format which is used by the MIT

CSAIL database. This database is developed to test object classes which are used in object detection

algorithms. Also LABELME, which will be discussed in a later section, uses the MIT CSAIL

format. We will clarify with a detailed example found on:

http://muscle.prip.tuwien.ac.at/docs/metadata_spec.pdf.



                                                                                          Page 19 of 87
Chapter 2                                                                                    Requirements




                    Figure 3.8                                             Figure 3.9


1 <annotation>
2 <filename>dog.tif</filename>                         31 </pt>
3 <folder>images/MUSCLE_database</folder>              32 <pt>
4 <source>                                             33 <x>0</x>
5 <sourceImage>Photo from the WWW</sourceImage>        34 <y>30</y>
6 <sourceAnnotation>MUSCLE Annotate                    35 </pt>
v0.01</sourceAnnotation>                               36 <pt>
7 </source>                                            37 <x>280</x>
8 <keyword>                                            38 <y>30</y>
9 <name>dog</name>                                     39 </pt>
10 </keyword>                                          40 <pt>
11 <keyword>                                           41 <x>280</x>
12 <hname0>Botanic</hname0>                            42 <y>0</y>
13 <hname1>grass</hname1>                              43 </pt>
14 <deleted>0</deleted>                                44 </polygon>
15 <verified>1</verified>                              45 </object>
16 <date>20-Aug-2005 11:09:55</date>                   46 <segmentation>
17 <annotator>Dennis Bloodnock</annotator>             47 <filename>dog_seg.tif</filename>
18 </keyword>                                          ....
19 <object>                                            65 <label>1</label>
20 <keyword>                                           66 </object>
21 <name>grass</name>                                  67 <object>
22 </keyword>                                          68 <keyword>
23 <deleted>0</deleted>                                69 <hname0>Zoology</hname0>
24 <verified>0</verified>                              70 <hname1>dog</hname1>
25 <date>8-Aug-2005 12:03:25</date>                    71 </keyword>
26 <annotator>Fred Nurque</annotator>                  72 <label>2</label>
27 <polygon>                                           73 </object>
28 <pt>                                                81 </segmentation>
29 <x>0</x>                                            82 </annotation>
30 <y>0</y>

        Line 1 to 7 give details about the file that contains the image, and the source. Line 2 gives the

filename, line 3 gives the directory where the file is saved. The keywords are indicated between

<keyword>...</keyword> tags. There are two formats for these keywords, name and hnamex.

The first one gives a description of the image or polygon, for example in line 9. The second one is a

label chosen from a hierarchy, x=0 is the top level.

                                                                                             Page 20 of 87
Chapter 2                                                                                    Requirements




          There are three different types of structure with which the keywords can be associated:

The whole image: line 8 to 18

A polygon: line 19 to 45 (compatible with the MIT CSAIL database annotations)

A segmentation: line 46-82: If you look at line 67-73, you can see very clearly the structure which is

used. First <segmentation>, then <object> for each region with a specific greylevel, and final <label>

which refers to value of the greylevel of the object.

    d.3     VIDEOTATER


          Videotater[VDTT] is a program made for users who work with video segments for example to

create music clips. It allows to create well detailed tags to video segments in order to create a more

sophisticated indexing in movie databases.              To support the user, Videotater makes use of

understandable visualizations permits easy navigation, selection and tagging of video.




          The visualization's main elements are the Timeline and the Polyfocal Visualization[VDTT] .

The timeline contains two different views of the video. The segment view, which shows seperate

segments who are already delineated; and the lower half shows information about the average value of

the pixels in every row of each frame. This last feature gives the user the possibility to guess if there is

a potential new segment. The polyfocal view gives 5 frames before and after the “in-frame”(the first

frame of a segment) and the same with the “out-frame”(the last frame of that same segment).




                                                                                             Page 21 of 87
Chapter 2                                                                                                Requirements




                               Figure 3.10 “The Polyfocal view with the IN-and OUT-Frame” (a) and (b) point at the 5
                                         frames, ( c) points at the selected segment. [VDTT]




    d.4     LABELME


          LabelMe is another annotation tool, based on Javascript[LBLM]. The user can label objects in

a picture by surrounding it with dots to make a clear border around the object. The dots are connected

like a polygon. When the first spot is clicked again, a popup dialog appears in which you can put the

annotation you wish to make. The annotation is put into an XML-format and it is saved in a central

database, called the LabelMe server.




                                                                                                        Page 22 of 87
Chapter 2                                                                           Requirements




                                    Figure 3.11 “Example of car”[LBLM]



       In the above picture you can see the different object selections. Every surrounding has an

annotation, the next code shows how it becomes saved in an XML-file.




<annotation>
<filename>img_0355.JPG</filename>
<folder>oct6_static_outdoor</folder>
<source>
<sourceImage>The MIT-CSAIL database of objects and scenes</sourceImage>
<sourceAnnotation> The MIT-CSAIL database of objects and scenes</sourceAnnotation>
</source>
<scenedescription>street urban city outdoor</scenedescription>
<object>
<name>pot</name>


                                                                                   Page 23 of 87
Chapter 2                                                                              Requirements

<deleted>0</deleted>
<verified>1</verified>
<date>23-APR-2004 06:38:38</date>
<polygon>
<pt>
<x>1234</x>
<y>419</y>
</pt>
<pt>
<x>1230</x>
<y>435</y>

       As you can see, the XML-format is similar to the format we've discussed above in the

MUSCLE-annotation. For more details, I refer to the explanation given by the example in that section.

As you can see on line 5, the MIT-CSAIL database is also used in LABELME.




3.2 Java-Applets

3.2.1 What is a Java Applet

       A Java-applet extends the possibilities of a webpage, using the Java programming-language. At

the beginning, Java-applets were used to add complex graphical applications to webpages. In general,

Macromedia Flash took this over. Currently Java-applets are used for illustrating and demonstrating

scientific principals [WIK].




       The usage of Java-applets demands installation of Java Virtual Machine (JVM), because Java

needs a bytecode-interpreter. This is a disadvantage comparing to Macromedia Flash: starting up JVM

takes some time and once started it occupies memory in the computer. As long as the browser is open,

JVM is working and using memory [WIK].



                                                                                       Page 24 of 87
Chapter 2                                                                                   Requirements



3.2.2 Advantages of Applets

        This section contains a list of the advantages of using applets [WIK]. The advantages which

were important for this project, get discussed in detail:

    •   Unless the applet requires a later version of the JRE, it can run on all installed Java versions at

        the same time.

    •   It works on different platforms like Linux, Windows,...

    •   The sandbox method makes the code trusted...at least as long as you run it local in

        AppletViewer, when you run it in a web browser, you need to sign a JAR-file.

    •   Most web browsers support it (Mozilla Firefox, Internet Explorer,...)

    •   it can have full access to the machine it is running on if the user agrees

    •   it can improve with use: after a first applet is run, the JVM is already running and starts

        quickly, benefiting regular users of Java

    •   it can be a real time application




        The advantages of Java-applets deployed on a website, is that it is often easier to locate for the

user. Especially for applications that aren't used every day, for example demo-versions: this annotation

tool. It is easier for a programmer to update only a single application on the web, then having to

reinstall it on several client desktops [JAV1].




        A Java Plug-in is an extension of the functionality of a web browser. It allows applets to be run

                                                                                            Page 25 of 87
Chapter 2                                                                                    Requirements

under Sun's Java 2 runtime environment (JRE).              Without Java Plug-in, only the Java runtime

environment installed in the web browser will be able to use [SUN]. When Sun's JRE is installed, it

will be accompanied with Java Plug-in. For this annotation tool this is convenient, because on

computers without the plug-in, and an old environment, the applet will not load.




3.2.3 Disadvantages of applets

Similar to the previous section, the following disadvantages can be found on wikipedia. In this section

we'll also discuss two of them more in detail, with which I encountered problems during programming.

   •        Java Virtual Machine must be running before start up

       •   On some web browsers, the installation of Java Plug-In is required

       •   HTML-based technologies are considered more efficient in designing a good GUI

       •   When untrusted, there is limited access to the user his hard disk or clip board

       •   applets may require a specific JRE.




           The annotation tool requires a specific JRE, thus it comes in handy to download the Java plug-

in. As previously discussed, this is memory consuming, and it is you see in the list, not default on all

web browsers. (In the 'Conclusion'-chapter there is more information about the problems and the

consequences which I have experienced.)




                                                                                             Page 26 of 87
Chapter 2                                                                              Requirements

        Also the security policy of Java applets is very strict. In fact, every applet is considered

untrusted by web browsers. This brings us to the next problem, we need to browse the file system, and

even write on the hard disk. Therefore, we had to sign the JAR-file. This is an easy procedure, which

is explained in a later chapter.




3.3 Open Source Development using Eclipse and SVN



3.3.1 What is 'open source'?


        'Open source software' is source code which users can see, adjust, or use if when desired.

After the release of the source code of Netscape Navigator in 1998, it was Eric Raymond who was one

of the pioneers to use this term. [WIK]




3.3.2 What is SVN?


        Source control, or version control is one of the most important elements in open source

development. Cooperating developers use this software, in order to collaborate on code without the

necessity of unsophisticated file-sharing techniques. [SVN] Subversion is used for this project to

accomplish source control.




                                                                                       Page 27 of 87
Chapter 2                                                                                   Requirements

       Subversion uses a central repository to storage a tree of files which you want to check. It serves

as a kind of file server, but it keeps track of every change you made in your files and directories. Since

Subversion can work over networks, it made it possible to have different developers working in

parallel, to work on different computers, ... It provides the ability to make more progress, because

modifications don't have to occur through one single conduit anymore.




3.3.3 SVN-Techniques


       Suppose two people work together on the same file of a project. The first user starts working on

'version 1'. The second user comes in later and works on 'version 1' as well, but the first user already

made some changes: 'version 1a'. When the first person saves his 'version 1a' and five minutes later, the

second person saves his 'version 1b', he overwrites the changes of the first person. Even if they use

different names to save it, there still would be a problem: the changes of 'version 1a' are not in 'version

1b' and vice versa. There are two techniques who solve these problems as far as possible, Lock-

Modify-Unlock, and Copy-Modify-Merge.




   a   Lock-Modify-Unlock


       A file is exclusively dedicated to one certain developer, other developers can not edit the same

source code at the same time [SVN]. As soon as the developer is finished with editing, or adjusting, the

source code is released, and made available again for the other developers.




                                                                                            Page 28 of 87
Chapter 2                                                                              Requirements




   b   Copy-Modify-Merge


       The previous technique has a big disadvantage, only one person at a time can work at the same

file[SVN]. “Copy-Modify-Merge” solves this problem, but not automatically. When committing the

file back in the repository, SVN looks for mutual changes and highlights them for the user. It is the

user his task to decide which changes can proceed and which get cancelled.




                                                                                       Page 29 of 87
Chapter 4                                                                             Implementation




4 Implementation


4.1 Applet

4.1.1 Architecture
   a   UML-SCHEME


       A UML(Unified Modeling Language)-scheme is a graphical representation of object oriented

systems. It is used to design and to analyze them. It is able to describe static and dynamic systems by

putting all the information in a standardized way in different kind of diagrams. On the next page is a

class diagram of the source code.




                                                                                         Page 30 of 87
Chapter 4                            Implementation




            Figure 4.1“UML-Scheme”




                                       Page 31 of 87
Chapter 4                                                                                   Implementation




   b   Description of Classes


    b.1     Annotator.class




          The Annotator class contains the init() method. This is the method where everything begins, it

first initializes the interface. Using the FileSelector class, it loads an image to the object File. When

this is succeeded, init() instructs the paint() method to load the image in the object File to the screen.




          When the user draws a rectangle (our region), the processMovement gets the coordinates of the

opposite corners of this rectangle. Every time the mouse is pressed and it makes a movement of a pixel,

it instructs to repaint.

          The paint() method puts the image on the screen, and gets the coordinates of the rectangle from

processMovement() method and draws it over the picture with a transparent highlight effect.




          Finally, the actionPerformed() method writes away the coordinates to a text file and an

MPEG-7 file. It gets the desired filename and filelocation from the FileSelector class, and uses

toTextFile() and ToMpeg7File() to put the content in a format and write it to a file on the harddisk.

The ToMeg7File() method will get discussed in a later section.




    b.2     FileSelector class




                                                                                              Page 32 of 87
Chapter 4                                                                                Implementation

          For the interface of the FileSelector class SWING-components are used. The main reason to

do this is because it is less depending on the underlying platform. It is possible that it appears to be

slightly slower than AWT, but the difference is essentially be small enough to ignore.

    b.3     Textfile.class


          SEE APPENDIX: SOURCE CODE CONTAINS DETAILED DESCRIPTION




4.1.2 MPEG-7


   a   MPEG-7 Scheme


1 <?xml version="1.0" encoding="UTF-8"?>
2 <Mpeg7                                                 xmlns="urn:mpeg:mpeg7:schema:2001"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
3 <Description xsi:type="urn:ContentEntityType" xmlns:urn="urn:mpeg:mpeg7:schema:2001">
4    <MultimediaContent xsi:type="urn:ImageType">
5     <Image>
6      <SpatialLocator>
7       <Polygon>
8         <Coords urn:dim="4">196 151 250 222</Coords>
9       </Polygon>
10     </SpatialLocator>
11    </Image>
12 </MultimediaContent>
13 </Description>
1 </Mpeg7>

          On the first line the version of XML needs to be specified in order to work. The encoding type

is the default UTF-8, it specifies which character set is used to encode data in the XML-document

[XML2].




          Next, the XML Namespace gets declared: 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-

                                                                                           Page 33 of 87
Chapter 4                                                                            Implementation

instance" ' The Namespace relates an element or attribute with a specified URI, this way it allows to

have multiple elements with the same name within the same XML document, but they still have a

different semantic meaning.




       The following section goes further in detail in the scheme of above. It gives a detailed

description on every line in the scheme related to the source code.




   b   Created Classes


First, a new instance get created by Mpeg7Document and an Mpeg7 element gets added. This is

represented on line 2 of the example in the previous section. Then the description element gets added,

Complete Description, the following figure gives a clear overview. The type of the description

element gets changed to Content Description, then to Content Entity.




                                                                                        Page 34 of 87
Chapter 4                                                                         Implementation




                     Figure 4.2“Complete Description”-scheme [MP7]




       Now, a MultimediaContentType element [MP7] gets added to Content Entity and the type gets

changed into ImageType. Stillregion is a descriptor, used to subdivide the image into regions. The

data for those regions and visual descriptors are kept in this “stillregion”descriptor [UMMR]. The

“SpatialLocator” holds the coordinates of the rectangle. In the source code there is Arrays and

Matrices used. These belong to MPEG-7 specific extensions. [XSMPDL7]




4.1.3 Creation of Jar-file


  a   Creation of a Jar-File


                                                                                    Page 35 of 87
Chapter 4                                                                              Implementation




        A JAR-file is an archive file which contains class-files, and if wanted, other files (images,

sound,...), in a compressed format [JAV1]. To create a JAR-file, you use the jar-tool. This tool can be

found in the default jdk/bin directory.        The command used to create annotator.jar is jar cvf

Annotator.jar *.* within the directory were the project was saved. Between 'jar' and 'annotator.jar' you

see the options of the command line:

    •   c creates a new or empty archive and adds files to it;

    •   v generates a verbose output

    •   f specifies the JAR-filename as the second command-line argument

        There are two reasons to use JAR-files: the first is minimizing network-overhead, the second is

in case you need special permissions. The first was in this case not the most important, because we

only have a few class-files. The issue with the network-overhead is that when the web browser reads

the HTML-code, which says he has to use annotator.class, will make a connection with this class.

Then he resolves the other classes used in this class, and he makes each time additional connections

what demands a lot of time. Thanks to the JAR-file, only one request is needed, which saves some time

and network-traffic. You can compare it with transporting an amount of cargo with 1 truck instead of

10 cars. The second reason on the other hand, was a necessity, the next section 'signed jar-files' goes

further into detail.




4.1.4 Applet Signature


For example the file browser used in the applet needs permissions to access the local hard disk of the



                                                                                         Page 36 of 87
Chapter 4                                                                               Implementation

user. To achieve this, we need to sign the JAR-file. This lets us know two things:

    1. Where did the applet come from ?

    2. Was the code corrupted in transit ?

To do this, you need to obtain a certificate, which may be generated by a software like keytool.




   a   Keytool


        Keytool manages key stores (databases of certificates and private keys). [JAV2]It is a part of

the JDK. Every entry in the key store has an alias ( a name). As an example, a key pair with the alias

diego is created.

“keytool -genkey -keystore diego.store -alias diego”

As you can see on the next page, the program asks you some questions to give you a certain

identification.




                                                                                          Page 37 of 87
Chapter 4                                                                                Implementation




                                       Figure4.3 “create a keystore alias diego”




   b   Jarsigner


       Now we have to sign the JAR-file with our key. To do this, we use the next tool, jarsigner. It is

located in the /bin directory of your Java-environment. The command I've used is:

jarsigner -keystore diego.store annotator.jar diego

So the program uses the alias diego, from the keystore diego.store to sign the file annotator.jar.

Before he signs it, the program will ask for the password, and after this the procedure is completed.




4.1.5 How to put an Applet Online?
   a   HTML-Code

<html>
<body>

                                                                                           Page 38 of 87
Chapter 4                                                                                    Implementation

<APPLET                                       CODE=src.edu.upc.terrassatsc.Annotator.class
CODEBASE="http://terrassatsc.upc.edu/~diegocant/"
ARCHIVE="Sannotationtool.jar, xbean.jar, MPEG7-Ver1.jar, jsr173_1.0_api.jar"
width=860 height=560>
</APPLET>
</body>
</html>

   b   Comments


        To put an applet online, you have to tell the browser where the code is located, this is done by

declaring CODEBASE [JAV1]. Since the code is a package (see 4.2.1. a), we add the name of the

package to the APPLET CODE-name. In the ARCHIVE statement, first of all the main jar-file has to

be added. Because we use external libraries in our source code, they have to be included in the HTML-

code as well.




4.2 Development



4.2.1 Creation and Configuration of an Eclipse project


   a   Create a New Project


        The first step, to create a new project in Eclipse, is to click “File-->New-->Project” and select

the 'Java project' wizard. The chosen options are shown in the figure below, most important is the

environment “JRE 1.6.0”. Some of the older environments don't support everything in the sourcecode

we have used. 'Create seperate source and output folders' tells the compiler to save the *.class files in a

different directory, the /bin directory, while the source, or the *.Java files are saved in the /src directory.

Eclipse starts generating the project as soon the 'finish' button is pushed.

                                                                                                Page 39 of 87
Chapter 4                                                                                 Implementation




                                        Figure 4.4 “New Java Project”




   b   Packages


    b.1     Introduction


          In the project, we used the concept of Java 'packages', to have a better organization of classes.

In general, packages are used to separate classes that have the same name but different code or origin.

As you can see, the package used is named src.edu.upc.terrassatsc. The standard procedure is indeed


                                                                                            Page 40 of 87
Chapter 4                                                                                  Implementation

to use the organization's internet domain name(which is unique), written in reverse. Moreover, you

can go further in making subpackages, like edu.src.



          When a class belongs to a package, the name of the package is located at the top of your source

file, before the code that defines the classes in the package.

For example:             package src.edu.upc.terrassatsc;
                         import Java.applet.Applet;
                         import Java.awt.Button;
                         ......

In the Eclipse environment, if the package-statement is not in the source file, then it will belong to the

'default package'. It is necessary to put the files of the package in a subdirectory with the same name,

thus src\edu\upc\terrassatsc.

    b.2     Creation of a package in Eclipse


          In the menu, the user selects “File-->New-->Package” and types src.edu.upc.terrassatsc . The

first figure shows the window where you have to type, the second figure shows the result.




                                                                                             Page 41 of 87
Chapter 4                                                                            Implementation




                                     Figure 4.5 “New Java Package window”




                                     Figure 4.6“Result of Created Package”




  c   Creation of a New Class


       Similar to the previous paragraphs, a class gets created by clicking “File-->New-->Class”, with

figure “New Java Class window” as result. If you left-click on 'AnnotationTool' as in the figure

“Result of Created Package”, and select “New-->Class”, then you need to type the package name as

shown in the figure “New Java Class window” to put the new class in the correct package.


                                                                                        Page 42 of 87
Chapter 4                                                                                 Implementation




                                       Figure 4.7“New Java Class window”




   d   Configure Classpath


       Three external JAR-files are used as libraries, these files are a necessity because the contain

essential elements for the creation of the Mpeg-7 file. In this project, first a folder /lib was created in

the project-folder and the three libraries were imported in this /lib directory. Left-mouse-button click

on the /lib folder, select import-->File System, simply browse to the files and select them.

                                                                                            Page 43 of 87
Chapter 4                                                                             Implementation




       The instructions to configure the class path to these files: click with left-mouse-button on the

project folder, select build path--> configure build path, and click on the tab 'Libraries'. Now you

click 'Add JARs' browse to your /lib folder and select the JAR-files [ECL].




                                      Figure 4.8 “Configure Class Path window”




4.2.2 SVN Repository Access With SubEclipse
   a   Installation of SubEclipse


       The user selects “Help --> Software Updates --> find and install “, then a window appears



                                                                                        Page 44 of 87
Chapter 4                                                                                       Implementation

where    he    can    select    update     sites.        He      clicks      'New   Remote   Site'    and    types

“http://subclipse.tigris.org/update_1.0.X” to download SubEclipse. The website comes in the list with

the other update-sites, the user now has to select the site he just added and click 'finish'. After

installation, the user has to restart Eclipse.




                                         Figure 4.9“enter the update-site”


   b    Configuring Eclipse to Connect with the repository


Click “Window-->Open Perspective-->SVN Repository” and click the right-mouse-button to add

“new             Repository              Location”.                             Then         you              type

“https://diegocant@svn.lafarga.cpl.cpu.edu/dades/annotation” and click 'finish'. Now you have a




                                 Figure 4.10 “Add a new SVN Repository”


connection from Eclipse with the Repository. Right-click on the location, and select 'checkout'. The

reason why a 'checkout' is necessary is to copy the existing project files from the repository to your


                                                                                                     Page 45 of 87
Chapter 4                                                                                    Implementation

local project. It is only the first time when you configure your eclipse to the project, that it is necessary.

The further instructions are similar to 4.2.1.a.




                        Figure 4.11“Checkout from SVN”                          Figure 4.12“Result”




        The next step is keeping your local project up-to-date with the repository, and the other way

around. When you right-click on the project, and select 'team'. The pop-up menu shows several

options, from which the most important for us are “commit”, “update”. “Update” takes the most recent

version of the repository and updates your local version. “Commit” updates the repository version

with your local version and SubClipse allows it to tag comments to your commits. The website were

you can find the source code is

https://lafarga.cpl.upc.edu/plugins/scmsvn/viewcvs.php/?root=annotation




                                                                                                Page 46 of 87
Chapter 4                                                   Implementation




            Figure 4.13“Commit window with Comment space”




                                                              Page 47 of 87
Chapter 4                                                   Implementation




            Figure 4.14 “Screenshot of SVN web interface”




                                                              Page 48 of 87
Chapter 5                                                                                              Results




5 Results

        In this chapter there are two sections. The first one describes in detail how you start the

annotation tool beginning in eclipse, and the annotation of an image. The second section gives a screen

shot of how it opens when you use a website. This will be not further discussed because of the

similarity with the first section.



5.1 Example of annotation, starting from Eclipse


   a   Run the Project in Eclipse




                                       Figure 5.1 “How to run the program in Eclipse


        You start the program by clicking with the left mouse-button on the annotator class. Then you

select 'run as' and 'Java Applet' as shown in the figure above.                   The applet starts running in

appletviewer, this is a test tool used during development.

   b   Select an Image from your hard drive

                                                                                                 Page 49 of 87
Chapter 5                                                                                         Results




                                           Figure 5.2 “First part of the program”


        The file browser pops up, the user browses to the image he desires and clicks the 'open' button.




   c   The Image Loads and Selection of a Rectangular Region


        The figures on the next page show the image in AppletViewer. The second figure has the

selection of the highlighted rectangle .




                                                                                           Page 50 of 87
Chapter 5                                                                           Results




                Figure 5.3 “Appletviewer with image loaded”




            Figure 5.4 “Appletviewer with image loaded and region selected”




                                                                              Page 51 of 87
Chapter 5                                                                                               Results



   d     The 'send coordinates' button




                                       Figure 5.5 “Put desired filename on a selected location”


         When the 'send coordinates' button is clicked, the file browser opens again. The user types the

filename and selects a location. Finally the program writes two files, with the same name, at the same

location, but with a different extension. One file is a txt-file with normal text format. The other file is

the MPEG-7 file, as previously discussed. The following images give step by step what is described

above.




                                       Figure 5.6 “The two files are written to this folder”




                                                                                                  Page 52 of 87
Chapter 5                                                                            Results




            Figure 5.7 “The content of the MPEG-7 file as seen in Mozilla Firefox”




            Figure 5.8 “The content of the txt file as seen in Notepad”




                                                                             Page 53 of 87
Chapter 5                                                                          Results

5.1.2 Example of Annotation, starting in a Web Browser




                Figure 5.9 “The Annotation Tool loaded from a web browser”




                                                                             Page 54 of 87
Chapter 6                                                                                                Future Work




6 Future Work

       The Annotation Tool can be improved in several ways. To begin with, the GUI can made

better. Moreover the functionality can be expanded to work with a BPT (Binary Partition Tree).

Semantic objects would be represented by or separate, or combined nodes of such an BPT, for example:




                      Figure 6.1 taken from “BPT Enhancement Based on Syntactic and Semantic Criteria”
                                by C.Ferran, X.Giró, F.Marqués and J.R.Casas




                                                                                                         Page 55 of 87
Chapter 6                                                                                 Future Work

         The JAR-file should get signed by a certificate from the school, keep in mind that there is a

public and a private key needed. The public key is only needed to validate the JAR-file, the private key

to sign it.




                                                                                         Page 56 of 87
Chapter 7                                                                                      Conclusion




7 Conclusion

       During this project I have experienced to work with several technologies/programs which were

new for me: Subversion, Applet technology, MPEG-7, Eclipse, signing jar-files,... The knowledge I

have now gives me a better viewpoint on computer programming then I had before.




       There are several goals which aren't achieved though. The first problems occurred with the

Filebrowser: the security issues it brought up took some time to find out what the problem actually was.

First for the version in eclipse (a permission-statement had to be added), later for the version on the web

browser (signing JAR-file). Finally these problems were solved, but the JAR-file is signed with a self-

generated certificate, which is not generated by the EUETIT.




       It took some time to find out how to work with Subversion, but once the project was connected,

it showed its use. From experience I can tell that it is important to make a lot of commits with specific

and detailed comments on what has changed. It is not only important for your project partner to know

what you have changed, but also for yourself in case you forget something.




       XML and MPEG-7 are very interesting subjects, though it can get complicated with the


                                                                                            Page 57 of 87
Chapter 7                                                                                   Conclusion

different libraries that need to be added. The possibilities however are gigantic. In this program, the

functionality doesn't get a big podium to show its capabilities, but during reading articles and books I

came in contact with its use in retrieval frameworks,...




                                                                                          Page 58 of 87
Chapter 7                                                                              Conclusion




Bibliography
WIK: , Wikipedia, , www.wikipedia.be
XML2: , website XMLBeans, , http://xmlbeans.apache.org/
XML1: Elliotte Rusty Harold, W. Scott Means, XML in a Nutshell, 2nd Edition, 2002
MPOV: José M. Marinez, MPEG-7 Overview,
MP7W: , , , http://www.chiariglione.org/mpeg/
MP7HP: , The MPEG-7 homepage, , http://mpeg.telecomitalialab.com/
MPWP: , MPEG-7 Whitepaper, 2003
ftggr: , fototagger, , www.fototagger.com
MSCL: , MUSCLE, , http://muscle.prip.tuwien.ac.at/
VDTT: Nicholas Diakopoulos and Irfan Essa, Videotater: An Approach for Pen-BasedDigital Video
Segmentation and Tagging,
LBLM: , Homepage Labelme, , www.labelme.com
SUN: , SUN Microsystems, , http://Java.sun.com/
SVN: Ben Collins-Sussman,Brian W. FitzpatrickC. ,Michael Pilato, Version Control with Subversion,
MP7: Marco Bertini, MPEG-7,
UMMR: Werner Klieber, Using MPEG-7 for Multimedia Retrieval, 2003
XSMPDL7: Dr. HaraldKosch,Steve Dennis,Alejandro Jaimes, Jane Hunter
JAV1: Cay S.Horstmann and Gary Cornell, Core Java Fundamentals,
JAV2: Cay S. Horstmann, Gary Cornell, Core Java Advanced Features,
ECL: , Homepagina Eclipse, , http://www.eclipse.org/




                                                                                    Page 59 of 87
Chapter 8                                                                    Appendix




8 Appendix: Source Code

8.1 Annotator.Java

package src.edu.upc.terrassatsc;

import java.applet.Applet;
import java.awt.*;
import java.awt.Button;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.ArrayList;
import javax.swing.JFileChooser;

//import mpegMpeg7Schema2001.Mpeg7Document;
import mpegMpeg7Schema2001.*;

import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;


public class Annotator extends Applet implements MouseListener,
                 MouseMotionListener, ActionListener {

        private static final long serialVersionUID = 5610359269819472163L;

        Image image;

        URL base;
Chapter 8                                                                   Appendix

      MediaTracker mt;

      private int temp;

      private int firstX;

      private int firstY;

      private int currentX;

      private int currentY;

      private Object filePath;// saving of coordinates parameters

      private Object fileName;

      Button okButton1;

      public void init() {

               temp = 0;
               setLayout(null);
               addMouseMotionListener(this);

               //        Create a file chooser
               final JFileChooser fc = new JFileChooser();
               int returnVal = fc.showOpenDialog(Annotator.this);

                 final File file;
   if (returnVal == JFileChooser.APPROVE_OPTION) {
      file = fc.getSelectedFile();
      System.out.println("Opening: " + file.getAbsolutePath() + ".");

     /* Read image from file */
              try {
                                image = getImage( file.toURI().toURL() );
                       } catch (MalformedURLException e1) {
                                // TODO Auto-generated catch block
               System.out.println("Unable to open image file.");
                                e1.printStackTrace();
                       }

               mt = new MediaTracker(this);
               mt.addImage(image, 1);
               try {
                        mt.waitForAll();
               } catch (final InterruptedException e) {
               }
               int imageWidth = image.getWidth(null);
               okButton1 = new Button("Send Coordinates");
               System.out.println(imageWidth);
               okButton1.setBounds(0,0,imageWidth,20);
               add(okButton1, "Northwest");
               okButton1.addActionListener(this);

   } else {
       System.out.println("Open command cancelled by user.");
Chapter 8                                                                                                  Appendix

   }
       }

       private void toTextFile( )
       {
                //       Write in the selected file in text mode
                final TextFile textFile = new TextFile(false, filePath + "/" + fileName + ".txt");
                textFile.println("first X: " + firstX + " " + "first Y: " + firstY
                                   + " " + "last X: " + currentX + " " + "last Y: "
                                   + currentY);
                System.out.println( "TXT Coordinates written to " + filePath + "/" + fileName + ".txt");
       }

       private void toMpeg7File() throws XmlException, IOException
       {
                //      Creates a new, completely empty instance
                Mpeg7Document mpeg7doc = Mpeg7Document.Factory.newInstance();

               // Add Mpeg7 element
               Mpeg7Document.Mpeg7 mpeg7 = mpeg7doc.addNewMpeg7();

               // Add Description element
               CompleteDescriptionType completeDescription = mpeg7.addNewDescription();

               // Change the schema type from CompleteDescription to ContentDescriptionType
               ContentDescriptionType contentDescription = (ContentDescriptionType) completeDescription
                                .changeType(ContentDescriptionType.type);

               // Change the schema type from ContentDescription to ContentEntityType
               ContentEntityType contentEntity = (ContentEntityType) contentDescription
               .changeType(ContentEntityType.type);

               //     Add MultimediaContent element
               MultimediaContentType multimediaContent = contentEntity.addNewMultimediaContent();

               //     Change the schema type from MultimediaContent to ImageType
               ImageType image = (ImageType) multimediaContent.changeType(ImageType.type);

               //       Add StillRegion element
               StillRegionType stillRegion = image.addNewImage();

               // Add SpatialLocator element
               RegionLocatorType regionLocator = stillRegion.addNewSpatialLocator();

               //      Add Polygon/Coords element
               IntegerMatrixType coords = regionLocator.addNewPolygon().addNewCoords();

               // Creat a list and add the rectangle coordinates
               List<Integer> boxVertices = new ArrayList<Integer>();
               boxVertices.add(new Integer(firstX) );
               boxVertices.add(new Integer(firstY) );
               boxVertices.add(new Integer(currentX) );
               boxVertices.add(new Integer(currentY) );

               // Set the dimension of the list
               List<Integer> dimension = new ArrayList<Integer>();
               dimension.add(new Integer(4) );
Chapter 8                                                                                         Appendix

              coords.setDim( dimension );

              // Set the list of coordinates
              coords.setListValue(boxVertices);

              // Create a XML object by parsing the MPEG-7 string
              XmlObject xmlObject = XmlObject.Factory.parse( mpeg7doc.toString() );

              //      Create a file stream
              OutputStream outputStream = new FileOutputStream( filePath + "/" + fileName + ".mp7");

              // Dump the XML object into the file stream
              xmlObject.save(outputStream);
      }

      /*
       * (non-Javadoc)
       *
       * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
       */
      public void mouseClicked(final MouseEvent arg0) {
               // TODO Auto-generated method stub

      }

      /*
       * (non-Javadoc)
       *
       * @see java.awt.event.MouseListener#mouseEntered(java.awt.event.MouseEvent)
       */
      public void mouseEntered(final MouseEvent arg0) {
               // TODO Auto-generated method stub

      }

      /*
       * (non-Javadoc)
       *
       * @see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent)
       */
      public void mouseExited(final MouseEvent arg0) {
               // TODO Auto-generated method stub

      }

      /*
       * (non-Javadoc)
       *
       * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
       */
      public void mousePressed(final MouseEvent arg0) {
               // TODO Auto-generated method stub

      }

      /*
       * (non-Javadoc)
Chapter 8                                                                                        Appendix

      *
      * @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent)
      */
      public void mouseReleased(final MouseEvent arg0) {
               temp = 0;
      }

      /*
       * (non-Javadoc)
       *
       * @see java.awt.event.MouseMotionListener#mouseDragged(java.awt.event.MouseEvent)
       */
      public void mouseDragged(final MouseEvent mEvent) {
               processMovement(mEvent);
      }

      /*
       * (non-Javadoc)
       *
       * @see java.awt.event.MouseMotionListener#mouseMoved(java.awt.event.MouseEvent)
       */
      public void mouseMoved(final MouseEvent arg0) {
               // TODO Auto-generated method stub

      }

      /*
       * (non-Javadoc)
       *
       * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
       */
      public void actionPerformed(final ActionEvent evt) {

              if (evt.getSource() == okButton1) {

                      // Select a filename to write the annotation to
                      final FileSelector fileSelector = new FileSelector();
                      fileSelector.actionPerformed();
                      filePath = fileSelector.getDirectory();
                      fileName = fileSelector.getFileName();

                      // Write to the selected file in text mode
                      toTextFile();

                      // Write to the selected file in MPEG-7 format
                      try {
                               toMpeg7File();
                      } catch (XmlException e) {
                               // TODO Auto-generated catch block
                               System.out.println( "XML Exception while writing MPEG-7 XML" );
                               e.printStackTrace();
                      } catch (IOException e) {
                               // TODO Auto-generated catch block
                               System.out.println( "IO Exception while writing MPEG-7 XML" );
                               e.printStackTrace();
                      }
              }
Chapter 8                                                                                    Appendix

           }

           private void processMovement(final MouseEvent evt) {
                    final int CoordX = evt.getX();
                    final int CoordY = evt.getY();
                    currentX = CoordX;
                    currentY = CoordY - 20;
                    if (temp == 0) {
                              firstX = CoordX;
                              firstY = CoordY - 20;
                              temp = 1;
                    }
                    repaint();
           }

           public void paint(Graphics g)
    {
                     // draw the image on the screen
                     final int green=255;
                     final int red=255 ;
                     final int blue=0;
                     final int transparency=50;
        g.drawImage(image,0,20,this);
        g.drawString("("+currentX+","+currentY+")",currentX+10,currentY+10);
        g.drawString("("+firstX+","+firstY+")",firstX,firstY+10);
        g.drawRect(firstX,firstY + 20,currentX-firstX, currentY-firstY);
        Color color = new Color(red, green, blue,255 * transparency / 100);
            g.setColor(color);
            g.fillRect(firstX, firstY + 20, currentX - firstX + 1, currentY - firstY + 1);
    }

}



8.2 FileSelector.Java
package src.edu.upc.terrassatsc;

import java.awt.BorderLayout;

import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;


public class FileSelector extends JApplet {

           private static final long serialVersionUID = 798921988041064078L;

           JButton button1 = new JButton();

           boolean successful = true;

           JOptionPane jop = new JOptionPane();
Chapter 8                                                                          Appendix

        public void init() {
                 button1.setText("Submit");
                 this.getContentPane().add(button1, BorderLayout.NORTH);
                 button1.setBounds(120, 200, 98, 30);
                 // button1.addActionListener(this);

        }

        public void actionPerformed() {

                 try {
                          JFileChooser fileDialog = new JFileChooser();
                          fileDialog.showOpenDialog(this);
                          temp1 = fileDialog.getCurrentDirectory();
                          // tempdirectory=(String) temp1;
                          // System.out.println(temp1);
                          temp2 = fileDialog.getSelectedFile().getName();
                          fileDialog.setVisible(true);

                 } catch (Exception e) {
                          e.printStackTrace();
                 }

        }

        public Object getDirectory() {
                return temp1;
        }

        public Object getFileName() {
                return temp2;
        }

        private Object temp1;

        private Object temp2;
}



8.3 TextFile.Java


package src.edu.upc.terrassatsc;

import java.io.*;
import java.text.DecimalFormat;

/**
 * A simple I/O class to help students read from or write to a text file. The
 * I/O classes that come with Java are very flexible, but are difficult for
 * beginners to learn. This class is a substitute that performs most of the
 * simple things you need to do in intro Java courses.
 *
 * None of the methods from this class throw exceptions. When errors occur, they
Chapter 8                                                                                  Appendix

 * print an error message and abort the program.
 *
 * For more details, see method descriptions below as well as example programs
 * provided with this class.
 *
 * @author Margaret Lamb
 * @version 1.3, August 2006
 */
/* Versions:
 * 1.1: July 2005, initial version
 * 1.2: September 2005: fixed minor problem with println
 * 1.3: August 2006: internal changes so package works with Java 1.4,
 * added padding and formatting functions
 * 1.3a: September 2006: more user-friendly error message when readInt hits end of file
 */
public class TextFile {

//       This object does all the real work. It's either an InputFileObject or an
         // OutputFileObject. The only reason for the indirection is to make it
         // possible to use regular constuctors instead of a static "factory" method
         // to create TextFile objects.
         private FileObject fileObj;

         /**
          * A TextFile object for reading user input from the keyboard ("standard
          * input")
          */
         public static final TextFile KEYBOARD = new TextFile(true);

         /**
          * A TextFile object for writing to the computer screen ("standard output").
          * This provides the same functionality as System.out, but is included for
          * completeness, and also contains formatted print and println methods for
          * ints and doubles.
          */
         public static final TextFile SCREEN = new TextFile(false);

         /**
          * Creates a new TextFile object for reading from or writing to a file.
          * &lt;p&gt;
          * &lt;b&gt;Errors:&lt;/b&gt; &lt;br&gt;
          *        Will abort with an
          * error message if the file can't be opened or if you attempt to read from
          * an input file which does not exist.
          *
          * @param inputFile true if this is an input file for reading; false if it's an
          * output file for writing
          * @param fileName the name of the file -- may be an absolute name
          * ("c:/Java/Assignment 1/inputfile.txt") or a simple name
          * ("inputfile.txt"). Simple names will be found in the same
          * folder as your program (.java) files.
          */
         public TextFile(boolean inputFile, String fileName) {
           if (inputFile)
             fileObj = new InputFileObject(fileName);
           else
             fileObj = new OutputFileObject(fileName);
Chapter 8                                                                             Appendix

       } // end constructor

       // special constructor for creating an object for reading from the standard
       // input or writing to the standard output
       private TextFile(boolean inputFile) {
         if (inputFile)
           fileObj = new InputFileObject();
         else
           fileObj = new OutputFileObject();
       } // end constructor

       /**
        * Reads a single character from the (input) file. Does not skip
        * whitespace characters.
        * &lt;p&gt;
        * &lt;b&gt;Errors:&lt;/b&gt; &lt;br&gt;
        *        Will abort with an
        * error if this is an output file, or if we have already reached the end of
        * the file.
        *
        * @return the character read from the file
        */
       public char readChar() {
         return fileObj.readChar();
       } // end readChar

       /**
        * Reads the next line from the (input) file.
        * &lt;p&gt;
        * &lt;b&gt;Errors:&lt;/b&gt; &lt;br&gt;
        *        Will abort with an
        * error if this is an output file, or if we have already reached the end of
        * the file.
        *
        * @return the line read from the file (minus the ending '\n')
        */
        public String readLine() {
         return fileObj.readLine();
        } // end readLine

       /**
        * Reads the next "word" from the (input) file. A word is a sequence of
        * characters other than the "whitespace" characters (space, tab and
        * newline). It will skip any initial whitespace and then read characters
        * until it sees either a whitespace character or the end of the file.
        * &lt;p&gt;
        * &lt;b&gt;Errors:&lt;/b&gt; &lt;br&gt;
        *        Will abort with an
        * error if this is an output file, or if we have already reached the end of
        * the file.
        *
        * @return the word read from the file
        */
        public String readWord() {
         return fileObj.readWord();
        } // end readWord
Chapter 8                                                                              Appendix

        /**
         * Reads an integer from the (input) file. It skips any whitespace
         * characters, reads the next "word" and converts it to an integer.
         * &lt;p&gt;
         * &lt;b&gt;Errors:&lt;/b&gt; &lt;br&gt;
         *        Will abort with an
         * error if this is an output file, if we have already reached the end of
         * the file, or if the next word is not in legal integer format
         *
         * @return the integer read from the file
         */
        public int readInt() {
         return fileObj.readInt();
        } // end readInt

        /**
         * Reads a double from the (input) file. It skips any whitespace
         * characters, reads the next "word" and converts it to a double.
         * &lt;p&gt;
         * &lt;b&gt;Errors:&lt;/b&gt; &lt;br&gt;
         *        Will abort with an
         * error if this is an output file, if we have already reached the end of
         * the file, or if the next word is not in legal double format
         *
         * @return the integer read from the file
         */
        public double readDouble() {
         return fileObj.readDouble();
        } // end readDouble

        /**
         * Skips "white space" in the (input) file. White space characters are
         * blanks, tabs and newlines. This method throws away white space characters
         * from the input until it reaches either a non-white character or the end
         * of the file. It's not an error to call this method when you're already at
         * the end of the file.
         * &lt;p&gt;
         * &lt;b&gt;Errors:&lt;/b&gt; &lt;br&gt;
         *        Will abort with an
         * error if this is an output file.
         */
        public void skipWhiteSpace() {
         fileObj.skipWhiteSpace();
        } // end skipWhiteSpace

        /**
         * Checks whether we've reached the end of the (input) file.
         * &lt;p&gt;
         * &lt;b&gt;Errors:&lt;/b&gt; &lt;br&gt;
         *        Will abort with an
         * error if this is an output file.
         *
         * @return true if we've reached the end of the file
         */
        public boolean eof() {
         return fileObj.eof();
        } // end eof
Chapter 8                                                                          Appendix


        /**
         * Writes a single character to the (output) file, followed by an
         * end-of-line character.
         * &lt;p&gt;
         * &lt;b&gt;Errors:&lt;/b&gt; &lt;br&gt;
         *        Will abort with an
         * error if this is an input file.
         *
         * @param c the character to write
         */
        public void println(char c) {
         fileObj.println(c);
        } // end println

        /**
         * Writes a string to the (output file), followed by an end-of-line
         * character.
         * &lt;p&gt;
         * &lt;b&gt;Errors:&lt;/b&gt; &lt;br&gt;
         *        Will abort with an
         * error if this is an input file.
         *
         * @param s the string to write
         */
        public void println(String s) {
         fileObj.println(s);
        } // end println

       /**
        * Writes a string to the (output) file, using a specified minimum width,
        * followed by an end-of-line character.
        * If the string is shorter than the width, it is padded on the left with
        * blanks.
        * &lt;p&gt;
        * &lt;b&gt;Errors:&lt;/b&gt; &lt;br&gt;
        *        Will abort with an
        * error if this is an input file.
        *
        * @param s the string to write
        * @param width the minimum width
        */
       public void println(String s, int width) {
         fileObj.println(s, width);
       } // end print

       /**
        * Writes an integer to the (output) file, followed by an end-of-line
        * character.
        * &lt;p&gt;
        * &lt;b&gt;Errors:&lt;/b&gt; &lt;br&gt;
        *        Will abort with an
        * error if this is an input file.
        *
        * @param i the integer to write
        */
        public void println(int i) {
Chapter 8                                                                                              Appendix

           fileObj.println(i);
          } // end println

         /**
          * Writes an integer to the (output) file, using a specified minimum width,
          * followed by an end-of-line character. If the integer has fewer than the
          * specified number of digits, it is padded on the left with blanks. If the
          * integer has more than the specified number of digits, the minimum width
          * is disregarded and the full integer is printed.
          * &lt;p&gt;
          * &lt;p&gt;
          * &lt;b&gt;Example:&lt;/b&gt; &lt;br&gt;
          *
          * &lt;tt&gt;println(1234,5)&lt;/tt&gt; will print &lt;tt&gt;" 12345"&lt;/tt&gt; &lt;br&gt;
          *
          * &lt;tt&gt;println(1234,3)&lt;/tt&gt; will print &lt;tt&gt;"1234"&lt;/tt&gt;.
          *
          * &lt;p&gt;
          * &lt;b&gt;Errors:&lt;/b&gt; &lt;br&gt;
          *        Will abort with an
          * error if this is an input file.
          *
          * @param i the integer to write
          * @param width the minimum number of output characters to write; the method
          * will add spaces at the beginning if necessary to make this
          * number of characters.
          */
         public void println(int i, int width) {
           fileObj.println(i, width);
         } // end println

         /**
          * Writes a double number to the (output) file in the default format,
          * followed by an end-of-line character. Uses as many digits as required
          * without leading or trailing zeros.
          * &lt;p&gt;
          * &lt;b&gt;Examples:&lt;/b&gt;&lt;br&gt;
          *
          * &lt;tt&gt;println(123.45)&lt;/tt&gt; prints &lt;tt&gt;"123.45"&lt;/tt&gt;. &lt;br&gt;
          *
          * &lt;tt&gt;println(11.0/7.0)&lt;/tt&gt; prints &lt;tt&gt;"1.5714285714285714"&lt;/tt&gt;.
          * &lt;p&gt;
          * &lt;b&gt;Errors:&lt;/b&gt; &lt;br&gt;
          *        Will abort with an
          * error if this
is an input file.
          *
          * @param d
          *         the number to write.
          */
          public void println(double d) {
           fileObj.println(d);
          } // end println

         /**
          * Writes a double number to the (output) file using a specified minimum
Chapter 8                                                                                                Appendix

       * width, followed by an end-of-line character. Always uses 6 digits after
       * the decimal point, even if that includes trailing zeros. Decimal digits
       * after 6 are rounded. Pads with spaces on the left, if necessary, to reach
       * the minimum width.
       * &lt;p&gt;
       * &lt;b&gt;Examples:&lt;/b&gt;&lt;br&gt;
       *
       * &lt;tt&gt;println(123.45,12)&lt;/tt&gt; prints &lt;tt&gt;" 123.450000"&lt;/tt&gt;. &lt;br&gt;
       *
       * &lt;tt&gt;println(11.0/7.0,9)&lt;/tt&gt; prints &lt;tt&gt;" 1.571429"&lt;/tt&gt;.
       * &lt;p&gt;
       * &lt;b&gt;Errors:&lt;/b&gt; &lt;br&gt;
       *         Will abort with an
       * error if this is an input file.
       *
       * @param d the number to write
       * @param width the minimum number of output characters to write; the method
       * will add spaces at the beginning if necessary to make this
       * number of characters.
       */
       public void println(double d, int width) {
        fileObj.println(d, width);
       } // end println

       /**
        * Writes a double number to the (output) file using a specified minimum
        * width and precision, followed by an end-of-line character. Always uses
        * exactly the specified number of digits after the decimal point, rounding
        * the rest. (If the precision is negative, prints zero digits after the
        * decimal point.) Pads with spaces on the left, if necessary, to reach the
        * minimum width. If you want to specify the precision but not a minimum
        * width, use a width of 1.
        * &lt;p&gt;
        * &lt;b&gt;Examples:&lt;/b&gt;&lt;br&gt;
        *
        * &lt;tt&gt;println(123.45,9,3)&lt;/tt&gt; prints &lt;tt&gt;" 123.450"&lt;/tt&gt;. &lt;br&gt;
        *
        * &lt;tt&gt;println(11.0/7.0,3,1)&lt;/tt&gt; prints &lt;tt&gt;" 1.6"&lt;/tt&gt;. &lt;br&gt;
        *
        * &lt;tt&gt;println(11.0/7.0,1,2)&lt;/tt&gt; prints &lt;tt&gt;"1.57"&lt;/tt&gt;.
        * &lt;p&gt;
        * &lt;b&gt;Errors:&lt;/b&gt; &lt;br&gt;
        *        Will abort with an
        * error if this is an input file.
        *
        * @param d the number to write
        * @param width the minimum number of output characters to write; the method
        * will add spaces at the beginning if necessary to make this
        * number of characters.
        */
       public void println(double d, int width, int precision) {
        fileObj.println(d, width, precision);
       } // end println

       /**
        * Writes a boolean value to the (output) file (as "true" or "false"),
        * followed by an end-of-line character.
Chapter 8                                                                          Appendix

       * &lt;p&gt;
       * &lt;b&gt;Errors:&lt;/b&gt; &lt;br&gt;
       *         Will abort with an
       * error if this is an input file.
       *
       * @param b the boolean value to write
       */
       public void println(boolean b) {
        fileObj.println(b);
       } // end println

       /**
        * Writes an object to the (output) file, followed by an end-of-line
        * character. The printing format corresponds to the "toString" method of
        * that object's type.
        * &lt;p&gt;
        * &lt;b&gt;Errors:&lt;/b&gt; &lt;br&gt;
        *        Will abort with an
        * error if this is an input file.
        *
        * @param obj
        *         the object to write
        */
       public void println(Object obj) {
         fileObj.println(obj);
       } // end println

       /**
        * Writes an end-of-line character to the (output) file.
        * &lt;p&gt;
        * &lt;b&gt;Errors:&lt;/b&gt; &lt;br&gt;
        *        Will abort with an
        * error if this is an input file.
        */
       public void println() {
         fileObj.println();
       } // end println

       /**
        * Writes a single character to the (output) file.
        * &lt;p&gt;
        * &lt;b&gt;Errors:&lt;/b&gt; &lt;br&gt;
        *        Will abort with an
        * error if this is an input file.
        *
        * @param c the character to write
        */
       public void print(char c) {
         fileObj.print(c);
       } // end print

       /**
        * Writes a string to the (output) file.
        * &lt;p&gt;
        * &lt;b&gt;Errors:&lt;/b&gt; &lt;br&gt;
        *        Will abort with an
        * error if this is an input file.
Chapter 8                                                                                            Appendix

       *
       * @param s the string to write
       */
       public void print(String s) {
        fileObj.print(s);
       } // end print

       /**
        * Writes a string to the (output) file, using a specified minimum width.
        * If the string is shorter than the width, it is padded on the left with
        * blanks.
        * &lt;p&gt;
        * &lt;b&gt;Errors:&lt;/b&gt; &lt;br&gt;
        *        Will abort with an
        * error if this is an input file.
        *
        * @param s the string to write
        * @param width the minimum width
       */
       public void print(String s, int width) {
         fileObj.print(s, width);
       } // end print

       /**
        * Writes an integer to the (output) file.
        * &lt;p&gt;
        * &lt;b&gt;Errors:&lt;/b&gt; &lt;br&gt;
        *        Will abort with an
        * error if this is an input file.
        *
        * @param i
        *         the integer to write
        */
       public void print(int i) {
         fileObj.print(i);
       } // end print

       /**
        * Writes an integer to the (output) file, using a specified minimum width.
        * If the integer has fewer than the specified number of digits, it is
        * padded on the left with blanks. If the integer has more than the
        * specified number of digits, the minimum width is disregarded and the full
        * integer is printed.
        * &lt;p&gt;
        * &lt;b&gt;Example:&lt;/b&gt; &lt;br&gt;
        *
        * &lt;tt&gt;println(1234,5)&lt;/tt&gt; will print &lt;tt&gt;" 12345"&lt;/tt&gt; &lt;br&gt;
        *
        * &lt;tt&gt;println(1234,3)&lt;/tt&gt; will print &lt;tt&gt;"1234"&lt;/tt&gt;.
        *
        * &lt;p&gt;
        * &lt;b&gt;Errors:&lt;/b&gt; &lt;br&gt;
        *        Will abort with an
        * error if this is an input file.
        *
        * @param i the integer to write
        * @param width the minimum number of output characters to write; the method
Chapter 8                                                                                                 Appendix

       * will add spaces at the beginning if necessary to make this
       * number of characters.
       */
       public void print(int i, int width) {
          fileObj.print(i, width);
       } // end print

       /**
        * Writes a double number to the (output) file in the default format. Uses
        * as many digits as required without leading or trailing zeros.
        * &lt;p&gt;
        * &lt;b&gt;Examples:&lt;/b&gt;&lt;br&gt;
        *
        * &lt;tt&gt;println(123.45)&lt;/tt&gt; prints &lt;tt&gt;"123.45"&lt;/tt&gt;. &lt;br&gt;
        *
        * &lt;tt&gt;println(11.0/7.0)&lt;/tt&gt; prints &lt;tt&gt;"1.5714285714285714"&lt;/tt&gt;.
        * &lt;p&gt;
        * &lt;b&gt;Errors:&lt;/b&gt; &lt;br&gt;
        *        Will abort with an
        * error if this is an input file.
        *
        * @param d the number to write.
        */
       public void print(double d) {
         fileObj.print(d);
       } // end print

       /**
        * Writes a double number to the (output) file using a specified minimum
        * width. Always uses 6 digits after the decimal point, even if that
        * includes trailing zeros. Decimal digits after 6 are rounded. Pads with
        * spaces on the left, if necessary, to reach the minimum width.
        * &lt;p&gt;
        * &lt;b&gt;Examples:&lt;/b&gt;&lt;br&gt;
        *
        * &lt;tt&gt;println(123.45,12)&lt;/tt&gt; prints &lt;tt&gt;" 123.450000"&lt;/tt&gt;. &lt;br&gt;
        *
        * &lt;tt&gt;println(11.0/7.0,9)&lt;/tt&gt; prints &lt;tt&gt;" 1.571429"&lt;/tt&gt;.
        * &lt;p&gt;
        * &lt;b&gt;Errors:&lt;/b&gt; &lt;br&gt;
        *        Will abort with an
        * error if this is an input file.
        *
        * @param d the number to write
        * @param width the minimum number of output characters to write; the method
        * will add spaces at the beginning if necessary to make this
        * number of characters.
        */
       public void print(double d, int width) {
         fileObj.print(d, width);
       } // end print

       /**
        * Writes a double number to the (output) file using a specified minimum
        * width and precision. Always uses exactly the specified number of digits
        * after the decimal point, rounding the rest. (If the precision is
        * negative, prints zero digits after the decimal point.) Pads with spaces
Chapter 8                                                                                            Appendix

       * on the left, if necessary, to reach the minimum width. If you want to
       * specify the precision but not a minimum width, use a width of 1.
       * &lt;p&gt;
       * &lt;b&gt;Examples:&lt;/b&gt;&lt;br&gt;
       *
       * &lt;tt&gt;println(1.5714,5,1)&lt;/tt&gt; prints &lt;tt&gt;" 1.6"&lt;/tt&gt;. &lt;br&gt;
       *
       * &lt;tt&gt;println(1.5714,15,2)&lt;/tt&gt; prints &lt;tt&gt;" 1.57"&lt;/tt&gt;. &lt;br&gt;
       *
       * &lt;tt&gt;println(1.5714,1,6)&lt;/tt&gt; prints &lt;tt&gt;"1.571400"&lt;/tt&gt;.
       * &lt;p&gt;
       * &lt;b&gt;Errors:&lt;/b&gt; &lt;br&gt;
       *         Will abort with an
       * error if this is an input file.
       *
       * @param d the number to write
       * @param width the minimum number of output characters to write; the method
       * will add spaces at the beginning if necessary to make this
       * number of characters.
       */
       public void print(double d, int width, int precision) {
        fileObj.print(d, width, precision);
       } // end print

       /**
        * Writes a boolean value to the (output) file (as "true" or "false").
        * &lt;p&gt;
        * &lt;b&gt;Errors:&lt;/b&gt; &lt;br&gt;
        *        Will abort with an
        * error if this is an input file.
        *
        * @param b the boolean value to write
        */
       public void print(boolean b) {
         fileObj.print(b);
       } // end print

       /**
        * Writes an object to the (output) file. The printing format corresponds to
        * the "toString" method of that object's type.
        * &lt;p&gt;
        * &lt;b&gt;Errors:&lt;/b&gt; &lt;br&gt;
        *        Will abort with
an
       * error if this is an input file.
       *
       * @param obj the object to write
       */
       public void print(Object obj) {
        fileObj.print(obj);
       } // end print

       /**
        * Closes the file when you're done using it. It's important to remember to
        * do this to free system resources associated with the file and to make
        * sure any buffered characters really make it to the file. It's not
Chapter 8                                                                                              Appendix

       * necessary to close the special Keyboard or Screen files.
       */
       public void close() {
        fileObj.close();
       } // end close

       /**
        * Aborts the program with an error message. Included here just because it's
        * generally useful, both for I/O and other purposes.
        *
        * @param msg the message to print before ending the program execution
        */
       public static void abort(String msg) {
         System.out.println(msg);
         System.exit(1);
       } // end abort

       /***************************************************************************
        * Helper methods for formatting numbers. These are used by the print
        * methods.
        **************************************************************************/

       /**
        * Pads a string with spaces on the left to reach a target width.
        * If the string is already longer than the width, leaves it alone --
        * doesn't truncate.
        * &lt;p&gt;
        * &lt;b&gt;Examples:&lt;/b&gt;&lt;br&gt;
        *
        * &lt;tt&gt;padLeft("hello", 7)&lt;/tt&gt; returns &lt;tt&gt;" hello"&lt;/tt&gt;. &lt;br&gt;
        *
        * &lt;tt&gt;padLeft("hello", 4)&lt;/tt&gt; returns &lt;tt&gt;"hello"&lt;/tt&gt;.
        * &lt;p&gt;
        * @param s the string to pad
        * @param width the target width (number of characters)
        * @return the string with spaces inserted on the left as needed
        */
       private static String padLeft(String str, int width) {
         String result = str;
         while (result.length() < width)
          result = " " + result;
          return result;
       } // end padLeft

       /**
        * Formats an integer for output, padding it to a target width.
        * Adds blank spaces to the left as needed to reach the width.
        * If the integer contains more spaces than the width, no digits
        * are truncated.
        * <p&gt;
        * <b&gt;Examples:</b&gt;<br&gt;
        *
        * <tt&gt;formatInt("12345", 7)</tt&gt; returns <tt&gt;" 12345"</tt&gt;. <br&gt;
        *
        * <tt&gt;formatInt("12345", 4)</tt&gt; returns <tt&gt;"12345"</tt&gt;.
        * <p&gt;
        * @param value the integer to format
Chapter 8                                                                                   Appendix

       * @param width the target width
       * @return the integer in string form, with blank spaces inserted on the
       * left as needed to reach the target width
       */
       private static String formatInt(int value, int width) {
        return padLeft(Integer.toString(value), width);
       } // end formatInt

       /**
        * Formats a double for output, with a specified precision and total width.
        * Returns the value that the print method would print given the same
        * double value, width and precision.
        * <p&gt;
        * <b&gt;Examples:</b&gt;<br&gt;
        *
        * <tt&gt;formatDouble(1.5714,5,1)</tt&gt; returns <tt&gt;" 1.6"</tt&gt;. <br&gt;
        *
        * <tt&gt;formatDouble(1.5714,5,2)</tt&gt; returns <tt&gt;" 1.57"</tt&gt;. <br&gt;
        *
        * <tt&gt;formatDouble(1.5714,1,6)</tt&gt; returns <tt&gt;"1.571400"</tt&gt;.
        * <p&gt;
        *
        * @param value the double to format
        * @param width the target width (total number of characters in the string)
        * @param precision the target precision (digits after the decimal point)
        * @return the double value as a string, formatted as specified
        */
       private static String formatDouble(double value, int width, int precision) {
         String formatString = "0.";
         for (int i = 0; i < precision; i++)
          formatString += "0";
         DecimalFormat pattern = new DecimalFormat(formatString);
         String formatted = pattern.format(value);
         return padLeft(formatted, width);
       } // end formatDouble

       /**
        * Formats a double for output, with a specified total width and the
        * default precision (6 digits after the decimal point).
        *
        * @param value the double to format
        * @param width the target width (total number of characters in the string)
        * @return the double value as a string, formatted as specified
        */
       private static String formatDouble(double value, int width) {
         return formatDouble(value, width, 6);
       } // end formatDouble


       /***************************************************************************
        * The inner class FileObject does all the real work. A FileObject is either
        * an InputFileObject for reading or an OutputFileObject for writing.
        **************************************************************************/
       private abstract class FileObject {
         // the name of the file
         protected String fileName;
Chapter 8                                                                                    Appendix

        // All methods are abstract. InputFileObject implements the read methods
        // and aborts if the write methods are called. OutputFileObject
        // implements the write methods and aborts if the read methods are called. See the
        // top-level TextFile methods for descriptions of the functionality,
        // parameters, etc.
        public abstract String readLine();
        public abstract String readWord();
        public abstract void skipWhiteSpace();
        public abstract char readChar();
        public abstract int readInt();
        public abstract double readDouble();
        public abstract void println(String s);
        public abstract void println(String s, int width);
        public abstract void println(char c);
        public abstract void println(int i);
        public abstract void println(int i, int midWidth);
        public abstract void println(double d);
        public abstract void println(double d, int width);
        public abstract void println(double d, int width, int precision);
        public abstract void println(boolean b);
        public abstract void println(Object obj);
        public abstract void println();
        public abstract void print(String s);
        public abstract void print(String s, int width);
        public abstract void print(char c);
        public abstract void print(int i);
        public abstract void print(int i, int width);
        public abstract void print(double d);
        public abstract void print(double d, int width);
        public abstract void print(double d, int width, int precision);
        public abstract void print(boolean b);
        public abstract void print(Object obj);
        public abstract void close();
        public abstract boolean eof();
       } // end class FileObject

       /***************************************************************************
        * An InputFileObject implements an input file, using the BufferedReader
        * class.
        **************************************************************************/
       private class InputFileObject extends FileObject {
         // The reader that does the real work.
         private BufferedReader reader;

        // Read-ahead; these characters have not been returned yet.
        // When we reach the end of the input file, buffer is set to null.
        private StringBuffer buffer = new StringBuffer();

        // Value returned by private function to denote end of file.
        private static final int EOF_VALUE = -1;

        // True if this file is the standard input (so that we won't
        // try to close it!)
        private boolean standardInput = false;

        public InputFileObject(String fileName) {
         this.fileName = fileName;
Chapter 8                                                                        Appendix

         try {
           reader = new BufferedReader(new FileReader(fileName));
         }
         catch (FileNotFoundException e) {
           abort("Error: input file \"" + fileName + "\" does not exist");
         }
        } // end constructor

        public InputFileObject() {
         this.fileName = "standard input";
         reader = new BufferedReader(new InputStreamReader(System.in));
         standardInput = true;
        } // end constructor

        // Three specific abort methods with frequently-used error messages
        private void errorAbort() {
          abort("I/O error while reading from file \"" + fileName + "\"");
        } // end errorAbort

        private void eofAbort() {
         abort("attempt to read past end of input file \"" + fileName + "\"");
        } // end eofAbort

        private void writeAbort() {
         abort("error: attempt to write to input file \"" + fileName + "\"");
        } // end writeAbort

        // Reads the next character from the input file and returns it as an
        // int. If we're at the end of the file, returns -1 instead.
        private int readCharOrEOF() {
          try {
            if (buffer == null) { // already hit EOF
              return EOF_VALUE;
            }
            else if (buffer.length() == 0) {
              String newLine = reader.readLine();
              if (newLine == null)
                return EOF_VALUE;
              else {
                buffer.append(newLine);
                buffer.append('\n');
              } // end if
            } // end if

           // If we get here, the buffer is not null or length 0, so return
           // the next character
           char result = buffer.charAt(0);
           buffer.deleteCharAt(0);
           return result;
         } // end try
         catch (IOException e) {
           errorAbort();
           return ' '; // keep compiler happy
         } // end catch
        } // end readCharOrEOF

        // Pushes a character back onto the input stream. Used when we
Chapter 8                                                                          Appendix

          // read a character we're not ready to send to the user.
          private void pushChar(char ch) {
            if (buffer == null)
              buffer = new StringBuffer(ch);
            else
              buffer.insert(0, ch);
          } // end pushChar

          // Returns true if ch is a "whitespace" character
          private boolean isWhite(char ch) {
            switch (ch) {
             case ' ':
             case '\t':
             case '\n':
              return true;
             default:

  return false;
            } // end switch
           } // end isWhite

          /* ***********************************************************************
           * PUBLIC METHODS
           *
           * See header comments in top-level TextFile methods for descriptions
           * of functionality, parameters, etc.
           * ***********************************************************************/
          public boolean eof() {
           int nextChar = readCharOrEOF();
           if (nextChar == EOF_VALUE)
             return true;
           else {
             pushChar((char) nextChar);
             return false;
           } // end if
          } // end eof

          public void skipWhiteSpace() {
           char ch = ' ';
           while (true) {
             if (eof()) {
               buffer = null;
               return;
             }
             else if (!isWhite(ch)) {
               pushChar(ch);
               return;
             }
             else
               // we just read a whitespace character, so keep going
               ch = readChar();
           } // end while
          } // end skipWhiteSpace

          public String readWord() {
           // skip white space, then read and accumulate characters
Chapter 8                                                                     Appendix

         // until non white space character or eof
         StringBuffer word = new StringBuffer();
         skipWhiteSpace();
         if (eof())
           eofAbort();
         while (true) {
           if (eof())
             return word.toString();
           char ch = readChar();
           if (isWhite(ch)) {
             pushChar(ch);
             return word.toString();
           } else {
             word.append(ch);
           } // end if
         } // end while
        } // end readWord

        public String readLine() {
         if (eof())
           eofAbort();
         // read and accumulate characters until end of line or end of file
         StringBuffer newLine = new StringBuffer();
         int newChar = readCharOrEOF();
         while (newChar != '\n' && newChar != EOF_VALUE) {
           newLine.append((char) newChar);
           newChar = readCharOrEOF();
         } // end while
         return newLine.toString();
        } // end readLine

        public char readChar() {
         int ch = readCharOrEOF();
         if (ch == EOF_VALUE)
           eofAbort();
         return (char) ch;
        } // end readChar

        public int readInt() {
         String intWord = readWord();
         try {
           return Integer.parseInt(intWord);
         } // end try
         catch (NumberFormatException e) {
           abort("error: \"" + intWord + "\" is not a legal integer");
           return 0; // keep compiler happy
         } // end catch
        } // end readInt

        public double readDouble() {
         String doubleWord = readWord();
         try {
           return Double.parseDouble(doubleWord);
         } // end try
         catch (NumberFormatException e) {
           abort("error: \"" + doubleWord + "\" is not a legal double");
           return 0; // keep compiler happy
Chapter 8                                                                      Appendix

         } // end catch
        } // end readDouble

        public void close() {
         if (standardInput)
           return; // don't close the standard input
         try {
           reader.close();
         }
         catch (IOException e) {
           abort("Error while attempting to close file \"" + fileName
             + "\"");
         }
         fileName = "closed file";
        } // end close

        // Calling an output method for an object of this class is an error.
        public void println(String s) {
          writeAbort();
        } // end println
        public void println(String s, int width) {
          writeAbort();
        } // end println
        public void println(int i) {
          writeAbort();
        } // end println
        public void println(int i, int midWidth) {
          writeAbort();
        }
        public void println(double d) {
          writeAbort();
        } // end println
        public void println(double d, int width) {
          writeAbort();
        } // end println
        public void println(double d, int width, int precision) {
          writeAbort();
        } // end println
        public void println(char c) {
          writeAbort();
        } // end println
        public void println(boolean b) {
          writeAbort();
        } // end println
        public void println(Object obj) {
          writeAbort();
        } // end println
        public void println() {
          writeAbort();
        } // end println
        public void print(String s) {
          writeAbort();
        } // end print
        public void print(String s, int width) {
          writeAbort();
        } // end print
        public void print(int i) {
Chapter 8                                                                        Appendix

         writeAbort();
        } // end print
        public void print(int i, int width) {
         writeAbort();
        } // end print
        public void print(double d) {
         writeAbort();
        } // end print
        public void print(double d, int width) {
         writeAbort();
        } // end print
        public void print(double d, int width, int precision) {
         writeAbort();
        } // end print
        public void print(char c) {
         writeAbort();
        } // end print
        public void print(boolean b) {
         writeAbort();
        } // end print
        public void print(Object obj) {
         writeAbort();
        } // end print

       } // end class InputFileObject

       /***************************************************************************
        * An OutputFileObject implements an output file, using the PrintStream
        * class.
        **************************************************************************/
       private class OutputFileObject extends FileObject {
         // the writer that does the real work
         private PrintStream writer;

        public OutputFileObject(String fileName) {
         this.fileName = fileName;
         try {
           writer = new PrintStream(new FileOutputStream(fileName));
         }
         catch (FileNotFoundException e) {
           abort("Error: can't open file \"" + fileName + "\" for writing");
         }
        } // end constructor

        public OutputFileObject() {
         this.fileName = "standard output";
         writer = System.out;
        } // end constructor

        // abort with a common error message
        private void readAbort() {
          abort("Error: attempt to read from output file \"" + fileName
          + "\"");
        } // end readAbort

        /* ***********************************************************************
         * PUBLIC METHODS
Chapter 8                                                                       Appendix

        *
        * See header comments in top-level TextFile methods for descriptions
        * of functionality, parameters, etc.
        * ***********************************************************************/
        public void println(String s) {
         print(s);
         println();
        } // end println

        public void println(String s, int width) {
         print(s, width);
         println();
        } // end println

        public void println(int i) {
         print(i);
         println();
        } // end println

        public void println(int i, int width) {
         print(i, width);
         println();
        } // end println

        public void println(double d) {
         print(d);
         println();
        } // end println

        public void println(double d, int width) {
         print(d, width);
         println();
        } // end println

        public void println(double d, int width, int precision) {
         print(d, width, precision);
         println();
        } // end println

        public void println(char c) {
         print(c);
         println();
        } // end println

        public void println(boolean b) {
         print(b);
         println();
        } // end println

        public void println(Object obj) {
         print(obj);
         println();
        } // end println

        public void println() {
         writer.println();
        } // end println
Chapter 8                                                                        Appendix


        public void print(String s) {
         writer.print(s);
        } // end print

        public void print(String s, int width) {
         print(padLeft(s,width));
        } // end print

        public void print(int i) {
         print(Integer.toString(i));
        } // end println

        public void print(int i, int width) {
         print(formatInt(i, width));
        } // end print

        public void print(double d) {
         print(Double.toString(d));
        } // end print

        public void print(double d, int width) {
         print(formatDouble(d, width));
        } // end print

        public void print(double d, int width, int precision) {
         print(formatDouble(d, width, precision));
        } // end print

        public void print(char c) {
         print(c + "");
        } // end print

        public void print(boolean b) {
         if (b)
           print("true");
         else
           print("false");
        } // end print

        public void print(Object obj) {
         print(obj.toString());
        } // end println

        public void close() {
         if (writer != System.out) {
           writer.close();
           fileName = "closed file";
         } // end if
        } // end close

        /* ***********************************************************************
         * Calling an input method for an object of this class is an error.
         * **********************************************************************/
        public String readLine() {
         readAbort();
         return null; // keep compiler happy
Chapter 8                                       Appendix

        } // end readLine
        public int readInt() {
         readAbort();
         return 0; // keep compiler happy
        } // end readInt
        public double readDouble() {
         readAbort();
         return 0; // keep compiler happy
        } // end readInt
        public boolean eof() {
         readAbort();
         return false; // keep compiler happy
        } // end eof
        public char readChar() {
         readAbort();
         return ' '; // keep compiler happy
        } // end readChar
        public String readWord() {
         readAbort();
         return null; // keep compiler happy
        } // end readChar
        public void skipWhiteSpace() {
         readAbort();
        } // end skipWhiteSpace

       } // end class OutputFileObject

      } // end class TextFile

						
Related docs