Using a JPanel extension class to set a background
Asked Answered
P

2

1

In my Main I want to create a JFrame, then I want to create a BackgroundPanel and I want to add this one in the JFrame.

This is Main class:

public class Main {

    public static void main(String args[]) {
        Frame frame = new Frame();
        BackgroundPanel back = new BackgroundPanel();
        frame.getContentPane().add(back);
        frame.setSize(400, 287);
        frame.setVisible(true);
    }
}

This is BackgroundPanel class:

import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class BackgroundPanel extends JPanel {

    private Image img;

    public BackgroundPanel() {
        img = Toolkit.getDefaultToolkit().createImage(getClass().getResource("sfondo.png"));
        loadImage(img);
    }

    private void loadImage(Image img) {
        try {
            MediaTracker track = new MediaTracker(this);
            track.addImage(img, 0);
            track.waitForID(0);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        setOpaque(false);
        g.drawImage(img, 0, 0, null);
    }
}

And the JFrame is a normal JFrame class.

When I execute it, there are no errors, simply it put out a normal JFrame without background. Help me Please!

@nIcEcOw I used the code in the first answear to print my image on a JPanel. But when I execute it, there's an error in output.

this the error:

Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: input == null!
    at javax.imageio.ImageIO.read(ImageIO.java:1388)
    at paintingexample.CustomPanel.<init>(PaintingExample.java:82)
    at paintingexample.PaintingExample.displayGUI(PaintingExample.java:28)
    at paintingexample.PaintingExample.access$000(PaintingExample.java:19)
    at paintingexample.PaintingExample$1.run(PaintingExample.java:42)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:312)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:733)
    at java.awt.EventQueue.access$200(EventQueue.java:103)
    at java.awt.EventQueue$3.run(EventQueue.java:694)
    at java.awt.EventQueue$3.run(EventQueue.java:692)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:703)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
BUILD SUCCESSFUL (total time: 1 second)

I'm confused about project's structure. I noticed that i can't put the package folder in bin directory; this creates a conflict in my ide. I dont understand how i can put the java files in src and the package folder in bin directory. My java files are in package folder..how I can do this?

I'm using NetBeans IDE 8.0

I red NetBean's image importing tutorial, and there also tips me to create another package to import images within. Now I the code is:

import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;

public class PaintingExample {

    private ImagePanel imagePanel;

    public void displayGUI() {
        JFrame frame = new JFrame("Swing Worker Example");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        JPanel contentPane = new JPanel();
        imagePanel = new ImagePanel();      
        contentPane.add(imagePanel);

        frame.setContentPane(contentPane);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                new PaintingExample().displayGUI();
            }
        };
        EventQueue.invokeLater(runnable);
    }
}


class ImagePanel extends JPanel {

    private ImageIcon imageIcon;

    public ImagePanel() {
        imageIcon = new javax.swing.ImageIcon(getClass().getResource("/org/me/myimageapp/newpackage/Schema elettrico divella rev 2014-Model.jpg"));
    }

    @Override
    public Dimension getPreferredSize() {
        return (imageIcon == null ? new Dimension(100, 100): new Dimension(
                                                   imageIcon.getIconWidth(), imageIcon.getIconHeight()));
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(imageIcon.getImage(), 0, 0, this);
    }
}

I changed :

imageIcon = new ImageIcon(ImageIO.read(ImagePanel.class.getResource(
                                                    "/images/aeroplaneright.jpeg")));

in

imageIcon = new javax.swing.ImageIcon(getClass().getResource("/org/me/myimageapp/newpackage/aeroplaneright.jpg"));

@nIcEcOw you're my hero! :D Now all works fine. But just another thing:

now I'm using your ImagePanel class in a bigger project. I'm also using part of SwingTest code in the Main class of project to create a frame of a customized jframe class (FramePrincipale) with ImagePanel background. When I execute I'm obtaining a frame with my bakcground, but there aren't the other swing elements (labels,textfields..) that are part of my customized jframe. How can I fix this?

this is Principale class (main project class):

import java.awt.EventQueue;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.JPanel;


public class Principale {


    private ImagePanel imagePanel;
    private static FramePrincipale frame = new FramePrincipale();

    private void displayGUI() throws IOException {





        JPanel contentPane = new JPanel();
        imagePanel = new ImagePanel();      
        contentPane.add(imagePanel);

        frame.setContentPane(contentPane);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }



