Jtable - getvalueAt() issue - java

I want to know why my getvalueAt() is picking old data when Enter is pressed.
I tried all update and table change modules, but I couldn't get it working. I am making an Excel sheet-like structure in JTable, in which one row updates on change to another row.
public void setValueAt(Object aValue, int row, int column) {
if(column == 2 || column == 3 || column == 4 || column == 5)
{
System.out.println("2 is: "+getValueAt(row, 2));
System.out.println("3 is: "+getValueAt(row, 3));
System.out.println("4 is: "+getValueAt(row, 4));
long closingbalance = Long.parseLong(getValueAt(row,2).toString())
+ Long.parseLong(getValueAt(row,3).toString())
- Long.parseLong(getValueAt(row,4).toString());
System.out.println("closing: "+closingbalance);
super.setValueAt(closingbalance,row, 6);
}
super.setValueAt(aValue, row, column);
}

I can't be able to answering your question on another forum, because a new forums version driving me crazy
there no reason parsing value from JTable,
JTable implemets all important data types
examples here or here
for better help edit your question with SSCCE

Verify that your CellEditor has concluded and that your TableModel is in a consistent state when you access other values. This example override's getValueAt() to derive the dependent cell's value. To avoid so much parsing, your TableModel should probably just contain instances of Long.
Assuming you really need to override setValueAt(), it's not clear what TableModel you're using. If you're extending DefaultTableModel, the super.setValueAt() implementation is appropriate; if you're extending AbstractTableModel, the super implementation is empty, and yours will need to fire the appropriate event.

Related

JComboBox remembering other selections

I have a JTable and in one column I have a JComboBox for each of the rows. I am dynamically adding rows when I press a button. The selection made in the combobox will determine what calculation is carried out for that particular row. For arguments sake lets say that the options for the combobox are: option 1, option 2, option 3 and option 4.
The issue I am having is as follows:
Say I have added 2 rows and select any option from the combobox for row 1, when I go to make a selection in the combobox for row 2 the same selection is ticked as was made for row 1. There seems to be some kind of memory. How can I disable this, so that the default selection is always -1 (i.e. non of the options selected)? I would like to have complete control over this.
Here is an example snippet of code just considering option 1:
String labels[] = {"Option 1", "Option 2", "Option 3", "Option4"};
JComboBox comboBox = new JComboBox(labels);
comboBox.setSelectedIndex(-1);
ItemListener itemListener = new ItemListener() {
public void itemStateChanged(ItemEvent itemEvent) {
int state = itemEvent.getStateChange();
ItemSelectable is = itemEvent.getItemSelectable();
if (selectedString(is) == "Option 1" & state == ItemEvent.SELECTED){
System.out.println("A");
}
}
};
comboBox.addItemListener(itemListener);
Thanks very much for your time and help :)
First of all don't use "==" when comparing strings. Instead you should be using the equals(...) method:
if (someString.equals(anotherString))
// do something
However, that is not the cause of the problem.
You are using the JComboBox incorrectly for a JTable. You should NOT be using a ItemListener (or any listener).
The combo box is just used as an editor for the table. That means when you select a value from the combo box, the TableModel of the table is updated. So if you have custom logic based on the selected value you need to override the setValueAt(...) method of your TableModel.
#Override
public void setValueAt(Object value, int row, int column)
{
super.setValueAt(value, row, column);
// add your custom logic here
}
How can I disable this, so that the default selection is always -1
The value displayed in the combo box is taken from the TableModel. So if you set the default value to be null the combo box will not have a selection when you start editing.
Read the section from the Swing tutorial on How to Use Tables for more information and working examples. Keep the tutorial link handy for future reference on Swing basics.

Add JButton only to a specific JTable cell (or more)

I wanna add a button to some specific cells where i might get null characters from my database. I tried overriding 'TableCellRenderer' . But it keep adding buttons to entire column. What should i do? (example wd b better)
But it keep adding buttons to entire column.
Yes, a renderer is designed to work for the entire column.
If you want a different renderer for a different row then you can override the getCellRenderer(...) method. Something like:
public TableCellEditor getCellEditor(int row, int column)
{
Object value = getValueAt(row, column);
if (value == null)
{
return super.getCellEditor(row, column);
}
else
return getDefaultRenderer(value.getClass());
}
You would also need similar code for the getCellEditor(...) method.
You can also check out Table Button Column for an example of a button renderer/editor.

JTable with multi-line cell renderer prints very weird

