我有一个JTable,我可以在其上显示一些信息和颜色背景。然而,每当数据发生变化时,我都会遇到问题,表格不会更新它的颜色。展望槽SO我发现了几个问题,他说这些例子应该工作:强制更新JTable不起作用
table.revalidate();
或
((CustomTableModel)table.getModel()).fireTableDataChanged();
或
table.repaint();
或
tableModel.fireTableCellUpdated(row, col);
我已经试过这些方法在桌子里面eModel,在JPanel类中持有表格本身,甚至在tablerenderer内部,但似乎没有任何工作(表格不会改变一点)
我检查了更新表格时收到的数据是否变化,但表格本身不更新。它只有当我重新启动应用程序。
我试图做一个Minimal, Complete, and Verifiable example只是通过复制的代码,但我可以使它以同样的方式,它已成为办法漫长而复杂的人了解工作之前...
为此我决定要上传整个project to github,但你可以找到这些类在这里的错误:
package Interface;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.text.ParseException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.StringTokenizer;
import javax.swing.AbstractAction;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import DataBase.Booking;
import DataBase.Room;
import Logics.Globals;
public class TablePanel extends JPanel{
private static TablePanel MainLogicInctance;
private JTable table;
private CustomTableModel model;
private JPopupMenu popup;
private JMenuItem view;
private JMenuItem confirm;
private JMenuItem unconfirm;
private JMenuItem edit;
private JMenuItem delete;
int x=0,y=0;
public TablePanel(){
model = new CustomTableModel(getObjectArray(), 0);
popup = new JPopupMenu();
view = new JMenuItem("view");
confirm = new JMenuItem("confirm");
unconfirm = new JMenuItem("unconfirm");
edit = new JMenuItem("edit");
delete = new JMenuItem("delete");
popup.add(view);
popup.add(confirm);
popup.add(unconfirm);
popup.add(new JPopupMenu.Separator());
popup.add(edit);
popup.add(delete);
this.setLayout(new BorderLayout());
this.setBackground(new Color(255,255,255));
table = new JTable(model);
MouseAdapter adapter = new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
if(e.getSource() != view && e.getSource() != confirm && e.getSource() != unconfirm && e.getSource() != edit && e.getSource() != delete){
x=table.rowAtPoint(e.getPoint());
y=table.columnAtPoint(e.getPoint());
System.out.println(Integer.toString(x)+"|"+Integer.toString(y));
}
if(e.getSource() == view){
Booking booking = Globals.getBookingByDateAndRoom(x, y);
System.out.println(Integer.toString(x)+"|"+Integer.toString(y));
System.out.println(booking.toString());
if(booking!=null){
JFrame frame = new PopupFrame("view",booking);
}
}
if(e.getSource() == confirm){
Booking booking = Globals.getBookingByDateAndRoom(x, y);
System.out.println(Integer.toString(x)+"|"+Integer.toString(y));
if(booking!=null){
Globals.updateBooking(booking.getName(), booking.getSurname(), booking.getPersons(), booking.getBegin(), booking.getEnd(), booking.getRoomID(), booking.getId(), true);
TablePanel.getInctance().updateAll();
}
}
if(e.getSource() == unconfirm){
Booking booking = Globals.getBookingByDateAndRoom(x, y);
if(booking!=null){
Globals.updateBooking(booking.getName(), booking.getSurname(), booking.getPersons(), booking.getBegin(), booking.getEnd(), booking.getRoomID(), booking.getId(), false);
TablePanel.getInctance().updateAll();
}
}
if(e.getSource() == edit){
Booking booking = Globals.getBookingByDateAndRoom(x, y);
if(booking!=null){
JFrame frame = new PopupFrame("edit booking",booking);
TablePanel.getInctance().updateAll();
}
}
if(e.getSource() == delete){
Booking booking = Globals.getBookingByDateAndRoom(x, y);
if(booking!=null){
JFrame frame = new PopupFrame("delete booking",booking);
TablePanel.getInctance().updateAll();
}
}
}
};
table.addMouseListener(adapter);
view.addMouseListener(adapter);
confirm.addMouseListener(adapter);
unconfirm.addMouseListener(adapter);
edit.addMouseListener(adapter);
delete.addMouseListener(adapter);
table.setComponentPopupMenu(popup);
table.setEnabled(false);
table.getColumnModel().setColumnSelectionAllowed(true);
table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
table.getTableHeader().setReorderingAllowed(false);
table.getTableHeader().setResizingAllowed(false);
table.getColumnModel().getColumn(0).setMinWidth(0);
table.getColumnModel().getColumn(0).setMaxWidth(0);
table.getColumnModel().getColumn(0).setWidth(0);
this.add(table.getTableHeader(), BorderLayout.NORTH);
this.setAllColoumnsRenderer();
this.add(table,BorderLayout.CENTER);
}
private void setAllColoumnsRenderer(){
for(int i=0; i<368;i++){
table.getColumnModel().getColumn(i).setCellRenderer(new CustomRenderer());
}
}
private Object[] getObjectArray() {
try {
BufferedReader reader = new BufferedReader(new FileReader("Recources/TableData/HeaderData.txt"));
String s;
s = reader.readLine();
StringTokenizer str = new StringTokenizer(s,",");
String tmp;
int i=0;
Object[] resault = new Object[368];
while(str.hasMoreTokens() && i<368){
tmp=str.nextToken();
if(!tmp.isEmpty()){
resault[i]=tmp;
}else{
resault[i]=" - ";
}
i++;
}
return resault;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private Object[] getRoomObjectArray(String room,int roomId) {
Object[] resault = new Object[549];
resault[0]=roomId;
resault[1]=room;
return resault;
}
public void addRoom(String roomname,int roomId){
this.remove(table);
((CustomTableModel) model).addRow(getRoomObjectArray(roomname,roomId));
table = new JTable(model);
((CustomTableModel) model).fireTableRowsInserted(0, ((CustomTableModel)model).getRowCount());
this.add(table);
this.revalidate();
this.repaint();
}
public static TablePanel getInctance() {
if (MainLogicInctance == null)
MainLogicInctance = new TablePanel();
return MainLogicInctance;
}
public JTable getTable(){
return table;
}
public void updateAll() {
System.out.println("forceUpdateRunning");
int rowCount = model.getRowCount();
for (int i = rowCount - 1; i >= 0; i--) {
((CustomTableModel) model).removeRow(i);
}
Room rooms[] = Globals.displayAllRooms();
for(Room room : rooms){
this.addRoom(room.getName(),room.getRoomId());
}
Booking bookings[] = Globals.displayAllBookings();
for(Booking booking : bookings){
this.addBooking(booking);
}
System.out.println("Time To Update!! :)");
table.revalidate();
((CustomTableModel)table.getModel()).fireTableDataChanged();
table.repaint();
}
public void addBooking(Booking booking){
int begin=0,end=0,current;
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");
LocalDate currentDate = LocalDate.parse(booking.getBegin(), formatter);
try {
begin = getDateNumber(booking.getBegin())+2;
end = getDateNumber(booking.getEnd())+2;
current = begin;
while(booking.getRoomID()>=model.getRowCount())
booking.setRoomID(booking.getRoomID()-1);
while(current<=end){
if(Globals.YEAR==currentDate.getYear()){
if(current == begin){
setCell(current,booking.getRoomID(),booking.getName());
}
if(current-1 == begin){
setCell(current,booking.getRoomID(),booking.getSurname());
}
}
currentDate.plusDays(1);
current++;
}
} catch (ParseException e) {
e.printStackTrace();
}
}
public int getDateNumber(String dateString) throws ParseException{
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");
LocalDate date = LocalDate.parse(dateString, formatter);
return date.getDayOfYear();
}
public int getYear(String dateString){
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");
LocalDate date = LocalDate.parse(dateString, formatter);
return date.getYear();
}
public void setCell(int x,int y,String name){
model.setValueAt(name, y, x);
}
}
CustomTableModel:
package Interface;
import java.text.ParseException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import javax.swing.table.DefaultTableModel;
import DataBase.Booking;
import Logics.Globals;
public class CustomTableModel extends DefaultTableModel{
private Booking[] bookings;
public CustomTableModel(Object[] data, int i){
super(data,i);
bookings = Globals.displayAllBookings();
}
public int getStatus(int row, int col) {
for(Booking booking : bookings){
System.out.println(booking.toString());
int begin=0,end=0,current;
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");
LocalDate currentDate = LocalDate.parse(booking.getBegin(), formatter);
try {
begin = getDateNumber(booking.getBegin())+2;
end = getDateNumber(booking.getEnd())+2;
current = begin;
while(booking.getRoomID()>=super.getRowCount())
booking.setRoomID(booking.getRoomID()-1);
while(current<=end){
if(Globals.YEAR==currentDate.getYear()){
if(current == col && booking.getRoomID() == row){
if(booking.isConfirmed())
return booking.getPersons();
return booking.getPersons()+10;
}
}
currentDate.plusDays(1);
current++;
}
} catch (ParseException e) {
e.printStackTrace();
}
}
return 0;
}
public int getDateNumber(String dateString) throws ParseException{
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");
LocalDate date = LocalDate.parse(dateString, formatter);
return date.getDayOfYear();
}
public boolean isCellEditable(int rowIndex, int columnIndex){
return false;
}
}
CustomRenderer:
package Interface;
import java.awt.Color;
import java.awt.Component;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
public class CustomRenderer extends DefaultTableCellRenderer {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
JLabel l = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
CustomTableModel tableModel = (CustomTableModel) table.getModel();
//====================Confirmed================
if (tableModel.getStatus(row,col) == 1) {
l.setBackground(new Color(255, 128, 128));
} else if (tableModel.getStatus(row,col) == 2) {
l.setBackground(new Color(255, 102, 102));
} else if (tableModel.getStatus(row,col) == 3) {
l.setBackground(new Color(255, 77, 77));
} else if (tableModel.getStatus(row,col) == 4) {
l.setBackground(new Color(255, 51, 51));
} else if (tableModel.getStatus(row,col) == 5) {
l.setBackground(new Color(255, 26, 26));
} else if (tableModel.getStatus(row,col) == 6) {
l.setBackground(new Color(255, 0, 0));
} else if (tableModel.getStatus(row,col) == 7) {
l.setBackground(new Color(230, 0, 0));
} else if (tableModel.getStatus(row,col) == 8) {
l.setBackground(new Color(204, 0, 0));
//===================Not Confirmed=============
} else if (tableModel.getStatus(row,col) == 11) {
l.setBackground(new Color(255, 204, 128));
} else if (tableModel.getStatus(row,col) == 12) {
l.setBackground(new Color(255, 194, 102));
} else if (tableModel.getStatus(row,col) == 13) {
l.setBackground(new Color(255, 184, 77));
} else if (tableModel.getStatus(row,col) == 14) {
l.setBackground(new Color(255, 173, 51));
} else if (tableModel.getStatus(row,col) == 15) {
l.setBackground(new Color(255, 163, 26));
} else if (tableModel.getStatus(row,col) == 16) {
l.setBackground(new Color(255, 153, 0));
} else if (tableModel.getStatus(row,col) == 17) {
l.setBackground(new Color(230, 138, 0));
} else if (tableModel.getStatus(row,col) == 18) {
l.setBackground(new Color(204, 122, 0));
//=====================empty===================
} else if(col>1){
l.setBackground(new Color(102, 255, 51));
}
return l;
}
}
由于这个版本我想从TablePanel类更新表的软件。但我已经在所有这三个类中尝试过了。
这是一个video它的行为。我希望我已经解释了这个问题,你知道解决方案吗?
你应该为每个GUI组件创建一个单独的MouseAdapter实例,而不是为所有人创建一个... –