尝试使用适当的行标题创建JTable

我试图创建一个JTable,其行标题看起来就像一个列标题,我花了太多时间在它上面:/我的情况类似于这个问题: JTable行标题实现 ,也许这一个: 自定义jtable具有表格单元格标题颜色的cellrenderer

他们似乎还没有把我带到那里。 我搜索了很多例子,但都缺乏。 甚至没有任何带有行标题的表的例子来自Oracle / Sun. 看起来这种表不应该那么罕见。

这个只是格式化第一列,但它看起来不像列标题: http : //java-swing-tips.blogspot.com/2011/01/jtable-rowheader.html

这个似乎使用JList作为行标题,它有对齐问题(每行关闭+1像素),并且当我设置外观时看起来不那么好。 http://www.java2s.com/Code/Java/Swing-Components/TableRowHeaderExample.htm

这个看起来像我需要使用的想法(行标题是一个单独的JTable,但随后作为行标题加载到JScrollPane),但我需要调整它到我的代码,然后确保行标题得到正确标题的外观和感觉。
http://www.chka.de/swing/table/row-headers/JTable.html

这就是我所做的减去最后一点。 我尝试将表头的渲染器也作为行标题的渲染器。 行标题/第一列现在是灰色而不是白色,就像它只是另一个数据列时一样,但仍然看起来不像列标题。 这是正确的吗? 或者我应该坚持将它作为主表中的常规列保留并使用它做其他事情?

所以这是我更新表的代码。 此方法仅为列标题采用String数组,为行标题采用String数组,为主数据采用2D String数组。 我有一个用于行标题的JTable dispTableRowHeader和一个用于主数据表的JTable dispTable