    public static void main(String[] args) {



        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                try {
                    new Principale().displayGUI();
                } catch (IOException ex) {
                    Logger.getLogger(Principale.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        };
        EventQueue.invokeLater(runnable);

  while (true) {


      frame.scriviLabel();


    }     

    }

}

FramePrincipale is a JFrame Form that is in the same project.

@nIcEcOw: Now it works! Thank You for all man! :-)

Permutation answered 17/7, 2014 at 15:39 Comment(13)
This is a Swing application so use a JFrame not a Frame.Plucky
Hopefully this answer and this answer, might be able to help you in your endeavour :-)Sage
@gesualdo: Please edit your question(do not put thingies in comment, it is hard to read here), with how you trying to access the image. Some idea bout the directory structure of the project too, will be helpful.Sage
where is ImageIO used in your code?Dogma
Click on read more to find the project structure as well.Dogma
@gesualdo: Here find this project structure, that I just created for this example. Else the link in my answer, regarding how to add images to some IDEs like NetBeans, Eclipse or IntelliJ IDEA, clearly states, how to go about it :-)Sage
@Dogma the error that i posted is generated from a code that i get from nice cow answer (up)Permutation
please share project structure? where is sfondo.png and this java file is present.Dogma
please share what is at line paintingexample.CustomPanel.<init>(PaintingExample.java:82) Share PaintingExample file as well.Dogma
@gesualdo: Which IDE is being used by you?Sage
@gesualdo: For my example to work on NetBeans, you simply need to create a new package, along with the present package that you have. Name this new package images and paste the image in it, by right clicking it. Then run the program again, that is it. NetBeans Docs. I am downloading NetBeans will give you a step by step work around soon :-)Sage
I doubt this worked for you, because of the package path that you using. You never did mentioned what is the package for the PaintingExample class. Someone came to my house, now I am installing and will create one gif for you to look at. If PaintingExample has package org.me.myapp then inside getResource("/newpackage/Schema elettrico divella rev 2014-Model.jpg") this will go.Sage
@gesualdo: I have updated my answer, with what I did in NetBeans and it is working like a charm :-) Do see if this helps you somewhat in any way, I be happy to know that :-)Sage
S
4

Considering that the directory structure for the project looks like this:

 Since Images are Application Resources,
 it's always best to access them in the
 form of a URL, instead of File, as you are doing.
 Uncomment this below line and watch this answer
 of mine, as to HOW TO ADD IMAGES TO THE PROJECT
 https://mcmap.net/q/279686/-loading-resources-like-images-while-running-project-distributed-as-jar-archive
 In order to access images with getClass().getResource(path)
 here your Directory structure has to be like this
                 Project
                    |
         ------------------------
         |                      |
        bin                    src
         |                      |
     ---------             .java files             
     |       |                   
  package   images(folder)
  ( or              |
   .class        404error.jpg
   files, if
   no package
   exists.)

PaintingExample

import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;

public class PaintingExample {

    private ImagePanel imagePanel;

    private void displayGUI() {
        JFrame frame = new JFrame("Swing Worker Example");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        JPanel contentPane = new JPanel();
        imagePanel = new ImagePanel();      
        contentPane.add(imagePanel);

        frame.setContentPane(contentPane);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                new PaintingExample().displayGUI();
            }
        };
        EventQueue.invokeLater(runnable);
    }
}

class ImagePanel extends JPanel {

    private ImageIcon imageIcon;

