Programming UI Matrix for best performance

Discussion in 'Java' started by Don Osburn, Aug 11, 2003.

  1. Don Osburn

    Don Osburn Guest

    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

    Don Osburn, Aug 11, 2003
    #1
    1. Advertising

  2. Don Osburn wrote:
    > 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
    John C. Bollinger, Aug 12, 2003
    #2
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Michael Bader
    Replies:
    11
    Views:
    12,046
    Michael Bader
    Mar 3, 2004
  2. lvcargnini

    Matrix composed by two matrix

    lvcargnini, Jul 4, 2006, in forum: VHDL
    Replies:
    3
    Views:
    2,671
    Jonathan Bromley
    Jul 5, 2006
  3. Holgerson

    Matrix*Vector and Vector*Matrix

    Holgerson, Oct 25, 2007, in forum: C++
    Replies:
    3
    Views:
    408
    Holgerson
    Oct 26, 2007
  4. Terry Reedy
    Replies:
    0
    Views:
    555
    Terry Reedy
    Apr 2, 2009
  5. Robert Kern
    Replies:
    0
    Views:
    594
    Robert Kern
    Apr 2, 2009
Loading...

Share This Page