Java: GetResource from different folder - javafx

I am trying to make 3 folders in a Javafx application. I have a Views folder which will contain my views, and I want to load an fxml file saved inside Views. I wrote this code inside start method:
Parent root = FXMLLoader.load(getClass().getResource("/Views/ProductView.fxml"));
My folders are structured as follows:
Apparently GetResources() can't find my file. What am I doing wrong?

Problem is that loader cannot find fxml file ...
So, load method can be either empty or gets Inputstream argument.
And this should work:
FXMLLoader loader = new FXMLLoader();
FileInputStream fileInputStream = new FileInputStream(new File("src/main/java/CRUD/bnkseekCRUD.fxml"));
Parent root = loader.load(fileInputStream);
At least it works for me. )))

try something like this something like this
Parent root=FXMLLoader.load(getClass().getClassloader().getResource("application/Models/Views/ProductView.fxml")

Related

Application works in Eclipse but doesn't work after exporting as runnable JAR [duplicate]

This question already has an answer here:
How do I determine the correct path for FXML files, CSS files, Images, and other resources needed by my JavaFX Application?
(1 answer)
Closed 2 years ago.
My project is running properly in eclipse but when I am creating a jar file of this project and trying to run it through cmd it is showing "Location is not set" error.
My project structure is:
The Method is (Running in eclipse):
#FXML
private void RegularCustomer(ActionEvent event) throws Exception{
Stage stage = (Stage) dailySales.getScene().getWindow();
Scene scene = dailySales.getScene();
FXMLLoader loader = new FXMLLoader(getClass().getResource("../customer/CustomerHome.fxml"));
System.out.println(loader.getLocation());
scene.setRoot(loader.load());
stage.setScene(scene);
stage.show();
}
What is wrong with this code?
There are some relative questions but they are different from it. Their code didn't run in IDE but my code run in IDE.
FYI: I made some changes in folder structure and was able to run successfully. But that structure was horrible because I put all my FXML files and controllers in same package.
When you use getClass().getResource(...) you are loading a resource, not specifying a path to a file. In the case where the class loader loads classes from the file system, these essentially equate to the same thing, and it does actually work (though even then there's no technical reason it has to). When the class loader is loading classes by other mechanisms (and probably in all cases anyway), then it's important to pay attention to the Java specifications for a resource.
In particular, note:
Resources, names, and contexts
A resource is identified by a string consisting of a sequence of
substrings, delimited by slashes (/), followed by a resource name.
Each substring must be a valid Java identifier. The resource name is of the form shortName or shortName.extension. Both shortName
and extension must be Java identifiers.
(My emphasis.) Since .. is not a valid Java identifier, there's no guarantee of this resource being resolvable. It happens that the file system class loader resolves this in the way you expect, which is why it works in your IDE, but the implementation of getResource(...) in the jar class loader does not implement this in the way you are hoping.
Try
FXMLLoader loader = new FXMLLoader(getClass().getResource("/sm/customer/CustomerHome.fxml"));
Using controller locations to load FXML:
Since you have organized your code so that each FXML is in the same package as its corresponding controller file (which I think is a sensible way to do things), you could also leverage this in loading the FXML: just load the FXML "relative to its controller":
FXMLLoader loader = new FXMLLoader(CustomerHomeCtrl.class.getResource("CustomerHome.fxml"));
This seems fairly natural in this setup, and the compiler will check that you have the package name for CustomerHomeCtrl correct at the point where you import the class. It also makes it easy to refactor: for example suppose you wanted to split sm.admin into multiple subpackages. In Eclipse you would create the subpackages, drag and drop the FXML and controllers to the appropriate subpackages, and the import statements would automatically be updated: there would be no further changes needed. In the case where the path is specified in the getResource(...), all those would have to be changed by hand.
A bit late but this can maybe help someone. If you are using IntelliJ, your resources folder may not be marked as THE resources folder, which has the following icon:
This is the way I fixed it:

One controller to 2 fxmls (JavaFX)

Is possible to connect two FXML (JavaFX) files to one controller?
I can't do this with changing "fx:controller" in each FXML file...
Any ideas?
Yes, you can do this. Although, it can be done, I do not recommend this approach.
Don't place a fx:controller attribute in either FXML. Create a new controller and set the same controller into separate FXMLLoader instances.
CustomerDialogController dialogController =
new CustomerDialogController(param1, param2);
FXMLLoader summaryloader = new FXMLLoader(
getClass().getResource(
"customerSummary.fxml"
)
);
summaryLoader.setController(dialogController);
Pane summaryPane = (Pane) summaryLoader.load();
FXMLLoader detailsLoader = new FXMLLoader(
getClass().getResource(
"customerDetails.fxml"
)
);
detailsLoader.setController(detailsController);
Pane detailsPane = (Pane) detailsLoader.load();
SplitPane splitPane = new SplitPane(
summaryPane,
detailsPane
);
I want to create one controller, because I have problem with sending data beetwen controlers
IMO using a shared controller just to share data is not the preferred solution for this.
Instead, either share the data between multiple controllers, for examples of this see:
Passing Parameters JavaFX FXML
There is a further example here:
JavaFX8 list bindings similar to xaml
Even better, see:
Applying MVC With JavaFx
https://edencoding.com/mvc-in-javafx/
Use the fx:root construct instead of fx:controller. It is explained in the Custom Components section of the FXML docs. I have used it in this example for my students if you want a bigger code example.
Using this approach, creating views and controllers will be a lot easier and flexible. You will be able to share data between and connect controllers like you would any other objects in your application (for example: by passing data via the constructor or setter methods).
If you're using SceneBuilder you'll simply need to remove the controller reference and check the box "Use fx:root". Then rework your code as shown in the examples.

SonataAdminBundle new block type

Did anybody create new block type for SonataAdminBundle using extend bundle? I'm trying to do so but it only works if I add service directly in original block.xml. Anything change in block.xml under config directory in MyBundle (extended SonataAdminBundle) has no effect.
Any one has solution? Plz help!!!
Are you sure that your XML file is correctly loaded in your own bundle?
It must be done in the load() method declared in file MyBundle\DependencyInjection\MyBundleExtension.php:
$loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('block.xml');

calling a method from a java file inside a jar

I have a jar file, which I dynamically load during execution of my java file (say my.java).
I do it this way:
File newFile = new File("path");
JarFile newJar= new JarFile(newFile);
Now there is a particular java file inside this jar, which I know the name of (say known.class).
I want create an object of this known.class, and call a method inside it from my.java.
I am not sure how to go about this. Can any one help?
I tried looking online, but didn't find anything helpful.
Thanks.
You need a .class file (compiled java code) inside the jar, not a .java file. If you have this, add the .jar to your classpath, or to one of the directories in your classpath, and then you can simply reference the Object from your Java code.
Ie:
MyObject newObj = new MyObject();
Here's how your specify the jar in the classpath:
java -classpath ".;myjar.jar" org.mine.MyClass
Edit: Since you don't want to change the classpath, try something like this:
File file = new File("/path/to/myjar.jar");
URL url = file.toURL();
URL[] urls = new URL[]{url};
ClassLoader cl = new URLClassLoader(urls);
Class cls = cl.loadClass("org.mine.myclass")
You need to create a URLClassLoader not a JarFile. Reading the doc for ClassLoader will get you going, and also for Class.

How can I instantiate class from a swf?

I have an FLA file with objects in the library which I have set to be "classes" (In CS3, right click an item in the library select properties, make sure it's set to export for action-script, and has a class name)
For this exercise, let's call the class "MyClass"
If I publish that FLA to an SWC and SWF:
I can load the SWC statically, and instantiate "MyClass" by simply doing:
var inst:MyClass = new MyClasS();
Now, the problem: I'd like to be able to do this at runtime by loading the SWF file using a loader object.
I understand how to access instances which have been created by hand in the FLA before publishing, but what I want to be able to do, is create new instances of the class "MyClass".
I can get a "MovieClip" representing the swf file, I can add it to my displaylist, but I can't seem to get at the classes contained therein. (I hope this makes sense)
Any suggestions for how to attack this would be much appreciated.
Edit : Format code
To complete Christian's answer:
var cls : Class = loader.contentLoaderInfo.applicationDomain.getDefinition("ClassName");
var instance : Object = new cls();
Additionally, it's worth noting that you won't get strong typing (ie. it must be declared as Object) unless the class implements interface which is also defined in your main application. You will then be able to declare the instance variable as the interface and have compile-time access to it's members.
Have a look here; you should be able to extract a class reference by using Loader.contentLoaderInfo.applicationDomain.getDefinition("MyClass").

Resources