1

Why won't table cell 0,1 change from aaa to XXXX?

import java.awt.*;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;


class MainFrame {

    public static void main(String[] args) {


        JFrame f = new JFrame("Refreshing JTable");
        JPanel p = new JPanel(new GridBagLayout());
        DefaultTableModel productsModel;
        JTable productsTable;

        f.setSize(800, 600);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


        String[] tableTitle = new String[] {"ID", "Name"};
        String[][] tableData = {{"1", "AAA"},{"2", "BBB"}};


        productsModel = new DefaultTableModel(tableData, tableTitle);
        productsTable = new JTable(productsModel) {
            public boolean isCellEditable(int r, int c) {
                return false;
            }
        };

        JScrollPane scrollpane = new JScrollPane(productsTable);


        tableData[0][1] = "XXXX";

        f.add(p);
        p.add(scrollpane);
        f.validate();
        f.setVisible(true);


    }


}

REASON: Apparently trying to update the array where data is stored will result in JTable not changing. Either DefaultTableModel needs to be updated or the whole table needs to be redrawn.

EDIT (possible Solution) One way is using Timer:

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;

class MainFrame {

    static JFrame f = new JFrame("Refreshing JTable");
    static JPanel p = new JPanel(new GridBagLayout());
    static DefaultTableModel productsModel;
    static JTable productsTable;

    public static void main(String[] args) {
        runGui();
    }

    @SuppressWarnings("serial")
    public static void runGui() {

        f.setSize(800, 600);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


        String[] tableTitle = new String[] {"ID", "Name"};
        String[][] tableData = {{"1", "AAA"},{"2", "BBB"}};


        productsModel = new DefaultTableModel(tableData, tableTitle);
        productsTable = new JTable(productsModel) {
            public boolean isCellEditable(int r, int c) {
                return false;
            }
        };

        JScrollPane scrollpane = new JScrollPane(productsTable);


        tableData[0][1] = "XXXX";

        Timer t = new Timer(2000, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                addColumns();
                remakeData();
                productsTable.setModel(productsModel);

            }
        });
        t.start();

        f.add(p);
        p.add(scrollpane);
        f.validate();
        f.setVisible(true);


    }

    private static void addColumns() {
        productsModel.setColumnCount(0);
        productsModel.addColumn("ID");
        productsModel.addColumn("Name");
    }

    private static void remakeData() {
        productsModel.setRowCount(0);
        productsModel.insertRow(productsModel.getRowCount(), new Object[] {"1", "Dummy item 1"});
        productsModel.insertRow(productsModel.getRowCount(), new Object[] {"2", "Dummy itme 2"});
        productsModel.insertRow(productsModel.getRowCount(), new Object[] {"3", "Dummy item 3"});
        productsModel.insertRow(productsModel.getRowCount(), new Object[] {"4", "Dummy item 4"});
        productsModel.insertRow(productsModel.getRowCount(), new Object[] {"5", "Dummy item 5"});
    }
}

EDIT(much better solution, the way it worked for me flawlessly) Using a static method. Since I'm adding new data in array through another Frame, I created a static method in MainFrame, which I call every time I add/update/delete Object in array. This method will redo the whole model after update and will therefore refresh table.

