When I research things on the internet I like to copy and paste certain paragraphs so I could review them later on.
I'm trying to write a program that would continuously check the clipboard for text content and write it to a text file any time it is renewed.
In the following test of the program I had "public class Clipboard" in my clipboard before running the program and the exception happened when I copied text from netbeans (The IDE I was using to run the program) while the program was running:
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class TestClipboard {
public static void main(String[] args) {
Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
String initial = "";
while(true) {
try {
String paste = c.getContents(null).getTransferData(DataFlavor.stringFlavor).toString();
if(!paste.equals(initial)) {
System.out.println(paste);
initial = paste;
}
} catch (UnsupportedFlavorException | IOException ex) {
Logger.getLogger(TestClipboard.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
The output:
public class TestClipboard
Exception in thread "main" java.lang.IllegalStateException: cannot open system clipboard
at sun.awt.windows.WClipboard.openClipboard(Native Method)
at sun.awt.datatransfer.ClipboardTransferable.<init>(ClipboardTransferable.java:78)
at sun.awt.datatransfer.SunClipboard.getContents(SunClipboard.java:144)
at delete.TestClipboard.main(TestClipboard.java:21)
Java Result: 1
BUILD SUCCESSFUL (total time: 34 seconds)
Why can't it open the system clipboard?
Does the getSystemClipboard() method not have global scope? - In other words, can I not get the clipboard's contents if the copy operation was performed in an internet browser?
You appear to be trying to read from the clipboard while another process is updating to it (or some such).
I fixed by:
Requesting an instance of the Clipboard within the loop
Adding a Thread.sleep into the while-loop
For example...
public class TestClipboard {
public static void main(String[] args) {
String initial = "";
while (true) {
try {
Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
String paste = c.getContents(null).getTransferData(DataFlavor.stringFlavor).toString();
if (!paste.equals(initial)) {
System.out.println(paste);
initial = paste;
}
} catch (UnsupportedFlavorException | IOException ex) {
Logger.getLogger(TestClipboard.class.getName()).log(Level.SEVERE, null, ex);
}
try {
Thread.sleep(40);
} catch (InterruptedException ex) {
}
}
}
}
It should be noted that it won't stop it from happening, it will only reduce the number of occurrences. When it is thrown, you could (just about) ignore and try again...
Related
I'm trying to run a python script whenever a button on my gui (swing) is pressed. However, the script never runs and I'm not sure how to fix this. I know the script works fine independently, it should be py not python because windows, and my file system ntfs.
So far I've been trying to use code that can be summarized as below:
myBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
Process p = Runtime.getRuntime().exec("py myScript.py");
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
});
I don't think I can chmod ntfs stuff but I tried setting permissions via right clicking the python file and trying to mess with the security settings. Full control for the script to users does nothing.
The python script has the following permissions, my guess is my code isn't working because it does not have execute permissions.
-rw-r--r--
Use complete python executable path instead of "py". It executes the file with just read permissions.
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;
public class Sample {
public static void main(String[] args) throws Exception {
try {
Process p = Runtime.getRuntime().exec("C:/Windows/py myScript.py");
String cmdOutput = null;
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
// read the output from the command
while ((cmdOutput = stdInput.readLine()) != null) {
System.out.println(cmdOutput);
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
myScript.py
print("This line will be printed.")
Output:
C:\Users\Administrator\Documents\demo>javac Sample.java
C:\Users\Administrator\Documents\demo>java Sample
This line will be printed.
This bug is happening only in win10. Currently in win7 it does not happen.
Essentially I write some text that the user has inputted in various fields.
I use this to save all the info the user wrote, so when the application is relaunched the info is already there.
Also, I call this class every time the user clicks a button.
With normal behavior, the application runs fine on win7, and it saves everything properly. With win10 though, saving effectively "corrupts" the file, or at least, it makes it empty.
package whatever;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Properties;
public class SaveFile {
public static void mainSave(String[] args) {
Properties prop = new Properties();
OutputStream output = null;
try {
String instaPathCombined = "config.properties";
output = new FileOutputStream(instaPathCombined);
// set the properties value, the get methods all retrieve a string.
prop.setProperty("a", UI.geta());
prop.setProperty("b", UI.getb());
prop.setProperty("c", UI.getc());
prop.setProperty("d", UI.getd());
prop.setProperty("e", UI.gete());
prop.setProperty("f", UI.getf());
prop.setProperty("g", UI.getg());
prop.setProperty("h", UI.geth());
prop.setProperty("i", UI.geti());
prop.setProperty("j", UI.getj());
prop.setProperty("k", UI.getk());
prop.setProperty("l", UI.getl());
prop.setProperty("m", UI.getm());
prop.setProperty("n", UI.getn());
prop.setProperty("o", UI.geto());
prop.setProperty("p", UI.getp());
prop.setProperty("q", UI.getq());
prop.setProperty("r", UI.getr());
prop.setProperty("s", UI.gets());
prop.setProperty("t", UI.gett());
prop.setProperty("u", UI.getu());
prop.setProperty("v", UI.getv());
// save properties to project root folder
prop.store(output, null);
} catch (IOException io) {
io.printStackTrace();
} finally {
if (output != null) {
try {
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
I have no idea on why it does this.
Also, this is literally a win10 issue, no other factors matter here, as I tried it on a VM with a fresh win10 installation and it happened.
Edit: Got it to work. My problem was I was using cmd to compile which exited the vm before the delay ended. Switched to jGrasp and the program worked as intended. Next I need to learn how to actually make a java applet to properly run on my computer. Thanks for your help everyone
I'm trying to set an alarm of sorts using java. I'd like to open a webpage after a set delay. The code below compiles and runs without errors or warnings but running the code does nothing. Just starts and stops the program. I have a feeling the issue arises from how I catch the exceptions but I'm not sure. I also am a little lost on what the actionPerformed() method does. Any help or insight is greatly appreciated
import java.awt.Desktop;
import java.net.URI;
import java.net.URISyntaxException;
import java.io.IOException;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.Timer;
public class YtAlarmTest
{
public static void main (String [] args)
{
String url = "https://stackoverflow.com/questions/ask";
int delay = 1000;
ActionListener task = new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
try
{
if (Desktop.isDesktopSupported())
{
Desktop.getDesktop().browse(new URI(url));
}
}
catch (URISyntaxException e)
{
System.out.println("exception");
}
catch (IOException e)
{
System.out.println("exceptio");
}
}
};
new Timer(delay, task).start();
}
}
I'm using Watcher in JDK7 which relies on inotify events. If the file is on a NFS, I want my program to fallback and use polling instead. Is there a way to detect if a file is on a remote drive (other than using Runtime.exec and parsing the mount table)? I'm only concerned with Linux compatibility for now.
I suppose one option is to use both inotify and polling when the program starts, but then disable the polling thread if an inotify event for my file is created.
You should be able to get relatively reliable info about the underlying file system type with FileStore.type().
It will definitely tell you if it's an NFS, or CIFS, not sure about other network mount types.
However I have no info about how reliable it is, #hoaz's suggestion to check if events are coming through might be a good idea.
I had the same problem. I have solved it by creating a new thread in de main class and touching the files periodically so a new change event gets fired.
The sample polls the dir for every 10 seconds does a touch.
Here a sample of the code:
package com.ardevco.files;
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.FileTime;
import java.util.ArrayList;
import java.util.List;
public class Touch implements Runnable {
private Path touchPath;
public Touch(Path touchPath) {
this.touchPath = touchPath;
this.checkPath = checkPath;
}
public static void touch(Path file) throws IOException {
long timestamp = System.currentTimeMillis();
touch(file, timestamp);
}
public static void touch(Path file, long timestamp) throws IOException {
if (Files.exists(file)) {
FileTime ft = FileTime.fromMillis(timestamp);
Files.setLastModifiedTime(file, ft);
}
}
List<Path> listFiles(Path path) throws IOException {
final List<Path> files = new ArrayList<>();
try (DirectoryStream<Path> stream = Files.newDirectoryStream(path)) {
for (Path entry : stream) {
if (Files.isDirectory(entry)) {
files.addAll(listFiles(entry));
}
files.add(entry);
}
}
return files;
}
#Override
public void run() {
while (true) {
try {
for (Path path : listFiles(touchPath)) {
touch(path);
}
} catch (IOException e) {
System.out.println("Exception: " + e);
}
try {
Thread.sleep(10000L);
} catch (InterruptedException e) {
System.out.println("Exception: " + e);
}
}
}
}
I have a .jar file and when I run it from the command prompt via java -jar MyJar.jar, it works fine. However double-clicking on it doesn't. Double-clicking starts the program correctly, but something on the inside doesn't work.
For the purposes of trying to figure out what is wrong on my own: what is the difference between double-clicking on a runnable .jar vs running it from the command line?
Where the program is executed is important and can change depending on how it was executed.
You can test this by using something like...
import java.awt.EventQueue;
import java.awt.HeadlessException;
import java.io.File;
import java.io.IOException;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class WhereAmI {
public static void main(String[] args) {
new WhereAmI();
}
public WhereAmI() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
try {
String path = new File(".").getCanonicalPath();
JOptionPane.showMessageDialog(null, "I was started in " + path);
} catch (IOException exp) {
exp.printStackTrace();
}
}
});
}
}
For example. When compiled, the Jar resides in /Volumes/Disk02/DevWork/personal/java/projects/wip/StackOverflow/WhereAmI/dist
If I change directories to this location and run java -jar WhereAmI.jar it outputs
If I change directories to /Volumes/Disk02/DevWork/personal/java/projects/wip/StackOverflow/WhereAmI and run java -jar dist/WhereAmI.jar it outputs
The execution context has changed. The same thing will happen when you double click the Jar and it is system dependent. It will also matter if it's a short cut or the actual Jar.
This will mean that if you rely on any relative resources, you must make sure that the Jar is executed within the correct location, relative to your resources.
How to achieve this is dependent on the OS
Double clicking runs it as "javaw -jar MyJar.jar"