This week's book giveaways are in the Jython/Python and Object-Oriented programming forums.
We're giving away four copies each of Machine Learning for Business: Using Amazon SageMaker and Jupyter and Object Design Style Guide and have the authors on-line!
See this thread and this one for details.
Win a copy of Machine Learning for Business: Using Amazon SageMaker and JupyterE this week in the Jython/Python forum
or Object Design Style Guide in the Object-Oriented programming forum!
  • 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 all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Bear Bibeault
  • Paul Clapham
  • Jeanne Boyarsky
  • Knute Snortum
Sheriffs:
  • Liutauras Vilda
  • Tim Cooke
  • Junilu Lacar
Saloon Keepers:
  • Ron McLeod
  • Stephan van Hulst
  • Tim Moores
  • Tim Holloway
  • Carey Brown
Bartenders:
  • Joe Ess
  • salvin francis
  • fred rosenberger

How can I move data from one table to another?

 
Ranch Hand
Posts: 119
2
Netbeans IDE PHP Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello, world!

I am wondering how I can move a row of table data from one table to another? Let's say I have two tables placed next to each other. I want to move data from the left table to the right when I click a button labeled "Move data". The left table has cell editors attached to it's columns and the right table has a plain DefaultTableModel registered to it without any editors. I have written a small demonstration of what I have in mind.
The program is called DualJTable.

I have experimented with the getValueAt(int row, int column) method and tried to create an array of that data which I then tried to insert into the right table but it didn't worked at all. I hope someone can see what I am trying to accomplish. Many thanks in advance for all help I can get.



Best regards,
Robert!

 
Marshal
Posts: 67464
257
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Don't think of your table as having data. Think about the underlying models as having the data. Think of the table as simply displaying the data. Get a row out of the model. Conq sider how to copy that row to the other model. Start by copying rows without a GUI at all, using only table model objects.
Don't extend JFrame and don't make it implement action listener, despite what you see in many books and tutorials. Create a different listener object for each action (here shown with a λ expression). You can use a λ for action listener because it has one method.
Don't set the frame visible in a constructor because of the risk of a this reference escaping. Give the class a setVisible(boolean) method, not inherited from JFrame, and start a new thre‍ad:-
 
Robert Ingmarsson
Ranch Hand
Posts: 119
2
Netbeans IDE PHP Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
@Mr.Ritchie

I don't understand what you mean, sir, by "get a row out of the model" ? I have tried experimenting with looping around the getValueAt(...)-method but it didn't worked. Also I have edited my small program after your suggestion like below



Regards,
Robert!

 
Campbell Ritchie
Marshal
Posts: 67464
257
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't know much about JTables, so I looked up the documentation for DefaultTableModel. My, that looks old‑fashioned. It is possible to use a method to get a Vector<Vector>> (‍) and you can get a row out of that (I think) with the get() method.
Does the table model reflect changes made by editing cells in the JTable? Have you been through the Java™ Tutorials?
 
Rancher
Posts: 3111
26
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

I have experimented with the getValueAt(int row, int column) method and tried to create an array of that data which I then tried to insert into the right table but it didn't worked at all.



That is the exact solution you need to implement.

Where did you implement this solution? I don't see the code.

How can we fix the code if we can't see the code?

I'm really not understanding the problem:

1. you know how many columns you have in the table, so you create an empty array
2. you know which row you selected you you create a loop based on the number of columns
3. you use the getValueAt(...) method of the JTable to get each value and add it to the array
4. once the loop is finished you invoke the addRow(...) method of the DefaultTableModel.



Note:

Instead of using an Array, I prefer using a Vector. Then as you iterate through the loop you just add the value to the Vector.

I find it easier because you don't need to worry about the Array index.

Also, the DefaultTableModel will convert the Array to a Vector anyway, so this would be a little more efficient.


Also, this is still not a SSCCE. Your are confusing your application with your problem.

Your stated problem is you can't move a row of data from one table to another.

So all you need is:

1. a frame
2. two tables
3. a button and ActionListener to invoke the move.

How the data gets added to the left table is irrelevant.

So if we need to test the code to see what is happening we should not have to take time to manually add the data.

Your SSCCE should hard code the data. If you don't know how to hard code data then check out: https://coderanch.com/t/604597/java/Change-background-colours-validation-SetValueAt

for the most basic example of a SSCCE. Note. since you table is all String data you don't even need to override the getColumnClass(...) method of the JTable.

Once the data is hard coded, there is no need for the custom editor and the code is even simpler/smaller.

The New Row and Delete buttons are irrelevant to the problem and should be removed.

The split pane is irrelevant.

Event the layout code is irrelevant. You can just add components to the BorderLayout of the frame.

By simplifying the code we can concentrate on looking at only the relevant code.


 
Robert Ingmarsson
Ranch Hand
Posts: 119
2
Netbeans IDE PHP Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
@Mr.Camick

