我在更新/刷新表中的数据时遇到问题。我正在使用DefaultTableModel。这是代码,请分享您的知识和建议。最好的祝福。
* 编辑1:* 原始代码有一个更新表数据的功能,但由于构造函数正在创建新的JTable和新的JScrollPane,因此证明是错误的。这就是我创建新构造函数并修复bug的原因。实现新的构造函数后,表数据仍然没有刷新。接下来我尝试调试构造函数接收到的其他类(passDatatoTable类)的数据。在我使用函数setValueAt()然后使用System.out.println(getValueAt(i,1))之后,输出为null。就是这样 首先是创建gui的主要类:
import javax.swing.*;
public class Glavni {
public static void main(String[] args) {
// TODO Auto-generated method stub
SwingUtilities.invokeLater(new Runnable() {
public void run() {
gui Scanner = new gui();
Scanner.setVisible(true);
}
});
}
}
这里的第二个是向gui发送数据的类
public class passDatatoTable {
public void passData(){
String str1,str2,str3,str4;
for (int i =0;i<=10;i++){
str1="Column 1 of row: "+i;
str2="Column 2 of row: "+i;
str3="Column 3 of row: "+i;
str4="Column 4 of row: "+i;
gui SendStringsToGUI = new gui(str1, str2, str3, str4);
}
}
}
这是gui课。按钮“添加数据”用于填充数据。这是代码:
public class gui extends JFrame implements ActionListener {
private static final long serialVersionUID = 1L;
String[][] data = new String[100][4];
String[] columnNames = new String[]{
"IP", "PC_NAME", "ttl", "db"
};
DefaultTableModel model = new DefaultTableModel(data,columnNames);
JTable table = new JTable(model);
JScrollPane scrollPane = new JScrollPane(table);
int i=0;
public gui(String IP, String PC_NAME, String ttl, String gw) {
//Used this constructor to avoid creating new gui in other classes
model.setValueAt(IP, i, 0);
model.setValueAt(PC_NAME, i, 1);
model.setValueAt(ttl, i, 2);
model.setValueAt(gw, i, 3);
i++;
model.fireTableDataChanged();
table.repaint();
scrollPane.repaint();
}
gui(){
JButton addData= new JButton("Add Data");
JButton next = new JButton("next");
JButton prev = new JButton("prev");
addData.addActionListener(this);
next.addActionListener(this);
prev.addActionListener(this);
JPanel panel = new JPanel(new BorderLayout());
JPanel buttonPanel = new JPanel();
buttonPanel.add(addData);
buttonPanel.add(prev);
buttonPanel.add(next);
panel.add(buttonPanel, BorderLayout.SOUTH);
panel.add(table.getTableHeader(), BorderLayout.PAGE_START);
panel.add(scrollPane, BorderLayout.CENTER);
getContentPane().add(panel);
}
这是ActionListeners。按钮next和prev用于分页,按钮“Add Data”用于创建类“passDatatoTable”的变量,用于填充表的数据
这是代码:
public void actionPerformed(ActionEvent e) {
if ("Add Data".equals(e.getActionCommand())){
passDatatoTable passSomeData = new passDatatoTable();
passSomeData.passData();
}
if ("next".equals(e.getActionCommand())) {
Rectangle rect = scrollPane.getVisibleRect();
JScrollBar bar = scrollPane.getVerticalScrollBar();
int blockIncr = scrollPane.getViewport().getViewRect().height;
bar.setValue(bar.getValue() + blockIncr);
scrollPane.scrollRectToVisible(rect);
}
if ("prev".equals(e.getActionCommand())) {
Rectangle rect = scrollPane.getVisibleRect();
JScrollBar bar = scrollPane.getVerticalScrollBar();
int blockIncr = scrollPane.getViewport().getViewRect().height;
bar.setValue(bar.getValue() - blockIncr);
scrollPane.scrollRectToVisible(rect);
}
}
答案 0 :(得分:3)
您似乎正在设置与您当前显示的Gui
无关的新Gui
对象的表格模型数据,因此JTable
table
中不会显示任何内容。
使用模型更新方法可以根据需要更新模型数据:
public void updateModel(String IP, String PC_NAME, String ttl, String gw) {
model.setValueAt(IP, i, 0);
model.setValueAt(PC_NAME, i, 1);
model.setValueAt(ttl, i, 2);
model.setValueAt(gw, i, 3);
i++;
}
您需要将Gui
对象的引用传递给PassDatatoTable
对象。后一个对象在其当前形式中具有非常少的功能,因此最好将此功能引入Gui
类。
此外无需致电:
model.fireTableDataChanged();
这将自动发生。
答案 1 :(得分:2)
你的问题可能在这里:
class passDatatoTable {
public void passData() {
String str1, str2, str3, str4;
for (int i = 0; i <= 10; i++) {
str1 = "Column 1 of row: " + i;
str2 = "Column 2 of row: " + i;
str3 = "Column 3 of row: " + i;
str4 = "Column 4 of row: " + i;
gui SendStringsToGUI = new gui(str1, str2, str3, str4); // **** line (A)
}
}
}
您似乎正在行(A)上创建一个新的gui对象并将数据传递给它。请注意,这个gui对象与正在显示的gui对象完全无关,因此以这种方式传递数据将导致显示数据无法观察到的变化。
一种可能的解决方案是通过构造函数参数传递对gui对象的引用,然后使用该gui对象的公共方法(不构造函数)来设置或更改数据。
这是我的意思的一个简单例子:
import java.awt.event.ActionEvent;
import javax.swing.*;
public class GuiTest2 {
private static void createAndShowGui() {
Gui2 mainPanel = new Gui2();
JFrame frame = new JFrame("Gui2");
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 Gui2 extends JPanel {
private JTextField field = new JTextField(10);
// pass a reference to the GUI object into the controller via
// its constructor
private JButton nextBtn = new JButton(new NextController(this, "Next"));
public Gui2() {
field.setEditable(false);
field.setFocusable(false);
add(field);
add(nextBtn);
}
public void setTextFieldText(String text) {
field.setText(text);
}
}
class NextController extends AbstractAction {
private static final String[] TEXTS = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday"};
private Gui2 gui;
private int index = 0;
// pass the Gui2 object into the controller's constructor
public NextController(Gui2 gui, String name) {
super(name);
this.gui = gui; // set the Gui2 field with the parameter
}
@Override
public void actionPerformed(ActionEvent arg0) {
// use the Gui2 object here
gui.setTextFieldText(TEXTS[index]);
index++;
index %= TEXTS.length;
}
}
答案 2 :(得分:0)
谢谢各位老兄。最后我解决了这个问题。最重要的是将一个对象发送到正在填充表中数据的类。换句话说,这就是我所做的:
还记得将数据传递给表的类吗?好像我在这里修改它一样:
public class passDatatoTable {
passDatatoTable(ScanFrame gui){
String str1,str2,str3;
for (int i =0;i<=10;i++){
str1="Column 1 of row: "+i;
str2="Column 2 of row: "+i;
str3="Column 3 of row: "+i;
gui.model.setValueAt(str1, gui.i, 0);
gui.model.setValueAt(str2, gui.i, 2);
gui.model.setValueAt(str3, gui.i, 3);
gui.i++;
}
}}
现在让我们回到gui课堂。只需删除构造函数(只需将其重命名为您喜欢的任何内容并在main函数中调用它)。这是一个例子。注意:所有2个构造函数都已消失,因为您不需要它们。
CODE:
public void CreateAndShowGUI(){
setVisible(true);//add this line to show gui
JButton addData= new JButton("Add Data");
JButton next = new JButton("next");
JButton prev = new JButton("prev");
addData.addActionListener(this);
next.addActionListener(this);
prev.addActionListener(this);
JPanel panel = new JPanel(new BorderLayout());
JPanel buttonPanel = new JPanel();
buttonPanel.add(addData);
buttonPanel.add(prev);
buttonPanel.add(next);
panel.add(buttonPanel, BorderLayout.SOUTH);
panel.add(table.getTableHeader(), BorderLayout.PAGE_START);
panel.add(scrollPane, BorderLayout.CENTER);
getContentPane().add(panel);
}
现在重要的标准即将来临。重新构建按钮&#34;添加数据&#34;?你需要做的就是将这个gui的引用发送到将数据填充到表(passDatatoTable类)的类中,它会起作用。
public void actionPerformed(ActionEvent e) {
if ("Add Data".equals(e.getActionCommand())){
passDatatoTable passSomeData = new passDatatoTable();
passSomeData.passData(this);//here!! just add this and it will work!!
}
if ("next".equals(e.getActionCommand())) {
Rectangle rect = scrollPane.getVisibleRect();
JScrollBar bar = scrollPane.getVerticalScrollBar();
int blockIncr = scrollPane.getViewport().getViewRect().height;
bar.setValue(bar.getValue() + blockIncr);
scrollPane.scrollRectToVisible(rect);
}
if ("prev".equals(e.getActionCommand())) {
Rectangle rect = scrollPane.getVisibleRect();
JScrollBar bar = scrollPane.getVerticalScrollBar();
int blockIncr = scrollPane.getViewport().getViewRect().height;
bar.setValue(bar.getValue() - blockIncr);
scrollPane.scrollRectToVisible(rect);
}
}
修改强>
import javax.swing.*;
public class Glavni {
public static void main(String[] args) {
// TODO Auto-generated method stub
SwingUtilities.invokeLater(new Runnable() {
public void run() {
gui Scanner = new gui();
Scanner.CreateAndShowGUI();
}
});
}
}
忘记添加主类。就这个。 如果您有任何问题/疑问,请询问。感谢@Hovercraft Full Of Eels和@Reimeus为他们的时间提供了很大的帮助。