I have a JTable with a custom Cell Renderer for multi-line cells. Everything is ok, the JTable is painted ok in the screen and I am very happy with it, but ast night when I tried to simply print it, I came up with a very strange issue. Using:
table.print(PrintMode.FIT_WIDTH, new MessageFormat("..."), new MessageFormat("..."));
I saw that the table did not print entirely. Then using another class made from a colleague for printing JTables I had the same result:
The table (with multi-line cells) needed 22 pages to print. The printed document (which I only viewed in xps format since I do not own a printer) had also 22 pages. But up to page 16 everything was printed as expected and after that only the borders and the column headers of the table were printed.
Strangely (to me) enough, when I tried to print the table using another cell renderer that does not allow for multi line cells, the table needed exactly 16 pages and was printed entirely, albeit the cropping in the lengthy cell values.
I searched all over the net but I had no luck. Does anybody know why could this be happening? Is there a solution?
Update:
My cell renderer is the following:
public class MultiLineTableCellRenderer extends JTextPane implements TableCellRenderer {
private List<List<Integer>> rowColHeight = new ArrayList<List<Integer>>();
public MultiLineTableCellRenderer() {
setOpaque(true);
}
public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
String s = (String)value;
if (s.equals("<περιοδάριθμος>")) {
setForeground(Color.blue);
}
else if(s.equals("<παραγραφάριθμος>")) {
setForeground(Color.red);
}
else {
setForeground(Color.black);
}
setBackground(new Color(224, 255, 255));
if (isSelected) {
setBackground(Color.GREEN);
}
setFont(table.getFont());
setFont(new Font("Tahoma", Font.PLAIN, 10));
if (hasFocus) {
setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
if (table.isCellEditable(row, column)) {
setForeground(UIManager.getColor("Table.focusCellForeground"));
setBackground(UIManager.getColor("Table.focusCellBackground"));
}
} else {
setBorder(new EmptyBorder(1, 2, 1, 2));
}
if (value != null) {
setText(value.toString());
} else {
setText("");
}
adjustRowHeight(table, row, column);
SimpleAttributeSet bSet = new SimpleAttributeSet();
StyleConstants.setAlignment(bSet, StyleConstants.ALIGN_CENTER);
StyleConstants.setFontFamily(bSet, "Tahoma");
StyleConstants.setFontSize(bSet, 11);
StyledDocument doc = getStyledDocument();
doc.setParagraphAttributes(0, 100, bSet, true);
return this;
}
private void adjustRowHeight(JTable table, int row, int column) {
int cWidth = table.getTableHeader().getColumnModel().getColumn(column).getWidth();
setSize(new Dimension(cWidth, 1000));
int prefH = getPreferredSize().height;
while (rowColHeight.size() <= row) {
rowColHeight.add(new ArrayList<Integer>(column));
}
List<Integer> colHeights = rowColHeight.get(row);
while (colHeights.size() <= column) {
colHeights.add(0);
}
colHeights.set(column, prefH);
int maxH = prefH;
for (Integer colHeight : colHeights) {
if (colHeight > maxH) {
maxH = colHeight;
}
}
if (table.getRowHeight(row) != maxH) {
table.setRowHeight(row, maxH);
}
}
}
Furthermore, if you test the following very simple example you will notice that something is terribly wrong with the printing, but I really can't find what!
public static void main(String[] args) throws PrinterException {
DefaultTableModel model = new DefaultTableModel();
model.addColumn("col1");
model.addColumn("col2");
model.addColumn("col3");
int i = 0;
for (i = 1; i <= 400; i++) {
String a = "" + i;
model.addRow(new Object[]{a, "2", "3"});
}
JTable tab = new JTable(model);
tab.print();
}
I believe you are having the same problem that I had when I asked this question:
Truncated JTable print output
I found a solution to my problem, and I believe it may help you as well.
The answer is here:
Truncated JTable print output
To summarize my answer:
If your TableCellRenderer is the only place in your code where you are setting rows to their correct height, then you are going to run into trouble caused by an optimization inside JTable: JTable only invokes TableCellRenderers for cells that have been (or are about to be) displayed.
If not all of your cells have been displayed on-screen, then not all of your renderers have been invoked, and so not all of your rows have been set to the desired height. With your rows not being their correct height, your JTable overall height is incorrect. After all, part of determining the overall JTable height is accounting for the height of each of that table's rows. If the JTable overall height isn't correct, this causes the print to truncate, since the JTable overall height is a parameter that is considered in the print layout logic.
An easy (but perhaps not squeaky clean) way to fix this is to visit all of your cell renderers manually before printing. See my linked answer for an example of doing this. I actually chose to do the renderer visitation immediately after populating my table with data, because this fixes some buggy behavior with the JTable's scrollbar extents (in addition to fixing the printing.)
The reason the table looks and works OK on-screen even when printing is broken, is because as you scroll around in the table, the various renderers are invoked as new cells come on screen, and the renderers set the appropriate row height for the newly visible rows, and various dimensions are then are recalculated on the fly, and everything works out OK in the end as you interact with the table. (Although you may notice that the scrollbar "extent" changes as you scroll around, which it really shouldn't normally do.)
Strange thing is that behavior is not deterministic.
Such behavior always makes me suspect incorrect synchronization.
It's not clear how your TableCellRenderer works, but you might try HTML, which is supported in many Swing components.
Another useful exercise is to prepare an sscce that reproduces the problem in minature. A small, complete example might expose the problem. It would also allow others to test your approach on different platforms.
This answer is probably too late for the one who asked this question, but for everybody with a similar problem, here is my solution;
I had exactly the same problem, I have my own TableCellRenderer to handle multi-line Strings which works flawless for showing the table but makes the printing of the table unreliable.
My solutions consists of 2 parts;
Part 1: I have created my own TableModel, in the getValueAt() I 'copied' a part of the StringCellRenderer logic, I make it recalculate and set the height of the table row in case af a multi-line String AND return the String as HTML with 'breaks' instead of line-separators.
Part 2: Before invoking the table.print() I call the getValueAt() for all cells (a for-loop over the columns with an inner for loop over the rows invoking the getValueAt()), this has to be done 'manually' because the print functionality doesn't invoke all getValueAt's (I have found reasons on different fora regarding this issue regarding the execution of the TableCellRenderers).
This way the clipping of the table is done like it is supposed to, only complete rows are printed per page and it devides the rows over severall pages if required with a table header at each page.

AbstractTableModel setValueAt not firing upon Jbutton Click

I have a custom TableModel that extends the AbstractTableModel.
public class IndicatorPropertyTableModel extends AbstractTableModel
The setValueAt function I wrote fires appropriately in cases when you type a new value into the editable cell and then move on to another cell. The problem I am having is that for the last editable cell the user will immediately click a JButton to continue. This does not trigger the setValueAt function thus not saving the data. Is there a good way to ensure that this value is always stored when a user immediately hits a button after editing a cell? setValueAt function below for reference if needed.
public void setValueAt(Object value, int row, int col) {
if (value == null)
return;
if (col == 0) {
//this.indicatorArguments[row].setIsSelected(value);
} else if (col == 2) {
this.indicatorArguments[row].setValue(value);
}
this.fireTableCellUpdated(row, col);
}
Thanks for any help you can provide.
I assume that your button is outside the table.
In the event listener or action of your button you would need a reference to the table. This table you could then ask whether isEditing returns true. Then you would get the current editor and after validating the last input value either call stopCellEditing to commit the value or cancelCellEditing to undo the value.
In short:
if(table.isEditing()){
table.getCellEditor().stopCellEditing();
}
would always commit not yet entered values.
Checking if the table is editing requires you to add code to all buttons on your GUI.
You may be able to use a simple one line solution that avoids this. Check out Table Stop Editing.

Is it possible to edit data in jtable and save it?

I would like to know if it's possible to view my values through JTable and then edit them through there?
isCellEditable(int row, int col)
This method determines which rows and columns the user is allowed to modify. Since this method returns a Boolean, if all cells are editable it simply returns a true. To prevent a JTable from editing a particular column or row value, it returns a false from this method. The following code enables only column one to display while allowing the rest of the columns to be modified.
// Make column one noneditable
while allowing the user to edit at
all // other columns.
If (col == 1){
return false;
}
else{
return true;
}
public void setValueAt(Object value, int row, int col)
When the user makes changes to an editable cell, the Table Model is notified via this method. The new value, as well as the row and column it occurred in, is passed as arguments to this method. If the original data is coming from a database, this method becomes important. As you'll see, data retrieved from a database is held locally within the Table Model, usually as vectors. When the user changes a cell value in a JTable, the corresponding data in the Table Model isn't automatically changed. It's your responsibility to add code in this event to ensure that the data in the Table Model is the same as the data in the JTable. This becomes important when code is added to update the database. The following code updates the data (held in an array of objects) in the Table Model with the new value that the user just entered in the JTable.
// Update the array of objects with
// the changes the user has just entered in a cell.
// Then notify all listeners (if any) what column
// and row has changed. Further processing may take place there.
rowData[row][col] = value;
fireTableDataChanged();
Sure it's possible just have TableModel.isCellEditable() return true, and if necessary set a TableCellEditor.
Yes it is possible.Basically the jtable is editable.you can check through the TableModel.isCellEditable() method. After editing it you can store the table value in the two dimensional array and store in database.
int i;
int j;
String tableData = new String[row count][column count];
for(i = 0; i < row count; i++)
{
for(j = 0; j < 3; j++)
{
tableData[i][j] = table.getValueAt(i, j).toString();
}
}

Categories

Resources