当前位置: 首页 > 知识库问答 >
问题:

JTable和DefaultTableModel不刷新表数据

步博厚
2023-03-14

我在更新/刷新表中的数据时遇到问题。我使用的是DefaultTableModel。以下是代码,请分享您的知识和建议。顺致敬意,

*编辑1:*原始代码有一个更新表数据的函数,但事实证明这是错误的,因为构造函数一次又一次地创建新的JTable和新的JScrollPane。这就是为什么我创建了新的构造函数,并修复了这个bug。在我实现了新的构造函数之后,表数据仍然没有刷新。接下来,我尝试调试构造函数从另一个类(passDatatoTable类)接收的数据。在我使用函数setValueAt()之后,然后是System。出来println(getValueAt(i,1)),输出为空。这就是第一个创建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用于分页,按钮AddData用于创建类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);
 }

 }

共有3个答案

邓高韵
2023-03-14

谢谢你们的帮助。我终于解决了这个问题。填表是一个重要的任务。换句话说,我就是这么做的:

还记得那个向表传递数据的类吗?就像我在这里做的那样修改它:

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个构造函数都不见了,因为您不需要它们。

代码:

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);
}

现在重要的标准杆来了。重新成员按钮“添加数据”?不是所有你需要做的就是将这个图形用户界面的重新发送到将数据填充到表的类(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();
        }
    });
}

    }

忘记添加主类。给你。如果你有任何问题,请提出。感谢装满鳗鱼的气垫船,感谢赖美斯为他们的时间提供的巨大帮助。

松俊美
2023-03-14

你的问题可能在这里:

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;
   }

}
咸高谊
2023-03-14

您似乎正在为新的Gui对象设置表格模型数据,该对象与当前显示的Gui不关联,因此JTable表格中没有显示任何内容。

使用模型更新方法可以根据需要更新模型数据:

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();

这将自动发生。

 类似资料:
  • > 我创建了一个函数,在该函数中我创建了表 我创建了另一个函数,它将我的数据从arraylist发布到我的表中。 到现在为止一切都很好。当我试图更新我的时,问题就出现了。实际上,我打开一个并尝试在列表中添加一个新项。我开始使用新项修改,但之后无法更新表,例如,我真的不知道将放在哪里,以及如何在需要时调用它。 我已经在这个网站上看到了一些问题,但我尝试的没有一个真正适用于我的程序。谢谢你的帮助,对不

  • 我有一个从本地MySQL服务器获取信息的表。它很好地读取数据并将其发布在GUI上。 提前道谢。(给出一个关于DefaultTableModel的例子会很棒)

  • 问题内容: 我对/ 有问题。我的数据表未刷新/更新。我正在使用,根据代码,一切都很好,并且没有任何错误。我也有一个带有分页的表,这就是为什么我使用动作监听器和按钮“上一个”和“下一个”的原因。我正在从其他函数传递到在is中的类中编码的函数 。问题是我填充了包含表数据的数组,但是表不会更新/刷新它。这是我的代码。谢谢前进。 大编辑 旧代码已删除。我添加了新代码,可以帮助您了解我的问题。希望这会有所帮

  • 我想从JTable获取DefaultTableModel,然后添加Column。我在JTable中搜索,但只找到了getModel()方法,然后无法添加列。最后,假设我在JTable中使用Binding方法设置日期,然后没有DefaultTableModel,我想添加列内容JButton添加到我的JTable中。