1

What I know that theoretically you can force a jTable to be non-editable by creating an AbstractTableModel and override the following method by always returning false all the time (eventhough this is not necessary due to the fact that the default method from the AbstractTableModel is already returning false).

@Override
public boolean isCellEditable(int row, int column) {
   return false;
}

It seems though that I still can't figure out how to make this work right for my code. What am I doing wrong? Here's my code:

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;

public class Datagrid extends AbstractTableModel {
    private static final long serialVersionUID = -1080095595481949205L;
    private String[] title;
    private String[][] data;
    private JTable table;
    private JFrame frm;

    public Datagrid(String[] title, String[][] data) {
        this.title = title;
        this.data = data;

        create_table();
    }

    public JTable getTable() {
        return table;
    }

    private void create_table() {
        table = new JTable(data, title);

        frm = new JFrame();
        frm.getContentPane().add(new JScrollPane(table));
        frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frm.pack();
        frm.setVisible(true);
    }

    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return false;
    }

    @Override
    public int getColumnCount() {
        return table.getColumnCount();
    }

    @Override
    public int getRowCount() {
        return table.getRowCount();
    }

    @Override
    public Object getValueAt(int row, int column) {
        return table.getValueAt(row, column);
    }

}
Sam
  • 7,252
  • 16
  • 46
  • 65
shidizzle
  • 55
  • 1
  • 1
  • 10
  • 1
    1) For better help sooner, post an [SSCCE](http://sscce.org/) (it will need a `main(String[])` to put it on-screen. 2) See [The Use of Multiple JFrames, Good/Bad Practice?](http://stackoverflow.com/a/9554657/418556). Particularly, `frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);` will cause problems if `create_table()` is called multiple times. 3) `create_table()` Please learn common [Java naming conventions](http://java.sun.com/docs/books/jls/second_edition/html/names.doc.html#73307) (specifically the case used for the names) for class, method & attribute names & use it consistently. – Andrew Thompson Nov 09 '12 at 08:22
  • 1
    You haven't set table model to the JTable – cubanacan Nov 09 '12 at 08:28
  • @cubanacan You should make this an answer – MadProgrammer Nov 09 '12 at 08:36
  • 1
    Here is one more problem, if you do `table.setModel(this)` you should get `StackOverflowError`, because when you invoke `table.getRowCount()` it invokes `getModel().getRowCount()` – cubanacan Nov 09 '12 at 08:37
  • @cubanacan You need to make these into an answer, you'll get an up-vote from me – MadProgrammer Nov 09 '12 at 08:43
  • thanks to @AndrewThompson and @cubanacan! I've already changed it. You guys are great and damn fast! I would give you all a +1 if you tell me how i can do it :D – shidizzle Nov 09 '12 at 08:59
  • @MadProgrammer I have just posted an answer with all problems and solution for them – cubanacan Nov 09 '12 at 09:02

3 Answers3

3

First of all, don't create UI elements from within models...

Second of all, don't create UI elements from out side the Event Dispatching Thread

Third of all (as pointed out by cubanacan), you've not applied the model to the the table...

public static void main(String args[]) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            TableModel model = new Datagrid(); // <-- Create a new instance of the model
            table = new JTable(model);         // <-- Apply it to the table..

            frm = new JFrame();
            frm.getContentPane().add(new JScrollPane(table));
            frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frm.pack();
            frm.setVisible(true);
        }
    });
}

cubanacan is on fire...

Fourthly, the following is going to crash your program. These methods are called by the table in order for it figure put how to configure itself.

public int getColumnCount() {
    return table.getColumnCount();
}

@Override
public int getRowCount() {
    return table.getRowCount();
}

@Override
public Object getValueAt(int row, int column) {
    return table.getValueAt(row, column);
}

You should referencing the internal data structures you are trying to model.

You might find it help to read through How to Use Tables

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
2
  • not an answer to isCellEditable, to remove from AbstractTableModel

.

public JTable getTable() {
    return table;
}

private void create_table() {
    table = new JTable(data, title);

    frm = new JFrame();
    frm.getContentPane().add(new JScrollPane(table));
    frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frm.pack();
    frm.setVisible(true);
}
  • separate view and model logics

  • in this form (missing add, remove row, setValueAt(...)) isn't possible to store any changes from JTables view to the AbstractTableModel

  • miss there ColumnClass

  • all data for JTables view are stored in XxxTableModel

  • quite correct AbstractTableModel for implemented methods in API (Object[]/Double[]/String[]... and Vector<Object>/Vector<String> ... )

Community
  • 1
  • 1
mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • First of all: thank you! Changing my table is not necessary due to the fact, that I only need to display my retrieved data from my database. Same is for ColumnClass. Why then should I implement them? – shidizzle Nov 09 '12 at 08:53
2

You have several problems here:

  1. You haven't set table model to the JTable.
  2. If you set your table model you will get StackOverflowError, because when you invoke table.getRowCount() it invokes getModel().getRowCount().
  3. If you set your table model you will not get column titles specified in constructor. Look at javadoc of method AbstractTableModel#getColumnName(int) for details.

Here is runnable and working solution based on your code:

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;

public class Datagrid extends AbstractTableModel {
    private static final long serialVersionUID = -1080095595481949205L;
    private String[] title;
    private String[][] data;
    private JTable table;
    private JFrame frm;

    public Datagrid(String[] title, String[][] data) {
        this.title = title;
        this.data = data;

        create_table();
    }

    public static void main(String[] args) {
        String[] columnTitles = {"Title 1", "Title 2"};
        String[][] tableData = {{"Value 1", "Value 2"}, {"Another Value 1", "Another Value 2"}};
        new Datagrid(columnTitles, tableData);
    }

    public JTable getTable() {
        return table;
    }

    private void create_table() {
        table = new JTable(data, title);
        table.setModel(this);
        frm = new JFrame();
        frm.getContentPane().add(new JScrollPane(table));
        frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frm.pack();
        frm.setVisible(true);
    }

    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return false;
    }

    @Override
    public int getColumnCount() {
        return title.length;
    }

    @Override
    public int getRowCount() {
        return data.length;
    }

    @Override
    public Object getValueAt(int row, int column) {
        return data[row][column];
    }

    @Override
    public String getColumnName(int column) {
        return title[column];
    }

}
cubanacan
  • 644
  • 1
  • 9
  • 26
  • 1
    remove to create a GUI from Model – mKorbel Nov 09 '12 at 09:08
  • ok, what i am now gonna do is creating a TableModel with parameters (String[] title, String[][] data). Also I am gonna create a new class which extends JTable where i'm gonna add my additional methods and listeners. Finally i will call those two in my main class by doing the following: [View Code](https://snipt.net/bamboocha/-1155/) - Is that correct now? :) – shidizzle Nov 09 '12 at 09:25
  • @bamboocha yes, it is better, but you really don't need class which extends `JTable`, if you are not going to extend some UI capabilities, listeners shoud go into controller class. Consider using [MVC](http://accu.org/index.php/journals/1524) pattern. – cubanacan Nov 09 '12 at 14:58