Getting data from an object in an ArrayList into GUI - java

I have an input file which has several fields separated by whitespace like this:
10 416-555-6666 Burgess 15
15 905-777-8888 Thomas 10
20 905-111-2222 Morris 5
I have a separate class file 'Record' which is related to the input file that has ID, telephone, Name, Years of Work.
In my main method, I've created an ArrayList of 'Record' objects called employeeList. The ArrayList is filled by a while loop that splits the read input file into their categories, defined by the Record constructor.
My next task is to create a GUI which can display and cycle through the input file, but I'm having trouble designing a way in which the 'Record' objects are being displayed in the Text fields. I've attached an image below to show what I'm trying to get:
example drawing
The next employee button would cycle to the next item on the ArrayList, being the next record object. I've attached my code below and would appreciate any suggestions on what to do next (making a GUI that displays the items ArrayList).
package javaapplication4;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.*;
import javax.swing.*;
import java.awt.*;
public class App {
private JFrame f;
private JPanel p;
private JButton b1;
private JLabel lab;
private JTextArea empID;
private JTextArea telephone;
private JTextArea name;
private JTextArea yearsWorked;
public App() {
gui();
}
public static void main(String[] args) throws FileNotFoundException {
File inputFile = new File("Emp.txt");
Scanner in = new Scanner(inputFile);
ArrayList<Record> employeeList = new ArrayList<Record>();
while(in.hasNextLine()) {
String line = in.nextLine();
String[] peopleInfo = line.split("\\s+");
int empId = Integer.parseInt(peopleInfo[0]);
String telephone = peopleInfo[1];
String name = peopleInfo[2];
int years_of_Work = Integer.parseInt(peopleInfo[3]);
employeeList.add(new Record(empId, telephone, name, years_of_Work));
}
new App();
}
public void gui() {
f = new JFrame("UpdateEmp");
f.setVisible(true);
f.setSize(600,400);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
p = new JPanel();
b1 = new JButton("Test");
lab = new JLabel();
empID = JTextField();
telephone = JTextField();
name = JTextField();
yearsWorked = new JTextField();
p.add(b1);
p.add(lab);
f.add(p);
}
}

You will need to move your list of records to the class that needs access to it (App) rather than being a local variable in the main method. You will also need an instance variable to record the index of the current record:
class App {
private final List<Record> records = new ArrayList<>();
private int currentRecord = 0;
...
}
I would suggest moving your logic for reading the records to a method of App so that you don't need to pass it around. Your main method should be very simple. Something like:
App app = new App();
app.readRecords();
app.showGui();
To show the records you will need methods to set the fields you've created as well as 'next' and 'previous' methods.
private void showRecord() {
assert currentRecord >= 0 && currentRecord < records.size();
Record record = records.get(currentRecord);
telephoneField.setText(record.getTelephone());
...
}
private void previous() {
if (currentRecord > 0) {
currentRecord--;
showRecord();
}
}
private void next() {
if (currentRecord < records.size() - 1) {
currentRecord++;
showRecord();
}
}

Related

adding into an Array list of objects from a text file in java

