本文介绍了摆动:更改JTable结构后,JScrollPane不刷新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在JPanel中有一个与DefaultTableModel关联的JTable,该JPanel中的SpringLayout位于JScrollPane中.

I have a JTable, associated with a DefaultTableModel, in a JPanel with a SpringLayout which is in a JScrollPane.

当我使用下面的JTable方法而不是JScrollPane修改DefaultTableModel的结构时.我必须再次应用此方法来刷新JScrollPane.

When I modify the structure of the DefaultTableModel with the method below the JTable is refreshed but not the JScrollPane. I have to apply a second time this method to refresh the JScrollPane.

public void updateProjectView() {
    SwingProjectViewerController spvc = SwingProjectViewerController.
            getInstance();
    this.projectTitle.setText(spvc.getAcronym() + " : " + spvc.getTitle());
    Object[][] tableContent =
            spvc.getCriteria(CriteriaPreselectionController.getInstance().
            getCriteriaPreselection());
    Object[] columnsName = new Object[]{"Col1", "Col2"};
    this.tableModel.setDataVector(tableContent, columnsName);
    this.tableModel.fireTableStructureChanged();
}

任何帮助,不胜感激!

推荐答案

下面是一个测试程序,该程序显示当JScrollPane持有JTable并且通过setDataVector(...)更改DefaultTableModel的DataVector时,无需调用fireTableDataChanged()在模型上可以正确更改JTable的数据并对其进行正确查看.

Here is a test program that shows that when a JTable is held by a JScrollPane and the DefaultTableModel's DataVector is changed via setDataVector(...) it is not necessary to call fireTableDataChanged() on the model for the JTable's data to change correctly and be viewed correctly.

程序GUI如下图所示.
数据更改之前:

The program GUI looks like the images below.
Before Data Changed:

数据更改后:

After Data Changed:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;

@SuppressWarnings("serial")
public class ScrollPaneRefresh extends JPanel {
   private static final int PREF_W = 600;
   private static final int PREF_H = 200;
   private Integer[][] initialData = {
         {1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 0},
         {1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 0},
         {1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 0}
         };
   private Integer[][] newData = {
         {1, 2}, {3, 4}
         };
   private String[] columnNames = {"Col1", "Col2"};
   private TablePanel gregsPanel = new TablePanel("With fireTableDataChanged", initialData, columnNames);
   private TablePanel myPanel = new TablePanel("Without fireTableDataChanged", initialData, columnNames);

   public ScrollPaneRefresh() {
      gregsPanel.setButtonAction(new AbstractAction("Change Table Data") {
         private boolean changeToNewData = true;

         @Override
         public void actionPerformed(ActionEvent evt) {
            if (changeToNewData) {
               gregsPanel.setTableModelDataVector(newData, columnNames);
            } else {
               gregsPanel.setTableModelDataVector(initialData, columnNames);
            }
            gregsPanel.fireTableDataChanged();
            changeToNewData = !changeToNewData;
         }
      });
      myPanel.setButtonAction(new AbstractAction("Change Table Data") {
         private boolean changeToNewData = true;

         @Override
         public void actionPerformed(ActionEvent evt) {
            if (changeToNewData) {
               myPanel.setTableModelDataVector(newData, columnNames);
            } else {
               myPanel.setTableModelDataVector(initialData, columnNames);
            }
            // myPanel.getScrollPane().getViewport().revalidate();
            changeToNewData = !changeToNewData;
         }
      });

      setLayout(new GridLayout(1, 0));
      add(gregsPanel.getMainPanel());
      add(myPanel.getMainPanel());
   }

   @Override // so scrollbars will show
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

   private static void createAndShowGui() {
      ScrollPaneRefresh mainPanel = new ScrollPaneRefresh();

      JFrame frame = new JFrame("ScrollPaneRefresh");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

class TablePanel {
   private JPanel mainPanel = new JPanel();
   private DefaultTableModel dm;
   private JTable table = new JTable();
   private JButton changeTableBtn = new JButton();
   private JScrollPane scrollpane = new JScrollPane(table);

   public TablePanel(String title, Object[][] data, Object[] columnNames) {
      dm = new DefaultTableModel(data, columnNames);
      table.setModel(dm);
      JPanel btnPanel = new JPanel();
      btnPanel.add(changeTableBtn);

      mainPanel.setBorder(BorderFactory.createTitledBorder(title));
      mainPanel.setLayout(new BorderLayout(5, 5));
      mainPanel.add(scrollpane, BorderLayout.CENTER);
      mainPanel.add(btnPanel, BorderLayout.PAGE_END);
   }

   public void setButtonAction(Action action) {
      changeTableBtn.setAction(action);
   }

   public void setTableModelDataVector(Object[][] data, Object[] columnNames) {
      dm.setDataVector(data, columnNames);
   }

   public void fireTableDataChanged() {
      dm.fireTableDataChanged();
   }

   public JScrollPane getScrollPane() {
      return scrollpane;
   }

   public JComponent getMainPanel() {
      return mainPanel;
   }
}

我上面的示例的不足之处在于它不能重现原始海报的问题,我认为这是由于我们使用了SpringLayout,而他没有完全描述或显示代码:

The deficiency of my example above is that it does not reproduce the original poster's problem, and I think that is due to us use of SpringLayout, which he does not fully describe or show code:

要获得更多更好的帮助,OP必须创建自己的 sscce 类似(或更简单)的东西我已经在上面发布了.要么解决该问题,要么不使用SpringLayout来保存JTable,而是直接将其添加到JScrollPane的视口视图中,或者使用JPanel将其添加到BorderLayout中(注意还要添加JTable的标头),然后将其添加到JScrollPane的视口视图.

For more and better help, the OP is going to have to create his own sscce similar (or simpler) than what I've posted above. Either that, or solve his problem by not using SpringLayout to hold the JTable but rather either add it directly to the JScrollPane's viewport view or add it to a BorderLayout using JPanel (taking care to also add the JTable's header) and add that to the JScrollPane's viewport view.

这篇关于摆动:更改JTable结构后,JScrollPane不刷新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-15 07:57