0

When instantiating my modified JPanel class, I pass in a file through the constructor. The file (XML) gets read and the data gets used by me later in the paint method. However, right after I parse the data, I call both repaint() and revalidate(), but my GUI looks exactly the same. I call these methods both in my main class which extends JFrame and my panel class which extends JPanel.

When I choose an xml file from my JFileChooser, the drawPanel class gets instantiated with its other constructor, taking in the file and parsing it, then calling repaint and revalidate. I omitted most of the code to save your time.

Here's the main class' code:

public class myCode extends JFrame {
  public myCode() {
    super("Roadway Simulator");

    setSize(800, 600);
    setLocationRelativeTo(null);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setLayout(null);
    drawie = new drawPanel();
    drawie.setSize(new Dimension(width - 200, height));
    drawie.setMinimumSize(new Dimension(width - 200, height));
    drawie.setMaximumSize(new Dimension(width - 200, height));
    drawie.setLocation(0, 0);
    add(drawie);

    setVisible(true);

    try{Thread.sleep(500);revalidate();repaint();}catch(InterruptedException eeee){}
}
  public static void main(String[] args){new myCode();}
}

Here's my drawPanel class:

class drawPanel extends JPanel {
  boolean drawRoad = false;
  public drawPanel() {
    super();
  }
  public drawPanel(Document doc){
    super();
    //the change in my paint method
    drawRoad = true;
    revalidate();
    repaint();
  }
  public paint(Graphics g){
    super.paint(g);
    if(drawRoad){
      g.setColor(Color.BLACK);
      g.fillRect(0,0,600,600);
    }
  }
}

My code is the same as above, just with a lot more detail. Why isn't my JFrame repainting?

Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
Jonathan Allen Grant
  • 3,408
  • 6
  • 30
  • 53
  • 1
    Avoid using `null` layouts, pixel perfect layouts are an illusion within modern ui design. There are too many factors which affect the individual size of components, none of which you can control. Swing was designed to work with layout managers at the core, discarding these will lead to no end of issues and problems that you will spend more and more time trying to rectify – MadProgrammer Oct 22 '14 at 01:23
  • [Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?](http://stackoverflow.com/questions/7229226/should-i-avoid-the-use-of-setpreferredmaximumminimumsize-methods-in-java-swi) - but in your case, since you're using a `null` layout, they will have no effect anyway... – MadProgrammer Oct 22 '14 at 01:23

2 Answers2

4

Here:

try{Thread.sleep(500);revalidate();repaint();}catch(InterruptedException eeee){}

Understand what Thread.sleep(...) does to a Swing GUI when called on the Swing event thread -- it puts the current thread which happens to be the Swing event thread, the one responsible for all drawing and user interaction, to sleep. In other words, you put your entire application completely to sleep.

Solution -- don't call this ever on the event thread.

As an aside, there's no cost to putting each method call on its own line, and no reason for that long line that you've posted as it serves no purpose other than to confuse.

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
4

try{Thread.sleep(500);revalidate();repaint();}catch(InterruptedException eeee){} is most likely blocking the Event Dispatching Thread, preventing from processing the Event Queue and making it look like your program has hung.

See Concurrency in Swing for more details...

It is also not recommended to override paint of Swing components and instead use paintComponent, see Performing Custom Painting for more details

In your case, I would recommend using a javax.swing.Timer instead of Thread.sleep, see How to use Swing Timers for more details

Updated

I don't see any where in your code that would change drawRoad from false to true, so your paint method is painting...nothing...so I guess you frame is painting exactly the way you told it to...

You may also like to take a look at Initial Threads and you might like to have a read through Code Conventions for the Java TM Programming Language, it will make it easier for people to read your code and for you to read others

Updated

Given that you example is incomplete and won't compile, when I rebuild it, this will work...

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
import org.w3c.dom.Document;

public class TestDraw extends JFrame {

    public TestDraw() {
        super("Roadway Simulator");

        setSize(800, 600);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        DrawPanel drawie = new DrawPanel(null);
        add(drawie);

        setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                new TestDraw();

            }
        });
    }

    class DrawPanel extends JPanel {

        boolean drawRoad = false;

        public DrawPanel() {
            super();
        }

        public DrawPanel(Document doc) {
            super();
            drawRoad = true;
            revalidate();
            repaint();
        }

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

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g); 
            if (drawRoad) {
                g.setColor(Color.BLACK);
                g.fillRect(0, 0, getWidth(), getHeight());
            }
        }
    }
}

If I change DrawPanel drawie = new DrawPanel(null); to DrawPanel drawie = new DrawPanel(); it still paints, but doesn't perform your custom painting.

The other problem is, as has already been highlighted, is the use of null layouts

Avoid using null layouts, pixel perfect layouts are an illusion within modern ui design. There are too many factors which affect the individual size of components, none of which you can control. Swing was designed to work with layout managers at the core, discarding these will lead to no end of issues and problems that you will spend more and more time trying to rectify.

Have a look at Why is it frowned upon to use a null layout in SWING? for more details...

Now, having said that, when you add drawie, you never give it a size, Swing is smart enough not to paint 0x0 sized components...

Community
  • 1
  • 1
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366