简体   繁体   English

从 Method.invoke 传递的变量除了 System.out.println 没有出现在任何东西中

[英]Variable passed from Method.invoke doesn't show up in anything but System.out.println

What I'm trying to do is create in input box for a game I'm making that displays on-screen with a message such as我想要做的是在输入框中为我正在制作的游戏创建一个显示在屏幕上的消息,例如

"Name: (input would appear here)" “姓名:(输入会出现在这里)”

What I did was pass in the message, which object I want my input to go to, and what function will use the variable(such as a function that sets the input to the player's name).我所做的是传递消息,我希望我的输入转到哪个对象,以及哪个函数将使用该变量(例如将输入设置为玩家姓名的函数)。 Now, I could just access the input variable from the InputBox object, but, in the long run, this will be more efficient.现在,我可以只从 InputBox 对象访问输入变量,但从长远来看,这会更有效率。 I'm using Method.invoke to pass the function into the object I want with the input string as an argument.我正在使用Method.invoke将函数传递到我想要的对象中,并将输入字符串作为参数。 Here is my code:这是我的代码:

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

}

Your description for the constructor says that the expected method has a signature of您对构造函数的描述说预期的方法有一个签名

void toRun(String input) {}

But your reflection code looks for a method with the signature但是您的反射代码寻找具有签名的方法

void toRun(String input, Object o) {}

If you are using Java 8 you can make use of a Consumer and remove all the reflection code:如果您使用的是 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);
        ...
    }
}

Assuming that your Player class has a method setName(String) like this:假设你的Player类有一个像这样的方法setName(String)

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

you can create an InputBox with a method reference您可以使用方法引用创建一个InputBox

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

or with a lambda expression或使用 lambda 表达式

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

To read more about lambda expressions and method references see the Java Tutorial series ( https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html ).要阅读有关 lambda 表达式和方法引用的更多信息,请参阅 Java 教程系列 ( https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html )。 For a discussion of whether you should use method references or lambda expressions see https://stackoverflow.com/a/24493905/5646962有关是否应该使用方法引用或 lambda 表达式的讨论,请参阅https://stackoverflow.com/a/24493905/5646962

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM