简体   繁体   English

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

[英]How to Display Row Header on JTable Instead of Column Header

How can i display my Jtable to this .. 我该如何显示我的Jtable ..

在此处输入图片说明

currently i only know to create this kind of jtable 目前我只知道创建这种jtable

在此处输入图片说明

below is my code 下面是我的代码

HERE 这里

           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);

This is a proof of concept only 这仅是概念证明

Disclaimer: Before I get a bunch of hate mail about the, obviously, horrible things I've done to make this work, I stole most of the painting code straight out of the source, this is how it's actually done within the look and feel code itself :P 免责声明:在我收到一堆关于我为完成这项工作所做的显然很可怕的事情的仇恨邮件之前,我直接从源代码中偷走了大多数绘画代码,这实际上是在外观上实现的代码本身:P

I've also gone to the nth degree, meaning that I've literally assumed that you wanted the row headers to look like the column headers. 我也进入了第n个级别,这意味着我从字面上假设您希望行标题看起来像列标题。 If this isn't a requirement, it would be SO much easier to do... 如果这不是必需的,那么它将变得非常容易...


Okay, this is a basic proof of concept, which provides the means to generate the row header and render them the same way as they are normally, just as row headers instead. 好的,这是一个基本的概念证明,它提供了生成行标头并以与通常相同的方式呈现它们的方法,就像行标头一样。

Things that need to be added/supported: 需要添加/支持的内容:

  • Detect when the table model is changed (that is, a new table model is set to the table) 检测何时更改了表模型(即,将新的表模型设置为表)
  • Detect when the column model is changed (that is, a new column model is set to the table) 检测何时更改了列模型(即,将新的列模型设置为表)

Much of this functionality would probably need to be added to the TableWithRowHeader implementation... 许多功能可能需要添加到TableWithRowHeader实现中...

Basically, what this "tries" to do, is create a custom row header, based on a JTableHeader , remove the existing column header and add itself into the row header view position of the enclosing JScrollPane . 基本上,此“尝试”要做的是基于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();
        }

    }

}

Disclaimer: This is likely to blow up in your face. 免责声明:这很可能会炸毁您的脸。 I make no checks for preventing the header from responding to things like changes to the column row sortering and ... in theory ... it shouldn't try and "resize" the column but I didn't test that... 我没有做任何检查来防止标题响应列行排序器的更改等问题……从理论上讲,它不应尝试“调整”列的大小,但我没有对此进行测试...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM