Вопрос

У меня есть функция, которая получает ключ от пользователя и генерирует Hashtable (по шаблону, указанному ключом). После создания Hashtable я хотел бы заполнить JTable так, чтобы каждый столбец представлял ключ, а каждая строка представляла значения, связанные с ключом. Я попробовал все, но не смог получить эту работу. Я не создаю таблицу из конструктора, так как мне нужно получить информацию от пользователя.

Это было полезно?

Решение

См. Как использовать таблицы: создание таблицы Модель .

  

Конструктор JTable, используемый   SimpleTableDemo создает свою таблицу   модель с таким кодом:

new AbstractTableModel() {
    public String getColumnName(int col) {
        return columnNames[col].toString();
    }
    public int getRowCount() { return rowData.length; }
    public int getColumnCount() { return columnNames.length; }
    public Object getValueAt(int row, int col) {
        return rowData[row][col];
    }
    public boolean isCellEditable(int row, int col)
        { return true; }
    public void setValueAt(Object value, int row, int col) {
        rowData[row][col] = value;
        fireTableCellUpdated(row, col);
    }
}

Вы должны обернуть свою хэш-таблицу описанным выше способом. Вот пример.

package eed3si9n.hashtabletable;

import java.awt.BorderLayout;
import java.util.Enumeration;
import java.util.Hashtable;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.JButton;
import java.awt.Dimension;

public class MainForm extends JFrame {

    private static final long serialVersionUID = 1L;
    private JPanel jContentPane = null;  //  @jve:decl-index=0:visual-constraint="23,38"
    private JScrollPane m_scrollPane = null;
    private JTable m_table = null;
    private Hashtable<String, String> m_hash = null;
    private JButton m_btnAdd = null;    

    /**
     * This is the default constructor
     */
    public MainForm() {
        super();
        initialize();
        m_hash = new Hashtable<String, String>();
        m_hash.put("Dog", "Bow");
    }

    private void onButtonPressed() {
        m_hash.put("Cow", "Moo");
        m_table.revalidate();
    }

    /**
     * This method initializes this
     * 
     * @return void
     */
    private void initialize() {
        this.setSize(409, 290);
        this.setTitle("JFrame");
        this.setContentPane(getJContentPane());
    }

    /**
     * This method initializes jContentPane
     * 
     * @return javax.swing.JPanel
     */
    private JPanel getJContentPane() {
        if (jContentPane == null) {
            jContentPane = new JPanel();
            jContentPane.setLayout(new BorderLayout());
            jContentPane.setSize(new Dimension(500, 500));
            jContentPane.setPreferredSize(new Dimension(500, 500));
            jContentPane.add(getM_scrollPane(), BorderLayout.NORTH);
            jContentPane.add(getM_btnAdd(), BorderLayout.SOUTH);
        }
        return jContentPane;
    }

    /**
     * This method initializes m_scrollPane 
     *  
     * @return javax.swing.JScrollPane  
     */
    private JScrollPane getM_scrollPane() {
        if (m_scrollPane == null) {
            m_scrollPane = new JScrollPane();
            m_scrollPane.setViewportView(getM_table());
        }
        return m_scrollPane;
    }

    /**
     * This method initializes m_table  
     *  
     * @return javax.swing.JTable   
     */
    private JTable getM_table() {
        if (m_table == null) {
            m_table = new JTable();
            m_table.setModel(new AbstractTableModel(){
    private static final long serialVersionUID = 1L;

    public int getColumnCount() {
        return 2;
    }

    public int getRowCount() {
        return m_hash.size();
    }

    public String getColumnName(int column) {
        if (column == 0) {
            return "Animal";
        } else {
            return "Sound";
        }
    }

    public Object getValueAt(int rowIndex, int columnIndex) {
        if (columnIndex == 0) {
            return getKey(rowIndex);
        } else {
            return m_hash.get(getKey(rowIndex));
        } // if-else

    }

    private String getKey(int a_index) {
        String retval = "";
        Enumeration<String> e = m_hash.keys();
        for (int i = 0; i < a_index + 1; i++) {
            retval = e.nextElement();
        } // for

        return retval;
    }

            });
        }
        return m_table;
    }

    /**
     * This method initializes m_btnAdd 
     *  
     * @return javax.swing.JButton  
     */
    private JButton getM_btnAdd() {
        if (m_btnAdd == null) {
            m_btnAdd = new JButton();
            m_btnAdd.setPreferredSize(new Dimension(34, 30));
            m_btnAdd.addActionListener(new java.awt.event.ActionListener() {
                public void actionPerformed(java.awt.event.ActionEvent e) {
                    onButtonPressed();
                }
            });
        }
        return m_btnAdd;
    }

    public static void main(String[] args) {
        //Schedule a job for the event-dispatching thread:
        //creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                MainForm frame = new MainForm();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setSize(500, 500);
                frame.setVisible(true);
            }
        });
    }
}  //  @jve:decl-index=0:visual-constraint="10,10"

Другие советы

Во-первых, избегайте Hashtable , переходите прямо к Map . В этом случае вам могут потребоваться две потенциальные стандартные реализации: LinkedHashMap может сохранить порядок добавления записей; TreeMap , SortedMap / NavigableMap , отсортирует результаты (порядок которых может быть определен Comparator . В качестве альтернативы вам может потребоваться форма Map , которая запускает события или также предоставляет TableModel .

Если вы хотите выполнить однократное преобразование из Map в таблицу, то это довольно просто.

public static TableModel toTableModel(Map<?,?> map) {
    DefaultTableModel model = new DefaultTableModel(
        new Object[] { "Key", "Value" }, 0
    );
    for (Map.Entry<?,?> entry : map) {
        model.addRow(new Object[] { entry.getKey(), entry.getValue() });
    }
    return model;
}

Затем просто создайте JTable с этой предварительно заполненной моделью.

(Отказ от ответственности: я не проверял или столько скомпилировал этот код.)

Чтобы синхронизировать Map и TableModel , нужно больше кода. Обычно лучше избегать дублирования состояния везде, где это возможно. Напишите класс, который представляет себя как Map и TableModel . Вы можете пойти дальше, имея Map , который запускает события, и TableModel , который адаптирует Map (хотя обратите внимание, что Map нет произвольного доступа на основе индекса, поэтому вам нужно быть умным или медленным для больших карт).

Если пойти по другому пути, более простым подходом было бы добавить данные прямо в DefaultTableModel и вообще не использовать Map .

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top