Java run+repaint = grey window

I'm trying to play around with JFrame/JPanels repaint(); and so forth, but when I start a thread, and call repaint via run while true, it only spits out a line of System.out.println("as"); which I put in place to check if loop was running.

So the question is: Why is my drawings disappearing when calling repaint in a loop? (It seems only a JFrame with the canvas_width/height is showing up, no panels etc.)

public static void main(String[] args) {

    JFrame frame = new JFrame();
    frame.setSize(CANVAS_WIDTH, CANVAS_HEIGHT);
    frame.setPreferredSize(new Dimension(CANVAS_WIDTH, CANVAS_HEIGHT));
    frame.setVisible(true);
    frame.setResizable(false);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JPanel p = new JPanel(new GridLayout());

    frame.getContentPane().add(p);
    Something s = new Something();

    p.add(s);
    p.setBackground(Color.black);
    frame.pack();

}

And the something class:

public class Something extends JPanel implements Runnable {


public Something(){
    Thread t = new Thread();
    t.start();
    run();

}


@Override
public void paintComponent(Graphics g){
    super.paintComponent(g);
    g.setColor(Color.cyan);
    g.fillRect(0, 0, getWidth()-150, getHeight()-100);
    g.setColor(Color.BLACK);
    g.fillOval(10, 10, 25, 25);

}


@Override
public void run() {
    while(true){
    repaint();
    System.out.println("as");

    try {
        Thread.sleep(1);
    } catch (InterruptedException e){}
    }
}
}

Any help regarding the contentpane is appreciated, since, I'm not sure this is done correctly.

Answers


Instead of calling Thread.sleep(n) in your Thread, implement a Swing Timer for repeating tasks. That ensures that repaint() is called on the Event Dispatch Thread.

See Concurrency in Swing for more details.

Also, repainting every 1 millisecond is being very optimistic.

Working SSCCE E.G. (Note this version actually changes the co-ords of the resulting paint operations, just so we know something is happening!

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Something extends JPanel {

    static final int CANVAS_WIDTH = 400;
    static final int CANVAS_HEIGHT = 100;
    private int xDelta = 0;

public Something(){
    ActionListener animater = new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent ae) {
            repaint();
        }
    };
    Timer t = new Timer(10,animater);
    t.start();
}


@Override
public void paintComponent(Graphics g){
    super.paintComponent(g);
    g.setColor(Color.cyan);
    g.fillRect(0, 0, getWidth()-(xDelta--), getHeight()-100);
    g.setColor(Color.BLACK);
    g.fillOval(xDelta, 10, 25, 25);

    if (xDelta<0) {
        xDelta = CANVAS_WIDTH;
    }
}

@Override
public Dimension getPreferredSize() {
    return new Dimension(CANVAS_WIDTH, CANVAS_HEIGHT);
}

public static void main(String[] args) {

    JFrame frame = new JFrame();

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JPanel p = new JPanel(new GridLayout());

    frame.getContentPane().add(p);
    Something s = new Something();

    p.add(s);
    p.setBackground(Color.black);
    frame.pack();
    frame.setResizable(false);
    frame.setVisible(true);
}
}

Need Your Help

Node.js How to pass Ajax success message to app.js

javascript jquery ajax json node.js

Node.js how to pass Ajax success message to app.js, because i need to know user Log-in status

Entity Framework & Self-Tracking Entities vs POCO

entity-framework-4 poco self-tracking-entities

If i'm wanting to use entity framework 4 as my data layer and want to send my entities to another tier whether it be via WCF or another mechanism and then want the ability to update the entities an...

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.