尝试使用正确的行标题创建 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中的一个例子,它具有正确样式的行和列标题,它们甚至在鼠标悬停时都会使单元格变蓝。太糟糕了,它不是用Java制作的,所以我可以尝试检查他们是如何做到的。
MySQL Workbench screenshot-
编辑下面 编辑下面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);
}
}