2011-04-15 186 views
11

我想创建一个可编辑的表格,然后检查数据以确保其有效。我不知道如何改变一个单元格的颜色。我想获得一个单元格,例如(0,0),并将前景变为红色。我已经阅读了关于自定义ColorRenderer的SO和Oracle的其他文章,但我不明白我会如何使用它。Java JTable更改单元格颜色

谢谢。

回答

17

说你想用不同颜色渲染的单元格代表一个状态(我将以Rejected和Approved为例)。然后,我会在我的表模型中实现一个名为getStatus(int row)的方法,该方法返回任何给定行的状态。

然后,当这个地方,我会去创建一个细胞渲染器负责渲染单元格所属的列。单元格渲染器将在下面的代码行中。

public class StatusColumnCellRenderer extends DefaultTableCellRenderer { 
    @Override 
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) { 

    //Cells are by default rendered as a JLabel. 
    JLabel l = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col); 

    //Get the status for the current row. 
    CustomTableModel tableModel = (CustomTableModel) table.getModel(); 
    if (tableModel.getStatus(row) == CustomTableModel.APPROVED) { 
     l.setBackground(Color.GREEN); 
    } else { 
     l.setBackground(Color.RED); 
    } 

    //Return the JLabel which renders the cell. 
    return l; 

} 

然后,当渲染到位,简单的“应用”渲染到表下面的一段代码:

Table.getColumnModel().getColumn(columnIndex).setCellRenderer(new StatusColumnCellRenderer()); 

关于执行小区可编辑,简单地实现表格模型中的isCellEditable(int rowIndex,int columnIndex)方法。如果您想保留用户提供的值(我假设您这么做!),您还需要实施方法 setValueAt(对象值,int rowIndex,int columnIndex)。

+0

另外:您也可避免实施的getStatus()方法你表模型,如果你喜欢这一点。假设你的表模型的getValueAt(int rowIndex,int columnIndex)以字符串形式返回状态(“APPROVED”,“REJECTED”),那么你可以简单地让渲染检查提供的值[...] RendererComponent(table,value ,布尔型[...]),并根据此更改单元格的颜色。然后,您不需要对表格模型进行“绕行”即可获取当前行/列的状态。这可能实际上是最简单的方法...... – sbrattla 2011-04-15 07:29:47

+0

最后一点小贴士:如果您要为实现getStatus(int row)的解决方案寻求解决方案,那么请确保使用table.convertRowIndexToModel(int row )。提供给getTableCellRendererComponent()的行是视图索引,如果排序由于排序而更改,则该索引可能与模型索引不同。 – sbrattla 2011-04-16 11:52:05

1

最简单的方法是编写一个简单的TableCellRenderer,方法是扩展DefaultTableCellRenderer并将getTableCellRendererComponent方法覆盖为setBackground(Color.RED)。例如:

final JTable table = new JTable(...); 
table.setCellRenderer(new DefaultTableCellRenderer() { 
    public Component getTableCellRenderer(JTable table, Object value, ...) { 
     super.getTableCellRenderer(...); 

     if (value should be highlighted) { 
      setBackground(Color.RED); 
     } 
     return this; 
    } 
}); 
+1

不 - 这是不完整的:DefaultTableCellEditor是一个破碎的实现,它展现了臭名昭着的“色彩内存” - 触摸颜色一次,你必须始终这样做,那就是添加一个分支,如果 – kleopatra 2011-04-30 13:51:44

+0

@kleopatra你是对的,应该有一个'else'将颜色重置为黑色。而且,'JTable'上没有'setCellRenderer'方法,所以这是一个不完整的例子。我的意图是,它将显示OP足够开始沿着正确的道路,他们可以自己学习小细节。 – 2011-05-02 17:16:02

2

我想提出一个可编辑的表格,然后检查数据,以确保其有效。

另一种方法是在保存到表模型之前编辑数据,以防止输入无效数据。

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 
import javax.swing.text.*; 
import javax.swing.event.*; 
import javax.swing.border.*; 
import javax.swing.table.*; 

