Add image from website to Frame in Java - java

I'm trying to make a Frame from which I want to add an image from a website.
Do I set the background as an image?
import java.awt.*;
import java.net.*;
class NewFrame extends Frame {
// Constructor.
public NewFrame (int width, int height)
{
// Set the title and other frame parameters.
this.setTitle ("Exercise 9.5");
this.setResizable (true);
this.setBackground (Color.cyan);
this.setSize (width, height);
// Show the frame.
this.setVisible (true);
}
// Override paint():
public void paint (Graphics g)
{
}
} // End of class "NewFrame"
public class ex5 {
public static void main (String[] argv)
{
NewFrame nf = new NewFrame (300, 250);
}
}

You can use the following
// load the image once
BufferedImage bi = ImageIO.read(new URL(imageLocAsString));
// now in paint(Graphics g) do
g.drawImage(bi, 0, 0, null);
Look here for more information.

Related

JFrame does not show picture from JLabel

my JFrame does not show the image of my JLabel.
The JFrame is shown but without the background image.
Expected result was: JFrame that shows a background image ("stelle.png").
I'd greatly appreciate if anyone could help :-)
Thanks!
Simon
public static void main(String[] args) {
new Gui();
}
public class Label extends JLabel {
#Override protected void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g.drawImage(Var.quadro, 0, 0, 800,600, null);
repaint();
}
}
public class Var {
static BufferedImage quadro;
public Var(){
try {
quadro = ImageIO.read(new File("quadri/stelle.png"));
}
catch (IOException e) {
e.printStackTrace();
System.out.println("No picture");
}
}
}
public class Gui {
public Gui(){
JFrame rahmen = new JFrame();
rahmen.setSize(800,600);
rahmen.setLocationRelativeTo(null);
rahmen.setVisible(true);
rahmen.setResizable(false);
rahmen.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
rahmen.setLayout(null);
rahmen.setTitle("Gioco");
Label label = new Label();
label.setVisible(true);
label.setBounds(0, 0, 800, 600);
rahmen.add(label);
}
}
Hi Have tweaked your solution below:
keep the package structure intact for the Test.java(can copy all code in it) and your pic stelle.png, refer the attached image below for this example to work seem less.
for incorporating changes in your own structure please keep image in a relative package quadri (refer the attached image, see how i kept it)
Please pay attention to my comments.
package com.demo.test.stack;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JLabel;
//Main class for executing test
public class Test {
public static void main(String[] args) {
new Gui();
}
}
//this is you extended Label class be careful while importing
class Label extends JLabel {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g.drawImage(Var.quadro, 0, 0, 800, 600, null);
repaint();
}
}
class Var {
static BufferedImage quadro;
//initializing the static variable in static class block (since you are using it directly)
static {
try {
//gettting the absolute path of your image
URL url = Test.class.getResource("quadri/stelle.png");
System.out.println(url.getPath());
quadro = ImageIO.read(new File(url.getPath()));
System.out.println("quadro: " + quadro);
} catch (IOException e) {
e.printStackTrace();
System.out.println("No picture");
}
}
}
//your feature class
class Gui {
public Gui() {
JFrame rahmen = new JFrame();
rahmen.setSize(800, 600);
rahmen.setLocationRelativeTo(null);
rahmen.setVisible(true);
rahmen.setResizable(false);
rahmen.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
rahmen.setLayout(null);
rahmen.setTitle("Gioco");
Label label = new Label(); //<<this label is your extended label (i.e com.demo.test.stack.Label)and not awt label
label.setVisible(true);
label.setBounds(0, 0, 800, 600);
rahmen.add(label);
}
}
Let me know if you ave any other queries.
Regards and welcome to SO.
Cheers

How to display a graphic from another class

