2014-10-02 42 views
2

我想創建一個JTable和(在着色細胞漂亮Excel等)永久上色它的細胞通過一個按鈕的點擊。到目前爲止,每一個細胞我選擇,它會在ArrayList<Cell>JTable中色細胞永久當我點擊按鈕

首先,我要對列表中的每一個細胞,當我點擊按鈕(這是從代碼的區別,我發現)被永久着色。我必須使用像這樣的statememnt table.getColumnModel().getColumn(column).setCellRenderer(this);

這是一個編譯代碼,如果你調試它,你會看到,當點擊按鈕時,我無法訪問getTableCellRendererComponent()方法。爲什麼會發生?如果你能告訴我你的意見,我將不勝感激。

(注:這是一個巨大的程序的複製,所以這是一個有點大混亂和硬編碼在一些地方不能讓它爲我想解決小)。

類ColorSelectedTableCells.java

public class ColorSelectedTableCells extends JPanel { 
    private JButton btn = new JButton("color cells"); 
    private MyCellRenderer myCellRenderer = new MyCellRenderer(); 
    public static final Object[][] DATA = new Object[3][3]; 
    public static final String[] COLS = {"A", "B", "C"}; 
    private static final int PREF_WIDTH = 400; 
    private static final int PREF_HEIGHT = 300; 
    private static CellSelectionSet cellSelectionSet = new CellSelectionSet(); 

    private JTable table = new JTable(DATA,COLS){ 
     @Override 
     public boolean isCellEditable(int row, int column) {return false;} 

     @Override 
     public boolean isCellSelected(int row, int column) { 
      if (cellSelectionSet.containsOneOrLess()) { 
      return super.isCellSelected(row, column); 
      } 
      return cellSelectionSet.contains(row, column); 
     } 

     @Override 
     public void changeSelection(int rowIndex, int columnIndex, boolean toggle, boolean extend) { 
      super.changeSelection(rowIndex, columnIndex, toggle, extend); 
      if (toggle) { 
      cellSelectionSet.add(rowIndex, columnIndex); 
      } 
      else { 
      if (extend) { 
       cellSelectionSet.add(rowIndex, columnIndex); 
      } 
      else { 
       cellSelectionSet.clear(); 
       cellSelectionSet.add(rowIndex, columnIndex); 
      } 
      } 
     } 
     }; 

public ColorSelectedTableCells() { 
    table.setDefaultRenderer(Integer.class, myCellRenderer); 
    table.setCellSelectionEnabled(true); 
    table.setColumnSelectionAllowed(false); 
    table.setRowSelectionAllowed(false); 

    JScrollPane scrollPane = new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); 
    JPanel btnPanel = new JPanel(); 
    btnPanel.add(btn); 

    setLayout(new BorderLayout()); 
    add(scrollPane, BorderLayout.CENTER); 
    add(btnPanel, BorderLayout.SOUTH); 

    btn.addActionListener(new ActionListener() { 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     myCellRenderer.setShowSelected(true); 
     table.repaint(); 
    } 
    }); 
} 

@Override 
public Dimension getPreferredSize() { 
    return new Dimension(PREF_WIDTH, PREF_HEIGHT); 
} 

private static void createAndShowUI() { 
    JFrame frame = new JFrame(); 
    frame.getContentPane().add(new ColorSelectedTableCells()); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.pack(); 
    frame.setLocationRelativeTo(null); 
    frame.setVisible(true); 
} 

public static void main(String[] args) { 
    java.awt.EventQueue.invokeLater(new Runnable() { 
    public void run() { 
     createAndShowUI(); 
    } 
    }); 
} 

類MyCellRenderer.java

private static class MyCellRenderer extends DefaultTableCellRenderer { 
    private boolean showSelected = false; 
    private byte colorSwitcher; 

    public void setShowSelected(boolean showSelected) { 
    this.showSelected = showSelected; 
    } 

    public void setColorSwitcher(byte colorSwitcher){ 
     this.colorSwitcher = colorSwitcher; 
    } 

    @Override 
    public Component getTableCellRendererComponent(JTable table,Object value, boolean isSelected, boolean hasFocus, int row,int column) { 
    Component superComponent = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); 

