JTable setvalueat stackoverflow [duplicate] - java

This question already has an answer here:
JTable Java Error Stack OverFlow when setvalue to a specific column
(1 answer)
Closed 6 years ago.
I am getting stackoverflow error when I try to change one of columns data when 2 columns of the columns has been edited.
I have 3 columns which are items, quantity, price.
I want to calculate the price when items and quantity has an input. Below is my code:-
itemsTable.getModel().addTableModelListener(new TableModelListener() {
#Override
public void tableChanged(TableModelEvent e) {
for (int i = 0; i < itemsTable.getRowCount(); i++) {
if (itemsTable.getValueAt(i, 0) != null) {
String item = itemsTable.getValueAt(i, 0).toString();
double price = Double.parseDouble(selectedItem.substring(item.indexOf("RM") + 2, item.length())); //get price from the cell
double qty = Double.parseDouble(itemsTable.getValueAt(i, 1).toString()); //get quantity from cell
itemsTable.setValueAt(price * qty, i, 2); //calculate price * qty and set price
}
}
}
});
I set a combobox that loaded with database data to items column and a JSpinner for quantity
What am I doing wrong? I am new to JTable.
EDIT
Answer:(credits to Titus)
#Override
public void tableChanged(TableModelEvent e) {
if (e.getType() == TableModelEvent.UPDATE && e.getColumn() != 2) {
for (int i = 0; i < itemsTable.getRowCount(); i++) {
if (itemsTable.getValueAt(i, 0) != null) {
...
}
}
}
}

Also wouldn't hurt to limit the loop to going from row e.getFirstRow() thru e.getLastRow(), and maybe updating price in an invokeLater process as well. But titus hit it head on: gotta stop the infinite cascade of change invokes handler which makes change that invokes handler which makes change...

Related

How to delete the reflected row of the second JTable if the user selects another row in the first JTable?

I am having trouble deleting the previous row of my second table of my Products Stock In GUI in Java.
The flow of the functionality of my GUI is this:
If the user will select a row in the first table of the GUI, the values of those rows will be reflected on the second rows
If the user will select another/different row in the first table, the previous reflected row which was selected in the first table must be deleted and is replaced by the current selected row.
To sum it up, I have to replace/delete the previous reflected rows if I will select a different row in the first table then replace that previous selected row into the current selected row.
Here's my source code:
private void firstTableMouseClicked(java.awt.event.MouseEvent evt) {
DefaultTableModel secondTblmodel = (DefaultTableModel) secondTable.getModel();
int selectPRoww = firstTable.getSelectedRow();
for (int x = 0; x < ProductAllData2[selectPRoww].length; x++) {
//ProductAllData2 is a 3D array
if (ProductAllData2[selectPRoww][x][0] != null) {
if (setRowCountID2 == 0)
secondTblmodel.setRowCount(0);
//Reflects and displays the values of the selected
// row from the first table to the second table
secondTblmodel.addRow(ProductAllData2[selectPRoww][x]);
// deletes previous row if index of selected row is
// greater than the previous selected row (doesn't work)
if (selectPRoww > selectPRoww) {
secondTblmodel.removeRow(selectPRoww - 1);
}
// deletes previous row if index of selected row is
// less than the previous selected row (doesn't work)
if (selectPRoww < selectPRoww) {
secondTblmodel.removeRow(selectPRoww + 1);
}
setRowCountID2++;
}
}
}
Am I missing something in my functionality or do I need to modify the for loops?
In my opinion, your logic should not be like this.
As the second table (View) depends on the selection of the first table, then the second table should always be cleared, then you do this logic.
//Reflects and displays the values of the selected
// row from the first table to the second table
secondTblmodel.addRow(data);
Important Point: Please use ListSelectionListener on table1, rather than depending on mouse clicks.
Example of usage:
table1.getSelectionModel().addListSelectionListener(new SharedListSelectionHandler());
class SharedListSelectionHandler implements ListSelectionListener {
public void valueChanged(ListSelectionEvent e) {
ListSelectionModel lsm = (ListSelectionModel) e.getSource();
int firstIndex = e.getFirstIndex();
int lastIndex = e.getLastIndex();
boolean isAdjusting = e.getValueIsAdjusting();
output.append("Event for indexes "
+ firstIndex + " - " + lastIndex
+ "; isAdjusting is " + isAdjusting
+ "; selected indexes:");
if (lsm.isSelectionEmpty()) {
output.append(" <none>");
} else {
// Find out which indexes are selected.
int minIndex = lsm.getMinSelectionIndex();
int maxIndex = lsm.getMaxSelectionIndex();
for (int i = minIndex; i <= maxIndex; i++) {
if (lsm.isSelectedIndex(i)) {
output.append(" " + i);
}
}
}
output.append(newline);
}
}
How to Write a List Selection Listener | The Java™ Tutorials
Similar StackOverflow: Deleting row from JTable after valueChanged event is triggered

