2013-03-08 102 views
1

我在這裏有兩列(JTable)。右欄是可編輯的,而另一欄不是。JTable valuechanged然後更改單元格顏色

所以,我的問題是,無論何時用戶更改單元格的值,該特定單元格將更改其單元格顏色。

我想這樣做是因爲我想讓用戶知道他/她在表格中進行了一些更改。

我發現這個地方,它以某種方式解決了我的問題,但有一件事沒有出現我的期望是更改值並單擊另一個單元格後,顏色變回原來的顏色。我想讓它保持直到它被保存。

@Override 
public Component prepareEditor(TableCellEditor editor, int data, int columns) { 
    Component c = super.prepareEditor(editor, data, columns); 
    c.setBackground(Color.RED); 
    return c; 
} 

這可能嗎?如果是,請舉例說明。

UPDATE:

String[] columnname = {"Student Name", "Grade"}; 

    Object[][] data = {}; 

    gradetable = new JTable(data, columnname){ 
     private Object[][] rowData; 

     public boolean isCellEditable(int data, int columns){ 
      return columns == 1; 
     } 


     public Component prepareRenderer(TableCellRenderer r, int data, int columns){ 
      final Component c = super.prepareRenderer(r, data, columns); 

      if (data % 2 == 0){ 
       c.setBackground(Color.LIGHT_GRAY); 
      } 
      else{ 
       c.setBackground(Color.WHITE); 
      } 

      if (isCellSelected(data, columns)){ 
       c.setBackground(Color.ORANGE); 
      }     

      return c; 
     } 

     @Override 
     public Component prepareEditor(TableCellEditor editor, int data, int columns) { 
      Component c = super.prepareEditor(editor, data, columns); 
      c.setBackground(Color.RED); 
      return c; 
     } 
    }; 

    gradetable.setModel(new DefaultTableModel(data, columnname)); 
    gradetable.setPreferredScrollableViewportSize(new Dimension (350, 130)); 
    gradetable.setFillsViewportHeight(true); 
    gradetable.getTableHeader().setReorderingAllowed(false); 
    gradetable.setGridColor(new Color(128,128,128,128)); 
    JScrollPane jsp = new JScrollPane(gradetable); 
    panel3.add(jsp); 

回答

4

表使用TableCellRenderer在屏幕上繪製值。編輯和渲染者實際上並沒有任何關係(從繪畫的角度來看)。

所以一旦編輯器已經被駁回(接受或取消),電池使用分配TableCellRenderer

您需要提供,該表格的模式,一些方法來確定哪些行已被更新和變化粉刷渲染器的狀態匹配。

FYI- DefaultTableCellRenderer使用JLabel作爲基礎渲染器,所以默認情況下它是透明的;您需要使其不透明才能正確渲染。

退房Using custom renderers更多細節

與例如

更新這無非是那麼概念的證明。它不會滿足你的絕對要求,你應該認真看看上面鏈接的教程。

Example image

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Component; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.util.ArrayList; 
import java.util.List; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 
import javax.swing.table.AbstractTableModel; 
import javax.swing.table.DefaultTableCellRenderer; 
import javax.swing.table.DefaultTableModel; 
import javax.swing.table.TableColumnModel; 
import javax.swing.table.TableModel; 

public class TableEdit { 

    public static void main(String[] args) { 
     new TableEdit(); 
    } 

    public TableEdit() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     public TestPane() { 
      setLayout(new BorderLayout()); 
      JTable table = new JTable(new MyTableModel()); 
      table.setSurrendersFocusOnKeystroke(true); 
      TableColumnModel model = table.getColumnModel(); 
      model.getColumn(1).setCellRenderer(new MyTableCellRenderer()); 
      add(new JScrollPane(table)); 
     } 

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

    public class MyData { 

     private String key; 
     private String value; 
     private boolean changed; 

     public MyData(String key, String value) { 
      this.key = key; 
      this.value = value; 
      this.changed = false; 
     } 

     public String getKey() { 
      return key; 
     } 

     public String getValue() { 
      return value; 
     } 

     public void setValue(String newValue) { 
      if (value == null ? newValue != null : !value.equals(newValue)) { 
       value = newValue; 
       changed = true; 
      } 
     } 

     public boolean hasChanged() { 
      return changed; 
     } 
    } 

    public class MyTableModel extends AbstractTableModel { 

     private List<MyData> data; 

     public MyTableModel() { 
      data = new ArrayList<>(25); 
      for (int index = 0; index < 5; index++) { 
       data.add(new MyData("A" + (index + 1), "B" + (index + 1))); 
      } 
     } 

     @Override 
     public int getRowCount() { 
      return data.size(); 
     } 

     @Override 
     public int getColumnCount() { 
      return 2; 
     } 

     @Override 
     public Object getValueAt(int rowIndex, int columnIndex) { 
      MyData myData = data.get(rowIndex); 
      Object value = null; 
      switch (columnIndex) { 
       case 0: 
        value = myData.getKey(); 
        break; 
       case 1: 
        value = myData.getValue(); 
        break; 
      } 
      return value; 
     } 

     @Override 
     public Class<?> getColumnClass(int columnIndex) { 
      return String.class; 
     } 

     @Override 
     public boolean isCellEditable(int rowIndex, int columnIndex) { 
      return columnIndex == 1; 
     } 

     public boolean hasChanged(int rowIndex) { 
      MyData myData = data.get(rowIndex); 
      return myData.hasChanged(); 
     } 

     @Override 
     public void setValueAt(Object aValue, int rowIndex, int columnIndex) { 
      MyData myData = data.get(rowIndex); 
      myData.setValue(aValue == null ? null : aValue.toString()); 
     } 
    } 

    public class MyTableCellRenderer extends DefaultTableCellRenderer { 

     @Override 
     public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { 
      super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); 
      setOpaque(isSelected); 
      TableModel model = table.getModel(); 
      if (model instanceof MyTableModel) { 
       MyTableModel myModel = (MyTableModel) model; 
       if (myModel.hasChanged(row)) { 
        if (!isSelected) { 
         setBackground(Color.RED); 
         setOpaque(true); 
        } 
       } 
      } 
      return this; 
     } 
    } 
} 
+0

嗨MadProgrammer,感謝您的答覆。你能告訴我一個解決我的問題的示例程序嗎? – 2013-03-08 06:19:25

+0

當然,其鏈接的答案 – MadProgrammer 2013-03-08 06:27:02

+0

謝謝。我會研究你給的答案。 – 2013-03-08 07:59:35