Несколько объектов в одной ячейке JTable

Возможно ли иметь несколько объектов внутри одной ячейки JTable, выглядящих так, когда у меня есть два JLabels в каждой ячейке в первой строке?

введите здесь описание изображения

Проблема, с которой я сталкиваюсь в этом примере, заключается в том, что я не могу добавить никаких слушателей ни к одному JLabels(Icons). Я предполагаю, что мне нужно изменить что-то еще, кроме CellRenderer?

public class JTableIcons extends JPanel {

    private DefaultTableModel model;
    private JTable table;

    public JTableIcons() {
        initModel();
        initTable();
        this.setLayout(new BorderLayout());
        this.add(table, BorderLayout.CENTER);
    }

    class MyRenderer implements TableCellRenderer {

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value,
                boolean isSelected, boolean hasFocus, int row, int column) {

            JPanel panel = new JPanel();
            if (row == 0) {
                JLabel lblCol = new JLabel("Column:" + column);
                Icon icon = UIManager.getIcon("OptionPane.errorIcon");
                JLabel lblIcon = new JLabel();
                lblIcon.setIcon(icon);
                panel.add(lblIcon);
                panel.add(lblCol);
            } else {
                JLabel lbl = new JLabel("(" + row + "," + column + ")");
                panel.add(lbl);
            }
            panel.setOpaque(false);
            return panel;
        }
    }

    private void initTable() {
        table = new JTable(model);
        table.setDefaultRenderer(Object.class, new MyRenderer());
        table.setShowGrid(true);
        table.setGridColor(Color.gray);
        table.setRowHeight(80);
    }

    private void initModel() {
        String[] cols = { "", "", "" };
        Object[][] rows = { { "", "", "" }, { "", "", "" }, { "", "", "" }, { "", "", "" } };
        model = new DefaultTableModel(rows, cols);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame f = new JFrame();
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.add(new JTableIcons());
                f.setVisible(true);
                f.setSize(new Dimension(500, 350));
                f.setLocationRelativeTo(null);
            }
        });
    }
}

person Grains    schedule 09.12.2013    source источник


Ответы (2)


Я хотел бы добавить два или более объектов,

Не используйте два компонента, когда достаточно одного. рендерер в этом example реализует интерфейс Icon для использования гибкого относительного позиционирования текста и значка. При необходимости добавьте несколько компонентов в подходящий легкий Container, например. JPanel.

а затем также иметь разных слушателей для добавленных объектов.

Для интерактивности используйте пользовательский TableCellEditor. Этот пример управляет переключателями на панели.

person trashgod    schedule 09.12.2013
comment
Добавление нескольких компонентов в JPanel — это то, что я уже делал в своем примере? Не могу найти разницу между примером значкассылка и моим примером в вопросе (оба являются просто пользовательским средством визуализации?). Правильно ли я делаю, и мне просто нужно добавить TableCellEditor? - person Grains; 09.12.2013
comment
Точно; вы можете использовать экземпляр вашего рендерера в вашем редакторе. - person trashgod; 09.12.2013

Спасибо MadProgrammer за пример. Удалось придумать это:

введите здесь описание изображения

Где к обоим значкам подключены слушатели.

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import java.io.IOException;
import java.util.Vector;

import javax.imageio.ImageIO;
import javax.swing.AbstractCellEditor;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;

public class IconsInTableCell extends JPanel {

    private static final String[] COLUMN_NAMES = { "Icons" };
    private MyTableModel tableModel;
    private JTable table;
    private JFrame frame = new JFrame();

