Failing to draw Image to JFrame - java

first I want to apologize for any mistakes, I'm not speaking english well, I'm new to Java and I'm new to Stackoverflow. Please be kind!
I keep failing to draw a simple image to screen. I tried everything, but I keep failing and I'm getting more and more confused. Here's my Sourcecode:
package com.Animation;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.awt.Graphics2D;
import java.awt.Point;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
#SuppressWarnings("serial")
public class Class1 extends JFrame{
private BufferedImage backgroundImg;
public Class1(){
this.setTitle("Animation");
this.setSize(1080, 720);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
LoadContent();
}
public static void main(String[] args){
new Class1();
}
private void LoadContent()
{
try
{
URL backgroundImgUrl = this.getClass().getResource("Back.jpg");
backgroundImg = ImageIO.read(backgroundImgUrl);
}
catch (IOException ex) {
System.err.println("Fehler!");
}
}
public void Draw(Graphics2D g2d)
{
g2d.drawImage(backgroundImg, 0, 0, null);
}
}
So what happens is, that a JFrame window opens with nothing to see on it. I think that's beacuse the Draw() method doesn't get called. But when I add like "Draw(g2d);" somewhere, I keep getting a NullPointerException. The picture "Back.jpg" is located in the same package as the class. I'm using eClipse and the JRE JavaSE 1.7.
I really hope you can help me, im totally exhausted by all my tries to figure out what's the problem. It would be cool if you could write the correct code into the answers and explain what I've done wrong. Remember, I'm new to all this.
Thanks a lot!

There are a lot of ways to do that. Examples
1) JLabel. //Not recommended
Add the JLabel in your JFrame, then do label.setIcon(backgroundImg);
2) JPanel
Override the paint() method in JPanel(make sure you've added it to your JFrame).
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(backgroundImg, 0, 0, this);
}

Try this. Here I have set the image to a JPanel instead of directly setting it to JFrame.
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
/**
*
* #author Rumesh
*/
public class Test extends JFrame{
public static void main(String[] args) throws IOException {
JFrame frame = buildFrame();
final BufferedImage image = ImageIO.read(new File("1.jpg"));
JPanel pane = new JPanel() {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, null);
}
};
frame.add(pane);
}
private static JFrame buildFrame() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setSize(200, 200);
frame.setVisible(true);
return frame;
}
}

I don't know if this is what you're searching for:
ImageIcon image = new ImageIcon("src/media/Image.jpg");
JLabel lblImg = new JLabel("", image, JLabel.CENTER);
lblImg.setBounds(..., ..., ..., ...);
add(lblImg);
This way you'll add an image to a JLabel and than place it on the screen. I hope it helps in some way.

Related

Java BufferedImage is not draw correctly

I have been wanting to program a 2D game from scratch in Java for a while. The pixel aesthetic is one of my favorites, so I am aiming for a pixel 2D game. However, whenever I try to use BufferedImage to draw my tiles, the tiles become extremely distorted.
The tile drawn is actually bigger than the real tile and it seems like it has been stretched. Basically, say I have a 16x16 tile and I draw it. I can visually tell it is distorted when I run the program, and when I take a screenshot, I can measure the pixels and it has somehow become a 20x20.
I have also noticed that when I set a JFrame or a JPanel in the JFrame to a certain size, it is not the actual size that is produced. In my program I create a 320x320 JPanel and put it in a JFrame, but when I take a screenshot and measure the window, it comes up to about 399x399.
Can someone please tell me how to fix this. I stop every game project because the graphics keep looking like rubbish.
This is the Main class:
package main;
import javax.swing.SwingUtilities;
public class Main {
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
Engine e = new Engine();
e.start();
}
});
}
}
This is the Engine class:
package main;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
public class Engine {
public JFrame f;
public void initFrame() {
f = new JFrame();
f.setTitle("Something");
f.setResizable(false);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLocationRelativeTo(null);
}
public void start() {
initFrame();
BufferedImage tree;
try {
tree = ImageIO.read(new File("res/boy_down_1.png"));
Panel p = new Panel(tree);
f.add(p);
f.pack();
} catch (IOException e) {
e.printStackTrace();
}
f.setVisible(true);
}
}
This is the Panel class:
package main;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;
public class Panel extends JPanel {
BufferedImage i;
public Panel(BufferedImage image) {
i = image;
this.setDoubleBuffered(true);
this.setPreferredSize(new Dimension(320, 320));
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(i, 20, 20, null);
g2d.dispose();
}
}
This is the 16x16 I am trying to draw
This is what my computer shows me
I have tried multiple ways to specify the size of the image, but Java seems to distort my image no matter what I do. Thank you in advance.

