【问题标题】:Connect a list of objects to a JTable将对象列表连接到 JTable
【发布时间】:2011-11-14 17:37:54
【问题描述】:

我有一个 Java 中 SI(单指令)类型的对象列表。 这是 SI 类及其构造函数。

    public class SI {
        private String recipe;
        private Integer makingOrder;
        private String instruction;
        private double estimatedTimeInMinutesSeconds;
        private Double timerInMinutesSeconds;
        private String timerEndingText;
        private boolean containsOtherInstructions = false;
        private List<SI> embeddedInstructionsList;

        public SI (String s1, Integer i1, String s2, double d1, Double d2, String s3){
            recipe = s1;
            makingOrder = i1;
            instruction = s2;
            estimatedTimeInMinutesSeconds = d1;
            timerInMinutesSeconds = d2;
            timerEndingText = s3;
        }
setters and getters methods ommited....

我需要在我的 GUI 中有一个表格来显示这个列表的数据。 当我开始程序时,我创建了一个

public List<SI> finalList = new ArrayList();

这是空的,所以我需要显示一个空表。 该表应包含

(String Recipe, Integer Order, String Instruction, double Est.time, Double Timer, String TimerText, boolean containsOtherInstructions)

之后,finalList 中填充了数据,我需要将这些数据显示在表格中。 为了给你举个例子,我创建了一个按钮来创建一些 SI 并将它们添加到 finalList。

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
    SI si1 = new SI("Greek Salad", 1, "cut veggies", 4, null, null);
    SI si2 = new SI("Greek Salad", 2, "put spices", 1, null, null);
    SI si3 = new SI("Greek Salad", 3, "feta and finish", 1, null, null);
    SI si4 = new SI("Break", null, "Your free 10 minutes", 10, null, null);
    SI si5 = new SI("Meat", 1, "preheat oven", 0.5, 10.0, "oven is ready");
    SI si6 = new SI("Meat", 2, "spices on meat", 2, null, null);
    SI si7 = new SI("Meat", 3, "cook meat", 1, 10.0, "meat is ready");
    SI si8 = new SI("Meat", 4, "serve", 1, null, null);
    SI si9 = new SI("Break", null, "Your free 10 minutes", 10, null, null);
    SI si10 = new SI("Jelly", 1, "Boil water", 0.5, 4.0, "water is ready");
    SI si11 = new SI("Jelly", 2, "add mix and stir", 4, null, null);
    SI si12 = new SI("Jelly", 3, "share in bowls, wait 3 hours", 2, null, null);
    finalList.add(si1);
    finalList.add(si2);
    finalList.add(si3);
    finalList.add(si4);
    finalList.add(si5);
    finalList.add(si6);
    finalList.add(si7);
    finalList.add(si8);
    finalList.add(si9);
    finalList.add(si10);
    finalList.add(si11);
    finalList.add(si12);
}

现在我需要在按下按钮时更新表格并显示数据。 我已经尝试了很多来找出如何做到这一点,但这太难了。我不确定我应该扩展 AbstractTableModel 还是只使用 defaultTableModel。

为了帮助您给我建议,此表的数据是最终数据,用户不能修改任何单元格。但是,应该允许用户做的是向上或向下移动行以更改 finalList 中的顺序。

PS:如果您对 GUI builder 有任何快速建议,我正在使用 netbeans。

【问题讨论】:

  • 1) What have you tried? 2) 你的问题是什么?
  • 我实际上被困在如何做到这一点......我已经检查了很多论坛,这个:dreamincode.net/forums/topic/… 可能是最接近的,但我不知道如何将它应用到我的对象列表中...如何设置列名和类型?如何将数据传递给表...
  • @Ioannis,是的,BeanTableModel 很复杂,因为它使用反射。但是,您不需要自定义任何代码。它的一行代码创建模型,另一行代码将模型添加到表中。您是否下载了JButtonTableModel.java 代码?它展示了如何直接使用 BeanTableModel,或者展示了如何通过几行代码扩展 RowTableModel 以使用您的 SI 对象。
  • 我注意到您在下面的评论中希望支持上下移动行。 RowTableModel 已经支持移动行的功能。如果您发现 BeanTableModel 太混乱,我建议您专注于 JButtonTableModel 示例。这些更改与您在下面使用的几乎相同,只是您扩展到 RowTableModel 而不是 AbstractTableModel 这使您能够使用所有 RowTableModel 方法而不是自己实现它们。
  • 我没有意识到 JbuttonTableModel 是一个例子......我终于理解了它,你是对的......使用 beanModel 很容易。我现在可能会选择行模型.. **就像这样简单**private BeanTableModel model = new BeanTableModel(SI.class); jtable.setmodel(model); Iterator iter = finalList.iterator(); while(iter.hasNext()){ SI si = (SI) iter.next(); model.addRow(si); } 以及我设法通过一些修改来移动行......谢谢。

标签: java swing list


【解决方案1】:

在模型-视图-控制器架构中,模型始终负责提供数据。如果您为 JTable 使用模型,则模型会提供数据。

