Proper (vs. desirable) use of Graphics object

Discussion in 'Java' started by Wolfgang, Jan 23, 2004.

  1. Wolfgang

    Wolfgang Guest

    I have been using a JPanel with a graphics object to draw lines, etc.,
    like this:

    private class DrawingPanel extends JPanel {
    public void paint(Graphics g) {
    x = 10; y = 20;
    g.drawString("someText", x, y);
    // draw all my graphics here...
    // which means all calculation of coordinate
    // locations x and y has to go here.
    // I DON'T LIKE THAT, it causes clutter..
    }
    }

    The above way of drawing is somewhat alien to me. I think of drawing
    more like calculating some positions, than passing them to a drawing
    method in a drawing object (something like a DrawingPanel). Java's
    design of the Graphics class seems to disallow my preference, or I
    cannot see a way to perform my simple "classical" way of drawing,
    since I cannot pass coordinate locations for drawing into
    DrawingPanel.paint.

    Am I overlooking somthing simple here? If so, how can you do this?

    Thanks,
    Wolfgang
    Wolfgang, Jan 23, 2004
    #1
    1. Advertising

  2. Wolfgang

    Chris Smith Guest

    Wolfgang wrote:
    > I have been using a JPanel with a graphics object to draw lines, etc.,
    > like this:
    >
    > private class DrawingPanel extends JPanel {
    > public void paint(Graphics g) {
    > x = 10; y = 20;
    > g.drawString("someText", x, y);
    > // draw all my graphics here...
    > // which means all calculation of coordinate
    > // locations x and y has to go here.
    > // I DON'T LIKE THAT, it causes clutter..
    > }
    > }


    Okay...

    > The above way of drawing is somewhat alien to me. I think of drawing
    > more like calculating some positions, than passing them to a drawing
    > method in a drawing object (something like a DrawingPanel).


    I'm not entirely clear on what you mean, so I apologize in advance if
    I've misinterpreted you.

    DrawingPanel is not "a drawing object". It's a component. It just
    happens to have the behavior of drawing itself, among *many* other
    things. If you want to encapsulate the drawing process itself in an OO
    way, nothing is preventing you from doing so. Something like:

    interface Drawable
    {
    public void draw(Graphics g, int x, int y);
    }

    public class DrawableSprite implements Drawable
    {
    ...
    }

    public class DrawingPanel extends JPanel
    {
    public void paint(Graphics g)
    {
    int x = 10;
    int y = 20;

    new DrawableSprite().draw(g, x, y);
    }
    }

    Is that what you mean by "calculate some positions, then pass them to a
    drawing method in a drawing object"?

    > Java's design of the Graphics class seems to disallow my preference, or I
    > cannot see a way to perform my simple "classical" way of drawing,
    > since I cannot pass coordinate locations for drawing into
    > DrawingPanel.paint.


    You never call paint anyway, so no you can't pass coordinates for it.
    The paint method is responsible for painting the whole component, so it
    wouldn't really make sense for any coordinates to be passed. If I had a
    clearer idea of how you want this to work (or maybe what I wrote above
    is it?) then perhaps I could give a better answer.

    --
    www.designacourse.com
    The Easiest Way to Train Anyone... Anywhere.

    Chris Smith - Lead Software Developer/Technical Trainer
    MindIQ Corporation
    Chris Smith, Jan 23, 2004
    #2
    1. Advertising

  3. Wolfgang

    Ryan Stewart Guest

    "Wolfgang" <> wrote in message
    news:...
    > I have been using a JPanel with a graphics object to draw lines, etc.,
    > like this:
    >
    > private class DrawingPanel extends JPanel {
    > public void paint(Graphics g) {
    > x = 10; y = 20;
    > g.drawString("someText", x, y);
    > // draw all my graphics here...
    > // which means all calculation of coordinate
    > // locations x and y has to go here.
    > // I DON'T LIKE THAT, it causes clutter..
    > }
    > }
    >
    > The above way of drawing is somewhat alien to me. I think of drawing
    > more like calculating some positions, than passing them to a drawing
    > method in a drawing object (something like a DrawingPanel). Java's
    > design of the Graphics class seems to disallow my preference, or I
    > cannot see a way to perform my simple "classical" way of drawing,
    > since I cannot pass coordinate locations for drawing into
    > DrawingPanel.paint.
    >
    > Am I overlooking somthing simple here? If so, how can you do this?


    What Chris said plus: You can pass the Graphics objects to other objects to
    let them draw on it. Instead of having one long paint method (or render
    method as I usually make it--depends on what you're doing) to calculate and
    draw every little thing, go the OO route. Recently I've been working on
    coding a Scrabble applet. My main class is the applet. I have a Board class
    and a Rack class and a Tile class for all the letters that go on both the
    board and the rack. There's other stuff as well, but consider just those two
    for the moment. It's quite possible that there could be 50, 60, or more
    tiles out on the board and rack at the same time. Am I going to draw all
    those from the applet's paint method? Of course not. For drawing the board
    and rack:
    board.render(g);
    rack.render(g);

    where g is the Graphics object. Then the board draws itself and calls:
    tile.render(g);

    for each tile on it. The rack does the same thing. So each object is fully
    encapsulated, including its drawing routines. Only a tile knows what it
    looks like, and it's the only one that needs to.
    Ryan Stewart, Jan 23, 2004
    #3
  4. "Ryan Stewart" <> wrote in message
    news:...
    | "Wolfgang" <> wrote in message
    | news:...
    | > I have been using a JPanel with a graphics object to draw lines, etc.,
    | > like this:
    ...

    |.... You can pass the Graphics objects to other objects to
    | let them draw on it. Instead of having one long paint method (or render
    | method as I usually make it--depends on what you're doing) to calculate
    and
    | draw every little thing, go the OO route.

    Like this?
    http://www.physci.org/launcher.jsp#DoubleBufferedAnimateFrame

    5 Balls [line 157] are instantiated,
    and they draw themselves on the
    graphics object..[l. 175]

    --
    Andrew Thompson
    * http://www.PhySci.org/ PhySci software suite
    * http://www.1point1C.org/ 1.1C - Superluminal!
    * http://www.AThompson.info/andrew/ personal site
    Andrew Thompson, Jan 23, 2004
    #4
  5. Wolfgang

    Sudsy Guest

    Wolfgang wrote:
    <snip>
    > Am I overlooking somthing simple here? If so, how can you do this?


    What you appear to be missing is one of the basic concepts of OOP.
    You send messages to objects instructing them to perform operations.
    The results will not necessarily be returned to the invoker. You
    might be able to query the object for the results but it doesn't
    have to be a synchronous operation.

    From the javadocs for java.awt.Component:
    "A component is an object having a graphical representation that
    can be displayed on the screen and that can interact with the user."

    A component must know how to paint itself. IOW, I hand a component
    a Graphics context and it's up to that component to render itself
    into the drawing area.
    It sounds weird if you're not used to it but there are tons of on-
    line examples and tutorials which cover this. I'd start at Sun
    (<http://java.sun.com/docs/books/tutorial>).
    Sudsy, Jan 23, 2004
    #5
  6. Wolfgang

    Ryan Stewart Guest

    "Andrew Thompson" <> wrote in message
    news:XS1Qb.24404$...
    > "Ryan Stewart" <> wrote in message
    > news:...
    > | "Wolfgang" <> wrote in message
    > | news:...
    > | > I have been using a JPanel with a graphics object to draw lines, etc.,
    > | > like this:
    > ..
    >
    > |.... You can pass the Graphics objects to other objects to
    > | let them draw on it. Instead of having one long paint method (or render
    > | method as I usually make it--depends on what you're doing) to calculate
    > and
    > | draw every little thing, go the OO route.
    >
    > Like this?
    > http://www.physci.org/launcher.jsp#DoubleBufferedAnimateFrame
    >
    > 5 Balls [line 157] are instantiated,
    > and they draw themselves on the
    > graphics object..[l. 175]


    Yes, like that. :)
    Ryan Stewart, Jan 23, 2004
    #6
  7. Wolfgang wrote:
    > I have been using a JPanel with a graphics object to draw lines, etc.,
    > like this:
    >
    > private class DrawingPanel extends JPanel {
    > public void paint(Graphics g) {


    Use paintComponent(), not paint() in Swing.

    > The above way of drawing is somewhat alien to me. I think of drawing
    > more like calculating some positions, than passing them to a drawing
    > method in a drawing object (something like a DrawingPanel).


    Swing and AWT use something like a callback mechanism for painting. You
    are not supposed to "push" graphics to the output. Instead, you are
    supposed to wait until Swing/AWT ask you to draw something. When
    Swing/AWT see the need to (re)draw some parts, the paint[Component]()
    method is called. This is Swing's/AWT's way of asking you to paint
    something. "Don't call us, we will call you!".

    This mechanism is necessary due to the way some GUI systems work. In
    fact, it is a 1:1 mapping of how some of this systems work. E.g. X11
    without backing store enabled, doesn't save the parts of a window which
    are obscured by other windows. So once the obscured parts are supposed
    to become visible again (window is moved, or brought to the front), the
    GUI system has to ask the application to redraw that particular part of
    the window. This request from the GUI system ends up in some native JVM
    code, and is (via a few intermediate steps) transfered to a call of the
    paint[Component]() method.

    > Java's
    > design of the Graphics class seems to disallow my preference,


    They can't allow it. Otherwise it would be difficult or inefficient to
    support GUI systems that work as described above.

    > or I
    > cannot see a way to perform my simple "classical" way of drawing,
    > since I cannot pass coordinate locations for drawing into
    > DrawingPanel.paint.


    Solution A - Most suitable for vector graphics:

    Use a simple list, or whatever data structure suits your needs. In this
    list, store the drawing operations you would like to perform. Inside
    paintComponent() iterate through that list, and execute the operations.

    The java.awt.gemo objects are good candidates for being the elements of
    such a list.

    You can apply some optimization by observing the clipping region of the
    provided Graphics[2D] object, and having a data structure which allows
    for a quick decision if some geometry object falls completely outside of
    the clipping region.

    Solution B - Most suitable for bitmap graphics:

    Do all your drawing to a separate image, like a BufferedImage. Within
    the paint[Component]() method you just copy the relevant parts from your
    BufferedImage to the provided Graphics[2D]. Again, you can optimize by
    observing the clipping region. You might also turn of Swing's internal
    double-buffering, since you are now buffering yourself.

    In both cases, have an eye on threading issues.

    Things you shouldn't do:

    Don't use getGraphics() to obtain a Graphics[2D] object from outside of
    paint[Component](). getGraphics() can return null, but, more important,
    you drawings will be corrupted on GUI systems like the one described
    above, because you don't repaint it when the GUI system needs it.

    /Thomas
    Thomas Weidenfeller, Jan 23, 2004
    #7
  8. Wolfgang

    Dale King Guest

    "Wolfgang" <> wrote in message
    news:...
    > I have been using a JPanel with a graphics object to draw lines, etc.,
    > like this:
    >
    > private class DrawingPanel extends JPanel {
    > public void paint(Graphics g) {
    > x = 10; y = 20;
    > g.drawString("someText", x, y);
    > // draw all my graphics here...
    > // which means all calculation of coordinate
    > // locations x and y has to go here.
    > // I DON'T LIKE THAT, it causes clutter..
    > }
    > }
    >
    > The above way of drawing is somewhat alien to me. I think of drawing
    > more like calculating some positions, than passing them to a drawing
    > method in a drawing object (something like a DrawingPanel). Java's



    In addition to the other fine answers, on the subject of calculating
    coordinates that is not really the best way to do things in the world of
    Java2D.

    Say you had a shape that could move around in different positions and/or be
    different sizes. Instead of recalculating the coordinates of the points
    yourself, instead you have define how it is drawn using any convenient
    coordinate system for your purposes and then instead of modifying your
    values you tell the Graphics2D object (its a subclass of Graphics and that
    is what is actually passed to you) to change its coordinate system so that
    it will transform from your coordinates to the proper on-screen coordinate
    system using an AffineTransform.

    Instead of actually drawing complex shapes as a series of graphics
    primitives calls you can also define the shape using some implementation of
    java.awt.Shape.

    I suggest studying the Java 2D tutorial:
    http://java.sun.com/docs/books/tutorial/2d/index.html
    --
    Dale King
    Dale King, Jan 23, 2004
    #8
    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. Harald Kirsch

    Proper use of CharsetDecoder?

    Harald Kirsch, Aug 4, 2003, in forum: Java
    Replies:
    1
    Views:
    3,897
    Roedy Green
    Aug 5, 2003
  2. Razvan

    Proper use of assertions

    Razvan, Oct 7, 2004, in forum: Java
    Replies:
    5
    Views:
    470
  3. VisionSet
    Replies:
    7
    Views:
    462
    Michael Rauscher
    Nov 9, 2004
  4. Replies:
    4
    Views:
    339
    Jorgen Grahn
    May 27, 2010
  5. H. Wade Minter
    Replies:
    8
    Views:
    267
    Robin
    Apr 25, 2004
Loading...

Share This Page