JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

The code that opens the file etc needs to be in a method (pass the file as a parameter) that is called after the user has selected a file in the open dialog.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Looks like your main(..) creates the GUI then immediately tries to open the file. Snag is, the user hasn't yet had a chance to pick menu or run the open dialog yet.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

It's hard to follow your code, but, if you're running main in GrabPixels, the very first thing it does is to read the file, before calling anything else that could set the file variable.
Either way, if you have a nullpointer in a given statement, try to print all the variables immediately before it to see which is null.
It may help to clean the code up and post the current version with code=java tags

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Exception suggests something wrong with run.file, but we don't have the code where that gets set!

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Its just that the line in question:
image = ImageIO.read(new File(run.file.getAbsolutePath()));
doesn't seem to appear anywhere in the posted code

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Does the error message correspond to the code you posted?

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Vector

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

PLease ignore my previous post - doesn't address the real problem. Sorry.

... and, as adatapost points out, arrays are passed by reference, so you don't need to return anything

... and if you make the method static:

public static void sort(int[]...) ...

you can call it without creating an instance, as in

BubbleSort.sort(array...);

I suspect your problem lies in the call on line 14. You pass a variable "length", but I can't see any declaration or initialisation for this - presumably its declared in the class, and maybe its value is 0?

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

your sort needs to return the whole sorted array, not just one element. (Remember the problem with the constructor earlier?)

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

That's right. In your GUI you'll need the array, plus a variable that holds the number of the array element that you're currently working with. Your buttons just increment/decrement that number, then display the corresponding array element. You'll sort it out with a little thought.
And, yes, time to mark this solved and start a new topic if necessary.
Good luck
J

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

any input on that?

It's (in my opinion) one of Java's poorest design points - primitive types that are not Objects, and so need an Object equivalent to get all the functionality. To call a Long method you need a Long object, not a long primitive. Since you know that the String is a valid representation of a Long, you can safely use

new Long(str1[1]).compareTo(new Long(str2[1]));

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Some debugging/testing hints:

For your Books class (please change that to Book!), add a
public String toString()
method that returns a string representation of the Book - maybe something easy like
return title + " " + isbn + " " + price ... etc.

Now you can see what's in your data by simply saying
System.out.println(book);
or
for (Book b : arrayOfBooks) {
System.out.println(b);
}

You can stick these statements anywhere you want to check that the data you have is what you expected (eg in the constructor, or after entering or editing a Book in the GUI). Start off with these in, then comment them out when it seems to be OK. If it subsequently goes wrong again, just un-comment them to find out why.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Change the consrtuctor to
public TestBooks(Books[] arrayOfBooks)
, then decide which Book to display first, eg
Books book = arrayOfBooks[0];

You don't need the buttons to check that you have passed the right data - just send it to System.out and look at it!

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

That's right. Your constructor takes a single Book as its parameter. If you want to pass an array of Book objects, the constructor's parameter needs to changed to an array.
It's confusing to call the class Books instead of Book - each instance represents a single Book, not some number of Books, and this obscures when you need a Book and when you need an array of Book objects.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Using "array[number]" you're refer to 1 single element in array , which has a position number-1 (since the array indexes are starting from 0).

I think this is a typo. Element [n] is in position n+1, not n-1.
ie Element [0] is in the first position, [1] is in the second position etc

Antenka commented: oh .. yeah .. thanks .. my bad :$ +2
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Yup, if you want the whole array, pass the whole array.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

getResource searches (unless you are doing clever stuff with class loaders) your classpath, so I'd try putting the data file alongside the class file (or specify its location as a path starting from the folder where the class file is) (modified as necessary if you have specified a package name).

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Are you comparing on the file size? If so, you convert it to String, and do a String compareTo so, for example "1000000"sorts lower than "2".

ps Any special reason why you use a 2D array? Why not just keep the array of Files and use File's accessor methods when you need values?

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

TestBooks myFrame = new TestBooks(bookArray[numBooks]);

