g.drawImage not successful, completely stumped - java

Trying to draw an image and I have no idea why it's not appearing on the screen. Image is loaded fine.
System.out.printf("%nPlayer_1.img_player1 is: "+Player_1.img_player1); says that the image is loaded correctly (correct image w/h etc).
Have tried all manner of image observers, drawing the image from different classes (namely Player_1.drawSquare and MyPanel.painComponent)
There are regular repaint() requests coming in from the Control class, but I do not believe this is preventing the drawing.
No error's are thrown.
player_1.gif is located within the game_2 package, I have tried running the code with it in the src and root folder.
package test;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.net.URL;
public class Main{
public static void main(String[] args) {
GUI.main(args);
}
}
class GUI {
static JFrame f = new JFrame("Swing Paint Demo");
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
System.out.printf("%nCreated GUI on EDT? "+
SwingUtilities.isEventDispatchThread());
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new MyPanel());
f.setSize(640,640);
f.setVisible(true);
}
}
class MyPanel extends JPanel {
public MyPanel() {
//setBorder(BorderFactory.createLineBorder(Color.black));
}
public Dimension getPreferredSize() {
return new Dimension(640,640);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
System.out.printf("%nPaincomponent on GUI");
Player_1.paintSquare(g);
System.out.printf("%nPlayer_1.img_player1 is: "+Player_1.img_player1);
}
}
class Player_1{
public static Image img_player1;
public int int_x = 0;
public int int_y = 1;
public int int_w = 1;
public int int_h = 1;
public static void paintSquare(Graphics g){
if (img_player1 == null)
img_player1 = IOControl.getImage("player_1.gif");
g.drawImage(img_player1, 32, 32, 32, 32, GUI.f);
}
}
class IOControl {
public static void main(String[] args) {
}
static BufferedImage getImage(String path)
{
BufferedImage tempImage = null;
try
{
URL imageURL = Main.class.getResource(path);
tempImage = toBufferedImage(Toolkit.getDefaultToolkit().getImage(imageURL));
}
catch(Exception e)
{
System.out.printf("%nAn error occured -" + e.getMessage());
}
System.out.printf("%n"+path);
System.out.printf("%nIOControl.path");
System.out.printf("%n"+tempImage);
System.out.printf("%nIOControl.tempImage");
return tempImage;
}
public static BufferedImage toBufferedImage(Image img)
{
if (img instanceof BufferedImage)
{
return (BufferedImage) img;
}
// Create a buffered image with transparency
BufferedImage bimage = new BufferedImage(32, 32, BufferedImage.TYPE_INT_ARGB);
// Draw the image on to the buffered image
Graphics2D bGr = bimage.createGraphics();
bGr.drawImage(img, 0, 0, null);
bGr.dispose();
// Return the buffered image
return bimage;
}
}

Don't call the main method. It is meant for the JVM to call as the starting point of your program. Also, you should only have one main method, in whichever class is the launching class.
Don't create the image in the paintXxx method. You should create in the constructor.
All the other faulty points I mentioned in my comments in the original post.
It looks like your main problem is in the getImage method. I simplified it for you and it works (given I fixed the other points I mentioned above).
public static BufferedImage getImage(String path) {
BufferedImage img = null;
try {
img = ImageIO.read(GUI.class.getResource(path));
} catch (IOException ex) {
ex.printStackTrace();
}
return img;
}
Here's the full running code. Note: you had the image location correct, with it in the same package as the Main class.
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new GUI().createAndShowGUI();
}
});
}
}
class GUI {
JFrame f = new JFrame("Swing Paint Demo");
public void createAndShowGUI() {
System.out.printf("%nCreated GUI on EDT? "
+ SwingUtilities.isEventDispatchThread());
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new MyPanel());
f.setSize(640, 640);
f.setVisible(true);
}
}
class MyPanel extends JPanel {
Player_1 player1;
public MyPanel() {
player1 = new Player_1(MyPanel.this);
}
public Dimension getPreferredSize() {
return new Dimension(640, 640);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
System.out.printf("%nPaincomponent on GUI");
player1.paintSquare(g);
}
}
class Player_1 {
public Image img_player1;
public int int_x = 0;
public int int_y = 1;
public int int_w = 1;
public int int_h = 1;
JPanel panel;
public Player_1(JPanel panel) {
this.panel = panel;
img_player1 = IOControl.getImage("player_1.png");
}
public void paintSquare(Graphics g) {
g.drawImage(img_player1, 32, 32, 32, 32, panel);
}
}
class IOControl {
public static BufferedImage getImage(String path) {
BufferedImage img = null;
try {
img = ImageIO.read(GUI.class.getResource(path));
} catch (IOException ex) {
ex.printStackTrace();
}
return img;
}
}

