I use my JTable, my JTableModel for my project. I can not start the table with my column headers and empty data. May you help me? Thank you.
Here is my code
MainCode class
public class MainCode extends JFrame{
public MainCode(){
...........other codes here........
MyTableModel tm= new MyTableModel();
MyTable table=new MyTable(tm);
//JTable table=new JTable(tm); if I write this line,I see column names.
table.setPreferredScrollableViewportSize(new Dimension(480,80));
table.setFillsViewportHeight(true);
JScrollPane scrollPanetable=new JScrollPane(table);
frame.getContentPane().add(scrollPanetable)
........another codes...........
}
}
MyTable class
public class MyTable extends JTable{
public MyTable(){
}
public MyTable(int row,int col){
super(row,col);
}
#Override
public void tableChanged(TableModelEvent e){
super.tableChanged(e);
repaint();
System.out.println("public void tableChanged(TableModelEvent e)");
}
}
MyTableModel class
public class MyTableModel extends AbstractTableModel{
private String[] columnNames;
private Object[][] data;
public MyTableModel(){
super();
columnNames=new String[]{"A","B","C"};
data=new Object[][]{ {null,null,null}};
}
public int getColumnCount() {
return columnNames.length;
}
public int getRowCount() {
return data.length;
}
public String getColumnName(int col) {
return columnNames[col];
}
public Object getValueAt(int row, int col) {
return data[row][col];
}
}
it is not started with column names. What is wrong with this code.I see below image.
Because you do not have constructor in MyTable which takes parameter MyTableModel.
You are creating table like this:
MyTable table=new MyTable(tm);
So you must have constructor in MyTable like this:
class MyTable extends JTable {
public MyTable(MyTableModel tm){
super(tm);
}
}
If you have MyTable code that you posted here, your code will not compile!
Why are you overriding JTable?
Your own comment, if I write this line,I see column names suggests that your overriding of JTable is the problem. You have an overridden implementation of tableChanged(...), which the docs say Application code will not use these explicitly, they are used internally by JTable. Otherwise, your subclassed JTable isn't doing anything special to warrant subclassing.
If you must subclass, you have to tell the subclass how to use your model, which you haven't done (either via a constructor or setModel(...)).
More than likely you have not added the JTable in a JScrollPane which will cause the column names to be hidden
add(new JScrollPane(table));
Related
I want to make my JTable Non-editable
As I use following code to set rows using SetModel():
jTable1.setModel(DbUtils.resultSetToTableModel(rs)); //Resultset is added as each row using r2xml JAR file
I cant use follwing code:
jTable1.setModel(new DefaultTableModel() {
#Override
public boolean isCellEditable(int row, int column) {
return false;
}
});
Because we cannot use two setModel() for jTable.
How to overcome this problem?
I want to setresult and make jTable Noneditable.
Here are 2 ways to achieve that:
Create and use your own TableModel implementation which forwards all calls to the table model returned by DbUtils except for isCellEditable() in which you can return always false hence disabling editing. Your own table model could get the model returned by DbUtils as a constructor argument for example.
You can extend JTable and override its isCellEditable() method to return false (by default it calls the model's isCellEditable() method). Maybe other Swing enthusiasts will see this as an evil hack, but it is the simplest solution to your problem here.
Elaborating method #1
This is how you can create your model:
class MyModel implements TableModel {
private final TableModel m;
public MyModel(TableModel m) {
this.m = m;
}
#Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
// This is how we disable editing:
return false;
}
// The rest of the methods just forward to the other model:
#Override
public int getRowCount() {
return m.getRowCount();
}
#Override
public int getColumnCount() {
return m.getColumnCount();
}
// ...and all other methods which I omit here...
}
And this is how you can use it:
jTable1.setModel(new MyModel(DbUtils.resultSetToTableModel(rs)));
Elaboration of method #2
Extending JTable can even be an anonymous class:
JTable jtable1 = new JTable() {
#Override
public boolean isCellEditable(int row, int column) {
// This is how we disable editing:
return false;
}
};
And using it:
// You can set any model, the table will not be editable because we overrode
// JTable.isCellEditable() to return false therefore the model will not be asked
// if editable.
jTable1.setModel(DbUtils.resultSetToTableModel(rs));
you can use this code for make non editable jTable
simply you write one line in your program
jTable.disable();
I want to refresh and display my JTable after a user pressed a button. Before that the button generates an Object[][] in which the filtered data from the table is held.
The filtered data is different only in the number of rows.
I'm using the netbeans UI creator and the only way I could populate the table with data is by defining the abstractTableModel.
Here is the code of my abstractTableModel:
class myTable extends AbstractTableModel{
private String[] stolpci = {"Kategorija","Podkategorija","Opis","Cena","Datum","Boni"};
private Object[][] data = PregledovalnikGUI.vrniTabelo(); /*PregledovalnikGUI.vrniTabelo() returns a value in form of Object[][] in which the data is held*/
public int getColumnCount() {
return stolpci.length;
}
public int getRowCount() {
return vrstice.length;
}
public String getColumnName(int col) {
return stolpci[col];
}
public Object getValueAt(int row, int col) {
return vrstice[row][col];
}
public Class getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
public void setValueAt(Object value, int row, int col) {
vrstice[row][col] = value;
fireTableCellUpdated(row, col);
}
The jTable is set like:
Tabela.setModel(new myTable());
Which methods do I need to define to get the table to refresh at runtime?
inside myTable you could have a method called refresh() something like this
public void refresh(Object[][] objects){
//make the changes to the table, then call fireTableChanged
fireTableChanged(null);
}
Then in the button listener, call the above method:
Tablea.refresh(objects);//objects stores your filtered data
If you create a new TableModel, then nothing, the table will automatically update itself.
If the underlying data of the model is changed, then from within the model (seen as you extending from AbstractTableModl), you could call fireTableDataChanged, which lets the table know that the contents of the table have changed and it should redraw itself.
This may require that the model either have a refresh method of its own or that it has the capability to listen to changes from the data it is modelling
I've learned how to display a JTable in a Frame, but I can't figure out how to actually change the data. I've read a ton of tutorials on the subject, but nothing seems to click. Can you answer some questions about the code below?
1) In the actionListener, I call tab.getModel().getValueAt(1,1) and tab.getValueAt(1,1). I get the same data, "Petty." Is the "getModel()" necessary if it delivers the same data?
I figured that "getModel()" allowed me to access any custom methods I wrote in the CustomTable.java class, but that doesn't seem to be true.
The command tab.getModel().setValueAt(pane, 1, 2); does nothing. It doesn't even run the System.out.println command in the method. So the method isn't even getting called.
2) Why can I call "getValueAt" but not "setValueAt"?
I wrote a new method called "test()". If I call it in the actionPerformed method, it's produces a compile error. It's as if the method doesn't exist.
3) So how do I call these custom methods in AbstractTable Model?
In the program I'm working now, the table is populated by the results of a SQL query. I have a method in a Service class that populates the ArrayList below with custom objects built from the query. It displays the data just fine.
I wrote a method "reQuery" in the AbstractTableModel class, which calls a method in the Service and repopulates the ArrayList with data from a fresh query. This method works properly, but I can't call it (much less update the table data).
What am I missing here?
The main method is just "new MainFrame();" THe MainFrame and CustomTable classes are below.
package scratchpad3;
import javax.swing.*;
import java.awt.event.*;
public class MainFrame extends JFrame implements ActionListener {
JPanel pane = new JPanel();
JButton butt = new JButton("Push Me To Update The Table");
JTable tab = new JTable(new CustomTable());
MainFrame(){
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(1000,200,1000,1000);
pane.setLayout(null);
add(pane);
butt.setBounds(20,10,200,100);
butt.addActionListener(this);
pane.add(butt);
tab.setBounds(20,125,500,500);
pane.add(tab);
tab.setValueAt(pane, 1, 2);
}
public void actionPerformed(ActionEvent e){
System.out.println("With getModel() " + tab.getModel().getValueAt(1, 1) );
System.out.println("Without getModel() " + tab.getValueAt(1, 1) );
tab.getModel().setValueAt("Tampa", 1, 2);
tab.getModel().test();
}
}
CustomTable.java
package scratchpad3;
import javax.swing.table.AbstractTableModel;
import java.util.ArrayList;
public class CustomTable extends AbstractTableModel {
String[] colName = {"First Name", "Last Name", "City", "State"};
ArrayList<String[]> rows = new ArrayList<String[]>();
public String getColumnName(int col){
return colName[col];
}
public int getColumnCount(){
return colName.length;
}
public int getRowCount(){
return rows.size();
}
public String getValueAt(int row, int col){
System.out.println("getValueAt method was called."); //To verify the method was called
String[] s = rows.get(row);
return s[col];
}
public boolean isCellEditable(int col, int row){
return true;
}
public void setValueAt(String s, int row, int col){
System.out.println("setValueAt method was called"); //To verify the method was called
rows.get(row)[col] = s;
fireTableDataChanged();
}
public void test(){
System.out.println("Test");
}
CustomTable(){
rows.add(new String[]{"Bob", "Barker", "Glendale", "CA"});
rows.add(new String[]{"Tom", "Petty", "Jacksonville", "FL"});
}
}
You don't override the AbstractTableModel.setValueAt method, because you use incorrect signature. It should be public void setValueAt(Object s, int row, int col) instead of public void setValueAt(String s, int row, int col).
Im using Window Builder plugin in eclipse to make all the visual components, and i add a JTable, and at first it was a simple JTable, and it show the data correctly. Since i need that the data of the JTable be non-editable, i create a model to use the method isCellEditable. my code is this.
public class MyTableModel extends AbstractTableModel {
private static final long serialVersionUID = 1L;
private String[] columnNames;
private Object[][] data;
public MyTableModel(Object[][] sentdata, String[] cnames){
columnNames = cnames;
data = sentdata;
}
#Override
public int getColumnCount() {
// TODO Auto-generated method stub
return 0;
}
#Override
public int getRowCount() {
// TODO Auto-generated method stub
return 0;
}
#Override
public Object getValueAt(int rowIndex, int columnIndex) {
// TODO Auto-generated method stub
return null;
}
public boolean isCellEditable (int row, int column){
return false;
}
}//fin del modelo
and in the constructor of the class is this
String[] NombresdeColumnas = {"Nombre del Producto", "Cantidad en Inventario", "Precio Unitario"};
RegistroInventario inventariodatos = new RegistroInventario();
Object[][] data = inventariodatos.regresarInventario();
MyTableModel model1 = new MyTableModel(data, NombresdeColumnas);
Table_Inventario = new JTable(model1);
Table_Inventario.setGridColor(Color.gray);
JScrollPane scrollPane_1 = new JScrollPane();
scrollPane_1.setViewportView(Table_Inventario);
and it doesnt show anything, but when i was doing this:
Table_Inventario = new JTable(data, NombresdeColumnas);
it was working just fine, i donĀ“t know if the error has todo with de Window Builder form eclipse or in the code cause im new doning JTables.
your issue is return 0; in
public int getColumnCount() {
and
public int getRowCount() {
use DefaultTableModel instead, sure if isn't there really important issue to use AbstractTableModel for Object[][] data or Vector of Vectors
usage of AbstractTableModel make me sence for model based on HashMap or java.util.List e.i.
Your AbstractTableModel does not contain any data.
You indicate it contains zero rows and zero columns by your implementation of the getColumnCount and getRowCount methods.
And even when you adjust those methods, you do not use the data passed in the constructor as you always return null in the getValueAt method.
I think you should start reading the 'How to create a TableModel' section from the table tutorial
I followed Oracle's model for implementing an AbstractTableModel
http://download.oracle.com/javase/tutorial/uiswing/examples/components/TableDemoProject/src/components/TableDemo.java
I did this because my table has to contain 3 columns, and the first has to be a JCheckBox.
Here's my code:
public class FestplattenreinigerGraphicalUserInterfaceHomePagePanelTableModel extends AbstractTableModel {
private String[] columnNames = {"Auswahl",
"Dateiname",
"Pfad"};
private Object[][] data = {
{new Boolean(true), "datei.tmp",
"/home/user/tmp"}
};
public int getColumnCount() {
return columnNames.length;
}
public int getRowCount() {
return data.length;
}
public String getColumnName(int col) {
return columnNames[col];
}
public Object getValueAt(int row, int col) {
return data[row][col];
}
public Class getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
public boolean isCellEditable(int row, int col) {
if (col == 0) {
return true;
} else {
return false;
}
}
public void setValueAt(Object value, int row, int col) {
data[row][col] = value;
fireTableCellUpdated(row, col);
}
}
Here are my questions:
How does JTable (new JTable(FestplattenreinigerGraphicalUserInterfaceHomePagePanelTableModel)) know what the column names are and their values are? Since there's no contructor in my AbstractTableModel?! Is it becaue columnNames and data must be named like they are and JTable accesses them?
How can i put new Values in my JTable? Since columnNames and data are arrays. Can i replace them with vectors? If so, how do I init these vectors? In a constructor in myAbsTableModel?
I think it's very easy to get a solution but this Table handling isn't trivial to me, so thank u very much!
All Swing components come with default model implementations. I suggest you understand how to use them first before trying to create your own. For a JTable its called the DefaultTableModel. Read the API for methods to dynamically add/remove rows of data from the model. Here is a simple example to get you started:
import java.awt.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;
public class TableBasic extends JPanel
{
public TableBasic()
{
String[] columnNames = {"Date", "String", "Integer", "Boolean"};
Object[][] data =
{
{new Date(), "A", new Double(1), Boolean.TRUE },
{new Date(), "B", new Double(2), Boolean.FALSE},
{new Date(), "C", new Double(9), Boolean.TRUE },
{new Date(), "D", new Double(4), Boolean.FALSE}
};
JTable table = new JTable(data, columnNames)
{
// Returning the Class of each column will allow different
// renderers and editors to be used based on Class
public Class getColumnClass(int column)
{
for (int row = 0; row < getRowCount(); row++)
{
Object o = getValueAt(row, column);
if (o != null)
return o.getClass();
}
return Object.class;
}
};
table.setPreferredScrollableViewportSize(table.getPreferredSize());
JScrollPane scrollPane = new JScrollPane( table );
add( scrollPane );
}
private static void createAndShowUI()
{
JFrame frame = new JFrame("TableBasic");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( new TableBasic() );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
First, I think you need to learn a bit more about Java, especially inheritance (I'm referencing your constructor problem.
Answers to your questions :
define your column names via a private final static attribute, assuming your column names don't change.
since your class extends AbstractTableModel, you can define a constructor for it, where you'll pass the data. Redefine the getValueAt method to allow the model to use the data you're passing.
Some more advice :
don't do what you're doing in getColumnClass. Normally, all elements in a column will have the same class, so do a switch on the column index to get the classes.
to add a JCheckBox in one of your columns, you'll have to use a custom TableCellRenderer
The JTable determines how many columns by calling getColumnCount() on your column model. It then iterates and calls getColumnName(idx) for each column. Your class tells it the column name -- look at your implementation of those methods.
You can store your data in whatever format you want. The JTable calls methods on your table model to retrieve that data. If you want to add new items to your model, you can implement an addItem(Object o) method to your model; just be sure to call fireTableRowsInserted() for each new item.