     if(showSelected && table.isCellSelected(row, column)){ 
     superComponent.setBackground(Color.GREEN); 
     } 
     else if (table.isCellSelected(row, column)){ 
     superComponent.setBackground(table.getSelectionBackground()); 
     } 
     else { 
     superComponent.setBackground(table.getBackground()); 
     } 
     return superComponent; 
    } 
    } 
} 

類cellSelectionSet.java

public class CellSelectionSet { 
    private List<Cell> cells = new ArrayList<>(); 

    public void add(int r, int c) { 
    if (!contains(r, c)) { 
     cells.add(new Cell(r, c)); 
    } 
    } 

    public boolean containsOneOrLess() { 
    return cells.size() <= 1; 
    } 

    public boolean contains(int r, int c) { 
    for (Cell cell : cells) { 
     if (cell.is(r, c)) { 
      return true; 
     } 
    } 
    return false; 
    } 

    public Cell getElementAt(int i){ 
    return cells.get(i); 
    } 

    public int getSize(){ 
    return this.cells.size(); 
    } 

    public void clear() { 
    cells.clear(); 
    System.out.println("CellSelectionSet cleared."); 
    } 
} 

類Cell.java

public class Cell { 
    private int row, column; 

    public Cell(int row, int column){ 
    this.row = row; 
    this.column = column; 
    } 

    public boolean is(int r, int c) { 
    return row == r && column == c; 
    } 
} 

回答

2

主要問題:

table.setDefaultRenderer(Integer.class, myCellRenderer); 

應該

table.setDefaultRenderer(Object.class, myCellRenderer); 

這將讓你的細胞改變顏色。但你有一個地方後按下按鈕,您選擇的每個單元格設置爲true,自動改變顏色,因爲showSelected財產的問題。誰知道,也許這就是你想要的。

也是另一個問題是與細胞停留在選擇的顏色。如果您的支票陳述存在問題

if(showSelected && table.isCellSelected(row, column)){ 

一旦您做出更多選擇,原始選擇將被清除。一個解決辦法是檢查CellSelectionSet以查看它是否包含該單元格,還要檢查它是否是新選定的。像

if (cellSelectionSet.contains(row, column) 
        && !cellSelectionSet.getCellAt(row, column).isNewlySelected()) 

東西,我在Cell類添加一個方法getCellAtCellSelectionSet

public Cell getCellAt(int row, int column) { 
    Cell c = null; 
    for (Cell cell : cells) { 
     if (cell.is(row, column)) { 
      c = cell; 
     } 
    } 
    return c; 
} 

,也是一個標誌,檢查是否是newlySelected

class Cell { 

    private boolean newlySelected = true; 

    public boolean isNewlySelected() { 
     return newlySelected; 
    } 

    public void setNewlySelected(boolean newlySelected) { 
     this.newlySelected = newlySelected; 
    } 
} 

當你第一次增加該小區,將新選擇,並不會呈現不同的顏色,默認是真實的,因爲它沒有通過檢查

!cellSelectionSet.getCellAt(row, column).isNewlySelected() 

但是,當你按下該按鈕,您遍歷列表並將所有單元格newlySelected設置爲false。

public void actionPerformed(ActionEvent e) { 
    //myCellRenderer.setShowSelected(true); 
    for (int i = 0; i < cellSelectionSet.getSize(); i++) { 
     cellSelectionSet.getElementAt(i).setNewlySelected(false); 
    } 
    table.repaint(); 
} 
+0

你救我!但現在我有另一個問題..選定的單元格會改變顏色,但是當我選擇另一個單元格時,所有預先返回到白色(「未選中」)。你能告訴我,我怎麼解決這個問題? – 2014-10-02 16:19:14

+0

查看我的更新。我認爲它的工作原理就像你想要的不是 – 2014-10-02 16:33:03

+0

當我選擇另一個單元格時,單元格仍然會返回「unselected」..我應該更改if中的標誌if(cellSelectionSet.contains(row,column)&&!cellSelectionSet.getCellAt(row,column ).isNewlySelected())'語句? – 2014-10-02 16:46:37