jackmaverick1 has the right answer. The value of names.length is 10, so your program is exploding when k==4.

Consider using a java.util.ArrayList<String> instead.

Hi Adam,

Thanks for that. It's a good idea. But they don't use individual user logins so they're not using a login screen - they have an embedded, encrypted connection string specified in app.config.

It's a huge suite of applications - some running in batch/offline mode in a command window, one really big one running as a web server, and a few smaller stand-alone apps. They share a lot of code, including database interaction.

All this code uses [B]the[/B] connection string. If I were designing this thing from scratch, I'd use a configuration-specific constant. But they client didn't want to refactor such a central piece of code because of the size of the regression testing load. I thought it would be nice if I could leave them with a nicer deployment process.

Any other ideas?

Okay, I think I have what you want now. This is VERY brief and simple and I've made things hard-coded that you would want to make configurable in production code. But I'm illustrating the principle here.

Remember that this is an ArrayList<Employee> and you can populate it with Employee objects in whatever way suits you best. BUT because it implements TableModel you can plug it into a JTable as it's data source. Just like you would with a Object [] [].

[CODE]package storytime;

import java.util.ArrayList;
import javax.swing.event.TableModelListener;

public class EmployeeCatalog extends ArrayList<Employee> implements javax.swing.table.TableModel {

private String[] colHdg = {"Id", "First Name", "Last Name"};
private Class[] colType = {Integer.class, String.class, String.class};

public int getRowCount() {
    return this.getRowCount();
}

public int getColumnCount() {
    return colHdg.length;
}

public String getColumnName(int columnIndex) {
    return colHdg [columnIndex];
}

public Class<?> getColumnClass(int columnIndex) {
    return colType [columnIndex];
}

public boolean isCellEditable(int rowIndex, int columnIndex) {
    return false /* or true if you want to implement that... */;
}

public Object getValueAt(int rowIndex, int columnIndex) {
    Object value = null;
    Employee row = this.get(rowIndex);
    switch (columnIndex) {
        case 0:
            value = row.getId();
            break;
        case 1:
            value = row.getfName();
            break;
        case 2:
            value = row.getlName();
            break;
    }
    return value;
}

public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
    throw new UnsupportedOperationException("Not supported yet.");
}

public void addTableModelListener(TableModelListener l) {
    throw new UnsupportedOperationException("Not supported yet.");
}

public void removeTableModelListener(TableModelListener l) {
    throw new UnsupportedOperationException("Not supported yet.");
}

}[/CODE]

Oh yes, the subset is a "backed" copy which means that it reflects any changes you make in the original set. Similarly any changes you make in the subset will be reflected in the original. Be careful added members to the subset - the original limits (606 to 630 inclusive) still apply. If you try to add a value outside this range the subset will throw an exception.

The first one means include the "from" value (606) and the second one means include the "to" value. If you had used false instead of true then your subset would have returned [608,610,612,629];

