4

请允许我解释我正在尝试做的事情 - 我认为标题大致解释了它,但我不太确定我正在以正确的方式做事,所以如果我错了,请纠正我!

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

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

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

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

在任何情况下,我都无法让任何示例代码工作,因为我不明白下面代码中的“obj”是什么,并且无法调用该方法:

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

我的问题是:

首先,我是否以正确的方式进行此操作?我对建议持开放态度,但请尽量保持简单,因为我真的才刚刚开始!

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

我的其他想法包括:我的Dialog Panel是否应该在它自己的类中,如果是,那么如何传递回调函数?

任何帮助或建议将不胜感激。

顺便说一句:回答“为什么不使用普通对话框?”这个问题。我只能说我目前正在做实验,我只是想看看我能不能做到这一点!

MVK

4

5 回答 5

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...");
        }
    });
}
于 2012-07-08T13:10:10.753 回答
2

obj命名您要调用其方法的对象,在您的情况下,您可以将其替换为this(或完全删除它,因为this暗示):

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

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

于 2012-07-08T13:09:59.327 回答
2
  1. 我认为您的想法是有效的,尽管它有一个主要缺点:您将方法名称存储为代码中的简单字符串,因此编译器无法检查它们的有效性。因此,如果您更改方法的名称,您必须手动确保已更新所有引用它的字符串。这就是“反思是一个坏主意”的通常含义。
  2. obj在您的代码中是您要调用方法的对象。举个简单的例子,someInteger.toString();with 反射的等价物是someInteger.getClass().getMethod("toString").invoke();.

更一般地说,一旦您对 Java 感到满意,您还可以查看像 Scala 这样的函数式语言,其中函数是常规对象,并且您想要的场景可以通过完整的编译器检查来实现。

于 2012-07-08T13:11:05.963 回答
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.

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

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

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

  2. 研究使用抽象工厂模式之类的东西。

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

如果您真的只是想了解如何使用反射来处理它,您可能需要阅读该主题。我发现是最好的教程之一。

于 2012-07-08T13:17:39.170 回答
1

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

于 2012-07-08T13:09:23.453 回答