DefaultTableModel make cell not editable JTable [duplicate] - java

This question already has answers here:
How to make a JTable non-editable
(7 answers)
Closed 6 years ago.
I have an JAVA project and want to make my JTable with a DefaultTableModel non-editable. I know a work-around to do this, called:
JTable table = new JTable(...){
public boolean isCellEditable(int row, int column){
return false;
}
};
Like said: i dont like this. This is not according the rules of my school training.
Is there any way to do this? Maybe is there a good way. I hope so!

You should not subclass the JTable itself, but the table model:
DefaultTableModel myModel = new DefaultTableModel(...) {
#Override
public boolean isCellEditable(int row, int column) {
return false;
}
}
Or even better, don't use a DefaultTableModel, and use an AbstractTableModel that directly gets the information in your business objects rather than copying all the information from the business objects to Vectors.

select Jtable , and don't forget to create table model (DefaultTableModel TableModel)
JTable table_1 = new JTable (TableModel){public boolean isCellEditable(int row,int column)
{switch(column){
case 4: // select the cell you want make it not editable
return false;
default: return true;}
}};

Related

Dynamically adding JTable header color/text

My project involves a JTable and GUI. The user populates the JTable by adding "transactions" (represented as a row) and can then copy or delete these "transactions" at will.
I have decided that I want to add some more color to the table. In particular I would like to have every other header and column have a black background with white text so that it is easy to view.
I have been able to write the code to accomplish with the columns. I have also been able to change the color of ALL column headers. The problem that I seem to be having is changing individual column headers dynamically (like I do the columns). I have referred to the question here: JTable header background color but am very confused by it.. The solution posted is quite complicated and I am having trouble translating it to my individual code. Here is what I have so far:
tbl = new JTable();
String header[] = new String[]{
"Notification Reference Number", "Amount","Credit/Debit Indicator","Initiating Party Id",
"Initiating Party Scheme Name", "Debtor Name","Debtor Zip Code","Debtor Town",
"Debtor Country Sub-Division","Debtor Address","Debtor Agent Clearing System Id","Debtor Agent Name",
"Creditor Agent Clearing System Id",
"Creditor Agent Name",
"Return/Reject Code","Return/Reject Additional Info",
"Payment Instrument","Type of Payment","Pass-Thru Data","Clearing Account","Transaction Type",
"Return Occurence","Retired Indicator","Representment Method",
"Check-Split Indicator","Check Split Amount","Corporate Check Indicator","Source Batch Identifier"
};
dtm.setColumnIdentifiers(header);
tbl.setModel(dtm);
tbl.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
JScrollPane scroll = new JScrollPane(tbl);
scroll.getViewport().setBackground(Color.gray);
boolean flag = false;
for(int i = 0; i < header.length; i++){
tbl.getColumnModel().getColumn(i).setPreferredWidth(200);
if(flag==false){
TableColumn tm = tbl.getColumnModel().getColumn(i);
tm.setCellRenderer(new ColorColumnRenderer(Color.black,Color.white));
flag=true;
}else if(flag==true){
TableColumn tm = tbl.getColumnModel().getColumn(i);
tm.setCellRenderer(new ColorColumnRenderer(Color.white, Color.black));
flag=false;
}
}
As you can see I use the "flag" Boolean to ensure that every other column is changed. Here is the code for changing the columns:
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
// TODO Auto-generated method stub
return null;
}
}
class ColorColumnRenderer extends DefaultTableCellRenderer{
Color bkgndColor, fgndColor;
public ColorColumnRenderer(Color bkgnd, Color foregnd){
super();
bkgndColor = bkgnd;
fgndColor = foregnd;
}
public Component getTableCellRendererComponent
(JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column)
{
Component cell = super.getTableCellRendererComponent
(table, value, isSelected, hasFocus, row, column);
cell.setBackground(bkgndColor);
cell.setForeground(fgndColor);
return cell;
}
}
During experimenting I was able to set all headers with this:
tbl.getTableHeader().setOpaque(false);
tbl.getTableHeader().setBackground(Color.black);
tbl.getTableHeader().setForeground(Color.white);
I have tried numerous methods of coding a specific header but all are unsuccessful. I'm sure the solution is simple I just can't figure it out.
I should note that I apologize for not posting a full code example. This code is actually quite complex so I was hoping someone might be able to easily identify what I need to do before I have to create new JTable and try to isolate this example - Although I will do this if necessary.

