How do relative file paths work in Eclipse? - java

So my 2009 new years resolution is to learn Java. I recently acquired "Java for Dummies" and have been following along with the demo code in the book by re-writing it using Eclipse. Anyway, every example in the book that uses a relative path does not seem to read the .txt file it's supposed to read from.
Here is the sample code:
import java.util.Scanner;
import java.io.File;
import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.JLabel;
import java.awt.GridLayout;
class TeamFrame extends JFrame {
public TeamFrame() throws IOException {
PlayerPlus player;
Scanner myScanner = new Scanner(new File("Hankees.txt"));
for (int num = 1; num <= 9; num++) {
player = new PlayerPlus(myScanner.nextLine(), myScanner.nextDouble());
myScanner.nextLine();
addPlayerInfo(player);
}
add(new JLabel());
add(new JLabel(" ------"));
add(new JLabel("Team Batting Aberage:"));
add(new JLabel(PlayerPlus.findTeamAverageString()));
setTitle("The Hankees");
setLayout(new GridLayout(11,2));
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack();
setVisible(true);
}
void addPlayerInfo(PlayerPlus player) {
add(new JLabel(player.getName()));
add(new JLabel(player.getAverageString()));
}
}
And you can see in the below screen shot I have included this file.
image no longer available
Also, I have verified that when I build the application that a copy of Hankees.txt is placed in the bin folder with the compiled .class files.
Lastly, if I change line 12 to the following and place Hankees.txt in the root of my C:\ drive the program compiles and runs fine.
Scanner myScanner = new Scanner(new File("C:\\Hankees.txt"));
So basically, my question is what am I doing wrong? Or is Eclipse responsible for this in some way?
Thanks for any and all help!

You need "src/Hankees.txt"
Your file is in the source folder which is not counted as the working directory.\
Or you can move the file up to the root directory of your project and just use "Hankees.txt"

A project's build path defines which resources from your source folders are copied to your output folders. Usually this is set to Include all files.
New run configurations default to using the project directory for the working directory, though this can also be changed.
This code shows the difference between the working directory, and the location of where the class was loaded from:
public class TellMeMyWorkingDirectory {
public static void main(String[] args) {
System.out.println(new java.io.File("").getAbsolutePath());
System.out.println(TellMeMyWorkingDirectory.class.getClassLoader().getResource("").getPath());
}
}
The output is likely to be something like:
C:\your\project\directory
/C:/your/project/directory/bin/

This is really similar to another question.
How should I load files into my Java application?
How should I load my files into my Java Application?
You do not want to load your files in by:
C:\your\project\file.txt
this is bad!
You should use getResourceAsStream.
InputStream inputStream = YourClass.class.getResourceAsStream(“file.txt”);
And also you should use File.separator; which is the system-dependent name-separator character, represented as a string for convenience.

Yeah, eclipse sees the top directory as the working/root directory, for the purposes of paths.
...just thought I'd add some extra info. I'm new here! I'd like to help.

You can always get your runtime path by using:
String path = new File(".").getCanonicalPath();
This provides valuable information about where to put files and resources.

Paraphrasing from http://java.sun.com/javase/6/docs/api/java/io/File.html:
The classes under java.io resolve relative pathnames against the current user directory, which is typically the directory in which the virtual machine was started.
Eclipse sets the working directory to the top-level project folder.

Related

Using CHelper plugin in IntelliJ for a coding contest

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.

Cannot create Path object from a string

I'm following along the Basic I/O Tutorial on Oracle.com, but I'm having difficulty making a Path object:
Path p1 = Paths.get("/tmp/foo");
Which gives the error:
error: The method get(URI) in the type Paths is not applicable for the arguments (String).
I'm on Linux and I'm working in Eclipse Kepler. I'm trying to access a text file in the current directory. Using Scanner and File I can work with the file, but I'd also like to fiddle around with a path to the file so I can continue with the tutorial.
edit: The entirety of the program is below. The second half is me being a rookie and confirming the file exists/works. When I comment out the Path definitions, I get the output of "Test" which is in the 'save.txt' file.:
package projectSARA;
import java.util.*;
import java.io.*;
import java.net.URI;
import java.nio.file.Path;
import java.nio.file.Paths;
public class Main {
public static void main(String[] args) {
String saveFile = "save.txt";
Path p1 = Paths.get(saveFile);
Path p2 = Paths.get("save.txt");
File file = new File(saveFile);
try{
Scanner in = new Scanner(file);
String test = in.next();
System.out.println(test);
}
catch(FileNotFoundException e){
System.out.println("File not found");
}
}// end main
}
It appears to be a problem of the (default) JRE settings in Eclipse.
To solve it, in the Package Explorer, right-click the "JRE System Library" > properties.
Select "Execution environment", then select "JavaSE-1.7 (java-7-oracle)", press OK.
It happened to me when creating a new project outside the workspace.
Actually I had the same issue with Oracle Java 8 running on Eclipse. But the solution above didn't help. The solution for me was to simply:
right-click on project in Package Explorer
Select Java Compiler
Enable Project Specific Settings
Set Compiler Compliance Level to 1.7

