2013-06-13 4 views
1

Я создаю JTable, когда кадр создан, но создайте пустой AbstractTableModel, который я продлил. Затем пользователь должен выбрать что-то из JComboBox, и пользователь может просмотреть сообщения, относящиеся к указанному выбору.Невозможно обновить мои JTable новыми данными

При нажатии кнопки предварительного просмотра я создаю новый AbstractTableModel с новыми данными и устанавливаю эту модель для вновь созданного объекта JTable. Как только это будет сделано, я звоню AbstractTableModel.fireTableDataChanged, JTable.repaint(), JTable.validate()JFrame.repaint(), JFrame.validate().

Со всеми этими вызовами я все еще не могу получить JTable для обновления с новыми данными.

Мои JFrame с JTable:

public class StudentMessageViewer extends JFrame implements ActionListener { 
    final String CMD_DELETE = "CMD_DELETE"; 
    final String CMD_DUMP = "CMD_DUMP"; 
    final String CMD_MOVE = "CMD_MOVE"; 
    final String CMD_PREVIEW = "CMD_PREVIEW"; 
    private Students students; 
    private JComboBox<String> Names; 
    private TableModel Model; 

    public Selector(Students students) { 
     super("Main"); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setSize(new Dimension(700, 800)); 
     setContentPane(getMainPanel()); 
     setLocationRelativeTo(null); 
     setVisible(true); 
    } 

    private JPanel getMainPanel() { 
     JPanel main = new JPanel(); 
     main.add(getSelectorPanel()); 
     main.add(getTablePanel()); 
     main.add(getButtonPanel()); 

     return main; 
    } 

    private JPanel getSelectorPanel() { 
     JPanel main = new JPanel(); 
     main.setLayout(new BoxLayout(main, BoxLayout.PAGE_AXIS)); 

     FlowLayout flowLayout = new FlowLayout(FlowLayout.RIGHT); 
     main.setMaximumSize(new Dimension(450, 180)); 
     Names = new JComboBox<String>(students.getNames()); 

     JPanel NamesPanel = new JPanel(); 
     NamesPanel.add(new JLabel("Name: ")); 
     NamesPanel.add(Names); 

     main.add(NamesPanel); 

     return main; 
    } 

    private JPanel getTablePanel() { 
     JPanel main = new JPanel();  

     this.Model = new Model(new Object[0][4]); 
     this.MessagesTable = new JTable(this.Model); 

     TableColumn column = this.MessagesTable.getColumnModel().getColumn(0); 
     column.setPreferredWidth(20); 
     this.MessagesTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 
     this.MessagesTable.setSelectionBackground(getBackground()); 
     this.MessagesTable.setSelectionForeground(getForeground()); 

     main.add(new JScrollPane(this.MessagesTable)); 

     return main; 
    } 

    private JPanel getButtonPanel() { 
     JPanel main = new JPanel(new FlowLayout(FlowLayout.RIGHT)); 

     JButton btnDelete = new JButton("Delete"); 
     JButton btnDump = new JButton("Dump"); 
     JButton btnMove = new JButton("Move"); 
     JButton btnPreview = new JButton("Preview"); 

     btnDelete.setActionCommand(CMD_DELETE); 
     btnDump.setActionCommand(CMD_DUMP); 
     btnMove.setActionCommand(CMD_MOVE); 
     btnPreview.setActionCommand(CMD_PREVIEW); 

     btnDelete.addActionListener(this); 
     btnDump.addActionListener(this); 
     btnMove.addActionListener(this); 
     btnPreview.addActionListener(this); 

     main.add(btnDelete); 
     main.add(btnDump); 
     main.add(btnMove); 
     main.add(btnPreview); 

     this.getRootPane().setDefaultButton(btnPreview); 

     return main; 
    } 

