很抱歉,之前可能已经提出过这个问题了,但是在上下文中我找不到任何答案,这些答案特别适用于我的问题,以便我应用解决方案。
无论如何,我正在研究一个使用文件的程序。当该文件更新时,我希望它将File变量替换为当前变量。我设置了一个可以使用该文件的主类,然后我设置了另一个具有不同线程的类来监听文件更新。当文件更新时,我希望更新主类中的变量。
这意味着更新侦听器类必须具有主类的实例,但是当我尝试在启动更新侦听器类期间发送它时,警告表示无法从静态上下文引用主类。 / p>
以下是代码:
主要类
package me.xeyler;
import com.sun.media.jfxmedia.logging.Logger;
import javax.swing.*;
import java.awt.Color;
import java.io.File;
import java.io.IOException;
import java.nio.file.*;
import static java.nio.file.StandardWatchEventKinds.*;
/**
* Created by Brigham on 10/19/2016.
*/
public class ViewerMain {
static FileHandler fileHandler;
static File skinFile;
public static void main(String[] args) {
boolean bool = false;
fileHandler = new FileHandler(this);
fileHandler.start();
while(true) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(bool);
}
}
public void setSkinFile(File skinFile) {
this.skinFile = skinFile;
}
}
文件侦听器类
package me.xeyler;
import com.sun.media.jfxmedia.logging.Logger;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.nio.file.*;
import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;
import static java.nio.file.StandardWatchEventKinds.OVERFLOW;
/**
* Created by Brigham on 10/19/2016.
*/
public class FileHandler implements Runnable {
private Thread fileThread;
private String threadName;
WatchService watcher = null;
private ViewerMain main;
public FileHandler(ViewerMain main) {
this.main = main;
this.threadName = "FileThread";
}
public void watchFile(Path path) {
}
public void watchFile(File file) {
watchFile(Paths.get(file.getPath()));
}
public void close() {
try {
watcher.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void start () {
if (fileThread == null) {
System.out.println("Starting new thread...");
fileThread = new Thread (this, threadName);
fileThread.start();
System.out.println("Started thread: " + threadName);
}
}
@Override
public void run() {
System.out.println("Running thread...");
Path dir = Paths.get(System.getProperty("user.home"),"documents");
try {
watcher = FileSystems.getDefault().newWatchService();
WatchKey key = dir.register(watcher,
ENTRY_MODIFY);
} catch (IOException x) {
x.printStackTrace();
}
for (;;) {
// wait for key to be signaled
WatchKey key;
try {
key = watcher.take();
} catch (InterruptedException x) {
return;
}
for (WatchEvent<?> event: key.pollEvents()) {
WatchEvent.Kind<?> kind = event.kind();
// The filename is the
// context of the event.
WatchEvent<Path> ev = (WatchEvent<Path>)event;
Path filename = ev.context();
if (filename.endsWith("text.txt")) {
System.out.println("File has changed");
//TODO: Update File variable in ViewerMain
main.setSkinFile(filename.toFile());
}
}
// Reset the key -- this step is critical if you want to
// receive further watch events. If the key is no longer valid,
// the directory is inaccessible so exit the loop.
boolean valid = key.reset();
if (!valid) {
// TODO: Handle inaccessible directory
break;
}
}
}
}
我怀疑答案非常明显,但感谢耐心!
答案 0 :(得分:2)
如果我理解正确,您需要ViewerMain
类的实例。
this
无法在静态上下文中应用。
public static void main(String[] args) {
ViewerMain viewer = new ViewerMain(); // an instance
fileHandler = new FileHandler(viewer);
skinFile
public File skinFile; // Remove static
public void setSkinFile(File skinFile) {
this.skinFile = skinFile;
}
答案 1 :(得分:0)
你不能这样做:
public void setSkinFile(File skinFile) {
this.skinFile = skinFile;
}
因为skinFile是静态的,所以如果将该属性设置为public static File skinFile;
然后直接从FileHandler加入属性会更好:
ViewerMain.skinFile = filename.toFile()
鉴于它是一个静态属性,你不需要类的实例来访问它,你可以直接使用该类。