I'm a beginner in Java and I would like to load an image with this script:
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;
import javax.swing.*;
/**
* This class demonstrates how to load an Image from an external file
*/
public class LoadImageApp extends Component {
BufferedImage img;
public void paint(Graphics g) {
g.drawImage(img, 0, 0, null);
}
public LoadImageApp() {
try {
img = ImageIO.read(getClass().getResource("/resources/java.png"));//cannot found image
} catch (IOException e) {
}
}
public Dimension getPreferredSize() {
if (img == null) {
return new Dimension(100,100);
} else {
return new Dimension(img.getWidth(null), img.getHeight(null));
}
}
public static void main(String[] args) {
JFrame f = new JFrame("Load Image Sample");
f.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
f.add(new LoadImageApp());
f.pack();
f.setVisible(true);
}
}
Then I put a picture on a folder resource "resources", change the name of the location of the picture like "/resources/java.png" and when I compile, there is an empty window without image.
You can see error here : https://ibb.co/ysjNyQw
The first thing you're going to want to do is do some research into "embedded resources", for example
I don't use Eclipse, I use Netbeans, but the process should be the same
As you can see, I've placed my image in the resources package within the projects "sources". This will ensure that it's available at runtime via the class path search mechanism (and embedded within the resulting Jar file when I export it).
I then used a JLabel to display it...
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.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
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 {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
BufferedImage image = ImageIO.read(getClass().getResource("/resources/java.png"));
JLabel label = new JLabel(new ImageIcon(image));
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(label);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
}
Now, if you want to continue using a custom painting route, I suggest having a read of:
Performing Custom Painting
Painting in AWT and Swing
to get a better understanding of how painting works in Swing and how you should work with it
Related
I copied the path of the image but no icon appears click on the image to see
no icon
I created simple frame and needed to include icon
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.awt.Color;
public class App {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setTitle("JFrame title goes here");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //exit out of app
frame.setResizable(false); // prevent frame from being resized
frame.setSize(700,700);
frame.setVisible(true);
try {
URL resource = frame.getClass().getResource("/games.png");
BufferedImage image = ImageIO.read(resource);
frame.setIconImage(image);
} catch (IOException e) {
e.printStackTrace();
}
frame.getContentPane().setBackground(new Color(123,50,250));
}
}
I am trying to load image in JPanel and after that I want to write an image caption also. At the moment I am not able to load the image. I do not want to use JLabel. Instead I want to use paint Component. Here is the code
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.AffineTransform;
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.SwingUtilities;
public class imageCaptio extends JFrame {
private JPanel caption = new JPanel(){
ClassLoader cl = getClass().getClassLoader();
Image i;
{
try {
i = ImageIO.read(cl.getResourceAsStream("res/car.jpg"));
} catch (IOException ex) {
Logger.getLogger(imageCaptio.class.getName()).log(Level.SEVERE, null,
ex);
}
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g.create();
// get scaling instance to scale the image to the component
AffineTransform imageAdjust =
AffineTransform.getScaleInstance((float)getWidth()/i.getWidth(this),
(float)getHeight()/i.getHeight(this));
// draw the image using the separate transform
if (i != null)
g2.drawImage(i, imageAdjust, this);
}
};
private imageCaptio() {
// Invoke the JFrame superclass constructor and configure the frame
super("image caption");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(800,800);
this.setVisible(true);
// Add a panel to the frame and draw the face within it.
this.add(caption);
}
public static void main(String[] args) {
// Create on the Event Dispatch Thread.
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new imageCaptio();
}
});
}
}
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
public class MainWindow extends JFrame{
public static void main(String[] args) {
JFrame mainWindow = new JFrame("Siege Arena");
mainWindow.setResizable(false);
mainWindow.setVisible(true);
mainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainWindow.setSize(500, 500);
loadpics();
}
Image bg;
public void loadpics(){
bg = new ImageIcon("C:\\test\\Background.png").getImage();
repaint();
}
public void paint(Graphics g){
g.drawImage(bg,0,0,null);
}
}
All I am trying to do is create a JFrame and load a simple image on to it, How exactly do i do that. Here I tried, and failed. Can someone help me?
Can someone see what is wrong?
Extendng from JFrame, you're not adding any new functionality and you're locking yourself into a single use of the component
Override paint of top level containers, like JFrame, it's far to easy (like you have) to break the paint chain which gives no end of problems
Not calling super.paint and breaking the paint chain
Not passing a ImageObserver to ImageIcon
Referencing the wrong instance of MainWindow when you try and load the image.
If I "guess" correctly, you are trying to paint a background image into a window. If so, then the way you've tried is DEFIANTLY not the way to go about it.
Instead...
Start with a custom component which extends from something JPanel
Use the paintComponent method to draw the image
Consider using ImageIO instead of ImageIcon. ImageIO will throw an exception if the image can't be loaded.
For example...
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
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();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(new BackgroundPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class BackgroundPane extends JPanel {
private BufferedImage bg;
public BackgroundPane() {
try {
bg = ImageIO.read(new File("C:\\test\\Background.png"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
#Override
public Dimension getPreferredSize() {
return bg == null ? new Dimension(200, 200) : new Dimension(bg.getWidth(), bg.getHeight());
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (bg == null) {
Graphics2D g2d = (Graphics2D) g.create();
int x = (getWidth() - bg.getWidth()) / 2;
int y = (getHeight() - bg.getHeight()) / 2;
g2d.drawImage(bg, x, y, this);
g2d.dispose();
}
}
}
}
Take a look at:
Painting in AWT and Swing
Performing Custom Painting
Reading/Loading an Image
for more details...
I am trying to change the icon (background) of a JLabel, but I am having an issue with the icon not updating. Whenever I tried lblStatusImg.setIcon(new ImageIcon(Brix_Updater_Module.class.getResource("/resources/fail.png"))); to change the JLabel in the main method, the compiler was first complaining that the variable lblStatusImg did not exist, so I moved it from the JFrame initialization method to a class level variable. After this, Eclipse complained that I was trying to reference a nonstatic method from static context, so I made lblStatusImg static. This made it possible for the program to compile, but the icon did not change whenever it was supposed to.
Since it's kind of hard to understand my problem here is a download link for an Eclipse workspace that demonstrates my problem. When you first open it, you will notice that there are some problems with it. They were left there on purpose to make it easier for you to see where I am having a hard time. If Eclipse asks you to make the items in question static, just do it and then run the program. You'll notice that it does not change the label icons as it should.
Since not all of you have Eclipse, here's the entire code from the workspace.
import java.awt.Component;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JLabel;
import java.awt.Font;
import javax.swing.SwingConstants;
import java.awt.Window.Type;
import java.io.BufferedOutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Timer;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class StackOverflow_Image_Resource_Demo {
private JFrame frmUpdate;
JLabel lblStatusImg = new JLabel("");
JButton btnUpdateComplete = new JButton("OK");
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
StackOverflow_Image_Resource_Demo window = new StackOverflow_Image_Resource_Demo();
window.frmUpdate.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
try {
lblStatusImg.setIcon(new ImageIcon(StackOverflow_Image_Resource_Demo.class.getResource("success.png")));
btnUpdateComplete.setVisible(true);
}
catch(Exception e)
{
Component frame = null;
lblStatusImg.setIcon(new ImageIcon(StackOverflow_Image_Resource_Demo.class.getResource("/resources/fail.png")));
JOptionPane.showMessageDialog(frame, "Update Failed", "Update Failed", JOptionPane.ERROR_MESSAGE);
System.exit(1);
}
}
/**
* Create the application.
*/
public StackOverflow_Image_Resource_Demo() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frmUpdate = new JFrame();
frmUpdate.setType(Type.UTILITY);
frmUpdate.setTitle("StackOverflow Image Resource Issue Demo");
frmUpdate.setBounds(100, 100, 450, 300);
frmUpdate.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frmUpdate.getContentPane().setLayout(null);
//JLabel lblStatusImg = new JLabel(""); - Commented out when I made lblStatusImg class level.
lblStatusImg.setIcon(new ImageIcon(StackOverflow_Image_Resource_Demo.class.getResource("/resources/updating.gif")));
lblStatusImg.setBounds(10, 22, 414, 97);
frmUpdate.getContentPane().add(lblStatusImg);
//JButton btnUpdateComplete = new JButton("OK"); - Commented out when I made btnUpdateComplete class level.
btnUpdateComplete.setVisible(false);
btnUpdateComplete.addMouseListener(new MouseAdapter() {
#Override
public void mouseReleased(MouseEvent arg0) {
System.exit(1);
}
});
btnUpdateComplete.setBounds(170, 179, 89, 23);
frmUpdate.getContentPane().add(btnUpdateComplete);
}
}
Here is a newer version of my code that updates the image, but doesn't fully load the UI until everything else is done.
import java.awt.Component;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JLabel;
import java.awt.Font;
import javax.swing.SwingConstants;
import java.awt.Window.Type;
import java.io.BufferedOutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Timer;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class StackOverflow_Image_Resource_Demo {
private JFrame frmUpdate;
JLabel lblStatusImg = new JLabel("");
JButton btnUpdateComplete = new JButton("OK");
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
StackOverflow_Image_Resource_Demo window = new StackOverflow_Image_Resource_Demo();
try {
lblStatusImg.setIcon(new ImageIcon(StackOverflow_Image_Resource_Demo.class.getResource("success.png")));
btnUpdateComplete.setVisible(true);
}
catch(Exception e)
{
Component frame = null;
lblStatusImg.setIcon(new ImageIcon(StackOverflow_Image_Resource_Demo.class.getResource("/resources/fail.png")));
JOptionPane.showMessageDialog(frame, "Update Failed", "Update Failed", JOptionPane.ERROR_MESSAGE);
System.exit(1);
}
window.frmUpdate.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public StackOverflow_Image_Resource_Demo() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frmUpdate = new JFrame();
frmUpdate.setType(Type.UTILITY);
frmUpdate.setTitle("StackOverflow Image Resource Issue Demo");
frmUpdate.setBounds(100, 100, 450, 300);
frmUpdate.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frmUpdate.getContentPane().setLayout(null);
//JLabel lblStatusImg = new JLabel(""); - Commented out when I made lblStatusImg class level.
lblStatusImg.setIcon(new ImageIcon(StackOverflow_Image_Resource_Demo.class.getResource("/resources/updating.gif")));
lblStatusImg.setBounds(10, 22, 414, 97);
frmUpdate.getContentPane().add(lblStatusImg);
//JButton btnUpdateComplete = new JButton("OK"); - Commented out when I made btnUpdateComplete class level.
btnUpdateComplete.setVisible(false);
btnUpdateComplete.addMouseListener(new MouseAdapter() {
#Override
public void mouseReleased(MouseEvent arg0) {
System.exit(1);
}
});
btnUpdateComplete.setBounds(170, 179, 89, 23);
frmUpdate.getContentPane().add(btnUpdateComplete);
}
}
Two things come to find. The first is, as you say, you're trying to reference a non-static variable from a static context.
The second is, you don't seem to understand how threading works...
Basically, main is typically executed within the "main" thread (when executed by the JVM).
You then use EventQueue.invokeLater. Which as, the name suggests, will execute the Runnable "later"...at some time in the future...
EventQueue.invokeLater(new Runnable() {
public void run() {
You then try and change the the icon (let's pass over the non-static reference for a momement)...but lblStatusImg won't have been initialized nor is it likely to have been displayed, as the Runnable has not yet been executed, meaning, even if you didn't run into a NullPointerException, you won't see the change...
You can test by adding a System.out in your Runnable and before the first lblStatusImg.setIcon call in the main method.
What you should do is...
Move the "status" change change to within the Runnable context.
Provide a setStatus method that is capable of changing the label and UI content as required based on the provide status
For example...
public static final int SUCCESS = 0;
public static final int FAIL = 0;
//...
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
StackOverflow_Image_Resource_Demo window = new StackOverflow_Image_Resource_Demo();
// This e
window.frmUpdate.setVisible(true);
window.setStatus(StackOverflow_Image_Resource_Demo.SUCCESS);
} catch (Exception e) {
e.printStackTrace();
Component frame = null;
window.setStatus(StackOverflow_Image_Resource_Demo.FAIL);
JOptionPane.showMessageDialog(frame, "Update Failed", "Update Failed", JOptionPane.ERROR_MESSAGE);
window.dispose();
}
}
});
}
You should avoid exposing instance fields as public and instead, provide methods that either change their state indirectly (such as setStatus) or directly (setStatusIcon). In this case, I prefer the first method as this allows the class to determine what a change in status actually means.
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();
}
});
}
}