Programming UI Matrix for best performance

D

Don Osburn

Am looking for some help on how to program a specific user interface (UI).
I need to create a large matrix (n x m) of rectangles, and give the user
the ability to click and drag the mouse over them to select them. When a
user clicks/drags over a rectangle, it should repaint itself a different
color and store the fact that it was selected. Since the matrix is rather
large, I want to put it in a JScrollPane so that the user can scroll over
the entire matrix.

So far I have come up with two ways to do this, and one of them was
horrendously slow. (It is unusable.) I would like some advice on how to do
this to get the best UI performance so that I have a really slick and fast
UI. The two methods I have tried are:

1. Create a new class called MyRectangle that extends java.awt.Rectangle.
This is a pretty simple class that just adds a couple of instance vars to
keep track of if it has been selected or not, and what color it should paint
itself and its border. Next, I create a class called MyJPanel that extends
JPanel. MyJPanel contains an (n x m) array of MyRectangles and overloads
the paintComponent() method to paint them all on the panel. MyJPanel also
implements the mouseListener(s) so it can tell when someone has
pressed/clicked/ or dragged over it. When it receives a MouseEvent, it
finds the correct MyRectangle (by comparing the point returned on MyJPanel),
sets that MyRectangle's instance vars appropriately, and then calls
UpdateUI().

Here is the problem with this design. That array of MyRectangles looks at
least like this:
MyRectangle myRectangleArray[][] = new MyRectangle[50][200];

So, in the paintComponent() method of the MyJPanel, it has to iterate
through the 50 * 200 rectangles in order to know how to paint each one on
the screen. Not to mention the fact that at each one it has to do a
comparision to determine how to set Graphics2D.setPaint( Color.XX ); for
that specific rectangle. As mentioned, I have implemented this and it is
EXCRUTIATINGLY SLOW. So, I moved on to....

2. Create a new class called MyJButton that extends javax.swing.JButton.
MyJButton contains instance vars to note if it is selected or not, what its
background color should be. MyJButton also implements the mouseListener(s)
and handles all the MouseEvents themselves. Now, instead of having MyJPanel
overload paintComponent() and handle all that myself, I just have it contain
an (n x m) array of MyJButtons and just add them to the panel using a
GridLayout. The problem here is that the mouseDragged event doesn't work
quite the way I'd like. In order to implement mouseDragged, I have to
create an interface and have each MyJButton callback to its container
MyJPanel to tell it when / where the dragging started and stopped so that
MyJPanel can update all the other MyJButtons. However, the performance
seems to be much better and the user can click all over without causing the
screen to lock up doing repaints.

Ok, here's my question. DOES ANYONE HAVE A BETTER WAY OF DOING THIS???

What I want is to present the user with an (n x m) matrix of rectangles
(inside a scrollable pane). This matrix will be LARGE, like at least 50 x
200 and would prefer to go up to 70 x 500 or more. The size of each
rectangle will need to be definable as the number of columns gets larger, I
will need to make the size of the individual rectangles smaller. The user
should be able to click and drag over these rectangles, and the program
should store which row / column was selected, and should then paint those
selected rectangles on the screen in a different (configurable) color.

Can anyone offer any help?

Don Osburn
(e-mail address removed)
(e-mail address removed)
 
J

John C. Bollinger

Don said:
Am looking for some help on how to program a specific user interface (UI).
I need to create a large matrix (n x m) of rectangles, and give the user
the ability to click and drag the mouse over them to select them. When a
user clicks/drags over a rectangle, it should repaint itself a different
color and store the fact that it was selected. Since the matrix is rather
large, I want to put it in a JScrollPane so that the user can scroll over
the entire matrix.

So far I have come up with two ways to do this, and one of them was
horrendously slow. (It is unusable.) I would like some advice on how to do
this to get the best UI performance so that I have a really slick and fast
UI. The two methods I have tried are:

1. Create a new class called MyRectangle that extends java.awt.Rectangle.
This is a pretty simple class that just adds a couple of instance vars to
keep track of if it has been selected or not, and what color it should paint
itself and its border. Next, I create a class called MyJPanel that extends
JPanel. MyJPanel contains an (n x m) array of MyRectangles and overloads
the paintComponent() method to paint them all on the panel. MyJPanel also
implements the mouseListener(s) so it can tell when someone has
pressed/clicked/ or dragged over it. When it receives a MouseEvent, it
finds the correct MyRectangle (by comparing the point returned on MyJPanel),
sets that MyRectangle's instance vars appropriately, and then calls
UpdateUI().

Huh? You should be calling one of the repaint() methods, not
updateUI(). In fact, repaint(Rectange) might be perfect for you.
Here is the problem with this design. That array of MyRectangles looks at
least like this:
MyRectangle myRectangleArray[][] = new MyRectangle[50][200];

So, in the paintComponent() method of the MyJPanel, it has to iterate
through the 50 * 200 rectangles in order to know how to paint each one on
the screen. Not to mention the fact that at each one it has to do a
comparision to determine how to set Graphics2D.setPaint( Color.XX ); for
that specific rectangle. As mentioned, I have implemented this and it is
EXCRUTIATINGLY SLOW. So, I moved on to....

2. Create a new class called MyJButton that extends javax.swing.JButton.
MyJButton contains instance vars to note if it is selected or not, what its
background color should be. MyJButton also implements the mouseListener(s)
and handles all the MouseEvents themselves. Now, instead of having MyJPanel
overload paintComponent() and handle all that myself, I just have it contain
an (n x m) array of MyJButtons and just add them to the panel using a
GridLayout. The problem here is that the mouseDragged event doesn't work
quite the way I'd like. In order to implement mouseDragged, I have to
create an interface and have each MyJButton callback to its container
MyJPanel to tell it when / where the dragging started and stopped so that
MyJPanel can update all the other MyJButtons. However, the performance
seems to be much better and the user can click all over without causing the
screen to lock up doing repaints.

Ok, here's my question. DOES ANYONE HAVE A BETTER WAY OF DOING THIS???

What I want is to present the user with an (n x m) matrix of rectangles
(inside a scrollable pane). This matrix will be LARGE, like at least 50 x
200 and would prefer to go up to 70 x 500 or more. The size of each
rectangle will need to be definable as the number of columns gets larger, I
will need to make the size of the individual rectangles smaller. The user
should be able to click and drag over these rectangles, and the program
should store which row / column was selected, and should then paint those
selected rectangles on the screen in a different (configurable) color.

Can anyone offer any help?

You should be able to make method (1) perform significantly better by
managing which rectangles actually need to be painted. To begin, take a
look at this page from the Java Tutorial:
http://java.sun.com/docs/books/tutorial/uiswing/painting/overview.html

The key pieces are these:

Whenever possible (especially with mouse drag operations) update the UI
by use of the one- or four-argument version of the repaint() method.
The more closely you can specify the required repaint area the better
the painting performance will be.

In paintComponent() use Graphics.getClipBounds() to obtain the area that
actually needs to be painted, then use your knowledge of the size and
layout of the rectangles to paint only those that need to be painted.

That would be much cleaner than the JButton version, and should be
comparable if not noticably superior in performance.


John Bollinger
(e-mail address removed)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top