Final row in a Jtable can not be removed

I have the following code, that allows me to remove a row from the right Jtable with a click. It works fine for all the rows, except when there is only one row remaining. BTW, sorry for most names being in portuguese, its my native language. Here are the images showing before and after i click the final row in the table. It updates the total, but the row remains. For every other case, it works perfectly.
Screenshot:
private void jtbSelecionadosMouseClicked(java.awt.event.MouseEvent evt)
{
int x = jtbSelecionados.rowAtPoint(evt.getPoint());
if (x >= 0)
{
String nomeProduto = (String)jtbSelecionados.getModel().getValueAt(x, 0);
for (int i = 0; i < itensVenda.size();i++)
{
if (itensVenda.get(i).getNomeProduto().equals(nomeProduto))
{
if(itensVenda.get(i).getQtd() > 1)
{
valorTotal -= (itensVenda.get(i).getPreco() / itensVenda.get(i).getQtd());
double precototal = itensVenda.get(i).getPreco();
double unit = precototal / itensVenda.get(i).getQtd();
System.out.println("Unidade: "+unit+"\nTotal: "+precototal);
itensVenda.get(i).setPreco(itensVenda.get(i).getPreco() - (itensVenda.get(i).getPreco() / itensVenda.get(i).getQtd()));
itensVenda.get(i).setQtd(itensVenda.get(i).getQtd() - 1);
recarregarTabela();
}
else if(itensVenda.get(i).getQtd() <= 1)
{
valorTotal -= itensVenda.get(i).getPreco() / itensVenda.get(i).getQtd();
itensVenda.remove(i);
recarregarTabela();
}
}
}
}
function that resets the table with new information:
private void recarregarTabela()
{
if (itensVenda.size() == 0)
{
dtm.getDataVector().removeAllElements();
dtm.setRowCount(0);
lblTotal.setText("Total: R$" + String.valueOf(valorTotal));
}
else
{
dtm.getDataVector().removeAllElements();
dtm.setRowCount(0);
for (Item item : itensVenda)
{
Object[] vetor = new Object[3];
vetor[0] = item.getNomeProduto();
vetor[1] = item.getQtd();
vetor[2] = String.format("%.2f", item.getPreco());
System.out.println(item.getPreco());
dtm.addRow(vetor);
}
lblTotal.setText("Total: R$" + String.valueOf(valorTotal));
}
}
You dont have to rebuild whole model everytime a single row is deleted. As you already have index of clicked or selected row you can just remove it from model using removeRow(index) method. I suspect that dtm is a DefaultTableModel so just call dtm.removeRow(index) everytime you need to remove row from table

Java: Waiting for a mouseClickedEvent

I am writing a program where users answer questions by clicking on JTable cells. If the question is answered correctly/incorrectly, the MouseListener changes the value of answeredResult. The program will keep running until there are no available questions (the available array list contains a list of Items, which is a class I created that contains strings event, year, and description, called by getEvent(), getYear(), and getDescription() methods respectively). However, for each question, I want to wait until a mouseClickedEvent is detected before executing the proceeding code (see below).
I know that adding another while loop for waiting is really bad. I've also seen
some answers suggesting to put whatever I want to do in the mouseClicked method, but I don't know how in my case, since I want to repeat it multiple times.
I think another problem is that the program is stuck in the while(available.size()!=0) loop. So it cant detect the mouse click.
Any suggestions on how to make this work?
ArrayList<Item> available = new ArrayList<Item>();
for(int i = 0; i < 5; i++){
available.add(new Item("Event " + i, "Year " + i, "Description " + i));
}
JTable table = new JTable(model);
table.addMouseListener(new java.awt.event.MouseAdapter() {
#Override
public void mouseClicked(java.awt.event.MouseEvent evt) {
int row = table.rowAtPoint(evt.getPoint());
int col = table.columnAtPoint(evt.getPoint());
if (row >= 0 && col == 2 && canPlay) {
clickedYear = (String)data[row][col];
if(clickedYear.equals(answerYear)){
answeredResult = 1;
}else{
answeredResult = -1;
}
}
}
});
while(available.size()!=0){
promptPanel.removeAll();
answeredResult = 0; //0-unanswered 1-correct 2-incorrect
int random = (int)(Math.random()*(available.size()-1));
JLabel label = new JLabel(available.get(random).getEvent()+"\n");
promptPanel.add(label);
canPlay = true;
//wait for mouse clicked before proceeding to the next code
if(answeredResult == 1){
JLabel correct = new JLabel("Correct!");
promptPanel.add(correct);
}else if(answeredResult == -1){
JLabel wrong = new JLabel("Wrong.");
promptPanel.add(wrong);
}
revalidate();
repaint();
available.remove(random);
}

JTable duplicate entry

How can I prevent duplication of data in JTable?
The for loop determines whether the data contains similar ID.
Yes, it determines and show a JOptionPane which works.
But my problem is that it scans for a duplicate after I setValue on table 2.
I want my program to prevent duplication of data before it setValue on table 2.
public void dProductList(){
table.addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent e) {
if(e.getClickCount() == 1) {
JTable tbl = (JTable)e.getSource();
int rrow = tbl.getSelectedRow();
if(rrow>=0) {
int dcol = 0;
int rcol = 0;
((DefaultTableModel)table2.getModel()).addRow(new Object[] {0,0,0,0});
while(rcol<table2.getColumnCount()-1) {
table2.setValueAt(table.getValueAt(rrow,rcol),drow,dcol);
totalAmount = totalAmount + (int) table2.getValueAt(drow,3);
rcol++;
dcol++;
if(rcol==table2.getColumnCount()-1) {
drow++;
}
label.setText(String.valueOf(totalAmount));
}
for(int i=0; i<table2.getRowCount()-1;i++){
if(table2.getValueAt(i,0).equals(table2.getValueAt(table2.getRowCount()-1,0))){
JOptionPane.showMessageDialog(null,"item already listed");
}
}
}
}
}
});
}
Use for loop checking just before table2.setValueAt and add only if no duplicate.
You could also keep your data to a Set (eg a HashSet) and check there before adding to your JTable.

getting last column last cell value

i create JTable in that table value are retrieve from data base
(Except fifth column) in fifth column .i enter value through keyboard
in fifth column but when getting value again from jtable at that time
i am not getting last entered value in fifth column please suggest
something
my method code bellow
public class TableDataDelete implements ActionListener
{
public void actionPerformed(ActionEvent ee) {
int b = table.getRowCount();
System.out.println("row count" + b);
for (int i = 0; i <b; i++) {
try
{
String str = (String) table.getModel().getValueAt(i, 3);
String str1 = (String) table.getModel().getValueAt(i, 5);
if (!(str1 == null)) {
((DefaultTableModel)table.getModel()).removeRow(i);
table.repaint();
System.out.println("remove row no is"+i);
}
}
catch(ArrayIndexOutOfBoundsException e)
{
System.out.println("array index out of bound exception"+e);
}
}
}
}
working code when i enter value of five cells it can get only first four cell from the column cant getting last entered cell value
You should use this code to stop cell editing to get last value
if(table.getCellEditor() != null){
table.getCellEditor().stopCellEditing();
}

Categories

Resources