我一直在阅读和谷歌搜索几个小时我可以打电话
public class Fee {
int id;
String name;
double amount;
FeeCategory feeCategory; // miscellaneous, other, tuition, etc
GradeLevel gradeLevel;
SchoolYear schoolYear;
String description;
boolean isActive;
public boolean isIsActive() {
return isActive;
}
public void setIsActive(boolean isActive) {
this.isActive = isActive;
}
public FeeCategory getFeeCategory() {
return feeCategory;
}
public void setFeeCategory(FeeCategory feeCategory) {
this.feeCategory = feeCategory;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getAmount() {
return amount;
}
public void setAmount(double amount) {
this.amount = amount;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public GradeLevel getGradeLevel() {
return gradeLevel;
}
public void setGradeLevel(GradeLevel gradeLevel) {
this.gradeLevel = gradeLevel;
}
public SchoolYear getSchoolYear() {
return schoolYear;
}
public void setSchoolYear(SchoolYear schoolYear) {
this.schoolYear = schoolYear;
}
我有许多不同的getter
方法及其setter
方法。
我需要能够调用该方法来填充JTable
的单元格,并使用相应的getter
方法返回的特定值。
所以我做的是创建一个DefaultTableCellRenderer
public class JTableRenderer extends DefaultTableCellRenderer{
@Override
public Component getTableCellRendererComponent(
JTable table, Object value,
boolean isSelected, boolean hasFocus,
int row, int col)
{
Component cellComponent = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
if(row%2 == 0){
cellComponent.setBackground(Color.YELLOW);
}
else{
cellComponent.setBackground(Color.CYAN);
}
for(int i=0; i<table.getRowCount(); i++){
for(int j=0; j<table.getColumnCount(); j++){
if(table.getValueAt(i, j) instanceof Fee){
Fee fee = (Fee)table.getValueAt(i, j);
table.setValue(fee.getId(),i,j);
}
}
}
return cellComponent;
}
}
问题在于我计划用于为某些单元格设置特定值的for循环。
正如您所看到的,它仅使用id
填充了所有单元格,因为我无法想到迭代getId(),getName(),getAmount(),getDescription()
的方法。
是否可以将所有4个方法放在数组中,如
Methods[] myMethods = {getId(),getName(),getAmount(),getDescription()};
然后,
for(int i=0; i<table.getRowCount(); i++){
for(int j=0; j<table.getColumnCount(); j++){
if(table.getValueAt(i, j) instanceof Fee){
Fee fee = (Fee)table.getValueAt(i, j);
table.setValue(fee.myMethod[j],i,j);
}
}
}
我想只调用4个getter
方法,但不是全部。
任何解决方案或建议?
答案 0 :(得分:2)
您将需要某种切换逻辑来处理索引到getter方法的映射。对我来说,最好的方法是使用Java 8 lambda函数,类似于下面的例子。正如您所看到的,这会将一个getValue(int index)方法添加到Fee类中,该类可以执行您想要的操作。映射由静态初始化中创建的Map处理。
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
public class Fee {
private String name;
private int fee;
private static Map<Integer, Function<Fee, Object>> getterIndex = new HashMap<>();
static {
getterIndex.put(0, Fee::getName);
getterIndex.put(1, Fee::getFee);
}
public String getName() {
return name;
}
public Fee setName(String name) {
this.name = name;
return this;
}
public int getFee() {
return fee;
}
public Fee setFee(int fee) {
this.fee = fee;
return this;
}
public Object getValue(int index) {
return getterIndex.get(index).apply(this);
}
public static void main(String[] args) {
Fee fee = new Fee().setName("Barry").setFee(1000);
System.out.println("name: " + fee.getValue(0));
System.out.println("fee : " + fee.getValue(1));
}
}
答案 1 :(得分:0)
为了动态调用这样的方法,你需要使用反射和可能的内省。
反射是指以编程方式使用程序本身的结构,例如Class
实例,它们定义的方法。如果您查看Java Class
class,您会发现它有访问其构造函数,字段,方法等的方法。
Introspection是在运行时使用某些对象的属性的能力。符合JavaBeans规范的类允许内省,它提供了一些比纯反射更容易使用的抽象。 Introspector
class in package java.beans允许您获取类的bean信息。从那里,&#34;属性&#34;可以使用该类。属性可以是具有getter和/或setter的字段,或者不是由字段支持的getter / setter(可以简单地对逻辑进行操作)。它允许更多,例如在实例上注册具有属性的侦听器,以便如果通过setter更改属性,则调用侦听器。这对于模型 - 视图 - 控制器方法很有用,其中对某些实例的更改可能需要在视图上触发更新事件。例如,如果代码的某些部分更改了表格中表示为行的对象的属性,则在GUI之外,可以使用侦听器更新相应的单元格。
如果您想使用数组,则必须使用Method
instances填充它。这些是通过内省得到的相应PropertyDescriptors的读取方法(可能还有一个带写入方法的单独数组)。如果访问规则允许,则可以在对象上调用此类Method
。实际上,使用将名称映射到Method
的地图可能会更好,因此实际的顺序并不重要。这样可以更轻松地在以后重构您的用户界面。您可能还想要一些将实际列名称映射到属性名称的方法,但是如果您设置了有关命名的特定规则并坚持使用它们,您可以从列名称派生属性名称,或者反转事物并为每个名称显示一列财产自动。
编辑:也许有趣的是要知道为什么你需要以如此圆润的方式做这些事情。 Java没有第一类方法。这意味着方法不能作为参数传递或作为任何其他数据处理,就像在JavaScript或Scala中那样。因此需要反思来间接获取和调用方法。 Java 8使用lambdas引入了一些函数式编程概念,但它们是伪装的单方法接口形式。此外,Java不是一种动态语言,如Ruby或Python,它是一种静态编译的语言。因此,在其他语言中一些简单(但也易于破解)的东西需要在Java中进行反射。如果您来自非Java背景,那么您需要执行某些操作的方式可能会让您觉得麻烦。
答案 2 :(得分:0)
添加到费用类:
public Object myMethod(int j) {
switch (j) {
case 0:
return this.getId();
case 1:
return this.getName();
case 2:
return this.getAmount();
case 3:
return this.getDescription();
default:
throw new IllegalArgumentException();
}
}
您应该有费用记录列表:
List<Fee> feeData=new ArrayList<Fee>();
然后致电:
for(int i=0; i<feeData.size(); i++){
if(feeData.get(i) instanceof Fee){
for(int j=0; j<table.getColumnCount(); j++){
Fee fee = (Fee)feeData.get(i);
table.setValueAt(fee.myMethod(j),i,j);
}
}
}