AIS BIIS

UI Construction using Java

Exercise 2 of 2

Selecting Records via the Starfield

Background

TradeViewer only allows records to be selected via a scrolling list of record identifiers. It would be useful to be able to select a record via its starfield representation (i.e., the little coloured dots).

Strategy

We will make the starfield sensitive to mouse events. When a "mouse button released" event is received, we shall test to see if a dot is underneath the cursor. If so, the dot will be highlighted in the starfield and its associated record displayed in the record view below the starfield.

 

Stage 1 Listening for mouse events in the starfield

 

o We want to be able to catch mouse button events over the starfield. We will use a strategy similar to the one used in exercise 1 to handle window events in the main TradeViewer window:

MouseAdapter is the relevant adapter for our purposes. Apart from the constructor, only one method needs to be defined:

public void mousePressed(MouseEvent me)

// send the starfield the cursor coordinates for testing against dot locations

Note: you can extract the cursor coordinates from the mouse event by these MouseEvent methods:

int getX()

// returns x coordinate of the cursor relative to current component

int getY()

// returns x coordinate of the cursor relative to current component

See hint 1 for help.

The installation should be done in the starfield�s constructor method. Use the following method:

addMouseListener(new <your new MouseAdapter subclass> (this));

�this� refers to the starfield and provides the adapter with a reference to the starfield for the mouse adapter to use when sending the cursor coordinates in mousePressed().

o Create a method called handleSelection() in the StarFieldView class to receive and handle the cursor coordinates. For the moment, this method should just print the cursor coordinates to standard output. See hint 2 if you need help.

o Build and test your program.

 

Stage 2 Testing the dots

o Examine the instance variables for class StarFieldView. Find these variables:

Point axisOrigin;

// holds the position of the origin of the coordinate system, as an offset from the panel�s upper left hand corner

double scale; // the scale multiplier for the view

double cacheX[], cacheY[];

// arrays which hold the field values representing each record

The position of a given dot, say dot n, in the starfield�s panel is computed thus:

x = axisOrigin.getX() + (int)(cacheX[n]*scale)

y = axisOrigin.getY() - (int)(cacheY[n]*scale)

Note that the y position is subtracted from the origin so that positive values are above the x axis and negative values below. Also note that the product of the field value and the scale must be explicitly cast to int before adding the origin offset.

o Write a method dotSelected() which, given a point, will return the lowest dot index within 2 pixels of the point, if any, and -1 otherwise.

You will need to use the abs() method of class Math:

int abs(int val)

// returns the absolute value of val

// e.g., Math.abs(-5) returns 5

Also, you can get the size of the cache arrays by using

sourceDomain.dataSize();

See hint 3 if you need help.

o Add a call to dotSelected() in handleSelection(). For the moment, write the result of the test to standard output.

o Build and test your program.

Stage 3 Updating the starfield and the list and record views.

o TradeViewer is the main coordinator for all its constituent panels. We shall leave to it the responsibility for updating the panels. So, the strategy is:

The overall communication will look like this:

Note: methods not yet implemented are shown in bold.

o The StarFieldView does not hold a reference to either the tradeviewer or even to its parent, starFieldPanel. Add a reference to the starFieldPanel in class StarFieldView and initialise it in the StarFieldView constructor.

o Create the missing methods from the diagram above, viz,

// just call tradeViewer.handleSelection()

See hint 4 for help.

TradeViewer already calls update() to update the recordPanel and the starFieldView (indirectly via its Panel).

Note: we could have had the starFieldView change its selected dot itself, instead of asking tradeViewer to do it. However, by leaving the job with tradeViewer, we maintain consistency in that the same method is used whether the selection is made in via the list or the starfield.

o Build and test your program.

 

 

Hints

Hint 1: MouseButtonHandler

class MouseButtonHandler extends MouseAdapter {

StarFieldView starfield;

public MouseButtonHandler(StarFieldView sfv) {

starfield = sfv;

}

public void mouseReleased(MouseEvent me) {

starfield.handleSelection(new Point(me.getX(), me.getY());

}

}

 

Hint 2: Stubbed handleSelection in StarFieldView

public void handleSelection(Point pt) {

System.out.println("button release at " + pt.getX() + ", " + pt.getY());

}

Hint 3: dotSelected() in StarFieldView

int dotSelected(Point p) {

int found = -1;

int max = sourceDomain.dataSize();

int i = 0;

while ((i < max) && (found == -1) )

if ( (Math.abs(pt.getX()-(axisOrigin.getX() + (int)(cacheX[i] *scale))) <=2 ) && (Math.abs(pt.getY()-(axisOrigin.getY()-(int)(cacheY[i] *scale))) <=2) )

found = i;

else

i++;

return found;

}

Hint 4: handleSelection() in StarFieldPanel

public void handleSelection(int index) {

application.handleSelection(index);

}