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();
Related
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 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));
This question already has answers here:
How to make a JTable non-editable
(7 answers)
Closed 1 year ago.
When a JTable component is created, cell editing is enabled by default. How can I prevent the user from editing the content of a JTable?
You can create a JTable using following code:
JTable jTable = new JTable() {
private static final long serialVersionUID = 1L;
public boolean isCellEditable(int row, int column) {
return false;
};
};
Basically what we are doing here is overriding isCellEditable and always returning false from it. This will make a non editabe JTabel.
A JTable uses an AbstractTableModel object. This is the thing you pass into the constructor of the JTable. You can write your own AbstractTableModel as follows
public class MyTableModel extends AbstractTableModel {
public boolean isCellEditable(int row, int column){
return false;
}
}
and then initialize your JTable as
JTable myTable = new JTable(new MyTableModel());
myTable.setDefaultEditor(Object.class, null);
Have you tryed simply:
JTable table = new JTable();
table.setEnabled(false);
About JComponent.setEnabled(boolean) it sayes:
Sets whether or not this component is enabled. A component that is enabled may respond to user input, while a component that is not enabled cannot respond to user input. Some components may alter their visual representation when they are disabled in order to provide feedback to the user that they cannot take input.
When it comes to JTable it doesnt seem to give any visual feedback at all. With the perk of still being able to click on the column headers. And in my implementation the application could still change the contents of the cells.
Hi I'm working a lot on java so I'm gonna give you my way:
There are two possibilities the first under netbeans. Go to customize code and make it like this:
JTArticleJPAddArrticle = new javax.swing.JTable();
JTArticleJPAddArrticle.setBackground(new java.awt.Color(204, 204, 255));
JTArticleJPAddArrticle.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
},
new String [] {
"Reference","Libellé","Marque","Prix d'achat","Prix de vente","Quantité","Total","Etat"
}
){
public boolean isCellEditable(int rowIndex, int columnIndex) {
return false;
}
});
jScrollPane8.setViewportView(JTArticleJPAddArrticle);
My other way is to do it is to make an instance of the table model. This is the second way:
model=new DefaultTableModel(head, 0){
#Override
public boolean isCellEditable(int i, int i1) {
return false; //To change body of generated methods, choose Tools | Templates.
}
};
jtable.setmodel(model);
Enjoy this is working well for me. All I want to do is help you guys out because I was helped out a lot earlier.
Well on netbeans you can right click on the table and click on table contents, then you go to the column tab and uncheck the "Editable" checkbox. Greetings!!
I know I am late but hope someone get use of this. You can simple add mouse listener like this:
jtable.addMouseListener( new MouseAdapter () {
#Override
public void mouseClicked ( MouseEvent e ) {
columnIndex = replacedAssets.getSelectedColumn ();
System.out.println ( "Double click on jtable" );
if ( columnIndex == 1 || columnIndex == 2 ) {
JOptionPane.showMessageDialog ( parent , "Editing this Field may cause error in the data." , "Error Edit Not Permitted For This Field" , JOptionPane.ERROR_MESSAGE );
}
}
});
this code prevent editing the columns of indexes 1 and 2 you can remove the if condition to make this work for all columns.
tm = new javax.swing.table.DefaultTableModel()
{
public Class<?> getColumnClass(int column)
{
switch(column)
{
case 0:
return String.class;
case 1:
return String.class;
case 2:
return String.class;
case 3:
return String.class;
case 4:
return String.class;
case 5:
return String.class;
case 6:
return String.class;
case 7:
return String.class;
case 8:
return String.class;
case 9:
return String.class;
case 10:
return String.class;
case 11:
return Boolean.class;
default:
return String.class;
}
}
#Override
public boolean isCellEditable(int row, int column) {
/* Set the 11th column as editable and rest non-
editable */
if(column==11){
return true;
}else{
//all other columns to false
return false;
}
}
};
table = new javax.swing.JTable(tm);
In this method "isCellEditable" we can enable and disable user edit for particular column. In this case enable column=11 and disable rest of the column
I want to bind a database table to a swing JTable, and make that JTable editable by using APIs in a updatable ResultSet(#insertRow,#deleteRow(),#updateRow()).
so I need to create a TableModel implementation by wrapping a ResultSet.
public class MyTableModel implements TableModel {
private ResultSet rs;
private ResultSetMetaData rsmd;
#Override
public int getRowCount() {
return 0;
}
#Override
public int getColumnCount() {
return 0;
}
#Override
public String getColumnName(int columnIndex) {
return null;
}
#Override
public Class<?> getColumnClass(int columnIndex) {
return null;
}
#Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return false;
}
#Override
public Object getValueAt(int rowIndex, int columnIndex) {
return null;
}
#Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
}
#Override
public void addTableModelListener(TableModelListener l) {
}
#Override
public void removeTableModelListener(TableModelListener l) {
}
}
then, how Can I implement the getRowCount() method ?
how to determine the numbers of rows in a updatable result set ?
for example, if user click a button "add row", then I call such methods :
rs.moveToInsertRow();
rs.updateString(1, "yqwang");
rs.insertRow();
how to sync the JTable UI and the underlying ResultSet?
You should not do that. A ResultSet needs an open connection to the database, and the changes done to the result set won't be committed to the database until you commit the connection.
This means that if the database decides to close the connection because it hasn't seen any activity for some time, or if your app crashes after three hours, you'll lose all the modifications done during these 3 hours.
This also means that you might lock some rows for a whole lot of time, and thus make other transactions wait for a whole lot of time before being able to do anything.
Copy the data from the result set into your table model, and start a new transaction each time you need to insert or update a row.
To bind JTable to database you need to refresh your JTable and relode JTable. To get no. of rows in result set just call these two methods-
rs.last();
int count = rs.getRow();
here count gives you no. of records in your ResultSet.
When you do insertRow() on the ResultSet "You cannot see INSERT result on the ResultSet". To see rows that where inserted you have to re-run your query and get new resultset.
For reference on "No result set type can see a row inserted by a result set INSERT operation." see http://docs.oracle.com/cd/B28359_01/java.111/b31224/resltset.htm#i1024719
I'm trying to use the example taken from the http://java.sun.com/products/jfc/tsc/articles/treetable2/index.html, in which I've substituted the filesystem model with my model.
I initially create a model, I display it in the JTreeTable, but now I'd like to update my model and then the JTreeTable (for example I want to add a node at the tree, modify a node, remove a node, etc.).
I don't know how I can do it. I can't see method that allow me to do what I want, I only see some method like treeNodesChanged, treeNodesInserted, etc., but probably I miss something in the global logic of this JTreeTable component.
Besides I'm not sure that I correctly create the model, because in various example I've seen people call various method over a "model" object (model.insertNodeInto, model.reload), inspite of I haven't a model object..In the example above, is simply called the abstract class AbstractTreeTableModel which implements TreeTableModel..
Update
public class TableModel extends AbstractTreeTableModel
implements TreeTableModel {
static protected String[] cNames = {"TrackNumber", "MWRTN", "LSRTN", "RFTN","TrackStatus","Prova","Prova2"};
// Types of the columns.
static protected Class[] cTypes = {TreeTableModel.class,Integer.class, Integer.class, Integer.class, Integer.class,String.class,String.class};
private ArrayList<Object> data=new ArrayList<Object>();
public void insertNode(Object node)
{ this.data.add(node); super.setRoot(data.get(0));}
In my main class I add objects to my model in this way:
...
model =new TableModel();
model.insertNode(threatList.get(i)); //inserting the root node
model.addChild(threatList.get(i),threatList.get(j)); // inserting the child
...
Then I pass the model to my JTreeTable and add it to my frame:
treeTable = new JTreeTable(model);
JScrollPane scroll=new JScrollPane(treeTable);
scroll.setAutoscrolls(false);
scroll.setPreferredSize(new Dimension(1000,80));
frame.add(scroll);
And this is the JTreeTable class:
public class JTreeTable extends JTable {
protected TreeTableCellRenderer tree;
public JTreeTable(TreeTableModel treeTableModel) {
super();
// Create the tree. It will be used as a renderer and editor.
tree = new TreeTableCellRenderer(treeTableModel);
// Install a tableModel representing the visible rows in the tree.
super.setModel(new TreeTableModelAdapter(treeTableModel, tree));
// Force the JTable and JTree to share their row selection models.
tree.setSelectionModel(new DefaultTreeSelectionModel() {
// Extend the implementation of the constructor, as if:
/* public this() */ {
setSelectionModel(listSelectionModel);
}
});
// Make the tree and table row heights the same.
tree.setRowHeight(getRowHeight());
// Install the tree editor renderer and editor.
setDefaultRenderer(TreeTableModel.class, tree);
setDefaultEditor(TreeTableModel.class, new TreeTableCellEditor());
setShowGrid(false);
setIntercellSpacing(new Dimension(0, 0));
setPreferredSize(new Dimension(60,60));
}
/* Workaround for BasicTableUI anomaly. Make sure the UI never tries to
* paint the editor. The UI currently uses different techniques to
* paint the renderers and editors and overriding setBounds() below
* is not the right thing to do for an editor. Returning -1 for the
* editing row in this case, ensures the editor is never painted.
*/
public int getEditingRow() {
return (getColumnClass(editingColumn) == TreeTableModel.class) ? -1 : editingRow;
}
//
// The renderer used to display the tree nodes, a JTree.
//
public class TreeTableCellRenderer extends JTree implements TableCellRenderer {
protected int visibleRow;
public TreeTableCellRenderer(TreeModel model) {
super(model);
}
public void setBounds(int x, int y, int w, int h) {
super.setBounds(x, 0, w, JTreeTable.this.getHeight());
}
public void paint(Graphics g) {
g.translate(0, -visibleRow * getRowHeight());
super.paint(g);
}
public Component getTableCellRendererComponent(JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row, int column) {
if(isSelected)
setBackground(table.getSelectionBackground());
else
setBackground(table.getBackground());
visibleRow = row;
return this;
}
}
//
// The editor used to interact with tree nodes, a JTree.
//
public class TreeTableCellEditor extends AbstractCellEditor implements TableCellEditor {
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int r, int c) {
return tree;
}
#Override
public Object getCellEditorValue() {
// TODO Auto-generated method stub
return null;
}
}
What I would is to fire an event after adding(or modifying, or removing) a child.
The model is the class holding your data. It must tell its view each time the data changes, so that the view refreshes itself and shows the new data of the model. This is the goal of the methods fireXxx().
Like with the other Swing components, when you change the data displayed by the component, you should thus do it by changing the data in the model, and call the appropriate fireXxx methods. The best thing to do is to encapsulate this in the model class, by adding specific methods in your subclass of AbstractTreeTableModel which perform the data modification and fire the appropriate event using one or several calls to fireXxx.
I suggest you read the Swing tutorial about tables and or trees and then apply what you learn here to your tree table. The idea is the same.