Java resize an image

I would like to display an image in an area in my Jframe but the image takes up much space.
I would like to take it fair precise dimensions.
How can I do this in Java
This is my simple code :
I am open to any proposal if I did not use the right method or the right class to instantiate the image.
import java.awt.*;
import javax.swing.*;
public class ExempleDeplace extends JFrame{
private JLabel myLabel;
public ExempleDeplace(){
setLayout(new FlowLayout());
setTitle("Fenetre, modele Duchi");
setSize(500,700);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel j = new JLabel(new ImageIcon("src/images/bateau.png"));
add(j);
setVisible(true);
}
public static void main (String[] args) {
ExempleDeplace c = new ExempleDeplace();
}
}
You can paint the image in a JPanel as the whole panel. Then whenever the panel is resized, the image will be resized along with it. Here's a quick-n-dirty runnable demo:
import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ImgFrame extends JFrame {
private static BufferedImage IMG;
static{
try {
IMG = ImageIO.read(new File("img/Original_Doge_meme.jpg")); //Replace with your image path
} catch (IOException e) {
e.printStackTrace();
}
}
public ImgFrame(){
add(new ImgPanel(), BorderLayout.CENTER);
setSize(500,700);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
class ImgPanel extends JPanel{
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(IMG, 0, 0, getWidth(), getHeight(), this);
}
}
public static void main(String[] args){
new ImgFrame();
}
}
It's probably cleaner to just resize the image. I highly recommend the image resizing utility methods provided by filthyrichclients.
I actually highly recommend the book as well, as it was one of the few books that actually demonstrated the power of Swing...
Once you have the code, you will want to call
createCompatibleImage(myImage, myWidth,myHeight);

Java - JPanel can't draw background image

I am learning how to work with Gui's in java. Currently I'm trying to make a simple program that opens a Gui and draws an image to the background. The problem is that the background is completely white instead of the image.
Code:
Main.java:
package com.flaghacker.buckygame;
public class Main
{
public static void main(String[] args)
{
GuiFrame guiFrame = new GuiFrame();
}
}
GuiFrame.java:
package com.flaghacker.buckygame;
import javax.swing.JFrame;
public class GuiFrame extends JFrame
{
private GuiPanel guiPanel;
public GuiFrame()
{
//General
super("Title");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Size
this.setSize(1100, 650);
this.setResizable(true);
//Components
guiPanel = new GuiPanel();
this.add(guiPanel);
//Final
this.setVisible(true);
}
}
GuiPane.java:
package com.flaghacker.buckygame;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import java.awt.Graphics;
import java.awt.Image;
public class GuiPanel extends JPanel
{
private Image backGround;
public GuiPanel()
{
backGround = new ImageIcon("D:\\Install\\Java Projects\\Testing\\Bucky\\Back.jpg").getImage();
}
#Override
public void paint(Graphics g)
{
super.paint(g);
g.drawImage(backGround, 0, 0, null);
}
}
I test your code and it works ... the possible problem are two
first) your image isn't in
"D:\\Install\\Java Projects\\Testing\\Bucky\\Back.jpg"
i suggested you to use
"D:/Install/Java Projects/Testing/Bucky/Back.jpg"
and verify
Case insensitive.
second) the image Back.jpg have width and height more high of 1100 650 so you display only a top left angle of image

I can not get an image to pop up using Swing

I have googled this and searched through this site to try and get an Image to show up using Swing, but every time i implement the code i find online it doesn't work. I have no idea what i am doing wrong, can anyone help me?
package Game;
import java.awt.Dimension;
import java.awt.Graphics;
import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Amazing {
private int width = 300;
private int height = width / 16 * 9;
private int scale = 3;
private static Graphics g;
private static JFrame frame = new JFrame();
private static JPanel panel = new JPanel();
public Amazing(){
Dimension size = new Dimension(width*scale, height*scale);
frame.setPreferredSize(size);
frame.setResizable(false);
frame.setTitle("Amazing!");
frame.add(panel);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public static void main(String[] args){
Amazing amazing = new Amazing();
Character character = new Character();
character.paintComponent(g);
}
}
package Game;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
public class Character extends JPanel{
private BufferedImage image;
public Character(){
try {
image = ImageIO.read(new File("E:\\Libraries\\Documents\\Java Stuff\\workspace\\Java_Final\\narwhal.png"));
} catch (IOException ex) {
// handle exception...
}
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 50, 50, null); // see javadoc for more info on the parameters
}
}
Amazing amazing = new Amazing();
All that line of code does is create a frame and then add an empty panel to it. Since the panel is empty there is nothing to paint.
Character character = new Character();
character.paintComponent(g);
You should never invoke the paintComponent() method directly. Swing will invoke that method when a component needs to be repainted. Anyway, creating a Character object does nothing. That object is just sitting in memory. It is not added to a GUI so it can never be painted.
I suggest you forget about custom painting and just use a JLabel to display an image. Read the section from the Swing tutorial on How to Use Labels for a working example. Not only that, the tutorial will show you how to better structure your code. You should not be using static variables. Start with the working example and then customize it to use your image.

