2017-02-09 56 views
0

我一直在阅读和我怎么能叫存储和调用/特定类的方法从一个数组

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; 
    } 

我有许多不同的方法gettersetter方法一起使用Google了几个小时。

我需要能够调用方法来填充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的方法,但不是所有的人。

任何解决方案或建议?

+0

您可以使用您的J-循环来决定,你必须使用哪个吸气剂。你可以打开j,如果j == 0 getId(),j == 1 getName()等等。 – IQV

+0

或者你也可以在Fee中写一个getter,它以column-ID作为参数,所以你决定在那里,必须返回哪个值。 – IQV

+0

1)一个开关使用一个基于getXXX的列,2)Java Stream允许你使用方法引用(现在不用多少不幸),也许可以使用这些数组(像'Fee :: getId之类的东西'), – AxelH

回答

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)); 
    } 
} 
+0

我会在GUI中执行Map(或数组),因为命令和getter需要取决于你想要的JTable。但我希望看到这个答案! – AxelH

+1

同意 - 重构将索引映射到显示逻辑的逻辑将是一个更好的整体设计。代码示例更多地展示了尽可能简单的技术。 – BarrySW19

0

为了动态调用那样的方法,你需要使用反射和可能的自省。

反射是当你以编程方式使用程序本身的结构,如Class实例,它们定义的方法。如果你看看Java Class class,你会发现它有访问其构造函数,字段,方法等的方法。

内省是能够在运行时使用某些对象的属性。符合JavaBeans规范的类允许自省,它提供了比纯反射更易于使用的抽象。 Introspector class in package java.beans允许你获取一个类的bean信息。从那里开始,可以使用该类的“属性”。一个属性可以是一个带有getter和/或setter的字段,也可以是一个没有字段支持的getter/setter(它可以简单地在逻辑上操作)。它允许更多,比如在一个实例上注册一个监听器和一个属性,这样如果通过setter改变了属性,监听器就会被调用。这对模型 - 视图 - 控制器方法很有用,对某些实例的更改可能需要在视图上触发更新事件。例如,如果您的代码的某些部分更改了在GUI外部表示为表中行的对象的属性,则可以使用侦听器来更新相应的单元格。

如果你想使用一个数组,你必须用Method instances填充它。这些将是通过内省获得的相应PropertyDescriptors的读取方法(可能还有一个带有写入方法的单独数组)。然后可以在对象上调用这样的一个Method,只要访问规则允许。实际上使用映射可能更好,它将映射名称映射到Method,所以实际顺序无关紧要。这会让以后重构用户界面变得更加容易。您可能还需要一些将实际列名称映射到属性名称的方法,但是如果您设置了有关命名的特定规则并坚持使用它们,则可以从列名称派生属性名称,或者反转并为每个列名称显示一列属性自动。

编辑:也许很有趣,知道为什么你需要在这样一个圆的方式做这些事情。 Java没有一流的方法。这意味着方法不能作为参数传递,或者被视为任何其他数据片段,就像在JavaScript或Scala中那样。因此需要反思来间接获取和调用方法。 Java 8引入了lambdas的一些函数式编程概念,但是它们是伪装的单一方法接口的一种形式。此外,Java不是一种动态语言,如Ruby或Python,它是一种静态编译语言。因此,其他语言中的一些简单(但也很容易中断)的事情需要Java中的反思。如果您来自非Java背景,您需要做某些事情的方式可能会很麻烦。

+0

还有其他解决方案可以防止使用Reflection(最后一种解决方案的使用)。一个简单的Builder来生成'Fee'类的行。或者像其他答案一样,Java 8提供了一种新方法来引用方法 – AxelH

+0

@AxelH我缺乏Java 8的经验,并且不知道它有那个方便的双冒号操作符。这使得如果使用Java 8,BarrySW19的答案更好,因为它使得东西更接近于一流的方法。 –

+0

@gh不用担心,我也不会更好;) – AxelH

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); 
          } 
         } 
        } 
相关问题