Xeyler Xeyler - 1 month ago 7
Java Question

Java reference from static class

Sorry, this question has probably been asked before, but I couldn't find any with an answer in the context that applies specifically enough to my problem for me to apply the solution.

Anyways, I'm working on a program that uses a file. When that file is updated, I want it to replace the File variable with the current one. I set up a main class that will work with the file, then I set up another class with a different thread that listens for the file update. When the file is updated, I want the variable in the main class to be updated.

That means that the update listener class has to have the instance of the main class, but when I try to send it during initiation of the update listener class, a warning says the main class cannot be referenced from a static context.

Here's the code:

Main Class

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;
}
}


File Listener Class

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;
}
}

}
}


I suspect the answer is really obvious, but thanks for the patience!

Answer

If I understand correctly, you need an instance of the ViewerMain class.

this cannot be applied in a static context.

public static void main(String[] args) {

    ViewerMain viewer = new ViewerMain(); // an instance
    fileHandler = new FileHandler(viewer);

Same for skinFile

public File skinFile; // Remove static

public void setSkinFile(File skinFile) {
    this.skinFile = skinFile;
}
Comments