Программисты JAVA общаются здесь
Anonymous
Редактор ячеек JTable перемещается из удаленной строки
Сообщение
Anonymous » 29 янв 2026, 14:01
В Swing возникает ошибка при удалении отредактированной строки из JTable.
Заполните таблицу.
Дважды щелкните первую строку (например, в столбце «Имя»).
Нажмите «Удалить строку».
Компонент редактора ячеек странным образом переместился на следующую строку.
/>
Смешно!
Разве таблица не должна автоматически обрабатывать подобные ситуации? Как лучше всего избежать этой ошибки?
MRE:
Код: Выделить всё
import common.data.Doctor;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.WindowConstants;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class SimpleTableDemo {
static JTable table;
static JButton fillButton;
static JButton removeRowButton;
public static void main(String[] args) {
Container mainPanel = createMainPanel();
JFrame frame = new JFrame("Table Demo");
frame.setContentPane(mainPanel);
frame.setLocationRelativeTo(null);
frame.pack();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
}
private static Container createMainPanel() {
JPanel mainPanel = new JPanel(new BorderLayout());
mainPanel.add(createScroller());
mainPanel.add(createButtonPanel(), BorderLayout.SOUTH);
return mainPanel;
}
private static Component createScroller() {
JScrollPane scroller = new JScrollPane();
scroller.setViewportView(createTable());
return scroller;
}
private static Component createTable() {
table = new JTable() {
@Override
public void addColumn(TableColumn aColumn) {
aColumn.setModelIndex(getColumnCount());
super.addColumn(aColumn);
}
};
table.setAutoCreateColumnsFromModel(false);
table.getSelectionModel().addListSelectionListener(e -> removeRowButton.setEnabled(table.getSelectedRows().length != 0));
List columns = Arrays.asList(TableColumns.code(), TableColumns.name());
columns.forEach(table::addColumn);
DefaultTableModel model = (DefaultTableModel) table.getModel();
model.setColumnCount(table.getColumnCount());
model.setColumnIdentifiers(columns.stream().map(TableColumn::getIdentifier).toArray());
return table;
}
private static Component createButtonPanel() {
JPanel panel = new JPanel();
panel.add(createFillButton());
panel.add(createRemoveRowButton());
return panel;
}
private static Component createFillButton() {
fillButton = new JButton("Fill");
fillButton.addActionListener(e -> fillTable());
return fillButton;
}
private static void fillTable() {
List doctors = createDoctors();
DefaultTableModel model = (DefaultTableModel) table.getModel();
model.setRowCount(0);
for (Doctor doctor : doctors) {
String code = doctor.getCode();
String name = doctor.getName();
model.addRow(new Object[]{code, name});
}
}
private static Component createRemoveRowButton() {
removeRowButton = new JButton("Remove row");
removeRowButton.setEnabled(false);
removeRowButton.addActionListener(e -> removeSelectedRow());
return removeRowButton;
}
private static void removeSelectedRow() {
DefaultTableModel model = (DefaultTableModel) table.getModel();
int selectedRow = table.getSelectedRow();
model.removeRow(selectedRow);
}
private static List createDoctors() {
List doctors = new ArrayList();
doctors.add(Doctor.of("1", "Maria"));
doctors.add(Doctor.of("2", "Patrick"));
return doctors;
}
}
Код: Выделить всё
public class Doctor {
private String code;
private String name;
private Doctor() {
}
public static Doctor of(String code, String name) {
Doctor doctor = new Doctor();
doctor.code = code;
doctor.name = name;
return doctor;
}
public String getName() {
return name;
}
public String getCode() {
return code;
}
}
Код: Выделить всё
import javax.swing.table.TableColumn;
// for simplicity, no custom TableColumn types are used here
public class TableColumns {
private TableColumns() {
}
public static TableColumn code() {
TableColumn column = new TableColumn();
column.setIdentifier("CODE");
column.setHeaderValue("Code");
return column;
}
public static TableColumn name() {
TableColumn column = new TableColumn();
column.setIdentifier("NAME");
column.setHeaderValue("Name");
return column;
}
}
Подробнее здесь:
https://stackoverflow.com/questions/798 ... eleted-row
1769684518
Anonymous
В Swing возникает ошибка при удалении отредактированной строки из JTable. [list] [*]Заполните таблицу. [*]Дважды щелкните первую строку (например, в столбце «Имя»). [*]Нажмите «Удалить строку». [*]Компонент редактора ячеек странным образом переместился на следующую строку. />[/list] Смешно! Разве таблица не должна автоматически обрабатывать подобные ситуации? Как лучше всего избежать этой ошибки? MRE: [code]import common.data.Doctor; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.WindowConstants; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableColumn; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Container; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class SimpleTableDemo { static JTable table; static JButton fillButton; static JButton removeRowButton; public static void main(String[] args) { Container mainPanel = createMainPanel(); JFrame frame = new JFrame("Table Demo"); frame.setContentPane(mainPanel); frame.setLocationRelativeTo(null); frame.pack(); frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); frame.setVisible(true); } private static Container createMainPanel() { JPanel mainPanel = new JPanel(new BorderLayout()); mainPanel.add(createScroller()); mainPanel.add(createButtonPanel(), BorderLayout.SOUTH); return mainPanel; } private static Component createScroller() { JScrollPane scroller = new JScrollPane(); scroller.setViewportView(createTable()); return scroller; } private static Component createTable() { table = new JTable() { @Override public void addColumn(TableColumn aColumn) { aColumn.setModelIndex(getColumnCount()); super.addColumn(aColumn); } }; table.setAutoCreateColumnsFromModel(false); table.getSelectionModel().addListSelectionListener(e -> removeRowButton.setEnabled(table.getSelectedRows().length != 0)); List columns = Arrays.asList(TableColumns.code(), TableColumns.name()); columns.forEach(table::addColumn); DefaultTableModel model = (DefaultTableModel) table.getModel(); model.setColumnCount(table.getColumnCount()); model.setColumnIdentifiers(columns.stream().map(TableColumn::getIdentifier).toArray()); return table; } private static Component createButtonPanel() { JPanel panel = new JPanel(); panel.add(createFillButton()); panel.add(createRemoveRowButton()); return panel; } private static Component createFillButton() { fillButton = new JButton("Fill"); fillButton.addActionListener(e -> fillTable()); return fillButton; } private static void fillTable() { List doctors = createDoctors(); DefaultTableModel model = (DefaultTableModel) table.getModel(); model.setRowCount(0); for (Doctor doctor : doctors) { String code = doctor.getCode(); String name = doctor.getName(); model.addRow(new Object[]{code, name}); } } private static Component createRemoveRowButton() { removeRowButton = new JButton("Remove row"); removeRowButton.setEnabled(false); removeRowButton.addActionListener(e -> removeSelectedRow()); return removeRowButton; } private static void removeSelectedRow() { DefaultTableModel model = (DefaultTableModel) table.getModel(); int selectedRow = table.getSelectedRow(); model.removeRow(selectedRow); } private static List createDoctors() { List doctors = new ArrayList(); doctors.add(Doctor.of("1", "Maria")); doctors.add(Doctor.of("2", "Patrick")); return doctors; } } [/code] [code]public class Doctor { private String code; private String name; private Doctor() { } public static Doctor of(String code, String name) { Doctor doctor = new Doctor(); doctor.code = code; doctor.name = name; return doctor; } public String getName() { return name; } public String getCode() { return code; } } [/code] [code]import javax.swing.table.TableColumn; // for simplicity, no custom TableColumn types are used here public class TableColumns { private TableColumns() { } public static TableColumn code() { TableColumn column = new TableColumn(); column.setIdentifier("CODE"); column.setHeaderValue("Code"); return column; } public static TableColumn name() { TableColumn column = new TableColumn(); column.setIdentifier("NAME"); column.setHeaderValue("Name"); return column; } } [/code] [img]https://i.sstatic.net/oNbgNRA4.png[/img] [img]https://i.sstatic.net/Oly7wVv1.png[/img] Подробнее здесь: [url]https://stackoverflow.com/questions/79878623/jtable-cell-editor-moves-from-deleted-row[/url]