如何获取库存中单击项目的名称
How to get the name of a clicked item in an Inventory
因此,我需要使用 InventoryClickEvent 事件获取自定义清单中的自定义项的名称。我试图获取 Item Meta,但它 returns 是一个 NullPointerException。因此,我做了一个小的 if 语句来处理没有 Meta 和 If 语句被触发的点击项目。因此,该项目没有项目元,即使它有知识和显示名称。请注意,我不怎么处理库存,所以我对它有点陌生。另外,我在另一个 class 中设置了带有显示名称和知识的 Item Meta,但我认为这不会影响任何事情。这是我的 InventoryClickEvent class.
代码
public class clickEvent implements Listener
{
private Files files = new Files();
private KitPvP kit = KitPvP.getInstance();
private Kit kits = new Kit();
private InvUtils invUtils = new InvUtils();
@EventHandler
public void onInventoryClick(InventoryClickEvent e)
{
HumanEntity player = e.getWhoClicked();
Inventory inv = e.getClickedInventory();
ItemStack item = e.getCurrentItem();
if (player instanceof Player)
{
if (inv != null && inv.getContents() != null && !inv.getContents().equals(Material.AIR) && inv.getName() != null && !inv.getName().equalsIgnoreCase(""))
{
String name = ChatColor.stripColor(inv.getName());
if (name.equalsIgnoreCase("Kits: ") || name.equalsIgnoreCase("Kits:"))
{
try
{
if (!kit.getDataFolder().exists())
{
kit.getDataFolder().mkdirs();
}
File kFolder = files.getFolder("Kits");
if (!kFolder.exists())
{
files.createFolder("Kits");
}
File menu = files.getFolder("GUI Menu");
if (!menu.exists())
{
files.createFolder("GUI Menu");
}
if (!e.getCursor().hasItemMeta())
{
Logger.log("Clicked Item does not have Item Meta!");
return;
}
if (!e.getCursor().getItemMeta().hasDisplayName())
{
Logger.log("Clicked Item does not have Display Name!");
return;
}
String check1Name = ChatColor.stripColor(e.getCursor().getItemMeta().getDisplayName());
String check2Name = check1Name.replace(" Kit", "");
File gItem = files.getGuiItem(check2Name);
if (!gItem.exists())
{
Logger.log("Cannot find required Files!");
return;
}
String itemName = gItem.getName();
if (itemName.equalsIgnoreCase(check2Name))
{
kits.equipKit(player, itemName);
e.setCancelled(true);
}
} catch (Exception ex)
{
ex.printStackTrace();
}
}
}
}
}
}
理解您的问题有点困难,因为它需要信息,但请继续。
1) 我假设您使用您的事件来继承项目等,因此 e.getCursor()
解析为 Item
。您确定检索到的对象在创建、捆绑在事件中并传递时包含元数据吗?我的第一个想法是检查事件的发射器是否创建了正确的信息。
2) 在第一个 if 子句之前执行 e.getCurrentItem();
。这有点令人困惑,因为 return 对象似乎是一个 ItemStack
。您的命名约定应该重新审视。其余代码也是如此。 ItemStack
持有什么物品?为什么你不能从那里取回有问题的物品?
3) 如 #1 中所述,检查事件的发射器正在做什么。 ItemMeta
很可能因此而未发送。
也是一个快速提示。避免像那样的长方法体。试着把你的问题分解成更小的问题。这将使调试和维护过程变得更加容易。最后,避免像你这样对常量进行 String
相等性检查。而不是 someVar.equals("someConstant") 由于 "someConstant".equals(someVar)。这是避免 NPE 的一个很好的技巧。
就用这个
if(e.getCurrentItem() != null && e.getCurrentItem().getType() == Material.INK_SACK){
String name = e.getCurrentItem().getItemMeta().getDisplayName();
}
将Material.INK_SACK替换为目标项
就像@Starmixcraft 说的,使用这个:
if(e.getCurrentItem() != null && e.getCurrentItem().getType() == Material.INK_SACK){
String name = e.getCurrentItem().getItemMeta().getDisplayName();
}
但替换
e.getCurrentItem().getType() == Material.INK_SACK
与
e.getCurrentItem().getType().equals(Material.INK_SACK)
因此,我需要使用 InventoryClickEvent 事件获取自定义清单中的自定义项的名称。我试图获取 Item Meta,但它 returns 是一个 NullPointerException。因此,我做了一个小的 if 语句来处理没有 Meta 和 If 语句被触发的点击项目。因此,该项目没有项目元,即使它有知识和显示名称。请注意,我不怎么处理库存,所以我对它有点陌生。另外,我在另一个 class 中设置了带有显示名称和知识的 Item Meta,但我认为这不会影响任何事情。这是我的 InventoryClickEvent class.
代码public class clickEvent implements Listener
{
private Files files = new Files();
private KitPvP kit = KitPvP.getInstance();
private Kit kits = new Kit();
private InvUtils invUtils = new InvUtils();
@EventHandler
public void onInventoryClick(InventoryClickEvent e)
{
HumanEntity player = e.getWhoClicked();
Inventory inv = e.getClickedInventory();
ItemStack item = e.getCurrentItem();
if (player instanceof Player)
{
if (inv != null && inv.getContents() != null && !inv.getContents().equals(Material.AIR) && inv.getName() != null && !inv.getName().equalsIgnoreCase(""))
{
String name = ChatColor.stripColor(inv.getName());
if (name.equalsIgnoreCase("Kits: ") || name.equalsIgnoreCase("Kits:"))
{
try
{
if (!kit.getDataFolder().exists())
{
kit.getDataFolder().mkdirs();
}
File kFolder = files.getFolder("Kits");
if (!kFolder.exists())
{
files.createFolder("Kits");
}
File menu = files.getFolder("GUI Menu");
if (!menu.exists())
{
files.createFolder("GUI Menu");
}
if (!e.getCursor().hasItemMeta())
{
Logger.log("Clicked Item does not have Item Meta!");
return;
}
if (!e.getCursor().getItemMeta().hasDisplayName())
{
Logger.log("Clicked Item does not have Display Name!");
return;
}
String check1Name = ChatColor.stripColor(e.getCursor().getItemMeta().getDisplayName());
String check2Name = check1Name.replace(" Kit", "");
File gItem = files.getGuiItem(check2Name);
if (!gItem.exists())
{
Logger.log("Cannot find required Files!");
return;
}
String itemName = gItem.getName();
if (itemName.equalsIgnoreCase(check2Name))
{
kits.equipKit(player, itemName);
e.setCancelled(true);
}
} catch (Exception ex)
{
ex.printStackTrace();
}
}
}
}
}
}
理解您的问题有点困难,因为它需要信息,但请继续。
1) 我假设您使用您的事件来继承项目等,因此 e.getCursor()
解析为 Item
。您确定检索到的对象在创建、捆绑在事件中并传递时包含元数据吗?我的第一个想法是检查事件的发射器是否创建了正确的信息。
2) 在第一个 if 子句之前执行 e.getCurrentItem();
。这有点令人困惑,因为 return 对象似乎是一个 ItemStack
。您的命名约定应该重新审视。其余代码也是如此。 ItemStack
持有什么物品?为什么你不能从那里取回有问题的物品?
3) 如 #1 中所述,检查事件的发射器正在做什么。 ItemMeta
很可能因此而未发送。
也是一个快速提示。避免像那样的长方法体。试着把你的问题分解成更小的问题。这将使调试和维护过程变得更加容易。最后,避免像你这样对常量进行 String
相等性检查。而不是 someVar.equals("someConstant") 由于 "someConstant".equals(someVar)。这是避免 NPE 的一个很好的技巧。
就用这个
if(e.getCurrentItem() != null && e.getCurrentItem().getType() == Material.INK_SACK){
String name = e.getCurrentItem().getItemMeta().getDisplayName();
}
将Material.INK_SACK替换为目标项
就像@Starmixcraft 说的,使用这个:
if(e.getCurrentItem() != null && e.getCurrentItem().getType() == Material.INK_SACK){
String name = e.getCurrentItem().getItemMeta().getDisplayName();
}
但替换
e.getCurrentItem().getType() == Material.INK_SACK
与
e.getCurrentItem().getType().equals(Material.INK_SACK)