Read from file and display in GUI java - java

I need to read the file in the main than add the red lines (from the file) to an array in the class that stores array objects and display in GUI class. My problem is that nothing goes to the GUI. The getTeamName from Team returns null.
I read the file in
fr = new FileReader("TeamsIn.txt");
Scanner in = new Scanner(fr);
while (in.hasNextLine()){
String line = in.nextLine();
team = new Team(line);
team = teamIn.addTeam(team);
than I add lines to the Team [] array in MatchManager
public Team addTeam( Team teamName)
{
for(int i = 0; i < MAX_TEAMS; i++)
teams[i] = teamName;
return teamName;
}
And i want to display in the GUI
Team t = new Team(teamName);
display = new JTextArea(ROWS, COLUMNS);
display.setEditable(false);
display.setText(t.getTeamName());
JScrollPane scrollPane = new JScrollPane(display);
return scrollPane;
public class Team {
public Team(String teamName){
this.teamName = teamName;
//System.err.println(teamName);
}
public String getTeamName(){
return teamName;
}
public String setTeamName(String tName){
return teamName;
}
But the display.setText(t.getTeamName()); doesnt return anything.

Here's a bit of advice. You may want to restructure your entire program. I know it may seem like "are you for real?", but yes I'm serious. I know you've probably spent a lot of time on it and the last thing you want to do is start over, but the reality of it is, you seem to have a really poor design. Here are some pointer.
Keep the data and view separate. And have some structure to your data. What I mean by that is to keep all the data and data manipulation method in one class.
Here's an example, using ideas from your program
public class MatchManager { // This class holds all the teams
private List<Team> teams = new ArrayList<Team>();
private int countTeam;
private static int MAX_TEAMS=8;
public MatchManager(){
try {
FileReader fr = new FileReader("TeamsIn.txt");
Scanner in = new Scanner(fr);
while (in.hasNextLine()){
String line = in.nextLine();
Team team = new Team(line);
teams.add(team);
}
} catch ( ... ) {}
}
public List<Team> getTeams(){
return teams;
}
}
What the above code does is Once you instantiate the MatchManager, all the teams will get populated.
The JavaBallTournamentGUI class is the one that the program should be launched from. Remember how I talked about keeping the data and view separate. If you think about it, is data supposed to run? No, data is not a program. The GUI is a program though. So run the GUI program getting data from your Model class, the MatchManager.
Something like this.
public class JavaBallTournamentGUI extends JFrame {
MatchManager manager = new MatchManager();
List<Team> teams;
public JavaBallTournamentGUI(){
teams = manager.getTeams();
}
}
Now you can use all the data from the MatchManager in the GUI class.
I notice you instantiating the Team class in a couple different places. That really isn't necessary. Whenever you want to get the data of a team, you can just call it from the list of Teams,
like this
String oneTeam = teams.get(2).getTeamName();
textField.setText(oneTeam);
Do you notice how everything flows more smoothly this way? If you don't, sorry, I tried the best I could to explain. But I hope you get the main points of this. This type of design is much cleaner.
Edit: To print all
If its a JTextArea
for (Team team : teams){
textArea.append(team.getTeamName() + "\n");
}

Related

How to store data in an index in an ArrayList into Arrays in Java

I am new to Java and I am trying to do a calculation using values within a txt file. I have read the txt file, which has 3 tabs, each with three values
I have been able to read the file and get the columns as indices but cannot add the separate values into array. So I want three separate arrays
Read file method
public void read()
{
try
{
FileReader read = new FileReader(file);
String line = null;
while((line = FileReader.readLine()) != null)
{
a.add(line);
}
}
catch (FileNotFoundException e) {}
catch(IOException e) {}
}
Processing method
private void processor () {
for (String li : a)
{
String[] data = li.split("\\s");
Index = Double.parseDouble(data[0]);
Customers = Double.parseDouble(data[1]);
rateOfBuy = Double.parseDouble(data[2]);
}
}
I dont think you are thinking about your data structures correctly. If I were you I would think about this a little differently. To me it makes the most sense just to use a simple array. To handle the complexity of the three columns, I would create a new class called CustomerRate or something to that effect. I would then make the data into instance variables belonging to instances of that class. That way you could just have a simple array of CustomerRate objects and then access the data stored by each of those objects. This will probably be a lot simpler to deal with overall too.
I am not sure exactly what you are trying to accomplish but I'll do my best to help
You would create your new class to be something like this:
your new class:
//This is your new class
public class CustomerRate {
private int person;
private double rate;
//constructor
public CustomerRate(int person, double rate) {
this.person = person;
this.rate = rate;
}
//add appropriate getters and setters and whatever else you need
public double getRate() {
return rate;
}
}
Use the data your parse from your file to create new CustomerRate Objects. Create an array of your objects. Note that this is just an example with one entry with random numbers I'm going to use so you will have to get the loop and parse working:
//creating an example customer
CustomerRate customer1 = new CustomerRate(100, 0.5);
//create your collection to store your customer data that you will add/parse
List<CustomerRate> myList = new ArrayList<CustomerRate>();
//adds to list
myList.add(customer1);
//gets element at index and then grabs the rate
double exampleCustomerRate;
exampleCustomerRate = myList.get(0).getRate();
I coded this quickly so I may have made some mistake but I hope that gives you the general idea of what you should do.
You just need another ArrayList to store your rateOfBusiness. Something like this:
String file = "test.txt";
ArrayList<String> a = new ArrayList<String>();
ArrayList<Double> rateOfBusiness = new ArrayList<>(); //Define with your other fields
Then loop through your data and do the math while adding to the array
private void process () {
for (String li : a)
{
String[] data = li.split("\\t");
Index = Double.parseDouble(data[0]);
Customers = Double.parseDouble(data[1]);; //per year
rateOfBuy = Double.parseDouble(data[2]); //per year
rateOfBusiness.add(Customers*rateOfBuy); //Do math and store for that customer
}
}
Edit: Even though this solves your problem, I would look into learning some Object Oriented principles. IsaacShiffman (or Lvl 9 Oddish, or whatever his name is) has a start on how you would solve this going that direction. Makes your code a lot easier to follow and debug.

Simple OOP/private variable query- Java

Not quite sure why this won't work, when i try to compile and run it gives me a null pointer exception. I know it's super simple and probably a stupid question but I can't seem to figure it out!
import javax.swing.JOptionPane;
public class Whatever
{
private int age;
private String name;
private float salary;
public Whatever ()
{
String userName = JOptionPane.showInputDialog ("What is your name?");
Whatever listData[] = new Whatever [10];
listData[6].name = userName;
}
public static void main (String [] args)
{
Whatever testWhatever = new Whatever ();
}
}
Array of Whatever instances - all are null.
I would guess you'd have another problem with OutOfMemoryError as soon as you fix it, because when you call new to initialize the Whatever array elements they'll construct their own arrays and call new, and so on until you get OOM error.
I'll spell it out for you so you can get to the next error:
import javax.swing.JOptionPane;
public class Whatever
{
private int age;
private String name;
private float salary;
public Whatever () {
String userName = JOptionPane.showInputDialog ("What is your name?");
Whatever listData[] = new Whatever[10];
for (int i = 0; i < listData.length; ++i) {
listData[i] = new Whatever(); // This is where you'll get the OOM error. See why?
}
// You'll never get here.
listData[6].name = userName;
}
public static void main (String [] args)
{
Whatever testWhatever = new Whatever();
}
}
And you're putting Swing code in a constructor? Did you intend this as an example of how to write bad code?
Just for future reference, you should run your code in a good IDE - like IntelliJ, the best on the market - with debugging turned on and step through the code. You'll figure it out pretty quickly where the problem lies, faster than asking at SO will tell you.
So yes, it's a pretty stupid example. Hopefully you aren't writing anything like this for real.
With this
Whatever listData[] = new Whatever [10];
you initialized a new Array, but the elements in the Array are not initialized.
So you get a NullPointerException when you access listData[6].name.
You could try this:
for(int i = 0; i < listData.length; i++) {
listData[i] = new Whatever();
}
, but please do this not in the constructor itself.
Because then you would get OutOfMemoryException like duffymo said.
Try to do this directly in main for example.

Saving an object which contains arraylists in arraylists

I have an object of type Restaurant called myRestaurant which contains EmployeesAList, MenuAList and OrdersAList, each of which storing instances of objects Employee, Menu_Item and Order. Each instance of Order stores integers, strings and an arraylist of integers.
When I save myRestaurant, every arraylist is saved except for the arraylist which is within the Orders class.
Any suggestions?
save method in Runner
public boolean SaveToFile(Restaurant myrest)
{
try
{
File outFile = new File("etrest.rest");
//creates object representing file
FileOutputStream outFileStream = new FileOutputStream(outFile);
//connection between program and file
ObjectOutputStream outObjectStream = new ObjectOutputStream(outFileStream);
//class which is used to pass objects which will be saved to file
//Write serializable ArrayList to file
outObjectStream.writeObject(myrest);
//output done, so close the stream
outObjectStream.close();
return true;
}
catch(IOException IOE)
{
System.out.println(IOE.toString()); //debug purpose
return false;
}
}
method in Restaurant to add Order
ArrayList OrdersAList = new ArrayList();
public void AddOrder(Order o)
{
OrdersAList.add(o);
}
part of order class
ArrayList Menu_ItemsIDAList = new ArrayList();
public Order()
{
paid = false;
WaiterNo = 0;
TableNo = 0;
item = 0;
}
public Order(boolean pd, int wN, int tN, int it)
{
paid = pd;
WaiterNo = wN;
TableNo = tN;
item = it;
}
//MENU ITEMS ENTERED PER ORDER
public void AddMenu_ItemID(int item)
{
Menu_ItemsIDAList.add(item);
}
when i create an instance of Order I create a loop to populate the Menu_ItemsIDAList
I can't exactly reconstruct your problem...
You/we should have a better overview where your lists will be saved exactly, and where is your "add"-method? In which class...
So I recommend to you, making a diagram. In your case a UML class diagram (http://en.wikipedia.org/wiki/Class_diagram).
Once you understand the classes, attributes and relations then you can draw such a diagram and can use the code in a proper way.
Of course we could give you a quick solution that "something is missing"... but for future development you should understand basics of object oriented programming. UML class and UML use case diagrams are a good start too...

Java - Add an object to an arraylist, then adding another to the arraylist causes the first element to be overwritten

I'm currently doing my third year programming project and its a folio tracker. :/ I have crated Stock_API and Portfolio_API interfaces (and implementations of them) and a GUI class which when instantiated takes two parameters as so:
public GUI(Portfolio_API p, Stock s){
tempPort = p;
tempStock = s;
}
I use this constructor as a way of getting implementations of these interfaces into the GUI without exposing the implementation to the GUI (which is one of the main objectives of this project). A portfolio object has a name(string) and an ArrayList. A stock object has a ticker symbol(string), a stock name(string), a share value(float), a number of shares(int) and a value of holding(float).
In the GUI i have a portCollection array list which holds objects of type portfolio_API and this is so the system can keep track of multiple portfolios. Also as mentioned in the block of code above has a tempStock and tempPort object.
Sorry to give u so much detail about the program but i thought it best so i could get the context across. Anyway, the problem at hand. I have a method which uses the GUI to get a ticker symbol, a stock name and a number of shares and adds the stock to the current portfolio open(each portfolio has its own tab). The method looks like this:
public void addStock() {
int num_shares = 0;
float dailyChange = 0.0f;
float stockValue = 0.0f;
boolean succeed = true;
// GUI gets information of stock from user
String ticker = JOptionPane.showInputDialog(frame,
"Enter the ticker symbol:");
String stockName = JOptionPane.showInputDialog(frame,
"Enter the Stock name:");
try {
num_shares = Integer.parseInt(JOptionPane.showInputDialog(frame,
"Enter the number of shares:"));
} catch (NumberFormatException e) {
JOptionPane.showMessageDialog(frame,
"Number of shares was not an integer. Try again");
succeed = false;
}
// If parsing was successful...
if (succeed) {
tempStock.setTicker(ticker);
tempStock.setNumberOfShares(num_shares);
tempStock.setStockName(stockName);
// Fetches newest value using the current ticker symbol
boolean succeedUpdate = tempStock.updateShareValue();
if (succeedUpdate) {
tempStock.calculateValueOfHolding();
// Adds to the current portfolio...
String tabName = tabbedPane.getTitleAt(tabbedPane
.getSelectedIndex());
System.out.println(tabName);
findPortfolio(tabName).addStock(tempStock);
findPortfolio(tabName).sort();
// ...Then adds it to the table
JPanel j = (JPanel) tabbedPane.getSelectedComponent()
.getComponentAt(0, 0);
JViewport v = ((JScrollPane) j.getComponent(0)).getViewport();
JTable table = (JTable) v.getComponent(0);
float currentTotal = findPortfolio(tabName).getTotal();
// Updates the total label
((JLabel) j.getComponent(1)).setText("Total: " + currentTotal);
Object[] newStock = { tempStock.getTicker(),
tempStock.getStockName(),
tempStock.getNumberOfShares(),
tempStock.getShareValue(),
tempStock.getValueOfHolding() };
((DefaultTableModel) table.getModel()).addRow(newStock);
}
}
}
When I add more than one stock, the new stock takes place of the old one an effectively overwrites it. I think its the reuse of tempStock that is doing it. Not sure why though as surely if i add the variable to an arraylist it becomes part of that arraylist and needs no association with the tempStock variable?
Methods that are used with the mentioned arraylists :
private Portfolio_API findPortfolio(String name) {
Portfolio_API p = null;
for (int i = 0; i < portCollection.size(); i++) {
if (portCollection.get(i).getName() == name) {
p = portCollection.get(i);
}
}
These two are in the Portfolio class:
#Override
public boolean addStock(Stock_API s) {
if (!doesExist(s)) {
portfolio.add(s);
return true;
} else {
return false;
}
}
#Override
public boolean doesExist(Stock_API s) {
boolean found = false;
for (int i = 0; i < portfolio.size(); i++) {
if (portfolio.get(i).getTicker() == s.getTicker()) {
found = true;
}
}
return found;
}
I've only come here for help because i have hit a brick wall and I really need help. If anyone could give me any suggestions, i'd be eternally in your debt.
Thanks,
Chris
Yes, I think you are right when you say you think it's because you're reusing the tempStock variable. This variable still references the original object so calling setTicker() etc on tempStock also changes the object referenced by your ArrayList because it's the same object. Try reinitialising your tempStock and see if it makes a difference:
// If parsing was successful...
if (succeed) {
tempStock = new Stock(); // or however you instantiate this object
tempStock.setTicker(ticker);
tempStock.setNumberOfShares(num_shares);
tempStock.setStockName(stockName);
Thanks guys for all your input. #oracle certified professor helped with the stock problems after adding an overloaded method for addStock but turned out the same problems plagued portfolio.
What I did was create a makePortfolio method in Portfolio_API to create a new portfolio and return it. That way it avoids any nasty overwrite, gonna add it to stock too just now.
Thanks again guys. Good night! :)

incorrect Vector.size() returned

I'm implementing a Graph which holds "Book" objects as its nodes. The nodes are connected if the books share a keyword. The keywords for each book are held in a Vector within the Book class. To do this, I've created 3 classes.
1) Books 2) Vertex 3) Graph
The Vertex class holds the Book object and also has a Vector containing all the other Vertex objects (other books which share a keyword). In the Driver, I create the book, pass it to a Graph which then inserts it into a Vertex and finally the Vertex into a Vector named "bookGraph".
public final class Graph {
private Vector<Vertex> bookGraph = new Vector<Vertex>();
private int bookCounter = 0;
public Graph() {
}
public void addBook(Book bk) {
Vertex vtx = new Vertex(bk);
bookGraph.add(vtx);
bookCounter++;
System.out.println("Book #1 has " + bookGraph.get(0).getBook().getKeywords().size() + " keywords");
// addAdjVertices();
}
public void showKeywords() {
System.out.println("Book #1 is " + bookGraph.get(0).getBook().getKeywords().size() + " keywords");
}
The information from the books are read from a file in the Driver and inserted into a book object. I'm trying to make sure that this information is read in correctly and properly inserted into the Graph. My problem occurs when trying to get the size of the keyword Vector within the "showKeywords()" method in the Graph class. bookGraph.get(0).getBook().getKeywords().size() returns 0 when the exact same command in the addBook() method returns the correct size. I've implemented accessor methods such as getTitle() or getAuthor() in the Book class and those work correctly within the showKeywords() method. The keyword vector seems to be the only issue within the showKeywords() method. What am I doing wrong here?
Here is my Driver class....
boolean fileopen = false;
String title, author, keys;
long isbn_number;
Vector<String> keywords = new Vector<String>();
String filename = "books.txt";
String[] keywordTokens;
Scanner fin = null;
Scanner input = new Scanner (System.in);
Graph books = new Graph();
try {
fin = new Scanner (new FileReader(filename));
String fline;
fileopen = true;
System.out.println("Reading books.txt...");
while (fin.hasNextLine()) {
fline = fin.nextLine();
title = fline;
fline = fin.nextLine();
author = fline;
fline = fin.nextLine();
isbn_number = Long.parseLong(fline);
fline = fin.nextLine();
keywordTokens = fline.split(",");
for (int x = 0; x < keywordTokens.length; x++) {
keywords.add(keywordTokens[x]);
}
Book tempBook = new Book(title,author,isbn_number,keywords);
books.addBook(tempBook);
keywords.clear();
if (fin.hasNextLine()) fline = fin.nextLine();
}
books.showKeywords();
System.out.println("Ready.");
}
catch (FileNotFoundException e) {
System.out.println("FILE NOT FOUND!");
}
Looks to me like it should work - there's nothing obviously wrong (like accidentally using static variables). Can you provide a short but complete program which demonstrates the problem? The error is likely to be somewhere else - are you calling setKeywords(new Vector<String>()) somewhere, for example?
Any reason for using Vector rather than the more common ArrayList by the way? I would also suggest that setKeywords(String key) should probably be called addKeyword instead...
EDIT: Okay, now that you've posted the code it's obvious: you're only ever creating a single instance of Vector. You're then reusing that instance for every line, and clearing it at the end.
Just declare your keywords variable inside the loop, create a new instance on every iteration, and don't clear it afterwards.
To make your code as readable as possible (and avoid this sort of thing) I would suggest you declare every variable at the point of first use wherever possible, with the narrowest possible scope.
Could you try this snippet and check whether the error is still there:
public void test() {
Vector<String> keywords = new Vector<String>();
keywords.add("keyword");
Book bk = new Book("Author", "Title", 12345, keywords);
Graph bookGraph = new Graph();
bookGraph.addBook(bk);
bookGraph.showKeywords();
}
I think you got lost in your graph of objects :) I suggest to use unit tests to determine how your code should behave and to make sure it actually does behave the way you expect. The tests can build small examples and then check the various getters to see whether they return the correct results.
For what do you need the copy constructor Book(Book)? Perhaps you put copies of the books instead of the books itself into your collection?

Categories

Resources