How to add rows on a JTable using AbstractTableModel?

I have a JTable with my own Model (extends AbstractTableModel), and I'd like to add a row to it when I Click a JButton.
I don't really know how to hadd the row to the Model.
here is my model:
public class MembersModel extends AbstractTableModel {
String[] columnNames = {
"Name",
"Money Spent",
"Percent",
"Current Deck"
};
Object[][] data = {
{"Cajo", new Integer(150), new Integer(0), "Event Deck"},
{"Sekiam", new Integer(200), new Integer(0), "Jeskay"},
{"Nuvas", new Integer(100), new Integer(0), "Big Shit"},
{"Dos", new Integer(100), new Integer(0), "Crap Deck"},
{"Atoj", new Integer(100), new Integer(0), "IDK"}
};
public MembersModel(){
super();
calcAllPercent();
}
public void calcAllPercent(){
for(int i = 0; i < data.length; ++i){
data[i][2] = calcPercetage((Integer) data[i][1]);
}
}
private int calcPercetage(int money){
return (money*100)/teamMoneySpent();
}
private int teamMoneySpent(){
int money = 0;
for(int i = 0; i < data.length; ++i){
money += (Integer) data[i][1];
}
return money;
}
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) {
return false;
}
public void setValueAt(Object value, int row, int col) {
data[row][col] = value;
calcAllPercent();
fireTableRowsUpdated(0, 4);
}
}
Should i create my table aswell or add the method to the Model?
The key will be the data nucleus that you're using for your model, which here is your 2-D array, Object[][] data. The question then boils down to this: how do you add another row to the array and then notify the model's listener of the addition. While this can be done by creating a new data array with another row, copying all the data from this array, and adding the new data to the newly added row, why bother? For my money I'd
create a class to hold the data of a single table row, here I'll call it MyType, but you'll give it a better name, and it will have String, int, int, and String fields to correspond to the columns of your table.
Give this class some of the methods you have in your model above, such as doing row-specific calculations, calcPercentage(..), teamMoneySpent(...), and then the model can call the row object's method when this information is needed.
use an ArrayList<MyType> as my table model data nucleus, not a 2-dimensional hard-coded array.
give my model class an addRow(MyType myObj) method
in the method add to the ArrayList
and then call the appropriate model notification method, which here would be fireTableRowsInserted(...).
Note, I'm not sure what you mean by,
Should i create my table aswell or add the method to the Model?
Some problems with your current model:
The setValueAt() method is wrong. You should invoking tableCellUpdated(...). You don't want to repaint the data in the entire table when you update a single cell. Actually you don't even need to implement the setValueAt(...) method because your table is not editable.
You didn't override the getColumnClass(...) method. This method is required so the table can use the proper renderer to display the data.
Instead of creating a completely new TableModel, you could extend the DefaultTableModel. It already supports an addRow(...) method.
However, as hovercraft has already pointed out a better design is create a custom Object to store all the data of a single row. For a solution that uses this approach check out Row Table Model for a solution. The base TableModel is more complicated, but it makes it easier to create custom TableModels in the future since all the common code is in one class.
I would implement hovercraft's suggestion first so you better understand the concepts of creating a TableModel with a custom Object. I include this link as a suggestion for the future.

How jTable change cell color on a specific row. Java [duplicate]

This question already has an answer here:
Colored Table Cells
(1 answer)
Closed 8 years ago.
I made a java application to manage tasks.
My application is connected to a MySQL database.
I need the table rows where the priority is equal to 1 change color automatically. I've been searching and found some examples, but I couldn't do to work with my table.
My table was made using drag and drop, so it is the default type as you can see through the code.
Does anyone could help me try to implement this functionality in my small application please?
I'm really discouraged.
Sorry everyone.
Can anyone help me please?
Code of my jtable
DefaultTableModel tmTasks = new DefaultTableModel(null, new String[]{"Status", "Priority", "Task", "Desc", "Date"});
List<Tasks> tasks;
ListSelectionModel lsmTasks;
private void showTasks(List<Tasks> tasks) {
while (tmTasks.getRowCount() > 0) {
tmTasks.removeRow(0);
}
if (tasks.size() == 0) {
JOptionPane.showMessageDialog(null, "NO Tasks");
} else {
String[] line = new String[]{null, null, null};
for (int i = 0; i < tasks.size(); i++) {
tmTasks.addRow(line);
tmTasks.setValueAt(tasks.get(i).getStatus(), i, 0);
tmTasks.setValueAt(tasks.get(i).getPriority(), i, 2);
tmTasks.setValueAt(tasks.get(i).getTasks(), i, 1);
tmTasks.setValueAt(tasks.get(i).getDesc(), i, 3);
tmTasks.setValueAt(tasks.get(i).getDate(), i, 4);
}
}
}
My jtable to tasks!
You need a cell renderer for your table. Something like this
public class PriorityCellRenderer extends DefaultTableCellRenderer {
#Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
super.getTableCellRendererComponent(
table, value, isSelected, hasFocus, row, column);
if (Integer.valueOf(1).equals(table.getValueAt(row, 1))) {
setForeground(Color.RED); // or background
}
return this;
}
}
Installing of renderer:
table.setDefaultRenderer(Object.class, new PriorityCellRenderer());