Drawing between 2 images in 1 JPanel

I want to draw the lines between 2 JScrollPanes (first scroll pane on the left side, second on the right). These JScrollPanes contain images. I want to draw lines between these 2 images (use some layers, use some trick etc.). I tried do it different ways, but i failed. Is it possible? (if not, i will have to make 2 images in one JScrollPane and it won't be nice).
EDIT
I want to draw between 2 images - throught components - get some points from images and draw lines between them. I apologize for poorly formulated question.
In order to accomplish this, I believe you'll need to make use of the Glass Pane. The Glass Pane sits on top of everything in the JRootPane and fills the entire view. This particular position allows two distinct capabilities:
Intercepting mouse and keyboard events
Drawing over the entire user interface
I believe your question is addressed by the second capability. The following is an example implementation, which you can later tailor to meet your own needs. Note that I've left out a lot of detail with regard to Glass Pane that you'll need to research on your own.
CODE
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class GlassPaneDemo {
private static BufferedImage bi;
public static void main(String[] args){
try {
loadImages();
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run() {
createAndShowGUI();
}
});
} catch (IOException e) {
// handle exception
}
}
private static void loadImages() throws IOException{
bi = ImageIO.read(new File("src/resources/person.png"));
}
private static void createAndShowGUI(){
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setGlassPane(new CustomGlassPane());
frame.getContentPane().add(getButtonPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.getGlassPane().setVisible(true);
frame.setVisible(true);
}
private static final JPanel getButtonPanel(){
#SuppressWarnings("serial")
final JPanel panel = new JPanel(){
#Override
protected void paintComponent(Graphics g){
Graphics gCopy = g.create();
gCopy.setColor(Color.BLUE.darker());
gCopy.fillRect(0, 0, getWidth(), getHeight());
gCopy.dispose();
}
};
final JLabel labelOne = new JLabel();
labelOne.setIcon(new ImageIcon(bi));
final JLabel labelTwo = new JLabel();
labelTwo.setIcon(new ImageIcon(bi));
panel.add(labelOne);
panel.add(labelTwo);
return panel;
}
#SuppressWarnings("serial")
private static class CustomGlassPane extends JComponent{
private Point p1;
private Point p2;
private boolean lineDrawn;
public CustomGlassPane(){
addMouseListener(new MouseAdapter(){
#Override
public void mouseClicked(MouseEvent e){
if(p1 == null || lineDrawn){
if(lineDrawn){
p1 = null;
p2 = null;
lineDrawn = false;
}
p1 = e.getPoint();
}else{
p2 = e.getPoint();
repaint(); // not optimal
lineDrawn = true;
}
}
});
// Block all other input events
addMouseMotionListener(new MouseMotionAdapter(){});
addKeyListener(new KeyAdapter(){});
addComponentListener(new ComponentAdapter(){
#Override
public void componentShown(ComponentEvent e){
requestFocusInWindow();
}
});
setFocusTraversalKeysEnabled(false);
}
#Override
protected void paintComponent(Graphics g){
if(p1 != null && p2 != null){
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(Color.RED);
g2.drawLine((int)p1.getX(), (int)p1.getY(), (int)p2.getX(), (int)p2.getY());
g2.dispose();
}
}
}
}
OUTPUT
EXPLANATION
In this example, I clicked two arbitrary points within each JLabel, and then drew a connecting line.
This should be very possible. You will need to create a custom component that is aware of both vertical ScrollBars. It should add itself as an AdjustmentListener to each scroll bar in order to detect changes and repaint the lines between the two.
See:
addAdjustmentListener method in the API
You can use this
http://java-sl.com/connector.html
as an example of such code.

Categories