private void updateDispTable(String[][] graphicalTable, String[] graphicalTableColumnHeader, String[] graphicalTableRowHeader) { //set model for the main data table, put in data. Also prevent editing cells dispTable.setModel(new javax.swing.table.DefaultTableModel( graphicalTable, graphicalTableColumnHeader ){ @Override public boolean isCellEditable(int rowIndex, int mColIndex) { return false; } }); //some mods for main data table dispTable.getTableHeader().setReorderingAllowed(false);//Was also able to do this within NetBeans GUI Builder by doing Table Contents from Jtable inspector item dispTable.getTableHeader().setResizingAllowed(false); //load main table to scrollpane jScrollPane2.setViewportView(dispTable); //get model for JTable that will be used as the row header, fill in values DefaultTableModel rowHeaderTableModel = new DefaultTableModel(0, 1);//one column for (int i = 0; i < graphicalTable.length; i++) rowHeaderTableModel.addRow(new Object[] { graphicalTableRowHeader[i] } ); //set model for row header, put in data. Alter renderer to make it like col header dispTableRowHeader.setModel(rowHeaderTableModel); dispTableRowHeader.setDefaultRenderer(Object.class, dispTableRowHeader.getTableHeader().getDefaultRenderer());//makes it gray but not like the header :/ //dispTableRowHeader.setDefaultRenderer(Object.class, jScrollPane2.getColumnHeader().getDefaultRenderer()); //load row header to scrollpane's row header jScrollPane2.setRowHeaderView(dispTableRowHeader); //set the table corner and disallow reordering and resizing JTableHeader corner = dispTableRowHeader.getTableHeader(); corner.setReorderingAllowed(false); corner.setResizingAllowed(false); jScrollPane2.setCorner(JScrollPane.UPPER_LEFT_CORNER, corner);//load to scrollpane } 

我非常感谢任何帮助!

编辑以下编辑我创建了一个全新的项目来试验并尝试了trashgod的方法(虽然它是为行标题而不是第二行)我发现它给了我相同的结果只是单元格样式灰色而不是样式像头。 然后我尝试删除我的外观和感觉调整

  // Set System L&F UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName() ); 

然后行标题看起来与列标题相同! ..但那是在Nimbus或任何默认的外观和感觉。 见下图。 第一个是将我的外观和感觉设置为上面的系统(在Win7中),第二个是默认设置。

系统外观(Win7) – 我调整了外观和感觉,设置了系统的外观和感觉

Java的Nimbus外观和感觉 – 默认外观

当然,我的程序也是如此。 所以现在看来​​我的问题在于外观和感觉。 我希望它看起来像第一个图像(系统的外观和感觉),但左侧的样式也是如此。

顺便说一下,这是MySQL Workbench的Win7中的一个例子,它具有正确设计的行和列标题,它们甚至在鼠标hover时将单元格变成蓝色。 太糟糕了,它不是用Java制作的,所以我可以尝试检查它们是如何做到的。

MySQL Workbench截图 – MySQL Workbench截图

编辑以下编辑 SSCCE代码

 package mytableexample2; import java.awt.Component; import javax.swing.JTable; import javax.swing.UIManager; import javax.swing.table.JTableHeader; import javax.swing.table.TableCellRenderer; public class MyTableExample2 extends javax.swing.JFrame { public MyTableExample2() { initComponents(); } @SuppressWarnings("unchecked") private void initComponents() { jScrollPane1 = new javax.swing.JScrollPane(); jTable1 = new javax.swing.JTable(){ @Override public Component prepareRenderer( TableCellRenderer renderer, int row, int col) { if (col == 0) { return this.getTableHeader().getDefaultRenderer() .getTableCellRendererComponent(this, this.getValueAt(row, col), false, false, row, col); } else { return super.prepareRenderer(renderer, row, col); } } }; jTable1.setAutoCreateRowSorter(false); final JTableHeader header = jTable1.getTableHeader(); header.setDefaultRenderer(new HeaderRenderer(jTable1)); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); jTable1.setModel(new javax.swing.table.DefaultTableModel( new Object [][] { {"Row 1", "Data 2", "Data 3", "Data 4", "Data 5"}, {"Row 2", "Data 6", "Data 7", "Data 8", "Data 9"}, {"Row 3", "Data 10", "Data 11", "Data 12", "Data 13"} }, new String [] { "", "Col 1", "Col 2", "Col 3", "Col 4" } )); jScrollPane1.setViewportView(jTable1); //Netbeans generated layout javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 380, Short.MAX_VALUE) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 278, Short.MAX_VALUE) .addContainerGap()) ); pack(); } public static void main(String args[]) { try { //THIS SETS TO SYSTEM'S LOOK AND FEEL UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName() ); //THIS SETS TO OTHER JAVA LOOK AND FEEL //UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel"); //UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel"); } catch (ClassNotFoundException ex) { java.util.logging.Logger.getLogger(MyTableExample2.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (InstantiationException ex) { java.util.logging.Logger.getLogger(MyTableExample2.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (IllegalAccessException ex) { java.util.logging.Logger.getLogger(MyTableExample2.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (javax.swing.UnsupportedLookAndFeelException ex) { java.util.logging.Logger.getLogger(MyTableExample2.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } /* Create and display the form */ java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new MyTableExample2().setVisible(true); } }); } // Variables declaration - do not modify private javax.swing.JScrollPane jScrollPane1; private javax.swing.JTable jTable1; } class HeaderRenderer implements TableCellRenderer { TableCellRenderer renderer; public HeaderRenderer(JTable jTable1) { renderer = jTable1.getTableHeader().getDefaultRenderer(); } @Override public Component getTableCellRendererComponent( JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) { return renderer.getTableCellRendererComponent( table, value, isSelected, hasFocus, row, col); } } 

使用此HeaderRenderer作为第一行列渲染器可能会产生您想要的效果:

附录:我已经更新了示例,以便通过手动布局反映您的sscce。 我的平台的getSystemLookAndFeelClassName()com.apple.laf.AquaLookAndFeel ,所以我没有看到相同的结果。 两个观察结果:您已经设置了setAutoCreateRowSorter(false)以防止排序小部件激增,而Nimbus保留了它的交替行突出显示。

在此处输入图像描述

 import java.awt.Component; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.table.JTableHeader; import javax.swing.table.TableCellRenderer; public class MyTableExample3 extends JFrame { private JScrollPane scrollPane; private JTable table; public MyTableExample3() { initComponents(); } @SuppressWarnings("unchecked") private void initComponents() { this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); table = new javax.swing.JTable() { @Override public Component prepareRenderer( TableCellRenderer renderer, int row, int col) { if (col == 0) { return this.getTableHeader().getDefaultRenderer() .getTableCellRendererComponent(this, this.getValueAt( row, col), false, false, row, col); } else { return super.prepareRenderer(renderer, row, col); } } }; table.setAutoCreateRowSorter(false); final JTableHeader header = table.getTableHeader(); header.setDefaultRenderer(new HeaderRenderer(table)); table.setModel(new javax.swing.table.DefaultTableModel( new Object[][]{ {"Row 1", "Data 2", "Data 3", "Data 4", "Data 5"}, {"Row 2", "Data 6", "Data 7", "Data 8", "Data 9"}, {"Row 3", "Data 10", "Data 11", "Data 12", "Data 13"} }, new String[]{ "", "Col 1", "Col 2", "Col 3", "Col 4" })); scrollPane = new JScrollPane(table); this.add(scrollPane); pack(); } public static void main(String args[]) { java.awt.EventQueue.invokeLater(new Runnable() { @Override public void run() { new MyTableExample3().setVisible(true); } }); } private static class HeaderRenderer implements TableCellRenderer { TableCellRenderer renderer; public HeaderRenderer(JTable table) { renderer = table.getTableHeader().getDefaultRenderer(); } @Override public Component getTableCellRendererComponent( JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) { return renderer.getTableCellRendererComponent( table, value, isSelected, hasFocus, row, col); } } } 

也许

在此处输入图像描述

 import java.awt.*; import java.awt.event.ActionEvent; import javax.swing.*; import javax.swing.UIManager.*; import javax.swing.event.*; import javax.swing.table.*; public class JTableRowHeader { private JFrame frame = new JFrame("JTable RowHeader"); private JScrollPane scrollPane; private JTable table; private DefaultTableModel model; private TableRowSorter sorter; private JTable headerTable; public JTableRowHeader() { table = new JTable(4, 4); for (int i = 0; i < table.getRowCount(); i++) { table.setValueAt(i, i, 0); } sorter = new TableRowSorter(table.getModel()); table.setRowSorter(sorter); model = new DefaultTableModel() { private static final long serialVersionUID = 1L; @Override public int getColumnCount() { return 1; } @Override public boolean isCellEditable(int row, int col) { return false; } @Override public int getRowCount() { return table.getRowCount(); } @Override public Class getColumnClass(int colNum) { switch (colNum) { case 0: return String.class; default: return super.getColumnClass(colNum); } } }; headerTable = new JTable(model); for (int i = 0; i < table.getRowCount(); i++) { headerTable.setValueAt("Row " + (i + 1), i, 0); } headerTable.setShowGrid(false); headerTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); headerTable.setPreferredScrollableViewportSize(new Dimension(50, 0)); headerTable.getColumnModel().getColumn(0).setPreferredWidth(50); headerTable.getColumnModel().getColumn(0).setCellRenderer(new TableCellRenderer() { @Override public Component getTableCellRendererComponent(JTable x, Object value, boolean isSelected, boolean hasFocus, int row, int column) { boolean selected = table.getSelectionModel().isSelectedIndex(row); Component component = table.getTableHeader().getDefaultRenderer().getTableCellRendererComponent(table, value, false, false, -1, -2); ((JLabel) component).setHorizontalAlignment(SwingConstants.CENTER); if (selected) { component.setFont(component.getFont().deriveFont(Font.BOLD)); component.setForeground(Color.red); } else { component.setFont(component.getFont().deriveFont(Font.PLAIN)); } return component; } }); table.getRowSorter().addRowSorterListener(new RowSorterListener() { @Override public void sorterChanged(RowSorterEvent e) { model.fireTableDataChanged(); } }); table.getSelectionModel().addListSelectionListener(new ListSelectionListener() { @Override public void valueChanged(ListSelectionEvent e) { model.fireTableRowsUpdated(0, model.getRowCount() - 1); } }); scrollPane = new JScrollPane(table); scrollPane.setRowHeaderView(headerTable); table.setPreferredScrollableViewportSize(table.getPreferredSize()); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); frame.add(scrollPane); frame.add(new JButton(new AbstractAction("Toggle filter") { private static final long serialVersionUID = 1L; private RowFilter filter = new RowFilter() { @Override public boolean include(javax.swing.RowFilter.Entry entry) { return ((Number) entry.getValue(0)).intValue() % 2 == 0; } }; @Override public void actionPerformed(ActionEvent e) { if (sorter.getRowFilter() != null) { sorter.setRowFilter(null); } else { sorter.setRowFilter(filter); } } }), BorderLayout.SOUTH); frame.pack(); frame.setLocation(150, 150); frame.setVisible(true); } public static void main(String[] args) { try {// UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) { if (info.getName().equals("Nimbus")) { UIManager.setLookAndFeel(info.getClassName()); break; } } } catch (Exception e) { //e.printStackTrace(); } EventQueue.invokeLater(new Runnable() { @Override public void run() { JTableRowHeader TestTableRowHeader = new JTableRowHeader(); } }); } } 

这是系统外观和感觉 – 在此处输入图像描述