I am trying to display a graphic from a separate class on a JPanel of my main class.
The main class is mytest and the separate class is Ball. Ball has a paint component method and simply draws a colored circle. In mytest, I instantiate a ball and add it to a JPanel (dp): dp.add(ball). Very simple, but all I get is the white panel background and no ball is drawn.
Here is the mytest code:
package myStuff;
import java.awt.*;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class mytest {
private JFrame frame=new JFrame();
private JPanel dp = new JPanel();
public static void main(String[] args) {
mytest gui = new mytest();
gui.go();
}
public void go() {
frame.setTitle("Test");
frame.setSize(1000,600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel dp=new JPanel();
dp.setBackground(Color.WHITE);
Ball ball = new Ball(dp.getWidth(),dp.getHeight());
dp.add(ball);
frame.add(dp);
frame.setVisible(true);
}
}
and here is the class Ball code:
package myStuff;
import java.awt.*;
import javax.swing.*;
public class Ball extends JComponent{
private int Width;
private int Height;
public Ball (int width, int height ) {
Width=width;
Height=height;
}
#Override
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
super.paintComponent(g2d);
g2d.setColor(Color.RED);
g2d.fillOval(Width/2,Height/2,40,40);
System.out.println("Doing graphics....");
}
}
An red ball should show up on the dp panel. All I get is the panel background and no ball. I know it is trying since the "Doing graphics" prints out twice.
Here is a working example.
import java.awt.*;
import javax.swing.*;
public class Mytest {
private JFrame frame = new JFrame();
public static void main(String[] args) {
Mytest gui = new Mytest();
SwingUtilities.invokeLater(() -> gui.go());
}
public void go() {
frame.setTitle("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel dp = new JPanel();
dp.setPreferredSize(new Dimension(500, 500));
dp.setBackground(Color.WHITE);
Ball ball = new Ball(150, 150);
dp.add(ball);
frame.add(dp);
frame.pack(); // invokes layout and sizes components
frame.setLocationRelativeTo(null); // centers on screen
frame.setVisible(true);
}
}
class Ball extends JComponent {
private int width;
private int height;
// A ball should probably only have a "diameter"
public Ball(int width, int height) {
this.width = width;
this.height = height;
setPreferredSize(new Dimension(width, height));
}
#Override
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
super.paintComponent(g2d);
g2d.setColor(Color.RED);
// smooths out the graphics
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.fillOval(0, 0, width, height);
System.out.println("Doing graphics....");
}
}
The two biggest suggestions are to:
Ensure when you change a Swing component you do so on the Event Dispatch Thread.
And use the anti aliasing to make your drawing look smoother (note this is optional and it can add extra processing overhead.)
The reason no red ball was drawn (or only 1/4 of one) was because you changed the location of where to draw it within the Component window. You tried to draw it at width/2 and height/2 which was the center of the Component. It should have been at 0,0 for normal rendering.
Also read about painting in the The Java Tutorials 1
You are setting the size of the frame, but the panel has zero size. You should set the preferred size of the panel, not the size of the frame. Then get the preferred size of the panel to pass to the Ball constructor, and pack the frame before making it visible.
Set the panel size before the line,
Ball ball = new Ball(dp.getWidth(),dp.getHeight());
Then add this code
setPreferredSize(new Dimension(Width, Height));
at the end of the "Ball" Constructor.
See this stack question for more details.

Java Graphics trying to draw rectangle

