java.lang.InstanceOnError。类变得抽象

java.lang.InstanceOnError。类变得抽象,java,minecraft,bukkit,Java,Minecraft,Bukkit,我目前正在为Minecraft开发一个Bukkit插件,在尝试创建一个新对象时,我遇到了一个java.lang.InstanceOnError错误。堆栈跟踪如下所示 Caused by: java.lang.InstantiationError: fancyui.craterhater.components.FancyComponent at fancyui.craterhater.uibuilder.ComponentMaker.getComponent(ComponentMaker.

我目前正在为Minecraft开发一个Bukkit插件,在尝试创建一个新对象时,我遇到了一个java.lang.InstanceOnError错误。堆栈跟踪如下所示

Caused by: java.lang.InstantiationError: fancyui.craterhater.components.FancyComponent
    at fancyui.craterhater.uibuilder.ComponentMaker.getComponent(ComponentMaker.java:13) ~[?:?]
    at fancyui.craterhater.uibuilder.Editor_Page_0.getComponents(Editor_Page_0.java:40) ~[?:?]
    at fancyui.craterhater.uibuilder.Editor$1.call(Editor.java:36) ~[?:?]
    at fancyui.craterhater.masterfancyui.FancyUI.openInventory(FancyUI.java:195) ~[?:?]
    at fancyui.craterhater.uibuilder.Editor.createEditorGUI(Editor.java:236) ~[?:?]
    at fancyui.craterhater.commandhandler.MasterCommand$2.call(MasterCommand.java:69) ~[?:?]
    at fancyui.craterhater.commandhandler.CECommand.playerExecutes(CECommand.java:105) ~[?:?]
    at fancyui.craterhater.commandhandler.CECommand.checkPlayerExecutes(CECommand.java:98) ~[?:?]
    at fancyui.craterhater.commandhandler.MasterCommand.onCommand(MasterCommand.java:153) ~[?:?]
    at org.bukkit.command.PluginCommand.execute(PluginCommand.java:44) ~[1.8.jar:git-Spigot-870264a-0a645a2]
    ... 15 more
ComponentMaker类的第13行简单地说:

FancyComponent fancyComponent = new FancyComponent();
我做了一些调试,并决定打印以下内容

System.out.println(FancyComponent.class.toGenericString());
这是印刷品

public abstract class fancyui.craterhater.components.FancyComponent
而FancyComponent类不是抽象的。以下是FancyComponent类:

public class FancyComponent {

    //FancyComponent class represents the individual items placed in a FancyUI. 
    //It handles things such as animation, itemstack building and event handling whilst
    //allowing the FancyUI to handle loading and deleting of these components.
    //FancyComponents are added to the FancyUI by the user of the API using LoadFunctions.
    //They can also be generated from a FancyUI file.

    private FancyLocation fancyLocation;
    private FancyItemStack fancyItemStack;
    private FancyDisplayType fancyDisplayType;
    private String identifier = null;
    private int ID = 0;
    private int basicSlot = 0;
    private boolean copied;

    public FancyComponent() {
        fancyDisplayType = FancyDisplayType.DYNAMIC;
    }

    public FancyComponent copy(FancyLocation newLocation) {
        FancyComponent newComponent = new FancyComponent();
        newComponent.setDisplayType(fancyDisplayType);
        newComponent.setID(ID);
        newComponent.setFancyItemStack(fancyItemStack);
        newComponent.setFancyLocation(newLocation);
        newComponent.setAttributes(attributes);
        newComponent.setIdentifier(identifier);
        return newComponent;
    }


    //Method gets called when FancyUI decides to load in new FancyComponents.
    //This happens when openInventory gets called and new components are generated.
    //This method should start future animations. It should also handle ItemStack placement.
    //The boolean here represents whether or not it has succesfully been added. This is used in the
    //FancyUI in order to keep track of all active components and not the once off-screen.
    public boolean addToUI(Inventory inventory, Player p, FileConfiguration fc, FileConfiguration fc2) {
        if(fancyLocation == null) {return false;}

        return addToUI(inventory, p, fancyLocation, fc, fc2);
    }

    public boolean addToUI(Inventory inventory, Player p, FancyLocation fancyLocation, FileConfiguration fc, FileConfiguration fc2) {
        if(fancyItemStack == null) {return false;}

        FancyUI fancyUI = fancyLocation.getFancyUI();
        FancyLocation masterFancyLocation = fancyUI.getFancyData().getCurrentFancyLocation();

        if(!fancyLocation.isInView(masterFancyLocation, fancyDisplayType)) {return false;}

        int basicSlot = fancyLocation.getBasicLocation(masterFancyLocation.getX(), masterFancyLocation.getY(), fancyDisplayType);

        if(basicSlot < 0 || basicSlot >= inventory.getSize()) {return false;}

        this.basicSlot = basicSlot;

        ItemStack itemStack = fancyItemStack.buildItemStack(p,fc2);

        if(fc != null) {
            if(fc.contains("Components."+identifier+".Animations")) {
                for(String animation : fc.getConfigurationSection("Components."+identifier+".Animations").getKeys(false)) {
                    if(fc.getBoolean(("Components."+identifier+".Animations."+animation+".continious"))){
                        List<String> frames = new ArrayList<>();
                        if(fc.contains("Components."+identifier+".Animations."+animation+".animation")) {
                            frames = fc.getStringList("Components."+identifier+".Animations."+animation+".animation");
                        }

                        int interval = fc.getInt("Components."+identifier+".Animations."+animation+".interval");

                        if(interval < 1) {
                            interval = 2;
                        }

                        int position = fc.getInt("Components."+identifier+".Animations."+animation+".position");
                        boolean continious = fc.getBoolean("Components."+identifier+".Animations."+animation+".continious");
                        boolean reverse = fc.getBoolean("Components."+identifier+".Animations."+animation+".reverse");

                        fancyItemStack.startAnimation(frames, p, interval, position, this, continious, reverse);
                        break;
                    }
                }
            }
        }

        if(fancyLocation.getFancyUI().getFancyData().isPlayerInventory()) {
            if(fancyItemStack.getCustomName().getFancyStringAnimations().length > 0) {
                fancyItemStack.startAnimation(fancyItemStack.getCustomName().getFancyStringAnimations()[0].getFrames(), p, 4, 0, this, true, false);
            }
        }

        inventory.setItem(basicSlot, itemStack);
        return true;
    }

    //Method to reload just this component. It is used when cycling through fancyLore. If a function makes changes
    //to other components the reload method in the FancyUI has to be called in order to fully reload a page.
    public void reload(Player p) {
        FileConfiguration fc = DataHandler.getFile(96,p.getUniqueId().toString(), false, "Data", "Users");
        ItemStack itemStack = fancyItemStack.buildItemStack(p,fc);

        if(fancyLocation == null) {
            return;
        }

        if(fancyLocation.getFancyUI().getFancyData().isPlayerInventory()) {
            p.getInventory().setItem(basicSlot, itemStack);
            return;
        }

        fancyLocation.getFancyUI().getFancyData().getInventory().setItem(basicSlot, itemStack);
    }


    //Method gets called when FancyUI deletes all information on other FancyComponents.
    //This happens when openInventory gets called and new components are generated.
    //Make sure that this method cleans up future animations so they don't go around throwing nullpointers.
    //The ItemStack itself is removed automatically by the FancyUI.
    public void notifyOfDeletion() {
        fancyItemStack.stopAnimating();
    }

    //Attributes are pieces of code written by the user of the API in order to have certain things
    //happen at certain events such as ON_CLICK or ON_DROP etc.
    private List<Attribute> attributes = new ArrayList<>();

    public void addAttribute(Attribute attribute) {
        attributes.add(attribute);
    }

    public List<Attribute> getAttributes(){
        return attributes;
    }

    public void setAttributes(List<Attribute> attributes) {
        this.attributes = attributes;
    }

    //Method to identify which Attributes need to run at these specific occasions. These occasions
    //may include things suchs as ON_CLICK or ON_1 just to name a few. This method consists of two
    //distinct parts. The first part handles all generated components which have scripts assigned to them
    //and the second part handles all components that have been generated by the plugin itself. And thus
    //do not have scripts assigned to them.
    public void handleEvent(FileConfiguration fc, FileConfiguration fc2, FunctionParams params, AttributeOccasion... attributeOccasions) {
        //The 'identifier' is a tag all generated components get. It is unique to all components. 
        //Non-generated components do not have this tag and thus we can check for null to see whether or not
        //it is generated.
        if(identifier != null) {
            if(fc.contains("Components."+identifier+".Scripts")) {
                for(String script : fc.getConfigurationSection("Components."+identifier+".Scripts").getKeys(false)) {
                    if(fc.contains("Components."+identifier+".Scripts."+script+".events")) {
                        List<String> scriptLines = fc.getStringList("Components."+identifier+".Scripts."+script+".script");
                        for(String event : fc.getStringList("Components."+identifier+".Scripts."+script+".events")) {
                            A: for(AttributeOccasion attributeOccasion : attributeOccasions) {
                                if(attributeOccasion.name().equalsIgnoreCase(event)) {
                                    fancyLocation.getFancyUI().getScriptParser().executeScript(params.getPlayer(), scriptLines, FancyUI.fancyUI.get(params.getPlayer().getUniqueId()), params.getFancyComponent(), fc2, false);
                                    break A;
                                }
                            }
                        }
                    }
                }
            }

            if(fc.contains("Components."+identifier+".Animations")) {
                for(String script : fc.getConfigurationSection("Components."+identifier+".Animations").getKeys(false)) {
                    if(fc.contains("Components."+identifier+".Animations."+script+".events")) {
                        for(String event : fc.getStringList("Components."+identifier+".Animations."+script+".events")) {
                            A: for(AttributeOccasion attributeOccasion : attributeOccasions) {
                                if(attributeOccasion.name().equalsIgnoreCase(event)) {
                                    List<String> frames = new ArrayList<>();
                                    if(fc.contains("Components."+identifier+".Animations."+script+".animation")) {
                                        frames = fc.getStringList("Components."+identifier+".Animations."+script+".animation");
                                    }

                                    int interval = fc.getInt("Components."+identifier+".Animations."+script+".interval");

                                    if(interval < 1) {
                                        interval = 2;
                                    }

                                    int position = fc.getInt("Components."+identifier+".Animations."+script+".position");

                                    boolean continious = fc.getBoolean("Components."+identifier+".Animations."+script+".continious");
                                    boolean reverse = fc.getBoolean("Components."+identifier+".Animations."+script+".reverse");
                                    fancyItemStack.startAnimation(frames, params.getPlayer(), interval, position, this, continious, reverse);
                                    break A;
                                }
                            }
                        }
                    }
                }
            }
        }

        //Handles all components generated by the plugin as well as generated components from file if this component is inside of an editor.
        //If inside an editor generated components will have some attributes linked to them by the plugin. If not inside an editor, generated components
        //will not have any attributes linked to them. 
        A:for(Attribute attribute : attributes) {
            for(AttributeOccasion attributeOccasion : attribute.getAttributeOccasions()){
                for(AttributeOccasion attributeOccasion2 : attributeOccasions) {
                    if(attributeOccasion.equals(attributeOccasion2)) {
                        attribute.getAttributeFunction().call(params);
                        continue A;
                    }
                }
            }
        }
    }

    //This method is used to move the cursor in list cycleables. 
    public void performCursorMove(int delta, Player p) {
        if(fancyItemStack == null) {return;}
        FancyLore fancyLore = fancyItemStack.getFancyLore();
        if(fancyLore == null) {return;}

        fancyLore.moveCursor(delta, p);
    }

    public void setCursorPosition(int n, Player p) {
        if(fancyItemStack == null) {return;}
        FancyLore fancyLore = fancyItemStack.getFancyLore();
        if(fancyLore == null) {return;}

        fancyLore.setCursorPosition(n, p);
    }

    public int getSlot() {
        return basicSlot;
    }

    public FancyLocation getFancyLocation() {
        return fancyLocation;
    }

    public FancyItemStack getFancyItemStack() {
        return fancyItemStack;
    }

    public void setFancyItemStack(FancyItemStack fancyItemStack) {
        this.fancyItemStack = fancyItemStack;
    }

    public void setFancyLocation(FancyLocation fancyLocation) {
        this.fancyLocation = fancyLocation;
    }

    public void setDisplayType(FancyDisplayType fancyDisplayType) {
        this.fancyDisplayType = fancyDisplayType;
    }

    public void setIdentifier(String identifier) {
        this.identifier = identifier;
    }

    public String getIdentifier() {
        return identifier;
    }

    public void setIsCopied(boolean copied) {
        this.copied = copied;
    }

    public boolean isCopied() {
        return copied;
    }

    public void setID(int ID) {
        this.ID = ID;
    }

    public int getID() {
        return ID;
    }

    public FancyDisplayType getFancyDisplayType() {
        return fancyDisplayType;
    }
}
公共类FancyComponent{
//FancyComponent类表示放置在FancyUI中的单个项。
//它处理诸如动画、项目堆栈构建和事件处理之类的事情
//允许FancyUI处理这些组件的加载和删除。
//FancyComponents由API用户使用LoadFunction添加到FancyUI中。
//它们也可以从FancyUI文件生成。
私人幻想;
私有FancyItemStack FancyItemStack;
专用FancyDisplayType FancyDisplayType;
私有字符串标识符=null;
私有int ID=0;
私有int basicSlot=0;
私有布尔复制;
公共FancyComponent(){
fancyDisplayType=fancyDisplayType.DYNAMIC;
}
公共FancyComponent副本(FancyLocation newLocation){
FancyComponent newComponent=新的FancyComponent();
setDisplayType(fancyDisplayType);
newComponent.setID(ID);
setFancyItemStack(fancyItemStack);
newComponent.setFancyLocation(新位置);
setAttributes(attributes);
newComponent.setIdentifier(标识符);
返回新组件;
}
//方法在FancyUI决定加载新的FancyComponents时调用。
//当调用openInventory并生成新组件时,就会发生这种情况。
//此方法应该可以启动未来的动画。它还应该处理ItemStack的放置。
//此处的布尔值表示是否已成功添加。这在
//FancyUI以跟踪所有活动部件,而不是一次关闭屏幕。
公共布尔addToUI(库存清单、播放器p、文件配置fc、文件配置fc2){
如果(fancyLocation==null){return false;}
返回addToUI(库存、p、fancyLocation、fc、fc2);
}
公共布尔addToUI(库存清单、播放器p、FancyLocation FancyLocation、文件配置fc、文件配置fc2){
如果(fancyItemStack==null){return false;}
FancyUI FancyUI=fancyLocation.getFancyUI();
FancyLocation masterFancyLocation=fancyUI.getFancyData().getCurrentFancyLocation();
如果(!fancyLocation.isInView(masterFancyLocation,fancyDisplayType)){返回false;}
int basicSlot=fancyLocation.getBasicLocation(masterFancyLocation.getX(),masterFancyLocation.getY(),fancyDisplayType);
if(basicSlot<0 | | basicSlot>=inventory.getSize()){return false;}
this.basicSlot=basicSlot;
ItemStack ItemStack=fancyItemStack.buildItemStack(p,fc2);
如果(fc!=null){
如果(fc.包含(“组件”+标识符+“.Animations”)){
用于(字符串动画:fc.getConfigurationSection(“组件”+标识符+“.Animations”).getKeys(false)){
if(fc.getBoolean(((“组件“+标识符+”.Animations“+动画+”.continious”)){
列表帧=新的ArrayList();
如果(fc.包含(“组件”+“标识符”+“.Animations”+“动画”+“.animation”)){
frames=fc.getStringList(“组件”+“标识符”+“动画”+“动画”+“动画”);
}
int interval=fc.getInt(“组件”+“标识符”+“.Animations”+“动画”+“.interval”);
如果(间隔<1){
间隔=2;
}
int position=fc.getInt(“组件”+“标识符”+“.Animations”+“动画”+“.position”);
boolean continious=fc.getBoolean(“组件“+标识符+”.Animations“+动画+”.continious”);
boolean reverse=fc.getBoolean(“组件“+标识符+”.Animations“+动画+”.reverse”);
fancyItemStack.startAnimation(帧、p、间隔、位置、此、连续、反向);
打破
}
}
}
}
if(fancyLocation.getFancyUI().getFancyData().isPlayerInventory()){
如果(fancyItemStack.getCustomName().getFancyStringAnimations().length>0){
fancyItemStack.startAnimation(fancyItemStack.getCustomName().getFancyStringAnimations()[0].getFrames(),p,4,0,this,true,false);
}
}
存货.setItem(基本批次、itemStack);
返回true;
}
//方法仅重新加载此组件。在fancyLore中循环时使用。如果函数进行了更改
//对于其他组件,必须调用FancyUI中的reload方法才能完全重新加载页面。
公共无效重新加载(玩家p){
FileConfiguration fc=DataHandler.getFile(96,p.getUniqueId().toString(),false,“数据”,“用户”);
ItemStack ItemStack=fancyItemStack.buildItemStack(p,fc);
if(fancyLocation==null){
返回;
}
if(fancyLocation.getFancyUI().getFancyData().isPlayerInventory()){
p、 getInventory().setItem(基本批次、itemStack);
返回;
}
fancyLocation.getFancyUI().getFancyData().getInventory().setItem(基本批次、项目堆栈);
}
//方法在FancyUI删除其他FancyComponents上的所有信息时调用。
//当调用openInventory并生成新组件时,就会发生这种情况。
//确保此方法清理将来的动画,使它们不会四处抛出空指针。
//ItemStack本身是rem