    public ImagePanel() {
        try {
            imageIcon = new ImageIcon(ImageIO.read(ImagePanel.class.getResource(
                                                    "/images/aeroplaneright.jpeg")));
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

    @Override
    public Dimension getPreferredSize() {
        return (imageIcon == null ? new Dimension(100, 100): new Dimension(
                                                   imageIcon.getIconWidth(), imageIcon.getIconHeight()));
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(imageIcon.getImage(), 0, 0, this);
    }
}

OUTPUT:

PAINTINGEXAMPLE

In response to edit

As mentioned in the edit, that you using some Integrated Development Environment - IDE, for creating the application. Since, every IDE use to work in a bit different way. Please see, if this post, regarding how to add images to Java Project, helps you in that direction.

EDIT for NetBeans

  1. Create a Java Project
  2. Provide any Project Name. In my case I am using SwingTest, as shown in image
  3. Provide Package Name. In my case I am using swingtest, as shown in image
  4. Right-click Source Packages. New -> Java Package. Under New Java Package window, provide Package Name, in my case I am using images
  5. Copy the image from the File System and move back to NetBeans IDE, Right-click the images package so created and paste the image(inside NetBeans IDE)
  6. Create two classes by Right-clicking swingtest package, New -> Java Class, the contents of which are shown below

That is it, you are done now. Run the Project, and you be able to see the images. Do watch the use of getClass().getResource(...) thingy:

imageIcon = new ImageIcon(ImageIO.read(ImagePanel.class.getResource(
                                                    "/images/loyalperson.jpg")));

SwingTest

package swingtest;

import java.awt.*;
import javax.swing.*;

public class SwingTest {

    private ImagePanel imagePanel;

    private void displayGUI() {
        JFrame frame = new JFrame("Swing Worker Example");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        JPanel contentPane = new JPanel();
        imagePanel = new ImagePanel();      
        contentPane.add(imagePanel);

        frame.setContentPane(contentPane);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                new SwingTest().displayGUI();
            }
        };
        EventQueue.invokeLater(runnable);
    }
}

ImagePanel

package swingtest;

import java.awt.Dimension;
import java.awt.Graphics;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JPanel;

public class ImagePanel extends JPanel {

    private ImageIcon imageIcon;

    public ImagePanel() {
        try {
            imageIcon = new ImageIcon(ImageIO.read(
                         ImagePanel.class.getResource("/images/loyalperson.jpg")));
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

    @Override
    public Dimension getPreferredSize() {
        return (imageIcon == null ? new Dimension(100, 100): new Dimension(
                         imageIcon.getIconWidth(),imageIcon.getIconHeight()));
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(imageIcon.getImage(), 0, 0, this);
    }
}

Steps with Images

ProjectImages

Here is the link to loyalperson.jpg

EDIT 2:

For adding a customized component, do this:

  1. Go to Tools -> Palette -> Swing/AWT Components
  2. Click on New Categroy. in New Palette Category window, provide New Category Name
  3. Click OK and Close the Palette Manager window
  4. Open ImagePanel in editor, now select Source View, now select Tools -> Add to Palette and select the Category just created by you.
  5. That I guess, will do. Now the component can be seen on the Palette window, under the Category chosen previously, which one can drag/drop on to the JFrame/JComponent.
Sage answered 18/7, 2014 at 9:35 Comment(5)
@peeskillet: Haha, THANK YOU and KEEP SMILING :-) Just downloaded NetBeans to answer this question, else I keep myself away from IDEs, though if need be, I do use Eclipse or IntelliJ IDEA :-)Sage
I like Netbeans because everything's so "vanilla-centric". Great support for plain Java EE. I only use Eclipse for it's Spring supportIgniter
@gesualdo: I am not sure, how you created that JFrame, in the first place. Though if you have added components to a JPanel first and then added to FramePrincipale JFrame, then I guess you simply have to override getPreferredSize() and paintComponent(...) of that JPanel, otherwise you might have to rebuild it again, it seems like :(Sage
This is one of the greatest clear answers I have met on StackOverflow. Thanks a lotWatermelon
@DenisOluka: Glad the answer did help you in some way :-) Thank you very much and KEEP SMILING :-)Sage
M
-1

if extends JPanel why not Override paint method in JPanel and then play with graphics ex: g.drawImage(img, x, y, width, height, ImageObserver)?

Masera answered 17/7, 2014 at 16:18 Comment(4)
sorry, but i didn't understand the second part: what I play with? What I have to change in g.drawImage(img,0,0,null); ??Permutation
what i mean is you must draw image with the graphics for example BufferedImage img = ImageIO.read(new File("image.png")); g.drawImage(img, xPosition, yPosition, width, height, imageObserver);Masera
-1 why not Override paint method in JPanel custom painting is done by overriding the paintComponent() method when using Swing.Plucky
@A48: Please have a look at Performing Custom Painting and especially the first question of Solving Common Painting Problems. This will tell, as to why paint() method is not appropriate for this task, and why one should override paintComponent() instead. Override paint() method only in situation where one wants to change the state of the graphics object, and wants child components to reciprocate to that change, though not otherwise :-)Sage

© 2022 - 2024 — McMap. All rights reserved.