|
Bookshelf Index
Chapter 18, Tables
By Matthew Robinson and Pavel Vorobiev
Introduction |
Download Chapter 18| Download Chapter 22 << NEXT >>
Running the Code
Figure 18.2 shows StocksTable with custom
rendering in action. Note the correct usage of color and icons,
which
considerably enhances the visualization of our data.
Improving visual communication Tables can be data
intensive and consequently it can be very difficult for the
viewer to
quickly
pick out the important information. The table in fig 18.1
highlighted
this. In
fig 18.2, we are improving the visual communication with the
introduction of
visual layers. The icons in the first column quickly tell the
viewer
whether a
price is rising or falling. This is visually re-inforced with the
red
and
green
introduced on the change columns.
Red particularly is a very
strong color. By introducing red and green only on the change
columns
and not
across the entire row, we avoid the danger of the red becoming
overpowering.
If
we had introduced red and green across the full width of the
table,
the colors
may have become intrusive and impaired the visual
communication.
18.4 Stocks Table: part III - Data Formatting
To further enhance the presentation
of our stock data, in this section we wll take into account that
actual stock
prices (at least on NYSE and NASDAQ) are expressed in fractions
of 32,
not in
decimals. Another issue that we will deal with is the volume of
trade,
which
can reach hundreds of millions of dollars. Volume is not
immediately
legible
without separating thousands and millions places with commas.

Click Figure 18.3 for full-scale image. JTable
with
custom
number formatting cell renderer to display fractions and
comma-delimited
numbers.
The Code: StocksTable.java
see \Chapter18\3
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.io.*;
import java.text.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import javax.swing.table.*;
// Unchanged code from
//section 18.3
class Fraction
{
public int m_whole;
public int m_nom;
public int m_den;
public Fraction(double value) {
int sign = value <0 ? -1 : 1;
value = Math.abs(value);
m_whole = (int)value;
m_den = 32;
m_nom = (int)((value-m_whole)*m_den);
while (m_nom!=0 && m_nom%2==0) {
m_nom /= 2;
m_den /= 2;
}
if (m_whole==0)
m_nom *= sign;
else
m_whole *= sign;
}
public double doubleValue() {
return (double)m_whole +
(double)m_nom/m_den;
}
public String toString() {
if (m_nom==0)
return ""+m_whole;
else if (m_whole==0)
return ""+m_nom+"/"+m_den;
else
return ""+m_whole+"
"+m_nom+"/"+m_den;
}
}
class SmartLong
{
protected static
NumberFormat FORMAT;
static {
FORMAT =
NumberFormat.getInstance();
FORMAT.setGroupingUsed(true);
}
public long m_value;
public SmartLong(long value)
{ m_value = value; }
public long longValue()
{ return m_value; }
public String toString()
{ return FORMAT.format(
m_value); }
}
class ColorData
{
public ColorData(Fraction data) {
m_color = data.doubleValue()
>= 0 ? GREEN : RED;
m_data = data;
}
// Unchanged code from section 18.3
}
class StockData
{
public static ImageIcon ICON_UP =
new ImageIcon("ArrUp.gif");
public static ImageIcon ICON_DOWN =
new ImageIcon("ArrDown.gif");
public static ImageIcon ICON_BLANK =
new ImageIcon("blank.gif");
public IconData m_symbol;
public String m_name;
public Fraction m_last;
public Fraction m_open;
public ColorData m_change;
public ColorData m_changePr;
public SmartLong m_volume;
public StockData(String symbol,
String name,
double last,
double open, double change,
double changePr, long volume) {
m_symbol =
new IconData(getIcon(
change), symbol);
m_name = name;
m_last = new Fraction(last);
m_open = new Fraction(open);
m_change = new ColorData(
new Fraction(change));
m_changePr = new ColorData(
new Double(changePr));
m_volume = new SmartLong(volume);
}
// Unchanged code from section 18.3
}
|
Understanding the Code
Class Fraction
This new data class encapsulates
fractions with denominator 32 (or in a reduced form). Three
instance
variables
represent the whole number, numerator, and denominator of the
fraction. The
only constructor takes a double parameter and carefully extracts
these
values,
performing numerator and denominator reduction, if possible. Note
that
negative
absolute values are taken into account.
Method doubleValue() performs the opposite task: it
converts the fraction into a double
value. Method toString()
forms a String
representation of the fraction.
Note that a zero whole number or a
zero nominator are omitted to avoid unseemly output like "0
1/2" or
"12 0/32".
Class SmartLong
This class encapsulates long values. The only
constructor takes a long
as parameter and stores it in the m_value instance
variable. The
real purpose of creating this
class is the overridden toString()
method, which inserts commas separating thousands, millions, etc.
places. For
this purpose we use the java.text.NumberFormat
class. An instance of this class is created as a static variable,
and
formatting values using NumberFormat's
format() method
couldn't be easier.
Note:
SmartLong cannot extend Long (although
it would be natural), because java.lang.Long
is a final class.
Note: We could use the different approach of just
formatting
the
initial
contents of our table's cells into text strings and perating on
them
without
introducing new data classes. This approach, however, is not
desirable from a
design point of view, as it strips the data of its true nature:
numbers.
Class ColorData
This class requires a new constructor
to cooperate with the new Fraction
data type. This third constructor takes a Fraction
instance as
parameter and uses its color
attribute in the same way it did previously: green for positive
values, and
red
for negative values.
Class StockData
This class uses new data types for
its instance variables. The list of instance variables now looks
like
the
following:
|
Field
| Type
| Data object
| Description |
m_symbol |
IconData |
String |
Stock
symbol (NYSE or NASDAQ) |
m_name |
String |
N/A |
Company
name |
m_last | Fraction |
N/A |
The price of the last trade |
m_open | Fraction |
N/A |
The price
at
the beginning of the trade day |
m_change | ColorData | Fraction |
Absolute change in price |
m_changePr | ColorData | Double
|
Percent change in price |
m_volume | SmartLong | N/A |
Day's
volume
of trade (in $) for this stock |
The StockData constructor is modified accordingly.
Meanwhile the parameters in the StockData
constructor have not changed, so
there is no need to make any changes to the data model class
using
StockData.
Running the Code
Figure 18.3 shows StocksTable in action with
number formatting. Presented this way, our data looks much more
familiar to
most of those who follow the stock trade on a regular basis.
Talking the Users language In this example, we have
changed the rendering of the stock prices into fractions rather
than
decimals.
This is a good example of providing better visual communication
by
speaking
the
same language as the viewers. In the North American stock
markets,
prices are
quoted in fractional amounts of dollars rather than dollars and
cents.
Switching to this type of display helps the application to
communicate
more
quickly and more influentially to the viewer, improving
usability.
Page
1
2
3
4
5
6
7
8
9
10
11
<< NEXT >>
Download Chapter 18| Download Chapter 22]
|