2016-10-03 58 views
-2

我想要做的是在輸入框中創建一個遊戲我正在使用消息顯示在屏幕上作爲從Method.invoke傳遞的變量不會顯示在任何東西,但System.out.println

「名稱:(輸入會出現在這裏)」

我所做的是傳遞消息,這對象我想我的輸入要去的,哪些功能將使用變量(如將輸入設置爲玩家姓名的函數)。現在,我可以從InputBox對象中訪問輸入變量,但從長遠來看,這會更有效率。我使用Method.invoke將函數傳遞到我想要的輸入字符串作爲參數的對象。這裏是我的代碼:

public class InputBox extends Textbox { 

    public String input = ""; 
    private String out; 
    private Object obj; 

    private int lastLastKey = 0; 

    /** 
    * 
    * @param message 
    * @param cl The object/class where the output variable is. 
    * @param out The method to run. Only takes the input variable, so use this format: void toRun(String input) 
    */ 
    public InputBox(String message, Object obj, String out) { 
     super(message); 
     this.out = out; 
     this.obj = obj; 
    } 

    public void tick(Game game){     
     if (game.input.lastKey != 0 && !game.input.keys[KeyEvent.VK_ENTER] 
       && !game.input.keys[KeyEvent.VK_SPACE] && !game.input.keys[KeyEvent.VK_SHIFT] && !game.input.keys[KeyEvent.VK_BACK_SLASH]){ 
      if(game.input.lastKey != lastLastKey) input+=Character.toUpperCase((char) game.input.lastKey); 
     }else if(game.input.keys[KeyEvent.VK_ENTER] && !input.isEmpty() && !cleared){ 
      Method method = null; 
      try { 
       method = obj.getClass().getMethod(out, new Class[]{ String.class, Object.class }); 
      } catch (NoSuchMethodException e) { 
       e.printStackTrace(); 
      } catch (SecurityException e) { 
       e.printStackTrace(); 
      } 

      try { 
       method.invoke(obj, new Object[]{ input, obj }); 
      } catch (IllegalAccessException e) { 
       e.printStackTrace(); 
      } catch (IllegalArgumentException e) { 
       e.printStackTrace(); 
      } catch (InvocationTargetException e) { 
       e.printStackTrace(); 
      } 
      cleared = true; 
     } 

     lastLastKey = game.input.lastKey; 
    } 

    public void render(Graphics g){ 
     if(!cleared){ 
      g.setColor(Color.white); 
      g.fillRect(10, Display.height-110, Display.width-20, 100); 

      g.setColor(Color.black); 
      g.drawRect(10, Display.height-110, Display.width-20, 100); 

      g.setFont(Game.smallFont); 
      FontMetrics fm = g.getFontMetrics(); 
      g.drawString(message+" "+input, Display.width/2-fm.stringWidth(message+" "+input)/2, Display.height-50); 
     } 
    } 

} 
+0

您的問題是什麼? –

+0

我的問題是,每當我運行這段代碼時,變量都會像我想要的那樣傳遞給其他類,但我唯一能做的就是使用System.out.print。其他變量的工作,但這並不 – bloobchube

+0

我不明白這是什麼意思。你能否重新修改,理想情況下用'System.out.print'添加一個顯示問題的[mcve]? –

回答

0

您的構造函數描述中提到了預期的方法具有

void toRun(String input) {} 

的簽名,但你的反射代碼查找的方法與簽名

void toRun(String input, Object o) {} 

如果您使用的是Java 8,則可以使用Consumer並刪除所有映射離子代碼:

public class InputBox extends Textbox { 

    private Consumer<String> out; 

    public InputBox(String message, Consumer<String> out) { 
     this.out = out; 
     ... 
    } 

    public void tick(Game game){ 
     ... 
     out.apply(input); 
     ... 
    } 
} 

假設你Player類有這樣的方法setName(String)

public class Player { 
    public void setName(String name) { 
    } 
} 

可以用一種方法參考

public InputBox createNameInputBox(Player p) { 
    return new InputBox("Name: ", p::setName); 
} 

或具有lambda表達式創建InputBox

public InputBox createAlternateNameInputBox(Player p) { 
    return new InputBox("Name: ", name -> p.setName(name)); 
} 

要了解有關lambda表達式和方法引用的更多信息,請參閱Java教程系列(https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html)。有關是否應使用方法參考或lambda表達式的討論,請參閱https://stackoverflow.com/a/24493905/5646962

+0

如何初始化使用者對象? – bloobchube

+0

@bloobchube增加了示例代碼和鏈接供參考 –

+0

謝謝,這工作!現在我終於可以繼續發展我的比賽了。 – bloobchube