Related

Calling Graphics.drawImage in the contructor of a JFrame Java [duplicate]

I'm new on working with Java and Netbeans. In many others languages, it's a simple stuff to do. But after broke my brain thinking, I couldn't. My doubt is simple to explain.
How can I show bitmaps (stored on Hard Drive) in runtime, in a commom JFrame, using java2D? What I need to edit, and or create? Is it simple to do?
Thanks in advance...
The basic process is use Graphics#drawImage to render an image you have previously loaded.
There are a number of things you need in order to achieve this...
An image to paint
A surface to paint on
Luckily, both these are relatively easy to achieve in Swing
See ImageIO for reading images, Reading/Loading an Image
See Performing Custom Painting for more details about how to perform painting in Swing...
import java.awt.BorderLayout;
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 ShowMyImage {
public static void main(String[] args) {
new ShowMyImage();
}
public ShowMyImage() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
ImagePane pane = new ImagePane();
try {
pane.setImg(ImageIO.read(new File("C:\\hold\\thumbnails\\_MTCGAC__Pulling_Cords_by_Dispozition.png")));
} catch (IOException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(pane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class ImagePane extends JPanel {
private BufferedImage img;
public ImagePane() {
}
public void setImg(BufferedImage value) {
if (img != value) {
img = value;
repaint();
}
}
public BufferedImage getImg() {
return img;
}
#Override
public Dimension getPreferredSize() {
BufferedImage img = getImg();
return img == null ? new Dimension(200, 200) : new Dimension(img.getWidth(), img.getHeight());
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
BufferedImage img = getImg();
if (img != null) {
int x = (getWidth() - img.getWidth()) / 2;
int y = (getHeight()- img.getHeight()) / 2;
g2d.drawImage(img, x, y, this);
}
g2d.dispose();
}
}
}
You need, as was told below to extend JPanel class and override paintComponent method in it.
public class DrawImageClass extends JPanel {
private static final long serialVersionUID = 1L;
private Image image;
public DrawImageClass(Image image) throws HeadlessException {
super();
this.image = image;
}
#Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
g2d.drawImage(image, null, null);
}
}
And then create JFrame and add this class to it.
public class App {
private static final int WIDTH=480, HEIGHT = 640;
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setSize(new Dimension(HEIGHT, WIDTH));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
try {
DrawImageClass panel = new DrawImageClass(ImageIO.read(new File(App.class.getResource("/1.png").getPath())));
panel.setPreferredSize(new Dimension(HEIGHT, WIDTH));
frame.add(panel);
frame.setVisible(true);
} catch (Exception e) {
System.out.println("wrong path or smth other");
}
}
}
Example for picture which is in resource folder in project
You can do this with the basic AWT package in java. You will need to extend the JFrame class and override its paintComponent method to display an image there. i.e.
public class MyFrame extends JFrame {
private java.awt.Image bitmap = ImageIO.read(new File("myBitmap.bmp"));
#Override
public void paintComponent(java.awt.Graphics graphics) {
int x = 0;
int y = 0;
int w = bitmap.getWidth(null);
int h = bitmap.getHeight(null);
graphics.drawImage(bitmap, x, y, w, h, this);
}
}
You can simply instantiate it then
MyFrame myFrame = new MyFrame();
myFrame.setPreferredSize(new Dimension(100, 100));
myFrame.setVisible(true);
This is a basic example of course.

How to setImage of each words translate into one to another by using imageArray

