Свинг Java | расширить AbstractTableModel и использовать его с JTable | несколько вопросов

Я следовал модели Oracle для реализации AbstractTableModel.

http://download.oracle.com/javase/tutorial/uiswing/examples/components/TableDemoProject/src/components/TableDemo.java

Я сделал это, потому что моя таблица должна содержать 3 столбца, и первым должен быть JCheckBox.

Вот мой код:

public class FestplattenreinigerGraphicalUserInterfaceHomePagePanelTableModel extends AbstractTableModel {
private String[] columnNames = {"Auswahl",
                                    "Dateiname",
                                    "Pfad"};
    private Object[][] data = {
    {new Boolean(true), "datei.tmp",
     "/home/user/tmp"}
    };

    public int getColumnCount() {
        return columnNames.length;
    }

    public int getRowCount() {
        return data.length;
    }

    public String getColumnName(int col) {
        return columnNames[col];
    }

    public Object getValueAt(int row, int col) {
        return data[row][col];
    }

    public Class getColumnClass(int c) {
        return getValueAt(0, c).getClass();
    }

     public boolean isCellEditable(int row, int col) {
        if (col == 0) {
            return true;
        } else {
            return false;
        }
    }

     public void setValueAt(Object value, int row, int col) {            
        data[row][col] = value;
        fireTableCellUpdated(row, col);
    }

}

Вот мои вопросы:

  1. Откуда JTable (new JTable(FestplattenreinigerGraphicalUserInterfaceHomePagePanelTableModel)) знает имена столбцов и их значения? Поскольку в моей модели AbstractTableModel нет конструктора?! Это потому, что имена столбцов и данные должны называться так, как они есть, и JTable обращается к ним?
  2. Как я могу поместить новые значения в свой JTable? Поскольку имена столбцов и данные являются массивами. Могу ли я заменить их векторами? Если да, то как мне инициализировать эти векторы? В конструкторе в myAbsTableModel?

Я думаю, что найти решение очень просто, но эта обработка таблиц не является для меня тривиальной, поэтому большое спасибо!


person JavaHater    schedule 29.11.2010    source источник
comment
Я никогда не видел класс с таким длинным именем, не могли бы вы переименовать «FestplattenreinigerGraphicalUserInterfaceHomePagePanelTableModel» во что-то более значимое;)?   -  person Alois Cochard    schedule 29.11.2010
comment
Название класса — шутка, не так ли? Скоро вам понадобится Festplattenreiniger (очиститель жесткого диска), если вы продолжите использовать такие имена ;-)   -  person Andreas Dolk    schedule 29.11.2010
comment
спасибо за хороший ответ, если бы я мог получить минус один, я бы так и сделал   -  person JavaHater    schedule 29.11.2010
comment
Что случилось со здравым чувством юмора? (Да, я только что это придумал)   -  person Bart van Heukelom    schedule 29.11.2010


Ответы (3)


Все компоненты Swing поставляются с реализациями моделей по умолчанию. Я предлагаю вам сначала понять, как их использовать, прежде чем пытаться создать свой собственный. Для JTable это называется DefaultTableModel. Прочитайте API для методов динамического добавления/удаления строк данных из модели. Вот простой пример для начала:

import java.awt.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;

public class TableBasic extends JPanel
{
    public TableBasic()
    {
        String[] columnNames = {"Date", "String", "Integer", "Boolean"};

        Object[][] data =
        {
            {new Date(), "A", new Double(1), Boolean.TRUE },
            {new Date(), "B", new Double(2), Boolean.FALSE},
            {new Date(), "C", new Double(9), Boolean.TRUE },
            {new Date(), "D", new Double(4), Boolean.FALSE}
        };

        JTable table = new JTable(data, columnNames)
        {
            //  Returning the Class of each column will allow different
            //  renderers and editors to be used based on Class

            public Class getColumnClass(int column)
            {
                for (int row = 0; row < getRowCount(); row++)
                {
                    Object o = getValueAt(row, column);

                    if (o != null)
                        return o.getClass();
                }

                return Object.class;
            }
        };
        table.setPreferredScrollableViewportSize(table.getPreferredSize());
        JScrollPane scrollPane = new JScrollPane( table );
        add( scrollPane );
    }

    private static void createAndShowUI()
    {
        JFrame frame = new JFrame("TableBasic");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( new TableBasic() );
        frame.pack();
        frame.setLocationRelativeTo( null );
        frame.setVisible( true );
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowUI();
            }
        });
    }
}
person camickr    schedule 29.11.2010

Во-первых, я думаю, вам нужно немного больше узнать о Java, особенно о наследовании (я имею в виду вашу проблему с конструктором.

Ответы на ваши вопросы:

  • определите имена столбцов с помощью атрибута private final static, предполагая, что имена столбцов не меняются.
  • поскольку ваш класс расширяет AbstractTableModel, вы можете определить для него конструктор, куда вы будете передавать данные. Переопределите метод getValueAt, чтобы модель могла использовать передаваемые вами данные.

Еще несколько советов:

  • не делай того, что ты делаешь в getColumnClass. Обычно все элементы в столбце имеют один и тот же класс, поэтому введите switch в индексе столбца, чтобы получить классы.
  • чтобы добавить JCheckBox в один из ваших столбцов, вам нужно будет использовать пользовательский TableCellRenderer
person Valentin Rocher    schedule 29.11.2010
comment
Вам не нужно писать код для пользовательского средства визуализации, чтобы отобразить флажок. JTable предоставляет средства визуализации и редактирования флажков по умолчанию. Все, что вам нужно сделать, это переопределить метод getColumnClass(), чтобы он возвращал логическое значение для столбца, и будет использоваться соответствующий модуль визуализации. - person camickr; 29.11.2010

  1. JTable определяет количество столбцов, вызывая getColumnCount() для вашей модели столбцов. Затем он выполняет итерацию и вызывает getColumnName(idx) для каждого столбца. Ваш класс сообщает ему имя столбца — посмотрите на свою реализацию этих методов.

  2. Вы можете хранить свои данные в любом удобном для вас формате. JTable вызывает методы вашей табличной модели для извлечения этих данных. Если вы хотите добавить новые элементы в свою модель, вы можете реализовать в своей модели метод addItem(Object o); просто обязательно вызывайте fireTableRowsInserted() для каждого нового элемента.

person Jeff Knecht    schedule 29.11.2010