Felipe Antonio
Felipe Antonio

Reputation: 29

drawing on new thread (canvas is good but not working on jpanel correctly)

I was drawing my game on Canvas, all was god, but I changed it into a JPanel, but now its not working correctly, here are the codes, you can just copy them and you'll see where is the problem (I have a menu and after clicking on the button it should create new thread and there i want to draw, the problem in JPanel is that the button is able to see, its blinking and i can press it, in canvas it was fine, there wasn't any button). I solved it, that after clicking on the button I setted him unvisible (button.setVisible(false)), but these codes are just examples and in my game I have more buttons, so its not practical because I need them to see after the game ends. I think I just forgot an important method in JPanel, thx for help, codes:

//Main class representing menu

public class Sandbox extends JFrame{
    Panel p = new Panel();

    public static void main(String[] args) {
    new Sandbox();
    }

    public Sandbox() {
    setLayout(null);
    setPreferredSize(new Dimension(200, 200));
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setResizable(false);
    final JButton but = new JButton("Button");
    but.setBounds(0, 0, 50, 50);

    but.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
        p.start();
        }
    });

    add(p);
    add(but);
    pack();
    setVisible(true);
    }

}

//Drawing on Canvas -> working well

public class Panel extends Canvas implements Runnable {
    Thread t;
    public Panel() {
    setSize(new Dimension(200, 200));
    setVisible(false);
    }
    public void start() {
    t = new Thread(this);
    t.start();
    setVisible(true);
    }

    public void draw() {
    BufferStrategy b = getBufferStrategy();
    if(b == null) {
        createBufferStrategy(3);
        return;
    }
    Graphics g = b.getDrawGraphics();
    g.setColor(Color.red);
    g.fillRect(0, 0, 200, 200);
    g.dispose();
    b.show();
    }

    @Override
    public void run() {
    while(!t.isInterrupted()) {
        try {
        draw();
        t.sleep(200);
        } catch (InterruptedException ex) {}
    }
    }

}

//Drawing on JPanel -> here i can press the button after first click on it

public class Panel extends JPanel implements Runnable {
    Thread t;
    public Panel() {
    setSize(new Dimension(200, 200));
    setVisible(false);
    }
    public void start() {
    t = new Thread(this);
    t.start();
    setVisible(true);
    }

    @Override
    public void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.setColor(Color.red);
    g.fillRect(0, 0, 200, 200);
    }

    @Override
    public void run() {
    while(!t.isInterrupted()) {
        try {
        repaint();
        t.sleep(200);
        } catch (InterruptedException ex) {}
    }
    }

}

Upvotes: 0

Views: 140

Answers (1)

camickr
camickr

Reputation: 324197

Not sure I understand exactly what you are trying to do but you do have a couple of problems:

  1. the setVisible(true) method should be invoked AFTER you have added all the components to the frame and packed the frame.

  2. by default the content pane of a JFrame uses a BorderLayout. You code is adding two components to the CENTER of the BorderLayout, but a BorderLayout only allows you to add one component to the CENTER, so only the last component added will be displayed.

Upvotes: 1

Related Questions