repaint() not being called
My program seems to refuse to repaint(), When I call repaint in order to refresh the image that is being displayed the paint method isn't called, even though the paintIcon is changed to the correct image and its calling reDrawImage(). The only time that paint is called is when the frame is hidden and brought back up. I've shown this to my programming teacher and he's baffled. Any help is greatly appreciated, and If you would like to see all the classes involved please ask. Thanks.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.imageio.*;
import java.util.*;
import javax.swing.border.EtchedBorder;
publicclass AddSpeciesextends JFrameimplements ActionListener
{
JLabel cNameLabel, sNameLabel, imageFileLabel, notesLabel, nAreaLabel;
JTextField cName, sName, imageFile, nArea;
JTextArea notes;
JButton addDone, fileBrowse, quit;
ImageIcon picture;
public AddSpecies()
{
System.out.println("AddSpecies()");
this.setResizable(false);
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
setSize(540,400);
setLocation(200,150);
setTitle("Add Species to Database");
getContentPane().setLayout(null);
cNameLabel =new JLabel("Enter Common Name:");
cNameLabel.setBounds(20,20,225,20);
cNameLabel.setForeground(new Color(50,100,200));
getContentPane().add(cNameLabel);
cName =new JTextField(25);
cName.setBounds(20,40,150,20);
cName.setBackground(Color.white);
getContentPane().add(cName);
sNameLabel =new JLabel("Enter Scientific Name:");
sNameLabel.setBounds(20,60,225,20);
sNameLabel.setForeground(new Color(50,100,200));
getContentPane().add(sNameLabel);
sName =new JTextField(25);
sName.setBounds(20,80,150,20);
sName.setBackground(Color.white);
getContentPane().add(sName);
nAreaLabel =new JLabel("Enter Native Area:");
nAreaLabel.setBounds(20,100,225,20);
nAreaLabel.setForeground(new Color(50,100,200));
getContentPane().add(nAreaLabel);
nArea =new JTextField(25);
nArea.setBounds(20,120,150,20);
nArea.setBackground(Color.white);
getContentPane().add(nArea);
imageFileLabel =new JLabel("Enter Location of image file:");
imageFileLabel.setBounds(20,140,225,20);
imageFileLabel.setForeground(new Color(50,100,200));
getContentPane().add(imageFileLabel);
fileBrowse =new JButton("Browse");
fileBrowse.setForeground(new Color(50,100,200));
fileBrowse.setBounds(20,164,100,20);
getContentPane().add(fileBrowse);
fileBrowse.addActionListener(this);
imageFile =new JTextField("Images\\zebra.jpg",25);
imageFile.setBounds(20,192,150,20);
imageFile.setBackground(Color.white);
getContentPane().add(imageFile);
imageFile.addActionListener(this);
notesLabel =new JLabel("Enter Notes:");
notesLabel.setBounds(20,220,225,20);
notesLabel.setForeground(new Color(50,100,200));
getContentPane().add(notesLabel);
notes =new JTextArea("");
notes.setBounds(20,240,260,120);
notes.setEditable(true);
notes.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
notes.setLineWrap(true);
notes.setWrapStyleWord(true);
notes.setForeground(new Color(50,100,200));
getContentPane().add(notes);
addDone =new JButton("Add Species");
addDone.setForeground(new Color(50,100,200));
addDone.setBounds(320,260,150,40);
getContentPane().add(addDone);
addDone.addActionListener(this);
quit =new JButton("Cancel");
quit.setForeground(new Color(50,100,200));
quit.setBounds(320,310,150,40);
getContentPane().add(quit);
quit.addActionListener(this);
reDrawImage();
setVisible(true);
}
publicvoid actionPerformed (ActionEvent evt)
{
System.out.println("actionPerformed()");
if(evt.getSource() == fileBrowse)
{
JFileChooser chooser =new JFileChooser("Images\\");
chooser.showOpenDialog(this);
try{
imageFile.setText(chooser.getSelectedFile().getPath());
}catch(Exception e){System.out.println("Cancel");}
reDrawImage();
}
else
if(evt.getSource() == addDone)
{
String wds[] =new String[200];
int index=0;
try{
BufferedReader reader =new BufferedReader (new FileReader("data\\database.txt"));
String input ="";
while( (input = reader.readLine()) !=null){
wds[index++] = input;}
reader.close();
int highNum=0;
String testStr="";
for(int j=0;j<index;j++)
{
for(int k=0; k><10;k++)
{
if(wds[j].charAt(k) == 9)
break;
testStr += wds[j].charAt(k);
}
if(Integer.parseInt(testStr)>highNum)
{
highNum = Integer.parseInt(testStr);
}
testStr="";
}
System.out.println("high: "+highNum);
BufferedWriter out =new BufferedWriter(new FileWriter("data\\database.txt"));
out.write(wds[0]);
for(int i=1; i<index; i++){
out.newLine();
out.write(wds[i]);}
out.newLine();
out.write((highNum+1)+"\t"+cName.getText()+"\t"+sName.getText()+"\t"+imageFile.getText()+"\t"+notes.getText()+"\t"+nArea.getText());
out.close();
}catch(Exception e){System.out.println(""+e);}
Species s =new Species();
this.dispose();
}
else
if(evt.getSource() == imageFile)
{
reDrawImage();
}
if(evt.getSource() == quit)
{
Species s =new Species();
this.dispose();
}
}
publicvoid reDrawImage()
{
try{
Image img1 = ImageIO.read(new File(imageFile.getText()));
Image img2 = img1.getScaledInstance(304,220,1);
picture =new ImageIcon(img2);
System.out.println("reDrawImage: "+picture);
}
catch(Exception e)
{JOptionPane.showMessageDialog(this,"Invalid Image","Error",JOptionPane.ERROR_MESSAGE);}
repaint();
}
publicvoid paint(Graphics g)
{
super.paint(g);
System.out.println("paint img:"+picture);
try{
picture.paintIcon(this,g,200,40);
}catch(NullPointerException e){System.out.println("Paint:NPE");}
}
}
>
# 1
Your code worked okay from the start when I ran it as–posted.
You can try this. Suggestions sprinkled throughout.
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.*;
import javax.imageio.*;
import javax.swing.*;
import javax.swing.border.EtchedBorder;
public class AS extends JFrame implements ActionListener
{
JLabel cNameLabel, sNameLabel, imageFileLabel, notesLabel, nAreaLabel;
JTextField cName, sName, imageFile, nArea;
JTextArea notes;
JButton addDone, fileBrowse, quit;
//ImageIcon picture;
BufferedImage image;
public AS()
{
System.out.println("AddSpecies()");
this.setResizable(false);
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
setSize(540,400);
setLocation(200,150);
setTitle("Add Species to Database");
getContentPane().setLayout(null);
cNameLabel = new JLabel("Enter Common Name:");
cNameLabel.setBounds(20,20,225,20);
cNameLabel.setForeground(new Color(50,100,200));
getContentPane().add(cNameLabel);
cName = new JTextField(25);
cName.setBounds(20,40,150,20);
cName.setBackground(Color.white);
getContentPane().add(cName);
sNameLabel = new JLabel("Enter Scientific Name:");
sNameLabel.setBounds(20,60,225,20);
sNameLabel.setForeground(new Color(50,100,200));
getContentPane().add(sNameLabel);
sName = new JTextField(25);
sName.setBounds(20,80,150,20);
sName.setBackground(Color.white);
getContentPane().add(sName);
nAreaLabel = new JLabel("Enter Native Area:");
nAreaLabel.setBounds(20,100,225,20);
nAreaLabel.setForeground(new Color(50,100,200));
getContentPane().add(nAreaLabel);
nArea = new JTextField(25);
nArea.setBounds(20,120,150,20);
nArea.setBackground(Color.white);
getContentPane().add(nArea);
imageFileLabel = new JLabel("Enter Location of image file:");
imageFileLabel.setBounds(20,140,225,20);
imageFileLabel.setForeground(new Color(50,100,200));
getContentPane().add(imageFileLabel);
fileBrowse = new JButton("Browse");
fileBrowse.setForeground(new Color(50,100,200));
fileBrowse.setBounds(20,164,100,20);
getContentPane().add(fileBrowse);
fileBrowse.addActionListener(this);
imageFile = new JTextField("Images\\zebra.jpg",25);
//"images/cougar.jpg");
imageFile.setBounds(20,192,150,20);
imageFile.setBackground(Color.white);
getContentPane().add(imageFile);
imageFile.addActionListener(this);
notesLabel = new JLabel("Enter Notes:");
notesLabel.setBounds(20,220,225,20);
notesLabel.setForeground(new Color(50,100,200));
getContentPane().add(notesLabel);
notes = new JTextArea("");
notes.setBounds(20,240,260,120);
notes.setEditable(true);
notes.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
notes.setLineWrap(true);
notes.setWrapStyleWord(true);
notes.setForeground(new Color(50,100,200));
getContentPane().add(notes);
addDone = new JButton("Add Species");
addDone.setForeground(new Color(50,100,200));
addDone.setBounds(320,260,150,40);
getContentPane().add(addDone);
addDone.addActionListener(this);
quit = new JButton("Cancel");
quit.setForeground(new Color(50,100,200));
quit.setBounds(320,310,150,40);
getContentPane().add(quit);
quit.addActionListener(this);
reDrawImage();
setVisible(true);
}
public void actionPerformed (ActionEvent evt)
{
System.out.println("actionPerformed()");
if(evt.getSource() == fileBrowse)
{
// You can make this a member variable if you like.
// We are inside java, so you can use "Images/".
JFileChooser chooser = new JFileChooser("Images\\");
chooser.showOpenDialog(this);
try{
imageFile.setText(chooser.getSelectedFile().getPath());
}catch(Exception e){System.out.println("Cancel");}
reDrawImage();
}
else
if(evt.getSource() == addDone)
{
}
else
if(evt.getSource() == imageFile)
{
reDrawImage();
}
if(evt.getSource() == quit)
{
Species s = new Species();
this.dispose();
}
}
public void reDrawImage()
{
try{
//Image img1 = ImageIO.read(new File(imageFile.getText()));
// getScaledInstance is slow and antique.
// Also, this way of scaling will produce
// distorted images. Using ImageIcon to
// draw images is not so good. Better to
// use a BufferedImage as a member variable.
//Image img2 = img1.getScaledInstance(304,220,1);
//picture = new ImageIcon(img2);
//System.out.println("reDrawImage: "+picture);
// Let's try this instead. It's generally much faster.
BufferedImage img1 = ImageIO.read(new File(imageFile.getText()));
image = scaleToSize(img1, 304, 220);
}
catch(Exception e)
{JOptionPane.showMessageDialog(this,"Invalid Image","Error",
JOptionPane.ERROR_MESSAGE);}
repaint();
}
private BufferedImage scaleToSize(BufferedImage src, int w, int h)
{
BufferedImage scaled = new BufferedImage(w, h, src.getType());
Graphics2D g2 = scaled.createGraphics();
// This helps for expanding small images.
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC);
// since we are scaling to fit the image into the available
// space (instead of filling the space) there will likely
// be some background showing which is black by default.
// To fill in the background you can specify a color or
// use the default background retrieved from the UI. You
// could also call getBackground on the contentPane.
g2.setBackground(UIManager.getColor("Panel.background"));
//getContentPane().getBackground());
g2.clearRect(0,0,w,h);
// Calculate scale to fit image within (w, h).
double xScale = (double)w / src.getWidth();
double yScale = (double)h / src.getHeight();
double scale = Math.min(xScale, yScale);
// Center src image as we scale it on-the-fly into scaled.
double x = (w - scale*src.getWidth())/2;
double y = (h - scale*src.getHeight())/2;
AffineTransform at = AffineTransform.getTranslateInstance(x, y);
at.scale(scale, scale);
g2.drawRenderedImage(src, at);
g2.dispose();
return scaled;
}
public void paint(Graphics g)
{
super.paint(g);
//System.out.println("paint img:"+picture);
// Probably not needed since ImageIO throws exceptions for you.
try{
//picture.paintIcon(this,g,200,40);
g.drawImage(image, 200, 40, this);
}catch(NullPointerException e){System.out.println("Paint:NPE");}
}
public static void main(String[] args) { new AS(); }
}
class Species {
Species() {
JOptionPane.showMessageDialog(null, "that's all folks!", "",
JOptionPane.PLAIN_MESSAGE);
System.exit(0);
}
}