2013-04-08 85 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(); 
    } 

}