Hey there,
I have the following code:

public void paintComponent(Graphics d){
                  int gjeresia_e_kornizes = 800;
                  int lartesia_e_kornizes = 800;
                  d.setColor(Color.white);
                  d.fillRect(0, 0, gjeresia_e_kornizes, lartesia_e_kornizes);
                  d.setColor(Color.red);
                                    
						d.fillOval(105, 70, 250, 350);
try { Thread.sleep(2000); }
catch (InterruptedException e) { }
                  d.setColor(Color.blue);
                  d.fillOval(150, 170, 50, 20);
                  d.fillOval(270, 170, 50, 20);
try { Thread.sleep(2000); }
catch (InterruptedException e) { }
                  d.setColor(Color.black);
                  d.drawLine(235, 200, 210, 310);
try { Thread.sleep(2000); 
catch (InterruptedException e) { }
                  d.drawLine(210, 310, 270, 310);
                  d.drawLine(270, 310, 250, 290);}
try { Thread.sleep(2000); 
catch (InterruptedException e) { }
                  d.drawLine(205, 340, 275, 340);
                  d.drawLine(205, 340, 190, 360);
                  d.drawLine(275, 340, 290, 360);
                }

I expect the code above to draw lines and ovals with 2-second interuptions for each time the try-catch part appears in the code. However, what I get is:
first the frame object appears with nothing in it (i see my jGRASP behind the frame). after 8 seconds (that is four times two seconds - 2 seconds for each try-catch), all the lines and ovals, which make a face, appear at once.

I am really curious to know if there is any way to reach the effect I am aming at using this kind of simple code. besides, there is a similar assignment in a java book. the only difference is the types of shapes I am supposed to use. thanks in advance for any eventual help.

Recommended Answers

All 12 Replies

RepaintManager.currentManager(your_component).setDoubleBufferingEnabled(false);

What you are doing is OK for a quick demo, but it doesn't really make sense. paintComponent() should paint the current state of the component, not produce animation. Depending on how you construct this, you may also get two or more queued paint events at startup, so the painting sequence may happen multiple times.

thanks for the reply, it is ok as it does compile, but it won't output what i intend it to output. i hope you or someone else come up with the solution.

thanks for the reply, it is ok as it does compile, but it won't output what i intend it to output. i hope you or someone else come up with the solution.

I just did. Turn off the double buffering as I showed, before you make the frame visible.

pardon me. thanks a lot.

i guess i should just add that line, but where? inside the main method, inside paintComponent? where?

thanks again. it worked. i inserted your line inside my constructor method. thanks a lot.

Ibarowsky, I've got another question: is it ok if i ask you?

I have the two following classes (copied from the book i study with):

import java.awt.*; import javax.swing.*;
/** MyWriter creates a graphics window that displays a sentence */
public class MyWriter extends JPanel
{ private int width; // the frame's width
private int height; // the frame's height
private String sentence = ""; // holds the sentence to be displayed
private int x_position; // x-position of sentence
private int y_position; // y-position of sentence
/** Constructor MyWriter creates the Panel
* @param w - the window's width
* @param h - the window's height */
public MyWriter(int w, int h)
{ 
RepaintManager.currentManager(this).setDoubleBufferingEnabled(false);
width = w;
height = h;
x_position = width / 5; // set the sentence's position
y_position = height / 2;
JFrame my_frame = new JFrame();
my_frame.getContentPane().add(this);
my_frame.setTitle("MyWriter");
my_frame.setSize(width, height);
my_frame.setVisible(true);
}
/** paintComponent paints the panel
* @param g - the ``graphics pen'' that draws the items */
public void paintComponent(Graphics g)
{ g.setColor(Color.red);
g.drawString(sentence, x_position, y_position);
}
/** writeSentence displays a new string in the window
* @param s - the sentence to be displayed */
public void writeSentence(String s)
{ sentence = s;
this.repaint(); // indirectly forces paintComponent to execute
}
/** positionSentence redisplays the existing sentence in a new position
* @param new x - the new horizontal starting position
* @param new y - the new vertical starting position */
public void positionSentence(int new_x, int new_y)
{ x_position = new_x;
y_position = new_y;
this.writeSentence(sentence); // force a rewrite of the existing sentence
}
}

import javax.swing.*;
public class AnotherExample
{ public static void main(String[] args)
{ MyWriter writer = new MyWriter(300, 200);
String s = JOptionPane.showInputDialog("Please type some text:");
writer.writeSentence(s);
s = JOptionPane.showInputDialog("Try it again:");
writer.writeSentence(s);
writer.positionSentence(0, 190);
writer.writeSentence(s + s);
}
}

last two lines in my AnotherExample class won't do anything. jGRASP does not report any eror. eclipse does report but i do not understand it very well. what would be the mistake?

warm regards!

You should not call any swing/AWT methods or constructors outside the EDT. If you do, anything can happen. It might work, it might crash (throw an unexpected runtime exception - I call that "crashing" for Java), it might crash one time in a hundred, it might work every time under one Java version and crash every time under another, it might do weird things you never expected. That includes creation of components and calling setVisible(). This means that all your gui calls should happen in listeners, overridden gui class methods, or be wrapped in SwingUtilities.invokeLater() or similar.

All the gui stuff is handled in an event queue. Things like repaints don't happen when you call them, they get put on a queue and happen as soon as the event processing system gets to them. Multiple repaints may be combined into one event, and events may not happen in the order you expect. So you can't just make a bunch of gui calls and expect the results to happen visibly in sequence.

You are setting the size of the frame, not the MyWriter. The second piece of text is below the end of the window. Usually you don't set the size of a frame, you let it take it's natural size by calling pack(), and set preferred sizes for components that don't already have a meaningful preferred size.

Creating the frame from within the MyWriter constructor is bad form. The constructor should build the MyWriter, not act as an extension to main().

At the end I'm not sure if you are trying to paint two pieces of text at once, or in sequence. If at once, then MyWriter needs to store and paint both, if in sequence, then you need a timer to separate the events in time.

You aren't following Sun's (Oracle's?) coding conventions. Most Java code approximately follows those conventions, so it's a good habit to get into.

Assuming you wanted the two strings at the end to be shown in sequence rather than at the same time, this could work:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class DrawTest {

   private static MyWriter writer;

   public static void main(String[] args) {
      SwingUtilities.invokeLater(
            new Runnable() {
               public void run() {
                  start();
               }
            });
   }


   public static void start() {
      writer = new MyWriter(300, 200);
      JFrame frame = new JFrame();
      frame.getContentPane().add(writer);
      frame.setTitle("MyWriter");
      frame.pack();
      frame.setVisible(true);
   
      String s = JOptionPane.showInputDialog("Please type some text:");
      writer.writeSentence(s);
      // There is no true guarantee that the text will show up
      // before the "try it again" modal dialog. If you just
      // use an invokeLater() here, it will probably work always
      // on Java versions with double buffering, and almost always
      // otherwise. In theory, even adding a time delay does not
      // guarantee it, but with a quarter second delay, it is going
      // to work unless something else very odd is happening.
      ActionListener timerAction = 
         new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
               step2();
            }
         };
      Timer t = new Timer(250, timerAction);
      t.setRepeats(false);
      t.start();
   }
   
  
   public static void step2() {
      final String s = JOptionPane.showInputDialog("Try it again:");
      writer.writeSentence(s);
      ActionListener timerAction = 
         new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
               writer.positionSentence(0, 190);
               writer.writeSentence(s + s);
            }
         };
      Timer t = new Timer(2000, timerAction);
      t.setRepeats(false);
      t.start();
   }
}


