如何在JTable而不是列标题上显示行标题 [英] How to Display Row Header on JTable Instead of Column Header

查看:91
本文介绍了如何在JTable而不是列标题上显示行标题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何向我展示我的Jtable ..

How can i display my Jtable to this ..

目前我只知道创建这种jtable

currently i only know to create this kind of jtable

以下是我的代码

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


推荐答案

这只是一个概念验证



免责声明:在我收到大量关于我为完成这项工作所做的显而易见的恐怖事件之前,我偷了大部分的画作代码直接源于源代码,这就是它在外观和代码本身中的实际完成情况:P

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

我也去了n度,这意味着我从字面上看,您希望行标题看起来像列标题。如果这不是一个要求,它会更容易做...

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. 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:


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

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

这些功能很可能需要添加到 TableWithRowHeader 实现...

Much of this functionality would probably need to be added to the TableWithRowHeader implementation...

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

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.

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...

这篇关于如何在JTable而不是列标题上显示行标题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