如何在JTable而不是列标题上显示行标题

Rid*_*ris 2 java swing jtable jtableheader

我怎样才能展示我的Jtable?

在此输入图像描述

目前我只知道创造这种jtable

在此输入图像描述

下面是我的代码

这里

           Object rowData1[][] =
                            {
                            { "","","","" },
                            { "","","","" },
                            { "","","","" },
                            { "","","","" }
                            };


            Object columnNames1[] = { "HEADER 1", "HEADER 2", "HEADER 3", "HEADER 4" };

            JTable table1 = new JTable(rowData1, columnNames1);

            table1.getColumnModel().getColumn(0).setPreferredWidth(120);

            JScrollPane scrollPane1 = new JScrollPane(table1);
Run Code Online (Sandbox Code Playgroud)

Mad*_*mer 5

这只是一个概念证明

免责声明:在我收到大量讨厌的邮件之前,我已经做了很多可怕的事情来完成这项工作,我直接从源代码中偷走了大部分的绘画代码,这就是它在外观和感觉方面的实际效果.代码本身:P

我也去了第n度,这意味着我确实假设您希望行标题看起来像列标题.如果这不是一项要求,那将会更容易......


好的,这是概念的基本证明,它提供了生成行标题并以与正常方式相同的方式呈现它们的方法,就像行标题一样.

需要添加/支持的事情:

  • 检测表模型何时更改(即,将新表模型设置为表)
  • 检测列模型何时更改(即,将新列模型设置为表)

大部分功能可能需要添加到TableWithRowHeader实现中......

基本上,这个"尝试"做的是创建一个自定义行标题,基于a JTableHeader,删除现有列标题并将其自身添加到封闭的行标题视图位置JScrollPane.

TableRowHeader

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JViewport;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TableColumnModelEvent;
import javax.swing.event.TableColumnModelListener;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;

public class TableRowHeaderTest {

    public static void main(String[] args) {
        new TableRowHeaderTest();
    }

    public TableRowHeaderTest() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                Object rowData1[][]
                                = {
                                    {"", "", "", ""},
                                    {"", "", "", ""},
                                    {"", "", "", ""},
                                    {"", "", "", ""}
                                };

                Object columnNames1[] = {"HEADER 1", "HEADER 2", "HEADER 3", "HEADER 4"};

                JTable table1 = new TableWithRowHeader(rowData1, columnNames1);

                table1.getColumnModel().getColumn(0).setPreferredWidth(120);

                JScrollPane scrollPane1 = new JScrollPane(table1);
                scrollPane1.setColumnHeaderView(null);

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(scrollPane1);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TableWithRowHeader extends JTable {

        private TableRowHeader rowHeader;

        public TableWithRowHeader(final Object[][] rowData, final Object[] columnNames) {
            super(rowData, columnNames);
            rowHeader = new TableRowHeader(this);
        }

        @Override
        protected void configureEnclosingScrollPane() {
            // This is required as it calls a private method...
            super.configureEnclosingScrollPane();

            Container parent = SwingUtilities.getUnwrappedParent(this);
            if (parent instanceof JViewport) {

                JViewport port = (JViewport) parent;
                Container gp = port.getParent();
                if (gp instanceof JScrollPane) {

                    JScrollPane scrollPane = (JScrollPane) gp;
                    JViewport viewport = scrollPane.getViewport();
                    if (viewport == null || SwingUtilities.getUnwrappedView(viewport) != this) {
                        return;
                    }
                    scrollPane.setColumnHeaderView(null);
                    scrollPane.setRowHeaderView(rowHeader);
                }
            }
        }

    }

    public class TableRowHeader extends JTableHeader {

        private JTable table;

        public TableRowHeader(JTable table) {
            super(table.getColumnModel());
            this.table = table;

      table.getColumnModel().addColumnModelListener(new TableColumnModelListener() {

                @Override
                public void columnAdded(TableColumnModelEvent e) {
                    repaint();
                }

                @Override
                public void columnRemoved(TableColumnModelEvent e) {
                    repaint();
                }

                @Override
                public void columnMoved(TableColumnModelEvent e) {
                    repaint();
                }

                @Override
                public void columnMarginChanged(ChangeEvent e) {
                    repaint();
                }

                @Override
                public void columnSelectionChanged(ListSelectionEvent e) {
                    // Don't care about this, want to highlight the row...
                }
            });
            table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
                @Override
                public void valueChanged(ListSelectionEvent e) {
                    repaint();
                }
            });
        }

        public JTable getTable() {
            return table;
        }

        @Override
        public Dimension getPreferredSize() {
            Dimension size = new Dimension();
            JTable table = getTable();
            if (table != null) {
                TableColumnModel model = table.getColumnModel();
                if (model != null) {

                    for (int index = 0; index < model.getColumnCount(); index++) {

                        TableColumn column = model.getColumn(index);
                        TableCellRenderer renderer = column.getHeaderRenderer();
                        if (renderer == null) {

                            renderer = getDefaultRenderer();

                        }
                        Component comp = renderer.getTableCellRendererComponent(table, column.getHeaderValue(), false, false, -1, index);
                        size.width = Math.max(comp.getPreferredSize().width, size.width);
                        size.height += table.getRowHeight(index);

                    }

                }
            }
            return size;

        }

    /**
     * Overridden to avoid propagating a invalidate up the tree when the
     * cell renderer child is configured.
     */
        @Override
        public void invalidate() {
        }

        /**
         * If the specified component is already a child of this then we don't bother doing anything - stacking order doesn't matter for cell renderer components
         * (CellRendererPane doesn't paint anyway).
         */
        @Override
        protected void addImpl(Component x, Object constraints, int index) {
            if (x.getParent() == this) {
                return;
            } else {
                super.addImpl(x, constraints, index);
            }
        }

        @Override
        protected void paintComponent(Graphics g) {

//            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();

            g2d.setColor(getBackground());
            g2d.fillRect(0, 0, getWidth(), getHeight());

            JTable table = getTable();
            if (table != null) {

                int width = getWidth();

                TableColumnModel model = table.getColumnModel();
                if (model != null) {

                    for (int index = 0; index < model.getColumnCount(); index++) {

                        TableColumn column = model.getColumn(index);
                        TableCellRenderer renderer = column.getHeaderRenderer();
                        if (renderer == null) {

                            renderer = getDefaultRenderer();

                        }

                        boolean selected = table.getSelectedRow() == index;

                        Component comp = renderer.getTableCellRendererComponent(table, column.getHeaderValue(), selected, false, 0, index);

                        add(comp);
                        comp.validate();

                        int height = table.getRowHeight(index) - 1;
                        comp.setBounds(0, 0, width, height);
                        comp.paint(g2d);
                        comp.setBounds(-width, -height, 0, 0);

                        g2d.setColor(table.getGridColor());
                        g2d.drawLine(0, height, width, height);

                        g2d.translate(0, height + 1);

                    }

                }
            }
            g2d.dispose();
            removeAll();
        }

    }

}
Run Code Online (Sandbox Code Playgroud)

免责声明:这可能会在你的脸上爆炸.我没有做任何检查,以防止标题响应像列行分拣的更改和......理论上...它不应该尝试"调整"列,但我没有测试...