-1

I have been coding for about 3 months now, (I've never had any programming experience) and I ran into a bit of an issue. I'm working on an idle clicking game, but I can't seem to access textArea.

I need to update textArea from outside its class since I am multi-threading and need separate run() methods.

class AddOne extends Thread {

    public static int money = 0;
    public static boolean flag = false;
    public void run() {
        try {
            money++;
            System.out.println(money);
            //update textArea with new money value

        }
        catch(Exception e){
            System.out.println("The exceptions are: " + e);
        }
    }
}

class AddOnePerSec extends Thread {

    public void run() {
        try {
            if(AddOne.flag == false)
            {   
                for(int i = 0; i<=100; i++)
                {
                    AddOne.flag = true;
                    AddOne.money++;
                    Thread.sleep(1000);
                    //update textArea with new money value

                }
                AddOne.flag = false;
            }
            else {System.out.println("Please wait...");}
        }
        catch(Exception e){
            System.out.println("The exceptions are: " + e);
        }
    }
}

public class ClickGame {

    private static JFrame frame;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    AddOne.flag = false;
                    ClickGame window = new ClickGame();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public ClickGame() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    public static void initialize() {
        frame = new JFrame();
        frame.setBounds(100, 100, 450, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(new BorderLayout(0, 0));

        JButton btnAdd = new JButton("Add 1");
        btnAdd.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                AddOne add = new AddOne();
                add.start();
            }
        });
        frame.getContentPane().add(btnAdd, BorderLayout.WEST);

        JButton btnAddEvery = new JButton("Add 1 every second for 100 seconds");
        btnAddEvery.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                AddOnePerSec persec = new AddOnePerSec();
                persec.start();
            }
        });
        frame.getContentPane().add(btnAddEvery, BorderLayout.EAST);

        JTextArea textArea = new JTextArea();
        frame.getContentPane().add(textArea, BorderLayout.CENTER);
    }
}

Ideally, the textArea will be updated with the new money variable every time money is changed in each thread.

Abra
  • 19,142
  • 7
  • 29
  • 41
Jesse Ford
  • 31
  • 4
  • [Why use getters and setters/accessors?](https://stackoverflow.com/questions/1568091/why-use-getters-and-setters-accessors) – FailingCoder Oct 20 '19 at 03:58
  • I used windowbuilder for eclipse. Most of the code was autogenerated. – Jesse Ford Oct 20 '19 at 04:01
  • I am asking you to use getter methods to access this textArea. – FailingCoder Oct 20 '19 at 04:02
  • Had to lookup what that is... Safe to say I skipped a few steps learning Java thanks, I'll fix it tomorrow. – Jesse Ford Oct 20 '19 at 04:06
  • 1) Please use code formatting for code and code snippets, structured documents like HTML/XML or input/output. To do that, select the text and click the `{}` button at the top of the message posting/editing form. 2) `JTextArea textArea = new JTextArea();` Suggest a size in rows & columns like this `JTextArea textArea = new JTextArea(4,20);` 3) `frame.setBounds(100, 100, 450, 300);` that size is just a guess. Instead `pack()` after components are added. – Andrew Thompson Oct 20 '19 at 04:14

1 Answers1

2

Well, I added the code that got it to do what you want. In my opinion, it's not the best way, it's simply what I call a quick-and-dirty solution. If you haven't already done so, I suggest reading the tutorial Creating a GUI With JFC/Swing

I simply added a member variable to class AddOne and AddOnePerSec. I also added a constructor to each one of those classes that initializes the member variable. That way you have a reference to the JTextArea from within the class.

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;

class AddOne extends Thread {
    private JTextArea textArea;
    public static int money = 0;
    public static boolean flag = false;

    public AddOne(JTextArea txtAr) {
        textArea = txtAr;
    }

    public void run() {
        try {
            money++;
            System.out.println(money);

            //update textArea with new money value
            // NOTE: Updating GUI must be done on EDT.
            EventQueue.invokeLater(() -> textArea.append(String.valueOf(money) + "\n"));
        }
        catch(Exception e){
            System.out.println("The exceptions are: " + e);
        }
    }
}

class AddOnePerSec extends Thread {
    private JTextArea textArea;

    public AddOnePerSec(JTextArea txtAr) {
        textArea = txtAr;
    }

    public void run() {
        try {
            if(AddOne.flag == false)
            {   
                for(int i = 0; i<=100; i++)
                {
                    AddOne.flag = true;
                    AddOne.money++;
                    Thread.sleep(1000);

                    //update textArea with new money value
                    // NOTE: Updating GUI must be done on EDT.
                    EventQueue.invokeLater(() -> textArea.append(String.valueOf(AddOne.money) + "\n"));
                }
                AddOne.flag = false;
            }
            else {System.out.println("Please wait...");}
        }
        catch(Exception e){
            System.out.println("The exceptions are: " + e);
        }
    }
}

public class ClickGame {

    private static JFrame frame;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    AddOne.flag = false;
                    ClickGame window = new ClickGame();
                    ClickGame.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public ClickGame() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    public static void initialize() {
        frame = new JFrame();
        frame.setBounds(100, 100, 450, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(new BorderLayout(0, 0));

        final JTextArea textArea = new JTextArea(110, 80);
        JButton btnAdd = new JButton("Add 1");
        btnAdd.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                AddOne add = new AddOne(textArea);
                add.start();
            }
        });
        frame.getContentPane().add(btnAdd, BorderLayout.WEST);

        JButton btnAddEvery = new JButton("Add 1 every second for 100 seconds");
        btnAddEvery.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                AddOnePerSec persec = new AddOnePerSec(textArea);
                persec.start();
            }
        });
        frame.getContentPane().add(btnAddEvery, BorderLayout.EAST);
        frame.getContentPane().add(textArea, BorderLayout.CENTER);
    }
}

Here is a screen-capture of the running app.

clikgame.png

Abra
  • 19,142
  • 7
  • 29
  • 41
  • Thanks, what I ended up doing is just moving all of the threads into one class so that they could access the object. – Jesse Ford Oct 21 '19 at 05:04