问题
i searched in differet questions from others. But i didn't succeed. I want to make my table editable. But i dont know how, to call "setValueAt()".
I have the following files:
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);
}
}
and 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);
}
}
回答1:
You TableModel is too complex. All you need to do is store a List of Movies. Then you getValueAt() and setValueAt() method should access the List.
Your constructor should simply be:
public MovieTableModel(List movies)
{
datenMov = movies;
}
The getValueAt() should be something like:
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;
}
}
and the setValueAt() method something like:
@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;
...
}
}
Edit:
Also, in the setValueAt() method you need to invoke:
fireTableCellUpdated(row, column);
回答2:
I encountered similar situation, and I finally solved it.
I found that, when we double click on a cell, it go to:
JTable.getDefaultEditor(Class<?> columnClass)
function.
In my case, it go to the line :
return getDefaultEditor(columnClass.getSuperclass());
Since I returned int.class
when overriding the getColumnClass()
in my Table Model
, so it returned null
for the editor.
In short, the solution is,
Don't return any Primitive Data Types when overriding getColumnClass()
in your table model !
来源:https://stackoverflow.com/questions/19877649/java-swing-jtable-setvalueat-doesnt-work