Hey guys, I was having a bit of trouble with making my GUI look presentable (not too busy or crammed up) and I have a few questions that shouldn't be too hard to answer.

I'll briefly explain what I have at the moment.

I have a total of 15 text fields that have information in them and when I click a submit button it adds it to the table. I then can click save once all my data is entered into the table and it will save my table data into a csv file. The problem with this is my table gets all crammed and messy with 15 columns. So I was wondering two things:

1) Is it possible to add 6 columns while the last column is a drop down menu that takes care of the last 10 textfields data which would be entered upon the submit button?

2) Or would it be possible to create a second table that would display the other half the information but also save to the csv file correctly. Ex: first table would have textfield data 1-8 and second table would have textfield data 9-15 but it would all save on one line in the csv file?

I believe both are possible, but I'm not quite sure about how to go about it.

A side note is that I'm using CSVReader/writer to save my table data to csv.

Recommended Answers

All 29 Replies

1) Is it possible to add 6 columns while the last column is a drop down menu that takes care of the last 10 textfields data which would be entered upon the submit button?

You can find code similar to this on the Java tutorials by looking up JTable stuff, but here is an example I wrote, slightly modified to fit your purposes. You'll notice that the TableColumn is attained by using getColumn(5), which means the TableColumn refers to your 6th column (which is what you requested in your explanation). Then that TableColumn's cell editor is set to be a JComboBox, which means when you click the column, the JComboBox will pop down, displaying whatever you put in it.

javax.swing.table.TableColumn column= jTable1.getColumnModel().getColumn(5);
        javax.swing.JComboBox comboBox = new javax.swing.JComboBox();
        //add your stuff in an ArrayList called list to the ComboBox as Strings. . 
        for (int i = 0; i < list.size(); i++){
           comboBox.addItem(list.get(i));
        }
        column.setCellEditor(new javax.swing.DefaultCellEditor(comboBox));

I forgot to say thank you for this bud.

I had implemented it and forgot to get back to the thread and post how it went.

The only problem I saw was that when I click my insert data button (to the table) the first index is blank until it is clicked. For the most part it won't be clicked.

Question 1:
Will this cause a problem when I write the data to a file?

Meaning will it write a blank spot for index[0]? Or will it skip that and only write the other indexes?

Another note that I saw was that it also added indexes that might not have been filled out, and I was having problems throwing an if statement in there to filter it out due to the loop:

for (int i = 0; i < list.size(); i++){
            if (!list.equals("")) {
                comboBox.addItem(list.get(i));
            }
           comboBox.addItem(list.get(i));
        }

The above won't work because they are incompatible types obviously.

Question 2:
But what would be a way to solve this issue?

