Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

You can replace "f, e & s" with names you want to use that was just quick example from Ezzaral. He should also remember that even if he is giving small code examples he should use meaningfull names to avoid confusion like now :).

Actually those variables came from the code sample he got elsewhere for a CaretListener (shown in first post). I wouldn't use those if I were writing an example myself :)

Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

First Question, this entire statment. Are these variables, f, e, and s really just generic terms for me to replace with my information, or are they meant to be taken literally?

JTextField f = (JTextField)e.getSource(); 
            final String s = f.getText();

f, is this really just my searchField? I cannot figure out why there is an f there or what it means.

Those are variables - from the code that you copied and pasted in from a method that had a parameter "e". The others are defined right there in the method. Rename them whatever you want - they are variables.

I know e.getSource() should be replaced with what I am looking for, ie my cdNameField text, and string s, I cannot figure out what s is supposed to be.
I keep wanting to change it to

JTextField searchField = (jTextField).cdNameField
final String ??? = searchField.getText();

but of course that does not mean anything.

You are correct - that doesn't mean anything. The original code was doing nothing more than defining a String variable (which they called "s"; name it whatever you like) with the contents of a text field, which is the String that you want to search for.

second question is cdEntry.

CdwArtist cdEntry = (CdwArtist)listModel.elementAt(i);

Where did that come from, and why do I need it here?

Well, you do want to check a field on an item in the list, right? To do that you have to have a reference to it, hence the reference.

If …

Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

It cannot find symbol e form e.getSource, or item from item.substring (and honestly I do not even know what these two things are) and to top that off my dialog box does not work either.

Well, look at your code and you will see that you don't have variables "e" or "item". You don't need e.getSource() any longer anyway because you can just get the text to search for from your text field (e.getSource() was getting a reference to the component that you had the caret listener attached to). You changed "String item" to "CdwArtist cdEntry", so you have to work with the cdEntry now (and it has method to get it's properties...).

The only problem with your message box is a missing parameter. The form you are trying to use takes four, not three, which I am sure the compiler yelled at you about.

Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

You already had a pretty good start on the searching in that first post. The only issue there is that instead of

String item = (String)listModel.elementAt(i);

you would instead want to get

CdwArtist cdEntry = (CdwArtist)listModel.elementAt(i);

Using a boolean such as "matchFound" which is flagged on a match, you can present the message dialog if there was no match.

Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

You have all the knowledge to do it already, you just need to think about it.
a) You need to loop through the listModel.
b) You need to get the cd object and compare it's name property to the string you are looking for.
c) if it's a match, you need to make that the current cd
d) you need to set the text field values to the new current cd values.

I really can't spell it out any more clearly than that short of writing the code myself.

Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

Well, that doesn't really do anything at all beyond put the current cd info into your text fields. You will of course want to do that - after you have found the appropriate cd in the list model.

This statement does nothing whatsoever: if (searchField == cdNameField);

Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

You merely need to break down my previous post into steps and think about what each of those requires. You have text in a search field that you want to compare to the name (or title or whatever) property of each cd object in the list. The only way to do that is to loop through those and check for a match on each one. If one matches, you can make that the current cd. If there is no match, you could use the JOptionPane.showMessageDialog() method to inform the user that no match was found (alternately a label under the search field could be used for that as well).

Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

If Search is clicked and there is text in the search field, you just need to compare that to the cd names in the list model and if you have a match (or partial match if you wish), select that cd object.

Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

1st - This listener seems to be a CaretListener .... how will that work with my ActionListener and my SEARCH button?

It won't as written. It will respond to any text change in your cd name field and perform a search on the list for an incremental match. If you want this to only occur when search is pressed you will need a state variable like boolean searching; for the caret listener to check before performing the search. Alternately you could provide a separate search field for the user to type in or use an input dialog (JOptionPane.showInputDialog(..) ) for this. It depends on how you want searching to be performed.

2nd - I already have a runnable for my panel. Does the code from this runnable next inside my current one, or can I have more than one in the same app?

