2013-03-08 172 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