Java, изменить содержимое ячейки как функцию другой ячейки в той же строке
Мне нужна помощь для решения моей проблемы. У меня есть таблица, например, с двойным столбцом и столбцом строки. Если значение в двойном столбце отрицательное, строка должна быть отрицательной. И наоборот, если значение положительно, строка должна быть "положительно". Проблема в том, что теперь, если я редактирую значение double в jTable, строка также должна быть обновлена.
Обновите мой вопрос, фактический код выглядит следующим образом: Но он не работает, потому что строка во втором столбце не будет обновлена после того, как я отредактирую значение первого столбца. Работает только при первом запуске программы.
import java.util.Vector;
import javax.swing.*;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.*;
public class ExampleRemoveAddRows extends JFrame {
private Object[] columnNames = {"Double", "positiv / negativ"};
private Object[][] data = {
{new Double(10.0), "positiv"},
{new Double(-10.0), "negativ"},
{new Double(20.0), "positiv"},
{new Double(-30.0), "negativ"}
};
private JTable table;
private DefaultTableModel model;
public ExampleRemoveAddRows() {
model = new DefaultTableModel(data, columnNames) {
@Override
public Class getColumnClass(int column) {
return getValueAt(0, column).getClass();
}
@Override
public Object getValueAt(int row, int column) {
if (column == 1) {
double number = Double.parseDouble(this.getValueAt(row, 0).toString());
System.out.println(number);
System.out.println("good");
System.out.println((number < 0) ? "negativ" : "positiv");
return "C: "+ this.getValueAt(row, 0);//((number < 0) ? "negativ" : "positiv");
} else {
return super.getValueAt(row, column);
}
}
};
table = new JTable(model);
table.setPreferredScrollableViewportSize(table.getPreferredSize());
JScrollPane scrollPane = new JScrollPane(table);
add(scrollPane);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
ExampleRemoveAddRows frame = new ExampleRemoveAddRows();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
Спасибо за вашу помощь.
Сэм
2 ответа
Я пересмотрел вашу систему, чтобы показать альтернативный подход, предложенный здесь. Обратите внимание на альтернативные способы получить Double
постоянная. Я также пересмотрел String
constrants.
Приложение: В полезных комментариях @kleopatra отмечает, что прямой запрос модели всегда даст правильный результат, но TableModelListener
изменения будут видны только в столбце 0, а не в столбце 1. Простой способ - сделать столбец 1 недоступным для редактирования, поскольку его значение полностью зависит от столбца 0.
@Override
public boolean isCellEditable(int row, int col) {
return col == 0;
}
Первый пример ниже использует DefaultTableModel
:
import javax.swing.*;
import javax.swing.table.*;
/** @see https://stackru.com/a/13628183/230513 */
public class ExampleRemoveAddRows extends JFrame {
public static final String NEGATIVE = "negativ";
public static final String POSITIVE = "positiv";
private Object[] columnNames = {"Double", POSITIVE + " / " + NEGATIVE};
private Object[][] data = {
{10d, null},
{-10.0, null},
{Double.valueOf(30), null},
{Double.valueOf("-30"), null}
};
private JTable table;
private DefaultTableModel model;
public ExampleRemoveAddRows() {
model = new DefaultTableModel(data, columnNames) {
@Override
public Class getColumnClass(int column) {
return getValueAt(0, column).getClass();
}
@Override
public boolean isCellEditable(int row, int col) {
return col == 0;
}
@Override
public Object getValueAt(int row, int col) {
if (col == 1) {
double number = (Double) this.getValueAt(row, 0);
return (number < 0) ? NEGATIVE : POSITIVE;
} else {
return super.getValueAt(row, col);
}
}
@Override
public void setValueAt(Object aValue, int row, int col) {
super.setValueAt(aValue, row, col);
fireTableCellUpdated(row, 1); // may have changed
}
};
table = new JTable(model);
table.setPreferredScrollableViewportSize(table.getPreferredSize());
JScrollPane scrollPane = new JScrollPane(table);
add(scrollPane);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
ExampleRemoveAddRows frame = new ExampleRemoveAddRows();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
Это изменение extends AbstractTableModel
:
import java.awt.EventQueue;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
import javax.swing.table.*;
/**
* @see https://stackru.com/a/13628183/230513
*/
public class ExampleRemoveAddRows extends JFrame {
public static final String NEGATIVE = "negativ";
public static final String POSITIVE = "positiv";
public ExampleRemoveAddRows() {
DoubleModel model = new DoubleModel();
model.add(10.1);
model.add(-10.2);
model.add(Double.valueOf(30.1));
model.add(Double.valueOf("-30.2"));
JTable table = new JTable(model);
table.setPreferredScrollableViewportSize(table.getPreferredSize());
JScrollPane scrollPane = new JScrollPane(table);
add(scrollPane);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
ExampleRemoveAddRows frame = new ExampleRemoveAddRows();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
private class DoubleModel extends AbstractTableModel {
List<Double> data = new ArrayList<Double>();
public void add(Double d) {
data.add(d);
}
@Override
public int getRowCount() {
return data.size();
}
@Override
public int getColumnCount() {
return 2;
}
@Override
public String getColumnName(int col) {
if (col == 0) {
return "Double";
} else {
return POSITIVE + " / " + NEGATIVE;
}
}
@Override
public Class<?> getColumnClass(int col) {
if (col == 0) {
return Double.class;
} else {
return String.class;
}
}
@Override
public boolean isCellEditable(int row, int col) {
return col == 0;
}
@Override
public Object getValueAt(int row, int col) {
if (col == 0) {
return data.get(row);
} else {
double number = (Double) this.getValueAt(row, 0);
return (number < 0) ? NEGATIVE : POSITIVE;
}
}
@Override
public void setValueAt(Object aValue, int row, int col) {
if (col == 0) {
data.set(row, (Double) aValue);
fireTableRowsUpdated(row, row);
}
}
}
}
У вас действительно есть доступ к TableModel, если я не ошибаюсь, через TableModelEvent.getSource()
,
Просто для того, чтобы привести базовый пример (в основном потому, что ответ с одним отправлением вряд ли выглядит как большая часть ответа)
TableModel model = (TableModel)te.getSource();
Double number = model.getValueAt(te.firstRow, 0);
model.setValueAt(((number < 0) ? "negativ":"positiv"), te.firstRow, 1);