Java swing jtable setvalueAt не работает

Вопрос:

Я искал в разных вопросах от других. Но мне это не удалось. Я хочу сделать таблицу доступной для редактирования. Но я не знаю, как назвать “setValueAt()”.

У меня есть следующие файлы:

MovieManager.java

import java.util.*;

public class MovieManager
{
private static List<Movie> movieList = new ArrayList<Movie>();

public static void main(String args[])
{
final Director david = new Director("David", "Finch", Gender.MALE);
final Movie film1 = new Movie("Fightclub", 140, "Amerika", "Best Movie ever!", david);
final Movie film2 = new Movie("Panic Room", 115, "Amerika", "Good Movie", david);
final Movie film3 = new Movie("Seven", 120, "Amerika", "Headless", david);

movieList.add(film1);
movieList.add(film2);
movieList.add(film3);

// start GUI
new MovieUI();
}

public static List<Movie> getMovieList()
{
return movieList;
}

public static void setMovieList(List<Movie> movieList)
{
MovieManager.movieList = movieList;
}
}

MovieUI.java

import javax.swing.JFrame;
import javax.swing.JPanel;

public class MovieUI extends JPanel
{
/**
*
*/
private static final long serialVersionUID = 1L;

public MovieUI()
{
//Create and set up the window.
final JFrame frame = new JFrame("Movie Manager");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

//Create and set up the content pane.
final Table newContentPane = new Table();
//newContentPane.setOpaque(true); //content panes must be opaque
frame.setContentPane(newContentPane);

//Display the window.
frame.pack();
frame.setVisible(true);
}
}

Table.java

import javax.swing.JPanel;
import javax.swing.JTable;
import java.awt.BorderLayout;
import java.awt.GridLayout;

import javax.swing.table.JTableHeader;
import javax.swing.table.TableRowSorter;

public class Table extends JPanel
{
/**
*
*/
private static final long serialVersionUID = 1L;

public Table()
{
super(new GridLayout(1,0));
final MovieTableModel model = new MovieTableModel();
final JTable table = new JTable(model);

final TableRowSorter<MovieTableModel> sorter = new TableRowSorter<MovieTableModel>();
table.setRowSorter(sorter);
sorter.setModel(model);

final JTableHeader header = table.getTableHeader();
setLayout(new BorderLayout());
add(header, BorderLayout.PAGE_START);
add(table, BorderLayout.CENTER);
}
}

и MovieTableModel.java

import java.util.ArrayList;
import java.util.List;

import javax.swing.table.AbstractTableModel;

class MovieTableModel extends AbstractTableModel
{
/**
*
*/
private static final long serialVersionUID = 1L;
private final List<String[]> daten = new ArrayList<String[]>();
private final List<Movie> datenMov = new ArrayList<Movie>();
private final String[] columnNames = {"Id", "Name", "Time", "Language", "Description", "Place"};

public MovieTableModel()
{
for (Movie movie: MovieManager.getMovieList())
{
String[] list = {String.valueOf(movie.getNumber()), movie.getTitle(), String.valueOf(movie.getTime()), "DE", movie.getDescription(), movie.getPlace()};
datenMov.add(movie);
daten.add(list);
}
}

public int getColumnCount()
{
return columnNames.length;
}

public int getRowCount()
{
return daten.size();
}

public String getColumnName(int col)
{
return columnNames[col];
}

public Object getValueAt(int row, int col)
{
return daten.get(row)[col];
}

public boolean isCellEditable(int row, int col)
{
if (col < 1)
{
return false;
}
else
{
return true;
}
}

public void setValueAt(String value, int row, int col)
{
System.out.println("Ich werde aufgerufen");
String[] list = daten.get(row);
list[col] = value;
daten.set(row, list);
System.out.println(daten.get(row)[col]);

List<Movie> movieliste = MovieManager.getMovieList();

Movie mov = (Movie) movieliste.get(row);
switch( col )
{
case 1:
mov.setTitle(value);
break;
case 2:
int foo = Integer.parseInt(value);
mov.setTime(foo);
break;
case 4:
mov.setDescription(value);
break;
case 5:
mov.setPlace(value);
break;
}

movieliste.set(row, mov);
MovieManager.setMovieList(movieliste);
}

}

Лучший ответ:

Вы TableModel слишком сложны. Все, что вам нужно сделать, это сохранить список фильмов. Затем метод getValueAt() и setValueAt() должен получить доступ к списку.

Ваш конструктор должен быть просто:

public MovieTableModel(List movies)
{
    datenMov = movies;
}

GetValueAt() должен выглядеть примерно так:

public Object getValueAt(int row, int column)
{
    Movie movie = datenMov.get(row);

    switch(column)
    {
        case 0: return movie.getNumber();
        case 1: return movie.getTitle();
        ...
        default: return null;
    }
}

и метод setValueAt():

@Override
public void setValueAt(Object value, int row, int column)
{
    Movie movie = get(row);

    switch (column)
    {
        case 0: movie.setNumber((String)value); break;
        case 1: movie.setTitle((String)value); break;
        ...
    }
}

Редактировать:

Кроме того, в методе setValueAt() вам нужно вызвать:

fireTableCellUpdated(row, column);

Ответ №1

Я столкнулся с подобной ситуацией, и наконец решил.

Я обнаружил, что, когда мы дважды щелкаем по ячейке, переходим к:

JTable.getDefaultEditor(Class<?> columnClass).

В моем случае он переходит к строке:

return getDefaultEditor(columnClass.getSuperclass());

Так как я вернул int.class переопределив getColumnClass() в моей Model таблицы, поэтому он вернул значение null для редактора.

Короче говоря, это решение,
Не возвращайте примитивные типы данных при переопределении getColumnClass() в вашей модели таблицы !

Оцените статью
TechArks.Ru
Добавить комментарий