public class TableEdit extends JFrame 
{ 
    TableEdit() 
    { 
     JTable table = new JTable(5,5); 
     table.setPreferredScrollableViewportSize(table.getPreferredSize()); 

     JScrollPane scrollpane = new JScrollPane(table); 
     getContentPane().add(scrollpane); 

     // Use a custom editor 

     TableCellEditor fce = new FiveCharacterEditor(); 
     table.setDefaultEditor(Object.class, fce); 
    } 

    class FiveCharacterEditor extends DefaultCellEditor 
    { 
     FiveCharacterEditor() 
     { 
      super(new JTextField()); 
     } 

     public boolean stopCellEditing() 
     { 
      try 
      { 
       String editingValue = (String)getCellEditorValue(); 

       if(editingValue.length() != 5) 
       { 
        JTextField textField = (JTextField)getComponent(); 
        textField.setBorder(new LineBorder(Color.red)); 
        textField.selectAll(); 
        textField.requestFocusInWindow(); 

        JOptionPane.showMessageDialog(
         null, 
         "Please enter string with 5 letters.", 
         "Alert!",JOptionPane.ERROR_MESSAGE); 
        return false; 
       } 
      } 
      catch(ClassCastException exception) 
      { 
       return false; 
      } 

      return super.stopCellEditing(); 
     } 

     public Component getTableCellEditorComponent(
      JTable table, Object value, boolean isSelected, int row, int column) 
     { 
      Component c = super.getTableCellEditorComponent(
       table, value, isSelected, row, column); 
      ((JComponent)c).setBorder(new LineBorder(Color.black)); 

      return c; 
     } 

    } 

    public static void main(String [] args) 
    { 
     JFrame frame = new TableEdit(); 
     frame.setDefaultCloseOperation(EXIT_ON_CLOSE); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 
} 
+0

这可能是我正在寻找的,我会给你一个镜头,让你知道。我有一个保存按钮来检查所有数据在保存之前是否有效。我希望能够保存有效的数据并跳过不是的数据。谢谢! – Matt 2011-04-15 17:12:01

1

这是在jTable中为特定列或单元格着色的最简单方法。

首先只需要创建一个简单的类CustomRenderer

class CustomRenderer extends DefaultTableCellRenderer <br /> 
{ 
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) 
    { 
     Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); 
     setForeground(Color.blue); > 
     return c; 
    } 
} 

此代码获取单元格的列来呈现

TableColumn col = tblExamHistoryAll.getColumnModel().getColumn(5); 
DefaultTableModel model3 = (DefaultTableModel)tblExamHistoryAll.getModel(); 
col.setCellRenderer(new CustomRenderer()); 

这是从表中清除所有以前行。如果你不希望他们只是删除这些行

model3.getDataVector().removeAllElements(); 
model3.fireTableDataChanged(); 
+0

-1对于fireXX从外面(想知道是否你是谁与确切的[相同的不正确答案](http://stackoverflow.com/a/13536681/203657) - 同名,新帐户?) – kleopatra 2012-11-25 11:45:54

1

我相信做色表中的正确的方法是通过ColorHighlighter表格渲染器在同一列中呈现不同颜色时遇到问题。

这是一个如何使用荧光笔的例子。在这种情况下,突出显示不可编辑的单元格。

public class IsCellEditablePredicate implements HighlightPredicate { 

private JXTable table; 

public IsCellEditablePredicate (final JXTable table) { 
    this.table = table; 
} 

@Override 
public boolean isHighlighted(Component component, ComponentAdapter componentAdapter) { 

    return !table.isCellEditable(componentAdapter.row, 
      componentAdapter.column); 
} 

}

,然后在你的setuping表的代码添加荧光笔和它的颜色参数:

ColorHighlighter grayHighlighter = new ColorHighlighter(new IsCellEditablePredicate(table)); 

    grayHighlighter.setBackground(Color.LIGHT_GRAY); 
    grayHighlighter.setForeground(table.getForeground()); 
    grayHighlighter.setSelectedBackground(table.getSelectionBackground().darker()); 
    grayHighlighter.setSelectedForeground(table.getSelectionForeground().darker()); 

    table.setHighlighters(grayHighlighter); 
+0

究竟是什么你的意思是你的句子加粗?你能举个例子吗? – jaivalis 2016-04-01 11:19:00