简体   繁体   中英

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!

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

You can not do this:

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

since skinFile is static, it would be better if you set that property as public static File skinFile; and then you accesed the property directly from the FileHandler:

ViewerMain.skinFile = filename.toFile()

given that it is a static property you dont need an instance of the class to access it, you can use the class directly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM