Hi, I'm trying to build a heap sort Swing applet, and at the moment I just want to output the binary heap and except for the positioning of the nodes which I'll have to mess around later, it's fine, but I'm unsure why the items in the node_arr array are displaying null if I call the print_heap method from main, BUT if I call print_heap method directly inside the paintComponent method of the Heap class, it prints out all the data?

Also, another issue, I have the main frame (JFrame in the main method), to hold the JPanel, but when I set layout to flow layout, and I run the program, the graphics no longer show up so I had to comment out that line ( Why can't I set the JFrame's layout manager before I insert the Heap object? Heap_Node is another class I have that just has an integer key and represents each individual yellow node to draw.

h.print_heap();//PROBLEM here: why is it null, but if I call print directly in paintComponent method, it's not???

There are two threads involved here. You calll print_heap() within main() and "it" (== the contents of the Heap instance's node_arr) is null because paintComponent() has not run and the array has not been populated. You also call print_heap() within paintComponent(): but that occurs in a different thread (the so-called "event dispatch thread") and, significantly, it occurs after you have populated the array.

There are a couple of general rules to bear in mind with Swing:

(1) Do everything thing that alters the graphial user interface on the event dispatch thread. This has a consequence for your main() method: it should do next to nothing. The only thing of any substance it need do is cause the gui to be created and made visible later (on the event dispatch thread). See HelloWorldSwing.java for an example of code that does this.

(2) The event dispatch thread where painting and event handling occurs should be fast. This means that methods like paintComponent() should be lean and mean. (I haven't read the code closely, but your paintComponent() is long: too long for a single method.) A 60Hz refresh rate on a monitor gives your program 0.016 seconds to get its painting done - or rather its share of 0.016 seconds, as other things might well be going on.

---

Before diving into Swing applications, you should take the time to read up on the basic structure of the technology (you don't need to know the ins and outs of every component, but you do need a basic understanding of how painting and event handling is done). Oracle has a Tutorial.

December 23rd, 2012, 12:34 AM

IHeartProgramming

Re: Help with Swing applet

Appreciate it, I have took time to learn background behind it, so now new problem, I understand everything being done for this example from Oracle's tutorials on custom graphics but I'm unsure why they neede an OFFSET, I mean I noticed that if I removed it (set it to 0), then when I drag the red square, there are artifacts left over. I thought that by calling repaint with arguments, the first repaint method will repaint to the current background color (so paint over where red square previously was, and the second repaint (in moveSquare() method I'm referring to) paints where the clipped area where red square currently is.

Notice the subtle difference between drawRect() and fillRect(). drawRect() outlines a rectangle that is squareW+1 pixels wide ie from squareX to squareX+squareW inclusive. On the other hand fillRect() - and repaint() - paints a region only squareW pixels wide: the "right hand" edge is not included. The same in the vertical direction.

You can see this visually by reversing the order of painting and put the red filled region on top of the black outline:

The extra +1 (I don't know why they called it "offset") is there to take this into account. Ie, the region to repaint is one pixel wider and taller than the square to take account of the fact that the outline is also 1 pixel wider.