Loading images is very slow in java - java

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);
}
}

Related

Images in Java coming up NPE

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.

Setting location for objects/images on a background

I'm currently working on a version of the game Ludo/Dude don't get mad, I've ran into a few problems one of the bigger ones being the fact that I cannot place the tokens where I want them to be. I need to set the tokens in certain positions for the start and will need a method with which I will calculate where to move them on the screen here is the code:
public class Ludo extends JFrame{
private BackgroundPanel imagePanel=null;
private JLabel jlTokenBlue1=null;
private JLabel jlTokenBlue2=null;
...
public Ludo(){
try{
//Creating background panel
imagePanel = new BackgroundPanel("ludoBoard.png");
add(imagePanel);
//create tokens for play
BufferedImage imageTokenBlue1 = ImageIO.read(new File("blue1.png"));
jlTokenBlue1 = new JLabel(new ImageIcon(imageTokenBlue1));
BufferedImage imageTokenBlue2 = ImageIO.read(new File("blue2.png"));
jlTokenBlue2 = new JLabel(new ImageIcon(imageTokenBlue2));
BufferedImage imageTokenBlue3 = ImageIO.read(new File("blue3.png"));
jlTokenBlue3 = new JLabel(new ImageIcon(imageTokenBlue3));
BufferedImage imageTokenBlue4 = ImageIO.read(new File("blue4.png"));
jlTokenBlue4 = new JLabel(new ImageIcon(imageTokenBlue4));
BufferedImage imageTokenRed1 = ImageIO.read(new File("red1.png"));
jlTokenRed1 = new JLabel(new ImageIcon(imageTokenRed1));
BufferedImage imageTokenRed2 = ImageIO.read(new File("red2.png"));
jlTokenRed2 = new JLabel(new ImageIcon(imageTokenRed2));
BufferedImage imageTokenRed3 = ImageIO.read(new File("red3.png"));
jlTokenRed3 = new JLabel(new ImageIcon(imageTokenRed3));
BufferedImage imageTokenRed4 = ImageIO.read(new File("red4.png"));
jlTokenRed4 = new JLabel(new ImageIcon(imageTokenRed4));
imagePanel.add(jlTokenBlue1);
imagePanel.add(jlTokenBlue2);
imagePanel.add(jlTokenBlue3);
imagePanel.add(jlTokenBlue4);
imagePanel.add(jlTokenRed1);
imagePanel.add(jlTokenRed2);
imagePanel.add(jlTokenRed3);
imagePanel.add(jlTokenRed4);
jlTokenRed1.setLocation(250,500);
}//End of try
catch(IOException ioe){
System.out.println("The background image cannot be loaded...");
}catch(NullPointerException npe){
npe.getMessage();
}
.
.
.
class BackgroundPanel extends JPanel
{
Image image;
public BackgroundPanel(String imageName)
{
try
{
image = javax.imageio.ImageIO.read(new java.net.URL(getClass().getResource(imageName), imageName));
}
catch (Exception e) { /*handled in paintComponent()*/ }
}
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
if (image != null)
g.drawImage(image, 0,0,this.getWidth(),this.getHeight(),this);
}
}
I've tried using setLocation and repaint but was unable to set the tokens to be placed where I want them to be. I'd like to place the tokens into the white fields in their respective colors any help and/or suggestion is greatly appreciated. Below is a picture of how it looks right now.
Here is the link to the drive containing everything if you wish to check the files your self. drive.google.com/open?id=1xap_xz2K3SF37XQfRN3Y_LHoTHg0HNox
!
I've started some code for your game. You'll have to complete the code.
Here's the GUI I created.
The first thing I did was to employ a model / view / controller pattern. By separating the logical functions of the game, I could concentrate on one part at a time.
Here's the model I created. It's not complete, but I think you can see what I'm trying to do herd. I put his class in its own model package.
package com.ggl.ludo.model;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
public class LudoModel {
private final BufferedImage gameBoard;
private final BufferedImage[] imageTokenBlue;
public LudoModel() {
imageTokenBlue = new BufferedImage[4];
imageTokenBlue[0] = getImage("blue1.png");
imageTokenBlue[1] = getImage("blue2.png");
imageTokenBlue[2] = getImage("blue3.png");
imageTokenBlue[3] = getImage("blue4.png");
gameBoard = getImage("ludoBoard.png");
}
public BufferedImage getGameBoard() {
return gameBoard;
}
public BufferedImage[] getImageTokenBlue() {
return imageTokenBlue;
}
private BufferedImage getImage(String fileName) {
try {
return ImageIO.read(getClass().getResourceAsStream("/" + fileName));
} catch (IOException e) {
return null;
}
}
}
All this code does is read in the images, and eventually, create the logical model of your game. It's not concerned with the view or the controller code at all.
The next class I created was the DrawingPanel class. This class draws the game board and eventually, draws the pieces on the board. The location of the pieces information goes into the model.
package com.ggl.ludo.view;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JPanel;
import com.ggl.ludo.model.LudoModel;
public class DrawingPanel extends JPanel {
private static final long serialVersionUID = 1L;
private LudoFrame frame;
private LudoModel model;
public DrawingPanel(LudoFrame frame, LudoModel model) {
this.frame = frame;
this.model = model;
int width = model.getGameBoard().getWidth();
int height = model.getGameBoard().getHeight();
this.setPreferredSize(new Dimension(width, height));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(model.getGameBoard(), 0, 0, this);
// Your piece drawing code goes here
}
}
Next, I created a class to hold the JFrame. The JScrollPane code can be removed. My old laptop can't display a game board as large as yours. Something to keep in mind if you want others to play this game.
I put the menu code in its own method. I like to keep separate things separate. My feeble mind can't handle too many processes at one time.
package com.ggl.ludo.view;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JScrollPane;
import com.ggl.ludo.model.LudoModel;
public class LudoFrame {
private DrawingPanel drawingPanel;
private LudoModel ludoModel;
public LudoFrame(LudoModel ludoModel) {
this.ludoModel = ludoModel;
generateGUIControl();
}
private void generateGUIControl() {
JFrame frame = new JFrame("Ludo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setJMenuBar(createMenu());
drawingPanel = new DrawingPanel(this, ludoModel);
JScrollPane scrollPane = new JScrollPane(drawingPanel);
scrollPane.setPreferredSize(new Dimension(400, 400));
frame.add(scrollPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JMenuBar createMenu() {
JMenuBar ludoMenuBar = new JMenuBar();
JMenu ludoMenuFirst = new JMenu("Information");
ludoMenuBar.add(ludoMenuFirst);
JMenuItem jmiDescription = new JMenuItem("Description");
JMenuItem jmiHelp = new JMenuItem("Help");
JMenuItem jmiRestart = new JMenuItem("Restart");
JMenuItem jmiExit = new JMenuItem("Exit");
ludoMenuFirst.add(jmiDescription);
ludoMenuFirst.add(jmiHelp);
ludoMenuFirst.add(jmiRestart);
ludoMenuFirst.add(jmiExit);
ludoMenuBar.add(ludoMenuFirst);
return ludoMenuBar;
}
}
Finally, the driver class that starts the whole process. You must start a Swing application on the Event Dispatch Thread(EDT). The call to SwingUtilities invokeLater ensures that your application starts on the EDT.
package com.ggl.ludo;
import javax.swing.SwingUtilities;
import com.ggl.ludo.model.LudoModel;
import com.ggl.ludo.view.LudoFrame;
public class Ludo implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Ludo());
}
#Override
public void run() {
new LudoFrame(new LudoModel());
}
}
I hope this has been helpful to you. As far as the controllers, I suggest that you use a mouse listener and draw the game pieces on the game board.
Remember, information about the game piece locations goes into the model. The view drawing code draws from the information in the model.

importing images causes rendering issues

Modifiers.java
package game;
import java.awt.*;
import java.io.*;
import javax.swing.*;
public class Modifiers extends Data{
public static void setupJcomponents(){
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
try{
PixelFont = Font.createFont(Font.TRUETYPE_FONT, new File("src/game/PixelFont.ttf"));
ge.registerFont(PixelFont);
} catch (IOException | FontFormatException e) {
PixelFont = new Font("OCR A Extended", Font.PLAIN, heightUnits*2);
ge.registerFont(PixelFont);
}
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setUndecorated(true);
frame.setSize(MW,MH);
frame.setResizable(false);
frame.setVisible(true);
frame.setLayout(null);
uiPanelMenu.setLayout(null);
uiPanelMenu.setVisible(true);
uiPanelMenu.setBounds(0,0,MW,MH);
uiPanelMenu.setOpaque(false);
for(int btn=0; btn<4; btn++) {
try {
buttonImage[btn] = new ImageIcon(Frame.class.getResource("/game/SelectionButton.png"));
} catch (Exception e) {
e.printStackTrace();
}
buttons[btn] = new JPanel();
buttonLabel[btn] = new JLabel("",SwingConstants.CENTER);
buttonLabel[btn].setIcon(buttonImage[btn]);
buttons[btn].setBounds(widthUnits*15,(heightUnits*13)+(heightUnits*3*btn),widthUnits*15,heightUnits*3);
buttonLabel[btn].setBounds(0,0,buttons[btn].getWidth(),buttons[btn].getHeight());
buttons[btn].setLayout(null);
uiPanelMenu.add(buttons[btn]);
buttons[btn].add(buttonLabel[btn]);
buttonLabel[btn].setForeground(Color.black);
buttons[btn].setBackground(Color.white);
buttonLabel[btn].setText("Button "+(btn+1));
buttonLabel[btn].setFont(new Font("PixelFont", Font.PLAIN, heightUnits*2));
buttons[btn].setVisible(true);
buttonLabel[btn].setVisible(true);
}
menuBackground.setBounds(0,0,MW,MH);
menuBackground.setBackground(Color.black);
menuBackground.setVisible(true);
uiPanelMenu.add(menuBackground);
healthIndicator.setText(String.valueOf(healthValue));
healthIndicator.setFont(new Font("PixelFont", Font.PLAIN, heightUnits*2));
healthIndicator.setBounds(widthUnits*20,heightUnits*20,widthUnits*5,heightUnits*2);
healthIndicator.setVisible(true);
healthIndicator.setOpaque(false);
healthIndicator.setForeground(Color.blue);
uiPanelFight.add(healthIndicator);
frame.getContentPane().add(uiPanelMenu);
}
}
data.java
package game;
import java.awt.*;
import javax.swing.*;
public class Data {
// this is where I will declare and alter all variable that will be used
public static JFrame frame = new JFrame();
public static JLabel healthIndicator = new JLabel("",SwingConstants.CENTER);
public static JPanel buttons[] = new JPanel[5];
public static JLabel buttonLabel[] = new JLabel[5];
public static JPanel menuBackground = new JPanel();
public static JPanel title = new JPanel();
public static JPanel uiPanelMenu = new JPanel();
public static JPanel uiPanelFight = new JPanel();
public static ImageIcon buttonImage[] = new ImageIcon[5];
public static final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
public static final int MW = (int) screenSize.getWidth();
public static final int MH = (int) screenSize.getHeight();
public static final int widthUnits = MW/45;
public static final int heightUnits = MH/25;
public static Font PixelFont;
public static int maxHealth = 100;
public static int healthValue = maxHealth;
}
frame.java
package game;
public class Frame {
public static void main(String[] args) {
Modifiers.setupJcomponents();
}
}
whenever i try to reference the image here:
buttonImage[btn] = new ImageIcon(Frame.class.getResource("/game/SelectionButton.png"));
if it is wrong then it will just give me a NullPointerException, but if the image name is correct then the entire panel that holds everything disappears, all of the objects i used are properly declared in a separate Data.java class, i know it is instantiated correctly but i dont know why everything is not rendering when the line hits the image location.
So your code raises so many questions it's not funny. However, your basic problem(s) come down to lack of understanding in how the basic Swing API works.
Swing is lazy. It won't update the UI when you add/remove components from containers, that's up to you.
So, your basic code currently looks like...
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
//frame.setUndecorated(true);
frame.setSize(MW, MH);
//frame.setResizable(false);
frame.setVisible(true);
// ?? Why ?? Besides, it's not doing what you think it is
frame.setLayout(null);
// Add all the stuff to uiPanelMenu ...
frame.getContentPane().add(uiPanelMenu);
The problem is, once you make the window visible, you are responsible for triggering layout and paint passes.
You can fix the basic problem by adding
frame.getContentPane().revalidate();
frame.getContentPane().repaint();
after frame.getContentPane().add(uiPanelMenu); or moving frame.setVisible(true); after frame.getContentPane().add(uiPanelMenu); which will probably produce a more desirable result.
I know you think you're making your life easier by using null layouts, but your not, nor are you taking into considerations all the differences in how text is rendered on different platforms/hardware.
You're doing yourself a massive disservice by not making use of the layout management API (and will end up having to replicate much of its functionality yourself).
Instead, take the time learn more about the available layout managers - Laying Out Components Within a Container

Trying to set image icon for JLabel but URL returns null

Trying to set image icon for JLabel but returns a null URL?
I am using Netbeans and have included background.png in my project but it still returns null?
import java.awt.image.BufferedImage;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
public class NewClass extends JFrame {
JLabel o = new JLabel();
public NewClass() {
createImage("background.png");
add(o);
setVisible(true);
setSize(100, 100);
setResizable(false);
}
public static void main(String[] args) {
new NewClass();
}
public void createImage(String str) {
URL url = getClass().getResource(str);
try {
BufferedImage image = ImageIO.read(url);
o.setIcon(new ImageIcon(image));
} catch (Exception e) {
e.printStackTrace();
}
}
}
Error details in stack trace:
java.lang.IllegalArgumentException: input == null!
at javax.imageio.ImageIO.read(ImageIO.java:1388)
at Test.NewClass.createImage(NewClass.java:32)
at Test.NewClass.<init>(NewClass.java:18)
at Test.NewClass.main(NewClass.java:26)
Please could you help unsure why it doesn't work, when i try
JLabel o = new JLabel(new ImageIcon("background.png");
It works but this is error prone incase background.png doesn't exist?
Thankyou
EDIT: components-SplitPaneDemo2Project - where this is name of netbeans project & background png is directly inside this folder
Located in here:
C:\Users\John\Documents\NetBeansProjects\components-SplitPaneDemo2Project
Screenshot:
I've tested your code with some changes and it works fine:
public class NewClass extends javax.swing.JFrame {
JLabel o = new JLabel();
public NewClass() {
initComponents();
createImage("background.png");
add(o);
setVisible(true);
setSize(100, 100);
setResizable(false);
o.setLocation(20, 20);
o.setSize(100, 25);
}
public void createImage(String str) {
URL url = getClass().getResource(str);
try {
BufferedImage image = ImageIO.read(url);
o.setIcon(new ImageIcon(image));
} catch (Exception e) {
e.printStackTrace();
}
}
....
}
in the constructor I've set location and size for 'o'.
'background.png' must be in the parent package of 'NewClass'.

Image drawing with PaintComponent Java

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);
}
}

Categories

Resources