gpt4 book ai didi

java - Swing : JScrollPane doesn't refresh after changes in the structure of a JTable

转载 作者:搜寻专家 更新时间:2023-11-01 04:03:21 26 4
gpt4 key购买 nike

我在 JPanel 中有一个与 DefaultTableModel 关联的 JTable,在 JScrollPane 中有一个 SpringLayout。

当我使用下面的方法修改 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();
}

非常感谢任何帮助!

最佳答案

这是一个测试程序,显示当 JTable 由 JScrollPane 持有并且 DefaultTableModel 的 DataVector 通过 setDataVector(...) 更改时,没有必要调用 fireTableDataChanged( ) 模型,以便 JTable 的数据正确更改并被正确查看。

程序 GUI 如下图所示。
数据更改前:
enter image description here

数据更改后:
enter image description here

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,他没有完整描述或显示代码:

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

为了获得更多更好的帮助,OP 将不得不创建自己的 sscce与我上面发布的类似(或更简单)。要么,要么通过不使用 SpringLayout 来保存 JTable 而是将其直接添加到 JScrollPane 的视口(viewport) View 或使用 JPanel 将其添加到 BorderLayout(同时注意添加 JTable 的标题)并将其添加到 JScrollPane 来解决他的问题视口(viewport) View 。

关于java - Swing : JScrollPane doesn't refresh after changes in the structure of a JTable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9706682/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com