I have now edited my code after your suggestion below, though I don't understand if this SSCCE-code anymore. I removed the splitpane, two buttons, some layoutmanagers and only used like you said 1 frame, 2 tables and 1 button.



Also, this is still not a SSCCE. Your are confusing your application with your problem.

Your stated problem is you can't move a row of data from one table to another.

So all you need is:

1. a frame
2. two tables
3. a button and ActionListener to invoke the move.



This is how my code looks like now



The code in the actionlistener method doesn't works with this version of my small program. In the previous code sample it added a row of a "raw" object in the right table.

I hope I still can get help with this problem. Anyway, I work very hard on this so I am not giving up just yet.

Best wishes,
Robert!
 
Rob Camick
Rancher
Posts: 3111
26
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

I don't understand if this SSCCE-code anymore


The point of a SSCCE is to demonstrate the you understand the problem you are asking by posting minimal code required to duplicate the problem. We don't care about your real application. We only want simple code that demonstrates the problem

Your stated problem is "how I can move a row of table data from one table to another?"

So for a SSCCE the minimal code you need to demonstrate the problem would be something like:

1. you must have a frame
2. you must have data in one table added to the frame
3. you must have a second table added to the frame
4. you must be able to select a row of data you want to move
5. you must have a button added to the frame
6. you must have an ActionListener added to the button to invoke the "Move Row" functionality

Does the code you posted allow us to attempt to do that? No it doesn't.

It doesn't meet requirements 2 and 4. You don't have any data in the left table. So how can we possibly select a row to move?

I stated in my previous answer that how the data is added to the table is irrelevant, so we don't need to know that in your real application the data comes from a database.

So I suggested in my last answer you just simply "hard code" some data in the table so you can test your "Move Row" logic. I then gave you a link that shows how to create a table with hard coded data.

The code in the actionlistener method doesn't works



The method you are invoking in the DefaultTableModel is addRow(...)

Did you read the API for the addRow(...) method?

It takes an Array (1 dimensional) or it takes a Vector.

Why are you creating a 2D Array?

So once again the steps in your ActionListener code would be:

1. get the selected row. You know how to do this since you did it in your Delete Row logic
2. create a Vector to hold each column value. (you could use an Array, but as I suggested in my earlier answer a Vector is simpler)
2. then you iterate through all the columns in that row and add each value to the Vector
3. when the loop is finished you invoke the addRow(...) method on your table model using the Vector you created
4. you then delete the row from the left table.

 
Robert Ingmarsson
Ranch Hand
Posts: 119
2
Netbeans IDE PHP Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Best, Mr.Camick!

Thanks a lot for all tons of informative advice. I am a very slow learner - must be because of my diagnostics, I think. But now when I see it all before like this in the post it becomes clearer to me what I am doing wrong. However back to the issue, I have read somewhere that you no longer should use Vectors for java instead you should only use lists. Anyway I am completely stuck when it comes to creating arrays from loops. My coding skills are limited to me here. Is it possible to use a list and then create an array of it with the toArray() - method?

I have now revised my code so it follows your guidelines, at least to my very best. I have manually added a row of data to the left table with the setRowCount(1)-method in its model. Please forgive me if it doesn't meets the standard requirements.



Thank you for your time. Regards,
Robert!

 
 
Rob Camick
Rancher
Posts: 3111
26
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

I have read somewhere that you no longer should use Vectors for java instead you should only use lists.


If you have a choice, when creating your own custom class or methods, you would use a List over a Vector.

However, for older API's you can only use what the API supports. The addRow(...) method only supports a Vector or Array.

As I mentioned in my first answer. the DefaultTableModel will convert the Array to a Vector.

Given the above statement and since a Vector is easier to use anyway, why would you want to use an Array?

In any case the code you posted is still using a 2D Array, which is completely wrong.

I have now revised my code so it follows your guidelines,


The updated code looks nothing like my example code.

Did you not copy and test the code in the link provided?

Did you not see data displayed in the table when you run the code?

As I explained in your last question, an editor is NOT data that has been added to the table.

When I run your code there is no data displayed in the table!

I understand the code will not be exactly the same, and I don't expect you to code exactly the same way it do, but the point of the example code is to demonstrate the "concept" of how to hard code data directly into the table.

The code you posted does not implement the "concept" of using hard coded data. There is no need for editors or combo boxes, just data.

So my suggestion on how to learn the "concept" of creating hard coded data for a JTable is to:

1. start with my complete working example.
2. customize the code so it only has two columns of data
3. get rid of the getColumnClass(...) override

Now you have a table with hard coded data. So your next step is to:

1. add the second table
2. add the "Move Row" button and ActionListener (with logic that uses either a Vector or Array, NOT a 2D Array)

If you need more help then feel free to use the resources of the forum/web and do a search for other code examples that use the "addRow(...)" method.

If you don't like the way I create my basic SSCCE, then learn from the Swing tutorial on How to Use Tables.. The "SimpleTableDemo" also has a simple example although it is more complicated than mine because it has some "debugging" code.
 
Robert Ingmarsson
Ranch Hand
Posts: 119
2
Netbeans IDE PHP Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Best, Mr.Camick!

I have carefully studied your advices now. If I am not doing it right now then it will be difficult for me to stay on here. I have one basic egocentric strength in my nature and that is that I never give up despite high-end odds. I've been through a lot of hardship in my life and I have always gotten through it with a lot of personal sacrifices but to a positive price, it has always made me wiser.

I think I have solved this issue now. I looped through the rows and columns in the left table and created an array of the values in each of it's columns through the getValueMethod()-method. So finally here is the latest version of my code.



Many thanks and wishes!
Robert!

 
 
Marshal
Posts: 24950
61
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It's unfortunate that Swing requires such large SSCCE's, but what you posted isn't too much larger than what you'd need for an SSCCE. So that's good progress.

However I tracked down the code you were asking about and I have a few comments on it. Here's the original:



I've fixed up the indentation so it's now possible to try to understand the code. So, you're looping through the rows of the "left view" and processing them one at a time. So far so good. (Although maybe you should be looking at the "left model", for consistency.)

But then for each of those rows you appear to be looping through the columns of the row, at least that's what the inner loop suggests. But inside that loop you ignore the looping entirely. Instead you hard-code the fact that there are two columns that you want to extract. You create an array containing the values from those two columns, which is correct, but then you have a useless line which tests it for null. That value can't ever be null.

And then you add the array as a row to the "right model". This is also correct, it's what you want to do. You just don't want to be doing it for every column, which is what happens if you do it inside the loop. Apparently you noticed that was happening so you wrote code to break out of the loop, the loop which you aren't using anyway. So here's my version of the code which gets rid of the unnecessary loop over the columns:




It's possible that you might want to remove the hard-coded number of columns in that code; in that case you would need the loop over the columns to build up a Vector of the column values. Then after the loop was completed you would add that Vector as a row to the "right model".
 
Rob Camick
Rancher
Posts: 3111
26
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You have been willing to listen to suggestions and your latest SSCCE is showing progress. Although I do have a few more suggestions on how to make the SSCCE smaller and easier to read.

First, to expand on Paul's last comment about removing the hard coding of the number of columns. While the code may be simple for two columns, what if you had 20 columns? Would you really want to type getValueAt(...) 20 times and remember to change the column index each time? That is how you introduce potential bugs into your code. That is, you forget to change an index or you get the indexes in the wrong order.

Iterating through each column is a more reliable approach. In case you don't understand what we are suggesting the basic code would be:


The beauty of this code is that it doesn't change if you have 2 or 20 columns.

Regarding making the SSCCE smaller, my comments are directly related to the working example I linked you to earlier:


There is no need for instance variables. Instance variables are used when you create a object in one method and you later need to reference that object in another method.

In your real application it is possible that some (but not all) should be instance variables, but in this particular SSCCE they are not needed.


There is no need for methods to create the tables. It forces us to scroll down to those methods to see if your are setting special properties that could potentially cause problems.

Just create the table as follows:


Now at a quick glance we can easily see that you create two tables, one with data and one without.


Again, no need for separate methods. It makes us wonder if you are doing anything special with the scroll panes.

You can just use:


Also, note how I moved the "constraint" to the second parameter. If you read the API for the add(String, Component) method you will see that this method has been obsolete since JDK 1.1.


The above code can be replace with:


and you no longer need the imports for the WindowListener.

Changes like those above reduced the code from 150 lines to 85 lines, but more importantly, the first 40 lines of the constructor now contain the entire logic of your problem. So it is easy for us to see exactly what you are doing in a small piece of code without wondering what all those old methods were doing.

Don't get me wrong, using methods is great for isolating logical pieces of code, but you don't need a method to add a TableModel to a JTable, or add a JTable to a JScrollPane.

 
Robert Ingmarsson
Ranch Hand
Posts: 119
2
Netbeans IDE PHP Java
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Best, Mr.Clapham and Mr.Camick!

I have listen very carefully to your kind advices on making my code more SSCCEE friendly here. And I totally get it now.

@Mr.Camick

I have taken your adivce on using a vector instead of "manually" looping through the columns since it would'nt make any sense like you said if I had 20 columns or more. Thanks for this advice. I wish I could write. I hope I now have simplified the code in question for readability. Wish my english were a little better so I could express myself with tons of kind comments and questions here like you two can. But I got this greed to learn and that has always been a strength of mine.

Thank you both so very much for your kind advices. Here is what my code looks like now after revision:



Best happy valentine wishes to all!
Robert!

 
Think of how stupid the average person is. And how half of them are stupider than that. But who reads this tiny ad?
Building a Better World in your Backyard by Paul Wheaton and Shawn Klassen-Koop
https://coderanch.com/wiki/718759/books/Building-World-Backyard-Paul-Wheaton
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!