0

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) {}
    }
    }

}
Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
  • The biggest problem is with the `null` layout. The `JPanel` and `JButton` are sitting at the same z-deepthness, where as `Canvas`, been a heavy weight component, simple out weights it... – MadProgrammer Apr 01 '14 at 20:32
  • So what should i do? use a layout or what? can you be more concrete or help me with an example? thanks – Felipe Antonio Apr 01 '14 at 21:23
  • You can use a JLayeredPane and add your Panel and button to it, which will allow you to better control the zorder or use the glass pane... – MadProgrammer Apr 01 '14 at 22:07
  • 1) For better help sooner, post an [MCVE](http://stackoverflow.com/help/mcve) (Minimal Complete and Verifiable Example). 2) Use a consistent and logical indent for code blocks. The indentation of the code is intended to help people understand the program flow. 3) Don't block the EDT (Event Dispatch Thread) - the GUI will 'freeze' when that happens. Instead of calling `Thread.sleep(n)` implement a Swing `Timer` for repeating tasks or a `SwingWorker` for long running tasks. See [Concurrency in Swing](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/) for more details. – Andrew Thompson Apr 02 '14 at 06:55
  • .. 4) Java GUIs might have to work on a number of platforms, on different screen resolutions & using different PLAFs. As such they are not conducive to exact placement of components. To organize the components for a robust GUI, instead use layout managers, or [combinations of them](http://stackoverflow.com/a/5630271/418556), along with layout padding & borders for [white space](http://stackoverflow.com/q/17874717/418556). – Andrew Thompson Apr 02 '14 at 06:56

1 Answers1

1

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.

camickr
  • 321,443
  • 19
  • 166
  • 288
  • Thanks for comment, but as i wrote = it's just an example, i edited it, so now it should be alright. "Not sure I understand exactly what you are trying to do" - did you tried both codes? just copy and paste it and try.. I already said it but one more... i have a problem in JPanel that i can press the button as many times as i want (it is in the background and its active) – Felipe Antonio Apr 01 '14 at 18:43
  • *"did you tried both codes?"* Post **one** MCVE, if you want people to look at it. An MCVE can contain more than one class, but cannot be more than one source file. – Andrew Thompson Apr 02 '14 at 06:57