1.what we are planning to do :
Reuse the ManifestEditor to open the MANIFEST.MF file, and add our features to the first OverviewPage.
2.what we already have known and done :
It's dangerous to use the internal classes and APIs, so we create a ManifestEditorNew which extends ManifestEditor.
import org.eclipse.pde.internal.ui.editor.plugin.ManifestEditor;
import org.eclipse.pde.internal.ui.editor.plugin.OverviewPage;
public class TheNewManifestEditor extends ManifestEditor{
//it's strange that the default fist page is not the OverviewPage,so we override this method
#Override
protected String computeInitialPageId() {
return OverviewPage.PAGE_ID;
}
}
3.what Exception we meet :
The NullPointerException.
Once our TheNewManifestEditor gained focus, the give us an NPE, but we can not find ant clues which caused this.
You probably need to called super.computeInitialPageId() because it looks like it does some set up.
Note: The reason the overview page is not always shown is because the editor remembers the the last page you looked at and shows you that. It will default to the overview page the first time the manifest is edited.
Just extending an internal class does not remove the fact that you are using internal Eclipse classes which violates the Eclipse API Rules of Engagement. Internal classes can and do change and sometimes even disappear altogether, you are likely to have a lot of trouble when moving between Eclipse releases.
Related
MyHUD.h
UCLASS()
class FPS_API AMyHUD : public AHUD
{
GENERATED_BODY()
UPROPERTY(EditDefaultsOnly, Category = Gameplay)
class UUserWidget* DefaultWidget;
...
}
I make Blueprint BP_MyHUD extends MyHUD and Widget Blueprint. The problem is, the DefaultWidget in BP_MyHUD is set None after i restart UE4 program or compile using button in toolbar at Blueprint editor. How can i fix the value of DefaultWidget in BP_MyHUD?
By default variables are set to "Private" and thus can't be modified in derived classes.
Try putting this UPROPERTY after you say public: (you could also use protected:)
UCLASS()
class FPS_API AMyHUD : public AHUD
{
GENERATED_BODY()
public:
UPROPERTY(EditDefaultsOnly, Category = Gameplay)
class UUserWidget* DefaultWidget;
...
}
Also I am unsure of the EditDefaultsOnly specifier when it comes to blueprints. My understanding was without
BlueprintReadWrite
You could not edit the variables in blueprints. But if you've been using this with success with other variables it is likely not the problem.
A bit late to the party, but here's the answer:
It's not possible.
Non-BindWidget pointers with EditDefaultsOnly indeed generate a selector in the Details panel, but this selector is not meant to select a widget inside our component's archetype. It's meant to select a widget outside an instance of our component (it also need to be public and maybe a BlueprintReadWrite too). In this case, the value you put in the selector indeed stay across builds.
Sadly, this error-inducing selector appearing anyway means that two things aren't quite working properly around this behaviour :
At the moment UE clears the selector when you're building, it should really display a warning/error explaining why
You shouldn't really be able to put EditAnywhere/EditDefaultsOnly on a non-BindWidget property, only a EditInstanceOnly... yet there's no warning/error either =(
(credits to #Bohdon Sayre from BenUI's discord community for helping me on this one)
I am having an issue in Eclipse (with Dagger 1 still).
In dagger, for dependency injection (javax.inject), you create a Module class, with provides methods, like this:
#dagger.Module
class FooModule {
#dagger.Provides
Something provideSomething() {
return new Something();
}
}
And this will generate a class (using annotation processing) called FooModule$$ModuleAdapter$ProvideSomethingProvidesAdapter.
If I set a breakpoint in a provideSomething method in FooModule class (my code), Eclipse almost always actually stops on that same line number in the FooModule$$ModuleAdapter$ProvideSomethingProvidesAdapter class instead.
Does anyone know how to avoid this problem? I suspect this is likely an Eclipse issue where it is somehow is mapping the generated file to what it thinks is the "source" file, but that's of course not what I want.
Is there perhaps some setting in eclipse to avoid this problem?
I am developing a couple of custom widgets that I would like to be able to use with UiBinder. Unfortunately I keep wasting my life away with chasing down the following error:
No class matching "..." in urn:import:...
This seems to be the catch-all exception that is thrown any time there is any error in the class that prevents the GWT compiler from processing it. This includes anything in the class's entire dependency tree.
To save myself and anyone of you who is running into the same issue some time and pain, let's compile a list here of the most unexpected and hard to find causes for this. I'll start with my latest one, which has made me decide to post this here.
I was using a CellList thusly:
private static RelationshipViewerUiBinder uiBinder = GWT.create(RelationshipViewerUiBinder.class);
#UiField(provided=true)
CellList<String> prioritisedDisplay;
public RelationshipViewer() {
prioritisedDisplay = new CellList<>(new TextCell());
initWidget(uiBinder.createAndBindUi(this));
}
note the Java 7 style <> on the CellList. Despite my IDE's protestations to the contrary, it turns out you DO need to explicitly say CellList< String> in that new call, or it wont compile and all you get is the above mentioned error. Thanks by the way, the existance of this question prompted me to scrutinise my code and probably saved me a couple of hours! This fixed it:
private static RelationshipViewerUiBinder uiBinder = GWT.create(RelationshipViewerUiBinder.class);
#UiField(provided=true)
CellList<String> prioritisedDisplay;
public RelationshipViewer() {
prioritisedDisplay = new CellList<String>(new TextCell());
initWidget(uiBinder.createAndBindUi(this));
}
I had written a component that used the GWT JSON functionality, but hadn't imported com.google.gwt.json.JSON into the module.
Thanks to your message here, this was only 2 hours down the drain...
I wrote a helper-class that this widget uses somewhere deep inside its dependency tree.
For this helper-class, I told Eclipse to auto-generate the hashCode() and equals(...) functions. The class contained a field of type double, for which Eclipse generates code that uses Double.doubleToLongBits().
Turns out GWT does not implement this method on its version of Double. But of course, neither does Eclipse detect this as a possible compile-error, nor does it cause any issues in Dev Mode if I use the widget inside the GWT-App's Java code rather than inside UiBinder.
3 hours down the drain... Great... Yay for helpful error messages.
UPDATE:
As of GWT 2.5.0 (RC1) GWT now supports Double.doubleToLongBits() rendering this particular error obsolete, but the general error mechanism of a missing JRE emulation remains and will probably manifest itself in a similarly unhelpful way.
I was trying to use a GwtQuery DragAndDropCellTree in a UiBinder .ui.xml, which was impossible as DragAndDropCellTree has no zero-arg constructor.
See more details
I'm implementing a variant of the JUnit New Test Suite Wizard, and instead of getting test classes from the current project, I need to get them from another source. They come to me as strings of fully-qualified class names.
Some of them may not yet exist in this user's workspace, let alone in the classpath of the current project. The user will need to import the projects for these later, but I don't want to mess with that in my wizard yet. I need to just add all classes to the new suite whether they exist yet or not.
For those classes that are already in this project's classpath, I can use IJavaProject.findType(String fullyQualifiedName) . Is there an analogous way to get ITypes for classes that are not (yet) visible?
I would be happy to construct an IType out of thin air, but ITypes don't seem to like being constructed.
I don't think that is possible: the Java Document Model interfaces are created based on the classpath.
Even worse, if the project do not exist in the users workspace, the resulting code would not compile, and that is another reason for not allowing the arbitrary creation of such constructs.
If I were you, I would try to help the user to import the non-existing projects in case of types are not available, thus avoiding the tackling with the Java Document Model.
For my purposes, creating a HypotheticalType and a HypotheticalMethod got the job done. I'm attaching an overview in case anyone else needs to follow this path.
First I created a HypotheticalType and had it implement the IType interface. I instantiated one of these at the proper spot in my modified wizard. Using Eclipse's Outline view I created a method breakpoint on all methods in my new class. This let me detect which methods were actually getting called during execution of my wizard. I also modified the constructor to take, as a String, the name of the class I needed the wizard to handle.
Almost all of the new methods are ignored in this exercise. I found that I could keep the default implementation (return null or return false in most cases) for all methods except the following:
the constructor
exists() - no modification needed
getAncestor(int) - no modification needed, but it might be useful to return the package of my hypothetical class, e.g. if my class is java.lang.Object.class, return java.lang.
getDeclaringType() - no modification needed
getElementName() - modified to return the class name, e.g. if my class is java.lang.Object.class, return Object.
getElementType() - modified to return IJavaElement.TYPE
getFlags() - not modified yet, but might be
getMethod(String, String[]) - modified to return a new HypotheticalMethod(name)
getMethods() - modified to return new IMethod[] { new HypotheticalMethod("dudMethod") }
In the process I discovered that I need to be able to return a HypotheticalMethod, so I created that type as well, inheriting from IMethod, and used the same techniques to determine which methods had to be implemented. These are the only methods that get called while this wizard runs:
The constructor - add a String parameter to bring in the name of the method
exists() - no modification needed
isMainMethod() - no modification needed
That covers the solution to my original question. Zoltán, I'll be doing as you suggested in an upcoming iteration and trying to assist the user in both the case in which the desired class is not yet in this project's classpath, and the case in which the desired class is in some project not yet in the workspace.
I've been going through the documentation for creating Prism applications and setting up the Shell seems to be split into 2 methods, CreateShell() and InitializeShell()
For CreateShell I simply have:
protected override DependencyObject CreateShell()
{
return ServiceLocator.Current.GetInstance<Shell>();
}
The documentation says that code is needed in the IntializeShell() method to ensure it is ready to be displayed. The following is given as an example:
protected override void InitializeShell()
{
Application.Current.MainWindow = (Window)this.Shell;
Application.Current.MainWindow.Show();
}
I have noticed however that if I omit the first line and just call the Show() method it seems to work (MainWindow already appears to have Shell assigned to it). Can you tell me why this is the case, and why we still need to explicity set the MainWindow property here?
Also as I did not specifically register Shell to an interface within the container, how is it able to resolve Shell in CreateShell()?
Question 1: Why does just calling Show() seem to work and why is Application.Current.MainWindow seem to be populated?
There are a few things you should check here. In a typical WPF application, the type for the main window can be specified in the App.xaml. If it is specified, WPF will instantiate one of those for you. This is not desirable because WPF won't use your container to instantiate your shell and any dependencies won't be resolved.
When you run that first line of code in InitializeShell, you'd be replacing the WPF-instantiated Shell object with the one you manually instantiated.
I looked at the code for the MEF and Unity bootstrappers and I don't see anywhere that MainWindow is being set, but I don't know if you might have customized the base bootstrappers, so that's something else to look for.
Show() works because you are simply showing the window you instantiated and the WPF-instantiated one isn't shown. This is my theory, but without seeing your code, it'd be tough to say for sure.
Question 2: How can Unity resolve something that hasn't been registered?
Unity can always resolve a concrete type, regardless of registration. It cannot resolve non-concrete classes that haven't been mapped to a concrete type. This is why Resolve<Shell> works, but Resolve<IMyInterface> doesn't unless you register a type.