I'm having a problem where I can't find images through Java. My friend and I are working on a project and we've done the exact same things. I've changed the paths to the location of the images and even dragged/dropped the images into Eclipse. However, I've had no luck. Here's my code:
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Toolkit;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Map;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class MapArray {
static JPanel[][] tiles = new JPanel[30][29];
static String[][] images = new String[30][30];
final static int SIZE = 30;
static int place=0;
public MapArray(){
}
protected static ImageIcon createImageIcon(String path) {
java.net.URL imgURL = Map.class.getResource(path);
if (imgURL != null) {
return new ImageIcon(imgURL);
} else {
System.err.println("Couldn't find file: " + path);
return null;
}
}
public static void setMap(){
try {
String a = getFileContents("C:\\Users\\*****\\workspace\\Pokemon\\src\\map1.txt");
for(int x=0; x<29; x++){
for(int y=0; y<30; y++){
images[x][y]=a.substring(0,a.indexOf(" "));
a=a.substring(a.indexOf(" ")+1);
System.out.println(images[x][y]);
}
}
} catch (Exception e) {
System.out.println("y u no work :(");
}
}
public static String getFileContents(String fileName) throws Exception {
File theFile = new File(fileName);
byte[] bytes = new byte[(int) theFile.length()];
InputStream in = new FileInputStream(theFile);
int m = 0, n = 0;
while (m < bytes.length) {
n = in.read(bytes, m, bytes.length - m);
m += n;
}
in.close();
return new String(bytes);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
setMap();
JFrame frame = new JFrame();
frame.setLayout(new GridLayout(30, 29, 0, 0));
for (int i = 0; i < 29; i++) {
for (int j = 0; j < 29; j++) {
tiles[i][j] = new JPanel(new GridLayout());
tiles[i][j].add(new JLabel(
createImageIcon("C:\\Users\\*****\\workspace\\Pokemon\\src\\tile"+"-"+images[i][j]+".png")));
frame.add(tiles[i][j]);
}
}
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
});
}
}
Everything I've tried with putting in the full image path doesn't work. Also, would anyone be able to help with relative paths? My friend and I will be sharing code between multiple computers so relative paths that aren't dedicated on where our workspace is located would be great. Thanks!
// get resource of *your* class, instead of Java's Map.class
MapArray.class.getResource(path);
...
String a = getFileContents("map1.txt"); // local path, not absolute
and put the file to your src folder, next to the MapArray.java file.
src/
|-- MapArray.java
|-- ...
`-- map1.txt
map1.txt will be moved into bin directory, next to .class file (bin/ is hidden in Eclipse by default, but that's where the classpath is set). Later you'll also want to make sure that the resource file is packaged into .jar.
would anyone be able to help with relative paths?
String a = getFileContents("./src/map1.txt");
Instead of posting a a whole bunch of code and not specifying the error message you get in your question, you could start with a simple code snippet (I neglect imports, ... since I am too lazy to fire up my IDE)
public static void main( String[] args ){
File file = new File( "C:...");//with the path you use in your code
System.out.println( file.exists() );
}
This is about what you need to discover/debug your problem. Then you can start on converting it to a relative path.
If the resources are inherently part of the app. (an embedded application resource) and not for write, they should be added to a Jar on the application's run-time class-path and accessed via URL obtained from Class.getResource(). It would work something like:
URL urlToMap1 = this.getClass().getResource("/src/map1.txt");
You'd need to check the exact path in the Jar that resource ends up at, and reference it from the root of the Jar (/) then the path within the Jar (src/map1.txt).
Related
So I created a message console. And used append to display messages and it works perfectly by running java -jar JavaProgram, however when I double click on it the application runs and I see the JFrame but nothing is displayed. The text that I did append is not present.
By the way, double clicking it on windows does display the message output but on my linux system nothing is displayed.
I'm running the same version of java on each machine.
Code Below:
package pdfCounter;
import java.io.*;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collection;
import java.util.Iterator;
import org.apache.commons.io.FileUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class App {
public static JTextArea textComponent;
public static int count;
public static void main(String args[]) {
try {
JFrame somePanel = new JFrame();
somePanel.add(new JLabel(" Message Console"), BorderLayout.NORTH);
textComponent = new JTextArea(5, 10);
somePanel.setVisible(true);
somePanel.setSize(900, 300);
somePanel.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
somePanel.add(new JScrollPane(textComponent));
pdfCounter.MessageConsole mc = new pdfCounter.MessageConsole(textComponent);
mc.redirectOut(null, System.out);
mc.redirectErr(Color.RED, null);
Path currentRelativePath = Paths.get("");
String s = currentRelativePath.toAbsolutePath().toString();
File root = new File(s);
count = 0;
boolean recursive = true;
Collection files = FileUtils.listFiles(root, null, recursive);
for (Iterator iterator = files.iterator(); iterator.hasNext(); ) {
try {
File file = (File) iterator.next();
if (file.getName().endsWith(".pdf")) {
String absoluteFile = file.getAbsolutePath();
append(absoluteFile);
PDDocument doc = PDDocument.load(new File(file.getAbsolutePath()));
count = doc.getNumberOfPages() + count;
doc.close();
}
} catch (Exception e) {
continue;
}
}
}
catch(Exception e) {
e.printStackTrace();
}
try (PrintStream out = new PrintStream(new FileOutputStream("NumberOfPages.txt"))) {
out.print(count);
}
catch (Exception e) {
e.printStackTrace();
}
}
public static void append(String absolutePath) {
textComponent.append(absolutePath + "\n");
}
}
when it gets to the `append(absoluteFile); part thats where the problem lies as it only appends on windows not linux.
UPDATE: I figured that opening it from a different file manager with double click, makes it work. With Nautilus is does not open, even when i choose to run it with java 8 or 9. Opening it with thunar(Different file manager) makes it work no problem with double clicking it. Both are set to run with java 9. I think it has something to do with folder permissions because if i run nautilus as root user, it works when double clicking.
I'm a little stumped, currently I am trying to list all of the attached devices on my system in linux through a small java app (similar to gparted) I'm working on, my end goal is to get the path to the device so I can format it in my application and perform other actions such as labels, partitioning, etc.
I currently have the following returning the "system root" which on windows will get the appropriate drive (Ex: "C:/ D:/ ...") but on Linux it returns "/" since that is its technical root. I was hoping to get the path to the device (Ex: "/dev/sda /dev/sdb ...") in an array.
What I'm using now
import java.io.File;
class ListAttachedDevices{
public static void main(String[] args) {
File[] paths;
paths = File.listRoots();
for(File path:paths) {
System.out.println(path);
}
}
}
Any help or guidance would be much appreciated, I'm relatively new to SO and I hope this is enough information to cover everything.
Thank you in advance for any help/criticism!
EDIT:
Using part of Phillip's suggestion I have updated my code to the following, the only problem I am having now is detecting if the selected file is related to the linux install (not safe to perform actions on) or an attached drive (safe to perform actions on)
import java.io.File;
import java.io.IOException;
import java.nio.file.FileStore;
import java.nio.file.FileSystems;
import java.util.ArrayList;
import javax.swing.filechooser.FileSystemView;
class ListAttachedDevices{
public static void main(String[] args) throws IOException {
ArrayList<File> dev = new ArrayList<File>();
for (FileStore store : FileSystems.getDefault().getFileStores()) {
String text = store.toString();
String match = "(";
int position = text.indexOf(match);
if(text.substring(position, position + 5).equals("(/dev")){
if(text.substring(position, position + 7).equals("(/dev/s")){
String drivePath = text.substring( position + 1, text.length() - 1);
File drive = new File(drivePath);
dev.add(drive);
FileSystemView fsv = FileSystemView.getFileSystemView();
System.out.println("is (" + drive.getAbsolutePath() + ") root: " + fsv.isFileSystemRoot(drive));
}
}
}
}
}
EDIT 2:
Disregard previous edit, I did not realize this did not detect drives that are not already formatted
Following Elliott Frisch's suggestion to use /proc/partitions I've come up with the following answer. (Be warned this also lists bootable/system drives)
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
class ListAttachedDevices{
public static void main(String[] args) throws IOException {
ArrayList<File> drives = new ArrayList<File>();
BufferedReader br = new BufferedReader(new FileReader("/proc/partitions"));
try {
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
String text = line;
String drivePath;
if(text.contains("sd")){
int position = text.indexOf("sd");
drivePath = "/dev/" + text.substring(position);
File drive = new File(drivePath);
drives.add(drive);
System.out.println(drive.getAbsolutePath());
}
line = br.readLine();
}
} catch(IOException e){
Logger.getLogger(ListAttachedDevices.class.getName()).log(Level.SEVERE, null, e);
}
finally {
br.close();
}
}
}
In Java, I have tried the different techniques of reading a file inside the jar. I have gotten one to work inside another program, but not this one. The InputStream that I get from the classname.class.getClassLoader().getResourceAsStream(filenamestring); method returns null.
package mainpkg;
import java.awt.GridLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.UIManager;
public class MainClass extends JFrame{
JTextField jtf = new JTextField();
boolean isInstalling = false;
public MainClass(){
super("StringThatTitleWillBe");
}
public void initiate(){
setLookAndFeel();
setSize(550, 400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GridLayout bl = new GridLayout(2, 1, 10, 10);
setLayout(bl);
JButton b = new JButton("Install");
b.addMouseListener(new MouseListener(){
#Override
public void mouseClicked(MouseEvent arg0) {
if(!isInstalling){
isInstalling = true;
install();
}
}
#Override
public void mouseEntered(MouseEvent arg0) {
}
#Override
public void mouseExited(MouseEvent arg0) {
}
#Override
public void mousePressed(MouseEvent arg0) {
}
#Override
public void mouseReleased(MouseEvent arg0) {
}
});
add(b);
jtf.setEditable(false);
add(jtf);
//show
setVisible(true);
}
private void setLookAndFeel() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception exc) {
System.out.print("failed to load look and feel");
}
}
public static void main(String[] args){
MainClass m = new MainClass();
m.initiate();
}
public void install() {
String files = "name of jarfile inside the jar to be read";
InputStream stream = MainClass.class.getClassLoader().getResourceAsStream(files);
File f = new File(files);
if(stream == null)
System.out.println("stream is null");
try {
int val = stream.read();
BufferedWriter br = new BufferedWriter(new FileWriter(f));
while(val != -1){
br.write(val);
val = stream.read();
}
stream.close();
br.close();
} catch (IOException e) {
e.printStackTrace();
}
isInstalling = false;
}
}
It Prints "stream is null" and gives an error on the line: stream.read();
I know that means that the file is not being converted to an InputStream properly.
Have I made a stupid mistake??? please help. Thanks in advance
Edit: the file that I want to copy in the same directory as the jar is directly inside the jar. It is not in a package or any such additional directory.
If a getResourceAsStream(String) returns null, that means that the class loader can't find a resource with the name you gave it. Either it is plain wrong, or maybe you have used a relative name and the resource isn't in the "/" directory in the JAR.
For details, read the javadoc for ClassLoader.getResourceAsStream, paying careful attention to:
the value returned, and
the handling of relative pathnames (follow the getResource link!!).
If you want to load a resource using a relative name that is resolved relative the classes package, you should write this:
MainClass.class.getResourceAsStream(files);
The Class.getResource... methods resolve relative names relative to the class. So the above would resolve "foo.txt" to "/mainpkg/foo.txt" ... where your version would resolve it to "/foo.txt".
I know that means that the file is not being converted to an InputStream properly
No it doesn't. It means that the resource named was not found. Check the Javadoc.
Then check the resource name, which you have helpfully omitted from your post, against a listing of the JAR.
If 'stream' is null you have no business continuing on with trying to read it and getting an NPE. This is just poor programming.
Also, a resource inside a JAR file is not a File, and constructing a File with its name is a meaningless activity.
Just for kicks I was experimenting and trying to make a program that would move all the files from my D:\Downloads directory that were installers to my G:\Downloads\Installers directory. I thought I had it working but upon using it, it returns "The process cannot access the file because it is being used by another process."
Here is the code and any input would be appreciated.
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
public class FileOrganizer {
public static void main(String[] args) {
File folder = new File("d:/Downloads");
File[] listOfFiles = folder.listFiles();
for (int i = 0; i < listOfFiles.length; i++) {
if (listOfFiles[i].isFile()) {
String name = listOfFiles[i].getName();
if (name.indexOf("Setup") > -1) {
Path source = Paths.get("d:/Downloads");
Path target = Paths.get("g:/Downloads/Installers");
try {
Files.move(source,
target.resolve(source.getFileName())),
StandardCopyOption.REPLACE_EXISTING);}
catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
Thanks in advance!
Try to change file name of each file, if file name is changeable then file is not used by any other process. You can not trace it with eyes, because there can be any thread which use it. After check each file, move it.
File sourceFile = ...;
boolean changeableSource = source.renameTo(sourceFile);
File destFile = ...;
boolean changeableSource = destFile.renameTo(destFile);
if(changeableSource && changeableSource ){
//Moving here...
}
Under Java what is the best way to go about converting an TIF file to a PNG?
Simplicity is preferable, but if the simplest way is to use a third party library then I would consider that solution.
First, install JAI. Then install JAI/ImageIO. Then do
public static void main(final String[] args) throws Exception
{
final BufferedImage tif = ImageIO.read(new File("test.tif"));
ImageIO.write(tif, "png", new File("test.png"));
}
Use imageMagic java libraries like im4java, their performance and quality is much better then JAI
for example:
import org.im4java.core.ConvertCmd;
import org.im4java.core.IMOperation;
public static void convertTifToPng(File inputImage, File outputImage){
IMOperation op = new IMOperation();
op.addImage(); //place holder for input file
op.addImage(); //place holder for output file
ConvertCmd convert = new ConvertCmd();
convert.run(op, new Object[]{inputImage.getAbsolutePath(), outputImage.getAbsolutePath()});
}
maven dependency for im4java is
<dependency>
<groupId>im4java</groupId>
<artifactId>im4java</artifactId>
<version>0.98.0</version>
</dependency>
Java advanced imaging APi is a good library for image manipulations
http://java.sun.com/products/java-media/jai/iio.html
Download JIMI Software Development Kit jimi1_0.zip and set JimiProClasses.zip to your classpath
http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-java-client-419417.html#7259-jimi_sdk-1.0-oth-JPR
JIMI is older java image library, but it is easy to use and there is no platform dependent code (no native executables, can use it like standard jar)
import java.awt.Image;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import com.sun.jimi.core.Jimi;
public class JIMIImageConverter {
public static byte[] convert(byte[] inBytes, String inMimeType, String outMimeType) throws Exception{
Image rawImage = Jimi.getImage(new ByteArrayInputStream(inBytes), inMimeType);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
Jimi.putImage(outMimeType, rawImage, outputStream);
return outputStream.toByteArray();
}
}
where inMimeType and outMimeType are graphics formats mimetypes
maybe you can use this code, works for me
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.awt.image.renderable.ParameterBlock;
import java.io.File;
import java.io.IOException;
import javax.media.jai.JAI;
import javax.media.jai.RenderedOp;
import com.sun.media.jai.codec.FileSeekableStream;
import com.sun.media.jai.codec.ImageCodec;
import com.sun.media.jai.codec.ImageDecoder;
import com.sun.media.jai.codec.SeekableStream;
public class ImageConvert {
public static RenderedImage[] readMultiPageTiff(String fileName)throws IOException{
File file = new File(fileName);
SeekableStream seekableStream = new FileSeekableStream(file);
ImageDecoder decoder = ImageCodec.createImageDecoder("tiff", seekableStream, null);
int numPages = decoder.getNumPages();
RenderedImage image[]= new RenderedImage[numPages];
int count = 0;
for(int i=0;i<decoder.getNumPages();i++){
image[i] = decoder.decodeAsRenderedImage(i);
count++;
}
String newFolderName;
String s3 = fileName;
String [] temp = null;
temp = s3.split("\\.");
int j;
j = 0;
do{
newFolderName = temp[j];
String spoonFeeding = newFolderName;
File f = new File(spoonFeeding);
f.mkdirs();
j++;
}while (j<1);
for (int i = 0; i < count; i++) {
RenderedImage page = decoder.decodeAsRenderedImage(i);
File fileObj = new File(newFolderName+"/" + (i+1) + ".png");
System.out.println("Saving " + fileObj.getCanonicalPath());
ParameterBlock parBlock = new ParameterBlock();
parBlock.addSource(page);
parBlock.add(fileObj.toString());
parBlock.add("png");
RenderedOp renderedOp = JAI.create("filestore",parBlock);
renderedOp.dispose();
}
return image;
}
}