My java code is generating the following message when I create a open FileDialog and make it visible. I have checked the code against code examples and I can't find anything wrong. And I am passing in the parent frame reference into the constructor. This is the code example:
public void open() {
if (openAreYouSure()) {
MyFilenameFilter filter = new MyFilenameFilter(Editor.JAWS_FILE_TYPE);
FileDialog d = new FileDialog(frame, "Open", FileDialog.LOAD);
d.setFilenameFilter(filter);
d.setBackground(lightSteelBlue3);
if (!mostRecentDir.equals(""))
d.setDirectory(mostRecentDir);
d.setVisible(true);
String path = d.getDirectory();
String file = d.getFile();
if (path != null && file != null) {
Editor.logger.info("opened file: " + path + file);
newSession();
mostRecentDir = path;
openFile(path + file);
}
}
}
This comes out when the d.setVisible(true); is called.
Gtk-Message: 12:10:44.979: GtkDialog mapped without a transient parent. This is discouraged.
This is the version of java I am using on centos 7.
/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.275.b01-0.el7_9.x86_64/jre/bin/java
All the write ups on this type of messages say its caused because you didn't pass in the parent into the dialog you are created, but I am in the constructor. This is happening for all pop dialog my application is creating.
Does anyone have any idea how to suppress or fix this problem? I am not seeing any java bug report on this, but I assume there is somewhere.
Related
I created a Locale setting so Italian, English, ... I needed to know how to set up a predefined config already: I have obviously tried how every good person does this but I think it is too inefficient, I also tried to create files through the IDE in the same location where the files in the DataFolder are created at the onEnable but obviously it didn't work, however what I tried to be ineffective is this: customConfig.set("Hi-Message", "I'm sorry, i love you");
The way I'm doing it right now, is simply having the config file in the source code itself and, if the file-version of the config does not exist yet, creates a new config file using the config file from the compiled source code.
In my onEnable method in Main, I simply call a method in another class FileManager.setup().
It looks a bit like this in setup():
public static void setup() throws IOException {
File plugin_work_directory = new File(plugin_work_path);
core_server_config = new File(plugin_work_path + "config.txt");
if (!plugin_work_directory.exists()) plugin_work_directory.mkdir();
if (!core_server_config.exists()) {
InputStream core_server_config_template = (Main.class.getResourceAsStream("/config.txt"));
Files.copy(core_server_config_template, Paths.get(plugin_work_path + "config.txt"));
}
Config.load();
if (Integer.parseInt(Config.getValue("config.version")) < Config.version) {
core_server_config.delete();
InputStream core_server_config_template = (Main.class.getResourceAsStream("/config.txt"));
Files.copy(core_server_config_template, Paths.get(plugin_work_path + "config.txt"));
}
Config.load();
}
Config.load() parses the values into a private hashmap of the Config class, whereby other classes can reference the hashmap through a String getValue(String string) method.
I have written a function which takes in a BufferedImage and compares it to a pre-existing image in my hard drive checking if they are same or not.
public boolean checkIfSimilarImages(BufferedImage imgA, File B) {
DataBuffer imgAdata = imgA.getData().getDataBuffer();
int sizeA = imgAdata.getSize();
BufferedImage imgB = null;
try {
imgB = ImageIO.read(B);
} catch (IOException ex) {
Logger.getLogger(SupportClass.class.getName()).log(Level.SEVERE, null, ex);
}
DataBuffer imgBdata = imgB.getData().getDataBuffer();
int sizeB = imgBdata.getSize();
if(sizeA == sizeB) {
for(int i = 0; i < sizeA; i++) {
if (imgAdata.getElem(i) != imgBdata.getElem(i)) {
return false;
}
}
}
return true;
}
This throws IOException "Cant read input file". Idk why this is happening. I am calling the function like this...
while(support.checkIfSimilarImages(currentDisplay, new File(pathToOriginalImage)) == false) {
System.out.println("Executing while-loop!");
bot.delay(3000);
currentDisplay = bot.createScreenCapture(captureArea);
}
where,
String pathToOriginalImage = "C:\\Users\\Chandrachur\\Desktop\\Home.jpg";
I can see that the path is valid. But as I am testing it for File.exists() or File.canRead() or File.absoluteFile().exists() inside the checkIfSimilarImages function and everything is returning false.
I have researched my question here and tried out these suggestions:
It is not only for this location, I have tried a variety of other locations but in vain. Also it is not a problem where I have hidden file extensions and the actual file might be Home.jpg.jpg .
The only thing that might be is that permissions might be different. I dont really know how to verify this, but there is no reason it should have some permission which is not readable by java. It is just another normal jpg file.
Can it be because I am passing the file object reference into a function so in this process somehow the reference is getting modified or something. I just dont know. I am running out of possibilities to test for...
The whole stack trace is as follows:
javax.imageio.IIOException: Can't read input file!
at javax.imageio.ImageIO.read(ImageIO.java:1301)
at battlesbot.SupportClass.checkIfSimilarImages(SupportClass.java:77)
at battlesbot.AutomatedActions.reachHomeScreen(AutomatedActions.java:72)
at battlesbot.BattlesBot.main(BattlesBot.java:22)
Exception in thread "main" java.lang.NullPointerException
at battlesbot.SupportClass.checkIfSimilarImages(SupportClass.java:81)
at battlesbot.AutomatedActions.reachHomeScreen(AutomatedActions.java:72)
at battlesbot.BattlesBot.main(BattlesBot.java:22)
C:\Users\Chandrachur\AppData\Local\NetBeans\Cache\8.2\executor-snippets\run.xml:53: Java returned: 1
BUILD FAILED (total time: 11 seconds)
I am on Windows 10, IDE is NetBeans.
UPDATE:
Huge thanks to #k5_ . He told me to paste this in path and it worked.
"C:/Users/Chandrachur/Desktop/Home.jpg";
It seems some invisible characters were in the path. But I still don't understand what that means.
Usually this kind of problem lies with access problem or typos in the filename.
In this case there were some invisible unicode characters x202A in the filename. The windows dialog box, the file path was copied from, uses them for direction of writing (left to right).
One way of displaying them would be this loop, it has 4 invisible characters at the start of the String. You would also see them in a debugger.
String x = "C:\\Users\\Chandrachur\\Desktop\\Home.jpg";
for(char c : x.toCharArray()) {
System.out.println( c + " " + (int) c);
}
I start an explorer window in java using
ProcessBuilder pb = new ProcessBuilder("explorer.exe",folderToOpen);
Process p = pb.start();
Before my java program exists, I want to close this window.
It is important, because this folder is actually a virtual folder.
The folder has been created using a java library for creating kernel level virtual filesystem.
When the program exists, the folder ceases to exists.
Windows explorer doesn't realize this, and keeps showing a number of error messages.
These error messages stop only when the user closes the explorer window of the virtual folder.
For better user experience I need to automatically close this virtual folder on exit.
The problem with explorer.exe is that, it doesn't open the new window in the instance used
to send the command. The window is opened in another process. So I don't have the handle
to the process, and so I cannot close it.
I tried the JNA route, but this threw a system error code 5 (meaning access denied )
final String folderName = Paths.get(super.path).getFileName().toString();
final WinDef.HWND[] windowHandle = new WinDef.HWND[1];
User32.INSTANCE.EnumWindows(new WinUser.WNDENUMPROC() {
#Override
public boolean callback(WinDef.HWND hwnd, Pointer pointer) {
char[]c = new char[255];
User32.INSTANCE.GetWindowText(hwnd, c, 250);
String s = new String(c).trim();
System.out.println(s);
if (s.equals(folderName)) {
windowHandle[0] = hwnd;
User32.INSTANCE.DestroyWindow(hwnd);
System.out.println(Kernel32.INSTANCE.GetLastError());
return false;
}
return true;
}
}, Pointer.NULL);
Any suggestion, comments, tips, guide, ideas, hints ?
Thanks :D
Update :
This seems to work, however, the risk is that it might close a similar window ( a window whoes name is same as the window I want to close). This would be bad-side effect.
final String folderName = Paths.get(super.path).getFileName().toString();
User32.INSTANCE.EnumWindows(new WinUser.WNDENUMPROC() {
#Override
public boolean callback(WinDef.HWND hwnd, Pointer pointer) {
char[]c = new char[255];
User32.INSTANCE.GetWindowText(hwnd, c, 250);
String s = new String(c).trim();
System.out.println(s);
if (s.equals(folderName)) {
User32.INSTANCE.PostMessage(hwnd,User32.WM_CLOSE,null,null);
System.out.println(Kernel32.INSTANCE.GetLastError());
return false;
}
return true;
}
}, Pointer.NULL);
anyone there with a better idea ?
Thanks again :D
Use destroy() as shown in Process.
So use p.destroy();
The filesystem AirportHDD is mounted (AFP) from the beginning and the file exists when I start this little program.
I tried to figure out the whole day why the following is not working, but couldnt find any solution:
public static void main(String[] arguments)
{
while(1==1)
{
File f=new File(
"/Volumes/AirportHDD/test/lock.csv");
System.out.println(f.exists());
AmySystem.sleep(100);
}
}
the output is:
true, true, ...
as soon as I remove the file from a different computer (AirportHDD is a mounted harddisk over network) then the output keeps saying:
true, true, ...
when I open the finder and goto this directory the output changes to: false, false, ...
when the file is added again (via another pc) the output is still:
false, false, ...
but if you open the finder again and click on the directory and finder shows the existing file, the output changes suddenly to: false, true, true, true, ...
NOTE:
also all other file operations like opening for read are failing as long as java 'thinks' the file is not there
if the program itself is creating and deleting the files then problem is not occurring
just found out while testing that with samba sharing everything is ok, but with AFP it just wont work
is there a way to tell java to do the same thing as finder, like a refresh, or do not try to cache, whatever?
I think you might be looking for the WatchService. Oracle was also kind enough to provide a tutorial.
Because the longevity of these links aren't guaranteed, I'll edit in an example code in a couple of minutes. I just wanted to let you know I think I found something in case you want to start looking at it for yourself.
UPDATE
Following the linked tutorial, I came up with code like this. I'm not sure it'll work (don't have time to test it), but it might be enough to get you started. The WatchService also has a take() method that will wait for events, which means you could potentially assume the file's existence (or lack thereof) based on the last output you gave. That will really depend on what this program will be interacting with.
If this works, good. If not, maybe we can figure out how to fix it based on whatever errors you're getting. Or maybe someone else will come along and give a better version of this code (or better option altogether) if they're more acquainted with this than I am.
public static void main(String[] arguments) {
Path path = Paths.get("/Volumes/AirportHDD/test/lock.csv");
WatchService watcher = FileSystems.getDefault().newWatchService();
WatchKey key = null;
try {
key = path.register(watcher,
ENTRY_CREATE,
ENTRY_DELETE);
} catch (IOException x) {
System.err.println(x);
}
while(true) {//I tend to favor this infinite loop, but that's just preference.
key = watcher.poll();
if(key != null) {
for (WatchEvent<?> event: key.pollEvents()) {
WatchEvent.Kind<?> kind = event.kind();
if (kind == OVERFLOW || kind == ENTRY_DELETE) {
System.out.println(false);
}
else if (kind == ENTRY_CREATE) {
System.out.println(true);
}
}//for(all events)
}//if(file event occured)
else {
File f=new File(path);
System.out.println(f.exists());
}//else(no file event occured)
AmySystem.sleep(100);
}//while(true)
}//main() method
Here is a JUnit test that shows the problem
The problem still happens using Samba on OSX Mavericks. A possible reason
is explaned by the statement in:
http://appleinsider.com/articles/13/06/11/apple-shifts-from-afp-file-sharing-to-smb2-in-os-x-109-mavericks
It aggressively caches file and folder properties and uses opportunistic locking to enable better caching of data.
Please find below a checkFile that will actually attempt to read a few bytes and forcing a true file access to avoid the caching misbehaviour ...
JUnit test:
/**
* test file exists function on Network drive
* #throws Exception
*/
#Test
public void testFileExistsOnNetworkDrive() throws Exception {
String testFileName="/Volumes/bitplan/tmp/testFileExists.txt";
File testFile=new File(testFileName);
testFile.delete();
for (int i=0;i<10;i++) {
Thread.sleep(50);
System.out.println(""+i+":"+OCRJob.checkExists(testFile));
switch (i) {
case 3:
// FileUtils.writeStringToFile(testFile, "here we go");
Runtime.getRuntime().exec("/usr/bin/ssh phobos /usr/bin/touch "+testFileName);
break;
}
}
}
checkExists source code:
/**
* check if the given file exists
* #param f
* #return true if file exists
*/
public static boolean checkExists(File f) {
try {
byte[] buffer = new byte[4];
InputStream is = new FileInputStream(f);
if (is.read(buffer) != buffer.length) {
// do something
}
is.close();
return true;
} catch (java.io.IOException fnfe) {
}
return false;
}
The problem is the network file system AFP. With the use of SAMBA everything works like expected.
Maybe the OS returns the wrong file info in OSX with the use of AFP in these scenarios.
I have a problem about creating a textfile with the name I want.
I want to create a textfile named : 'username' Subjects.
private void saveSubjects(){
RegisterFrame r = new RegisterFrame();
String username = r.txtUser.getText();;
try{
FileWriter f = new FileWriter(username + "" + "Subjects" + ".txt", true);
String subjects[] = lstSubjects.getItems();
for(int i = 0; i<subjects.length; i++){
f.write(subjects[i] + "\r\n");
}
f.close();
JOptionPane.showMessageDialog(null, "Data saved!", "Data Saved", JOptionPane.INFORMATION_MESSAGE);
}catch(Exception e){
JOptionPane.showMessageDialog(null, "Nothing Inputted!", "Error", JOptionPane.ERROR_MESSAGE);
}
}
I want to get the username from RegisterFrame as it is inputted there but it's not working.
I know it's a simple thing but I'm still a beginner in this. How can I solve this?
Thanks in advance
try this:
String username = r.txtUser.getText();
System.out.println("The loaded username is: " + username);
then you will see where your problem is : writing into the file OR getting the username text.
If the problem is in getting the text, consider other way of getting it or modify the question by removing the file write part and specifiing the username getting part.
Otherwise, IDK where the error is.
BTW: how is it not working? the file is not created at all? do you see any errors? the file has wrong name? please specify
Your code for writing the file seems to be fine. Based on your code I tried this which worked perfectly:
public static void main(String[] args) {
FileWriter f = null;
try {
f = new FileWriter("Subjects.txt", true);
String subjects[] = {"subject1", "subject2"};
for (String subject : subjects) {
f.write(subject + "\r\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(f);
}
}
I'd say your problem is elsewhere.
Please note that best practice dictates that Closeable objects such as FileWriter should be closed in a finally block
Assuming new RegisterFrame() starts up a GUI window, the issue is your code runs before you have a chance to type in your name. Instead you need to use event listeners to capture the contents of text fields, otherwise the code to get the name runs immediately after the window opens, long before you have a chance to type anything in.
The timeline is like this:
RegisterFrame starts a new thread to display the GUI without blocking your code
Your code immediately pulls "" from txtUser, which is of course empty
Now you type your name in
Nothing happens, because nothing in your code is paying attention to that action
Instead, it should be:
RegisterFrame starts a new thread to display the GUI without blocking your code
The method returns, or starts doing work that isn't dependent on the GUI
Now you type your name in
An event listener is triggered from the new thread, and the associated action to get the name and write to a file is executed
You have to decide what sort of listener makes sense for your use case, for instance you might want to wait until the user clicks a button (that says "Submit" or "Write File" for instance) and register an ActionListener on that button. Then you put your username polling and file writing behavior in that action* and you're golden!
*I should add that in truth you want to do as little as possible in ActionListeners, and it would be better to check if the username is not empty, then pass the actual work off to another thread, for instance with a SwingWorker, but for your purposes I suspect it will be alright to not worry about that.