You can have multiple runnables just fine. All those are doing is putting a piece of code into a queue to be run in a separate thread.

Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

You cannot define a method inside another method - and that is what your code is trying to do.

Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

wow. that worked. so, setpreferredsize instead of logo.getsize was the answer?

Would you explain why that would make a difference?

The layout manager uses the preferred size of a component in determining how much space to allocate for it in the layout. If preferred size is not set it will try to determine one on its own based upon inspection of the component. Since you don't have any other components in that panel, just a custom paint routine, it didn't have anything to go on and probably gave it a size of 0x0 (or nearly, I'm not really sure there).

The point is, setPreferredSize(), setMinimumSize(), and setMaximumSize() are used by the layout managers in determining the initial, min, and max sizes to allocate to your components.

Just a side note:
You could also add the following constructor to your ShapesJPanel class, which would keep the preferred size info inside the panel that requires it

public ShapesJPanel(){
         super();
         setPreferredSize(new Dimension(75,150));
     }
Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

Ok, use this instead

// add shapesJPanel to frame    
ShapesJPanel logo = new ShapesJPanel();
logo.setPreferredSize(new Dimension(200,200));
getContentPane().add( logo );
Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

Um, this class has nothing in it. Are you sure this is the code? It's also called Shapes - not ShapesJPanel.

Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

It would help if you posted the ShapesJPanel code.

Ezzaral 2,714 Posting Sage Team Colleague Featured Poster
// add shapesJPanel to frame    
ShapesJPanel logo = new ShapesJPanel();
logo.setSize(125,200);
getContentPane().add( logo );
Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

How are you displaying the logo? You may have to set the size on your panel before you add it to your container if the logo has no intrinsic size of its own.

Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

Is there anything in the ShapesPanel?

Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

I would assume that is because you have explicitly set the table height. If you only give it a couple of rows, those rows will fill the available height.

Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

As peter_budo pointed out, there are some organizational issues with the way you are trying to build your layouts, but I think if you put

getContentPane().add( new ShapesJPanel() ); // add shapesJPanel to frame

right after you set the layout in initComponents(), your panel should show up fine.

Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

You might try adding /wait to the start command you are using, since you are chaining process commands here:

Process p = r.exec("cmd /c start /wait run.cmd");
Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

Or I could just do this.
if (++currCD >= listModel.size()) currCD= 0;
and not worry about it at all. Is this ugly programming by pro standards?

That is exactly what I was trying to get you to figure out. You don't need any method calls to know that the first index is zero.

Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

Keeps coming from my fingers, but I know currCD and lastElement cannot be compared like that.

Which is why I keep pointing out listModel.size(). That is the current number of items in your list. That number -1 is the index of the last item. If your pointer equals the number of items, you have incremented too far and need to wrap back to the index of the first item.

Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

>with first I think you been trying to say

currCD = listModel.get(0);

and last will be like thhis

currCD = listModel.lastElement();

don't forget deal with exception

His usage there misled you a bit. Actually, the currCD variable is just an int index for the current cd, so the get(0) and lastElement() won't apply since they return the objects in those positions.

This is a simple matter of keeping track of an index. listModel.size()-1 is the index of the last item. From there, implementing your next() and last() code should be trivial to figure out.

Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

You don't want to get currCD-- from listModel, just currCD. You have already decremented it in the statement that handles the bounds rollover.

size()-1 is the index of the last item in the model, i.e. 10 items indexed from 0-9.

Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

My bad, you'll need to use String.valueOf( newCD.getItemno() ) in the setText method for the numeric entries or a DecimalFormat formatter.

Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

You simply call setText() on the textfield with the value from the cd object.

itemField.setText( newCD.getItemno());
Ezzaral 2,714 Posting Sage Team Colleague Featured Poster
if (--currCD<0) currCD = listModel.size()-1;

and then listModel.get(currCD); would work just fine.

Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

Your parsing problem is clear from the exception message:

[B]Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: For input string: ""

[/B]It's trying to parse an int from an empty string. If you look at the code in your previous handler, you have it backward. You want to set the text to the value from the object - not the other way around.

Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

One I had not even considered until you asked it. I want to go back one record at a time, when I hit the very first record I would like to just loop around to the last record and start the process over again. Any suggestions?

Well, think about your index in relation to the list. If the decrement puts it past 0 you know what you want the next value to be and listModel has a size() function to help you out.

no1zson commented: The most helpful guy on this board ... at least to me. :o) +1
Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