My goal is to make a class that contains rectangle and then use it and change it in other classes.
I tried to write this code and make an object Rect rect = new Rect(); but when i start the program the rectangle doesn't show up.
I also tried to add it with window.add(rect); but had same problem i'm sure im doing something wrong but i don't really know what.
One more thing that i tried was calling method from other class Rect.drawRect(g); but then it asks for "Argument" and if i add Argument g like i had in method drawRect it says "g cannot be resolved to a variable"
I hope someone can explain and tell me what did i do wrong, also would be great to know how to make rectangle or a circle and later use it in other classes and maybe change its color and size, I only found how to do it in one class.
import javax.swing.JFrame;
public class Main extends Rect{
public static void main(String[] args ) {
JFrame window = new JFrame("test");
window.setSize(1000, 800);
window.setVisible(true);
window.setResizable(false);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Rect rect = new Rect();
}
}
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;
public class Rect extends JPanel{
public void drawRect(Graphics g){
g.setColor(Color.RED);
g.fillRect(100, 100, 200, 200);
}
}
The most important thing is that you need to write some code to do the painting. This is done by overriding the paintComponent method inside your Rect class a bit like this:
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.RED);
g.fillRect(100, 100, 200, 200);
}
Your second issue is that you want to be able to change the colour and size of your rectangle from other classes. For a simple example, this can easily be done by adding some static values inside your Rect class:
public static Color myColor = Color.RED;
public static int myX = 100;
public static int myY = 100;
public static int myWidth = 200;
public static int myHeight = 200;
Now update your paint method to use the static values:
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(myColor);
g.fillRect(myX, myY, myWidth, myHeight);
}
Now, whenever or wherever you use the Rect panel it will now show the rectangle according to the static values.
For example, below is a simple and working program, note how it uses the following:
//create Rect
Rect rect = new Rect();
//set the size of the new panel
rect.setPreferredSize(new Dimension(800, 600));
//add the rect to your JFrame
window.add(rect);
//now you can change the color for all Rect instances
//Note how I use Rect instead of rect, however, both will work.
Rect.myColor = Color.BLUE;
//And dont forget to repaint it if you want to see the changes immediatly
rect.repaint();
Full example, main class:
import javax.swing.JFrame;
import java.awt.Color;
public class Main{
//Note how we don't need to extend the Rect class (It just adds confusion)
public static void main(String[] args ) {
JFrame window = new JFrame("test");
window.setSize(1000, 800);
window.setVisible(true);
window.setResizable(false);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//create Rect
Rect rect = new Rect();
//set the size of the new panel
rect.setPreferredSize(new Dimension(800, 600));
//add the rect to your JFrame
window.add(rect);
//now you can change the color for all Rect instances
//Note how I use Rect instead of rect, however both will work.
Rect.myColor = Color.BLUE;
//And dont forget to update it
rect.repaint();
}
}
And the Rect class:
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;
public class Rect extends JPanel{
public static Color myColor = Color.RED;
public static int myX = 10;
public static int myY = 10;
public static int myWidth = 200;
public static int myHeight = 200;
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(myColor);
g.fillRect(myX, myY, myWidth, myHeight);
}
}
Note, if you don't want to call Rect.repaint() every time you make a color/size change then just make a new method that changes each value and include repaint(), for example:
public void changeWidth(int width){
myWidth = width;
repaint();
}
UDP: You need override void paintComponent(Graphics g) instead void drawRect(Graphics g)and call super.paintComponent(g) inside method. Then you can use window.add(rect);.
Thanks #FredK for correction

Swing, resize then draw

I have an image that is to be drawn on a JFrame. The dimensions of the image are dependent on the dimensions of the JFrame.
The JFrame is drawn significantly more often then the JFrame is actually re-sized. Thus I had the image re-sized then stored in the component re-size event and only drew the re-sized image in the draw method.
//called on componentResized
private void scaleImage(){
if((this.getHeight() * this.getWidth()) != 0)
scalledBackGroundImage = backGroundImage.getScaledInstance(this.getWidth(), this.getHeight(), Image.SCALE_FAST);
else
scalledBackGroundImage = null;
}
#Override
public void paint(Graphics g){
if(scalledBackGroundImage != null)
g.drawImage(scalledBackGroundImage, 0, 0, this);
super.paint(g);
}
However I would seem that the re-size event is called after paint when a component is redrawn. Thus the image displayed is the image for the previous frame size. This really becomes a problem with actions like maximize or minimize.
I am looking for a way to detect a JFrame re-size before paint is called.
(I know I could call repaint() on re-size but it seem a bit rude to ask for the component to be drawn twice when re-sizing)
Thanks for any help.
See The Perils of Image.getScaledInstance(). It really is not a very good choice.
Not only do you have the problem you described above, but I get a lot of flickering:
import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.plaf.*;
import javax.swing.text.*;
import java.io.*;
public class ResizeSSCCE extends JPanel
{
Image original;
Image scaled;
public ResizeSSCCE()
{
original = new ImageIcon( "mong.jpg" ).getImage();
scaled = original;
scaleImage();
ComponentListener cl = new ComponentAdapter()
{
#Override
public void componentResized(ComponentEvent e)
{
scaleImage();
}
};
addComponentListener(cl);
}
#Override
public void paintComponent(Graphics g)
{
if (scaled != null)
g.drawImage(scaled, 0, 0, this);
// g.drawImage(original, 0, 0, getWidth(), getHeight(), this);
}
private void scaleImage()
{
if (getHeight() * getWidth() != 0)
scaled = original.getScaledInstance(getWidth(), getHeight(), Image.SCALE_FAST);
}
private static void createAndShowUI()
{
JFrame frame = new JFrame("ResizeSSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( new ResizeSSCCE() );
frame.setSize(200, 200);
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
Change the code to use your image and then run using the scaled version to see the flickering. Then change the code to use the original image that is scale of the fly to see the difference. As the article suggests scaling on the fly is the better approach.
Add a component listener to JFrame as
jFrame.addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
//Your resize method here
}
});

