2017-09-24 114 views
1

如果我使用以下方法来显示一个JTable:添加行为到默认的JTable单元格渲染器

package jtable.fontsize; 
import java.awt.BorderLayout; 
import java.awt.Font; 
import java.lang.reflect.InvocationTargetException; 

import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.SwingUtilities; 

import rcutil.swing.table.LastColumnChangesWidthJTable; 


public class JTableCellPlay extends JFrame 
{ 
    public JTableCellPlay() 
    { 
    super("setting Table font size"); 
    setDefaultCloseOperation(EXIT_ON_CLOSE); 
    } 

    public static void main(String ... arguments) throws InvocationTargetException, InterruptedException 
    { 
    JTableCellPlay mainScreen = new JTableCellPlay(); 
    mainScreen.go(); 
    } 

    public void go() throws InvocationTargetException, InterruptedException 
    { 
    SwingUtilities.invokeAndWait(new Runnable() { public void run() { createScreen(); } }); 
    setVisible(true); 
    } 

    public void createScreen() 
    { 
    LastColumnChangesWidthJTable aLittleJTable = new LastColumnChangesWidthJTable(new LittleTableModel()); 
    aLittleJTable.setDefaultRenderer(Integer.class, new IntegerCellRenderer()); 
    JScrollPane scrollPane = new JScrollPane(aLittleJTable); 
    add(scrollPane, BorderLayout.CENTER); 
    pack(); 
    } 
} 

与以下渲染:

package jtable.fontsize; 

import java.awt.Color; 
import java.awt.Component; 

import javax.swing.JLabel; 
import javax.swing.JTable; 
import javax.swing.table.TableCellRenderer; 


public class IntegerCellRenderer extends JLabel implements TableCellRenderer 
{ 
    @Override 
    public Component getTableCellRendererComponent 
         (JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) 
    { 
    String resultString = String.format("~%d~", (Integer)value); 
    setText(resultString); 
    setHorizontalAlignment(JLabel.CENTER); 
// if (isSelected) 
// { 
//  setOpaque(true); // evidently necessary for JLabel as a component in a JTable cell 
//  setBackground(Color.GRAY); 
// } 
    return this; 
    } 
} 

和下面的模型(让你的代码跑,是的,我知道有其他方法可以做到这部分):

package jtable.fontsize; 

import javax.swing.table.AbstractTableModel; 

public class LittleTableModel extends AbstractTableModel 
{ 
    public Class<? extends Object> getColumnClass(int column) 
    { 
    Class<? extends Object> c = null; 
    switch (column) 
    { 
    case 0: c = String.class; break; 
    case 1: c = Integer.class; break; 
    case 2: c = String.class; break; 
    } 
    return c; 
    } 

    String[] columnNames = { "first", "second", "third" }; 
    Object[][] data = { { "one", 2, "three" }, { "four", 5, "six" } }; 

    public int getColumnCount() { return 3; } 
    public int getRowCount() { return 2; } 
    public String getColumnName(int index) { return columnNames[index]; } 

    public Object getValueAt(int row, int column) 
    { 
    Object result = data[row][column]; 
    return result; 
    } 
} 

然后,当我选择行之一,与两个STR列会得到高亮选择,但“整数”列不会。

如果我注释掉设置“整数”渲染器的那一行,然后单击一行就会按预期选择整行。

我知道我可以使用渲染器中的注释行来突出显示单元格,添加setOpaque(true)setBackground(Color),甚至可以玩游戏来获取选定和未选择的背景颜色,但我怀疑有一些方法可以使用最初用于这类事情的相同渲染器,并只使用渲染器中的代码来完成我需要做的特殊工作。有人可以解释这是如何工作的?

+0

几种方法被建议在[*当选择高亮显示单元行*](https://stackoverflow.com/q/32301649/230513)。 – trashgod

回答

1

为什么不简单地给你的渲染器一个别的块,你撤销在块中做出的改变?

if (isSelected) { 
    setOpaque(true); 
    setBackground(Color.GRAY); 
} else { 
    setOpaque(false); // allow underlying color to show 
    setBackground(null); // no color added 
} 

或者另一种选择是让你的渲染器类扩展DefaultTableCellRenderer而不是执行的TableCellRenderer,让您使用的默认渲染的先天突出能力:

@SuppressWarnings("serial") 
class IntegerCellRenderer2 extends DefaultTableCellRenderer { 
    @Override 
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, 
      int row, int column) { 
     String resultString = String.format("~%d~", (Integer) value); 
     setText(resultString); 
     setHorizontalAlignment(JLabel.CENTER); 
     return super.getTableCellRendererComponent(table, resultString, isSelected, hasFocus, row, column); 
    } 
} 

注意,您可以设置一些属性渲染器的构造函数中。例如:

@SuppressWarnings("serial") 
class IntegerCellRenderer2 extends DefaultTableCellRenderer { 
    public IntegerCellRenderer2() { 
     setHorizontalAlignment(JLabel.CENTER); 
    } 

    @Override 
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, 
      int row, int column) { 
     String resultString = String.format("~%d~", (Integer) value); 
     setText(resultString); 
     // setHorizontalAlignment(JLabel.CENTER); 
     return super.getTableCellRendererComponent(table, resultString, isSelected, hasFocus, row, column); 
    } 
} 
+0

嗯,我不知道不透明的设置和背景是什么,先验,不仅仅是我知道选择颜色是灰色的。正如我所说,我知道我可以打电话来了解这些是什么,但我想知道更好的方法。你的第二个方法似乎工作,但它似乎对我来说是狡猾 - 如果默认渲染器设置对齐?我不喜欢在我的课上有代码,这取决于它的超类的内部。 – arcy

+0

@arcy:你想要做什么? –

+0

@arcy;如果你使用默认渲染器,你可以很容易地查询超级组件的背景状态和不透明属性状态,但是,最终你会怎么做呢? –