So if numBooks is (say) 2, you populate elements [0] and [1] in the array, but you pass element [2] to the GUI

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Hi sos. Yes, point taken.I also chose not to get into weak references. I think its always difficult to know how much info to give and how much to omit when helping someone with a specific problem to solve. Maybe I err on the side of keeping it as simple as possible to get the job done, but any feedback is welcome.
J

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Glad to help. Perhaps you should mark this thread as solved now?

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Maybe I missed it, but there's no code to display the contents, just to read it and display any errors.

edit: parallel post with previous - I was referring to code in post 4.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Garbage collection happens only when there are exactly zero remaining references, so you have to think about every reference that you may hold, and make sure every one is nulled. So if you have a node with children, and you null the reference from its parent, it will still hold a ref to the children, and the children will still hold a ref to it, so nothing gets collected.
Maybe write a delete method for a TreeNode that:

calls delete for each of its children (recursive).
(edit - this step not needed) clears its children vector.
deletes itself from the hashmap.
deletes itself from its parent.

That should do it!

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

As for the unwanted children - if you really want the object to be garbage collected you will need to remove the references to it from its children - you can do that with a
public void clearParent() { parent = null;}
and you will need to remove it from the HashMap.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Since the child is an object of type TreeNode, you should really use that as the parameter, not an index or name or whatever.
In that case, you can use the remove(Object 0) method for your Vector

public void removeChild(TreeNode c) {
children.remove(c);
}

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

So for remove each pNode from Tree I should find its position in parent's vector and remove it from there. There is no other way faster than this to remove the nodes?

That's right. You need a public method removeChild(TreeNode c) in your TreeNode class. Then when you have the node you want to remove you can call it's parent's removeChild(...) method.
You may also want to think about what to do when you remove a node that has its own children - what should happen to them?

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

pNode is NOT an object. It is a reference variable, that is able to refer to an object. Setting it to null just means it doesn't refer to any object. It does not directly affect any object that it may have referred to previously. As BJSJC said object get deleted by the JVM some time after it finds that there are no references anywhere to that object. SO as long as there is one reference left (eg parent node refers to child, or child node refers to parent) nothing gets deleted.
I think what you want to do here is to remove a node from your tree by removing all the references (parent or child) to it in the tree.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

As far as I can see you use a highly tortuous loop to inspect each value in the hashmap then, if it is null, you set the variable pNode (whatever that may be!) to null. It seems equivalent to:

for (TreeNode t : pHash.values()) {
  if (t == null)  someRandomVariable = null;
}

What did you expect?

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

You have a class PanelAnswer with overrides for paintComponent, but you don't do much to create one. I still don't see why you create an unrelated JPanel when you call the constructor for PanelAnswer unless you intend to use it as a container, in which something more like this should work:

