my JFrame does not show the image of my JLabel.
The JFrame is shown but without the background image.
Expected result was: JFrame that shows a background image ("stelle.png").
I'd greatly appreciate if anyone could help :-)
Thanks!
Simon
public static void main(String[] args) {
new Gui();
}
public class Label extends JLabel {
#Override protected void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g.drawImage(Var.quadro, 0, 0, 800,600, null);
repaint();
}
}
public class Var {
static BufferedImage quadro;
public Var(){
try {
quadro = ImageIO.read(new File("quadri/stelle.png"));
}
catch (IOException e) {
e.printStackTrace();
System.out.println("No picture");
}
}
}
public class Gui {
public Gui(){
JFrame rahmen = new JFrame();
rahmen.setSize(800,600);
rahmen.setLocationRelativeTo(null);
rahmen.setVisible(true);
rahmen.setResizable(false);
rahmen.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
rahmen.setLayout(null);
rahmen.setTitle("Gioco");
Label label = new Label();
label.setVisible(true);
label.setBounds(0, 0, 800, 600);
rahmen.add(label);
}
}
Hi Have tweaked your solution below:
keep the package structure intact for the Test.java(can copy all code in it) and your pic stelle.png, refer the attached image below for this example to work seem less.
for incorporating changes in your own structure please keep image in a relative package quadri (refer the attached image, see how i kept it)
Please pay attention to my comments.
package com.demo.test.stack;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JLabel;
//Main class for executing test
public class Test {
public static void main(String[] args) {
new Gui();
}
}
//this is you extended Label class be careful while importing
class Label extends JLabel {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g.drawImage(Var.quadro, 0, 0, 800, 600, null);
repaint();
}
}
class Var {
static BufferedImage quadro;
//initializing the static variable in static class block (since you are using it directly)
static {
try {
//gettting the absolute path of your image
URL url = Test.class.getResource("quadri/stelle.png");
System.out.println(url.getPath());
quadro = ImageIO.read(new File(url.getPath()));
System.out.println("quadro: " + quadro);
} catch (IOException e) {
e.printStackTrace();
System.out.println("No picture");
}
}
}
//your feature class
class Gui {
public Gui() {
JFrame rahmen = new JFrame();
rahmen.setSize(800, 600);
rahmen.setLocationRelativeTo(null);
rahmen.setVisible(true);
rahmen.setResizable(false);
rahmen.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
rahmen.setLayout(null);
rahmen.setTitle("Gioco");
Label label = new Label(); //<<this label is your extended label (i.e com.demo.test.stack.Label)and not awt label
label.setVisible(true);
label.setBounds(0, 0, 800, 600);
rahmen.add(label);
}
}
Let me know if you ave any other queries.
Regards and welcome to SO.
Cheers
Related
It is very simple program and i have tried my best but the JPanel doesn't come up with a background image. I just want a simple background image on my panel.
Here is my code:
import javax.swing.*;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.*;
import java.awt.Graphics;
class PanelEx extends JPanel
{
BufferedImage img;
PanelEx()
{
try
{
img = ImageIO.read(new File("C:/Users/Pictures/s_4261.jpg"));
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
public void printComponent(Graphics g)
{
g.drawImage(img,0,0,null);
}
}
class JPanelEx2 extends JFrame
{
PanelEx pe;
public static void main(String args[])
{
new JPanelEx2();
}
JPanelEx2()
{
pe = new PanelEx();
add(pe);
setTitle("JPanel Title");
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setSize(320,240);
setVisible(true);
}
}
Thanks in advance
Replace
public void printComponent(Graphics g) {
with
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Don't use a JPanel. Just use a JLabel with an Icon then you don't need custom code.
See Background Panel for more information as well as a solution that will paint the image on a JPanel with 3 different painting options:
scaled
tiled
actual
This question already has answers here:
How to draw an image over another image?
(2 answers)
Closed 5 years ago.
I Have used JPanel to embed two images. One is png image and another is jpeg. I have to overlay png image over jpeg. I have tried out. Please fix me if, I am wrong.
import java.awt.*;
import java.io.IOException;
import javax.swing.*;
public class Test extends JFrame
{
public Test()
{
super();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(1366,768);
onInit();
setVisible(true);
}
private void onInit()
{
JPanel panel=new JPanel();
panel.setLayout(null);
panel.setBounds(0,0,1366,768);
panel.setBackground(new Color(0,0,0,0));
JLayeredPane lp = getLayeredPane();
lp.setBounds(0,0,1366,768);
JLabel adLabel1=new JLabel();
adLabel1.setBounds(0,0,1366,768);
Image img1=new ImageIcon("F:\\wall papers\\Download-High-Res-Crazy-Concrete-Textures.jpg").getImage();
ImageIcon ad1=new ImageIcon(img1.getScaledInstance(1366,768,Image.SCALE_SMOOTH));
adLabel1.setIcon(ad1);
JLabel adLabel2 = new JLabel();
adLabel2.setBounds(0, 0, 1366, 768);
Image img2=new ImageIcon("<path>\\A100004.png").getImage();
ImageIcon ad2=new ImageIcon(img2.getScaledInstance(1366,768,Image.SCALE_SMOOTH));
adLabel2.setIcon(ad2);
adLabel2.setBackground(new Color(0,0,0,0));
adLabel2.revalidate();
lp.add(adLabel1,JLayeredPane.MODAL_LAYER);
lp.add(adLabel2,JLayeredPane.DRAG_LAYER);
panel.add(lp);
}
public static void main(String args[])
{
// Schedule a job for the event-dispatching thread:
// creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new Test();
}
});
}
}
If I do not use JPanel it is working, it shows only a blank panel. But I want it to be done in the JPanel.
Example:
and I tried with this png image:
You have a number of possible solutions, you could, for example try:
Using a GridBagLayout, although that would become insanely complex really quickly
Create you own LayoutManager, but that's probably overkill for the problem
Use a OverlayLayout manager, but since I don't have any experience with it, I can't say if it would solve your issue or not.
Or, you could...
Take control of the whole process and fallback to custom painting. This gives you the same level of flexibility as writing your own LayoutManager, but without the complexity and since you're only drawing images, makes a life a whole lot simpler.
If you need to display other components (like text or text fields) you could use a custom painting route to render the images as the background and one or layout mangers to deal with the other components.
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
try {
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
public class TestPane extends JPanel {
private BufferedImage background;
private BufferedImage foreground;
public TestPane() throws IOException {
background = ImageIO.read(getClass().getResource("Background.png"));
foreground = ImageIO.read(getClass().getResource("Foreground.png"));
}
#Override
public Dimension getPreferredSize() {
return background == null ? new Dimension(200, 200) : new Dimension(background.getWidth(), background.getHeight());
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int x = 0;
int y = 0;
int width = getWidth();
if (background != null) {
x = (getWidth() - background.getWidth()) / 2;
y = (getHeight() - background.getHeight()) / 2;
width = background.getWidth();
g2d.drawImage(background, x, y, this);
}
if (foreground != null) {
x = x + width - foreground.getWidth();
g2d.drawImage(foreground, x, y, this);
}
g2d.dispose();
}
}
}
I have been trying to figure this out why not the next picture showing on the same panel after click the button. I want to separate those classes not into one class and used repaint() to re-invoke paintComponent() with the new pic.
Please help me. I am almost dying :(
when I run this, the first picture appears well. when the button is clicked to change the first picture to the second one, the Panel just keep on showing the first picture.
Thank you.
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;
class drawImage extends JPanel {
BufferedImage[] b = new BufferedImage[2];
public drawImage() {
try {
b[0] = ImageIO.read(new File("img/gameOn.png"));
b[1] = ImageIO.read(new File("img/gameOff.png"));
} catch (IOException e) {
e.printStackTrace();
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(b[0], 0, 0, null);
}
public void setNextImage(BufferedImage image) {
b[0] = image;
repaint();
}
public BufferedImage getB0() {
return b[0];
}
public BufferedImage getB1() {
return b[1];
}
}// end drawImage
class clickedListener implements ActionListener {
BufferedImage pre = new drawImage().getB0();
BufferedImage next = new drawImage().getB1();
#Override
public void actionPerformed(ActionEvent e) {
new drawImage().setNextImage(next);
}
}
public class buttonFrame {
public static void main(String[] args) throws IOException {
JFrame jf = new JFrame("Button & Frame");
JButton btn = new JButton("Click");
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setVisible(true);
jf.setLayout(new GridLayout(2, 0));
jf.add(new drawImage());
jf.add(btn);
jf.setSize(200, 250);
btn.addActionListener(new clickedListener());
}
}
Why not change your approach and make use of a JLabel instead? Set your image as an icon on the label and add it to your JPanel:
BufferedImage image = ImageIO.read(new File("image-path"));
JLabel label = new JLabel(new ImageIcon(image));
panel.add(label);
You can then make subsequent calls to JLabel#setIcon(...) each time you want the image to change.
You can also use ImageIcon like this
image = new ImageIcon(imageList[1]);
and when each time button is clicked you can change image like this
label.setIcon(image);
I've been trying for a while to load an image into this JFrame for it to display it without success. Here is the code:
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JOptionPane;
public class Main extends JPanel{
Bird bird = new Bird(this);
public void paint(Graphics g){
super.paint(g);
Graphics2D g2D = (Graphics2D) g;
g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
bird.paint(g2D);
}
public static void main(String[] args)throws InterruptedException{
JFrame frame = new JFrame("Java Birds");
Main game = new Main();
frame.add(game);
frame.setSize(500, 300);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
while(true){
game.repaint();
Thread.sleep(10);
}
}
}
This is my Bird Class:
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Toolkit;
public class Bird {
private static final Image sprite = Toolkit.getDefaultToolkit().getImage("bird.jpeg");
private static final int DIAMETER = 30;
double g = 0.12, vy = 0, xo = 100, yo = 10;
private Main game;
public Bird(Main game){
this.game = game;
}
public void paint(Graphics2D g){
g.setColor(Color.BLACK);
g.drawImage(sprite, 30, 30, game);
}
}
When I run this nothing shows up onscreen, but if I place a g.fillOval instruction I do get a circle in the panel. Help much appreciated, please.
There are a cascade of issues, first...
public void paint(Graphics g){
super.paint(g);
Graphics2D g2D = (Graphics2D) g;
g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
bird.paint(g2D);
}
You're overriding paint, it is highly unrecommended to do so, instead, it is recommended that you override paintComponent instead.
Another problem is...
Toolkit.getDefaultToolkit().getImage("bird.jpeg");
The problem with this is getImage(String) expects that the value you pass it refers to a file on the file system. In most cases, this is not true and the image is stored as an embedded resource, in which use you would need to use something more like...
Toolkit.getDefaultToolkit().getImage(Bird.class.getResource("bird.jpeg"));
or
Toolkit.getDefaultToolkit().getImage(Bird.class.getResource("/bird.jpeg"));
There is still no guarantee that the image is loaded and none of these approaches actually tells you when it has failed.
A better solution would be to use ImageIO to read the image, apart from supporting more formats, it will throw an IOException when it fails...
public class Bird {
private Image sprite;
//...
public Bird(Main game) throws IOException {
image = ImageIO.read(getClass().getResource("/bird.jpeg"));
This...
while(true){
game.repaint();
Thread.sleep(10);
}
Is also very dangerous, you've started this in the main method, but you've take no consideration into what thread main might be called in. While in "normal" operations, main is called by the JVM from what is known as the "main thread", there is no guarantee that this is how your main method is called. It might called by another class from the context of the EDT which would cause the program to freeze.
Generally you should either use a javax.swing.Timer or a separate thread all together.
To display an image which fills the entire panel, you should have the following. You can use ImageIO.read(File) to read in an image from a file (you can adjust the position and size of the image inside the paintComponent method). You may want to also see Graphics.drawImage`.
import javax.swing.*;
import java.awt.image.*;
import java.awt.*;
public class PictureFrame extends JComponent{
private final Image img;
public PictureFrame(final String file) throws IOException {
this(new File(file));
}
public PictureFrame(final File file) throws IOException {
this(ImageIO.read(file));
}
public PictureFrame(BufferedImage img){
this.img = img;
this.setPreferredSize(new Dimension(img.getWidth(), img.getHeight()));
}
public void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(img, 0, 0, getWidth(), getHeight(), null);
}
}
Tester main:
public static final String TEST_FILE = "file path here";
public static void main(String... args) throws IOException {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
}
final JFrame frame = new JFrame();
final JComponent picture = new PictureFrame(TEST_FILE);
frame.setContentPane(picture);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 300);
frame.setVisible(true);
}
This is a really general question, but how should I add an animated background for a JPanel. I want the background to be behind all the panel's components and graphics. Right now, I have two separate classes (one for the main panel and the other for the background). The background class uses repaint() to animate a grid moving across the screen. I've tried to make the main panel background transparent, but that hasn't gotten me anywhere.
Even more info:
My main panel is part of a CardLayout and it has many different classes in it. So when I'm adding my main panel to my main frame, I'm doing frame.getContentPane().add(cards, BorderLayout.CENTER)
cards is a JPanel which acts as a container for the mainpanel and all the panels inside main panel.
Can anybody help me out in getting a panel animated background?
You can use Toolkit.getImage() to load animated image and then draw the image in container's paintComponent. Make sure the ImageObserver is set (not null) in order to update animation frames properly. For details how image is loaded, observed and updated see How Images are Loaded appendix in Java AWT Reference.
Here is a simple example:
import java.awt.*;
import javax.swing.*;
import java.net.URL;
class AnimatedPanelDemo {
static class ImagePanel extends JPanel {
private Image image;
ImagePanel(Image image) {
this.image = image;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image,0,0,getWidth(),getHeight(),this);
}
}
private static void createAndShowUI() {
try {
JFrame frame = new JFrame("Image");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
Image image = Toolkit.getDefaultToolkit().getImage(new URL(
"http://duke.kenai.com/iconSized/duke.running.gif"));
ImagePanel imagePanel = new ImagePanel(image);
imagePanel.add(new JLabel("Some label"));
frame.add(imagePanel);
frame.setSize(100, 100);
frame.setVisible(true);
}
catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
Well, this is my first answer on stackoverflow.
Will try to help with my learning curve with this complex AWT and Swift API.
Below there's the contructor that extends JFrame
package xpto;
import java.awt.Dimension;
import java.awt.GraphicsConfiguration;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.event.WindowStateListener;
import java.awt.image.ImageObserver;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import sun.java2d.SunGraphicsEnvironment;
import java.awt.Graphics;
import java.awt.Graphics2D;
public class FrameLuckyRaffle extends JFrame {
/**
*
*/
private JLabel backgroundLabel;
private ImageIcon imageIcon;
private Image bgImage;
/**
* Constructor of this frame.
*/
public FrameLuckyRaffle(String background, final String dbname) {
try {
setTitle("Lucky Raffle of "+ dbname);
GraphicsConfiguration config = this.getGraphicsConfiguration();
Rectangle usableBounds = SunGraphicsEnvironment.
getUsableBounds(config.getDevice());
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setBounds(100, 100, (int)(usableBounds.getWidth()*0.8),
(int)(usableBounds.getHeight()*0.8));
setMinimumSize(new Dimension(1024, 700));
setResizable(true);
setDefaultLookAndFeelDecorated(true);
backgroundLabel = new JLabel() {
public void paintComponent(Graphics g) {
// alternative --> g.drawImage(bgImage, 0, 0, null);
// I prefer to control the new ImageObserver parameter as bellow
g.drawImage(bgImage, 0, 0, new ImageObserver() {
#Override
public boolean imageUpdate(Image img, int infoflags,
int x, int y, int width, int height) {
img.getScaledInstance(getWidth(),getHeight(),
Image.SCALE_FAST);
return true;
}
});
// this is used to have easier control on
// image manipulation on my application
Graphics2D g2d = (Graphics2D)g;
super.paintComponent(g2d);
revalidate();
repaint();
}
};
backgroundLabel.setBounds(0, 0, 0, 0);
// this is necessary if you want more child
// components to be visible on the JFrame afterwards
backgroundLabel.setOpaque(false);
setContentPane(backgroundLabel);
addWindowListener(new WindowListener() {
#Override
public void windowOpened(WindowEvent e) {
// Set Frame Background
imageIcon = new ImageIcon(Toolkit.getDefaultToolkit().
createImage(FrameBusinessPure.class.getResource(background)));
bgImage = imageIcon.getImage().
getScaledInstance(getWidth(),getHeight(), Image.SCALE_FAST);
}
// Even after closing the window, JVM didn't Garbage Collected the instanced
// objects, for some reason. Forcing the objects to null helped on that.
#Override
public void windowClosed(WindowEvent e) {
backgroundLabel = null;
imageIcon = null;
bgImage = null;
System.gc();
}
});
addWindowStateListener(new WindowStateListener() {
#Override
public void windowStateChanged(WindowEvent e) {
// if you flush the object on runtime you will surpass the
// memory leak on using GIFs and most complex graphics
bgImage.flush();
bgImage = imageIcon.getImage().
getScaledInstance(getWidth(),getHeight(), Image.SCALE_FAST);
}
});
addMouseMotionListener(new MouseMotionListener() {
#Override
public void mouseDragged(MouseEvent e) {
// if you flush the object on runtime you will surpass the
// memory leak on using GIFs and most complex graphics
bgImage.flush();
bgImage = imageIcon.getImage().
getScaledInstance(getWidth(),getHeight(), Image.SCALE_FAST);
});
}catch (Exception e) {
e.printStackTrace();
}
}
}
Feel free to learn more on below link
https://www.oracle.com/java/technologies/painting.html