Bukkit - ShapedRecipe is deprecated - java

I want to make custom item with custom recipe. I created class with 2 methods, item and customRecipe.
My class looks like this
public class LifeCrystal implements Listener {
private ItemStack item = new ItemStack(Material.DIAMOND);
private ItemMeta meta = item.getItemMeta();
private Plugin plugin = BelieveMe.getPlugin(BelieveMe.class);
public void Item(Player player){
meta.setDisplayName(ChatColor.GOLD + "Life Crystal");
ArrayList<String> lores = new ArrayList<>();
lores.add("Increase your life points");
lores.add("...or revive someone");
meta.setLore(lores);
item.setItemMeta(meta);
}
public void customRecipe(){
ShapedRecipe r = new ShapedRecipe(item);
r.shape(" E ", "LAL", "DGD");
r.setIngredient('E', Material.EMERALD);
r.setIngredient('L', Material.LAPIS_LAZULI);
r.setIngredient('A', Material.GOLDEN_APPLE);
r.setIngredient('D', Material.DIAMOND);
r.setIngredient('G', Material.GOLD_INGOT);
plugin.getServer().addRecipe(r);
}
}
"new ShapedRecipe(item)" is crossed and my error message is "ShapedRecipe is deprecated". I searched for that and find some information about NamespacedKey. I really don't know what to do now

It appears as if you just need to change your ShapedRecipe object constructor (according to the JavaDocs). Changing it to something like:
NamespacedKey nsKey = new NamespacedKey(plugin, "unique_key_here");
ShapedRecipe r = new ShapedRecipe(nsKey, item);
should work on the latest version (1.14.4-R0.1-snapshot at time of writing). There is also a guide written on the official Spigot wiki, linked here.
Quick note: From researching, seems the key HAS to be unique per 1.11 requirements, so make sure you have something that doesn't conflict with any vanilla recipes.

Related

How can I add a new Item to fabric?

I'm trying to code a mod, which adds a new Item to the game and I'm following a tutorial on youtube. I also looked everything up on the fabric website, but the code doesn't work.
Here is the code I used. It is from the fabric wiki:
public static final Item CUSTOM_ITEM = new Item(new FabricItemSettings().group(ItemGroup.MISC));
#Override
public void onInitialize() {
Registry.register(Registry.ITEM, new Identifier("tutorial", "custom_item"), CUSTOM_ITEM);
}
Somehow in my library the .group() function doesn't exist and that's the same with other functions.
Do I have to download something or how can I fix this?
I tried adding a new Item to my mod, but it didn't work.

Vaadin change value from nested Layout

I use Vaadin 14 and would know whether it is possible to report changes in the nested list to objects in the main view.
A rough example is shown in the picture. Above you can see the sum as size (here 2), if I press Delete it should change to 1.
Is that possible and how?
concept
I don't have any code yet, it's a thought where I would like to have a hint about what would be possible, e.g. Observer Pattern or something, but code could look something like this
code:
#Rout("")
public class MainView extends VerticalLayout {
private List<CustomDetails> customDetails = new ArrayList<>();
public MainView(){
final var form = new FormLayout();
customDetails.forEach(form::add);
add(H1("Header"), form)
}
}
public class CustomDetails extends Details{
private CustomForm customForm;
private final Service service;
public CustomDetails(){
customForms = new CustomForm(service.getListOfObjects());
this.setContent(customForms)
}
}
public class CustomForm extend FormLayout{
private FormLayout formLayout = new FormLayout();
private List<Object> objects = new LinkedList<>();
public CustomForm(List<Object> list){
this.objects = list;
setUp();
add(new Paragraph("SUM: "+ list.size()), layout);
}
private void setUp(){
objects.forEarch(o->{
....
layout.add(...)
})
}
}
In Vaadin there is an utility class Binder which is used to bind data to forms. If your use case is related to this, i.e. your so called nested layout is in fact a form and objects you refer to are data beans you want bind into that form. I recommend to study that first.
If you have list editor, I would also investigate if it fits your application to implement it with Grid or IronList/VirtualList, which is backed by DataProvider. Say you edit one item, and after saving the item, you can call dataProvider.refreshItem(item) to update the view.
Observer Pattern or something...
Yes, that is a solution. It is a lot of work and has been done before.
One such library is Beanbag.
Note: I wrote this (or rather, I started writing it a day ago).
EDIT:
As of this edit, we have the ObservableCollection interface. You can use it like so:
// You have a collection called "strings".
// Wrap it in an ObservableCollection.
final ObservableCollection<String, Collection<String>, BasicObservableCollection.Default<String, Collection<String>>> observableStrings = ObservableCollections.observableCollection(strings);
// Add a removed observer.
observableStrings.addElementRemovedObserver(observation -> System.out.println("\"" + observation.getValue() + "\" was removed.");
// Remove an element.
observableStrings.remove("hello");
If you need the wrapper to have List methods, just wait until tomorrow evening EST. I'll have the code up by then and will update this post accordingly.

How do I suggest that the user wrap this parameter in a method call?

A common problem we find in code review is people writing this:
assertThat(thing, nullValue());
instead of this:
assertThat(thing, is(nullValue()));
In order to catch it sooner, I thought I'd try writing a custom error-prone check. This is a poorly documented area though so I've been doing so by digging inside GitHub for working examples.
I have so far:
#AutoService(BugChecker.class)
#BugPattern(
name = "AssertThatThingNullValue",
summary = "`assertThat(thing, nullValue())` doesn't sound like English, wrap `nullValue` in `is`"
severity = WARNING)
public class AssertThatThingNullValue extends BugChecker implements MethodInvocationTreeMatcher
{
private static final Matcher<ExpressionTree> ASSERT_THAT = staticMethod()
.onClassAny("org.hamcrest.MatcherAssert", "org.junit.Assert")
.named("assertThat");
private static final Matcher<ExpressionTree> NULL_VALUE = staticMethod()
.onClass("org.hamcrest.Matchers")
.named("nullValue");
private static final Matcher<ExpressionTree> NULL_VALUE_INVOCATION =
methodInvocation(NULL_VALUE);
private static final Matcher<ExpressionTree> ASSSERT_THAT_THING_NULL_VALUE =
methodInvocation(ASSERT_THAT, MatchType.LAST, NULL_VALUE_INVOCATION);
#Override
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state)
{
if (ASSSERT_THAT_THING_NULL_VALUE.matches(tree))
{
buildDescription(tree)
.addFix(SuggestedFixes.somethingGoesHere(...))
.build();
}
return Description.NO_MATCH;
}
}
My problem is I can't figure out how to build the suggested fix from the available methods in SuggestedFixes. I'm wondering whether this API just isn't fleshed out well or whether I'm just going down the wrong track entirely and should be writing the check in a better way?