vedran
  • 2,167
  • 9
  • 29
  • 47
  • 5
    For better help sooner, post an [SSCCE](http://sscce.org/). – Andrew Thompson Mar 20 '12 at 18:59
  • 1
    I second Andrew's great recommendation as I think that there is no way we can guess what's wrong based on the information present. Also consider sprinkling your code with a hearty dose of System.out.println calls to help with debugging the source for the error and to make sure your assumptions are all correct. – Hovercraft Full Of Eels Mar 20 '12 at 19:12
  • possible duplicate of [Java, how to refres JTable](http://stackoverflow.com/questions/9790883/java-how-to-refres-jtable) – kleopatra Mar 20 '12 at 19:14
  • 1
    how often do you intend to post the exact same question without any signs of progress in understanding _and_ always without an sscce? – kleopatra Mar 20 '12 at 19:15
  • @HovercraftFullOfEels To put it simply, what is the best way to refresh table whenever any change occurs? For some reason table.revalider() doesn't seem to be working – vedran Mar 20 '12 at 19:15
  • 2
    @vedran: to put it simply, since you're using a DefaultTableModel, you need to do *nothing*. The JTable will automatically change the state of its view if the model changes since the model knows to fire notification methods that tell the view to update. Since this is not occurring, it suggests that there's a bug somewhere, which is why we are unable to help you yet. – Hovercraft Full Of Eels Mar 20 '12 at 19:18
  • @kleopatra no that was different issue, and as you can see solved. This one is about an error in code which I'm trying to find since this morning with no luck – vedran Mar 20 '12 at 19:18
  • the base issue is the exact same: you are doing something so wrongly that the table doesn't update itself - which is _does_ if everything is done correct, just as @HovercraftFullOfEels commented. _Show an sscce, now_ Without, there is exactly nothing anybody can do to help you. – kleopatra Mar 20 '12 at 19:22
  • @HovercraftFullOfEels I've edited the post to display only relevant parts of it. Sorry the be the bother, but I only started with swing yesterday and I was trying to fix this bug since like 12 hours ago Kinda getting desperate here. Is that part of the code correct, will that do the trick? – vedran Mar 20 '12 at 19:22
  • @vedran: without [sscce](http://sscce.org) there's no way of knowing if this is the same problem or a new problem. You are wasting our time pasting code that is unrelated to the problem, that contains all those unnecessary revalidates and repaints. Why are you refusing to post these when you've been asked previously several times? – Hovercraft Full Of Eels Mar 20 '12 at 19:24
  • @vedran: Either you've solved it or lost interest -- which is it? – Hovercraft Full Of Eels Mar 20 '12 at 21:00
  • @HovercraftFullOfEels, neither. went to lectures and then to sleep. I was painfully tired. I'll do the dummy version today and post it. – vedran Mar 21 '12 at 06:58
  • @HovercraftFullOfEels ok, here's the simplest version of what I'm trying to do: http://stackoverflow.com/questions/9800101/java-jtable-wont-refresh – vedran Mar 21 '12 at 07:24
  • Glad you've got it sorted, but you should not use static anything except for the main method. – Hovercraft Full Of Eels Mar 21 '12 at 11:34

2 Answers2

3

The solution to your problem (and the previous one) is rather simple, but unfortunately a bit too long to post it in a comment

  1. You make sure you do some reading on how a JTable actually works. A good starting point is the Swing tutorial and perhaps even the class javadoc of the most important classes JTable and TableModel. Another good read about Swing and the use of MVC is this document. It is much broader then only JTables but will provide you with more insight in how all Swing components are designed, and how you should use them.
  2. After reading that tutorial, you should understand that if you want to update the data which is shown in the table, you update the model of your table. The model will fire events which are received by the table, and the table will make sure it updates itself. After all, the table is only a view on the data (=the TableModel) so updates on the take should take place on the model side. If this is not clear, go back to step 1
  3. Now take a look at your code and remove the listener. Instead, update the model on the table and see how the table updates itself.
  4. If this does not work, you come back to this site with an SSCCE which you post. That way we can see that you tried something, what you tried and most likely what is wrong in your code. This SSCCE should include your code of the TableModel you use and the code that updates your TableModel since that is the most likely location for your problem.
Robin
  • 36,233
  • 5
  • 47
  • 99
  • Hi, thanks for the answer. Thanks to Andrew I found the problem. It would seem that I'm adding new data to array which I'm using as data container for the model, which won't do anything. Instead I'm looking for a solution which would allow me to constantly update table model. For now I have found a solution through a timer which calls remakeTable() method, which completely deletes model data, and then replace it with a new sql querry. – vedran Mar 21 '12 at 08:43
3

One problem with the SSCCE posted on your related thread is that the code changes the array which originally formed the table model, whereas it should be changing the table model itself.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • The thing is, the table shows data from sql query which I store in the array. Also, when I add the product, I add it in DB not just tablemodel. How could I then retrieve data from sql and store it directly in model? – vedran Mar 21 '12 at 07:47
  • *"The thing is, the table shows data from sql query which I store in the array."* So ...what? You expect the DB to update when the local array is altered? I'm confused, or you are, or both of us are. – Andrew Thompson Mar 21 '12 at 07:51
  • Probably you :) After all I'm the newb here. As for the question, rather poorly constructed one: Is there a solution you'd suggest for me which would help me update table model every time I add something through query? – vedran Mar 21 '12 at 07:55
  • PS: I have found the temporary solution through a timer, which literally deletes the whole model data and then replace it by a new query every few ms. Is that an acceptable standard or solution to this issue? I'm working on university project, so my grade is really standard-dependent. – vedran Mar 21 '12 at 07:58
  • *"add something through query?"* Try to imagine I'm not inside your head or looking over your shoulder at the screen of your PC. What does that mean? ***Details, people!*** – Andrew Thompson Mar 21 '12 at 07:59
  • I have two JFrames; one is MainFrame and other is AddProduct. When I want to add new product to DB I go to AddProduct window through JButton and using sql I can add new products to DB. This new product should then appear on the MainFrame table of products. It doesn't. And the only way for it to work in this example is to close the program and restart it, when the table will be populated by old + new products. Program works completely, adding removing, deleting products, creating invoices and adding products to them, creating contracts, etc. It's just this bug I need to fix so I can wrap it up. – vedran Mar 21 '12 at 08:10
  • 1
    *"..I have two JFrames.."* Not the immediate problem, but fix that **first.** See [Multiple frames: good/bad practice?](http://stackoverflow.com/a/9554657/418556) for details. As an aside, do you have an aversion to up-voting? Personally I'll give an up-vote to anyone who offers an answer to any of my questions (though I write good questions, so generally get good answers). – Andrew Thompson Mar 21 '12 at 08:15
  • I had the same discussion with one of the tutors regarding the two frames. He also suggested that I should try and avoid it, but since he saw the code, he said the implementation was ok. The second frame is just used to create products and consists of 4 textfields. Basically it doesn't interact with mainframe as it shouldn't. PS. As for upvotes, I do upvote but you'll have to forgive me, I'm drowning here and forget to do stuff. 3 deadlines for 3 different uni projects in 2 different languages, one of which I only started a month ago (C)... – vedran Mar 21 '12 at 08:32
  • I finally did it. I created a static method in my mainframe which I call every time I add/update/delete products to and from DB through another frame. Thank you for sticking with me this long. I know I can be annoying and unreasonable sometimes, but as I said I'm swamped and could really use help. – vedran Mar 21 '12 at 10:17
  • 1
    *"I finally did it."* Congratulations! Glad you got it sorted. :) – Andrew Thompson Mar 21 '12 at 10:23
  • Thank you. Now, onto the next issue :) I have to create panel where I can have search option for products table. I already have the underlying DAO and service methods ready, just need gui work. I was thinking about doing sort of Live search, where after anything gets typed in text field sql query will show results in JTable where att=something.getText()... ? Is that a good thing to do, or do you suggest going with old fashioned search button style? – vedran Mar 21 '12 at 11:09
  • *"or do you suggest.."* I suggest asking a new question specific to that topic. ;) – Andrew Thompson Mar 21 '12 at 11:28