i have a problem with the repaint function
when i compile, the error is
pc3#pc3-desktop:~/Desktop$ javac LoadImageApp.java
LoadImageApp.java:17: cannot find symbol
symbol : method repaint(int,int,int,int,int)
location: class java.awt.Graphics
g.repaint(1000,0,0,1440,900)
^
1 error
and this is my code -->
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;
import javax.swing.*;
public class LoadImageApp extends Component {
BufferedImage img;
public void paint(Graphics g) {
g.drawImage(img, 0, 0, null);
super.update(g);
g.repaint(1000,0,0,1440,900);
}
public LoadImageApp() {
try{
img = ImageIO.read(new File("screenshot.jpg"));
}catch(IOException e){}
}
public Dimension getPreferredSize() {
if (img == null) {
return new Dimension(100,100);
} else {
return new Dimension(img.getWidth(null), img.getHeight(null));
}
}
public static void main(String[] args) {
JFrame f = new JFrame("Load Image ");
f.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
f.add(new LoadImageApp());
f.pack();
f.setVisible(true);
}
}
can anyone tell me what is the problem ? i intend to do a program that is display the image and keep refreshing every 0.1 seconds . the image will be receive from other machine and every 0.1 seconds and the image will be keep override the old image ..
thanks in advance for those who reply .. THANK YOU !!!!!!
I would highly recommend reading the Swing tutorials and understand the methods defined in the Graphics class as well as the Component class. More specifically, what do you expect the statement:
g.repaint(1000, 0, 1440, 900)
to do? If it's repaint one of your components based on some interval, you can do this using a TimerTask. Also from reading the tutorials you'll see why you have a compilation error. The repaint method is not defined on Graphics.
As a side note, don't name your method paint - it's confusing since there is a paint method already defined in Component
I don't actually know where you found that repaint method signature for Graphics since it does not exist.
You should instead call repaint on the component which is the owner of that specified Graphics, which is the LoadImageApp itself.
But first of all you absolutely need to study a little bit better how drawing works with AWT and Swing, take a look here.
In Addition you should use something that schedules your update phase, otherwise your code, as it is, doesn't make any sense. There is nothing that is periodically loading the imagine neither anything that is repainting the frame. I'd suggest a TimerTask like Amir told you.
Related
First class
package com.mudd.render;
import java.awt.Dimension;
import javax.swing.JFrame;
import com.mudd.game.Game;
public class render {
int width = 500;
int height = 600;
Game g = new Game();
public void show(){
JFrame gameWindow = new JFrame("..");
gameWindow.setPreferredSize(new Dimension(width, height));
//gameWindow.setIconImage(new ImageIcon(imgURL).getImage());
gameWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gameWindow.pack();
gameWindow.add(g);
gameWindow.setVisible(true);
}
public static void main(String[] args) {
render game = new render();
game.show();
}
}
Second class
package com.mudd.game;
import java.awt.Graphics;
import javax.swing.JPanel;
#SuppressWarnings("serial")
public class Game extends JPanel {
public void paint(Graphics g){
g.fillOval(10, 10, 500, 500);
System.out.println("Test");
}
}
What is causing my Test print statement to be printed twice? If I add other priintlns it will also print them both out. I've been learning Java from Head First Java and I've done other small command line projects but nothing like this has ever happened to me.
Swing graphics are passive -- you don't call the painting methods directly yourself, but rather the JVM calls them. They are sometimes possibly called at your suggestion such as when you call repaint() but even this is never a guarantee, and they are sometimes possibly called at the suggestion of the platform, such as when it determines that your application has "dirty" pixels that need cleaning. So you have to plan for this -- the painting method should contain no code that changes the state of the object nor should it contain business logic code. Instead it should have code for painting and nothing more.
For more details on this, please see:
Lesson: Performing Custom Painting: introductory tutorial to Swing graphics
Painting in AWT and Swing: advanced tutorial on Swing graphics
Side recommendations:
Override the JPanel's paintComponent method, not its paint method
Use the #Override annotation for any method override
Don't forget to call the super's method in your override.
Here's my code:
package javaapplication2;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class JavaApplication2 extends JPanel {
public static void main(String[] args) {
JFrame frame = new JFrame("Simple Sketching Program");
frame.getContentPane().add(new JavaApplication2());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 300);
frame.setVisible(true);
}
#Override
public void paint(Graphics g) {
g.setColor(Color.BLACK);
g.fillRect(0, 0, getSize().width, getSize().height);
while(true) {
delay(1000);
}
}
}
I'm still trying to get the hang of things here.
Now if the while(true) loop is commented out, it works fine, and the screen is covered in black.
I've even put it in repaint() and called it from paint, and that does the same thing. I'm sure I'm miles from making this fine. If there's things I'm doing wrong, could you inform me? I've been looking everywhere to get this to work, and couldn't find anything that applied. Thank you.
Because painting happens in the Event Dispatch Thread, and you're blocking it with your obvious infinite loop. This will prevent any further painting from happening, events from being processed, and anything else that happens inside the EDT.
That's why you never perform long running operations on EDT, but use a SwingWorker or other mechanism instead.
So I finally got a Canvas to work the way I want it but it flickers constantly, repaint() is run 20 times a second and the flicking does lessen when I make it run 10 times a second.
package pd.data;
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import pd.areas.MainMenu;
#SuppressWarnings("serial")
public class Main extends JFrame implements Runnable {
private JPanel contentPane = new JPanel();
private Thread gameThread = new Thread(this);
public boolean running = false;
#SuppressWarnings("unused")
private int current = PDU.PD_MAIN_MENU;
private MainMenu mainmenu;
public Main() {main.setTitle("PD");
main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
main.setLocation(SPU.screenWidth / 2 - SPU.windowSize.width / 2,
SPU.screenHeight / 2 - SPU.windowSize.height / 2);
main.setResizable(false);
main.setVisible(true);
contentPane.setLayout(new BorderLayout(0, 0));
contentPane.setPreferredSize(SPU.windowSize);
main.setContentPane(contentPane);
main.pack();
mainmenu = new MainMenu();
contentPane.add(mainmenu, BorderLayout.CENTER);
this.gameThread.start();
}
#Override
public void run() {
running = true;
while (running) {
{
mainmenu.repaint();
}
try {
Thread.sleep(SPU.TSU);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new Main();
}
}
And below is my MainMenu class:
package pd.areas;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
#SuppressWarnings("serial")
public class MainMenu extends Canvas{
BufferedImage img = null;
public MainMenu() {
this.setBackground(Color.BLACK);
}
public void paint(Graphics graphics){
try {
img = ImageIO.read(this.getClass().getResource(
"/image.png"));
} catch (IOException e1) {
e1.printStackTrace();
}
graphics.drawImage(img, this.getWidth() / 2 - img.getWidth()/2, 50, null);
}
}
Although the flicker is actually a nice effect, it's going to effect the whole canvas and not just the image I'm guessing, how can I fix the flicker?
Don't use java.awt.Canvas. Use a JPanel instead.
Draw in the JPanel's paintComponent method.
Don't forget to call your super's painting method which for paintComponent would be super.paintComponent(graphics)
Never try to read in an image from within any painting method. That will slow down painting and make your program seem unresponsive. Why keep reading in the same image over and over again anyway? Read it in once and save it to a variable.
Though this thread was opened 5 years ago, it's still going to be an issue for anyone new to Java SE.
I had the same problem with Canvas myself, but wasn't convinced enough to switch to javax components because I recalled a VLC project called JVLC which used Canvas to render videos flawlessly (granted jvlc uses some native code).
Tip 1: perhaps it's better to try JPanel instead.
Tip 2: in gaming systems, it's better to use a game engine (it'll save you lots of time).
Tip 3: in gaming systems, implement a fps mechanism rather than calling repaint() on every change.
Tip 4: if you have to call more than 10 lines of code in your paint() implementation you're going to slow it down. It's better to draw to a BufferedImage for every graphical change you need to make to your app, then have the paint() implementation itself draw just the image itself. This should play nicely with an fps mechanism and will reduce the chances of any flickering.
In this video drawing() method is called in main class. When we remove drawing() in the main method it still draws the shape. How can we avoid this situation ?
shapes class:
import java.awt.*;
import javax.swing.*;
public class shapes{
public static void main(String[] args){
JFrame frame = new JFrame("Test");
frame.setVisible(true);
frame.setSize(400,200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
draw object = new draw();
frame.add(object);
object.drawing();
}
}
Draw class:
import java.awt.*;
import javax.swing.*;
public class draw extends JPanel{
public void drawing(){
repaint();
}
public void paintComponent(){
super.paintComponent(g);
g.setColor(Color.BLUE);
g.fillRect(10,15,100,100);
}
}
There are some minor issues with the code, but I assume that it's only a small snippet for demonstration purposes. For details, have a look at Performing Custom Painting.
Actually, this tutorial would also answer your question, but to summarize it:
The paintComponent method will be called automatically, "by the operating system", whenever the component has to be repainted. The call to repaint() only tells the operating system to call paintComponent again, as soon as possible. So you can call repaint() to make sure that something that you canged appears on the screen as soon as possible.
If you explicitly want to enable/disable certain painting operations, you can not influence this by preventing paintComponent from being called. It will be called anyhow. Instead, you'll introduce some flag or state indicating whether something should be painted or not.
In your example, this could roughly be done like this:
import java.awt.*;
import javax.swing.*;
public class Draw extends JPanel{
private boolean paintRectangle = false;
void setPaintRectangle(boolean p) {
paintRectangle = p;
repaint();
}
#Override
public void paintComponent(){
super.paintComponent(g);
if (paintRectangle) {
g.setColor(Color.BLUE);
g.fillRect(10,15,100,100);
}
}
}
You can then call the setPaintRectangle method to indicate whether the rectangle should be painted or not.
I know this is probably simple, but it is causing me trouble. When I use paint(), it shows nothing, and if I use paintComponent(), it shows an error (cannot find symbol). What am I doing wrong?
This is an example of using paint():
import javax.swing.*;
import java.awt.Graphics;
import java.awt.*;
public class Test extends JFrame {
public Test() {
this.setPreferredSize(new Dimension(400, 400));
this.pack();
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
#Override
public void paint(Graphics g) {
super.paint(g);
// define the position
int locX = 200;
int locY = 200;
// draw a line (there is now drawPoint..)
g.drawLine(locX, locY, locX, locY);
}
public static void main(String[] args) {
Test test = new Test();
}
}
Comments say this is a nice and simple code but I can't see anything because it shows nothing.
[SOLVED]
To all who answered, thanks. LOL at me bros, I really didn't notice that there was a tiny dot. Awesome dude, thanks.
You code is not the recommended way of doing things, but that aside, it works.
You do not set a color to paint with, and you draw a single dot. You probably just didnt see it (I had to look twice). It draw a single black pixel at 200, 200.
I would bet the problem is that you're only drawing a single point, so it's hard to see. Your code works fine for me.
However, you should be extending JPanel, not JFrame. Recommended reading: http://docs.oracle.com/javase/tutorial/uiswing/painting/