Well, that is because it is a JList, which is suppose to display multiple items. toString() merely determines what the list displays for each item you add to it.

If you just want to show a single description then all you need is a text area or a label to show the description for a particular object.

Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

toString() is a method of the CdwArtist class. You do not need to access the list at all - it's purpose is to return information about the object instance itself. Methods that need that information call aCdObject.toString() to get it's string value. You seem to be running yourself in circles there but I cannot see why. You had a working toString() on the class so I'm not sure what you are trying to change.

Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

You cannot call a method on an int.

Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

listModel does not have a newCD method. It has a get(int index) method, which you have used before. Just retrieve the object like you have in the past and call toString() on it.

Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

For your purpose, all you really need is one formatter in the cd class

DecimalFormat formatter = new DecimalFormat("$0.00");

and used in toString() like

" Stock Value: " + formatter.format(getValue()) +
Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

I looked at the documentation, and I know it should help, but it does not. I just do not yet understand how to read those parameters on that site and mine down to what I need.

I understand it's a lot to swallow, but keep in mind, if you intend to do much with programming at all, in any language, you'll eventually need to get comfortable with using the api docs and Sun has a lot of links in there to tutorials that present basic usage.

You may also find the following tutorial in debugging helpful in squashing some of the errors you come across:
http://www.seas.upenn.edu/~cse1xx/projects/Debug/GuideToDebugging/beginners.html

Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

To format string output you just need to pass the numeric value to the format() method

myFormat.format(aDecimalValue);

http://java.sun.com/docs/books/tutorial/i18n/format/decimalFormat.html

Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

One issue may be that you are creating FormattedTextFields with a null format. You pass an uninitialized NumberFormat variable to them. Correcting those though will not affect what you are getting in the toString output. To make those conform to a format you will need to use a DecimalFormat such as new DecimalFormat("0.00") which has a format() function that you can use to present the string representation that you need.
http://java.sun.com/javase/6/docs/api/java/text/DecimalFormat.html

Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

I am sure this is a symptom of the problem, but the only thing that IS showing up is Name, Artist and .05 for restocking fee, everything else, even price that I enter shows up as 0. Something has to be pointed to the wrong place I think.

Yes, it sounds like your setters are not being called properly.

Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

Consider also that methods may be called in toString() as well, so this is just as valid

public String toString()
{
return "Artist:" + artist +
" CD Name: " + name +
" Item Number: " + itemno +
" Price: $" +price +
" In Stock: " + nstock +
" Stock Value: " + getValue()+
" Restocking Fee: " + restock +
" Total Inventory Value: $" + getTotal();
}

