У меня есть JTable, кнопка редактирования и кнопка сохранения. когда я нажимаю кнопку редактирования, я хочу вставить два JTextFields в конкретную выбранную ячейку. Так что я могу писать (строки) в эти текстовые поля. когда я нажимаю кнопку «Сохранить», я хочу удалить эти два текстовых поля из ячейки и вставить эти строки (в ту же ячейку таблицы).

-2
devilmk 14 Ноя 2019 в 23:03
Что не так с функциональностью JTable по умолчанию. Он уже поддерживает это требование. Вы можете перейти к ячейке и начать печатать, и данные в ячейке будут обновлены. Или вы можете дважды щелкнуть ячейку, чтобы начать редактирование. Все, что вам нужно сделать, это переопределить метод iseCellEditable(...) JTable. Прочитайте учебник. Вам дали ссылку в последнем вопросе. Ваше текущее требование не имеет смысла. Зачем заставлять пользователя делать дополнительный шаг по нажатию кнопки «Изменить»? Что произойдет, если вы переведете их в режим «Редактировать», а они захотят «Отменить»?
 – 
camickr
15 Ноя 2019 в 07:49
Что произойдет, если пользователи перейдут к другому компоненту, не нажимая «Сохранить». Требование не очень понятное. Возможно, вам следует отображать модальный JDialog, когда пользователь нажимает «Изменить». Затем, когда диалоговое окно будет закрыто, вы можете обновить TableModel.
 – 
camickr
15 Ноя 2019 в 07:51
Я думаю так же, но требование только такое. В таблице сохраните имя человека, разделенное запятыми, и название города (в одном столбце). И в каждой строке есть кнопка редактирования и удаления (со значком). когда пользователь нажимает кнопку «Изменить», он должен иметь возможность редактировать имя человека и название города в двух текстовых полях (в одной ячейке). и кнопка сохранения сохранит их снова в строках, разделенных запятыми.
 – 
devilmk
15 Ноя 2019 в 08:10
Возможно, редактор списков подскажет вам некоторые идеи. Он добавляет один JTextField в строку списка, когда вы хотите отредактировать элемент. В вашем случае вы должны добавить панель, содержащую два поля JTextField, в ячейку JTable.
 – 
camickr
15 Ноя 2019 в 18:41
Спасибо, я попробовал это решение, но Jlist не редактируется. Я смог добавить кнопки и строку, но кнопка не нажималась. Теперь для каждой строки я использую панель и добавляю их в большую панель.
 – 
devilmk
16 Ноя 2019 в 22:35

1 ответ

Вам не нужно добавлять JTextField в JTable, чтобы ячейку можно было редактировать. Функцию isCellEditable(int row, int column) можно переопределить, чтобы она возвращала логическое значение, зависящее от кнопки редактирования. Вот пример:

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.EventQueue;
import java.awt.event.*;
import java.awt.Dimension;

public class EditTableExample extends JFrame {
    private boolean editable = false;
    public EditTableExample() {
        //set up jframe
        setPreferredSize(new Dimension(500, 500));
        setMinimumSize(new Dimension(500, 500));
        setResizable(false);
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        //set up content pane
        JPanel contentPane = new JPanel();
        setContentPane(contentPane);
        //table model
        Object[][] tableContents = new Object[][]{ //contents of our table
                {"Person1", "City1"},
                {"Person2", "City2"},
                {"Person3", "City3"}
        };
        Object[] tableHeader = new Object[]{
                "Name", "City"
        };
        DefaultTableModel model = new DefaultTableModel(tableContents, tableHeader) {
            @Override
            public boolean isCellEditable(int row, int column) {
                return editable;
            }
        };
        //table
        JTable table = new JTable(model);
        //scrollpane to house table
        JScrollPane tablePane = new JScrollPane(table);
        tablePane.setPreferredSize(new Dimension(450, 450));
        //button that will add a row
        JButton add = new JButton("Add Row");
        add.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ev) {
                model.addRow(new Object[model.getColumnCount()]); //adds a new, empty row to the table
            }
        });
        //button that will toggle edit mode
        JButton edit = new JButton("Toggle Edit");
        edit.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ev) {
                editable = !editable; //switches the value of 'editable' on click
            }
        });
        //button to remove a row
        JButton remove = new JButton("Remove Row");
        remove.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ev) {
                try {
                    model.removeRow(table.getSelectedRow()); //remove selected row
                }
                catch (ArrayIndexOutOfBoundsException e) {
                    JOptionPane.showMessageDialog(rootPane, "No Row Selected");
                }
            }
        });
        //add everything together
        contentPane.add(tablePane);
        contentPane.add(add);
        contentPane.add(edit);
        contentPane.add(remove);
    }
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                EditTableExample e = new EditTableExample();
                e.setVisible(true);
            }
        });
    }
}

Как видите, функция isCellEditable вернет значение «editable», логическое значение, значение которого переключается кнопкой «редактировать». Вместо того, чтобы иметь одну ячейку для каждого человека, содержащую «Имя, город», есть два столбца: один для имени человека и один для его города. Дайте мне знать, если у вас есть еще вопросы.

1
danelliott 15 Ноя 2019 в 19:56
Спасибо за код. Я пробовал так, как вы объяснили. И я должен сделать эту часть. Но в моем случае я использую панели для строк внутри панели.
 – 
devilmk
16 Ноя 2019 в 22:38