I made 5 java classes that their goals were to Translate English into French and to setup the image of each words writing in the Jfield1 when you click on the Jbutton.
My applet arrive to translate each English words writing in JField1 into French words in JField2. And I add two more Classes(ImageImplement and ImageInFrame) for setting up the image But unfortunately nothing work. And I really don’t know how to use imageArray.
Please help me!!!
I am sorry my english is not so good.
THIS IS MY APPLET
My first Class is StringArrayEnglishWord
public class StringArrayEnglishWords extends JPanel {
String[] names;
Graphics2D g2d;
public StringArrayEnglishWords(){
EnglishWords();
// drawNames();
}
public void paintComponent (Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
}
public void EnglishWords(){
names=new String[16];
names[0]="Tomatoes";
names[1]="Chairs";
names[2]="Car";
names[3]="Computer";
names[4]="Flowers";
names[5]="Family";
names[6]="Sister";
names[7]="Husband";
names[8]="God";
names[9]="Book";
names[10]="Watch";
names[11]="Pencil";
names[12]="Bottle";
names[13]="Map";
names[14]="Wife";
names[15]="Bag";
}
public void drawNames(){
for (int i=0; i<names.length; i++){
g2d.drawString(names[i], 50, (1+i)*16);
}
}
public int indexOfWord(String userInput)
{
for(int i=0;i<names.length;i++)
{
if(userInput.equals(names[i])){return i;}
}
return -1;
}
}
My second classes is StringArrayFrenchWords:
public class StringArrayFrenchWords extends JPanel {
String[] names2;
Graphics2D g2d;
public StringArrayFrenchWords(){
FrenchWorld();
// drawNames();
}
public void paintComponent (Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
}
public void FrenchWorld(){
names2=new String[16];
names2[0]="Tomate";
names2[1]="Chaise";
names2[2]="Voiture";
names2[3]="Ordinateur";
names2[4]="Fleurs";
names2[5]="Familles";
names2[6]="Soeur";
names2[7]="Epoux, Mari";
names2[8]="Dieu";
names2[9]="Livre";
names2[10]="Montre, Regarder";
names2[11]="Crayon";
names2[12]="Bouteille";
names2[13]="Carte,plan";
names2[14]="Femmme";
names2[15]="Sac";
}
public void drawNames(){
for (int i=0; i<names2.length; i++){
g2d.drawString(names2[i], 50, (1+i)*16);
}
}
}
My third Classe is extend Japplet (Translator):
public class Translator extends JApplet implements ActionListener {
String StringField1, StringImage;
StringArrayEnglishWords Englishw;
StringArrayFrenchWords Frenchw;
ImageInJframe img;
ImageImplement Images;
Image Image;
JButton[] buttons;
JComboBox[] comboBoxes;
JButton TranslateButton;
JPanel JPanel0,JPanel1;
JPanel buttonPanel;
JPanel comboBoxesPanel;
JTextField field1,field2;
ImageIcon Imageicon;
JLabel ImageLabel;
public void init(){
setUpFields();
Englishw=new StringArrayEnglishWords();
Frenchw=new StringArrayFrenchWords();
img = new ImageInJframe(); // this was for set up the image
setUpimages();// for setup image too
}
public void setUpFields() {
TranslateButton = new JButton("TranslateButton");
field1 = new JTextField(10);
field2 = new JTextField(10);
field2.setEditable(false);
JPanel0 = new JPanel(new FlowLayout());
JPanel0.add(field1);
TranslateButton.addActionListener(this);
field1.addActionListener(this);
field2.addActionListener(this);
JPanel0.add(TranslateButton);
JPanel0.add(field2);
add(JPanel0, BorderLayout.SOUTH);
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
}
public void setUpimages() {//setUp images too
ImageLabel.setIcon((Icon) img);
JPanel1 = new JPanel(new FlowLayout());
JPanel1.add(ImageLabel);
add(JPanel1, BorderLayout.CENTER);
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == TranslateButton) {
System.out.println(field1);
StringField1 = field1.getText();
int index = Englishw.indexOfWord(StringField1);//this will give you the index of the word
if (index == -1) {
field2.setText("Word not found.");
System.out.println(field2);
} else {
field2.setText(Frenchw.names2[index]);
System.out.println("English Words=" + field1.getText());
System.out.println("French Words =" + field2.getText());
//setup Image
Image = img.getIconImage();
int index2 = img.indexOfImage(StringImage);
JPanel1.add(img);
}
}
}
}
My two classes was for seting up images bu using JFame and imageArray: ImageInJframe and ImageImplement
public class ImageInJframe extends JFrame {
JFrame Frame;
Image[] pics;
String[] names = {"apple.jpg", "bags.jpg", "bathroom.jpg", "battled.jpg", "car.png",
"chairs.jpg", "Computer.jpg", "family.jpg", "flowers.jpg", "god.jpg", "house.png", "map.jpg"
, "men.jpg", "pencil.jpg", "sisters.jpg", "tomato.jpg", "watch.jpg", "women.jpg", "book.gif"};
final int NUM_PICS=names.length;
Graphics g;
public static void main(String args[])
{
new ImageInJframe().start();
}
public void start()
{
ImageImplement panel = new ImageImplement(new ImageIcon(String.valueOf(pics)).getImage());
add(panel);
setVisible(true);
setSize(400,400);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setImage();
}
public void setImage() {
pics = new Image[NUM_PICS];
}
public int indexOfImage(String userInput)
{
for(int i=0;i<pics.length;i++)
{
if(userInput.equals(pics[i])){return i;}
}
return -1;
}
}
ImageImplement extend JPanel:
public class ImageImplement extends JPanel {
Image img;
public ImageImplement(Image img) {
this.img = img;
Dimension size = new Dimension(img.getWidth(null), img.getHeight(null));
setPreferredSize(size);
setMinimumSize(size);
setMaximumSize(size);
setSize(size);
setLayout(null);
}
public void paintComponent(Graphics g) {
g.drawImage(img, 0, 0, null);
}
Painting occurs on demand, when your paintComponent is called, you are expected to repaint the current state of the UI. Maybe you should start by taking a look at Painting in AWT and Swing and Performing Custom Painting for more detals about how painting works
Basically, from your paintComponent, you need to call draw, but you should pass it the Graphics context that was passed to the paintComponent method. It's dangerous and unwise to maintain a reference to a Graphics context you did not create
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
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.add(new StringArrayEnglishWords());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class StringArrayEnglishWords extends JPanel {
String[] names;
public StringArrayEnglishWords() {
EnglishWords();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
drawNames(g2d);
g2d.dispose();
}
public void EnglishWords() {
names = new String[16];
names[0] = "Tomatoes";
names[1] = "Chairs";
names[2] = "Car";
names[3] = "Computer";
names[4] = "Flowers";
names[5] = "Family";
names[6] = "Sister";
names[7] = "Husband";
names[8] = "God";
names[9] = "Book";
names[10] = "Watch";
names[11] = "Pencil";
names[12] = "Bottle";
names[13] = "Map";
names[14] = "Wife";
names[15] = "Bag";
}
public void drawNames(Graphics2D g2d) {
for (int i = 0; i < names.length; i++) {
g2d.drawString(names[i], 50, (1 + i) * 16);
}
}
public int indexOfWord(String userInput) {
for (int i = 0; i < names.length; i++) {
if (userInput.equals(names[i])) {
return i;
}
}
return -1;
}
}
}
You should also be careful when modifying the Graphics context, it is shared by all the components which are within the same window, in most cases, I find it useful to take a snapshot of the Graphics context (Graphics#create) and use that, then I don't need to remember to reset it when I'm done.
Applets are also a dead technology, the plugin has been deprecated and is no longer been supported and in most cases, is actively blocked by most browsers. See Java Plugin support deprecated and Moving to a Plugin-Free Web for more details
Updated
Change...
ImageImplement panel = new ImageImplement(new ImageIcon(String.valueOf(pics)).getImage());
add(panel);
to...
JLabel panel = new JLabel(new ImageIcon(names[0]).getImage());
add(panel);
Assuming the image files are in the current directory where the program is been executed from, then it should work. If they are contained within the package with the class files, then you'll need to use Class#getResource to obtain a reference to the the image and pass the resulting URL to ImageIcon
Your ImageImplement panel is doing nothing, so even if it had a proper image to show, it wouldn't show anything.
String.valueOf(pics) makes no sense at all
You've posted a whole bunch of, what seems to be unrelated code and it's difficult to know what problem you're referring to
This...
ImageLabel.setIcon((Icon) img);
Makes no sense, img is an instance of ImageInJFrame, how is that even remotely related to a Icon?
I officially have no idea what you're trying to do

Placing JButton on image

Aim: to place JButton on a top of an image that is loaded from a different class.
Problem: only JButton or image can be displayed
//main class
JPanel mPanel.add(new JButton("ddd") );
mPanel.add(drawbg);
class DrawBg extends JPanel {
public Dimension getPreferredSize() {
return new Dimension(1280, 720);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
// background
Image img = new ImageIcon(getClass().getResource("/images/test_bg.jpg")).getImage();
int imgX = img.getWidth(null);
int imgY = img.getHeight(null);
g.drawImage(img, (getWidth() - imgX), (getHeight() - imgY), imgX, imgY, null);
}
Edit Ah yes, as ControlAltDel points out, you're not adding your JButton to your drawing JPanel instance. Just do that, and your problem is solved.
I don't see the bug in your code, so it might lie in code not shown. I do see a problem in that you're reading the image in, inside of paintComponent, something that should never be done as it will slow down painting and thus slow down the perceived responsiveness of your program. Also, why re-read in the image with each paint. Instead read it in once.
For example:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
public class ButtonOnImg extends JPanel {
public static final String IMG_PATH = "https://duke.kenai.com/gun/Gun.jpg";
private BufferedImage img;
public ButtonOnImg() throws IOException {
URL url = new URL(IMG_PATH);
img = ImageIO.read(url);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
g.drawImage(img, 0, 0, null);
}
}
#Override
public Dimension getPreferredSize() {
if (img == null) {
return super.getPreferredSize();
} else {
int w = img.getWidth();
int h = img.getHeight();
return new Dimension(w, h);
}
}
private static void createAndShowGui() {
try {
ButtonOnImg mainPanel = new ButtonOnImg();
mainPanel.add(new JButton("Button!"));
JFrame frame = new JFrame("ButtonOnImg");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Which displays as:

Having trouble with dynamically updating a BufferedImage

I'm trying to render a dynamically changing image on a JPanel. I have tried many things and I simply do not get how to do it or what I'm doing wrong and I'm at the point of going insane. I'm new to swing and this is a small but essential part of my program which enables me to see what I'm doing.
The simple requirement is the picture rendered initially in the JPanel in the code mentioned below should update at each tick with random colors. I cannot get the image to update. Instead I get another square appearing in the middle of the image I'm trying to update and that small square dynamically changes. I do not know what I'm doing wrong. Please let me know how to rectify the code below so I could get the whole image to update.
Thank you.
The code is as follows
(MainTest.java)
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.Timer;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
public class MainTest extends JFrame {
static ImageEditor img ;
JPanel panel;
Timer to;
public MainTest()
{
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(265, 329);
getContentPane().setLayout(null);
img = new ImageEditor();
panel = new ImageEditor();
panel.setBounds(10, 11, 152, 151);
panel.add(img);
getContentPane().add(panel);
JButton btnIterate = new JButton("Iterate");
btnIterate.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ThirdClass t = new ThirdClass(img);
to = new Timer(10,t);
to.start();
}
});
btnIterate.setBounds(10, 230, 89, 23);
getContentPane().add(btnIterate);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
MainTest frame = new MainTest();
//frame.getContentPane().add(imgx);
frame.setVisible(true);
}
});
}
}
(ImageEditor.java)
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
#SuppressWarnings("serial")
public class ImageEditor extends JPanel {
private static BufferedImage img = new BufferedImage(100, 100, 1);
public ImageEditor() {
render();
}
public void paintComponent(Graphics g) {
if (img == null)
super.paintComponents(g);
else
g.drawImage(img, 0, 0, this);
}
public void render() {
float cellWidth = 10;
float cellHeight = 10;
int imgW = img.getWidth();
int imgH = img.getHeight();
float r, g, b;
Graphics2D g2 = img.createGraphics();
g2.setBackground(Color.black);
g2.clearRect(0,0,imgW,imgH);
for (int x=0; x<100; x++) {
for (int y=0; y<100; y++) {
r = (float)Math.random();
g = (float)Math.random();
b = (float)Math.random();
g2.setColor(new Color(r,g,b));
g2.fillRect((int)(x*cellWidth), (int)(y*cellHeight),
(int)cellWidth+1, (int)cellHeight+1);
}
}
g2.setColor(Color.black);
g2.dispose();
repaint();
}
public BufferedImage getImage() {
if (img == null)
img = (BufferedImage)createImage(100, 100);
return img;
}
public void setImage(BufferedImage bimg) {
img = bimg;
}
}
(ThirdClass.java)
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class ThirdClass implements ActionListener {
static ImageEditor mock;
public ThirdClass(ImageEditor img)
{
mock = img;
Train();
}
public void Train()
{
mock.render();
}
#Override
public void actionPerformed(ActionEvent arg0) {
Train();
}
}
From the code:
img = new ImageEditor();
panel = new ImageEditor();
panel.setBounds(10, 11, 152, 151);
panel.add(img);
getContentPane().add(panel);
You are defining img as an ImageEditor, but you probably meant for it to be a BufferedImage. You are then adding it to panel, which is another ImageEditor - but it is being added through the superclass method JPanel.add, when you probably meant to use the method you wrote, ImageEditor.setImage().
EDIT: To summarize:
The tiny block of updating pixels you described is the BufferedImage (img.img), inside of your ImageEditor img, which is in turn inside of the ImageEditor panel, which is itself inside the applet's content pane.
replace static ImageEditor img in the MainTest class with BufferedImage img
replace img = new ImageEditor in MainTest's no-args constructor with img = new BufferedImage()
replace panel.add(img) in MainTest's no-args constructor with panel.setImage(img)
replace static ImageEditor mock in the ThirdClass class with BufferedImage mock
replace the ImageEditor img argument in ThirdClass's constructor with BufferedImage img
replace any other stuff involving img to correctly handle it as a BufferedImage
One other thing, although this problem isn't itself the cause of any program malfunction, you should rename the Train() method in ThirdClass to something like train() so it matches proper java style.
After my initial post of the above question I have gone back to the basics and managed to answer my own question.
I am inserting the complete code below so another user having the same problem would not have to go through the same process over again.
My mistake was very trivial. However for people starting swing I think this might be helpful
(MainTest.java)
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.Timer;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class MainTest extends JFrame {
ImageEditor img;
JPanel panel;
Timer t;
public MainTest()
{
setSize(600,600);
setDefaultCloseOperation(EXIT_ON_CLOSE);
getContentPane().setLayout(null);
img = new ImageEditor();
panel = img;
panel.setBounds(0, 0, 510, 510);
getContentPane().add(panel);
JButton btnStart = new JButton("Start");
btnStart.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
test();
}
});
btnStart.setBounds(0, 528, 89, 23);
getContentPane().add(btnStart);
}
private void test() {
Train tx = new Train(img);
t = new Timer(100, tx);
t.start();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
MainTest frame = new MainTest();
frame.setVisible(true);
}
});
}
}
(ImageEditor.java)
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
#SuppressWarnings("serial")
public class ImageEditor extends JPanel {
private static BufferedImage img = new BufferedImage(500, 500, 1);
public ImageEditor() {
setLayout(null);
}
public void paintComponent(Graphics g) {
if (img == null)
super.paintComponents(g);
else
g.drawImage(img, 0, 0, this);
}
public void render() {
float cellWidth = 10;
float cellHeight = 10;
int imgW = img.getWidth();
int imgH = img.getHeight();
float r, g, b;
Graphics2D g2 = img.createGraphics();
g2.setBackground(Color.black);
g2.clearRect(0,0,imgW,imgH);
for (int x=0; x<100; x++) {
for (int y=0; y<100; y++) {
r = (float)Math.random();
g = (float)Math.random();
b = (float)Math.random();
g2.setColor(new Color(r,g,b));
g2.fillRect((int)(x*cellWidth), (int)(y*cellHeight),
(int)cellWidth+1, (int)cellHeight+1);
}
}
g2.setColor(Color.black);
g2.dispose();
repaint();
}
public BufferedImage getImage() {
if (img == null)
img = (BufferedImage)createImage(500, 500);
return img;
}
public void setImage(BufferedImage bimg) {
img = bimg;
}
}
(Train.java this class was named ThirdClass.java in my question)
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Train implements ActionListener {
ImageEditor temp;
Train(ImageEditor img)
{
temp = img;
}
public void train()
{
temp.render();
}
#Override
public void actionPerformed(ActionEvent e) {
train();
}
}
Thank you for all who commented and answered my question.