    public IconsInTableCell() {
        super(new BorderLayout(0, 5));
        setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        tableModel = new MyTableModel();
        table = new JTable(tableModel);
        table.setDefaultEditor(Icon.class, new IconEditor());
        table.setDefaultRenderer(Icon.class, new IconRenderer());
        table.setRowHeight(60);
        add(new JScrollPane(table), BorderLayout.CENTER);
        tableModel.add(new TableEntry());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new JScrollPane(table), BorderLayout.CENTER);
        frame.pack();
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                frame.setVisible(true);
            }
        });
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new IconsInTableCell();
            }
        });
    }

    private enum Icon {
        Delete, Sort;
    }

    private class IconPanel extends JPanel implements MouseListener {

        private JLabel icon1;
        private JLabel icon2;

        IconPanel() {
            super(new GridLayout(0, 1));
            setOpaque(true);

            try {
                icon1 = new JLabel(new ImageIcon(ImageIO.read(new File("Photo01.jpg"))));
                icon2 = new JLabel(new ImageIcon(ImageIO.read(new File("tst.jpg"))));

                icon1 = new JLabel(UIManager.getIcon("OptionPane.errorIcon"));
                icon2 = new JLabel(UIManager.getIcon("OptionPane.warningIcon"));
            } catch (IOException e) {
                e.printStackTrace();
            }

            icon1.addMouseListener(this);
            icon2.addMouseListener(this);

            this.setLayout(new GridBagLayout());
            GridBagConstraints c = new GridBagConstraints();
            add(icon1, c);
            add(new JLabel("TEXT"), c);
            add(icon2, c);
        }

        @Override
        public void mouseClicked(MouseEvent e) {
            if (e.getSource() == icon1)
                System.out.println("icon1");
            else if (e.getSource() == icon2)
                System.out.println("icon2");
        }

        @Override
        public void mousePressed(MouseEvent e) {
        }

        @Override
        public void mouseReleased(MouseEvent e) {
        }

        @Override
        public void mouseEntered(MouseEvent e) {
        }

        @Override
        public void mouseExited(MouseEvent e) {
        }
    }

    private class TableEntry {

        private Icon theIcons;

        TableEntry() {
        }

        TableEntry(Icon aIcons) {
            theIcons = aIcons;
        }

        public Icon getIcons() {
            return theIcons;
        }

        public void setIcons(Icon aIcon) {
            theIcons = aIcon;
        }
    }

    private class MyTableModel extends AbstractTableModel {

        private Vector<Object> theEntries;

        MyTableModel() {
            theEntries = new Vector<Object>();
        }

        @SuppressWarnings("unchecked")
        public void add(TableEntry anEntry) {
            int index = theEntries.size();
            theEntries.add(anEntry);
            fireTableRowsInserted(index, index);
        }

        public void remove(int aRowIndex) {
            if (aRowIndex < 0 || aRowIndex >= theEntries.size()) {
                return;
            }
            theEntries.removeElementAt(aRowIndex);
            fireTableRowsDeleted(aRowIndex, aRowIndex);
        }

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

        @Override
        public Class<?> getColumnClass(int columnIndex) {
            return Icon.class;
        }

        @Override
        public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
            TableEntry entry = (TableEntry) theEntries.elementAt(rowIndex);
            entry.setIcons((Icon) aValue);
            fireTableCellUpdated(rowIndex, columnIndex);
        }

        @Override
        public boolean isCellEditable(int rowIndex, int columnIndex) {
            return true;
        }

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

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            TableEntry entry = (TableEntry) theEntries.elementAt(rowIndex);
            switch (columnIndex) {
            case 0:
                return entry.getIcons();
            }
            return null;
        }
    }

    private class IconEditor extends AbstractCellEditor implements TableCellEditor {

        private IconPanel theIconPanel;

        IconEditor() {
            theIconPanel = new IconPanel();
        }

        @Override
        public Object getCellEditorValue() {
            return null;
        }

        @Override
        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
            if (isSelected) {
                theIconPanel.setBackground(table.getSelectionBackground());
            } else {
                theIconPanel.setBackground(table.getBackground());
            }
            return theIconPanel;
        }
    }

    private class IconRenderer extends IconPanel implements TableCellRenderer {

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            if (isSelected) {
                setBackground(table.getSelectionBackground());
            } else {
                setBackground(table.getBackground());
            }
            return this;
        }
    }
}
person Grains    schedule 10.12.2013