How can i populate a JTable via a dynamic array or ArrayList fwith values from a database

I have 6 columns and a maximum of about 20 rows in the database. I like to make a general program in Java that populates the JTable with these values. I am very much conversant with using dynamic arrays, but not familiar with JTable attributes and model in Swing.
Can anyone guide me here on tho requirement? Thanks
You have to create your own table model. See the API documentation here: http://docs.oracle.com/javase/7/docs/api/javax/swing/table/TableModel.html
Basically, getColumnCount() would return your number of columns, getRowCount() the number of rows in your database, getColumnName(int columnIndex) some name for every column (the column name from the database or an arbitrary name, maybe from a constant string array). getColumnClass(int columnIndex) can, in the simple case, return String.class for every column. Then you have to convert every value to string.
getValueAt(int rowIndex, int columnIndex) has to return the value from the database for the given row and column. You should probably pre-load all these values in a 2D array or something like this (but that would be the answer to another question ;) ).
You can ignore the other methods for now, they are for editable tables.
Your code could look something like this:
String[][] tableData = readTableDataFromDatabase();
String columnNames = initColumnNames(); //From DB or constants
TableModel model = new DbTableModel(tableData, columnNames);
class DbTableModel extends AbstractTableModel {
private String[][] tableData;
private String[] columnNames;
public DbTableModel(String[][] tableData, columnNames) {
this.tableData = tableData;
this.columnNames = columnNames;
}
#Override
public Object getValueAt(int rowIndex, int columnIndex) {
return tableData[rowIndex][columnIndex];
}
#Override
public int getRowCount() {
return tableData.length;
}
#Override
public int getColumnCount() {
if(tableData.length == 0)
return 0;
return tableData[0].length;
}
#Override
public String getColumnName(int column) {
return columnNames[column]
}
}
This example assumes that you read the data from the database as a 2D array. If you use an O/R-Mapper (like the Java Persistence API - JPA), which I highly recommend, you would probably load a list of Entities. Each entity would contain the data for a table row. Anyway, the table model would not change much. Instead of accessing array values, you would get an entity object from the list and call "get"-Methods on the Entity.
There's more information in the Java tutorial: http://docs.oracle.com/javase/tutorial/uiswing/components/table.html#data
Nice but i hope readTableDataFromDatabase(); return resultset object
Have a look at the tutorial here: http://docs.oracle.com/javase/tutorial/uiswing/components/table.html#data
Here's a sample of a List-based read-only TableModel I wrote some time ago:
https://sourceforge.net/p/puces-samples/code/HEAD/tree/tags/sessionstate-1.0/sessionstate-suite/sessionstate-sample/src/blogspot/puce/sessionstate/sample/ParticipantTableModel.java

String path displayed when adding Image in JTable

I tried using setValueAt in adding an image but the problem is it prints the string and does not load the image. any help on this. the code is below
int selectedColumn = table1.getSelectedColumn();
int selectedRow = table1.getSelectedRow();
ImageIcon addIcon = new ImageIcon("c:\\onion.png");
table1.getModel().setValueAt(addIcon, selectedRow, electedColumn);
You need to create a table model which returns Icon.class for its getColumnClass method.
Ensure that your table knows what data is stored in a given column so it can choose the appropriate renderer. So, your JTable creation code should be something like this:
DefaultTableModel tableModel = new DefaultTableModel(dataObject, columnNames);
JTable table = new JTable(tableModel){
public Class getColumnClass(int column){
return getValueAt(0, column).getClass();
}
};

Categories