问题描述
即使我通过@kleopatra阅读和测试答案
-
的$ b
import java.awt。*;
import java.awt.event。*;
import javax.swing。*;
import javax.swing.table。*;
公共类SelectedTableHeader {
private JFrame frame = new JFrame(Table Demo);
私有JTableHeader头;
private Object selectedColumn = null;
private String [] columnNames = {String,Integer,Float,Double,Locale& Double,Boolean};
private Object [] [] data = {
{aaa,new Integer(12),new Float(12.15),new Double(100.05),new Double(12.05),true},
{bbb,new Integer(5),new Float(7.154),new Double(6.1555),new Double(417.55),false},
{CCC,new Integer(92), new Float(0.1135),new Double(3.1455),new Double(11.05),true},
{ddd,new Integer(12),new Float(31.15),new Double(10.05),new Double (23.05),true},
{eee,new Integer(5),new Float(5.154),new Double(16.1555),new Double(17.55),false},
{fff ,new Integer(92),new Float(4.1135),new Double(31.1455),new Double(3.05),true}};
private TableModel model = new DefaultTableModel(data,columnNames){
private static final long serialVersionUID = 1L;
@Override
public Class<?> getColumnClass(int column){
return getValueAt(0,column).getClass();
}
};
private JTable table = new JTable(model);
public SelectedTableHeader(){
header = table.getTableHeader();
header.addMouseListener(new MouseAdapter(){
@Override
public void mouseClicked(MouseEvent e){
JTableHeader h =(JTableHeader)e.getSource() ;
int i = h.columnAtPoint(e.getPoint());
Object o = h.getColumnModel()。getColumn(i).getHeaderValue();
if(i< 0){
selectedColumn = null;
return;
}
selectedColumn = o;
h.requestFocusInWindow();
}
} );
final TableCellRenderer hr = table.getTableHeader()。getDefaultRenderer();
header.setDefaultRenderer(new TableCellRenderer(){
private JLabel lbl;
@Override
public Component getTableCellRendererComponent(
JTable table,对象值,boolean isSelected,boolean hasFocus,int row,int column){
if(selectedColumn == value){
lbl =(JLabel)hr.getTableCellRendererComponent(table,value,true,true,row ,列);
lbl.setBorder(BorderFactory.createCompoundBorder(lbl.getBorder(),BorderFactory.createLineBorder(Color.red,1)));
lbl.setHorizontalAlignment(SwingConstants.LEFT);
} else {
lbl =(JLabel)hr.getTableCellRendererComponent(table,value,false,false,row,column);
lbl.setBorder(BorderFactory.createCompoundBorder(lbl.getBorder(),BorderFactory .createEmptyBorder(0,5,0,0)));
lbl.setHorizontalAlignment(SwingConstants.CENTER);
}
if(column == 0){
lbl.setForeground(Color.red);
} else {
lbl.setForeground(header.getForeground());
}
/ * return(value == selectedColumn)? hr.getTableCellRendererComponent(
table,value,true,true,row,column):hr.getTableCellRendererComponent(
table,value,false,false,row,column); * /
return lbl ;
}
});
table.setRowHeight(20);
table.setPreferredScrollableViewportSize(table.getPreferredSize());
JScrollPane scroll = new JScrollPane(table);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(scroll);
frame.pack();
frame.setLocation(150,150);
frame.setVisible(true);
}
public static void main(String [] args){
EventQueue.invokeLater(new Runnable(){
@Override
public void run(){
SelectedTableHeader selectedTableHeader = new SelectedTableHeader();
}
});
}
}
解决方案In根据我的经验,当你覆盖任何
JTable
Renderer $时,最好获得
DefaultTableCellHeaderRenderer
C $ C>。因此,不要直接从Renderer
中弄乱JLabel
,而是抓住Renderer
withsuper()
。因此,您的代码应如下所示:header.setDefaultRenderer(new DefaultTableCellHeaderRenderer(){
@Override
public Component getTableCellRendererComponent(
JTable table,Object value,boolean isSelected,boolean hasFocus,int row,int column){
DefaultTableCellHeaderRenderer rendererComponent =(DefaultTableCellHeaderRenderer)super.getTableCellRendererComponent (table,value,isSelected,hasFocus,row,column);
if(selectedColumn == value){
rendererComponent.setBorder(BorderFactory.createCompoundBorder(rendererComponent.getBorder(),BorderFactory。 createLineBorder(Color.red,1)));
rendererComponent.setHorizontalAlignment(SwingConstants.LEFT);
} else {
rendererComponent.setBorder(BorderFactory.createCompoundBorder(rendererComponent.getBorder(),BorderFactory .createEmptyBorder(0,5,0,0)));
rendererC omponent.setHorizontalAlignment(SwingConstants.CENTER);
}
if(column == 0){
rendererComponent.setForeground(Color.red);
} else {
rendererComponent.setForeground(header.getForeground());
}
返回rendererComponent;
}
});
尝试直接回答您的问题:
问题1:
问:如何正确使用客户渲染器绘制JTable中的特定单元?
答:您当前的代码是在
JTableHeader
上设置Renderer
。要在表格单元格上添加渲染器,代码与上面的代码类似,只需通过Column模型设置:table.getColumnModel()。getColumn(0).setCellRenderer(new DefaultTableCellRenderer(){
@Override
public Component getTableCellRendererComponent(JTable table,Object value,boolean isSelected,boolean hasFocus,int row,int column ){
DefaultTableCellRenderer renderer =(DefaultTableCellRenderer)super.getTableCellRendererComponent(table,value,isSelected,hasFocus,row,column);
//设置代码以渲染组件。
返回渲染器;
}
});
注意:
JTables
是列 - 基于,这意味着某列中的所有数据必须是相同的类型(您的SSCCE遵循此约定)。我最喜欢的是为每种类型提供自定义Renderer
。例如,每当我有一个Date
列时,我就会使用这个渲染器:import java.awt.Component;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import org.joda.time.LocalDate;
/ **
*
* @author Ryan
* /
公共类DateCellRenderer extends DefaultTableCellRenderer {
String pattern ;
public DateCellRenderer(String pattern){
this.pattern = pattern;
}
@Override
public Component getTableCellRendererComponent(JTable table,Object value,boolean isSelected,boolean hasFocus,int row,int column){
DefaultTableCellRenderer renderer =( DefaultTableCellRenderer)super.getTableCellRendererComponent(table,value,isSelected,hasFocus,row,column);
if(value!= null&& value instanceof LocalDate){
renderer.setText(((LocalDate)value)。toString(pattern));
} else
抛出新的IllegalArgumentException(仅支持的对象类型是LocalDate。);
返回渲染器;
}
}
我用类似的代码调用此代码:
table.getColumn(Date Entered)。setCellRenderer(new DateCellRenderer(MMM dd,yyyy));
问题2:
问:特别是一个表头颜色java swing
A:嗯..你的SSCCE好像已经弄清楚了。
问题3:
问:关于super.getTableCellRendererComponent(...)必须是返回前的最后一行代码行,我不能通过这些建议写出正确的渲染器,因为我只能这样工作
A:我不确定你的意思必须是最后一个代码退货前的一行。事实并非如此,我上面给出的代码片段证实了这一点
问题4:
问:为Borders,HorizontalAlignment和Foreground添加了JLabel,特别是背景通过使用Component而不是JLabel引起了一些非句子,(在某种程度上不重要)
A:好的......
DefaultTableCellHeaderRenderer
足以满足所有这些,边框,路线,前景和背景。Even I read and test answers by @kleopatra
How do I correctly use customer renderers to paint specific cells in a JTable?
about
super.getTableCellRendererComponent(...)
must be last code line before returns, I'm not able to write correct Renderer by those suggestion, for me works only this wayJLabel
is added for Borders, HorizontalAlignment and Foreground, especially Background caused me a few non_senses by using Component instead ofJLabel
, (not important here somehow)
from SSCCE
import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.table.*; public class SelectedTableHeader { private JFrame frame = new JFrame("Table Demo"); private JTableHeader header; private Object selectedColumn = null; private String[] columnNames = {"String", "Integer", "Float", "Double", "Locale & Double", "Boolean"}; private Object[][] data = { {"aaa", new Integer(12), new Float(12.15), new Double(100.05), new Double(12.05), true}, {"bbb", new Integer(5), new Float(7.154), new Double(6.1555), new Double(417.55), false}, {"CCC", new Integer(92), new Float(0.1135), new Double(3.1455), new Double(11.05), true}, {"ddd", new Integer(12), new Float(31.15), new Double(10.05), new Double(23.05), true}, {"eee", new Integer(5), new Float(5.154), new Double(16.1555), new Double(17.55), false}, {"fff", new Integer(92), new Float(4.1135), new Double(31.1455), new Double(3.05), true}}; private TableModel model = new DefaultTableModel(data, columnNames) { private static final long serialVersionUID = 1L; @Override public Class<?> getColumnClass(int column) { return getValueAt(0, column).getClass(); } }; private JTable table = new JTable(model); public SelectedTableHeader() { header = table.getTableHeader(); header.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { JTableHeader h = (JTableHeader) e.getSource(); int i = h.columnAtPoint(e.getPoint()); Object o = h.getColumnModel().getColumn(i).getHeaderValue(); if (i < 0) { selectedColumn = null; return; } selectedColumn = o; h.requestFocusInWindow(); } }); final TableCellRenderer hr = table.getTableHeader().getDefaultRenderer(); header.setDefaultRenderer(new TableCellRenderer() { private JLabel lbl; @Override public Component getTableCellRendererComponent( JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { if (selectedColumn == value) { lbl = (JLabel) hr.getTableCellRendererComponent(table, value, true, true, row, column); lbl.setBorder(BorderFactory.createCompoundBorder(lbl.getBorder(), BorderFactory.createLineBorder(Color.red, 1))); lbl.setHorizontalAlignment(SwingConstants.LEFT); } else { lbl = (JLabel) hr.getTableCellRendererComponent(table, value, false, false, row, column); lbl.setBorder(BorderFactory.createCompoundBorder(lbl.getBorder(), BorderFactory.createEmptyBorder(0, 5, 0, 0))); lbl.setHorizontalAlignment(SwingConstants.CENTER); } if (column == 0) { lbl.setForeground(Color.red); } else { lbl.setForeground(header.getForeground()); } /*return (value == selectedColumn) ? hr.getTableCellRendererComponent( table, value, true, true, row, column) : hr.getTableCellRendererComponent( table, value, false, false, row, column);*/ return lbl; } }); table.setRowHeight(20); table.setPreferredScrollableViewportSize(table.getPreferredSize()); JScrollPane scroll = new JScrollPane(table); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(scroll); frame.pack(); frame.setLocation(150, 150); frame.setVisible(true); } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { SelectedTableHeader selectedTableHeader = new SelectedTableHeader(); } }); } }
解决方案In my experience, it's better to get the
DefaultTableCellHeaderRenderer
when you overwrite anyJTable
Renderer
. So, instead of messing with theJLabel
from theRenderer
directly, you grab theRenderer
withsuper()
. So, your code should look like this:header.setDefaultRenderer(new DefaultTableCellHeaderRenderer() { @Override public Component getTableCellRendererComponent( JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { DefaultTableCellHeaderRenderer rendererComponent = (DefaultTableCellHeaderRenderer)super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); if (selectedColumn == value) { rendererComponent.setBorder(BorderFactory.createCompoundBorder(rendererComponent.getBorder(), BorderFactory.createLineBorder(Color.red, 1))); rendererComponent.setHorizontalAlignment(SwingConstants.LEFT); } else { rendererComponent.setBorder(BorderFactory.createCompoundBorder(rendererComponent.getBorder(), BorderFactory.createEmptyBorder(0, 5, 0, 0))); rendererComponent.setHorizontalAlignment(SwingConstants.CENTER); } if (column == 0) { rendererComponent.setForeground(Color.red); } else { rendererComponent.setForeground(header.getForeground()); } return rendererComponent; } });
To try and answer your questions directly:
Question 1:
Q: How do I correctly use customer renderers to paint specific cells in a JTable?
A: Your current code is setting a
Renderer
on theJTableHeader
. To add a Renderer on your table cells would be similar code to what's above, only you'd set it through the Column model:table.getColumnModel().getColumn(0).setCellRenderer(new DefaultTableCellRenderer() { @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { DefaultTableCellRenderer renderer = (DefaultTableCellRenderer)super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); // Set your code to render your component. return renderer; } });
Note about this:
JTables
are column-based, which means that all the data in a certain column must be the same type (your SSCCE follows this convention). My favorite thing to do is to provide a customRenderer
for each type. For example, whenever I have aDate
column, I use this renderer:import java.awt.Component; import javax.swing.JTable; import javax.swing.table.DefaultTableCellRenderer; import org.joda.time.LocalDate; /** * * @author Ryan */ public class DateCellRenderer extends DefaultTableCellRenderer { String pattern; public DateCellRenderer(String pattern){ this.pattern = pattern; } @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { DefaultTableCellRenderer renderer = (DefaultTableCellRenderer)super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); if (value != null && value instanceof LocalDate) { renderer.setText(((LocalDate)value).toString(pattern)); } else throw new IllegalArgumentException("Only supported Object type is LocalDate."); return renderer; } }
And I call this code with something similar:
table.getColumn("Date Entered").setCellRenderer(new DateCellRenderer("MMM dd, yyyy"));
Question 2:
Q: particular one table header color java swing
A: Umm.. Your SSCCE seems to have it figured out.
Question 3:
Q: about super.getTableCellRendererComponent(...) must be last code line before returns, I'm not able to write correct Renderer by those suggestion, for me works only this way
A: I'm not sure what you mean "must be last code line before returns." That is not the case, proven by the code snip I gave above
Question 4:
Q: JLabel is added for Borders, HorizontalAlignment and Foreground, especially Background caused me a few non_senses by using Component instead of JLabel, (not important here somehow)
A: Ok... the
DefaultTableCellHeaderRenderer
is sufficient for all of those, borders, alignment, foreground and background.这篇关于如何使用Renderer for TableHeader的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!