[URL="

All kinds of things happening here...

Firstly, you're passing in a parameter of [ICODE]char unit2[/ICODE] but that parameter never gets used in the routine. So presumably unit is a numeric class member of some kind that your method can use. Is that what you want?

Secondly, in the method displayData, you're using variables called none2. unit2 and amount2 but they aren't declared in the method. So if they aren't class members then they don't exist at all outside the scope of convertLiquid.

You have to remember that your parameters are [I]local[/I] to the method that declares them - nowhere else. Also, the names of your parameters are [I]independent[/I] of the names of the variables you want to pass into the method - they don't have to be the same as anything outside the method. In fact, it's better if they're not otherwise you get difficult-to-track shadowing situations where parameters and local variables hide class members.

I suspect - although this is a guess-by-God - that you intend your call to ready something like this: [ICODE]c.println ("Your amount is " + amount + " converted to " + convertLiquid (-1.0, unit, amount));[/ICODE]

And your convertLiquid method should (perhaps) be using unit2 rather than unit...

The third thing is that this is an awfully ugly way of doing your conversion method, although as a student you may not have learned a better way yet. You could use an array.
[CODE]double [] convertFactors = {33.8140227, 0.001, 1000,
0.00852167911, 4.22675284, 202.884136, 67.6280454,
0.264172052, 1.05668821, ...

Okay, you're good with supplying a JTable with data, so I'll stick with the db side of things. I presume you're able to get a db connection going. This is very platform-specific and I'd need detailed information to help with that side. Here is the code I would use (using a method to show where the connection is coming from):

[CODE]import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.ResultSet;

List<Employee> loadEmployees (Connection dbConn) throws SQLException {
List<Employee> empList = new ArrayList<Employee> ();
Statement stmt = dbConn.createStatement (ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
ResultSet rs = stmt.executeQuery ("Select id,fname,lname,dep From Employee");
while (rs.next ()) {
empList.add (new Employee (rs)); // for the sake of argument...
}
rs.close ();
stmt.close ();
return empList;
}[/CODE]

This code will return with an arraylist similar to what you would end up with if you'd read it from a text file.

Hope that helps...

Well, what I do is:

A class called Employee that represents a single instance of an employee. Probably corresponding to a row from your Employee table. Possible containing related or derived employee data as well. How you expose the properties of your Employee class is a design decision only you can make...

With classes that reflect a table row I often make a constructor that takes a ResultSet row as an argument. Whether that's exposed to the public or encapsulated is another design decision you have to make with a view to your application's architecture.

If you want something that would conceptually correspond to an ArrayList<Employee> then I would call that EmployeeList or EmployeeTable (if it was your explicit intention to use it to reflect the entire employee table... which would be a bad design decision because of scalability issues). You could declare [ICODE]class EmployeeTable extends ArrayList<Employee>[/ICODE] and give it a constructor that tables a query (string or object), which it would use to obtain and instantiate the list members.

You're not getting many answers because we have no idea how you intend to use your employee data so we can't offer specific advice - just statements of principle, which aren't usually that helpful...

You need an extra close brace after the constructure in class Length. And take out the extra brace on the very last line. The way your code is, the public class InheritanceTest is a nested inner class within Length. I reckon that's what stultuske was talking about.

Other than that, your code should work...

Yes, the while problem was only going to show up once you've solved the problem of why it's not looping at all.

I'm assuming that the program just goes silent without any kind of error message at all. Tell me if I'm wrong on this.

You don't need [ICODE]new Console ();[/ICODE] at the start of askData, displayData and goodbye. Take those out, leaving only the one in your main method. See what happens there.

If that doesn't help, try putting in some lines around the place like [ICODE]c.println ("at end of askData");[/ICODE] and [ICODE]c.println("back from askData");[/ICODE] to see exactly where the flow of control goes on the way out of your code.

In plain words it says "while proc is not equal to 5 or proc not equal to 2 or proc not equal to 3". In order for the condition to be false proc would have to be equal to 5 AND equal to 2 AND equal to 3. Clearly not possible.

In relation to the main issue you're having, if you enter 3 does the program ask you the next question?

Once your not-looping-at-all issue is solved you'll have to do something about your terminating condition because your next problem is that it will never stop looping.

Your terminating condition will always be true: [ICODE]while (proc != 5 || proc != 2 || proc != 3);[/ICODE]

It doesn't matter what value proc has (5 for example), it won't be either of the other two values.

Definitely either Java 6 or Java 7. Definitely not Java 5 (1Z0-853) unless you're looking at joining a team that's working exclusively at that release level. Java 6 introduced radically useful and flexible new features. Java 7 introduced much less new stuff.

But... a beginner?!? Have you looked at any sample exam questions or a study guide? The Oracle Certified Professional exams make professional developers with years of Java experience sweat. A lot.

Best of luck!

Okay, it's a good start. A couple of important points though.

Firstly, you're running everything in a static method. You should run in an instance. Follow these steps:
1) Take all your local variables out of the main method and make them class variables.
2) Change the line that starts "public static void main" and give it a new, non-static, declaration. Something like "void dispatcher ()" would work.
3) Make a new public static void main that looks like this:
[CODE]public static void main (String[] args) {
Minilab5 banker = new Minilab5 ();
banker.dispatcher ();
}[/CODE]

Keep in mind that dispatcher() will probably evaporate completely away as you GUI'ise your application. You can start GUI'ising by extending javax.swing.JFrame. To make the frame visible you'll have to add the line banker.setVisible (true); before you call the dispatcher.

The next step is to start refactoring out the code in each case into separate methods. So for instance, you'd have a case looking like this:
[CODE]case 1:
deposit ();
break;[/CODE]

Later on you'll add some controls and stop talking through the console. But start with this first and post your next effort.

This question is a bit academic now as my contract at this place is coming rapidly to a close. But for future reference, I'd be very interested in the answer. We're talking about .Net 2.0 and Visual Studio 2005. Don't limit your responses to this platform though; I'm interested in best practice rather than hacky work-arounds for an elderly platform.

