Reputation: 411
I always look for questions in StackOverflow, but I do not seem to find an answer for this one.
I'm using Java to create an application with Swing forms. I have added a Canvas AWT component to a JFrame.
I preload an image from the DB, draw it into the canvas and then set the JFrame as visible.
Problem is the image will flash: It is shown for some miliseconds, then, the JFrame is repainted.
Why does this happen? I tried to override the paint()
method in the JFrame as well, and draw the image each time paint
is called. But it is not working this way.
Button Frame
(main frame) - (replace final String imgPath
with a sample image of your choice)
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class ButtonFrame extends javax.swing.JFrame {
public ButtonFrame() {
initComponents();
}
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jButton1 = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jButton1.setText("View Image");
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(59, 59, 59)
.addComponent(jButton1)
.addContainerGap(44, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(54, 54, 54)
.addComponent(jButton1)
.addContainerGap(70, Short.MAX_VALUE))
);
pack();
}// </editor-fold>
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
final String imgPath = "/tmp/img.png";
try
{
BufferedImage bi = ImageIO.read(new File(imgPath));
ImgFrame imgFrame = new ImgFrame();
imgFrame.setImage(bi);
imgFrame.setVisible(true);
// imgFrame.setImageInCanvas(bi);
} catch (IOException x) {}
}
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(ButtonFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(ButtonFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(ButtonFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(ButtonFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new ButtonFrame().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JButton jButton1;
// End of variables declaration
}
ImageFrame
(frame where the image is shown)
import java.awt.Graphics;
import java.awt.image.BufferedImage;
public class ImgFrame extends javax.swing.JFrame {
BufferedImage bi;
public ImgFrame() {
initComponents();
}
public void setImage(BufferedImage bi)
{
this.bi = bi;
}
public void setImageInCanvas(BufferedImage bi)
{
canvas1.getGraphics().drawImage(bi, 0, 0, null);
}
@Override
public void paint(Graphics g)
{
setImageInCanvas(bi);
}
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
canvas1 = new java.awt.Canvas();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(canvas1, javax.swing.GroupLayout.PREFERRED_SIZE, 266, javax.swing.GroupLayout.PREFERRED_SIZE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(canvas1, javax.swing.GroupLayout.PREFERRED_SIZE, 155, javax.swing.GroupLayout.PREFERRED_SIZE)
);
pack();
}// </editor-fold>
// Variables declaration - do not modify
private java.awt.Canvas canvas1;
// End of variables declaration
}
Video example: https://drive.google.com/file/d/0B53gOV_BD8J8Mm10LW5CN2E3M2M/view
The problem has been solved:
I have overriden the paint
method in JFrame like this:
@Override
public void paint(Graphics g)
{
g.drawImage(bi, 0, 0, null);
}
Where bi
is a BufferedImage.
Then, the Canvas was overlapping the Form, since it was set to fit the JFrame, and the image was not displaying. I have removed it (the AWT Canvas) and the Image is now displaying in the background.
Thank you very much!
Special thanks to Dodd10x and Andrew Thompson.
Upvotes: 0
Views: 539
Reputation: 3349
Do not mix Swing and AWT. First thing to change is switch from Canvas to JComponent if you are displaying in a JFrame.
Upvotes: 3