What is the correct path to display an ImageIcon png file for Windows 7?

I wanted to test having a program with a simple png image on it. I wrote a short program that does this, but I can't seem to get the path right. I have checked, checked again, rechecked, and quadruple checked my path name as to not get it right, but this image will not display, no matter what I do. I used a short class wrote by Oracle in the ImageIcon documentation (the creaetImageIcon()) to accomplish this, but it doesn't seem to help. I'll post the entire program below, as it is very short.
package practiceImages;
import java.awt.BorderLayout;
import java.awt.Toolkit;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class ImageIconGUITest {
public static void main(String[] args) {
ImageIconGUITest gui = new ImageIconGUITest();
gui.display();
}
private ImageIcon createImageIcon(String path, String description) {
java.net.URL imgURL = getClass().getResource(path);
if (imgURL != null) {
return new ImageIcon(imgURL, description);
} else {
System.err.println("Couldn't find file: " + path);
return null;
}
}
private void display() {
JFrame frame = new JFrame();
JLabel label = new JLabel(createImageIcon(
"Users/Evan/javaItems/Sprites_and_Other_Art/green.png", "the color green"));
frame.add(BorderLayout.CENTER, label);
frame.setSize(500, 500);
frame.setVisible(true);
}
}
The getResource(String) method will only find resources that are on the run-time class-path of the application. Since this image seems like an application resource (i.e. supplied by you as part of the application) it should be put on the run-time class-path.
E.G. Most IDEs have a place you can put resources within the project structure, that will automatically be included at run-time. Move (or copy) the image to that path.
Then it becomes a matter of providing the correct String. Let us imagine your project is set up something like this:
bin
src
com
our
Application.java
resources
green.png
So Application.java is in package com.our;, while the image is in the path resources/green.png.
If accessing the image from the Application, the correct path would be (drum roll please..)
"/resources/green.png"
Notes
The leading / is important. It tells the JRE we want to look for the image from the 'root of the class-path', as opposed to using a path relative to the package of the class itself.
Correct case is also vital. A string of "/resources/green.png" will not locate an image named "/resources/Green.png" or "/resources/green.PNG".
Eclipse paths
Right click on the src directory, select Properties at the bottom of the menu.
Navigate (using the normal way you'd use without Eclipse) to the directory of the Location.
Then go to the parent directory.
You should see a bin directory that contains classes and (hopefully) the image.
Firstly, you've supplied a relative path, so the system is looking for the image relative to the location you executed the program.
Secondly, the path should have a drive spec or at least a leading /. Depending on your setup, something like 'C:/Users/Evan/javaItems/Sprites_and_Other_Art/green.png' should work (you may need to change the drive spec to meet your system)
Thirdly, make sure that the file exists in the specified location, System.out.println(new File("C:/Users/Evan/javaItems/Sprites_and_Other_Art/green.png").exists()) should return true, other wise the file is in the wrong location.
A relative path basically means a path location relative to the programs execution. So, if you were running the program from C:/Program Files/MyAwesomeApplication for example, a relative path of Users/Evan/javaItems/Sprites_and_Other_Art/green.png would become an absolute path of C:/Program Files/MyAwesomeApplication/Users/Evan/javaItems/Sprites_and_Other_Art/green.png. This describes the path from the root location to the file/folder in question.
You can test this by using System.out.println(new File("C:/Users/Evan/javaItems/Sprites_and_Other_Art/green.png").getAbsolutePath(‌​)) which will give you the full path.
Using this fixed it for me:
JButton btnBanana = new JButton("New button");
btnBanana.setIcon(new ImageIcon("D:\\Android\\Company\\images\\bananas-icon.png"));
use double slash instead of one , i had this problem and i fixed it . ill show you an example :
public Driver (){
ImageIcon us = new ImageIcon("C:\saeed.gif"); // OS cant find it
ImageIcon uk = new ImageIcon("C:\\saeed0.gif"); // OS can
JButton button = new JButton ("Click here " , us ) ;
button.setRolloverIcon(uk);
add(button);
}
To get the path of a image to a text filed, this code will help you
txtPath.setText(lblImage.getIcon().toString());
//txtPath is the text filed use todiplay the path
//lblImage is the label which shows the image
You need to do C:\\Test\\test.png and not C:/Test/test.png

how to make java use the newest version of a file

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

method must call super() error in Netbeans

Recently I've made a Netbeans project and I am using SVN along with it. I am seeing duplicate class error, and in the console it says
java.lang.VerifyError: (class: pie/chart/explorer/PieChartExplorer, method: <init> signature: ()V) Constructor must call super() or this()
Could not find the main class: pie.chart.explorer.PieChartExplorer. Program will exit.
Exception in thread "main" Java Result: 1
Here is PieChartExplorer.java:
package pie.chart.explorer;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class PieChartExplorer extends JFrame implements ActionListener {
JTextField one = new JTextField(10);
JTextField two = new JTextField(10);
JTextField three = new JTextField(10);
JButton sub = new JButton("Click to be amazed");
public PieChartExplorer() {
super("Pie Chart Explorer");
setSize(300,100);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
FlowLayout flo = new FlowLayout();
setLayout(flo);
setVisible(true);
add(one);
add(two);
add(three);
sub.addActionListener(this);;
add(sub);
}
public static void main(String[] args) {
PieChartExplorer app = new PieChartExplorer();
}
#Override
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if(source == sub) {
try {
Pie show = new Pie(Float.parseFloat(one.getText()),Float.parseFloat(two.getText()),Float.parseFloat(three.getText()));
} catch(Exception ex) {
JOptionPane.showMessageDialog(this, "Please check entered data");
}
}
}
}
I have tried:
Clean and Rebuild project
Making sure that I have called super in all constructors
How can this be fixed? Code for download.
I found that renaming the package did not work, the old package was still there.
The problem for me started when I copied a package from another application into the current application, which already had a package with the same name. I was trying to add some missing classes to the package. After I did that, the error started.
To resolve it, I deleted the entire package from the target web app and did a clean and build. Then I copied the source package into the target application. No errors.
I saw these symptoms just the other day.
I had I file I had been editing and decided I wanted to split my changes into 2 commits. I went to the directory containing my file "x/y/Z.java", made a directory in "x/y" named "backup", moved "Z.java" there, and pulled a fresh copy from version control. Note all of this was done outside the IDE.
Back in the IDE I merged in the changes for the first commit and when I built I got the duplicate class message for "Z.java".
When I copied the source to "backup" I did it outside the IDE and it still had the original package "x.y" as did my newly edited "Z.java". NB would not compile the new "Z.java" because it could see it had already created "x.y.Z.class" (from "x/y/backup/Z.java").
There are 2 ways to fix this:
Rename "x/y/backup/Z.java" to "x/y/backup/Z.java.backup". (Prevent the backup copy from being compiled.)
Change the package in "x/y/backup/Z.java" from "x.y" to "x.y.backup". (Make the backup create a different class file.)
After making either of these changes, perform a "clean and build". Note: simply building will not fix the problem, you need to perform a clean to remove the rogue class file.
Note: #1 was done by renaming Z.java from the command line, not within NB. NB will not let you change the file extension.
Cleaning and Building solves the problem
If you still have the problem, this is how I solved it..
In my case I changed the class with main method later and the initial class was still referenced in the proporties file.
Change that setting, clean and build.. It worked for me...
In my case, i had the same problem in a Web application after making an external copy of a POJO and manually editing it outside NETBEANS. The problem actually was what the others suggested in other answers about a conflict in the already compiled .class files.
What i did to overcome this was simply delete the folder webAppname/WEB-INF/classes (where compiled classes reside) and then do a Clean and Build
Hope this helps someone

Categories