How to draw an image over another image?

I have a Java project that's about traffic network simulation in a random city, I've managed to figure out a way to implement this project, so I divided each intersection into a section which is basically an extended JPanel class (named Carrefour)...everything works well until I got stuck with how to draw vehicles and make them pass through roads.
So my problem is how to draw an image (vehicle image) over an another image (road)?
Another approach that does not require extending components.
import javax.swing.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.util.Random;
import java.net.URL;
import javax.imageio.ImageIO;
public class ImageOnImage {
ImageOnImage(final BufferedImage bg, BufferedImage fg) {
final BufferedImage scaled = new BufferedImage(
fg.getWidth()/2,fg.getHeight()/2,BufferedImage.TYPE_INT_RGB);
Graphics g = scaled.getGraphics();
g.drawImage(fg,0,0,scaled.getWidth(),scaled.getHeight(),null);
g.dispose();
final int xMax = bg.getWidth()-scaled.getWidth();
final int yMax = bg.getHeight()-scaled.getHeight();
final JLabel label = new JLabel(new ImageIcon(bg));
ActionListener listener = new ActionListener() {
Random random = new Random();
public void actionPerformed(ActionEvent ae) {
Graphics g = bg.getGraphics();
int x = random.nextInt(xMax);
int y = random.nextInt(yMax);
g.drawImage( scaled, x, y, null );
g.dispose();
label.repaint();
}
};
Timer timer = new Timer(1200, listener);
timer.start();
JOptionPane.showMessageDialog(null, label);
}
public static void main(String[] args) throws Exception {
URL url1 = new URL("http://i.stack.imgur.com/lxthA.jpg");
final BufferedImage image1 = ImageIO.read(url1);
URL url2 = new URL("http://i.stack.imgur.com/OVOg3.jpg");
final BufferedImage image2 = ImageIO.read(url2);
//Create the frame on the event dispatching thread
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run() {
new ImageOnImage(image2, image1);
}
});
}
}
If this is Swing, then draw the background image in a BufferedImage. Display this BufferedImage in a JComponent's (such as a JPanel's) paintComponent method using Graphic's drawImage(...) method, and then draw the changing images over this in the same paintComponent method. Don't forget to call the super.paintComponent(...) method first though.
Please note that this question has been asked quite a bit here and elsewhere, and as you would expect, there are lots of examples of this sort of thing that you can find here with a bit of searching.
Edit
You ask:
Thanks, this is how I draw the firt image (road)
Again, you would create a BufferedImage for this, likely by using ImageIO.read(...). Then you'd draw this in your JPanel's paintComponent(Graphics g) method override using g.drawImage(...).
For example...
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.*;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
#SuppressWarnings("serial")
public class IntersectionImagePanel extends JPanel {
private static final String INTERSECTION_LINK = "http://www.weinerlawoffice.com/" +
"accident-diagram.jpg";
private BufferedImage intersectionImage;
public IntersectionImagePanel() {
URL imageUrl;
try {
imageUrl = new URL(INTERSECTION_LINK);
intersectionImage = ImageIO.read(imageUrl );
} catch (MalformedURLException e) {
e.printStackTrace();
System.exit(-1);
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (intersectionImage != null) {
g.drawImage(intersectionImage, 0, 0, this);
}
}
#Override
public Dimension getPreferredSize() {
if (intersectionImage != null) {
int width = intersectionImage.getWidth();
int height = intersectionImage.getHeight();
return new Dimension(width , height );
}
return super.getPreferredSize();
}
private static void createAndShowGui() {
IntersectionImagePanel mainPanel = new IntersectionImagePanel();
JFrame frame = new JFrame("IntersectionImage");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}

Categories

Resources