将函数作为字符串传递的正确方法

时间:2012-07-08 13:00:36

标签: java

请允许我解释一下我想要做什么 - 我认为标题大致解释了,但我不太确定我会以正确的方式处理事情,所以请更正我,如果我错了!

我使用LayeredPane创建了自定义对话框。基本上jPanel显示POPUP_LAYER,因此出现在主要内容的顶部。此面板包含一个简单的'label-textbox-okay-cancel'控件组。我将其称为“对话面板”。

我想做什么: 当在主窗口(包含在LayeredPane中)上单击按钮时,将出现对话框面板并允许用户输入一些文本,然后单击“确定”或取消。这很容易,但我希望这个代码可以重复使用,这意味着主窗口上的其他按钮将调用相同的对话框面板,但标签中的文本不同。 / p>

这当然要求我包含某种回调函数,以便对话框面板上的okay按钮将根据调用它的按钮运行正确的代码。

我当前的尝试是存储一个字符串,该字符串将包含当用户单击对话框面板上的okay按钮时应该运行的函数的名称。我试图检索这个字符串并将其转换为函数名称,到目前为止,我发现了许多对“反射”的引用,其中许多提示它不是一个好主意。

在任何情况下,我都无法获得任何示例代码,因为我不明白下面代码中的'obj'是什么,我无法调用该方法:

method = obj.getClass().getMethod(myCallbackString);

我的问题是:

首先,我是否正确地采取了这种方式?我不仅仅对建议持开放态度,但请尽量保持简单,因为我真的刚刚开始!

其次,上面代码中的'obj'是什么?我真的很想知道,即使这不是我应该做的事情!

我的其他想法包括:我的对话面板应该在自己的类中,如果是,再次,如何传递回调函数?

感谢任何帮助或建议。

BTW:回答“为什么不使用普通对话?”这个问题。我只能说我正在尝试,我只是想看看能不能做到这一点!

MVK

5 个答案:

答案 0 :(得分:5)

Java程序传递回调函数的常用方法是传递实现特定回调函数的接口实例。虽然不是必需的,但是匿名实现接口是典型的。

例如,这是一个界面:

interface MyCallback {
    void performCallback();
}

以下是定义对话框接收回调的方法的方法:

void openWithCallback(MyCallback cb) {
    // Do something useful...
    ...
    // Perform the callback
    cb.performCallback();
}

以下是调用该方法的方法:

public void OpenDialog() {
    myDialog.openWithCallback(new MyCallback() {
        public void performCallback() {
            System.out.println("Inside callback...");
        }
    });
}

答案 1 :(得分:2)

obj命名要调用其方法的对象,在您的情况下,您可以将其替换为this(或完全删除它,因为隐含了this):< / p>

private void callByName(String name) { 
  try { getClass().getMethod(name).invoke(this); }
  catch (RuntimeException e) { throw e; }
  catch (Exception e) { throw new RuntimeException(e); }
}

为此,您需要使用适当的名称声明一个公共的无参数方法。

答案 2 :(得分:2)

  1. 我认为您的想法是有效的,尽管它有一个主要缺点:您将方法名称存储为代码中的简单字符串,因此编译器无法检查它们的有效性。因此,如果更改方法的名称,则必须手动确保已更新引用它的所有字符串。 这通常意味着'反思是一个坏主意'。
  2. 代码中的
  3. obj是您要调用方法的对象。举一个简单的例子,someInteger.toString();与反射相当的是someInteger.getClass().getMethod("toString").invoke();
  4. 更一般地说,一旦你对Java感到满意,你也可以看看像Scala这样的函数式语言,其中函数是常规对象,你想要的场景可以通过完整的编译器检查来实现。

答案 3 :(得分:2)

我认为你使这个方式比以前更加复杂。你说你想要这个:

This is all easy enough, but I would like this code to be re-usable, which means 
that other buttons on the main window will invoke the same Dialog Panel, but with
different text in the label.

根据定义,DialogBox是可重用的。为什么不单击按钮单击侦听器将相应的文本传递给对话框,以便显示正确的信息?

如果根据调用者点击对话框上的按钮后需要执行特定操作,您可能需要考虑:

  1. 创建了一个自定义DialogBox扩展,其中包含了根据谁调用它来知道要做什么的逻辑。然后,当一个按钮调用自定义对话框时,它会传递一个参数,让它在对话框被解除后知道它想要做什么。

  2. 使用类似抽象工厂模式的东西。

  3. 是的,你可以通过反思来做到这一点。是的,这是一个非常糟糕的主意,其他人在其他答案中讨论了很多原因,特别是如果这是生产代码(尽管你似乎表明它是一个实验。)

    如果您真的只是想看看如何使用反射,那么您可能想要阅读该主题。我发现this是其中一个更好的教程。

答案 4 :(得分:1)

我没有使用过JPanel,但我理解的是你的查询,答案似乎相当简单。而不是传递方法名称,为什么不在接口上工作并传递该接口的不同实现?