How to bring SQL Variable into GUI? - java

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);
}
}

Related

how to solve java.lang.NullPointerException for array assignment

I am trying to assign a variable from SQL result to array element but it keeps showing me java.lang.NullPointerException. I tried to declare the array above but it seems not working. The exception doesn't show the line of the error but I write print statements to figure out the exception place then I found out that when I print the value of the activity[i] it equals null.
Here is the code:
package main;
import java.awt.EventQueue;
public class ACTIVITY {
private Connection con;
private Statement stm;
private String sql;
private ResultSet rs;
private static int c_id=-1;
private static int s_id=-1;
private int a_id=-1;
private String activity[]=new String[5];
private int activityID[] =new int[5];
public static JFrame frame;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
ACTIVITY window = new ACTIVITY();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public ACTIVITY() {
initialize();
}
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
frame.getContentPane().add(panel, BorderLayout.CENTER);
panel.setLayout(null);
panel.setVisible(true);
try {
Class.forName("com.mysql.jdbc.Driver");
con=
DriverManager.getConnection("jdbc:mysql://localhost:3306/db1","****" , "********");
stm= con.createStatement();
sql="Select * from activity where sid="+s_id;
rs=rs=stm.executeQuery(sql);
String name=" ";int i=0;
while(rs.next()){
name=rs.getString("a_name");
a_id=rs.getInt("a_id");
activity[i]=name;//after this assignment it always equal null
activityID[i]=a_id;
i++;
}
//the rest of the code
con.close();
} catch(Exception e) {System.out.println(e); }
}
}
Personally, I'd suggest using ArrayList instead of an array for this, but that's just personal preference. Here's an article on that https://www.w3schools.com/java/java_arraylist.asp
As far as the issue as you have it, the problem is you have a declared a private string array and are trying to assign values to it in another method. The array is populating with default values of null since it's a String array. The reason you're getting the exception is because it's returning this default value rather than your assigned value.
You can still use a private array, but you'll want to declare it as static and use a static method to add a value to it. That way, when you add the value to it, it'll be returnable the way you expect. This is a much simpler example, but shows how to achieve this:
public class Test {
private static String activity[] = new String[5];
public void addValue() {
activity[0] = "Yo";
}
public static void main(String[] args) {
Test test = new Test();
test.addValue();
System.out.println(activity[0]);
}
}
As for your specific code, I would suggest declaring both activity[] and activityID[] as static arrays. Then, you will need to create an object in your main method to call your value. Your changes would look like this:
private static String activity[] = new String[5];
private int activityID[] =new int[5];
Then in your main method, add:
window.initialize(); //where window is your class object you declared
That will get you the result you want. I'd also suggest renaming your method you called the same thing as your class.

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.

Access another class's data member's field in 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).

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())

Categories