Class Loop problem while calling method from other class [closed] - java

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I am trying to call a method from a other class but here is the problem:
The main class imports the second class with this:
Sc secondclass = new Sc();
The main class also contains this method:
public void home_open() {
for (int i = 0; i < buttons.length; i++) {
buttons[i].setVisible(false);
}
}
If I want to import this into the second class:
Mc mainclass = new Mc();
A loop will happen, if I want to import it in this way:
Mc mainclass;
This error will occur:
"this.this$0.mainclass" is null
My Goal is to call a method in the main class.

Change the constructor of the second class to
public class Sc {
private Mc mc;
/**
* Constructor
*/
public Sc(Mc mc) {
this.mc = mc;
}
}
and call the constructor like so
Mc mainclass = new Mc();
Sc secondclass = new Sc(mainclass);
Now you can call methods of class Mc via the mc member of class Sc.
EDIT
Based on the [pseudo] code linked to in this comment, consider the following.
Class Home
package homeshop;
import javax.swing.JButton;
public class Home {
private JButton[] buttons;
public Home() {
new Shop(this);
}
void homeOpen() {
for (int i = 0; i < buttons.length; i++) {
buttons[i].setVisible(true);
}
}
}
Class Shop
package homeshop;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
public class Shop {
private Home home;
private JButton[] buttons;
public Shop(Home home) {
this.home = home;
buttons[0].addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
home.homeOpen();
}
});
}
}
Method homeOpen, in class Home, has package access so that it can be called from class Shop since both classes are in the same package. Also note that I changed the method name so as to adhere to Java naming conventions.

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.

Is it possible to have an object which creates another copy of itself within it's constructor, while avoiding an infinite loop? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
I have zero reason to believe this is possible, but I'm trying to restore my ability to ask questions again, considering I am now in a position to contribute (4th year computer science major, working a software engineering job), compared to when I was a senior in high school, trying to play around with minecraft modding before I really knew Java.
Here is the code that initially wasn't working, and triggered my deciding to impose this question.
/**
*
*/
package net.halalaboos.huzuni.console.commands;
import net.halalaboos.huzuni.Huzuni;
import net.halalaboos.huzuni.client.notifications.Notification;
import net.halalaboos.huzuni.console.Command;
import net.halalaboos.lib.io.FileUtils;
import net.minecraft.src.GuiPlayerInfo;
import net.minecraft.src.StringUtils;
import twitter4j.*;
import twitter4j.conf.ConfigurationBuilder;
import twitter4j.TwitterException;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class TwitterAlerts implements Command {
public Status tweet;
public String tweetalert;
public ConfigurationBuilder cb = new ConfigurationBuilder();
TwitterFactory tf = new TwitterFactory(cb.build());
Twitter twitter = tf.getInstance();
TwitterAlerts object = new TwitterAlerts();
TwitterAlerts()
{
setkey();
checkstatus();
}
public void setkey()
{
setkey();
cb.setDebugEnabled(true);
cb.setOAuthConsumerKey("5c8ZcMgQihdS5kzGun9iSw");
cb.setOAuthConsumerSecret("aRUUbQnDu5yAjmdI23LdjRu6vDtPWaKhc6dFVklne0");
}
List<String> twitters = new ArrayList<String>();
List<String> pasttweets = new ArrayList<String>();
/**
* #see net.halalaboos.huzuni.console.Command#getAliases()
*/
#Override
public String[] getAliases() {
return new String[] {"twitteralerts", "tfollow"};
}
/**
* #see net.halalaboos.huzuni.console.Command#getHelp()
*/
#Override
public String[] getHelp() {
return new String[] {"Do /twitteralerts <name of tweeter> to be alerted of new tweets!"};
}
/**
* #see net.halalaboos.huzuni.console.Command#getDescription()
*/
#Override
public String getDescription() {
return "In game alerts of new tweets on followed accounts.";
}
/**
* #see net.halalaboos.huzuni.console.Command#run(java.lang.String, java.lang.String[])
*/
#Override
public void run(String input, String[] args) {
twitters.add(input);
}
public void checkstatus()
{
while(twitters != null)
{
try {
for(int i=0;i<twitters.size();i++)
{
tweet = twitter.getUserTimeline(twitters.get(i)).get(0);
if (pasttweets.contains(tweet.getText()))
{
}
else
{
Huzuni.notificationManager.add(new Notification("Tweet Retrieved", tweet.getText()));
pasttweets.add(tweet.getText());
}
}
} catch (TwitterException e) {
e.printStackTrace();
}
}
}
}
Your class has a field
TwitterAlerts object = new TwitterAlerts();
when you initialize this field, it creates a new object, which creates a new object, ad nauseam.
Every TwitterAlerts object has a TwitterAlerts object which has a TwitterAlerts which has a TwitterAlerts...Get the idea?
Get rid of that field. You aren't even using it.
look at these lines
TwitterAlerts object = new TwitterAlerts();
TwitterAlerts()
{
setkey();
checkstatus();
}
when you create an instance of TwitterAlerts, it wil create another instance of it. and then another create an instance of it....so you know why?

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