Question 3:
And lastly, when I want to use tableModel.getValueAt() how exactly would I do that for a drop down menu (being as its the 5th column in a table?

Previously I had used getValueAt() like so:

for (int i = 0; i < tableModel1.getRowCount(); i++) {
                    String a = (String) tableModel1.getValueAt(i, 0);
                    String b = (String) tableModel1.getValueAt(i, 1);
                    String c = (String) tableModel1.getValueAt(i, 2);
                    String d = (String) tableModel1.getValueAt(i, 3);
                    String e = (String) tableModel1.getValueAt(i, 4);

which leaves me slightly confused on how to get it from the column 5 drop down menu.


Sorry for such a delay and thanks for the help already provided.

I've been using SWT lately not swing, so its hard to remember, but if you are talking about the Table's cell that has a JComboBox in it, it is supposed to be blank until you click it.... if you want to change that, you'd have to use some method like setSelectedItem on the JComboBox, and you might also have to call table.revalidate() afterwards or something like that, so that the table will know its data changed.

Question One (50% Solved):
Alright well it shouldn't cause a problem when writing it to a csv file would it? (meaning when saving it, would it also save a blank value?)

If it doesn't save a blank space then I shouldn't have a problem.

Question Two (Solved) :
I solved that one. I added the if statement to when I was adding the info to the arraylist instead which worked fine.

Question Three (Not Solved) :
For question three I am still a bit confused. How to I get the information from the jComboBox.

Would something like the following work? (I'm not sure how many items will be in the jComboBox at any given time):

// using CsvReader/Writer so that it can be written to a file

com.csvreader.csvWriter writer = new com.csvreader.CsvWriter("C:\\"); 

for (int j = 0; jComboBox.getItemCount(); j++) {
	String itemA = (String) jComboBox.getItemAt(j); 

	writer.writeRecord(new String[] { itemA } );
}

writer.close

The JComboBox is just an editor for a cell value. The cell value itself is an object in your data model just like any other column.

The reason I am asking is because out of a normal jTable cell you can get that info and save it to a file simply by doing this:

String a = (String) tableModel1.getValueAt(i, 0);
writer.writeRecord(new String[] { a } );

However when I tried that with the column that was a jComboBox it saves the whole array of objects as "" (blank) instead of the information that was entered into the jComboBox.

So would my example from my previous post work/be logical?

I'm not sure how you've tied in the JComboBox with your actual table model, but the JComboBox is merely an editor for a value, a String most likely and the value that was selected should be available just like any other table value with getValueAt(int,int). The editor is not the content, it's just a mechanism to change that content.

Sorry for the late reply, I see what you're saying now. So now my question has changed a little

Is there a way to write all the values of the jComboBox to a file instead of just the one that is selected?

That usage pattern does not really make any sense in the context of a table cell editor.

I'll explain my reasoning then, (perhaps there is a better option than a jComboBox that I'm not aware of)

I have a table in which I have 5 columns and another table with 10 columns. Instead of having two tables, I want to combine them without taking up 15 columns. Thus, I make a jComboBox to display the other values from the table with 10 columns.

Since the data in the second table are all small strings its easy to click the jComboBox and view what has been put in there. However, I want to save all of them to a file along with the other 5 columns.

When I do this:

for (int i = 0; i < tableModel1.getRowCount(); i++) {
                    String itemA = (String) tableModel1.getValueAt(i, 0);
                    String itemB = (String) tableModel1.getValueAt(i, 1);
                    String itemC = (String) tableModel1.getValueAt(i, 2);
                    String itemD = (String) tableModel1.getValueAt(i, 3);
                    String itemE = (String) tableModel1.getValueAt(i, 4);
                    String itemF = (String) tableModel1.getValueAt(i, 5);

                    writer.writeRecord(new String[] { itemA, itemB, itemC , itemD , itemE , itemF } );

                    }

writer.close

For:

String itemF = (String) tableModel1.getValueAt(i, 5);

It only writes the value that is selected, I want it to write down however many values I have in the combobox.

Is there a way to do that? Or is there another editor that is a better choice?

If you don't want all of the values visible at once as a table, I would personally probably go with a list or second table that loads the additional entries as the primary table selection changes.

The specifics of how you need to view and work with the data ultimately drive choices like that.

Well I am trying to cut out some of the columns because 15 just makes it look messy. So condensing it to 6 total columns and the last one being a jComboBox it allows me to have all the information there and when the person wants to view the extra data they just have to click the jComboBox to see the info.

This lines up all the information that I need and after lining it up, I want to save it to my csv file so that I can load it whenever I would like and have the table fill up automatically.

So instead of just writing the selected value I am wanting to know how to save all the values in the jComboBox.

The jComboBox is just there to conserve space and make the GUI present itself cleaner. The information it contains is just as important as the other info which is why I need to have a way to write all the values to text and not just the one that is selected.

I have been searching for ways to do so and I haven't really found a good way of going about it.

If you don't want all of the values visible at once as a table, I would personally probably go with a list or second table that loads the additional entries as the primary table selection changes.

I want all the values visible, just in a 'clean' atmosphere so that the table doesn't look crammed/jumbled. I don't want it to look like an overwhelming amount of information to take in.

I know how to write the values of a jTable, just not how to write all the values that are in the cell of the jComboBox.

>I want all the values visible, just in a 'clean' atmosphere so that the table doesn't look crammed/jumbled
Putting them into a combo box is not keeping them visible. The user must select the drop down portion to see them. This is a selection choice which would just as easily drive another list or table that listed the additional details.

Why not simply put the table in a scroll pane and let the user scroll over to those additional columns whenever they want to see them?

I have it on a scroll pane but thats for vertical purposes instead of horizontal.

The reason I don't want it horizontally is because the user would have to scroll over every time they want to add some new data or edit data.

By having it a jComboBox one can just click on the cell and view it quickly and move onto the next step of deciding whether to edit it or add new information.

To keep it clean, simple, and efficient for the user; I am looking for a way to write all the information contained in the cell with the jComboBox into the same file as the information of the columns next to it.

I take it there isn't a way to do this?

Oh, I'm sure you could do it given how flexible JTable and related models are. You would probably need to alter your table model to store a List in that column and use a JComboBox as the renderer for that List. You'll have to update the combo box's model to reflect the List value for each row.

It's not as quick and simple as using a combo box as an editor for a single value though.

So there wouldn't be the possibility of doing something simple such as the following code?

(I haven't test the code yet, just logically thought of how it could possibly be done and threw it together)

int itemCount = comboBox.getItemCount();
        ArrayList<String> list = new ArrayList<String>();

        for (int j = 0; j < itemCount; j++) {
            String abc = (String) comboBox.getItemAt(j);
            list.add(abc);
            System.out.println(list);
        }

This obviously would just print it out, but am wondering if this same technique could be used for writing it to a file?

That could be done if you stored a unique JComboBox instance in that column value for each row, which is somewhat equivalent to storing a List in that cell. You will probably have to deal with forwarding click events through the JTable down to the embedded component if you do store a combo box as a data item.

Honestly, the best way to handle these "but could I..." questions is to code them up and try them. It seems like an awkward way to handle that data to me, but it's your app and you're free to display it any way you choose.

To be honest I just want to have the last column have the ability to drop down and show the values in it when clicked and then have an easy way to save it. Whether it be a jComboBox or some other way.

I'm just not too familiar with my options, which is why I came here :]

Do you know any alternatives I could take?

I'll explain what I am doing so that you don't have to read all the above posts.

I have 6 columns total (5 normal and 1 that is a jComboBox). The jComboBox is more for looks than actual purpose. The info that is in the jComboBox is taken from textfields after they are filled in.

The only reason I have the jComboBox is so that it doesn't take up an extra 10 columns. This way the user can just click on the cell and it will drop down and show all the info in it. However when I save the info, it only saves the selected item. I had attempted to do a for loop to get around it but it didn't quite work.

So I'm currently stuck on how to save that data that is in the jComboBox. I don't want just the selected item, but all of the items in it.

Ezzaral has been a pretty big help thus far, however, we have yet to come up with a decent solution for it.

To give you an example of how to get the JComboBox that is the editor for your Table, specifically, for a TableColumn within that JTable. Note: I'm unsure if the way I called getTableCellEditorComponent was technically correct, so you should check the javadocs on what the arguments for that are for, but it got back what I was expecting.

JTable table = new JTable();
table.addColumn(new TableColumn());
TableColumn sportColumn = table.getColumnModel().getColumn(0);
JComboBox comboBox = new JComboBox();
comboBox.addItem("Snowboarding");
comboBox.addItem("Rowing");
sportColumn.setCellEditor(new DefaultCellEditor(comboBox));
		JComboBox box = (JComboBox)sportColumn.getCellEditor().getTableCellEditorComponent(table, null, false, 0, 0);
		for (int i = 0; i < box.getItemCount(); i++) System.out.println(box.getItemAt(i));

*Explanation: You can only use the getValueAt method to get the value that is currently showing in the JTable. In order to "get all of the values in the JComboBox" (that's what you want to do, right?), you would first have to get the JComboBox itself, then you would have to loop over the items stored in that JComboBox. I modified the code I'd shown you earlier (from Sun's tutorials) to do just that. Below, you'll notice the line sportColumn.setCellEditor(new DefaultCellEditor(comboBox)). This line is important. sportColumn is your column from the JTable; Each column has what is called a Cell Editor. The Cell Editor controls the rules for editing a cell's data when the cell is being edited by the user. From the line I showed you, you'll see that a new DefaultCellEditor is created, and the comboBox is passed to this editor. Hopefully now it'll be clear why later, I call sportColumn.getCellEditor().getTableCellEditorComponent() - the ComboBox is the component that your values are stored in, so it is what we want to get (so that we can save the values to a file later).

JTable table = new JTable();
table.addColumn(new TableColumn());
TableColumn sportColumn = table.getColumnModel().getColumn(0);
JComboBox comboBox = new JComboBox();
comboBox.addItem("Snowboarding");
comboBox.addItem("Rowing");
sportColumn.setCellEditor(new DefaultCellEditor(comboBox));
		JComboBox box = (JComboBox)sportColumn.getCellEditor().getTableCellEditorComponent(table, null, false, 0, 0);
		for (int i = 0; i < box.getItemCount(); i++) System.out.println(box.getItemAt(i));

*hopefully this helps, I just looked into it for you, so its possible that what I said was wrong, lol. But I've done a decent amount with JTables in the past.

Sorry for the late response on this part, I haven't had the chance to continue working on this part till today. I went ahead and tried what you were saying and the output comes out blank.

My code isn't the exact same as yours because I already have the table and column so I will go ahead and show you my source (in case I messed it up)

javax.swing.JComboBox comboBox = new javax.swing.JComboBox();
                    TableColumn myColumn = jTable1.getColumnModel().getColumn(5);
                    myColumn.setCellEditor(new DefaultCellEditor(comboBox));
                    JComboBox box = (JComboBox)myColumn.getCellEditor().getTableCellEditorComponent(jTable1, null, false, 0,0);

                    for (int i = 0; i < comboBox.getItemCount(); i++) {
                        //System.out.println(comboBox.getItemAt(i));
                                String allItems = (String) comboBox.getItemAt(i);

            writer.writerRecord(new String[] { item1, item2, item3, allItems });
}

Both printing it and adding it to file returned blank. I'm not quite sure why as the logic sounds correct. I hadn't even thought about getting the cell editor for the column. Didn't even know much about it until ezzaral mentioned it.

Am I missing something? Or does it also return blank for you?

I gave your code a test just to see if it was a problem with mine. Yours works, and I think I might know why mine is giving me problems.

I am running two loops because I am trying to write each column down and the last column which has the comboBox.

Here is what my code looks like:

private void SaveCsvActionPerformed(java.awt.event.ActionEvent evt) {     
                                   
        javax.swing.table.DefaultTableModel tableModel = (javax.swing.table.DefaultTableModel)jTable1.getModel();

        javax.swing.JComboBox comboBox = new javax.swing.JComboBox();
        TableColumn myColumn = jTable1.getColumnModel().getColumn(5);
        myColumn.setCellEditor(new DefaultCellEditor(comboBox));
        JComboBox box = (JComboBox)myColumn.getCellEditor().getTableCellEditorComponent(jTable1, null, false, 0,0);

        try {

            com.csvreader.CsvWriter writer = new com.csvreader.CsvWriter("C:\\myFile.csv");
            writer.writeRecord(new String[]{"Column1", "Column2", "Column3", "Column4", "Column5"});

            for(int i = 0; i< tableModel.getRowCount(); i++) {
                    String column1 = (String) tableModel.getValueAt(i, 1);
                    String column2 = (String) tableModel.getValueAt(i, 2);
                    String column3 = (String) tableModel.getValueAt(i, 3);
                    String column4 = (String) tableModel.getValueAt(i, 4);

                    for (int h = 0; h < box.getItemCount(); h++) {
                                String column5 = (String) box.getItemAt(h);

          
                    writer.writeRecord(new String[] {column1, column2, column3, column4, column5});
                }
            }
            writer.close();
        } catch(Exception e) {
            e.printStackTrace();
        }
}

Now looking at that, it looks like having that loop inside the other loop could easily cause problems.

So my question is, how would you loop through the comboBox cell editor and adding that to file right behind the other columns in the table?

Huh? Can you clarify what you're trying to do?

Okay well you're example shows how you read all the values at each index inside the jComboBox, assuming that the comboBox is the only column.

Well my table has 4 other columns in front of that column that has the jComboBox.

I am looping through my table to get each row. While looping through each row, I also have to loop through the jComboBox (and its editor) to get all the values in there.

So I have 5 columns and I am wanting to write them to a file. It looks like this:

Column1 = infoString
Column2 = infoString2
Column3 = infoString3
Column4 = infoString4
Column5 = String array (info thats in jComboBox, not just the one thats selected)

The reason I think mine is having trouble is that I loop through the first 4 columns and on the last one I have to do another for loop to get the jComboBox information. I think that is throwing it off, but I can't end the first for loop because then when writing the information to file I can't access the strings for each row.


Is that a bit more clear? I can elaborate more if needed.

Okay I have messed with the code a bit, not really progress but at least I have separated the loops, added commentary to help clarify what I'm doing, and am actually getting some output.

Here is what my code looks like now:

private void SaveCsvActionPerformed(java.awt.event.ActionEvent evt) { 

	//Table Model
	javax.swing.table.DefaultTableModel tableModel = (javax.swing.table.DefaultTableModel)jTable1.getModel();

	//ComboBox + Default Editor
        javax.swing.JComboBox comboBox = new javax.swing.JComboBox();
        TableColumn myColumn = jTable1.getColumnModel().getColumn(6);
        myColumn.setCellEditor(new DefaultCellEditor(comboBox));
        JComboBox box = (JComboBox)myColumn.getCellEditor().getTableCellEditorComponent(jTable1, null, false, 0,0);

        try {
	    //Start CSV Writer to write the header to myFile.csv
            com.csvreader.CsvWriter writer = new com.csvreader.CsvWriter("C:\\myFile.csv");
            writer.writeRecord(new String[]{"Column 1, Column 2, Column 3, Column 4, Column 5"});

	    //Set strings null so that they can be referred to outside of the loops
            String column1 = null;
            String column2 = null;
            String column3 = null;
            String column4 = null;
            String column5 = null;

	    //Get the info in the first 4 columns
            for(int i = 0; i< tableModel.getRowCount(); i++) {
                    column1 = (String) tableModel.getValueAt(i, 1);
                    column2 = (String) tableModel.getValueAt(i, 2);
                    column3 = (String) tableModel.getValueAt(i, 3);
                    column4 = (String) tableModel.getValueAt(i, 4);
            }
		    
		    //Get column 5 which contains jComboBox, get all values and set to a string and print to screen
                    for (int h = 0; h < box.getItemCount(); h++) {
                                column5 = (String) box.getItemAt(h);
                    }

	    //Create String[] so that we can write to file and check it with print statement
            String[] abc = new String[] { column1, column2, column3, column4, column5 };

	    //Write String[] abc to myFile.csv
            writer.writeRecord(new String[] { column1, column2, column3, column4, column5});

	    //Print out String[] abc to check if it worked correctly
            System.out.println("Did it come up with my info in the comboBox? >>" + abc + "<<");

	    //Print out each string individually
 	    System.out.println("What about doing it individually? >>" + column1 + column2 + column3 + column4 + column5 + "<<");  

	    //Close the writer
            writer.close();

        } catch(Exception e) {
            e.printStackTrace();
        }
}

Info inserted into jTable1:

column1: column1
column2: column2
column3: column3
column4: column4
column5: info1, info2, info3, info4, info5, info6, info7, info8, info9, info10

String[] abc print statement:

Did it come up with my info in the comboBox? >>[Ljava.lang.String;@19a0c7c<<

Printing Strings individually:

What about doing it individually? >>column2column3column4column5null<<

String[] abc written to file:

column1, column2, column3, column4

myFile.csv reads:

column1,column2,column3,column4,

Basically column5 doesn't change from what I initialize it to, which in this case is null.

So it seems that my 'box.getItemAt(h)' is coming up null. Which I found odd so I tested out yours, and yours worked.

So any idea why mine might be giving me problems?

Sorry for making another post, but its due to an error in the previous one and it not allowing me to edit the post.

In my previous post and code, I have:

JComboBox box = (JComboBox)myColumn.getCellEditor().getTableCellEditorComponent(jTable1, null, false, 0,0);

That was a mistake on my part, I actually have:

JComboBox box = (JComboBox)myColumn.getCellEditor().getTableCellEditorComponent(jTable1, null, false, 0,5);

I'm still having problems and I'm not sure why its not picking things up. I went ahead and put a print statement on 'box.getItemCount()' and its returning 0. The comboBox is populated so it shouldn't be giving me that.

Once again sorry for the triple post, however I didn't want you getting thrown off by a simple typo.

*Is there a reason we are not allowed to edit posts after a certain amount of time?*

Okay well I have fixed the previous problem, but now its not quite working the way I am wanting it to work.

for(int i = 0; i< tableModel.getRowCount(); i++) {
                    Column1= (String) tableModel.getValueAt(i, 1);
                    Column2 = (String) tableModel.getValueAt(i, 2);
                    Column3 = (String) tableModel.getValueAt(i, 3);
                    Column4 = (String) tableModel.getValueAt(i, 4);

                    for (int h = 0; h < box.getItemCount(); h++) {
                        Column5= (String) box.getItemAt(h);
                    }

                    
                    
                    System.out.println("Print whats in >>" + Column1 + "," + Column2 + "," + Column3 + "," + Column4 + "," + Column5 + "<<");

            }

Info submitted to columns:

Column1: info1
Column2: info2
Column3: info3
Column4: info4
Column5: data1, data2, data3, data4, data5, data6, data7, data8, data9, data10

Problem (it prints out):

Print whats in >> info1, info2, info3, info4, data10 <<

What I'm wanting it to print/write:

Print whats in >> info1, info2, info3, info4, data1, data2, data3, data4, data5, data6, data7, data8, data9, data10 <<

Then I go ahead and enter another set of data into it and the jComboBox seems to only recall the latest ComboBox info that it read.


My goal:
I want it to read (and write) each row at a time. Meaning it will get columns 1-4 (normal cells) and will get column5 (jComboBox) and write it to a file as the first line. And continue to do so with each line.

I know its a problem with how my loops are set up, however I'm not quite sure how to get it to read it all as one loop would seeing as it has to loop through the comboBox.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.