I am currently trying to render an Image to a JPanel. Here is my Code:
import java.awt.Graphics;
import java.awt.Image;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
public class ScreenSaver extends JPanel {
private static final long serialVersionUID = 001;
public static void main(String[] args) {
new ScreenSaver();
}
public ScreenSaver() {
new Window(1600, 900, "ScreenSaver", this);
}
public Image ball;
public void initCode() {
try {
File pathToBall = new File("ball.png");
ball = ImageIO.read(pathToBall);
} catch (IOException ex) {
ex.printStackTrace();
}
renderImage()
}
public void renderImage(Graphics g) {
g.drawImage(ball, 0, 0, 100, 100, null);
}
}
The "initCode()" method gets called after the JFrame has loaded. My problem now is that I want to call the "renderImage()" method. In the parameters I have to put "Graphics g" to use the "g.drawImage" function. Sadly I now dont know what to put in the brackets when I want to call "renderImage()". Can someone help?
The painting of pictures and graphic elements works a little differently than in your question.
Here is a working example:
import java.awt.*;
import java.io.*;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.swing.*;
public class PaintExample extends JFrame{
private BufferedImage ball;
public static void main(String[] args) {
new PaintExample();
}
public PaintExample(){
initCode();
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setPreferredSize(new Dimension(1600, 900));
setMinimumSize(new Dimension(800, 600));
add(new JPanel(){
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(ball, 0, 0, 100, 100, this);
}
});
pack();
setLocationRelativeTo(null);
setTitle("Paint Example");
setVisible(true);
}
public void initCode() {
try {
File pathToBall = new File("ball.png");
ball = ImageIO.read(pathToBall);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
I hope this solves your problem.
Swing is event driven, this means that you never directly call painting methods.
Basics for a custom painting component:
extends JComponent
override paintComponent(Graphics g), this is the point where you can put your rendering code
override getPreferredSize(), so that the layout managers can do their duty, a suitable value is your image size
In addition I don't understand this line:
new Window(1600, 900, "ScreenSaver", this);
Related
I'm just beginner at Java Programming and am using NetBeans. The code below runs and No Error is displayed but no image is seen! This image is in the "frame" package beside this two classes.
package frame;
import javax.swing.JPanel;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Screen extends JPanel{
private BufferedImage image;
public Screen(){
try {
System.out.println("OK");
image = ImageIO.read(getClass().getResourceAsStream("phantomPDF.png"));
} catch(IOException e) {
e.printStackTrace();
}
repaint();
}
public void paint(Graphics g){
g.drawImage(image, 100, 100, null);
System.out.println("Yes");
}
}
and this is my frame and main method :
package frame;
import java.awt.GridLayout;
import javax.swing.*;
public class Frame extends JFrame{
Screen s;
public Frame() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400, 600);
setResizable(false);
setTitle("Graphics");
setVisible(true);
init();
}
public void init(){
setLocationRelativeTo(null);
setLayout(new GridLayout(1, 1, 0, 0));
s = new Screen();
add(s);
}
public static void main(String[] args){
new Frame();
}
}
I had to put "try - catch" statement into "paint" class so that works fine now ... but why should i do that?
I've been trying tp paint an image of a cheetah just to mess around with the paint method and such, but it doesn't seem to be working, any idea why?
I've tried a ton of stuff i found on here but nothing seems toi work at all, all i get is my button, i know its the actual paint method not working because it doesn't even pain the Hello string.
Here's the main class:
package dev.main;
import javax.swing.JFrame;
import javax.swing.JPanel;
import dev.angora.gui.GameGUI;
#SuppressWarnings("serial")
public class Main extends JFrame {
public static JFrame p = new JFrame("Angora Realms");
public static void main (String[] args) {
new Main();
}
public Main() {
p.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
p.pack();
p.setSize(640, 800);
p.setVisible(true);
p.setLayout(null);
GameGUI g = new GameGUI();
g.createGui(p);
}
}
And here is the class I try to paint in:
package dev.gui;
import java.awt.Button;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URL;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class GameGUI extends JFrame implements ActionListener {
public Button drawCard = new Button("Draw Card");
public Image cheetah = null;
public void createGui(JFrame p) {
drawCard.addActionListener(this);
drawCard.setBounds(20,30,80,30);
p.add(drawCard);
}
#Override
public void actionPerformed(ActionEvent event) {
Object cause = event.getSource();
if (cause == drawCard) {
System.out.println("Ay");
}
}
public void paintComponent(Graphics g) {
super.paint(g);
g.drawString("Hello", 200, 50);
if (cheetah == null) {
cheetah = getImage("plains/Cheetah.png");
Graphics2D g2 = (Graphics2D)g;
g2.drawImage(cheetah, 100, 100, 100, 300, this);
}
}
public Image getImage(String path) {
Image tempImage = null;
try {
URL imageURL = GameGUI.class.getResource(path);
tempImage = Toolkit.getDefaultToolkit().getImage(imageURL);
}
catch (Exception e) {
System.out.println("An error occured -" + e.getMessage());
}
return tempImage;
}
} '
You're creating something like three JFrames, so it's kind of hard to track where things are actually going. There is no need to use extends JFrame for either of the two classes you presented, in fact, this will highlight the cause of your error...
JFrame does not have a paintComponent method, so it will never be called, instead, change GameGUI to extend from JPanel and add #Override to the start of the paintComponent method declaration (before it), then change super.paint(g); to super.paintComponent(g);
For example...
public class GameGUI extends JPanel implements ActionListener {
public Button drawCard = new Button("Draw Card");
public Image cheetah = null;
public void createGui(JFrame p) {
drawCard.addActionListener(this);
drawCard.setBounds(20,30,80,30);
p.add(drawCard);
}
#Override
public void actionPerformed(ActionEvent event) {
Object cause = event.getSource();
if (cause == drawCard) {
System.out.println("Ay");
}
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
No offense, but I'm not a fan of passing a reference of the "container" to the child component so it can add itself in this way. Better to create an instance of GameGUI and add it to what ever container you want. The GameGUI doesn't need to know or care...IMHO
Runnable Example
Don't use pack and setSize, they are competing with each other. The content of the frame should dictate the size of the frame. This is done through the use of appropriate layout managers and overriding getPreferredSize of custom components.
Don't call setVisible until AFTER you've established the base UI
Make sure you are adding your components to a displayable surface if you expect them to be painted
Also, you're mixing heavy weight (java.awt.Button) and light weight (Swing/javax.swing.JFrame) components together...my recommendation is, don't, this will cause a bunch of other issues you really don't need to deal with.
import java.awt.Button;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URL;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main extends JFrame {
public static void main(String[] args) {
new Main();
}
public Main() {
JFrame p = new JFrame("Angora Realms");
p.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GameGUI g = new GameGUI();
p.add(g);
p.setSize(640, 800);
p.setVisible(true);
}
public class GameGUI extends JPanel implements ActionListener {
public Button drawCard = new Button("Draw Card");
public Image cheetah = null;
public GameGUI() {
drawCard.addActionListener(this);
add(drawCard);
}
#Override
public void actionPerformed(ActionEvent event) {
Object cause = event.getSource();
if (cause == drawCard) {
System.out.println("Ay");
}
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawString("Hello", 200, 50);
if (cheetah == null) {
cheetah = getImage("plains/Cheetah.png");
Graphics2D g2 = (Graphics2D) g;
g2.drawImage(cheetah, 100, 100, 100, 300, this);
}
}
public Image getImage(String path) {
Image tempImage = null;
try {
URL imageURL = GameGUI.class.getResource(path);
tempImage = Toolkit.getDefaultToolkit().getImage(imageURL);
} catch (Exception e) {
System.out.println("An error occured -" + e.getMessage());
}
return tempImage;
}
}
}
Eventually after I work out this small detail it will receive a building and room number to outline said building and room number so it is easy to locate but I can't get the rectangle to draw even close to acurately over a single room.
package programSTLApp;
/*
Program to request the classroom no. in STLCC and Display the location of
that classroom.
*/
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class STLApp extends JFrame
{
private JLabel imageLabel;
private JButton button;
private JPanel imagePanel;
private JPanel buttonPanel;
public STLApp()
{
super("My STLCC Class Locator");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
buildImagePanel();
buildButtonPanel();
add(imagePanel, BorderLayout.CENTER);
add(buttonPanel,BorderLayout.SOUTH);
pack();
setVisible(true);
}
private void buildImagePanel()
{
imagePanel = new JPanel();
imageLabel = new JLabel("Click the button to see the drawing indicating "
+ "the location of your class");
imagePanel.add(imageLabel);
}
private void buildButtonPanel()
{
buttonPanel = new JPanel();
button = new JButton("Get Image");
button.addActionListener(new ButtonListener());
buttonPanel.add(button);
}
private class ButtonListener implements ActionListener
{
#Override
public void actionPerformed(ActionEvent e)
{
ImageIcon SiteLayoutFV = new ImageIcon("D:\\B120.jpg");
imageLabel.setIcon(SiteLayoutFV);
imageLabel.setText(null);
pack();
}
}
public void paint(Graphics g)
{
super.paint(g);
g.setColor(Color.RED);
g.fillRect(55,740,164,815);
}
public static void main(String[] args)
{
new STLApp();
}
}
As has already being pointed out, top level containers ain't a studiable class for performing custom painting, there is just to much going with these containers to make it easy to paint to.
Instead, create yourself a custom component, extending from something like JPanel, and override it's paintComponent method.
Once you have the floor pane rendered, you can render you custom elements over the top of it.
How you store this information is up to you, but basically, you need some kind of mapping that would allow you to take the floor/room and get the Shape that should be rendered.
Because the floor map might float (it may not always be rendered at 0x0 for example), you need to be able to translate the coordinates so that the Shape will always match.
Take a look at...
Performing Custom Painting
2D Graphics
For more details
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
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.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class FloorPlan {
public static void main(String[] args) {
new FloorPlan();
}
public FloorPlan() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private BufferedImage floorPlan;
private Rectangle myOffice = new Rectangle(150, 50, 32, 27);
public TestPane() {
try {
floorPlan = ImageIO.read(new File("floorPlan.png"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
#Override
public Dimension getPreferredSize() {
return floorPlan == null ? new Dimension(200, 200) : new Dimension(floorPlan.getWidth(), floorPlan.getHeight());
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
if (floorPlan != null) {
int x = (getWidth() - floorPlan.getWidth()) / 2;
int y = (getHeight() - floorPlan.getHeight()) / 2;
g2d.drawImage(floorPlan, x, y, this);
g2d.setColor(Color.RED);
g2d.translate(x, y);
g2d.draw(myOffice);
}
g2d.dispose();
}
}
}
I am drawing an image on JTextArea background, it is drawn using other look and feels (Metal, Windows etc) but when I use Nimbus Look And Feel it does not draw image What can be the possible problem and how to fix that?
Here is the code I am using
Image TextArea Class
public class ImageTextArea extends JTextArea{
File image;
public ImageTextArea(File image)
{
setOpaque(false);
this.image=image;
}
#Override
public void paintComponent(final Graphics g)
{
try
{
// Scale the image to fit by specifying width,height
g.drawImage(new ImageIcon(image.getAbsolutePath()).getImage(),0,0,getWidth(),getHeight(),this);
super.paintComponent(g);
}catch(Exception e){}
}
}
And the Test class
public class TestImageTextArea extends javax.swing.JFrame {
private ImageTextArea tx;
public TestImageTextArea() {
tx = new ImageTextArea(new File("img.jpg"));
setTitle("this is a jtextarea with image");
setDefaultCloseOperation(EXIT_ON_CLOSE);
JPanel mainp = new JPanel(new BorderLayout());
add(mainp);
mainp.add(new JScrollPane(tx), BorderLayout.CENTER);
setSize(400, 400);
}
public static void main(String args[]) {
/*
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (Exception ex) {
System.out.println("Unable to use Nimbus LnF: "+ex);
}
*/
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new TestImageTextArea().setVisible(true);
}
});
}
}
When I remove the comments it does not draw image.
Basically, when you call super.paintComponent, it will call the UI delgate's update method. This is where the magic happens.
Below is the Nimbus's SynthTextAreaUI implementation
public void update(Graphics g, JComponent c) {
SynthContext context = getContext(c);
SynthLookAndFeel.update(context, g);
context.getPainter().paintTextAreaBackground(context,
g, 0, 0, c.getWidth(), c.getHeight());
paint(context, g);
context.dispose();
}
As you can see, it actually paints the background, with out regard for the opaque state of the component, then calls paint, which will call the BasicTextUI.paint method (via super.paint)
This is important, as BasicTextUI.paint actually paints the text.
So, how does that help us? Normally, I'd crucify someone for not calling super.paintComponent, but this is exactly what we're going to do, but we're going to do it knowing in advance what responsibility we're taking on.
First, we're going to take over the responsibilities of update, fill the background, paint our background and then call paint on the UI delegate.
import java.awt.BorderLayout;
import java.awt.Color;
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.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class NimbusTest {
public static void main(String[] args) {
new NimbusTest();
}
public NimbusTest() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new JScrollPane(new TestTextArea()));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestTextArea extends JTextArea {
private BufferedImage bg;
public TestTextArea() {
try {
bg = ImageIO.read(new File("C:\\Users\\swhitehead\\Documents\\My Dropbox\\Ponies\\Rainbow_Dash_flying_past_3_S2E16.png"));
} catch (IOException ex) {
Logger.getLogger(NimbusTest.class.getName()).log(Level.SEVERE, null, ex);
}
}
#Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
// Fill the background, this is VERY important
// fail to do this and you will have major problems
g2d.setColor(getBackground());
g2d.fillRect(0, 0, getWidth(), getHeight());
// Draw the background
g2d.drawImage(bg, 0, 0, this);
// Paint the component content, ie the text
getUI().paint(g2d, this);
g2d.dispose();
}
}
}
Make no mistake. If you don't do this right, it will screw not only this component but probably most of the other components on your screen.
I'm trying to make a simple GUI using JAVA
no image is shown
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.*;
import javax.swing.*;
import javax.imageio.*;
public class EmiloLadderSnack {
public JFrame frame=new JFrame("EmiloLadderSnack");
public Image img;
public Graphics g;
public EmiloLadderSnack()
{
frame.setBounds(0, 0, Toolkit.getDefaultToolkit().getScreenSize().width, Toolkit.getDefaultToolkit().getScreenSize().height);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
try
{
img= ImageIO.read(new File("/media/01CCE00FA6888D80/Achieve/Eclipse/EmiloLadderSnack/src/photo.jpg"));
g.drawImage(img, 50, 50, null);
}
catch(Exception e)
{
System.out.println(e.toString());
}
}
public static void main(String args[])
{
new EmiloLadderSnack();
}
}
please help me to show an image in my simple GUI using JAVA
I'm using Eclipse
Hovercraft Full Of Eels is right, as he/she usually is. It really did not look like you tried.
Look at the tutorials, but I do believe when Hovercraft Full Of Eels says the correct way, hover means as follows.
Let me explain what I did below. First I created a new class that extended the JFrame. The JFrame is what is suppose to hold all of the components in a window. Then draw on the JPanel so that all of your drawings are contained in a lightweight container. I set the layout with a new layout I just discovered due to StackOverflow which I am very thankful for. The layout is called the MigLayout and it is a third party resource. You have to download it and import it. Please note that you do not have to have the MigLayout, but it is preferable to use due to its ease of use. After I set the Layout Constraint to fill and docked the JPanel in the center I created a new class which extended the JPanel so that I could change the paint method. The #Override lets you, in a way, re create the method for that extended class. As you can see once draw to that one graphics class then you are all set. There is a lot more you should read up on. Read the comments below your post, they suggest fairly good material.
Anything I get wrong Hovercraft will say below in the comments. So look for that as well.
Hovers corrections:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class GraphicExample extends JPanel {
private static final String IMG_FILE_PATH = "/media/01CCE00FA6888D80/" +
"Achieve/Eclipse/EmiloLadderSnack/src/photo.jpg";
private BufferedImage img;
public GraphicExample(BufferedImage img) {
this.img = img;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
g.drawImage(img, 0, 0, this);
}
}
#Override
public Dimension getPreferredSize() {
if (img != null) {
return new Dimension(img.getWidth(), img.getHeight());
}
return super.getPreferredSize();
}
private static void createAndShowGui() {
try {
BufferedImage img = ImageIO.read(new File(IMG_FILE_PATH));
JFrame frame = new JFrame("GraphicExample");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new GraphicExample(img));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
// the easy way to display an image -- in a JLabel:
ImageIcon icon = new ImageIcon(img);
JLabel label = new JLabel(icon);
JOptionPane.showMessageDialog(frame, label);
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
My initial recommendations:
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
import net.miginfocom.swing.MigLayout;
public class DrawCircle extends JFrame {
JPanel panel;
public DrawCircle(String title, int width, int height) {
this.setTitle(title);
this.setSize(width, height);
this.setLocationRelativeTo(null); // Center JFrame
this.setLayout(new MigLayout("fill")); // Download external jar
this.panel = new DrawOval();
this.add(panel, "dock center"); // Link: http://www.miglayout.com/
this.setVisible(true);
}
public class DrawOval extends JPanel {
Color color = new Color(1, 1, 1);
public DrawOval() {
}
#Override
public void paint(Graphics g) {
g.setColor(color.RED);
g.fillOval(0, 0, this.getWidth(), this.getHeight());
}
}
}
I can't imagine that this is compiling. There must be a NullPointerException.
When you want to draw something you usually subclass JPanel and do the drawing in the paintComponent() method, like this:
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(img, 50, 50, null);
}