You can code getValue() either way you choose: by maintaining a "value" variable and updating it as other properties are changed, or by simply returning the calculation itself return nstock * price; (this would not be so great for performance if the calculation was called often or was expensive to calc. That really isn't a consideration in your particular case though.).

Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

It looks like you are getting a lot closer to something that will work out. I don't see any way for a user to add a CD though and you have already filled your array to the hard-coded max of 5 items. I assume you have put that part in to test the workings of your first(), last(), etc. methods?

no1zson commented: Always has a suggestion +1
Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

Inventory3.java:128: int cannot be dereferenced
cdNameField.setText(currCD.getcdName());
^
Inventory3.java:129: int cannot be dereferenced
artistField.setText(currCD.getArtist());

I think some of my logic may be off. I have taken the day off work tomorrow to try and work through one or both of these programs to completion. The more coding experience I can get under my best with either application the better. Finals are coming up in a couple weeks.

Again, you are trying to use the integer index value like an object. You need to actually get that object (using currCD as the index) from your listModel as a CdwArtist object.

Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

Count the number of params in your super() call and take a look at the base constructor.

Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

I could explain more of an architecture that would let your price field get populated after the relevant data had been entered, but honestly it would require some additional changes that I don't really think you would find worth it just now.

Instead, consider this: Why not simply display the value of calculated fields in the toString() info that shows in the list entry and drop the text fields for them altogether? There is little need to provide text entry fields for data that the user doesn't need to enter or edit - such as values calculated from other inputs.

Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

ActionPerformed will only get triggered by hitting enter in the text field with the listener. Even if triggers though, you will not get the value from a new CD that you are entering, because it is not yet in the list model until you click "add". Instead, what will be set in the field will be the value of the last CD (the one that currCD points to). To alleviate that you would have to either calc the price from text fields that you do have, or have the "Add" button create a new blank CD to work with and put in a Save button that added it to the list model.

Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

You have "currCd" - your variable is "currCD". Case matters.

You don't need the //CdwArtist currentCD = (CdwArtist) listModel.get( currCD ); line in there for anything.

Ezzaral 2,714 Posting Sage Team Colleague Featured Poster
private void btnAddActionPerformed(ActionEvent evt)
        {
            // Create cd to add
            currCD++;
            artistField.getText(currCD.getArtist());
            cdNameField.getText(currCD.getcdName());    
            Integer.parseInt(itemField.getText(currCD.getitemno()));
            Integer.parseInt(nstockField.getText(currCD.getNstock()));
            Float.parseFloat(priceField.getText(currCD.getPrice()));
            Float.parseFloat(valueField.getText(currCD.getValue()));
            Float.parseFloat(totalField.getText(currCD.getTotal()));
            Float.parseFloat(rstkField.getText(currCD.getrestock()));    
            
            // Add cd to list
            
            
            listModel.addElement(currCD);

Ok, I see. That was not the "currentCD" reference I was talking about. I meant a persistent one that you kept at the class level.
You do need to create a CdwArtist object there to add it to the list. Perhaps we should just call that "newCD" to avoid confusion. Also, since the index is 0 based, it would be easier to initialize currCD with a value of -1 when you declare it, so your add code would be:

private void btnAddActionPerformed(ActionEvent evt)
        {
            // Create cd to add
            CdwArtist newCD = new CdwArtist();
            newCD.setArtist(artistField.getText());
            newCD.setCdName(cdNameField.getText());    
            newCD.setItemNo(Integer.parseInt(itemField.getText());
            
                        <snip other sets>

            // Add cd to list
            listModel.addElement(newCD);
            currCD = listModel.size()-1;    // set currCD to the index that was added
Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

I have to remark out the CurrentCD line to get it to run, but I know I need it in there for currCD to work.

No, if you stick with currCD and access the cd object with listModel.get(currCD), you do not need currentCD necessarily. It's just a convenience reference and is probably just confusing you.

Display and toString() would come last.

I thought you already put a toString() method on your CdwArtist class? There was discussion about an item number and line breaks but I thought you had that part in there. You don't really need to get all that fancy on the toString() representation of the object in the list.

Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

implementing the delete button (remove the element from the array and repopulate the list display to reflect thus), and not allowing it to add CDs with blank values, what do you need to do?

Removing the cd from the list with listModel.remove( currCD ); should update the list display automatically, so that's one less thing to worry about.

Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

It would be a lot easier to just download Wampserver or XAMPP. Both will install Apache, MySQL, and PHP already configured.

Ezzaral 2,714 Posting Sage Team Colleague Featured Poster

Yes, as masijade mentioned, initialize the array elements to the value you want to represent "empty" before you start filling it. You didn't say what the valid range for your number entries was, but filling with -1 or Integer.MIN_VALUE can be useful values to represent "unset".