i thinkj i have a type argument problem which im really confused about, Ive started with an Arraylist which, extends to the another class with my main methods. and i have a Events class, which i want to categorize from the txt file, the main problem i have is adding from my txt file which iread into an ArrayList, java pops up with this error message
incompatible types: java.lang.String cannot be converted to CSC8012.Events
But in my events it has String? Im really confused
This is my generic arraylist i think?
import java.util.ArrayList;
public class SortedArrayList<E extends Comparable> extends
ArrayList<E> {
public void insert(E e) {
this.add(e);
int lastIndex = 0;
for( lastIndex = this.size() -1 ; lastIndex > 0 && this.get(lastIndex-1).compareTo(e) > 0 ; lastIndex--){
this.set(lastIndex, this.get(lastIndex-1));
}
this.set(lastIndex,e);
}
}
Heres my events class objects
public class Events implements Comparable<Events>{
//fields setting up the variables
String ticketsbought;
String eventname;
public Events(String ticketsbought, String eventname ){
this.ticketsbought = ticketsbought;
this.eventname = eventname;
}
#Override
public int compareTo (Events E){
return
ticketsbought.compareTo(E.getTicketsbought()) + eventname.compareTo(E.getEventname());
}
public String getTicketsbought() {
return ticketsbought;
}
public String getEventname() {
return eventname;
}
//setting it up for the main method from the constructor fields above
public void setTicketsbought(String ticketsbought) {
this.ticketsbought = ticketsbought;
}
public void setEventname(String eventname) {
this.eventname = eventname;
}
#Override
public String toString()
{
return "Tickets bought " + this.ticketsbought + "Event name " + this.eventname;
}
}
My main menu class
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Objects;
import java.util.ArrayList;
import java.util.Collections;
java.util.Scanner;
public class MainProgram extends SortedArrayList{
public static void main(String[] args) throws FileNotFoundException{
boolean bye = false;
String line;
String option;
Scanner sc = new Scanner(System.in); //tos take in our input
do{
System.out.println("Choose an option.."); // heres our options
System.out.println("e Information on all events");
System.out.println("c All information on clients");
System.out.println("f to quit");
System.out.println("b to update when tickets are bought by a registered Client");
System.out.println("r to update the stored data when a Client cancels a ticket");
option = sc.nextLine();
switch (option) { // these are splitting our inputs to these cases with different outcomes
case "e":
//System.out.println("information on events");
Scanner inFile = new Scanner(new FileReader("input.txt"));
// Other declarations// Reading and processing the input data// Printing out the results outFile.close();
ArrayList<Events> events = new ArrayList<>();
while(inFile.hasNextLine()) {
String data = inFile.next();
events.add(data);//error based on these? Event is based off of arraylist<E> and inherits from those whilst i have them as string?
You are seeing the exception because of Generics in Java.
Your ArrayList is declared to take Events objects.
ArrayList<Events> events = new ArrayList<>();
However, you are trying to add a String object to it.
String data = inFile.next();
events.add(data); //Cannot add a String object, only Events object allowed.
One way to fix this is to create an Events object using the String, and then add to the Arraylist. I am assuming each line has Event name and String in it, separated by a comma.
//Get your event name and tickets from the String data.
String tokens[] = data.split(",");
String eventName = tokens[0];
String ticketsBought = tokens[1];
//create an events object
Events eventObj = new Events(eventName, ticketsBought);
//Now add to your arraylist.
events.add(eventObj);
As an aside, you do not need to extend SortedArrayList in MainProgram. The main class is usually top level class in your project, and it will only contain objects (this is a common practice). If you want to use the new logic you have added in SortedArrayList, then instead of creating ArrayList<Events> events = new ArrayList<>();, you can create SortedArrayList<Events> events = new SortedArrayList<>();

Java : variable reuse

I'm writing a simple Java program.
First, the program asks user to input some info like name and id of the student and uses radio button for asking whether the student is present or absent. After finishing the inputs, then program validate whether predefined student names and inputs are match or not. And check id number again and spit out if input is over 4. Lastly check radio button is true or false. If one of the above two rules get error then program will quit without executing next method.
I have three .java files. One for UI. One for validation and one for storing data.
UI.java
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class UI extends JFrame {
JTextField name = new JTextField("Name", 10);
JTextField id = new JTextField("Id", 10);
JRadioButton attendance = new JRadioButton("Present");
JButton JB = new JButton("Check");
public UI() {
super("Test");
JPanel JP = new JPanel();
JP.add(name);
JP.add(id);
JP.add(attendance);
JP.add(JB);
add(JP);
pack();
setLocationRelativeTo(null);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void buttonAction(){
UI UIbutton = new UI();
UIbutton.JB.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == UIbutton.JB) {
String nameInput = UIbutton.name.getText();
int idInt = Integer.parseInt(UIbutton.id.getText());
boolean attInput = UIbutton.attendance.isSelected();
Validate.nameChk(nameInput);
Validate.idChk(idInt);
Validate.attChk(attInput);
Student studentObj = new Student(UIbutton.name.getText(), idInt, UIbutton.attendance.isSelected());
System.out.println(studentObj.name + "'s ID number is : " + studentObj.id + ".");
System.out.println(studentObj.name + " is present: " + studentObj.attendance);
System.exit(0);
}}});
}
public static void main(String[] args) {
buttonAction();
}
}
Validate.java
public class Validate {
public static void nameChk (String nameInput) {
String n1 = "Matthew";
String n2 = "John";
String n3 = "Mark";
String n4 = "Luke";
if ((nameInput.equalsIgnoreCase(n1))||
(nameInput.equalsIgnoreCase(n2))||
(nameInput.equalsIgnoreCase(n3))||
(nameInput.equalsIgnoreCase(n4))){
System.out.println("Your data is okay.");
}
else {
System.out.println("Error, wrong student name.");
System.exit(0);
}
}
public static void idChk (int idInt) {
if (idInt > 4) {
System.out.println("Your id is not correct.");
System.exit(0);
}
else {
System.out.println("Your id is correct.");
}
}
public static void attChk (boolean attInput) {
if (attInput) {
System.out.println("The student is present.");
} else {
System.out.println("The student is absent.");
}
}
}
Student.java
public class Student {
String name;
int id;
boolean attendance;
Student(String name, int id, boolean attendance) {
this.name = name;
this.id = id;
this.attendance = attendance;
}
}
What I want to know is how can I reuse output of that actionlister method somewhere else. Let say I would create foo.java class and use that studentObj variable to give grades like
System.out.println(studentObj.name+"has B+.");
Sort of.
How can I do that? How to turn that variable into global?
This can be achieved in different ways.
Quite simple, but not a good practice would be to create a Singleton. It would contain Students objects and you'll be able to access them from anywhere. Here is example with eager singleton, but you can implement much better versions (check about singleton implementations i.e. here https://www.journaldev.com/1377/java-singleton-design-pattern-best-practices-examples)
public class StudentsSingleton {
private Map<Integer, Student> students = new HashMap<>();
public Student getStudent(int id) { return students.get(id);}
public void addStudent(Student s) { students.put(s.id, s);}
private static final StudentsSingleton instance = new StudentsSingleton();
//private constructor to avoid client applications to use constructor
private StudentsSingleton(){}
public static StudentsSingleton getInstance(){
return instance;
}
}
In that case, you can access it from anywhere by getting the instance :
StudentsSingleton.getInstance().getStudent(id);
A much better solution and a good practice would be to use some Dependency Injection framework i.e. Spring. In that case, you would create a Bean and inject it whenever it is needed to use.

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

How To Display Objects in Java JList?

I'm trying to create a student registration system. In this system, students can see course name, course credit, and the instructor of the course by clicking the "Courses" button.For this purpose i have a Courses class, a database, a frame and a JList courslist.
ArrayList<Courses> aq = Database.allCourses();
//allCourses() is a static method in my Database class that returns fields from my Database as an ArrayList<Courses>
courselist.setListData(Driver.converToCoursesArray(aq));
//Driver.converttoCoursesArray() is a static method in my Driver class that takes a ArrayList<Courses> as a paramater and returns a Courses[] array.
Now, my problem is that in my frame, JList always seen like p1.Courses#4532
I've seen a similar problem when i was accidently trying to print an object with System.out.println(). But in this situation i convert the arraylist to an array and my JList holds objects(JList). So i'll be happy if you help me.
You need to override toString() in the Course class, such that it returns the name of the course you want to display.
Take a look at this example:
import javax.swing.*;
import java.awt.*;
public final class Example extends JFrame {
public Example() {
Course[] courses = {
new Course("Course 1"),
new Course("Course 2"),
new Course("Course 3")
};
JList<Course> courseJList = new JList<>(courses);
getContentPane().add(courseJList);
pack();
setMinimumSize(new Dimension(200, 200));
setVisible(true);
}
public static void main(String[] args) {
new Example();
}
}
final class Course {
private final String courseName;
public Course(final String courseName) {
this.courseName = courseName;
}
#Override
public String toString() {
return courseName;
}
}
This displays the following:

JComboBox getSelectedItem

New to java and i am unable to see why my action listener is not working on the jcombobox. I think i have followed the other examples on the net to getSelectedItem, but nothing is happening.
FYI, my project is a unit converter (using MVC..hopefully, but that is not my priority).
Any assistance is greatly appreciated.
Thanks, Simon.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class UnitConverterView extends JFrame{
//variables and components
private static final long serialVersionUID = -4673040337179571462L;
private JComboBox<String> unitCategory;
private JTextField fromValue = new JTextField(7);
private JComboBox<String> convertFrom;
private JLabel equalsLabel = new JLabel(" = ");
private JTextField toValue = new JTextField(7);
private JComboBox<String> convertTo;
//constructor
UnitConverterView(){
//set up the view and components
JPanel unitPanel = new JPanel();
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(600,300);
String[] categories = {"Length","Weight","Speed","Temperature"};
unitCategory = new JComboBox<>(categories);
String[] tofromValues = {" "};
convertFrom = new JComboBox<>(tofromValues);
convertTo = new JComboBox<>(tofromValues);
unitPanel.add(unitCategory);
unitPanel.add(fromValue);
unitPanel.add(convertFrom);
unitPanel.add(equalsLabel);
unitPanel.add(toValue);
unitPanel.add(convertTo);
this.add(unitPanel);
}
//get value to convert from
public int getMeasurement() {
return Integer.parseInt(fromValue.getText());
}
//listen for unitCategory to be selected
void addUnitCategoryListener(ActionListener listenForUnitCategory) {
unitCategory.addActionListener(listenForUnitCategory);
}
class UnitCatListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
/*String unitSelected = (String) unitCategory.getSelectedItem();
if (e.getSource() == unitCategory) {
String unitName = (String) unitCategory.getSelectedItem();
System.out.println("UnitName = " + unitName);
changeText(unitName);
}*/
JComboBox cb = (JComboBox)e.getSource();
String unitName = (String) cb.getSelectedItem();
System.out.println("UnitName = " + unitName);
}
void changeText(String name) {
toValue.setText(name);
}
}
}
You have declared a method addUnitCategoryListener() for registering listener to the combobox, but you never called this method. That's why the listener is never registered.
Add the below line at the end of your constructor, then you should be fine:
addUnitCategoryListener(new UnitCatListener());
To simply solve your problem, call the method you created to register the listener on the component. Add this to your constructor:
addUnitCategoryListener(new UnitCatListener());
However, there are a few things you'll want to know:
An ItemListener will usually do a better job than an ActionListener for a JComboBox. The previous one does not fire events if the user selects the already selected item (basically, does nothing). Usually there is nothing you need to do in these cases.
You don't need an extra method just to register the listener, you can directly add to your constructor the line
unitCategory.addActionListener(new UnitCatListener());
and remove your custom method.
The methods changeText and getMeasurement are never used.
Use parametrized types: instead of JComboBox use JComboBox<String>.
You don't need the equalsLabel as a field - a local variable will do - since you do not need to reference it anywhere later (unless you plan on changing a property of the label at runtime).

Categories