    private void setTableData() {   
     Object data[][] = students.Select(Names.getSelectedItem().toString()); 

     this.Model = new Model(data); 
     this.MessagesTable = new JTable(this.Model); 

     TableColumn column = this.MessagesTable.getColumnModel().getColumn(0); 
     column.setPreferredWidth(20); 
     this.MessagesTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 
     this.MessagesTable.setSelectionBackground(getBackground()); 
     this.MessagesTable.setSelectionForeground(getForeground()); 

     ((AbstractTableModel) this.MessagesTable.getModel()).fireTableDataChanged(); 
     this.MessagesTable.repaint(); 
     this.repaint(); 
     this.validate(); 
    } 

    @Override 
    public void actionPerformed(ActionEvent event) { 
     String actionCmd = event.getActionCommand(); 

     if(actionCmd.equals(CMD_DELETE)) 
      System.out.println("DELETE"); 
     else if(actionCmd.equals(CMD_DUMP)) 
      System.out.println("DUMP"); 
     else if(actionCmd.equals(CMD_MOVE)) 
      System.out.println("MOVE"); 
     else if(actionCmd.equals(CMD_PREVIEW)) 
      setTableData(); 
    } 
} 

Мой TableModel класс, который я протянул AbstractTableModel:

public class Model extends AbstractTableModel { 
    Object data[][]; 
    String columnNames[] = { "", "Message ID", "Group ID", "DateSent", "Message"}; 

    public Model(Object[][] data) { 
     this.data = new Object[data.length][columnNames.length]; 
     for (int i = 0; i < data.length; i++) { 
      this.data[i][0] = Boolean.TRUE; 
      for (int j = 0; j < columnNames.length - 1; j++) 
       this.data[i][j + 1] = data[i][j]; 
     } 
    } 

    public int getColumnCount() { 
     return (columnNames == null ? 0 : columnNames.length); 
    } 

    public String getColumnName(int column) { 
     return (columnNames == null ? "" : columnNames[column]); 
    } 

    public int getRowCount() { 
     return (data == null ? 0 : data.length); 
    } 

    public Object getValueAt(int row, int column) { 
     return (columnNames == null ? new Object() : data[row][column]); 
    } 

    @SuppressWarnings({ "unchecked", "rawtypes" }) 
    public Class getColumnClass(int column) { 
     return (getValueAt(0, column).getClass()); 
    } 

    public void setValueAt(Object value, int row, int column) { 
     data[row][column] = value; 
    } 

    public boolean isCellEditable(int row, int column) { 
     return (column == 0); 
    } 
} 

ответ

0

Так что я понял это. В методе setTableData() класса StudentMessageViewer я создавал новый объект TableModel и новый объект JTable, но присваивал эти два новых объекта исходной переменной. Поэтому мне, возможно, пришлось бы сделать repaint() или validate(), но я не мог понять это.

Но, чтобы исправить это, я создал совершенно новый объект TableModel и использовал JTable.setModel() для замены старого TableModel.

Вот модифицированный метод:

private void setTableData() {   
    Object data[][] = students.Select(Names.getSelectedItem().toString()); 

    this.Model = new Model(data); 

    TableColumn column = this.MessagesTable.getColumnModel().getColumn(0); 
    column.setPreferredWidth(20); 
    this.MessagesTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 
    this.MessagesTable.setSelectionBackground(getBackground()); 
    this.MessagesTable.setSelectionForeground(getForeground()); 

    this.MessagesTable.setModel(this.MyModel); 
} 

Теперь я могу обновлять таблицу, как много раз я хочу.

0

AbstractTableModel поддерживает слушателей, что таблица регистрируется на нем, чтобы реагировать на изменения содержимого. Однако AbstractTableModel не знает, когда базовые данные фактически становятся разными - это уже полностью в вашем коде.

Попробуйте позвонить по телефону fireTableDataChanged с модели или (в худшем стиле) на модель, когда вы знаете, что данные теперь разные или что-то более неохотное, чем fireTableRowsUpdated для известного изменения ограниченной области.