Android: Custom Parcelable Class Crashes App Without Throwing Exception

I've got an Android app with custom objects which implement the Parcelable interface. They way I have it set it up is that my program initially creates an ArrayList of a custom class Products from a file in the bundle. I can see and confirm that the arraylist and it's instance variabels are populated appropriately. This class has several instance variables along with one being another ArrayList but with the String class. Remember that fact.
I am trying to pass the ArrayList<Product> into a new activity like so:
try {
Intent i = new Intent(RootActivity.this, ProductsActivity.class); //Intent from this activity to the next
i.putParcelableArrayListExtra("Products", app_products); //Puts my ArrayList<Class A> as an extra
startActivity(i); //Launch the activity
}
catch(Exception e){
Log.d("Activity Error", "Error Here:" + e.getMessage());
}
I am collecting the information back from the intent in my new activity by pulling the ArrayList out by using
app_products = getIntent().getParcelableArrayListExtra("Products");
For my custom class, it looks something like this, along with the implemented Parcelable methods.
public class Product implements Parcelable{
private String name;
private String cost;
private ArrayList<String> similarItems;
public Product{
name = null;
cost = null;
similarItems = new ArrayList<String>();
}
public Product(String name, String cost){
this();
this.name = name;
this.cost = cost;
}
public addSimilarItem(String item){
similarItems.add(item);
}
public static final Parcelable.Creator<Product> CREATOR
= new Parcelable.Creator<Product>()
{
public Product createFromParcel(Parcel in) {
return new Product(in);
}
public Product[] newArray(int size) {
return new Product[size];
}
};
public int describeContents(){
return 0;
}
private Product(Parcel in){
name = in.readString();
cost = in.readString();
similarItems = in.readArrayList(String.class.getClassLoader());
}
public void writeToParcel(Parcel out, int flags){
out.writeString(name);
out.writeString(cost);
out.writeList(similarItems);
}
}
So this works well WITHOUT my String arraylist being added in the class
Comment out out.writeList(similarItems); and also similarItems = in.readArrayList(String.class.getClassLoader());
but once you add them back in into the class, the app crashes but it doesn't even throw a message for debugging. I've wrapped everything around try-catch statements and android doesn't even report the app crashed with the normal dialog on the springboard. I am truly at a loss.
It is worth mentioning that I've used some log statements to understand where the program is crashing despite the fact that android wont throw an exception. I can see that all of the items in my ArrayList undergoes the writeToParcelMethod and completes writing. The Product(Parcel in) method is never called. Lastly, I can also see the class I am launching the new activity from enters the Pause State and my new Activity is never created.
Let me know if I can provide any additional information.
Fairly certain your problem is the use of writeList(). writeList() seems to indicate that it follows the same contract as writeValue() for the items contained in the list. readList() however, seems to indicate that the values must be Parcelable (which String is not).
Either way, typically these calls have to be very specifically linked to their inverse (e.g. writeString() must be read in with readString(), not readValue()) so you should instead use the provided methods for reading/writing String Lists:
// Takes in a List<String> which may be null
out.writeStringList(similarItems);
// Returns either null or a new ArrayList<String> with the contents
similarItems = in.createStringArrayList();
These seemed to be due to some malformed XML which my app uses as a resource. Not sure why this was this issue but after many hours of hunting it down, I was able to remove the bad XML and will revisit this issue at a later date towards when I need to release the app.
Right now, I'm just gonna worry about continuing to develop it. I'll try to remember to check back here if I find anything interesting about my XML.

