Reputation: 11
I'm trying to call my paintComponent method by using repaint but it is never being called. This is my first class:
public class start
{
public static void main(String[] args){
Frame f = new Frame();
f.createFrame();
}
}
And this is the class that I want the paintComponent method to be called to but all that happens is a blank frame appears:
import javax.swing.JButton;
import javax.swing.JComponent;
import java.awt.Graphics;
import javax.swing.JFrame;
import java.awt.image.*;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import javax.swing.Timer;
public class newFrame implements Runnable,ActionListener
{
JFrame window = new JFrame("Frame");
int i = 0;
Canvas myCanvas = new Canvas();
public void createFrame(){
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setBounds(30, 30, 700, 500);
window.setFocusable(true);
window.setFocusTraversalKeysEnabled(false);
window.setVisible(true);
Thread t = new Thread(this);
t.start();
}
public void run(){
Timer timer = new Timer (17,this);
timer.start();
}
public void actionPerformed(ActionEvent e){
myCanvas.updateGame();
myCanvas.render();
window.add(myCanvas);
}
}
class Canvas extends JPanel{
int x = 10;
int y = 10;
public void updateGame(){
x++;
}
public void render(){
repaint();
System.out.println("Output1");
}
@Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g.drawString("hi",x,y);
System.out.println("Output1");
}
}
Output1 is printed multiple times but Output2 is never printed. Why isn't the paintComponent method being called by repaint?
Upvotes: 1
Views: 418
Reputation: 347334
The core problem is within your ActionListener
...
public void actionPerformed(ActionEvent e){
myCanvas.updateGame();
myCanvas.render();
window.add(myCanvas);
}
When you call window.add
, the JFrame
has to first remove myCanvas
and then re-add it, revalidate the layout and schedule a repaint, all of this is taking time, in the mean time, you've jumped in repeated the process, setting a situation in which the framework simply can't keep up with you.
Instead, add window.add(myCanvas);
to the constructor
public void createFrame() {
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setBounds(30, 30, 700, 500);
window.setFocusable(true);
window.setFocusTraversalKeysEnabled(false);
window.setVisible(true);
window.add(myCanvas);
Timer timer = new Timer(17, this);
timer.start();
}
Also, there is simply no need to use a Thread
to start a Timer
, it's just confusing the issue.
Beware that Java already has classes called Frame
and Canvas
, which could add additional confusion to some developers (especially those who don't have access to the source)
Upvotes: 1
Reputation: 9093
You only have "Ouput1"
printed ever. There is no "Output2"
printed anywhere.
Upvotes: 3