为了创建模型,请创建一个扩展 AbstractTableModel 的单独类,并具有一个构造函数,该构造函数创建您需要的所有 SI 对象并将它们存储到 ArrayList。

 public class FinalTableModel extends AbstractTableModel {

    private List<SI> li = new ArrayList();
    private String[] columnNames = { "Recipe", "Order", "Instruction",
                "Est.time", "Timer", "Timer Label", "Has Subinstructions"};

    public FinalTableModel(List<SI> list){
         this.li = list;
    }

    @Override
    public String getColumnName(int columnIndex){
         return columnNames[columnIndex];
    }

    @Override     
    public int getRowCount() {
        return li.size();
    }

    @Override        
    public int getColumnCount() {
        return 7; 
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        SI si = list.get(rowIndex);
        switch (columnIndex) {
            case 0: 
                return si.getRecipe();
            case 1:
                return si.getMakingOrder();
            case 2:
                return si.getInstruction();
            case 3:
                return si.getEstimatedTimeInMinutesSeconds();
            case 4:
                return si.getTimerInMinutesSeconds();
            case 5:
                return si.getTimerEndingText();
            case 6:
                return si.isContainsOtherInstructions(); 
           }
           return null;
   }

   @Override
   public Class<?> getColumnClass(int columnIndex){
          switch (columnIndex){
             case 0:
               return String.class;
             case 1:
               return Integer.class;
             case 2:
               return String.class;
             case 3:
               return Double.class;
             case 4:
               return Double.class;
             case 5:
               return String.class;
             case 6:
               return Boolean.class;
             }
             return null;
      }
 }

然后制作你的 JFrame 并像这样创建你的 JTable:

    jScrollPane1 = new javax.swing.JScrollPane();
    jTable1 = new javax.swing.JTable();

    jTable1.setModel(new FinalTableModel(finalList));
    jScrollPane1.setViewportView(jTable1);

这个想法是 JTable 将通过调用 getValueAt(row, col) 自动从模型请求数据。

Netbeans 可以很容易地将模型分配给您的 JTable。模型是 JTable 的一个属性。单击“...”按钮并选择“自定义代码”。在下面创建一个模型实例。

【讨论】:

  • 嗨 Costi,我不手动创建列表...它是自动计算的...所以我需要以某种方式将其传递给模型...
  • 没关系。只需在模型类的构造函数中进行这些计算。然后 JTable 将从那里获取数据。
  • 我快到了...我做了我的课,我将列表作为参数传递给构造函数...(我不知道为什么我以前看不到)。当我按下按钮时,我更新了表格。我不知道如何修复表格以显示布尔等复选框......现在我将所有内容都作为字符串
  • 我这样做@Override public Class&lt;?&gt; getColumnClass(int columnIndex){ switch (columnIndex){ case 0: return String.class; case 1: return Integer.class; case 2: return String.class; case 3: return double.class; case 4: return Double.class; case 5: return String.class; case 6: return Boolean.class; } return null; } 并且出于某种原因我收到错误 NullPointerException
  • 好的,知道了。 double 应该是 Double ....thanx 的帮助。我现在还有其他任务来上下移动行并通常控制表格列表,但这是另一回事......是否可以编辑上面的代码以更清楚地了解我是如何为其他观众做的?
【解决方案2】:

使用 DefaultTableModel 更容易,但是您不需要使用 ArrayList,而是使用 DefaultTableModel 保存的数据模型,尽管您可以使用 ArrayList 来加载模型。

您可以使用包含列标题和 0 行的数组构造 DefaultTableModel,然后在 for 循环中添加行,使用上面的 ArrayList 创建 Vector&lt;Object&gt;Object[],然后将其输入带有addRow 方法的模型。请注意,您不能将 SI 对象添加为一行,而是必须从每个 SI 对象中提取数据并将其放入对象数组或对象向量中。

如果您改为使用 AbstractTableModel 路线,您将使用自己的数据结构作为模型的核心,因此在这里,您的 ArrayList 可以正常工作,但您将负责更多繁重的工作.这并非不可能,但需要更多的工作。您可能希望查看 Rob Camick 的 webtip 博客,因为它有一些不错的模型示例。你可以在这里找到它:Java Tips Weblog。特别是,请查看它的Row Table Model 条目。

【讨论】:

  • 我看到我不应该使用 DefaultTableModel,因为我想动态移动我的 finalList 中的数据。行表模型类似于抽象模型,不同之处在于它为您提供了更多使用行的方法并且不太关心列,对吗?如果是这样的话,我更喜欢摘要中的内容。我无法弄清楚将列表与表格连接起来的代码。
  • 如果您使用 DefaultTableModel,您也可以动态移动数据,所以这不是限制。使用 DefaultTableModel 的主要限制是您不会直接处理 SI 对象,而是处理 SI 对象持有的数据。至于“计算代码”,这是你必须要做的事情。但是,如果您遇到特定问题,请向我们展示您的尝试,我们可能会为您提供帮助。
  • 我创建了我的模型类扩展了 abstractTableModel,我知道我的列名,所以我将它们传递给 private String[] columnNames =.. 我得到了最初需要的方法,如 getColumnCount()、getRowCount()、 getColumnName(int col), getValueAt 但我不知道如何将我的列表传递到“私有对象 [][] 数据 = {}”中。在其他帖子中手动输入数据' private Object[][] data = { { "hgflig", "Campione", "Snowboarding", new Integer(5), new Boolean(false) }' 但我不知道如何在那里传递我的 SI 列表。有什么建议如何在其中传递对象吗?
  • +1, `RowTableModel' 只是显示对象行的起点。您可能希望使用Bean Table Model 来实现完整的实现。它还有一个示例,向您展示如何手动扩展 RowTableModel 以实现两个必需的方法。
  • 我现在正在检查它...我做得很好,我设法使用默认模型在表格上获取数据,但我需要另一个模型来完成这项工作..我会尽快通知您。感谢您的帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-23
  • 1970-01-01
  • 2014-04-02
  • 1970-01-01
  • 1970-01-01
  • 2014-04-06
  • 2022-01-01
相关资源
最近更新 更多