Jlabel ImageIcon is drawn in negative coordinates

I have this piece of code from my Graphics Engine library:
package WG;
import java.awt.*;
import java.awt.image.*;
import javax.swing.*;
public class window {
public static boolean running=true;
public static int WIDTH = 800, HEIGHT = 600;
public static String TITLE = "New Window";
public static JFrame frame;
public static int[] pixels;
public static BufferedImage img;
public static Thread thread;
public window(){}
public static void create() {
img = new BufferedImage(WIDTH, HEIGHT,BufferedImage.TYPE_INT_RGB);
pixels = ((DataBufferInt)img.getRaster().getDataBuffer()).getData();
frame = new JFrame("WINDOW");
//frame.setResizable(false);
frame.setLayout(new FlowLayout(FlowLayout.LEADING,0,0));
frame.add(new JLabel(new ImageIcon(img)));
frame.pack();
//frame.setSize(WIDTH, HEIGHT);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public void render() {
BufferStrategy bs=frame.getBufferStrategy();
if(bs==null){
frame.createBufferStrategy(2);
return;
}
Graphics g= bs.getDrawGraphics();
g.drawImage(img, 0,0, WIDTH, HEIGHT, null);
g.dispose();
bs.show();
}
public static void clear_screen(){
for (int i = 0; i < WIDTH * HEIGHT; i++)
pixels[i] =0;
};
}
and this piece of code in my main java file:
import WG.*;
public class Main_window{
private static boolean running = true;
public static window wind = new window();
public static Thread thread;
public static void main(String[] args) {
window.create();
start();
}
public static void start() {
while (running) {
window.clear_screen();
Forms.drawRect(0, 0, 100, 100);//my own method
wind.render();
}
}
}
I have 2 problems here:
1-->The image on the window is displayed on negative coordinates(the rectangle is not 100x100)
If I re-size the window the image is trying to be drawn at 0 0 coordinates but then again is drawn at negative coordinates.
2-->I get 2 different errors:
a)Component must be a valid peer at Graphics g= bs.getDrawGraphics();
b)Buffers have not been created at bs.show();
What are these problems?
I saw on YouTube on this channel he used Canvas and stuff but he is not getting any errors (I know about not mixing the swing with the awt)
EDIT
//from graphics library
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(img, 0, 0, WIDTH, HEIGHT, null);
g.dispose();
}
//from the main file
public static void start() {
while (running) {
window.clear_screen();
Forms.drawRect(0, 0, 100, 100);//my own method
wind.frame.repaint();
}
}
Your Graphics context, g, is not valid until the host's peer component is extant. The exceptions are thrown because it would cause serious problems for a program to write into host memory or devices at will.
Instead, override paintComponent(), as shown here and here, where you have complete control over the component's geometry in local coordinates.
There's nothing wrong with coordinates. It seems you're using the wrong object. The square is exactly 100x100 if measured from the top of the entire JFrame so negative coordinates are not an issue. Add components to the JFrame's content pane and not to the JFrame itself.
Replace:
frame.add(new JLabel(new ImageIcon(img)));
with
frame.getContentPane().add(new JLabel(new ImageIcon(img)));
There might be something more to it but this is certainly the starting point. Consult the Javadoc in case of further problems

Categories