class MyWriter extends JPanel {
   private String sentence = "";
   private int xPosition;
   private int yPosition;
   
   public MyWriter(int w, int h) {
      setPreferredSize(new Dimension(w, h));
      xPosition = w / 5;
      yPosition = h / 2;
   }

   public void paintComponent(Graphics g) {
      super.paintComponent(g);
      g.setColor(Color.red);
      g.drawString(sentence, xPosition, yPosition);
   }

   public void writeSentence(String s) {
      sentence = s;
      this.repaint();
   }

   public void positionSentence(int newX, int newY) {
      xPosition = newX;
      yPosition = newY;
      this.writeSentence(sentence);
   }
}

thanks a lot man. i'm impressed AND confused. the book i am studying with insists that it has a well thought programing style, yet it does have multiple mistakes. and now that you solved my problems, i trust you more than the book i am reading.. i was just wondering if you could direct me on what book should i study with for a better understanding of java.
thanks again.

I haven't done much evaluation of Java textbooks or "for dummies" books and can't really give a recommendation.

Some authors feel that when teaching the basics, it is OK to "simplify" the rest at the expense of good style or bullet-proof code, which I think is a mistake. One way of teaching with the "fun" of graphics but without exposing the learner to the complexities of AWT/swing is to provide a simplified graphics library, and some textbooks do take that approach (their own graphics libraries are usually somewhat buggy, but that is a separate issue). Another way is to tell the learner "just type this part in and don't worry about what it means yet".

I see. thanks a lot man. I appreciate your help very much. Have fun and take care.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.