2017-02-09 53 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); 
          } 
         } 
        } 
相關問題