The company where I've been working runs different DEV, SIT, UAT and PROD databases. They have connection strings for all four databases in their app.config file, but only one is uncommented at any given time. To do a SIT build, you have to uncomment the SIT connection string, comment out the DEV string, build, then revert app.config. This seems very clumsy.

I played with creating four separate build configurations Configuration Manager and then using the configuration variables in app.config. For example using something like <add name="DBKEY" connectionString="$(Configuration)" ProviderName="System.Data.SqlClient" />

This didn't work and the connection string was returned as a literal.

I also found the tag in MyProject.vbproj: <None Include="app.config" />. I changed this to <None Include="app_$(Configuration).config" /> with some success. I could build the solution and run the exe from the target folder. But maintaining four separate replicats of app.config with the connection string as the only difference was worse than the problem I was trying to resolve. It also didn't work with the "Setup and Deployment" project.

I've come to the conclusion that adding a custom different constant to each build type in the "advanced compile options" for ...

My answer to the CSV import problem is the CsvParser class. The code will follow shortly, but using the class is illustrated with a little example. This code takes a CSV input file, which we will assume has a header row, with some specific header values assumed to be present. The data is assumed to follow in subsequent rows and the values are assumed to be in the columns corresponding to the headers.

[CODE]Dim parser As New CsvParser(new IO.StreamReader(txtFilePath.Text))
dim hdr as List(Of String) = parser.parseToList
dim idxName as Integer = hdr.IndexOf("Name")
dim idxEmail as Integer = hdr.IndexOf("Email")
While Not parser.eof
dim value as List(Of String) = parser.parseToList
dim name as String = value(idxName)
dim email as String = value(idxEmail)
' Do something with the values...
End While
parser.close()[/CODE]

And that's it. The class itself follows:

[CODE] Public Class CsvParser

    Private Const CR As Integer = Asc(vbCr)
    Private Const LF As Integer = Asc(vbLf)

    Private src As TextReader
    Private ch As Integer

    Public Sub New(ByVal reader As TextReader)
        src = reader
        advance()
    End Sub

    Public Sub close()
        src.Close()
    End Sub

    Protected Sub advance()
        ch = src.Read
    End Sub

    Public ReadOnly Property eof() As Boolean
        Get
            Return (ch < 0)
        End Get
    End Property

    Public ReadOnly Property eol() As Boolean
        Get
            Return (ch = CR) OrElse (ch = LF) OrElse eof
        End Get
    End Property

    Public Function parseToList() As List(Of String)
        Dim fld As New List(Of String)
        While Not eol
            fld.Add(nextField)
        End While
        If Not eof Then
            Dim nextCh As Integer ...

I've seen a lot of posts over time relating to importing and exporting CSV. Most of the answers involve using TextReader.readline and String.split, [B]which will not work[/B] with any but the simplest data. When you are writing for users who have the expectation that your application will work with anything they export from Excel, you will have to cover all the CSV bases.

I hope that this post will give you a clear idea of what you're involving yourself in when you decide you need to read a CSV file.

The characteristics of CSV data are:
[LIST=1]
[]The comma character is used to separate the fields. (This is obvious, but I thought I'd start with a couple of obvious points to warm up)
[
]The last field on the line is ended by the end-of-line character or the physical end of the file.
[]Any field that contains commas, double-quotes [I]or control characters[/I] will be surrounded by double-quote marks.
[
]Any double-quote marks within the field will be "escaped" with an extra double-quote character. For instance, the value Paul "Chuck" Norris would be converted to "Paul ""Chuck"" Norris".
[*]After the opening double-quote [I]ANY[/I] character is valid. Including line breaks. This is why you can't use readline.
[/LIST]
I have a parser class that works nicely and I'll post that on this thread in a little while, along with some notes on using it.

Cheers all!

Please note guys, and anybode else who comes here from searching for a solution to the problem of parsing CSV data:

The code posted in this thread does not parse CSV data in any but it's most excruciatingly simple form.

You cannot just split on commas because a) character fields may contain commas, and b) even if they don't character fields will be surrounded by double-quote characters that have to be stripped away.

You also cannot use readline because character fields may contain newline characters.

Finally, you must un-escape the double double-quoting escaping system used for fields that contain double-quote characters.

The absence of a CSV parser in the .Net library is a bit shocking in view of the fact that Microsoft invented the format in the first place, it's such a common requirement, and there seems to be so few solutions out there.

I don't have a solution either. When I find one I'll post a link or the code...