why the painted content flash and disappear?

I try to run a simple code example from java almanac site but the painted content just flash and disappear. Can any people help to find the reason? Thanks in advance.

Below are the code:

package font;

import java.text.AttributedString;

import java.awt.*;

import java.awt.font.LineBreakMeasurer;

import java.awt.font.TextLayout;

import javax.swing.*;

publicclass DrawParagraphDemoextends JPanel{

public DrawParagraphDemo(){

this.setPreferredSize(new Dimension(500,500));

}

/**

* Create the GUI and show it. For thread safety,

* this method should be invoked from the

* event-dispatching thread.

*/

privatestaticvoid createAndShowGUI(){

//Make sure we have nice window decorations.

JFrame.setDefaultLookAndFeelDecorated(true);

//Create and set up the window.

JFrame frame =new JFrame("Demo");

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

//Create and set up the content pane.

DrawParagraphDemo demo =new DrawParagraphDemo();

frame.setContentPane(demo);

//Display the window.

frame.pack();

frame.setVisible(true);

demo.drawParagraph((Graphics2D) demo.getGraphics(),"One line of test string", 400);

}

publicvoid drawParagraph(Graphics2D g, String paragraph,float width){

LineBreakMeasurer linebreaker =new LineBreakMeasurer(

new AttributedString(paragraph).getIterator(), g.getFontRenderContext());

float y = 0.0f;

while (linebreaker.getPosition() < paragraph.length()){

TextLayout tl = linebreaker.nextLayout(width);

System.out.println(tl);

y += tl.getAscent();

tl.draw(g, 0, y);

y += tl.getDescent() + tl.getLeading();

}

}

publicstaticvoid main(String[] args){

//Schedule a job for the event-dispatching thread:

//creating and showing this application's GUI.

javax.swing.SwingUtilities.invokeLater(new Runnable(){

publicvoid run(){

createAndShowGUI();

}

});

}

}

[3825 byte] By [jiazhimia] at [2007-10-2 15:29:41]
# 1

IMHO, it is obvious - your drawing is overwritten on repaint. You should preserve the drawing and provide it on paint() callbacks. Therefore, it is suggested by AWT designers that you override the paint(graphics) method and draw on the graphic context submitted to it.

Alternatively, you may go on and use a buffered canvas written by me in http://forum.java.sun.com/thread.jspa?threadID=716141 In this approach you extend the panel of your frame and render once into a buffer. The buffer will be used to replicate the damaged regions.

Here is a version of your program which works:

class ImageComponent extends Component {

Image image;

//ImageComponent (Image image) {this.image = image;}

//void setImage(Image image) {this.image = image;}

//ImageComponent () {}

public Graphics getGraphics() {

image = createVolatileImage(getWidth(), getHeight());

return image.getGraphics();

}

public void paint(Graphics g) {

Rectangle clip = g.getClipBounds();

int x1 = clip.x;

int x2 = clip.x+clip.width;

int y1 = clip.y;

int y2 = clip.y+clip.height;

g.drawImage(image, x1, y1, x2, y2, x1, y1, x2, y2, null);

}

}

public class DrawParagraphDemo extends JPanel {

private static void createAndShowGUI() {

JFrame.setDefaultLookAndFeelDecorated(true);

JFrame frame = new JFrame("Demo");

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

//Create and set up the content pane.

//DrawParagraphDemo demo = new DrawParagraphDemo();

//frame.setContentPane(demo);

Component demo = new ImageComponent();

demo.setPreferredSize(new Dimension(100, 100));

frame.getContentPane().add(demo);

//Display the window.

frame.pack();

frame.setVisible(true);

drawParagraph((Graphics2D) demo.getGraphics(), "One line of test string", 400);

}

}

I would recommend to extend a canvas panel from the ImageComponent presented at that topic though; since, it handles resizing. Or just override the paint(g) of the JPanel ancestor, as your painting is trivial (fast).

valjoka at 2007-7-13 14:52:44 > top of Java-index,Desktop,Core GUI APIs...
# 2

You need to add the custom painting to the paintComponent() method of the component:

protected void paintComponent(Graphics g)

{

super.paintComponent(g); // this paints the background

drawParagraph((Graphics2D)g, "One line of test string", 400);

}

Get rid of the code after setVisible( true );

