2013-04-08 83 views
0

我已经尝试了一段时间,并通过互联网寻找解决方案,但我失败了。 我想要做的是动态地改变Jtable的行背景。 我创建的ArrayList这使选择行(添加他们每次用户按ALT +单击单元格) 的数量并以我个人的TableCellRenderer我已经加入Jtable cellRenderer更改背景行

for(Integer c: leftSelectedCells){ 
if(c.equals(row)){comp.setForeground(Color.red); } 
else { comp.setForeground(Color.black);} 
} 

这是工作,对于少数细胞,或一些时间后,选定的列都回到他们的阴道颜色,我已经检查,整数仍然在阵列中,所以这不是问题,任何想法可能会导致问题?

+2

您需要为每种能够提供所需功能的列类型提供TableCellRenderes。查看[如何使用表格](http://docs.oracle.com/javase/tutorial/uiswing/components/table.html)以获取更多详细信息 – MadProgrammer 2013-04-08 20:55:00

+1

只是一般性建议,但通常是CTRL(不是ALT)是修饰符键用于多选。 – rob 2013-04-09 08:33:42

+0

在这种情况下,最好使用JTable.setDefaultCellRenderer,而不是按列设置呈示器。另外:你说你想改变行背景,但你的示例代码设置前景。在我的回答中,我已经在设置前景方面跟随您的领先优势,但是您可以轻松修改它以设置背景,如果确实如此,那就是您想要的。 – rob 2013-04-09 09:03:26

回答

2

正如上面评论中提到的,您需要为所有需要的列提供自定义渲染器。作为替代,您可以覆盖JTable.prepareRenderer根据受影响的行列表设置背景。 @camickr的Table Row Rendering解释了这种方法。下面是一个例子,突出显示用鼠标点击的行+ Alt键。为了简单起见,突出显示的行列表保留为客户端属性。

import java.awt.Color; 
import java.awt.Component; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.util.ArrayList; 
import java.util.List; 

import javax.swing.*; 
import javax.swing.table.DefaultTableModel; 
import javax.swing.table.TableCellRenderer; 

public class TableHighlight { 
    TableHighlight() { 
     JFrame frame = new JFrame("TableHighlight"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     Object[][] data = { { "Column 1", "Column 2" }, 
       { "Column 1", "Column 2" }, { "Column 1", "Column 2" }, 
       { "Column 1", "Column 2" } }; 

     Object[] columnNames = { "Column 1", "Column 2" }; 

     DefaultTableModel model = new DefaultTableModel(data, columnNames); 

     final JTable table = new JTable(model) { 
      @Override 
      public Component prepareRenderer(TableCellRenderer renderer, 
        int row, int column) { 
       Component c = super.prepareRenderer(renderer, row, column); 
       List<Integer> selectedRows = (List<Integer>) getClientProperty("highlightRows"); 
       c.setBackground(selectedRows.contains(row) ? Color.cyan : getBackground()); 
       return c; 
      } 
     }; 

     table.putClientProperty("highlightRows", new ArrayList<Integer>()); 

     table.addMouseListener(new MouseAdapter() { 
      @Override 
      public void mouseClicked(MouseEvent evt) { 
       if (!evt.isAltDown()) 
        return; 
       int row = table.rowAtPoint(evt.getPoint()); 
       if (row == -1) 
        return; 
       List<Integer> selectedRows = (List<Integer>) table 
         .getClientProperty("highlightRows"); 
       int index = selectedRows.indexOf(row); 
       if (index != -1) 
        selectedRows.remove(index); 
       else 
        selectedRows.add(row); 
       table.repaint(); 
      } 
     }); 

     frame.add(new JScrollPane(table)); 
     frame.setLocationByPlatform(true); 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    public static void main(String args[]) { 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       new TableHighlight(); 
      } 
     }); 
    } 
} 
1

我建议使用CTRL进行多选而不是ALT。首先,任何想要多重选择的用户都已经知道如何去做,因为CTRL是多重选择的事实上的标准修饰键。其次,您可以免费获得所需的行为,而无需实施任何特殊的功能(可能除外,您的首选配色方案)。

package com.example.table.multiselect; 

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

import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.table.DefaultTableCellRenderer; 
import javax.swing.table.DefaultTableModel; 
import javax.swing.table.TableCellRenderer; 

public class MultiRowTableSelect extends JFrame { 

    public MultiRowTableSelect() { 
     DefaultTableModel model = new DefaultTableModel(0, 3); 
     model.addRow(new Integer[]{1, 2, 3}); 
     model.addRow(new Integer[]{4, 5, 6}); 
     model.addRow(new Integer[]{7, 8, 9}); 
     model.addRow(new Integer[]{10, 11, 12}); 

     JTable tbl = new JTable(model); 
     tbl.setRowSelectionAllowed(true); // when you click a cell, the entire row will be highlighted 

     /* Assuming you want all cells to be rendered using the custom renderer 
     * unless otherwise overridden, you can simply set the JTable's default 
     * renderer. The implementation is so simple here that I'm just 
     * creating an anonymous subclass of DefaultTableCellRenderer. 
     */ 
     tbl.setDefaultRenderer(Object.class, new DefaultTableCellRenderer() { 
      @Override 
      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); 

       if (isSelected) { 
        c.setForeground(Color.RED); // you can set the foreground and/or background here 
       } 

       return c; 
      } 
     }); 

     add(new JScrollPane(tbl), BorderLayout.CENTER); 

     setDefaultCloseOperation(EXIT_ON_CLOSE); 
     setLocationByPlatform(true); 
     pack(); 
     setSize(400, 200); 
     setVisible(true); 
    } 


    /** 
    * @param args 
    */ 
    public static void main(String[] args) { 
     new MultiRowTableSelect(); 
    } 

}