Weka: Supervised Discretize issue and error during attribute selection "Not enough training instances"

I've been learning the Weka API on my own for the past month or so (I'm a student). What I am doing is writing a program that will filter a specific set of data and eventually build a bayes net for it, and a week ago I had finished my discretization class and attribute selection class. Just a few days ago I realized that I needed to change my discretization function to supervised and ended up using the default Fayyad & Irani method, after I did this I began to get this error in my attribute selection class:
Exception in thread "main" weka.core.WekaException:
weka.attributeSelection.CfsSubsetEval: Not enough training instances with class labels (required: 1, provided: 0)!
at weka.core.Capabilities.test(Capabilities.java:1138)
at weka.core.Capabilities.test(Capabilities.java:1023)
at weka.core.Capabilities.testWithFail(Capabilities.java:1302)
at weka.attributeSelection.CfsSubsetEval.buildEvaluator(CfsSubsetEval.java:331)
at weka.attributeSelection.AttributeSelection.SelectAttributes(AttributeSelection.java:597)
at weka.filters.supervised.attribute.AttributeSelection.batchFinished(AttributeSelection.java:456)
at weka.filters.Filter.useFilter(Filter.java:663)
at AttributeSelectionFilter.selectionFilter(AttributeSelectionFilter.java:29)
at Runner.main(Runner.java:70)
My attribute selection before the change worked just fine, so I think that I may have done something wrong in my discretize class. My other part of this question relates to that, because I also noticed that my discretize class does not appear to really be discretizing the data; it's just putting all the numeric data into ONE range, not binning it strategically like the Fayyad & Irani should.
Here is my discretize class:
import weka.core.Instances;
import weka.filters.Filter;
import weka.filters.supervised.attribute.Discretize;
import weka.filters.unsupervised.attribute.NumericToNominal;
public class DiscretizeFilter
{
private Instances data;
private boolean sensitiveOption;
private Filter filter = new Discretize();
public DiscretizeFilter(Instances data, boolean sensitiveOption)
{
this.data = data;
this.sensitiveOption = sensitiveOption;
}
public Instances discreteFilter() throws Exception
{
NumericToNominal nm = new NumericToNominal();
nm.setInputFormat(data);
Filter.useFilter(data, nm);
Instances nominalData = nm.getOutputFormat();
if(sensitiveOption)//if the user wants extra sensitivity
{
String options[] = new String[1];
options[0] = options[0];
options[2] = "-E";
((Discretize) filter).setOptions(options);
}
filter.setInputFormat(nominalData);
Filter.useFilter(nominalData,filter);
return filter.getOutputFormat();
}
}
Here is my attribute selection class:
import weka.attributeSelection.BestFirst;
import weka.attributeSelection.CfsSubsetEval;
import weka.core.Instances;
import weka.filters.supervised.attribute.AttributeSelection;
public class AttributeSelectionFilter
{
public Instances selectionFilter(Instances data) throws Exception
{
AttributeSelection filter = new AttributeSelection();
for(int i = 0; i < data.numInstances(); i++)
{
filter.input(data.instance(i));
}
CfsSubsetEval eval = new CfsSubsetEval();
BestFirst search = new BestFirst();
filter.setSearch(search);
filter.setEvaluator(eval);
filter.setInputFormat(data);
AttributeSelection.useFilter(data, filter);
return filter.getOutputFormat();
}
public int attributeCounter(Instances data)
{
return data.numAttributes();
}
}
Any help would be greatly appreciated!!!
Internally Weka stores attribute values as doubles. It appears that an exception was thrown because every single instance in your dataset (data) is "missing a class", i.e. was given an internal class attribute value NaN ("not a number") for whatever reason. I would recommend to double-check if data's class attribute was created/set correctly.
I figured it out, it was my mistake of misunderstanding the description of the method "outputFormat()" in the Discretize class. I instead got the filtered instances from the useFilter() and that solved my problems! I was just giving the attribute selection filter the wrong type of data.

Categories