Access another class's data member's field in Java - java

So, I want to access one class's data member's field from a whole other class through reflection. I have been unable to figure out, how, after I get the data member through reflection, I can change the field's value. I don't really know how to express it better, so I will let the code speak for me.
Here follows the handler class that calls the buttons. Following are the rest of the classes, whose functionality I will explain on the go.
import java.awt.*;
import java.awt.event.*;
public class SimHandler extends Frame{
public myValveButton but0,but1,but2,but3,but4,but5,but6,but7;
public SimHandler(){
super("Liquer Plant Control Panel");
this.setLayout(null);
this.setFont(new Font("Helvetica", Font.PLAIN, 14));
this.setBackground(Color.black);
but0 = new myValveButton("S1a",100,40,this);
but1 = new myValveButton("S1b",100,140,this);
but2 = new myValveButton("S2a",200,40,this);
but3 = new myValveButton("S2b",200,140,this);
but4 = new myValveButton("S3a",100,240,this);
but5 = new myValveButton("S3b",100,340,this);
but6 = new myValveButton("S4a",200,240,this);
but7 = new myValveButton("S4b",200,340,this);
this.setSize(335,410);
this.setLocation(100,100);
this.setVisible(true);
this.toFront();
this.setResizable(false);
this.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
This is actually where I try to use reflection to change the value of Silo's instance state. Below this one follow LiqPlantSim and Silo classes. As you can see, the state variable cannot be resolved that way, and after quite some googling, I can't figure out how I can make it work.
import java.awt.Button;
import java.awt.Frame;
import java.awt.event.*;
import java.lang.reflect.Field;
public class myValveButton extends Button{
String label;
public myValveButton(String label,int x,int y,Frame f){
super(label);
this.label = label;
this.addActionListener(new myValveButtonHandler(label));
f.add(this);
this.setBounds(x, y, 35, 30);
}
}
class myValveButtonHandler implements ActionListener{
Field f;
String label;
public myValveButtonHandler(String label){
this.label = label;
}
public void actionPerformed(ActionEvent pushButton){
try {
f = LiqPlantSim.class.getDeclaredField("silo"+label.split("")[1]);
System.out.println(f);
//f.state = "full" //Eclipse says 'state cannot be resolved to a type or is not a field'
} catch (NoSuchFieldException e) {
} catch (SecurityException e) {
}
System.out.println(label.split("")[2]);
}
}
Here is the LiqPlantSim class.
import java.util.HashMap;
import java.util.Map;
public class LiqPlantSim{
public Silo silo1,silo2,silo3,silo4;
public Pipe pipe;
public LiqPlantSim(){
silo1 = new Silo(false,false);
silo2 = new Silo(false,true);
silo3 = new Silo(true,false);
silo4 = new Silo(true,true);
pipe = new Pipe();
}
}
Here is the Silo Class.
public class Silo {
public boolean mixer,resistance;
public String state,mixerState,resState;
public Silo(boolean mix,boolean res){
mixer = mix;
resistance = res;
state = "empty";
}
}
Apart from finding out how I can access the silo's state variables, I would really appreciate any feedback and/or advice on how I could structure my work better, and on any mistakes I might have made.

First off, Class#getDeclaredField(String) returns a Field object, not the actual value of that field. To get the value, you must use Field#get(Object), where the argument is an instance of the class for which you are trying to access a field. In your code, this would be:
LiqPlantSim sim = doSomethingToGetInstance();
f = LiqPlantSim.class.getDeclaredField("siloX");
Silo silo = (Silo) f.get(sim);
Which brings me to my next point: Why use reflection at all? Your answer probably has to do with getting the correct Silo using the label. You should* restructure LiqPlantSim to use an array or a List to solve this:
import java.util.HashMap;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;
public class LiqPlantSim{
private List<Silo> silos;
public Pipe pipe;
public LiqPlantSim(){
silos = new ArrayList<>();
silos.add(new Silo(false,false));
silos.add(new Silo(false,true));
silos.add(new Silo(true,false));
silos.add(new Silo(true,true));
pipe = new Pipe();
}
public Silo getSilo(int index) {
return silos.get(index);
}
//Possibly other methods to access silos
}
(EDIT: You should do the same with the buttons in SimHandler)
Then, in the handler, you can access a Silo like this:
public void actionPerformed(ActionEvent pushButton){
try {
int labelLength = label.length();
int index = Integer.parseInt(label.substring(labelLength - 1, labelLength));
Silo silo = doSomethingToGetLiqPlantSimInstance().getSilo(index);
silo.state = "full" //Note that it is good practice to use private fields and public getters and setters
} catch (NoSuchFieldException e) {
} catch (SecurityException e) {
}
System.out.println(label.split("")[2]);
}
Better yet, get the index in the constructor and store it so you don't have to recalculate it every time.
*Of course, this is only a suggestion

Why do you implement your action-listeners in the button class? The ValveButton should not be aware of what to do when it is clicked.
Instead you should implement your action-listener in your SimHandler class. After instantiating your 8 ValveButtons you can add the action-listeners in a loop.
Anyways - if you really need to go for a solution using reflection I would recomment using the tiny PrivilegedAccessor framework. Though recommended to be used only in unit-tests it might be useful in your case.

This: "silo"+label.split("")[1] will create the String siloS.
To get the number from the label variable try: label.substring(1,2)
Also you don't need to pass the Frame f to the myValveButton constructor, you can add the buttons to the frame directly in the SimHandler using this.add(but0).

Related

How to bring SQL Variable into GUI?

I would like to insert in my GUI the variable anzahl from the minor class in a text field. Counting works in the minor class, but I do not know how I now get the counted value in the GUI? In the GUI, I just want to see the value from the minor class. Can someone help me with the code examples?
Minor Class:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import javax.swing.JLabel;
import java.sql.DriverManager;
public class Count {
static Connection conn;
static Statement eintrag;
static Statement eintrag2;
static JLabel textPB1;
static String ausgabe;
public static String anzahl;
Statement abfrage;
int i;
ResultSet res;
private int num;
Count() {
try {
Class.forName("org.mariadb.jdbc.Driver");
Connection con = java.sql.DriverManager.getConnection("jdbc:mariadb://fm-s012mp.fhws.de","Java","xyc");
Statement s = con.createStatement();
ResultSet res;
res = s.executeQuery("SELECT COUNT (*) AS anzahl FROM `lagersystem_test`.`00_hauptdatenbank` WHERE Boxinhalt > '0'" );
while (res.next() ) {
System.out.print(res.getString("anzahl") );
GUI_Lager.setTextExternally(res.getString("anzahl"));
}
res.close();
s.close();
con.close();
}
catch (Exception e) { System.out.println(""+e.getMessage());}
}
}
GUI: (short Form)
public class GUI_Lager extends JFrame {
private static final long serialVersionUID = 1L;
JLabel textPB; // "Text Prozessbar
static JLabel textPB1;
(....)
public GUI_Lager() {
textPB1 = new JLabel(""); // Variable from the Class
textPB1.setBounds(200, 10, 400, 25);
textPB1.setVisible(true);
add(textPB1);
(....)
}
public static void setTextExternally(String text) {
textPB1.setText(text);
// TODO Auto-generated method stub
}
}
}
To update a JLabel, you would use:
yourLabel.setText("your text");
So in context with the code provided in your question (assuming it is working without issue), you would do this:
while (res.next() == true) {
//System.out.print(res.getString("anzahl") );
//This "anzahl" i want to have in my GUI
textPB1.setText(res.getString("anzahl")); //Now you should have the label set
}
If for some reason the JLabel does not like being changed that way in a loop, you could also just instantiate a new object reference like so:
textPB1 = new JLabel(res.getString("anzahl"));
Update 1:
If you need to set the value from a different class simply create a method in the class with textPB1, which you will call from the class you are grabbing the DB value from, like so:
public static void setTextExternally(String text){
textPB1.setText(text);
//or
textPB1 = new JLabel(text);
}
Then in your loop from before, do this:
while (res.next() == true) {
//label should be set in other class using setter method below
MainGUI.setTextExternally(res.getString("anzahl"));
}
Update 2:
This update shows a specific example of a Swing application being used with the methods I have already provided, with a few changes now that I see your base GUI code. I would suggest building off from these files if you need a direct example to work up from:
Your GUI_Lager class:
import javax.swing.JFrame;
import javax.swing.JLabel;
public class GUI_Lager extends JFrame {
private static final long serialVersionUID = 1L;
JLabel textPB1;
public GUI_Lager() {
//no need for constructor, so it can be null
}
public void showGUI() {
//let's make the GUI here
this.setSize(300, 300);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setVisible(true);
//-----------------your code
//let's give it dummy text at first to ensure we can change it
textPB1 = new JLabel("Dummy Text");
textPB1.setBounds(200, 10, 400, 25);
textPB1.setVisible(true);
add(textPB1);
//-----------------your code
}
public void setTextExternally(String text) {
//alters the text of class variable/label textPB1
textPB1.setText(text);
}
}
And then the Count class:
import java.util.Scanner;
public class Count {
public static void main(String[] args) {
GUI_Lager gui = new GUI_Lager();
gui.showGUI(); //you must show the GUI first
//now we change the value, it will be done using your SQL selection from before
gui.setTextExternally("Awesome, it works!");
//launch Count.java and the Swing application will have a
// single label that says "Awesome, it works!"
//...change your data as needed based on your specific implementation
//but let's also show how to change it using console input
Scanner scan = new Scanner(System.in);
System.out.println("What do you want to change the text label to?");
String text = scan.nextLine().trim();
gui.setTextExternally(text);
}
}

Calling a Method That Takes a Parameter Within ActionListener

I've encountered a problem while trying to call a method within a class that implements actionListener. The method being called, DataCompiler, needs to use the integer wordCountWhole, which is returned in the wordCount class. The problem is that I can't pass the required parameter to the actionListener method.
import javax.swing.*;
import java.awt.*;
import java.awt.List;
import java.awt.event.*;
import java.beans.PropertyChangeListener;
import java.text.BreakIterator;
import java.util.*;
import java.util.stream.IntStream;
public class GUI extends JFrame {
public JTextArea textInput;
public JButton dataButton;
public String str;
public GUI() {
super("Text Miner");
pack();
setLayout(null);
dataButton = new JButton("View Data"); //Button to take user to data table
dataButton.setSize(new Dimension(120, 50));
dataButton.setLocation(5, 5);
Handler event = new Handler(); //Adds an action listener to each button
dataButton.addActionListener(event);
add(dataButton);
public class wordCount {
public int miner() {
//This returns an integer called wordCountWhole
}
}
public class Handler implements Action { //All the possible actions for when an action is observed
public void action(ActionEvent event, int wordCountWhole) {
if (event.getSource() == graphButton) {
Graphs g = new Graphs();
g.Graphs();
} else if (event.getSource() == dataButton) {
DataCompiler dc = new DataCompiler();
dc.Data(wordCountWhole);
} else if (event.getSource() == enterButton) {
wordCount wc = new wordCount();
sentenceCount sc = new sentenceCount();
wc.miner();
sc.miner();
}
}
}
}
And here's the code for the DataCompiler class:
public class DataCompiler{
public void Data(int wordCountWhole){
int m = wordCountWhole;
System.out.println(m);
}
}
You don't add the parameter there because you've invalidated the contract of the interface.
Use a constructor* (see note below, first)
public class Handler implements Action{ //All the possible actions for when an action is observed
private int wordCountWhole;
public Handler(int number) { this.wordCountWhole = number; }
#Override
public void actionPerformed(ActionEvent event) {
Although, it isn't entirely clear why you need that number. Your DataCompiler.Data method just prints the number passed into it, and that variable seemingly comes from nowhere in your code because it is not passed to the ActionListener.
* You should instead use Integer.parseInt(textInput.getText().trim()) inside Handler class / the listener code and not use a constructor. Otherwise, you'd always get the number value when you add the Handler, which would be an empty string and throw an error because the text area has no number in it.
Additionally, wc.miner(); returns a value, but calling it on its own without assigning it to a number just throws away that return value.

non-static JLabel cannot be referenced from static context while moving console println into GUI

Whatever I try to modify there's always a problem and the program won't run.
The thing is that my program works fine, when it's launched in the console, everything is ok, but when I try to make a GUI, and get text from console in the window, variables doesn't seem to work as they were.
The program is very simple, it has three packages like this:
//class SklepZoologiczny in package sklepzoologiczny
package sklepzoologiczny;
import javax.swing.JFrame;
import zwierzeta.*;
import magazyn.*;
public class SklepZoologiczny {
public static void main(String[] args) {
GUI GUI = new GUI();
GUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GUI.pack();
GUI.setSize(300, 500);
GUI.setVisible(true);
GUI.setTitle("Appka Zaliczeniowa - Sklep Zoologiczny");
GUI.setResizable(false);
GUI.setLocationRelativeTo(null);
}
}
//class GUI in package sklepzoologiczny
package sklepzoologiczny;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import magazyn.*;
import zwierzeta.*;
public class GUI extends JFrame {
public JLabel l_imie, l_gatunek, l_rasa;
public JButton b_dodaj, b_usun, b_lista;
public JTextField tf_imie, tf_gatunek, tf_rasa;
public String imie, gatunek, rasa;
public ArrayList lista_psow, lista_kotow;
public String pies, kot, gatunek_zwierza;
public String imie_psa, rasa_psa;
public String imie_kota, rasa_kota;
public GUI() {
setLayout(new FlowLayout());
b_dodaj = new JButton("Uruchom Program");
add(b_dodaj);
l_imie = new JLabel("Text from console to GUI should go here");
add(l_imie);
event dodanie = new event();
b_dodaj.addActionListener(dodanie);
}
public class event implements ActionListener {
public void actionPerformed(ActionEvent dodanie) {
magazyn magazyn1 = new magazyn();
magazyn1.kasa = 0;
pies pies1 = new pies();
kot kot1 = new kot();
krolik krolik1 = new krolik();
pies1.ustawImie("Max");
kot1.ustawImie("Nuta");
krolik1.ustawImie("Filip");
pies1.ustawCene(200);
kot1.ustawCene(100);
krolik1.ustawCene(50);
pies1.ustawRase("Jamnik");
kot1.ustawRase("Perski");
krolik1.ustawRase("Mini_Lop");
pies1.ustawGatunek("pies");
kot1.ustawGatunek("kot");
krolik1.ustawGatunek("krolik");
System.out.println("Operacje Zakupu Zwierzat");
System.out.println("---");
magazyn1.dodajZwierza(pies1);
magazyn1.dodajZwierza(kot1);
magazyn1.dodajZwierza(krolik1);
magazyn1.StanSklepu();
System.out.println("Transkacje");
System.out.println("---");
magazyn1.sprzedajZwierza("Nuta");
magazyn1.StanSklepu();
}
}
}
//class magazyn in package magazyn
package magazyn;
import java.util.ArrayList;
import zwierzeta.*;
public class magazyn {
public float kasa;
ArrayList <zwierzeta> lista = new ArrayList(20);
public void dodajZwierza(zwierzeta i){
lista.add(i);
sklepzoologiczny.GUI.l_rasa.setText("Do sklepu dodano zwierza o imieniu: " + i.wezImie());
}
public void sprzedajZwierza(String i){
for(int j=0; j<lista.size(); j++){
if(lista.get(j).wezImie() == i){
kasa = kasa + lista.get(j).wezCene();
lista.remove(j);
System.out.println("Sprzedano: " + i);
}
}
}
public void StanSklepu(){
System.out.println("Aktualny stan sklepu:");
for(int i=0; i<lista.size(); i++){
System.out.println(lista.get(i).wezImie()+", " +lista.get(i).wezGatunek()+", " + lista.get(i).wezRase() + ", cena: " + lista.get(i).wezCene());
}
System.out.println("Stan kasy \t\t\t" + kasa);
}
}
//class zwierzeta in package zwierzeta
package zwierzeta;
public abstract class zwierzeta {
String imie, gatunek, rasa;
float cena;
/* public void checkProduct() throws ProductException{
if(isDamaged == true){
ProductException damaged = new ProductException();
damaged.setErrorMessage("Product is damaged:");
throw damaged;
}
}*/
public void ustawImie(String i){
imie = i;
}
public String wezImie(){
return imie;
}
public void ustawGatunek(String i){
gatunek = i;
}
public String wezGatunek(){
return gatunek;
}
public void ustawRase(String i){
rasa = i;
}
public String wezRase(){
return rasa;
}
public void ustawCene(float i){
cena = i;
}
public float wezCene(){
return cena;
}
}
There are also three classes in package zwierzeta which only extends zwierzeta with no code in it.
So the thing is, whatever I try to put in the dodajZwierza in magazyn.java, there's always an error which says that I can't use non-static variable l_rasa to reference in a static context. I don't know how to fix this, I tried to make class as static in GUI but it just gets worse with more errors.
How can I get the text to appear in the window instead of a console?
First of all - you better avoid using members with names identical to type names:
GUI GUI = new GUI();
You - and the JVM - are more than likely to get confused by this, not knowing whether you are trying to access the class type or the class instance when you later run something like:
GUI.setVisible(true);
Second, if you want to let one class access a member of another class, it is much better to provide a getter that returns (a reference to ) that member, instead of defining the member as static and let the other classes access it directly.
You seem to conflate classes and instances: you want to create an instance of class GUI and then pass this instance around to be able to use the instance rather than the class.
In your main method, you create an instance of class GUI:
GUI GUI = new GUI();
The variable which refers to this instance you call GUI, the same as the class. This is a very bad idea. Java naming conventions dictate that variable names start with a non-capital letter, so you should write:
GUI gui = new GUI();
and change the rest of the main method accordingly.
Now, this instance gui is what you want to use. You have to pass it to the methods where you use it, and then write for example
gui.l_rasa.setText(...);
By the way, your code becomes more maintainable if you make the member variables of a class private, and add getter and setter methods to access them.
You are trying to access non static variable defined in GUI class as:
public JLabel l_imie, l_gatunek, l_rasa;
Here:
sklepzoologiczny.GUI.l_rasa.setText
I dont see its being initialised, but you could define it as static in GUI class like:
public static JLabel l_rasa;//initialize it may be and that would resolve your issue.

My method to load the html from a url in a web browser does not work

I am trying to make a web browser for the fun of it, i seem to get errors when ever i put in my loadHtml method, when i comment that out everything works even the action listener.
import java.awt.*;
import javax.swing.*;
import java.util.*;
import java.awt.event.*;
import java.applet.*;
public class browserPannel extends JFrame{
public static void main(String[] arg) {
JFrame browser = new JFrame("A Nun In A Weelchair");
browser.setSize(1000,700);
browser.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
browser.setLocationRelativeTo(null);
JPanel header = new JPanel();
header.setBackground(Color.lightGray);
JTextField url = new JTextField(20);
url.addActionListener(
new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
//loadHtml(event.getActionCommand);
System.out.println("action performed");
}
}
);
url.setSize(890,30);
url.setVisible(true);
JButton send = new JButton("Send");
send.setSize(75,30);
send.setVisible(true);
JEditorPane htmlc = new JEditorPane();
htmlc.setBackground(Color.red);
htmlc.setEditable(true);
htmlc.setContentType("text/html");
header.add(url, BorderLayout.SOUTH);
header.add(send);
browser.getContentPane().add(header, BorderLayout.NORTH);
browser.getContentPane().add(new JScrollPane(htmlc));
browser.pack();
browser.setVisible(true);
}
private void loadHtml(String link)
{
try{
//htmlc.setPage(link);
//url.setText(link);
}catch(Exception e){
System.out.println("ops sorry could not fined Virgine Mobile");
}
}
}
from what i can tell it looks like it can not recognize the url and the htmlc
I have tried to comment the htmlc.setPage and the url.setText, and when i do that my program compiles.
why am i getting these errors, shouldn't it recognize that they are defined above?
Your method isn't static but you're trying to call it from a static context (main()) Also, your instances in the main() method aren't visible in the loadHtml() method. You could pass them into the method (or declare them as static fields in your class). Finally, you shouldn't swallow Exception (at least printStackTrace()). So I think you were looking for something like,
private static void loadHtml(JEditorPane htmlc, JTextField url, String link) {
try{
htmlc.setPage(link);
url.setText(link);
}catch(Exception e){
System.out.println("ops sorry could not find Virgin Mobile");
e.printStackTrace();
}
}
Also, loadHtml(event.getActionCommand); isn't correct. You'd need parenthesis to call your original method loadHtml(event.getActionCommand());, but with the above changes it would be loadHtml(htmlc, url, event.getActionCommand()); (and to use the htmlc and url references in your inner class you must declare those references as final. For example, final JTextField url = new JTextField(20);).
Alternatively, you could make the components static so they're shared across all instances (and methods - first comment them out in your main method) -
private static final JTextField url = new JTextField(20);
private static final JEditorPane htmlc = new JEditorPane();
private static void loadHtml(String link) {
try{
htmlc.setPage(link);
url.setText(link);
}catch(Exception e){
System.out.println("ops sorry could not find Virgin Mobile");
e.printStackTrace();
}
}
Then you should be able to use loadHtml(event.getActionCommand())

Setting JLabel Text at Runtime

I am pretty new to Java(about 2 weeks in), and I am trying to set the text of a JLabel. The only problem is I am doing calculations in another class and I don't know how to reference the Jlabel I have already created. Here are the two classes in question.
package fightsim;
import javax.swing.JPanel;
import net.miginfocom.swing.MigLayout;
import javax.swing.JLabel;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class FightSimPane extends JPanel {
FightManager FightManager = new FightManager();
/**
* Create the panel.
*/
public FightSimPane() {
setLayout(new MigLayout("", "[][][][][][][][][][]", "[][][][]"));
JLabel lblChampionleft = new JLabel("ChampionLeft");
add(lblChampionleft, "cell 1 3");
JButton btnGo = new JButton("Go");
btnGo.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
FightManager.startFight();
FightManager.runTheFight();
}
});
add(btnGo, "cell 5 3");
JLabel lblChampionright = new JLabel("ChampionRight");
add(lblChampionright, "cell 9 3");
}
public void setLeftChampionLabel(String s){
//not able to reference Jlabel lblChampionLeft here???
System.out.println("Setting Left Champion text to"+s);
}
public void setRightChampionLabel(String s){
//not able to reference Jlabel lblChampionRight here???
System.out.println("Setting Right Champion text to"+s);
}
}
And the class that is trying to set the Label.
package fightsim;
public class FightManager {
Champion LeftChamp = new Champion();
Champion RightChamp = new Champion();
public FightManager() {
}
Thread LeftChampThread = new Thread(LeftChamp);
Thread RightChampThread = new Thread(RightChamp);
;
public void startFight() {
LeftChamp.setHealth(200);
RightChamp.setHealth(300);
LeftChamp.setATKsp(1000);
RightChamp.setATKsp(1000);
LeftChamp.setAD(20);
RightChamp.setAD(20);
}
public void runTheFight() {
System.out.println("Starting Threads");
LeftChampThread.start();
RightChampThread.start();
while ((LeftChamp.getHealth() > 0) && (RightChamp.getHealth() > 0)) {
if (RightChamp.isReadyToAttack()) {
LeftChamp.setHealth(LeftChamp.getHealth() - RightChamp.getAD());
RightChamp.setNotReady();
System.out.println("Setting Left Champion test to"
+ Integer.toString(LeftChamp.getHealth()));
// This is where I'd like to update the left Jlabel in
// FightSimPane
}
if (LeftChamp.isReadyToAttack()) {
RightChamp
.setHealth(RightChamp.getHealth() - LeftChamp.getAD());
LeftChamp.setNotReady();
System.out.println("Setting Right Champion test to"
+ Integer.toString(RightChamp.getHealth()));
// This is where I'd like to update the right Jlabel in
// FightSimPane
}
}
}
}
So, the question...How do I let my FightManager Class access and change the JLabel in my FightSimPane Class/Gui. Thanks in advance, and sorry if this is a stupid question. I am terribly new to programming and I'm still trying to take it all in. With that said, any other advice would be great. Thanks!
Pass references around so that classes can communicate with each other, and not only that but with the correct active instance of the class of the other type. For instance, you could give FlightManager a FlightSimPane field:
class FightManager {
private FightSimPane fightSimPane;
// and fill it in the constructor:
public FightManager(FightSimPane fightSimPane) {
this.fightSimPane = fightSimPane;
}
Then you'll be dealing with the actual visualized FightSimPane GUI object.
Note that you'll have to take care to pass in the correct instance:
public class FightSimPane extends JPanel {
FightManager FightManager = new FightManager(this);
Then you can call the public methods of FightSimPane in the FightManager class:
public void runTheFight() {
System.out.println("Starting Threads");
LeftChampThread.start();
RightChampThread.start();
while ((LeftChamp.getHealth() > 0) && (RightChamp.getHealth() > 0)) {
if (RightChamp.isReadyToAttack()) {
LeftChamp.setHealth(LeftChamp.getHealth() - RightChamp.getAD());
RightChamp.setNotReady();
System.out.println("Setting Left Champion test to"
+ Integer.toString(LeftChamp.getHealth()));
// !!! **** added this *************
fightSimPane.setRightChampionLabel("Setting Left Champion test to"
+ Integer.toString(LeftChamp.getHealth()));
}
EDIT 1
I see another potentially serious and unrelated problem here:
while ((LeftChamp.getHealth() > 0) && (RightChamp.getHealth() > 0)) {
//.........
}
This code appears to be called on the main Swing thread, the EDT and it's nature (while (true)) suggests that it has a very good chance of locking up the EDT bringing your Swing GUI's graphics processing and updating and all user interactions to a screeching halt. You may need to use a Swing Timer for this or a background thread so as to leave the EDT free to do its necessary work.
Declare the reference variable of FightSimPane class in FightManager class and pass the reference of FightSimPane object via the constructor of FightManager.
In FightManager class,
public class FightManager {
Champion LeftChamp = new Champion();
Champion RightChamp = new Champion();
private FightSimPane pane;
public FightManager(FightSimPane pane) { this.pane=pane;}
public FightManager() {
}
....
Using "pane" reference variable you can access accessible elements of FightSimPane class.
Modify the FightSimPane code,
public class FightSimPane extends JPanel {
FightManager fightManager;
public FightSimPane() {
fightManager= new FightManager(this);
...
}

Categories