My problem is that when I create a message dialog using
JOptionPane.showMessageDialog( ... )
On an application that displays a JPanel that draws an image as background (taken from: java swing: how to add an image to a jpanel), the backgrund image is not displayed, so I have to minimize and maximize the application to get the background image back.
So far I can only get back the background image by doing something like this:
app.getApplication().getMainFrame().repaint();
but it only works after I close the Message Dialog.
Any ideas?
The link you had posted, in that he is accessing Image with File, which seems to me as not that good a way to access Application Resources, for that you must use URL.
Have a look at this sample code, and check where you going wrong with this :
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
public class ImageTest extends JPanel
{
private BufferedImage image;
private void displayGUI()
{
JFrame frame = new JFrame("Image Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
try
{
setImage(new URL("http://gagandeepbali.uk.to/" +
"gaganisonline/images/planetbackground.jpg"));
}
catch(MalformedURLException mue)
{
mue.printStackTrace();
}
frame.setContentPane(this);
frame.pack();
frame.setVisible(true);
JOptionPane.showMessageDialog(frame,
"I am working.",
"Image Working ?",
JOptionPane.QUESTION_MESSAGE);
}
private void setImage(URL path)
{
try
{
System.out.println(path);
image = ImageIO.read(path);
}
catch(IOException ioe)
{
ioe.printStackTrace();
}
}
#Override
public Dimension getPreferredSize()
{
return (new Dimension(image.getWidth(), image.getHeight()));
}
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(image, 0, 0, this);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new ImageTest().displayGUI();
}
});
}
}
Related
I need help to add an image to the separate JFrame, but I can't seem to get it to work. Like I want the image to open in a separate frame like when I run this code it opens a blank JFrame. d help to add an image to the separate JFrame, but I can't seem to get it to work. Like I want the image to open in a separate frame like when I run this code it opens a blank JFrame.
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
import javax.swing.JFrame;
class PPJJ extends JFrame implements ActionListener, KeyListener
{
public void paint(Graphics g) {
Toolkit t=Toolkit.getDefaultToolkit();
Image i=t.getImage("tenor.gif");
g.drawImage(i, 120,100,this);
}
public static void main(String[] args)
{
JFrame frame = new JFrame("VOLUNTEER FOR THING");
PPJJ obj = new PPJJ();
JPanel panel = new JPanel();
JLabel lname = new JLabel("Enter your name here");
JTextField tname = new JTextField(21);
JButton btn = new JButton("Click");
btn.addActionListener(obj);
tname.addKeyListener(obj);
panel.add(lname);
panel.add(tname);
panel.add(btn);
frame.add(panel);
frame.setSize(300, 130);
frame.show();
frame.setLocationRelativeTo(null);
PPJJ m = new PPJJ();
JFrame f =new JFrame();
//f.add(m);
f.setSize(500,500);
f.setVisible(true);
frame.add(new JLabel(new ImageIcon("volunteer.jpeg")));
}
public void actionPerformed(ActionEvent e)
{
String s = e.getActionCommand();
if(s.equals("Click here")){
JOptionPane.showMessageDialog(null , "THANKS FOR SIGNING UP");
}
}
public void keyPressed(KeyEvent e) {
if (e.getKeyCode()==KeyEvent.VK_ENTER){
JOptionPane.showMessageDialog(null , "THANKS FOR SIGNING UP");
}
}
#Override
public void keyReleased(KeyEvent arg) {}
#Override
public void keyTyped(KeyEvent arg) {}
}
Oh, animated GIFs 😓.
Image handling isn't simple in most cases, but animated GIFs are whole other level of pain ... I mean fun.
Normally, I prefer to use ImageIO.read, but ImageIO returns a BufferedImage and it's not (easily) possible to then render animated GIFs through it.
The "easy" route of displaying animated GIFs is by using Image or ImageIcon.
The first step is get your image "embedded" within your application context (assuming that you're not allowing the user to select the image). How this is done will depend on your IDE and build system (Eclipse and Netbeans allow you to simply include them in the src folder, when you're not using Maven).
Next, you want to use Class#getResource to obtain a URL reference to the embedded resource. In this case, you can use ImageIO.read, ImageIcon(URL) or Toolkit#getImage(URL) to load the image. But, as I've said, ImageIO.read isn't going to help you.
Next, you need a component which can render the image, lucky for us, Swing can do this pretty much auto magically for use, all we need to do is make sure the component is passed as the ImageObserver reference, for example...
public class BackgroundPane extends JPanel {
private Image image;
public BackgroundPane(Image image) {
this.image = image;
}
#Override
public Dimension getPreferredSize() {
Image image = getBackgroundImage();
return image == null ? super.getPreferredSize() : new Dimension(image.getWidth(this), image.getHeight(this));
}
public Image getBackgroundImage() {
return image;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Image image = getBackgroundImage();
if (image == null) {
return;
}
int x = (getWidth() - image.getWidth(this)) / 2;
int y = (getHeight() - image.getHeight(this)) / 2;
g.drawImage(image, x, y, this);
}
}
Also, note, JLabel supports animated GIFs via it's icon property as well, but look at How to set a background picture in JPanel for reasons why you shouldn't use a JLabel as a background container.
Now, all we need to do is load the image, pass it to the background, add what ever content we need to the component and show it, easy, or at least it should be. ImageIcon and Toolkit#getImage both off load the reading of the image to a background thread, so inspecting the images dimensions before the image is loaded will return 0x0 😓, so, we need to wait for it to load (this is why I prefer ImageIO.read as it won't return until the image is loaded or an error occurs).
Something like...
Image image = Toolkit.getDefaultToolkit().getImage(getClass().getResource("/images/kitty.gif"));
BackgroundPane backgroundPane = new BackgroundPane(image);
// Did I mention I had this workflow, but ImageIO doesn't
// support animated images, without a lot of work
MediaTracker mt = new MediaTracker(backgroundPane);
mt.addImage(image, 0);
mt.waitForAll();
// The image is now loaded, hooray for us
Runnable example...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
Image image = Toolkit.getDefaultToolkit().getImage(getClass().getResource("/images/kitty.gif"));
BackgroundPane backgroundPane = new BackgroundPane(image);
// Did I mention I had this workflow, but ImageIO doesn't
// support animated images, without a lot of work
MediaTracker mt = new MediaTracker(backgroundPane);
mt.addImage(image, 0);
mt.waitForAll();
backgroundPane.setLayout(new GridBagLayout());
JLabel label = new JLabel("All your kitty is belong to us");
label.setForeground(Color.WHITE);
backgroundPane.add(label);
JFrame frame = new JFrame();
frame.add(backgroundPane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (InterruptedException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
public class BackgroundPane extends JPanel {
private Image image;
public BackgroundPane(Image image) {
this.image = image;
}
#Override
public Dimension getPreferredSize() {
Image image = getBackgroundImage();
return image == null ? super.getPreferredSize() : new Dimension(image.getWidth(this), image.getHeight(this));
}
public Image getBackgroundImage() {
return image;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Image image = getBackgroundImage();
if (image == null) {
return;
}
int x = (getWidth() - image.getWidth(this)) / 2;
int y = (getHeight() - image.getHeight(this)) / 2;
g.drawImage(image, x, y, this);
}
}
}
Please note...
If you're not using an animated GIF, then you can just use ImageIO.read instead of Toolkit#getImage and you won't need to wait (as ImageIO.read works in the current thread), in which case the code would look more like...
try {
BackgroundPane backgroundPane = new BackgroundPane(ImageIO.read(getClass().getResource("/images/kitty.gif")));
backgroundPane.setLayout(new GridBagLayout());
JLabel label = new JLabel("All your kitty is belong to us");
label.setForeground(Color.WHITE);
backgroundPane.add(label);
JFrame frame = new JFrame();
frame.add(backgroundPane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
(the BackgroundPane code doesn't change)
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
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();
}
}
}
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