Java GUI coding, help?

Get help on programming - C++, Java, Delphi, etc.
Post Reply
Richard_
Registered User
Posts: 2295
Joined: 18 May 2003, 02:00
Location: Durban, South Africa

Java GUI coding, help?

Post by Richard_ »

Hopefully someone can help me with this... Instead of drawing a pretty graphic to screen, this program draws a vast expanse of nothing. I'm guessing it has something to do with the way I've coded the paintComponent methods, but for the life of me I can't see where the problem is.


Code: Select all

import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class FrontEnd extends JFrame {

	public FrontEnd() {
		Image miniIcon = new ImageIcon("icon.gif").getImage();
		this.setIconImage(miniIcon);
		MainScreen mainScr = new MainScreen();
		add(mainScr);
		mainScr.repaint();
	}

	public static void main(String args[]) {
		FrontEnd window = new FrontEnd();
		window.setTitle("Blah");
		window.setSize(400, 400);
		window.setLocationRelativeTo(null);
		window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		window.setVisible(true);

	}

}

//#####################################################################################################

class MainScreen extends JPanel {

	public MainScreen() {

		JPanel p = new JPanel(new GridLayout(1, 1, 0, 0));
		System.out.println("Container panel created");

		Image image = new ImageIcon("icon.gif").getImage();
		ImageViewer viewPanel = new ImageViewer(image);
		add(viewPanel);
		viewPanel.repaint();		

	}
	
	protected void paintComponent(Graphics g) {
		ImageViewer.repaint();
		System.out.println("The main screen is redrawn");
	}
	
	
}

//#####################################################################################################

class ImageViewer extends JPanel {

	private java.awt.Image image;

	public ImageViewer(Image image) {
		this.image = image;	
		System.out.println("ImageViewer constructor called");
	}

	protected void paintComponent(Graphics g) {
		super.paintComponent(g);
		g.drawImage(image, 0, 0, this);
		System.out.println("ImageViewer paintComponent called");
	}

}
User avatar
rustypup
Registered User
Posts: 8872
Joined: 13 Dec 2004, 02:00
Location: nullus pixius demonica
Contact:

Re: Java GUI coding, help?

Post by rustypup »

1) split your code base into distinct class files - until you've had the pleasure of maintaining an app with 5 or more classes buried in the same file you won't get this, but it can be an unpleasant experience...

2) Is this a current snapshot of your functioning code? just glancing through, this line:

Code: Select all

ImageViewer.repaint();
says "shouldn't compile" as the repaint() method in the ImageViewer class isn't static.

Code: Select all

ImageViewer myView = new ImageViewer(someIMage);
myView.repaint(); //referenced
will work...

3) are you sure you're loading a valid image? blank images render as blanks as well... to perform a sanity check on your rendering code, draw a string as well..

Code: Select all

protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      g.drawImage(image, 0, 0, this); 
      java.awt.Color oldColor = g.getColor();
      g.setColor(java.awt.Color.RED);
      g.drawString("RENDERING IN SHARED CONTEXT", 10, 10);
      g.setColor(oldColor); //revert - g is shared by all components!
      System.out.println("ImageViewer paintComponent called");
}
if the string renders, your image hasn't been loaded..

4) another funny is the MainScreen constructor:

Code: Select all

JPanel p = new JPanel(new GridLayout(1, 1, 0, 0));
p isn't used anywhere... try:

Code: Select all

super(new GridLayout(1, 1, 0, 0));
instead - although this should have zero effect on the rendering issue...

now, the important bit... as far as possible, never use the shared graphical context. the reasons are numerous, (the biggie being that changes made to the shared context effect all rendering ops thereafter unless reverted), but the most important is that by casting to a new Graphics2D context, you have access to all the snazzy stuff, (AlphaComposite, RenderingHint, scaling, etc, etc) - it's as easy as pi:

Code: Select all

protected void paintComponent(Graphics g) {
      super.paintComponent(g);
       
      Graphics2D g2d = (Graphics2D)g.create(); //unique context
      
      //turn on some quality hints
      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
      g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
      //AlphaComposite manages transparancy - 0=invisible, 1=opaque
      g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.8f));
      
      AffineTransform tform = g2d.getTransform();//store current instance
      
      //insert scale transform
      double xScale = (this.getSize().getWidth()/image.getWidth(this));
      double yScale = (this.getSize().getHeight()/image.getHeight(this));
      g2d.scale(xScale, yScale);
      
      g2d.drawImage(image, 0, 0, this);
      
      //revert scale transform
      g2d.setTransform(tform);
      
      g2d.setColor(java.awt.Color.RED);
      g2d.drawString("RENDERING IN DISTINCT CONTEXT", 10, 10);
      System.out.println("ImageViewer paintComponent called");
      g2d.dispose();//NB!
}

when using a new context, always be sure to dispose of it. while handy for image processing, those left in ram can pile up quite quickly... once the rendering has finished, there is no good reason to hang onto it.
Most people would sooner die than think; in fact, they do so - Bertrand Russel
Post Reply