public PanelAnswer(){
    JFrame jf = new JFrame("Hello");
    jf.add(this);
    this.add(new JLabel("Hello"));
    jf.pack();
    jf.setVisible(true);
    // initPanelAnswer();
}
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Maybe its smart enough to realise that repainting an uninitialised unpopulated invisible panel is unnecessary?
ps: What's the point of answer = new JPanel... don't you want an instance of PanelAnswer?

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Can't immediately see why you have that problem. You'll have to do some more dubugging!
ps: getContentPane().add(... this is not needed since Java 1.5, you can just call add(...

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Not enough info for a proper answer, but probably you need to create a public method that sets the content pane, then you can call that method from a different class. (Normally you don't need to set the content pane, JFrame has one by default.)

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

I guess, in your drawCircle methods you need to clear the previous contents before drawing the circle at its new coords.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

drawCircleLeft(this.getX() + (e.getX() - startDragX), this.getY()

in this line (and any others like it) you need to replace the this.getX() with the original X coord of your circle, ditto the Y coord. You need to store the original coords in the mousePressed event. What we are doing here is computing the latest position of the circle as original position + (distance the mouse has moved)

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Moving an actual component would trigger a repaint automatically, but it looks like he is "dragging" a shape that's been painted on the component, which would require a repaint() to update the location.

Yes, I agree. Like I said, that was just some code that I happened to have that could possibly be a starting point for the OP. I was dragging a whole JFrame.

OP: In the new mouse events you need to re-draw your circle at the new coords - this should replace my this.setLocation calls

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Works for me without the repaint, setLocation will trigger one anyway - the one in the mousereleased is there for a completely different (irrelevant here) reason.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Here's a really easy solution (although it's probably not what are hoping for!)

public void rotateCCW() {
   rotateCW(); rotateCW(); rotateCW(); 
}

:-)

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Here (basically unedited) is some code from an old program I wrote that allows an object to be dragged around the screen. Perhaps you can use it as a start point?

private int startDragX, startDragY;
private boolean draggable = false, dragging = false, dragged = false;

public void mousePressed(MouseEvent e) {
  startDragX = e.getX(); // in case this is the start of a drag
  startDragY = e.getY();
  dragging = false;
  // System.out.println(startDragX + " x " + startDragY);
 }

 public void mouseReleased(MouseEvent e) {
  // System.out.println("we had a move to " + e.getX() + " x " e.getY());
  this.setLocation(this.getX() + (e.getX() - startDragX), this.getY()
	  + (e.getY() - startDragY));
  repaint();
}

public void mouseDragged(MouseEvent e) {

  if (!dragging) { // this is the start of a drag event sequence
                 // ignore if drag moves less than a pixel or two...
    if (Math.abs(startDragX - e.getX()) + Math.abs(startDragY - e.getY()) > 4) {
    // System.out.println("we are dragging from " + startDragX + " x
    // " + startDragY);
    }
    dragging = true;
  }
  if (dragging) { // drag in progress
    // System.out.println("we are at " + e.getX() + " x " + e.getY());
    this.setLocation(this.getX() + (e.getX() - startDragX), this.getY()
	 + (e.getY() - startDragY)); // for user feedback
  }
}
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

In this case you are relying on the JVM to catch the exception when your main(..) method throws it, presumably because the JVM's default processing (print out the details of the Exception to System.err and terminate the program) is good enough.
In general you would put the IO method calls inside a try/catch so you can decide exactly what to do - eg show the user a standard error dialog box

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Yes, that really is confusing! But if you now have it working....

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

You are overriding a protected method with a private one, try making it protected?

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Because x is assigned from an input.nextInt(), I assume it's declared as int, so:
%f requires a floating point value, but 2*x is an integer value. Change the format to %d when you print the diameter, OR change the calculation to 2.0*x so the result is floating point.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Looks 60-70% right to me. Presumably just a few messed-up coordinates.
I would store the coordinates as data, rather than embed them into the code - I'd use a Vector of Points. I'd hold those in a simple text file, and just read it into the Vector, so it would be easy to edit the data. Then I'd have a simple loop that looped thru the Points drawing 1 segment at a time. For testing I'd put a bit extra in the loop so it sent the coodinates to System.out, then waited for a CR before plotting that point. Like that I could step thru the drawing 1 point at a time and see exactly which coords were wrong.
If I wanted to get clever I'd write a little JPanel that I could click on, and the Mouse handler would add the points where I clicked to the Vector of points, then write it all to the text file.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Hi sincerelibran. Nice code, but it looks like its duplicating the existing Point class in the Java API
http://java.sun.com/j2se/1.4.2/docs/api/java/awt/Point.html

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

writeObjectOverride: being protected shouldn't stop you overriding it. What errors do you get?

Have you looked at Externalizable? http://java.sun.com/j2se/1.3/docs/api/java/io/Externalizable.html looks like it may be what you are looking for?

Finally - so the default serialization writes a k or two of extra data. Is this really a problem, or just an itch you can't scratch? (ps: even a single int gets padded into a 1024 bye block)

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Just a guess - but maybe moveTo(...) rather tha drawTo when you want to go to a new coordinate without drawing?

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

I found this in Sun's serialisation spec:
"Each subclass of a serializable object may define its own writeObject method. ... When implemented, the class is only responsible for having its own fields, not those of its supertypes or subtypes."
Implies to me that the superclass's (JPanel's) fields will be serialised automatically?

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Yes, sorry, I didn't mean to imply that you weren't!

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Serialization stores everything about your class instances, so if you don't want all that you have the override the appropriate methods.
The portability issue is that Sun warn you that the details of how these things are serialised may change in future releases, so you cannot assume that an object serialised under 1.6.14 will de-serialise under 1.7. Depending on why you are serialising, and how long the data will be stored, this may or may not be as issue for you.