I'm trying to implement a new type of project based on this tutorial. The problem is that I want that my project be saved as a single file, with a custom extension, so all the content must reside on that file. Like project_name.cep (cep - custom extension project). I don't want to open a new type of file inside project, that file is my project, and I want to write nodes inside it.
This is an example of the ProjectFactory to use:
#ServiceProvider(service=ProjectFactory.class)
public class CustomProjectFactory implements ProjectFactory{
public static final String PROJECT_EXT = "cep";
//Specifies when a project is a project, i.e.,
#Override
public boolean isProject(FileObject projectDirectory) {
return PROJECT_EXT.equals(projectDirectory.getExt()); //assuming that getExt() give the file extension
}
//Specifies when the project will be opened, i.e., if the project exists:
#Override
public Project loadProject(FileObject dir, ProjectState state) throws IOException {
return isProject(dir) ? new CustomProject(dir, state) : null;
}
#Override
public void saveProject(final Project project) throws IOException, ClassCastException {
// leave unimplemented for the moment
}
}
The problem is that the FileChooser opened when I tried to open the project seems to be a DIRECTORIES_ONLY chooser, so a single file can't be opened.
Can be done? I really appreciate some example of how to do this and if is not to much to ask how to write nodes inside this single file and represent it in the explorer (just some advices).
Indeed NetBeans projects are identified on their directories.
The only way I see is to create a custom version of the NetBeans project module which allows to select files.
Related
I am creating a contacts application using Maven in Netbeans. For the operation of the program I want users to add and store images (contact avatars) in a folder /avatars and access them on a listener event. I can access images from within the ProjectRoot/src/main/resources/images directory, but cannot access ProjectRoot/avatars. Note: I do not want to store avatars in the resources directory because these will be user-added during the programs operation.
I have tried using getClass().getResource(avatarPath); as suggested in similar questions, but it has not worked. I have also tried adding the "avatars" directory to the POM as its own resource directory, but that has not worked either.
How can I access files/folders in the root directory of my project when using Maven?
listviewContacts.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Contact>() {
#Override
public void changed(ObservableValue<? extends Contact> observable, Contact oldValue, Contact newValue) {
String avatar = newValue.getAvatar();
String avatarPath = null;
if (avatar.isEmpty()) {
avatarPath = "/images/" + DEFAULT_AVATAR; // loads from ProjectRoot/src/main/resources/images
} else {
avatarPath = "/avatars/" + avatar; // won't load from ProjectRoot/avatars
}
try {
imageviewContact.setImage(new Image(avatarPath));
} catch (IllegalArgumentException ex) {
System.err.println("Could not locate " + avatarPath);
}
}
});
You are mixing 2 different things.
You can either have a classpath resource packed in jarfile along with your classes, or in a directory that is explicitly added java to java classpath(using java -cp commandline argument). That can be accessed via getClass().getResource.
Or you can load a file from arbitrary location, using java.io.File. Then your "projectRoot" is some folder in a filesystem, that you can either hardcode, configure by -DprojectRoot=C:/fun/with/files, or use some of relative paths.
Maven has nothing to do with it, as avatars "will be will be user-added during the programs operation".
Your users will not launch your IDE, right ?
The problem was in understanding where the different constructors of javafx.scene.image.Image begin their path.
When using the URL constructor for Image, the URL path will start in Maven's defined resources folder (/src/main/resources or whatever additional resource directories were added to the pom.xml file):
// the supplied string invokes the URL constructor
Image image = new Image("path/to/file");
When using the InputStream constructor for Image (via FileInputStream), the path will start at the root directory of the project/application:
// the FileInputStream invokes the InputStream constructor
Image image = new Image(new FileInputStream("path/to/file"));
I quite recently discovered a coding site, with coding contests : CodinGame, and in order to solve the problems, we have to hand them over only one file with a main (in the following example, the class Player), and if other classes are needed, we include them in this file.
For this purpose (and seen to be working for another coding site), I have downloaded intelliJ and the plugin CHelper in order to put all the source files into one java file (it is supposed to be the purpose of the CHelper plugin). The problem is: I don't understand how to use/setup this plugin for my coding site. I know it should work because another user of this site has already used the plugin for this purpose.
What I want
For a more detailed example of what I want, here is the class with a main:
// Class Player in file Player.java
public class Player {
public static void main(String[] args) {
System.out.println(new Cell(1,2).toString());
}
}
And this class Cell is in another java file :
// Class Cell in file Cell.java
public class Cell {
int x,y;
public Cell(int x, int y) {
this.x = x;
this.y = y;
}
public String toString() {
return "["+x+","+y+"]";
}
}
And I would like the plugin to merge the two (or more) java files in order to have this :
// Generated : 2 files merged into one file: Player.java
public class Player {
public static void main(String[] args) {
System.out.println(new Cell(1,2).toString());
}
// Class Cell merged in this file
public class Cell {
int x,y;
public Cell(int x, int y) {
this.x = x;
this.y = y;
}
public String toString() {
return "["+x+","+y+"]";
}
}
}
What I achieved
I installed IntelliJ correctly, and downloaded the CHelper plugin.
I installed the toolbar menu buttons linked to TopCoder (the site that this plugin is expressly made for), but the Launch TopCoder button throws a RuntimeException : cannot run program .../javaws no such file.
With some tasks downloaded from TopCoder, I succeeded in merging 2 files into one : TaskA.java into Main.java (with templates downloaded)
What would be ideal
If an Eclipse plugin could work like what I want, I would be very happy to know of it. In fact, that was what I was looking for at the beginning of my search, and I only found some plugin for the IntelliJ IDE.
So I finally found a way to do what I wanted: the guy who had done it shared me a link to the help I needed.
I am going to sum it up specifically for CodinGame here.
I- Toolbar buttons
The important buttons to add to the menu toolbar are
create new task
modify task
delete task
Edit project settings
Now, we have some buttons in the red rectangle :
II- Edit settings
Then we have to edit project settings :
set the default directory to your default package
output directory is for the generated source file
III- Create task
Next thing, we have to create a new task (green "+" button) and set it up using the advanced option. We add the tests input and known output with the button Edit tests. We say we want the generated file to be called Solution.java, and the class where we are going to write is going to be called CGXFormatter.java
We now have two files which have appeared in our package .../puzzle :
CGXFormatter.java with a method solve, which is where we are going to read the input and give our answer in the output
CGXFormatter.task, which contains the info on the test cases, etc. in order for the plugin to generate the source file
IV- Write your solution
For example, we are just going to print "This is the result" in our CGXFormatter class (but we could have created another class file and called it, it would have worked by copying the definition of the class in the generated solution class). Like this :
package com......puzzle;
import java.util.Scanner;
import java.io.PrintWriter;
public class CGXFormatter {
public void solve(int testNumber, Scanner in, PrintWriter out) {
out.println("This is the result");
}
}
V- Generate the solution
Last step: click on run. Then we have the directory generated which is created, and in it, we have the Solution.java file newly generated. We can read this :
import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Scanner;
/**
* Built using CHelper plug-in
* Actual solution is at the top
*
* #author XXX
*/
public class Solution {
public static void main(String[] args) {
InputStream inputStream = System.in;
OutputStream outputStream = System.out;
Scanner in = new Scanner(inputStream);
PrintWriter out = new PrintWriter(outputStream);
CGXFormatter solver = new CGXFormatter();
try {
int testNumber = 1;
while (true)
solver.solve(testNumber++, in, out);
} catch (UnknownError e) {
out.close();
}
}
static class CGXFormatter {
public void solve(int testNumber, Scanner in, PrintWriter out) {
out.println("This is the result");
}
}
}
VI- Last step
Okay, there still remains a little problem: in CodinGame, the solution class should not have public in front of it, so just put class Solution instead of public class Solution and you're done.
If you want, you can also put it in a script to do it automatically with a multirun (plugin to install in IDEA, also).
That's it, you're done.
VII- Edit Octobre 2019
If the plugin complains about not finding a net.egork.... class, you can add these steps that I found here
Update Intellij IDEA to the latest version. Secondly, you go to File
-> Settings... -> Plugins and search for the chelper plugin. It is required to run the task run configurations, and it supplies you with
the buttons on the toolbar, too. After you have done that, you should
be getting the error about impossibility to find and load class from
net.egork... Now you go to the jetbrains plugin site, search for
chelper plugin there, and download the latest zip archive. After
unzipping it, go to File -> Project Structure... -> Libraries -> + ->
Java, select recursively the folder you just unzipped until you get to
a bunch of jars that contain that missing class in the error. After
you have added those jars to your classpath, along with JDK, it should
be enough
As a side note, I remarked that the out.println didn't work as I intended (I don't know why), so I replaced it by System.out.println instead of using the proposed out object in the solve method.
I am trying to develop a module that can update my running Java Desktop App.
The problem is that I have to replace the actual running jar with another jar, all the while displaying an image and a progress bar with the remaining time of the update process.
One solution I thought about is that I can put a jar in my main jar, and when launching the update process, to extract that second jar which will display the image and the progess bar, and also which will replace the old main jar with a new main jar.
My question is if this is possible and how can I do it.
I do not have a lot of experience with java and java packaging so if you have any examples or links, it would be of great help for me.
Thank you very much.
R.
Run this code when press UPDATE button ..
if(Desktop.isDesktopSupported()){
try {
Desktop.getDesktop().open(new File("update.jar"));
System.exit(0);
} catch (IOException ex) {
}
}
This will open update.jar and close main.jar. Now run this code from main class of update.jar
//wait sometime for terminate main.jar
try{
Thread.sleep(5000);
} catch(Exception e){
e.printStackTrace();
}
if(isUpdateVersionAvailable()) { //first check update from database
if(copyMainJarFileFromServer()){ //copy newMain.jar from server and paste
new File("main.jar").delete(); //delete main.jar
rename(new File("newMain.jar")); //rename newMain.jar to main.jar
}
}
boolean isUpdateVersionAvailable() {
//todo
}
boolean copyMainJarFileFromServer() {
//todo
}
void rename(File file){
file.renameTo(new File("main.jar"));
}
You can have a starter jar that checks for updates and launches the app from the main jar.
It will show start logo, an image, that standard java can display at start-up.
The start0er could also be used to restart the app in another interface language.
package starter;
...
public class StarterApp {
public static void main(String[] args) {
String workDir = System.getProperty("user.dir");
Path mainJar = Paths.get(workDir + "...");
Path nextMainJar = Paths.get(workDir + "...");
if (Files.exists(nextMainJar)) {
Files.copy(nextMainJar, mainJar, StandardCopyAction.REPLACE_EXISTING);
}
URLClassLoader classLoader = new URLClassLoader(new URL[] {mainJar.toURL()});
Class<?> appClass = classLoader.find("mainjar.MainApp");
... instantiate the app
}
As you see the main jar must not be loaded from too early, maybe not be on the class path entirely, and hence the use of a separate ClassLoader. The same might probably be done with the main jar on the class path of the starter app, and using Class.forName("mainjar.MainApp"). The Class-Path can be specified in META-INF/MANIFEST.MF.
The secundary jars may reside in a lib/ directory.
For those readers wanting more modular, service oriented, updateable apps, one could make an OSGi application, a container for bundles (=jars), that provide exchangable services and life-time control.
I have a libGDX game project for Android, and I want to execute a Groovy script in it.
To do so, I am examining this example code: https://github.com/melix/grooidshell-example
They managed to execute Groovy embed in Java on Android. Particularly GrooidShell.java (https://github.com/melix/grooidshell-example/blob/master/GroovyDroid/src/main/java/me/champeau/groovydroid/GrooidShell.java)
I have managed to implement most of the code in the Android launcher of the libGDX project. However, I cannot run it because I am missing two arguments:
public GrooidShell(File tmpDir, ClassLoader parent) {
The first one can be any directory. And the second one, I don't even know what is it for.
My question is, what is the ClassLoader and File arguments supposed to be? I need to get them and use them in the AndroidLauncher class of libGDX, which is like this:
public class AndroidLauncher extends AndroidApplication {
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
initialize(new MyGdxGame(), config);
}
}
At first pay attention to GroovyActivity.groovy:
GrooidShell shell = new GrooidShell(applicationContext.getDir("dynclasses", 0), this.classLoader)
first argument of GrooidShell wants to create to a directory named "dynclasses" with default premission:
public abstract File getDir (String name, int mode)
Retrieve, creating if needed, a new directory in which the application can place its own custom data files. You can use the returned File object to create and access files in this directory. Note that files created through a File object will only be accessible by your own application; you can only set the mode of the entire directory, not of individual files.
Parameters
name Name of the directory to retrieve. This is a directory that is created as part of your application data.
mode Operating mode. Use 0 or MODE_PRIVATE for the default operation, MODE_WORLD_READABLE and MODE_WORLD_WRITEABLE to control permissions.
Returns
A File object for the requested directory. The directory will have been created if it does not already exist.
second argument this.classLoader refer to current running ClassLoader and you can use it as is or this.class.classLoader in groovy script. you also can use getApplicationContext().getClassLoader() in your activity java code.
getClassLoader()
Embedding Groovy
I have this problem that i have a program that writes and creates a .java file and puts it in my package folder, after this it takes the information from the .java file and uses it in it self. (it creates a new class with a method that i then import).
The problem is that if it wont work until i with eclipse update the "self created file". is there a way to make my main file update the "self created file".
Sorry if this is a duplicate. I just couldn't find it any where.
my code:
package dk.Nicolai.Bonde;
import java.io.*;
public class main {
public String outputString ="Math.sqrt(25)" ;
static String outputPath ="src/output.txt";
/**
* #param args
* #throws UnsupportedEncodingException
* #throws FileNotFoundException
*/
public static void main(String[] args) throws IOException{
new main().doit(args);
}
public void doit(String[] args) throws IOException{
PrintWriter writer = new PrintWriter("src/dk/Nicolai/Bonde/calculate.java", "UTF-8");
writer.println("package dk.Nicolai.Bonde;");
writer.println("public class calculate{");
writer.println("public void calc(){");
writer.println("System.out.println("+outputString+");");
writer.println("}");
writer.println("}");
writer.flush();
writer.close();
calculate calcObj = new calculate();
calcObj.calc();
}
}
Your main mistake is that you expected that it's during runtime automagically compiled into a .class file after save (which a sane IDE such as Eclipse is doing automatically for you behind the scenes everytime you press Ctrl+S). This is thus not true. During runtime, you need to compile it yourself by JavaCompiler and then load by URLClassLoader. A concrete example is given in this related question&answer: How do I programmatically compile and instantiate a Java class?
You'll in the concrete example also notice that you can't do just a new calculate(); thereafter. The classpath won't be auto-refreshed during runtime or so. You'd need to do a Class#forName(), passing the FQN and the URLClassLoader. E.g.
Calculate calculate = (Calculate) Class.forName("com.example.Calculate", true, classLoader);
Your other mistake is that you're relying on the disk file system's current working directory always being the Eclipse project's source root folder. This is not robust. This folder is not present at all when building and distributing the application. You should instead write the file to a fixed/absolute folder elsewhere outside the IDE project's structure. This is also covered in the aforelinked answer.
No, you cannot. You have to manually update resources in Eclipse. Although you can write a plugin for Eclipse which runs your file and update resources.
Eclipse uses directories and files to store its resources but is not direct representation of file system.
Your code could not work, because
calculate is required at compile time of main. You supply it at runtime.
calculate.java will not compiled, so even other techniques to dynamically load classes will not work
If you want to build classes at runtime, consider to use the reflexion API