在数组中存储和调用特定的类方法

时间:2017-02-09 13:09:18

标签: java swing

我一直在阅读和谷歌搜索几个小时我可以打电话

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循环。

enter image description here

正如您所看到的,它仅使用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方法,但不是全部。

任何解决方案或建议?

3 个答案:

答案 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);
                            }
                        }
                    }