• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • Liutauras Vilda
  • Jeanne Boyarsky
  • paul wheaton
Sheriffs:
  • Ron McLeod
  • Devaka Cooray
  • Henry Wong
Saloon Keepers:
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
  • Tim Moores
  • Mikalai Zaikin
Bartenders:
  • Frits Walraven

Head First Java BeatBox restoring a file query

 
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi all,

I hope I've put this in the correct forum.

I've completed the Head First Java Beat Box and everything worked fine. I then went on to the saving and restoring part and got that working (note I added a JFileChooser to my code). The problem I'm having is getting my head around the file restore part of the code as follows (note I made some variable/method name changes etc to the Head First code):-



From what I understand so far, the code above does the following:
Line 2 - Declare a boolean array called "loadCheckBoxState" and set it to null.
Lines 4/5 - Create a new object input stream to read from the saved file that gets passed to it.
Line 6 - Create the loadCheckBoxState boolean array. Then fill it with the contents of the objectInput stream, casted as a boolean array (boolean []). Q1. I'm not sure why it has to be casted as the file was saved as a boolean array?
Line 13 - Create a loop to iterate 256 times.

Now here's where my major problem is.
Line 14 - Declare a JCheckBox check and make it equal to the state of the actual checkbox in the class (note checkBoxState is the checkBox that was loaded into the ArrayList and the panel in the code not re-produced above) at the loop position. Q2. It's this line that's getting me. Why do we need to cast "(JCheckBox)"??? And how does this code actually change the checkBoxState checboxes in the code not re-produced (which are used to create the MIDI and build the track)??? To me this line reads make the JCheckBox check = the state of the JCheckBox checkBoxState
Lines 15 - Lines 19 - Iterate through the saved file and if the loaded checkbox is true/false, make the JCheckBox check true/false. My questions on this line will be answered (I think) if someone can answer my questions on Line 14.

Any help would be much appreciated. I hope I'm being clear in what I'm asking.

I can reproduce the full class if it would make it easier.

Thanks,

Al.
 
Ranch Hand
Posts: 859
IBM DB2 Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


The objectInStream.readObject() returns an Object which you then "convert" or cast to be the same as loadCheckBoxState
which happens to be an array of booleans.

Not sure about line 14, but probably quite similar.

Remember, an Object can pretty much be anything under the covers (except primitive).
Using generics here <> could also help.

WP
 
Al Dunne
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Great that's the Line 6 casting answered. Thanks William. What you mean about Generics <>? Around my queries?
 
William P O'Sullivan
Ranch Hand
Posts: 859
IBM DB2 Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Sorry,

It this case, they cannot help.

As for line 14, I have no idea how checkBoxState is defined.
It's obviously a collection of probably JCheckBox(es).

Show me what is.

WP
 
Al Dunne
Greenhorn
Posts: 13
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It's an ArrayList of type JCheckBox. Here's my full cose (sorry about all the comments, it was me trying to understand each step). I'd really like to understand how the file import is altering the state of the checkBoxState ArrayList. Again, any help much appreciated. Al.

 
Marshal
Posts: 79969
396
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Al Dunne wrote: . . . sorry about all the comments . . .

There’s nothing wrong with comments, but you need to use the right type. The lines are too long, which makes the code very difficult to read. Use /*...*/ comments over several lines, not one long //... comment. The same applies to those long array initialisers; they should be spread over several lines, otherwise they fall off the width of the screen.
 
Al Dunne
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks Ritchie. Can anyone help with line 14 of original code posting / line 273 of full code posting?

How exactly is this changing the checkBoxState arraylist?

Al.
 
Campbell Ritchie
Marshal
Posts: 79969
396
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I presume you have an array of booleans or similar and you are iterating the list and array simultaneously. You should actually avoid the if-else, like this:-There is some poor code style there.
  • It is error-prone to try running arrays in parallel, and arrays in parallel with lists are even worse. If you can think of some way to link the values directly to the boxes, preferably in the same class, that would be a great improvement. It would also allow you to use a for-each loop.
  • You can get some nasty Exceptions if the length of the array, the list, and the loop termination number are different.
  • You ought to parameterise the list, so as to avoid the error-prone (CheckBox) cast.


  • What you are doing is going through a list of check boxes, and setting their selected-ness (grammar!) to match the value in the parallel boolean[] array.
     
    Al Dunne
    Greenhorn
    Posts: 13
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Campbell Ritchie wrote:
    What you are doing is going through a list of check boxes, and setting their selected-ness (grammar!) to match the value in the parallel boolean[] array.



    But can you tell me how this actually happens. I understand that line 265 makes the boolean [] loadCheckBoxState = the boolean [] read from the saved file (object cast back to a boolean []).

    But whay I don't understand is how this then changes the state of the boolean [] "ArrayList <JCheckBox> checkBoxState" that gets run through the buildTrackAndStart method (Line 106).

    So the line to adjust this has to be Lines 272 - 280


    I think it must be Line 2 from the little snippet above that is changing the state of checkBoxState[i].
    To me this reads, new JCheckBox check = whatever is stored in checkBoxState [i] but I'm probably wrong and this actually means make whatever is in checkBoxState = to whatever gets put into 'check'.
    Can anyone clarify this?

    This is code from the HeadFirst Java book (slightly modified by me). If there's bad coding, it's their fault.

    Sorry about the delay getting back also. I have another problem in NetBeans that has been sucking up my time. Still haven't solved it. Relates to jar files. I might stick it up here now aswell.
     
    Campbell Ritchie
    Marshal
    Posts: 79969
    396
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    I think you are right in general, but there are lots of little points. You don’t have a CheckBox[], but a List<CheckBox>. It ought to have been parameterised; maybe that is old code from the 1st edition which hasn’t been updated. In the good old days before generics, you had to cast whatever you “got” out of a Collection (if you wanted to use anything but methods inherited from java.lang.Object). To use the setSelected() method, you have to tell the compiler that anything “got” has that method, which you do with a cast. Of course, if you mistakenly insert something which cannot be cast, you suffer an exception when you retrieve it. If (since Java5) you call it a List<CheckBox>, then the compiler knows anything put in is a CheckBox, so it knows anything coming out is also a CheckBox and it can perform the casting for you, secure in the knowledge it can’t suffer such an Exception.
    Now you have a List with 256 CheckBoxes in, all with a selected field, and a parallel array (ouch!). If the array and the List are the same size, and the List only contains CheckBoxes, then you set each CheckBox’s selected field to a value to match the value in the array. It is like saying

    When you start, I want you to select some of the check boxes. Select Nos 2 3 5 7 11 13 17 19 ... and un-select all the others.

    Are you reading all those booleans from a file? I didn’t remember that. It is along time since I looked at that part of Head First Java™.
     
    Al Dunne
    Greenhorn
    Posts: 13
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Yes, the saveBeatBox method is at Line 236 above. It just saves a boolean [] called savedCheckBoxState.

    Still don't understand how this line changes the state of checkBoxState[i]. Is it not always that the thing on the left of the = will become what's on the right?



    The code is from the second edition of HeadFirst which I think is the latest version.

    Thanks for taking the time.
     
    Campbell Ritchie
    Marshal
    Posts: 79969
    396
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    That code doesn’t change the state of the List at all. What it does, however, is get a reference to every Check Box in the List, and the next statement changes the state of that check box. My version did it all in one line.
     
    Al Dunne
    Greenhorn
    Posts: 13
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Campbell Ritchie wrote:That code doesn’t change the state of the List at all. What it does, however, is get a reference to every Check Box in the List, and the next statement changes the state of that check box. My version did it all in one line.



    Am I right then in saying that "JCheckBox check = (JCheckBox) checkBoxState.get(i);" makes 'check' be a reference to checkBoxState[i] so that if you change the state of 'check' (as the bit after that code does) it will change the state of checkBoxState[i].

    This is the part that I don't understand as in the most part all I've been working with is primitives where if you say int num = otherNum (another int) then the value of num will be the same as otherNum. Whereas if you applied the logic from above writing int num = otherNum would make the value in OtherNum the same as num.

    I'm vaguely remebering something about object references??? If you make an object1 ref = object2, am I right in saying that the object 1 is just a reference to object2 rather than an object itself. Confusing myself now.

     
    Campbell Ritchie
    Marshal
    Posts: 79969
    396
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Al Dunne wrote: . . . Am I right then in saying that "JCheckBox check = (JCheckBox) checkBoxState.get(i);" makes 'check' be a reference to checkBoxState[i] . . .

    No. There is no such thing as checkBoxState[i]. That is a List, and you are getting a reference to its i-th element, not [i] which is only used for arrays.

    Yes, check represents a reference to the whichever-th object out of the List. It provides access to that object and you can call its public methods. One of those methods alters whether it is selected or not.
    Yes, the whichever-th element of that List and check both point to the same object, so a method call in one reference affects the object which the other reference points to. That is why you can have the long version you quoted and the short version I quoted.The difference with primitives is that a primitive is stored as its actual value.At this point the contents of the memory location underlying j is 0000....0001_0101 and that underlying i is 0000....0111_1111. But objects don’t work like that. The memory location underlying check and the whichever-th you-know-what are the same. There is no way readily to find out the actual memory location, which the JVM hides from you. But whatever it is, it points to the same object and calling a method (or similar) on one of those references affects the state of the object. Just as when you heat Kettle kk, Kettle k gets hot too.
     
    Al Dunne
    Greenhorn
    Posts: 13
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Thanks a lot for your help Ritchie. Much appreciated.
     
    I'm a lumberjack and I'm okay, I sleep all night and work all day. Lumberjack ad:
    Gift giving made easy with the permaculture playing cards
    https://coderanch.com/t/777758/Gift-giving-easy-permaculture-playing
    reply
      Bookmark Topic Watch Topic
    • New Topic