camickra at 2007-7-13 14:52:44 > top of Java-index,Desktop,Core GUI APIs...
# 3
Thanks very much for the help. It works. Thanks to valjok as well for the suggestion
jiazhimia at 2007-7-13 14:52:44 > top of Java-index,Desktop,Core GUI APIs...
# 4

Hi i have similar problem and i have followed Camickr's suggestion but it looks like my image was still being painted over here's my code

import java.io.*;

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

import javax.swing.filechooser.*;

/*

* FileChooserDemo2.java is a 1.4 application that requires these files:

*ImageFileView.java

*ImageFilter.java

*ImagePreview.java

*Utils.java

*images/jpgIcon.gif (required by ImageFileView.java)

*images/gifIcon.gif (required by ImageFileView.java)

*images/tiffIcon.gif (required by ImageFileView.java)

*images/pngIcon.png (required by ImageFileView.java)

*/

public class Asst4 extends JPanel

implements ActionListener {

static private String newline = "\n";

private JTextArea log;

private JFileChooser fc;

private JPanel display,button;

JButton load,grey,color;

private Image image;

static JComponent newContentPane;

public Asst4() {

super(new BorderLayout());

//Create the log first, because the action listener

//needs to refer to it.

display=new JPanel();

display.setOpaque(true);

button=new JPanel();

load=new JButton("Load Image");

grey=new JButton("Greyscale Image");

color=new JButton("Color Image");

load.addActionListener(this);

//display.setBackground(Color.BLACK);

//System.out.println("displayable: "+isDisplayable()+" visible: "+isVisible()+" valid: "+isValid());

//System.out.println("displayable: "+display.isDisplayable()+" visible: "+display.isVisible()+" valid: "+display.isValid());

display.setSize(500,500);

button.add(load, BorderLayout.WEST);

button.add(grey, BorderLayout.CENTER);

button.add(color, BorderLayout.EAST);

add(button,BorderLayout.NORTH);

add(display,BorderLayout.CENTER);

setVisible(true);

}

public void actionPerformed(ActionEvent e) {

//Set up the file chooser.

if (fc == null) {

fc = new JFileChooser();

//Add a custom file filter and disable the default

//(Accept All) file filter.

fc.addChoosableFileFilter(new ImageFilter());

fc.setAcceptAllFileFilterUsed(false);

//Add custom icons for file types.

fc.setFileView(new ImageFileView());

//Add the preview pane.

fc.setAccessory(new ImagePreview(fc));

}

//Show it.

int returnVal = fc.showDialog(Asst4.this,"Load Image");

//Process the results.

if (returnVal == JFileChooser.APPROVE_OPTION) {

File file = fc.getSelectedFile();

Toolkit toolkit = Toolkit.getDefaultToolkit();

image = toolkit.getImage(file.getAbsolutePath());

MediaTracker mediaTracker = new MediaTracker(this);

mediaTracker.addImage(image,0);

try {

mediaTracker.waitForID(0);

} catch (InterruptedException ie) {

System.err.println(ie);

System.exit(1);

}

} else {

System.out.println("Loading cancelled by user." );

}

fc.setSelectedFile(null);

}

protected void paintComponent(Graphics g)

{

super.paintComponent(g); // this paints the background

if(image!=null)

drawImage(image);

}

private void drawImage(Image image){

Graphics2D g=(Graphics2D)display.getGraphics();

g.drawImage(image,0,0,null);

}

/**

* Create the GUI and show it. For thread safety,

* this method should be invoked from the

* event-dispatching thread.

*/

private static void createAndShowGUI() {

//Make sure we have nice window decorations.

JFrame.setDefaultLookAndFeelDecorated(true);

JDialog.setDefaultLookAndFeelDecorated(true);

//Create and set up the window.

JFrame frame = new JFrame("Compsci_375_Assignment_4");

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

//Create and set up the content pane.

newContentPane = new Asst4();

newContentPane.setOpaque(true); //content panes must be opaque

frame.setContentPane(newContentPane);

//Display the window.

frame.setBounds(50,50,500,500);

//frame.pack();

frame.setVisible(true);

}

public static void main(String[] args) {

//Schedule a job for the event-dispatching thread:

//creating and showing this application's GUI.

javax.swing.SwingUtilities.invokeLater(new Runnable() {

public void run() {

createAndShowGUI();

}

});

}

}

Can anyone tell me what's going on and also why if i pack the frame my display panel is disappear?

Thanks a lot

Cannabisa at 2007-7-13 14:52:44 > top of Java-index,Desktop,Core GUI APIs...