简体   繁体   中英

non-static variable cannot be referenced from static context

i have read similar issues on here, but i still can't figure out how to fix my code. i am testing a timer and while i can put the timer output in the command line while the gui opens in seperate thread i cannot get the timer's output into my JtextArea called attArea. i understand i am not referencing the instance of my Gui class which causes the problem, but i do not know how to fix my code so i can. i have even tried instantiating my timer class inside the buildGui method belonging to Gui class. that way compiles and the timer is running i think because the exit on close from the Gui does not give me a new prompt on the command line, so the timer must still be running on it's own thread. however it is not printing in the attarea. below is my code(3 classes)

 class Main{
   public static void main(String[] args){
     new Gui();
     new TimerTest();
   }
  }

next class

import javax.swing.*;
import java.awt.*;
class Gui extends JFrame{
  int fieldWidth = 20;
  String[] choose = {"Choose"};
  JPanel pnlBack = new JPanel();
  JPanel topPanel = new JPanel();
    JPanel citiesPanel = new JPanel();
      JLabel citiesLabel = new JLabel("Cities: ");
      JComboBox citiesBox = new JComboBox(choose);
      //citiesBox.add("choose");
    JPanel typePanel = new JPanel();
      JLabel typeLabel = new JLabel("Type:  ");
      JComboBox typeBox = new JComboBox(choose);
    JPanel namePanel = new JPanel();
      JLabel nameLabel = new JLabel("Name: ");
      JComboBox nameBox = new JComboBox(choose);
  JPanel midPanel = new JPanel();
    JPanel attPanel = new JPanel();
        JTextArea attArea = new JTextArea(12, 50);
  JPanel bottomPanel = new JPanel();
    JPanel gasPricePanel = new JPanel();
      JLabel gasPriceLabel = new JLabel("               Price of gas: ");
      JTextField gasPriceBox = new JTextField(fieldWidth);
    JPanel mpgPanel = new JPanel();
        JLabel mpgLabel = new JLabel("           mpg of vehicle: ");
        JTextField mpgBox = new JTextField(fieldWidth);
    JPanel moneyPanel = new JPanel();
        JLabel moneyLabel = new JLabel("        Money you have:");
        JTextField moneyBox = new JTextField(fieldWidth);
    JPanel costPanel = new JPanel();
        JLabel costLabel = new JLabel("                  Cost of trip: ");
        JTextField costBox = new JTextField(fieldWidth);
    JPanel distancePanel = new JPanel();
        JLabel distanceLabel = new JLabel(" Distance you can go: ");
        JTextField distanceBox = new JTextField(fieldWidth);

Gui(){
    buildGui();
}

//method to buld the gui
void buildGui(){
    this.setSize(600,500);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setTitle("Travel Calc");
    this.setResizable(false);
    this.setVisible(true);
    //System.out.println("buiding the gui.");
    pnlBack.setLayout(new BoxLayout(pnlBack, BoxLayout.Y_AXIS));
    topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.Y_AXIS));
    topPanel.setBorder(BorderFactory.createLineBorder(Color.black)); 
    midPanel.setLayout(new BoxLayout(midPanel, BoxLayout.Y_AXIS));
    midPanel.setBorder(BorderFactory.createLineBorder(Color.black));
    bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.Y_AXIS));  
    bottomPanel.setBorder(BorderFactory.createLineBorder(Color.black));
    //add back panel to Jframe
    add(pnlBack);
    //add panels to back panel
    pnlBack.add(topPanel);
        topPanel.add(citiesPanel);
            citiesPanel.add(citiesLabel);
            citiesPanel.add(citiesBox);
        topPanel.add(typePanel);
            typePanel.add(typeLabel);
            typePanel.add(typeBox);
        topPanel.add(namePanel);
            namePanel.add(nameLabel);
            namePanel.add(nameBox);    
    pnlBack.add(midPanel);
        midPanel.add(attPanel);
            attPanel.add(attArea);
    pnlBack.add(bottomPanel);
        bottomPanel.add(gasPricePanel);
            gasPricePanel.add(gasPriceLabel);
            gasPricePanel.add(gasPriceBox);
        bottomPanel.add(mpgPanel);
            mpgPanel.add(mpgLabel);
            mpgPanel.add(mpgBox);
        bottomPanel.add(moneyPanel);
            moneyPanel.add(moneyLabel);
            moneyPanel.add(moneyBox);
        bottomPanel.add(costPanel);
            costPanel.add(costLabel);
            costPanel.add(costBox);
            costBox.setEditable(false);
        bottomPanel.add(distancePanel);
            distancePanel.add(distanceLabel);
            distancePanel.add(distanceBox);
            distanceBox.setEditable(false);

        // add connection method goes here  
        // new TimerTest();
 }
}

3rd class

import java.util.Timer;
import java.util.TimerTask;


public class TimerTest {

static int counter = 0;

public TimerTest(){

      TimerTask timerTask = new TimerTask() {

        @Override
        public void run() {
            Gui.attArea.append("TimerTask executing counter is: " + counter );
            //System.out.println("TimerTask executing counter is: " +      counter);
            counter++;//increments the counter
        }
    };

    Timer timer = new Timer("MyTimer");//create a new Timer

    timer.scheduleAtFixedRate(timerTask, 0, 3000);//this line starts the timer at the same time its executed
}
}

Pass the reference of Gui to the TimerTest class

class TimerTest {

    static int counter = 0;

    public TimerTest(final Gui gui) {

        TimerTask timerTask = new TimerTask() {

            @Override
            public void run() {
                gui.attArea.append("TimerTask executing counter is: " + counter);
                ...
            }
        };
        ...
    }
}

class Main {
    public static void main(String[] args) {
        Gui gui = new Gui();
        new TimerTest(gui);
    }
}

Let's say you create a document, and want a friend to read the document. What do you do? You give him the document, right?

Same with Java objects: you have a GUI, and you want the Timer to access the GUI. So you give the GUI to the timer:

class Main{
    public static void main(String[] args){
        Gui theGui = new Gui();
        new TimerTest(theGui);
    }
}

Now the TimerTest constructor receives the gui that it will have to access. It just needs to keep a reference to this gui in a field:

public class TimerTest {

   private Gui theGui;

   public TimerTest(Gui gui) {
       this.gui = gui;
   }

   ...
}

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