0

Ok so I think the title is all I've got to ask here.

My AbstractTableModel works fine, when I want to add an empty row, I use the following code to do so:

public void addRow() {
    Object[][] oldData = data;
    data = new Object[oldData.length + 1][3];

    // Copy old data to new data
    for (int x = 0; x < oldData.length; x++) { 
        data[x] = oldData[x]; 
    } 

    // Append new row 
    data[oldData.length] = new Object[] {"", "", false}; 

    fireTableRowsInserted(data.length - 2, data.length - 1);
}

Now, since I'm showing an empty row, I want the user to edit it, and I assume that the user will. Now, how do I make sure that the data is saved in my array as the user makes changes? Or, if that's not possible, what better alternative is there?

Ok so I should probably explain what I want to do:

enter image description here

I'm loading contents from a file, and displaying as a table. Now, the user might add new rows to the table on clicking the Add Row button. This will add 1 empty row per click. (In this image above is an instance when the button is pressed twice.

Now, I want that the user can edit the cells, and then maybe delete some rows (maybe) but on clicking the Save Database button, the updated data in the table is stores.

mKorbel
  • 109,525
  • 20
  • 134
  • 319
Karan Goel
  • 1,117
  • 1
  • 12
  • 24
  • Some questions to clarify what you want to do: you want to save *only* those rows modified/added or all the table? What have you tried so far? You seem to have a pretty good understanding of what you did so far, but it's not clear (to me) in what part exactly are you stuck :3 – asermax Mar 02 '13 at 06:00
  • Just use the `DefaultTableModel`. You can use the `addRow(...)` method to add an empty row. The DefaultTableModel also has a `removeRow(...)` method. – camickr Mar 02 '13 at 06:04
  • @asermax I want to save the complete updated table meaning everything in the table after adding/removing. – Karan Goel Mar 02 '13 at 16:38
  • @camickr I'm vary of using `DefaultTableModel` since it requires a lot more code and isn't really flexible enough. – Karan Goel Mar 02 '13 at 16:38
  • well, then it's pretty straight forward, just iterate over your model's objects inserting or updating the rows accordingly. The only caveat is that you have to do it in a different thread than the EDT to avoid blocking the UI. – asermax Mar 02 '13 at 16:52
  • @asermax Ah, so you mean when the user clicks the Save button, I start a new thread that the iterates over my `data`? BTW, I'm new to the concept of concurrency. – Karan Goel Mar 02 '13 at 16:54
  • How is it more code since you don't need to write a custom model? How is it not flexible enough? It supports your requirements of add/remove! – camickr Mar 02 '13 at 16:56
  • @asermax, updates to the model should be done on the EDT. – camickr Mar 02 '13 at 16:57
  • @camickr you seem to be missing the point of the question. He's wants to save the model data into a DB after the user modified it. Also, which model he wants to use is irrelevant, as long as it does what he wants to :/ user2059238: yep, that's it. Probably the best way to do it in your case is with a [`SwingWorker`](http://docs.oracle.com/javase/7/docs/api/javax/swing/SwingWorker.html) since it abstract some stuff about working with threads. If you have any doubts on concurrency, I'm sure you can find a lot of good info about it around here d: – asermax Mar 02 '13 at 17:02
  • @asermax, the question says `Now, how do I make sure that the data is saved in my array as the user makes changes?` So he doesn't know how to write a custom TableModel. His custom model doesn't do what he wants. My point is that he is struggling with writing a custom model when it is not required. I believe you just understand the basic of using a component before you attempt to change the behaviour. The comment about updating a DB is not what this question is about. He can't update the DB it he can't add the user data to the model. – camickr Mar 02 '13 at 17:23
  • As a sidenote, you should NOT be using arrays for your TableModel to store dynamic data. Adding and removing rows from an array is lots of work. That is why the DefaultTableModel uses Vectors. It manages all this work so you don't have to. – camickr Mar 02 '13 at 17:25
  • @camickr Oh, you're right about that question, I overlook that, sorry! In that case, unless there's any good reason to keep the custom model, I concurr that using the `DefaultTableModel` (or subclassing it) is the way to go. – asermax Mar 02 '13 at 20:00
  • Ok so now I'm using a `DefaultTableModel`. I'm not using a custom `Model` but the one that is provided. Also, I'm now using a vector os vectors and not a 2D array. However, my check boxes do not display, rather, they come as just "false". I am over-riding the `getColumnClass` method within my class. – Karan Goel Mar 20 '13 at 20:12

1 Answers1

2

You may get a better understanding by comparing several approaches:

  • In this example, either a background thread or a button can add a new row to a table. The background thread sequences instances of Runnable on the EDT via invokeLater(). It is conceptually easier to understand, but it is also easier to get wrong.

  • SwingWorker encapsulates sequencing access to shared data. The API and tutorial show the basic approach of updating a component's model using publish()/process(). This preferred mechanism is more robust and scalable.

  • In this more advanced example, a Swing Timer paces an Executor that controls a series of SwingWorker instances.

In all cases, the tables remain functional. You might use any as a basis for an sscce.

Addendum: Could you explain a little more about the strategies you suggested?

I've updated the list of examples and suggested some things to look for in context.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • I'm not so good with `Thread`. Could you explain a little more about the strategies you suggested? – Karan Goel Mar 02 '13 at 16:53
  • 2
    @user2059238, The answer provided links to working examples for you to look at and try. – camickr Mar 02 '13 at 16:59
  • As @camickr suggests, you may want to compare the approaches. I've updated the answer to include some intermediate material. As the first example uses checkboxes, consider converting it to use `SwingWorker`. – trashgod Mar 02 '13 at 18:48