JTable颜色渲染区分用户添加的值?

时间:2016-02-15 22:32:01

标签: java swing user-interface jtable

我有一个JTable,其中数据单元将由某个模型填充,但是如果用户认为模型设置值不满意,则可以覆盖这些值。

我正在尝试使用以下逻辑实现渲染器:

  • 如果单元格没有数据,则背景为红色。
  • 如果单元格具有模型设置数据,则颜色背景为白色。
  • 如果单元格具有用户设置数据,则背景为紫色。

我已经扩展DefaultTableCellRenderer,但不知道是否可以将“用户设置”数据与“模型集数据”区分开来。如何摆动单元格渲染器访问数据设置源?我能想到的最好的方法是使用一些隐藏的字符来区分我的数据类型吗?

我附上了一个关于这看起来如何的规范。

enter image description here

这是渲染器代码,以防有用:

import java.awt.Color;
import java.awt.Component;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;

/* 
Provides abstract methods/color defaults for JTable cell rendering.
 */
public class CustomCellRenderer extends DefaultTableCellRenderer {


    public Color HASDATA_COLOR = Color.getHSBColor((270f/360),0.22f,0.96f);
    public Color HIGHLIGHT_COLOR = Color.getHSBColor((94f/360), 0.27f, 0.89f);


   @Override
   public Component getTableCellRendererComponent(JTable table, Object value,
            boolean isSelected, boolean hasFocus, int row, int col) {

      Component c = super.getTableCellRendererComponent(table, value,
               isSelected, hasFocus, row, col);
      Object valueAt = table.getModel().getValueAt(row, col);

       // Populated cell color
       if (valueAt != null ) {
            c.setBackground(HASDATA_COLOR);
          }
       }

       if (isSelected){
          c.setBackground(HIGHLIGHT_COLOR);
      }      
      return c;
   }    
}

2 个答案:

答案 0 :(得分:1)

我制作了一个TableModel扩展类,它存储了MyData个对象的2D数组,其中包含initial字段和data字段。 initial在构造函数中设置,它将是您的模型设置值。您还可以将data字段设置为initialMyTableModel setValueAt功能会设置模型的data字段。在您的渲染器中,您可以检查initial是否等于data

答案 1 :(得分:1)

如果这是一个简单的一个下午项目,上面的答案可以很好地运作。

我知道它可能听起来有点过度工程,但我会避免使用该模型的标量值。问题是,一个值包含一个值,一个额外的状态,告诉该值的来源,数据模型应代表该值。

模型的一个“值”可能包含valueSource枚举,告诉它是来自原始,还是来自重写。这个简单的设计决策允许您进一步增强用例(例如,如果您需要多种颜色的多种颜色),并将渲染与编辑分开。

示例:

  • 说,你正在使用汇率。可以通过某种方式(通过直接编辑JTable或使用专用编辑器对话框)覆盖默认速率。
  • 而不是存储例如作为“模型”的双打数组,定义一个更好的模型
  • 首先,有一个班级率(见下文)
  • 渲染器中的
  • ,在渲染速率时,从该
  • 中读取源类型

public class Rate {
       public enum RateSource {
          EMPTY,
          DEFAULT,
          EDITED
       };

       private double rate;
       private RateSource rateSource;

       // construct an empty rate
       public Rate() {   
          this.rateSource=RateSource.EMPTY;
       }


       // construct a known rate
       public Rate(double defaultRate) {   
          this.rate=defaultRate;
          this.rateSource=RateSource.DEFAULT;
       }

       // call to set a rate, aka. edit
       public void setRate(double rate) {
          this.rate=rate;
          this.rateSource=RateSource.EDITED;
       }

       public RateSource getRateSource() {
          return rateSource;
       }
    }
}

public class Rate { public enum RateSource { EMPTY, DEFAULT, EDITED }; private double rate; private RateSource rateSource; // construct an empty rate public Rate() { this.rateSource=RateSource.EMPTY; } // construct a known rate public Rate(double defaultRate) { this.rate=defaultRate; this.rateSource=RateSource.DEFAULT; } // call to set a rate, aka. edit public void setRate(double rate) { this.rate=rate; this.rateSource=RateSource.EDITED; } public RateSource getRateSource() { return rateSource; } } }

(我很遗憾这个代码块的sytax亮点出了问题。) 您的数据可以是Rate实例的数组(但是定义一个模型来建模应用程序的数据而不是使用数组,这是一种非常简化的JTable数据建模方法)。

然后在你的渲染器中: