Java:将方法调用存储在数组中,然后执行?

Java:将方法调用存储在数组中,然后执行?,java,methods,abstraction,Java,Methods,Abstraction,我到处找了,但找不到确切的我要找的东西 我要做的是定义了一个类,它表示JPanel中的一个区域,可以通过创建指定大小的BuffereImage来绘制该区域,并使用该图像图形将该区域加倍缓冲到JPanel,然后将该区域作为图像绘制到父JPanel,基本上创建面板区域,而不必处理javax疯狂的面板组织逻辑,该逻辑依赖于所有面板接触边界。这本质上是一个图形小部件的图形上下文,可以移动/调整大小等,类似于视频游戏UI 我想做的是能够在graphics类中存储绘制操作的方法调用,包括参数。这样做的目的是

我到处找了,但找不到确切的我要找的东西

我要做的是定义了一个类,它表示JPanel中的一个区域,可以通过创建指定大小的BuffereImage来绘制该区域,并使用该图像图形将该区域加倍缓冲到JPanel,然后将该区域作为图像绘制到父JPanel,基本上创建面板区域,而不必处理javax疯狂的面板组织逻辑,该逻辑依赖于所有面板接触边界。这本质上是一个图形小部件的图形上下文,可以移动/调整大小等,类似于视频游戏UI

我想做的是能够在graphics类中存储绘制操作的方法调用,包括参数。这样做的目的是,无论是在运行时还是在源代码中,我都可以在方法中加载已指定的参数值,这些参数值可以在不破坏封装的情况下调用,因为在当前情况下,父类必须直接绘制到BuffereImage,我希望避免这样的情况,即可以在运行时添加方法,或者绘制的方法调用必须在PanelRegion类本身中完成,这迫使我在每次需要另一个PanelRegion时都创建一个新的专门化PanelRegion,这将无法有效地工作

我希望能够做到的只是:

Class graphics = panelRegion.getGraphics();
String methodName = "drawRectangle";
int xPos = 0;
int yPos = 0;
int width = 0;
int height = 0;

ImaginaryMethodClass method = graphics.getMethod(methodName, int, int, int, int);
method.imaginaryMethodThatLoadsParameterValues(xPos, yPos, width, height);

panelRegion.addMethod(method);
panelRegion.invokeDrawMethods();


如果这没有意义,那么我发现的唯一解决方案就是可以使用reflector类将方法抽象地加载到数组中,但是当您想要执行时,仍然必须发送该方法的参数值,基本上使其成为源代码中的一个复杂方法调用。我想把这一步剪掉,或者让它以我给定的值自动执行。

您试图做的就是调用

在Java中实现这一点的一种简单方法是创建一个匿名类来实现。Runnable是一个定义单个方法的接口:
void run()
。您可以在代码中的任何位置实现匿名类,当您实现时,您可以引用当前范围中的任何变量

Java8通过为其添加一些语法糖,使其变得更容易。您问题中的代码在Java 8中如下所示:

Graphics graphics = panelRegion.getGraphics();

Runnable methodCall = () ->  graphics.drawRectangle(xPos, yPos, width, height);

panelRegion.addMethod(methodCall);
当您还没有使用Java 8时,代码有点复杂:

Graphics graphics = panelRegion.getGraphics();

Runnable methodCall = new Runnable() {
   public void run() {
       graphics.drawRectangle(xPos, yPos, width, height);
    }
}

panelRegion.addMethod(methodCall);
在上述两个(完全等效)示例中,
graphics.drawRectangle(xPos,yPos,width,height)
不执行。它仅在调用
methodCall.run()
时执行

panelRegion的实现将使用它将要执行的命令维护一个
列表
。当它执行该列表时,它只对每个列表调用
.run()
方法

class PanelRegion {

    private List<Runnable> listOfMethods = new ArrayList<>();

    public void addMethod(Runnable methodCall) {
        listOfMethods.add(methodCall);
    }

    public void invokeDrawMethods()
    {
         for(Runnable aMethod : listOfMethods) {
             aMethod.run();
         }
    }
}
类面板区域{
私有列表listOfMethods=newarraylist();
public void addMethod(Runnable methodCall){
添加(methodCall);
}
public void invokeDrawMethods()
{
for(可运行方法:listOfMethods){
aMethod.run();
}
}
}

+1表示@Phillipp answer。此外,如果要从方法返回对象,可以使用
Callable

Graphics graphics = panelRegion.getGraphics();

Callable methodCall = () ->  graphics.drawRectangle(xPos, yPos, width, height);

panelRegion.addMethod(methodCall);
对于以下Java 8:

Graphics graphics = panelRegion.getGraphics();

Callable methodCall = new Callable() {
   @Override
   public Object call() {
       return graphics.drawRectangle(xPos, yPos, width, height);
    }
}

panelRegion.addMethod(methodCall);
然后像这样调用:

class PanelRegion {
    private List<Callable> listOfMethods = new ArrayList<>();

    public void addMethod(Callable methodCall) {
        listOfMethods.add(methodCall);
    }

    public void invokeDrawMethods()
    {
         for(Callable aMethod : listOfMethods) {
             Object ret = aMethod.call();
             // do something with ret
         }
    }
}
类面板区域{
私有列表listOfMethods=newarraylist();
公共void addMethod(可调用的方法调用){
添加(methodCall);
}
public void invokeDrawMethods()
{
for(可调用方法:listOfMethods){
Object ret=aMethod.call();
//用ret做点什么
}
}
}

请参阅感谢您添加可运行位;我已经在维基百科上找到了命令结构,尽管它有效,但我还是遇到了一些问题。这样做更容易、更可靠
class PanelRegion {
    private List<Callable> listOfMethods = new ArrayList<>();

    public void addMethod(Callable methodCall) {
        listOfMethods.add(methodCall);
    }

    public void invokeDrawMethods()
    {
         for(Callable aMethod : listOfMethods) {
             Object ret = aMethod.call();
             // do something with ret
         }
    }
}