Bas*_*en_ 3 java swing jtable jscrollpane
我有一个JTable,与一个DefaultTableModel相关联,在一个JPanel中,一个SpringLayout位于JScrollPane中.
当我使用下面的方法修改DefaultTableModel的结构时,刷新JTable但不刷新JScrollPane.我必须第二次应用此方法来刷新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();
}
Run Code Online (Sandbox Code Playgroud)
任何帮助非常感谢!
这是一个测试程序,它显示当JScrollPane持有JTable并且通过setDataVector(...)它更改DefaultTableModel的DataVector时,没有必要调用 fireTableDataChanged()模型来使JTable的数据正确更改并正确查看.
程序GUI看起来像下面的图像.
数据更改前:
数据更改后:

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;
}
}
Run Code Online (Sandbox Code Playgroud)
上面我的例子的不足之处在于它没有重现原始海报的问题,我认为这是由于我们使用SpringLayout,他没有完全描述或显示代码:
我有一个JTable,与一个DefaultTableModel相关联,在一个JPanel中,一个SpringLayout位于JScrollPane中.
为了获得更多更好的帮助,OP必须创建与我上面发布的类似(或更简单)相似(或更简单)的sscce.或者通过不使用SpringLayout来保存JTable来解决他的问题,而是将其直接添加到JScrollPane的视口视图中,或者使用JPanel将其添加到BorderLayout(注意也添加JTable的头部)并将其添加到JScrollPane的视口视图.
我之前遇到过这个问题.
尝试使JTable无效并重新绘制JScrollPane.
table.invalidate();
scrollPane.repaint();
Run Code Online (Sandbox Code Playgroud)