I'm studying java currently, and yet again I ran into a code in the book which doesn't wanna work and i can't figure out why. This code snippet is from Head First Java
import javax.swing.*;
import java.awt.*;
public class SimpleGui {
public static void main (String[] args){
JFrame frame = new JFrame();
DrawPanel button = new DrawPanel();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(button);
frame.setSize(300,300);
frame.setVisible(true);
}
}
import java.awt.*;
import java.lang.*;
public class DrawPanel extends JPanel {
private Image image;
public DrawPanel(){
image = new ImageIcon("cat2.jpg").getImage();
}
public void paintComponent(Graphics g){
g.drawImage(image,3,4,this);
}
}
the image is in the same directory where my class files are, and the image is not showing. What am i missing here?
1) In your paintComponent() you must to call super.paintComponent(g);. Read more about custom paintings.
2) instead of Image use BufferedImage, because Image its abstrat wrapper.
3)use ImageIO instead of creating Image like this new ImageIcon("cat2.jpg").getImage();
4)Use URL for resources inside your project.
I changed your code and it helps you:
class DrawPanel extends JPanel {
private BufferedImage image;
public DrawPanel() {
URL resource = getClass().getResource("cat2.jpg");
try {
image = ImageIO.read(resource);
} catch (IOException e) {
e.printStackTrace();
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 3, 4, this);
}
}
Related
I was trying out putting images in java. My end goal is to make a image I can control with arrow keys, but I can't seem to put an image in. I imported the image, and I have the name correct. I keep getting a null pointer exception.
code:
import java.awt.*;
import javax.swing.*;
public class Test extends JPanel {
public static ImageIcon image;
public void paintComponent(Graphics g) {
super.paintComponent(g);
image = new ImageIcon(getClass().getResource("rocketJava.jpg"));
image.paintIcon(this,g, 20, 20);
}
public static void main(String[] args) {
JFrame f= new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Test s = new Test();
f.add(s);
f.setSize(600,600);
f.setVisible(true);
}
}
The problem was just that I needed to move the picture file to the bin folder.
i am setting frame's background image when i run program my other components are invisible only image is visible in frame
class ImagePanel extends JComponent {
private Image image;
public ImagePanel(Image image) {
this.image = image;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, this);
}
In the main class I call the above class as shown below:
BufferedImage myImage = ImageIO.read(new File("cal.jpg"));
frame.setContentPane(new ImagePanel(myImage));
You have this code:
BufferedImage myImage = ImageIO.read(new File("cal.jpg"));
frame.setContentPane(new ImagePanel(myImage));
but you appear to be creating the ImagePanel instance inline, and don't appear to be adding any components to this ImagePanel instance, so I'm not surprised that you're not seeing any components. You also don't seem to be adding any components to it in the ImagePanel constructor.
Consider adding components to the ImagePanel class within its constructor, or in the class that uses it, create an ImagePanel instance, assign it to a variable, add components to it, and then place it into the JFrame's contentPane.
Side recommendations:
Consider getting your image as a Jar resource and not as a File, since likely you will Jar the classes at some point, and if you continue using File, your image might not be reachable.
Make sure to give your ImagePanel a decent layout manager. I believe that JComponents use null layouts by default, something that you don't want to use.
For example, this worked for me:
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Image;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;
public class TestImagePanel {
private static void createAndShowGui() {
String resource = "/imgFolder/PlanetEarth.jpg";
Image image = null;
try {
image = ImageIO.read(TestImagePanel.class.getResource(resource));
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
ImagePanel mainPanel = new ImagePanel(image);
mainPanel.setLayout(new FlowLayout());
mainPanel.add(new JButton("Fubars Rule!"));
JFrame frame = new JFrame("TestImagePanel");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
#SuppressWarnings("serial")
class ImagePanel extends JComponent {
private Image image;
public ImagePanel(Image image) {
this.image = image;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, this);
}
#Override
public Dimension getPreferredSize() {
Dimension superSize = super.getPreferredSize();
int w = image == null ? superSize.width : Math.max(superSize.width, image.getWidth(null));
int h = image == null ? superSize.height : Math.max(superSize.height, image.getHeight(null));
Dimension d = new Dimension(w, h);
return d;
}
}
and showed this GUI:
I have a JFrame. Within that JFrame I have a JLayeredPane layed out with an OverlayLayout that contains multiple Jpanels. in one of those JPanels I have a BufferedImage. When the JFrame is resized, the image quickly dissapears and dislocates, then it jumps back again, dislocates again, back again, and so on.
I have tried a lot of things to stop the image from flickering, but I don't know what the cause of the problem exactly is.
The Jpanel that holds the image contains the following code to render the image:
protected void paintComponent (Graphics g) {
super.paintComponent(g);
g.drawImage(myBufferedImage, 0, 0, 200, 200, null);
}
In trying to reconstruct and simplify the problem, I got a working version of what I wanted. I still don't know what the problem is with my other code though.
This is the code that works:
import java.awt.*;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;
public class Main {
public Main() {
// Create the JFrame:
JFrame window = new JFrame();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setSize(600, 400);
window.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
// Create the pane to hold layers:
JLayeredPane layers = new JLayeredPane();
layers.setLayout(new OverlayLayout(layers));
// Add two layers:
layers.add(new MyGraphics());
layers.add(new MyImage());
//
window.add(layers);
window.setVisible(true);
}
public static void main(String[] args) {
Main app = new Main();
}
public class MyImage extends JPanel {
public BufferedImage source;
public MyImage () {
this.setPreferredSize(new Dimension(180,180));
this.setLocation(0,0);
try {
this.source = ImageIO.read(new File("image.jpg"));
} catch (IOException ie) {
ie.printStackTrace();
}
}
protected void paintComponent (Graphics g) {
super.paintComponent(g);
g.drawImage(this.source, 0, 0, 180, 180, null);
}
}
public class MyGraphics extends JPanel {
public MyGraphics () {
this.setOpaque(false);
this.setPreferredSize(new Dimension(180,180));
this.setLocation(0,0);
}
protected void paintComponent (Graphics g) {
super.paintComponent(g);
g.drawLine(0, 0, 180, 180);
}
}
}
Try adding below line of code in constructor:
public FlickerDemo()
{
// No flickering during resize
System.setProperty("sun.awt.noerasebackground", "true");
}
I have been trying to upload an image onto a Java Applet Window but unfortunately it turns out to be blank..Here is the code i have written pls help!
import java.awt.*;
import javax.swing.*;
import java.awt.geom.*;
import java.net.*;
import java.util.*;
public class RandomImages extends JFrame
{
private Image img;
public void static main(String[] args)
{
new RandomImages();
}
public RandomImages()
{
super("Random Images");
setSize(450,450);
setVisible(true);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Toolkit tk=Toolkit.getDefaultToolkit();
img=tk.getImage(getURL("Your File Name"));
}
Below is the code that fetches the url of the filename looking for...
private URL getURL(String filename)
{
URL url=null;
try{
url=this.getClass().getResource(filename);
}
catch(Exception e) {}
return url;
}
AffineTransform id=new AffineTransform();
Code for paint component...
public void paint(Graphics g)
{
super.paint(g);
Graphics2D g2d=(Graphics2D)g;
AffineTransform trans=new AffineTransform();
Random rand=new Random();
g2d.setColor(Color.BLACK);
width=getSize().width;
height=getSize().height;
g2d.fillRect(0,0,width,height);
Loop for generating random ships on screen
for(int s=0;s<20;s++)
{
trans.setTransform(id);
trans.translate(rand.nextInt()%width,rand.nextInt()%height);
trans.rotate(Math.toRadians(360*rand.nextDouble()));
double scaled=rand.nextDouble()+1;
trans.scale(scaled,scaled);
trans.drawImage(img,trans,this);
}
}
}
1)Instead of using paint(Graphics g) for custom paintings you need to use paintComponent(Graphics arg0) of JComponent. For example draw image on JPanel and the add panel to your frame. Your JFrame isn't a JComponent.
2) As I know public static void main(String[] args) ;)
Read more about customPaintings.
The best way to add image in JFrame is to use JLabel.
Example:
JLabel image = new JLabel(new ImageIcon("Image.jpg"));
Now add this JLabel(image) into your JFrame.
public RandomImages()
{
super("Random Images");
setSize(450,450);
setVisible(true);
setLayout(new FlowLayout());//you have not used the Layout
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel image = new JLabel(new ImageIcon("Image.jpg"));
add(image);
}
Another way is to use drawImage() function of Graphics class in paint(Graphics g) function .
But you should use paintComponent against paint
I was trying to load a few images using java but it seems to be extremely slow, it's around 13 images I'm trying to get each of 9KB size.
Is it my code or is it java that's causing the problem. I can load all the images alot faster using the browser.
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.*;
import javax.imageio.ImageIO;
import javax.swing.*;
public class ImageSample {
static public void main(String args[]) throws Exception {
JFrame frame = new JFrame("Display image");
//Image url here
String url="";
JPanel panel = new testImage();
frame.add(panel);
frame.setSize(500, 500);
frame.setVisible(true);
frame.setExtendedState(frame.getExtendedState() | JFrame.MAXIMIZED_BOTH);
}
}
class testImage extends JPanel {
static Image image;
public void testImage(String url)
{
image = Resources.getImage(url);
}
public void paintComponent(Graphics g) {
g.drawImage(image, 0, 0, 40, 40, null);
}
}
class Resources
{
private static Resources myResource = new Resources();
// NOTE: there is no error checking here so if parameter is mistyped
// somewhere else in code, then this will probably throw a nullpointerexception
public static Image getImage(String name)
{
// TODO: Find out which way is better or preferred
URL url=null;
try {
url = new URL(name);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return Toolkit.getDefaultToolkit().getImage(url);
}
}
Thanks,
Sreejith
Your program isn't actually doing what you think it's doing because you have made some fundamental mistakes with your class and method names:
class testImage extends JPanel {
static Image image;
public void testImage(String url)
{
image = Resources.getImage(url);
}
public void paintComponent(Graphics g) {
g.drawImage(image, 0, 0, 40, 40, null);
}
}
The standard is that class names should always begin with an upper-case letter, and method names should begin with a lower-case letter to avoid confusion. Because you have confused the two, you didn't notice that the testImage(url) you declare in this class is a void method, not a constructor, even though the name is the same. Therefore, when you call JPanel panel = new testImage(); you are not calling that method - you're just calling the default empty constructor that every class is given if no constructors are declared in the code. Note also that you haven't used the variable url and that your field image should not be static.
To be honest, you're going about the whole thing the wrong way and should start again from scratch. Costis' solution looks good. You should definitely give ImageIcons a try because they remove the hard work of having to manually get the resource URL and render it.
Try this example with your image. It is not slow.
public class ImageLoad extends JFrame {
public ImageLoad() {
setSize(800, 800);
JPanel panel = new JPanel();
ImageIcon icon = new ImageIcon("singer.jpg");
JLabel label = new JLabel();
label.setIcon(icon);
panel.add(label);
add(panel);
}
public static void main(String[] args) {
new ImageLoad().setVisible(true);
}
}