2016-01-29 145 views
0

我正在使用基於Eclipse的軟件,該軟件允許創建應用程序並自動提供默認用戶界面。 我想修改這個接口(例如更改按鈕圖標,前景色等),但不幸的是我無法修改源代碼,所以我試圖通過Java反射來實現。 由於像JD-GUI這樣的軟件,我無論如何都可以對已編譯的jar文件有所瞭解,但我不想修改和重新編譯jar。 問題是,這個接口是通過擴展Swing組件的定製類來構建的,並且在查看jar文件時,我發現了一些惱人的技巧。如下的例子:通過反射調用超類方法

final class MyToggleButton extends JToggleButton{ 
    MyToggleButton (ImageIcon defaultIcon){ 
     super.setIcon(defaultIcon); 
    } 
    @Override 
    public void setIcon(Icon icon){} 
} 

通過內置在這樣的類,如果我調用的setIcon()方法MyToggleButton的一個實例,它沒有影響,因爲重寫方法內部不代碼(我認爲)。所以我不能改變它們在特定按鈕上默認設置的圖標。

有沒有人知道一種方法來解決這個問題? 在此先感謝您的幫助。

P.S.我不是一個傑出人物,但我很熟悉反思。

回答

0

正如其他人所提到的,如果它被覆蓋了,就不可能通過反射來調用超類的方法。如果在所有可能的情況下,您應該尋找另一種解決問題的方法,例如yole's suggestion,因爲這很難讀取和維護(例如,如果方法實施更改或default_icon字段更改名稱)。

但是,如果你絕對要和必須你可以做這樣的事情,以「模擬」基於源的setIcon()here上線的方法調用1710

public static void setButtonIcon(MyToggleButton button, Icon icon) { 
     if (button.getIcon() == icon) 
      return; 

     Icon old = button.getIcon(); 

     // Use reflection to set the icon field 
     try { 
      Field f = AbstractButton.class.getDeclaredField("default_icon"); 
      f.setAccessible(true); 
      f.set(button, icon); 
     } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { 
      e.printStackTrace(); 
      return; 
     } 

     button.firePropertyChange(AbstractButton.ICON_CHANGED_PROPERTY, old, icon); 
     button.revalidate(); 
     button.repaint(); 
} 

Reflection reference

1

這是不可能的。只有通過一個特殊的字節碼指令(invokespecial)纔可以調用超類方法並繞過類中的覆蓋,而該指令只能在覆蓋該方法的類中使用。沒有辦法通過反思來進行這樣的呼叫。

+0

你好,謝謝你的迴應。爲了確保我明白了,這是否意味着,由於上述源代碼,無法更改JToggleButton的圖標? – Roberto

+0

更改圖標最簡單的方法是解壓縮.jar文件,更改包含圖標的文件並重新打包。這比反編譯和重新編譯類要容易得多,而且比任何可能出現的反射技巧都要可靠得多。 – yole

0

您不能調用超類的方法版本。但是,通過反思,你可能會執行相同的邏輯。例如,通過反射,您可以將圖標分配到JToggleButton中的字段,並調用將屬性更改事件分派給註冊的偵聽器等的方法。

本質上,您會查看JToggleButton(或在那裏定義該方法),並使用反射在其原始setIcon()方法中重現代碼。不容易,美觀或可維護,但它會工作。

+0

非常感謝您的幫助。不幸的是,這對我來說似乎有點複雜,因爲我不是程序員。你能否提供給我,如果沒有太大麻煩,請使用我在上面發佈的類所需的代碼示例? – Roberto

相關問題