简体   繁体   中英

I Can't Access Objects After “run()” Method

I am using NetBeans to create this program.
I use MyMain to create a JForm using FrameDemo. Then I add a JPanel (SensorUI SensorLL=new SensorUI) to the JForm. (Note I simplified this a little, I actually add four instances of the JPanel.)

The Panel includes a Label "Sensor".

Ultimately my program will be running a timer and once a second it will sample a sensor and display the sampled value in the Sensor Label.

I have a method in Sensor called write(value) that will write (value) in Sensor.

My problem is the creation of the Panel was placed in a "run()" method by NetBeans (I assume). I can: Sensor.write("xxx"); Successfully if it is inside the run() curlys, but if I place the Sensor.write("xxx"); outside the run curlys I get

cannot find symbol symbol: variable Sensor location: class MyMain

My code is below. I removed a lot of unnecessary information, I hope not too much. Each class is in a separate NetBeans class file if that means anything. For some reason when I look at the preview there is shading that causes early lines of the classes to not be in the shading. I don't know if the final post will come out that way. If so, sorry.

public class MyMain {

public static void main(String[] args) {

    //Schedule a job for the event-dispatching thread:
    //creating and showing this application's GUI.
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            FrameDemo.createAndShowGUI();
            SensorUI SensorLL=new SensorUI("SensorLL");
            FrameDemo.addObject(SensorLL);
            SensorLL.writeSensor("xxx");//<<<<<This is OK
        }
    }
    );

            SensorLL.writeSensor(SensorLL, "xxx");//<<<This is not
}

public class FrameDemo {

  /**
 * Create the GUI and show it.  For thread safety,
 * this method should be invoked from the
 * event-dispatching thread.
 */
static        JFrame frame = new JFrame("BrewTool");  

public FrameDemo(){

}
static void createAndShowGUI() {
    //Create and set up the window.
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    frame.pack();

    frame.setVisible(true);

}
static void addObject(SensorUI Sensor){
    frame.add(Sensor);

}
}

public class SensorUI extends javax.swing.JPanel {

/**
 * Creates new form SensorUI
 */
public SensorUI(String title) {
    initComponents();
    Temperature.setBorder(javax.swing.BorderFactory.createTitledBorder(title));
}

/**
 * This method is called from within the constructor to initialize the form.
 * WARNING: Do NOT modify this code. The content of this method is always
 * regenerated by the Form Editor.
 */
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">

A whole lot of NetBeans "Generated Code" removed from this listing The Jpanel includes a JLabel named "Sensor"

public void writeSensor(String value){
    Sensor.setText(value);
}

You declared the variable 'SensorLL' in the wrong scope:

public class MyMain {

    public static void main(String[] args) {

    // Declare it in the main-method
    SensorUI SensorLL = null;

    //Schedule a job for the event-dispatching thread:
    //creating and showing this application's GUI.
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            FrameDemo.createAndShowGUI();

            // Here you can simply initialize it, because it's
            // already declared
            SensorLL=new SensorUI("SensorLL");
            FrameDemo.addObject(SensorLL);
            SensorLL.writeSensor("xxx");//<<<<<This is OK
        }
    }
    );

    // Works perfectly fine, because SensorLL is declared
    // outside the run-method
    SensorLL.writeSensor(SensorLL, "xxx");//<<<This is not
}

You can't access it from outside the run-method, because in your code it only exists inside the run-method.

EDIT I tried to change your SensorUI class to get the wished behaviour. I came up with this

public class SensorUI extends javax.swing.JPanel {

private Thread updateThread = null;
private boolean updateThreadIsRunning = false;

/**
 * Creates new form SensorUI
 */
public SensorUI(String title) {

    // I can't figure out what those do (mainly because of missing source code).
    initComponents();
    Temperature.setBorder(javax.swing.BorderFactory.createTitledBorder(title));

    // Create a Thread in each SensorUI which is started once the Component is
    // created and then updates the JLabel Sensor each second
    // Now each SensorUI has its own Thread which keeps updating the content of
    // the corresponding JLabel

    this.updateThread = new Thread(new Runnable() {

        @Override
        public void run() {

                updateThreadIsRunning = true;

                while(updateThreadIsRunning){
                    // The message which is shown on the Sensor JLabel
                    writeSensor("xxx");
                    try{
                        // Here you can change the update intervall in milliseconds
                        Thread.sleep(1000);
                    } catch (InterruptedException e){
                        e.printStackTrace();
                    }
                }

        }
    });

    this.updateThread.start();

}

// Here are the leftout lines

public void writeSensor(String value){
    Sensor.setText(value);
}
}

If i got you right, this should exactly do what you want. I wasn't able to test the code because of the missing classes so if find any mistakes just say something and i'll try to update the code accordingly.

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