I dont know how well I'll be able to ask this question, but given a text file I need to parse through and extract the productID data and store it in a HashSet, userID data and store it in a HashSet, and the review/score and store it in an ArrayList. They also need to be used to create a graph, where the productID is connected with an edge between the userID.
The data is found here http://snap.stanford.edu/data/web-FineFoods.html
You can ignore review/time, review/helpfulness, review/summary, and review/text information, they dont need to be stored in memory.
My current code looks like this:
import java.io.*;
import java.util.*;
import java.nio.charset.*;
public class Reviews
{
String fileName = "newfinefoods.txt";
GraphType<String> foodReview;
HashSet<String> productID;
HashSet<String> userID;
ArrayList<String> review;
int counter; //was using this to make sure I'm counting all the lines which I think I am
public Reviews(){
foodReview = new GraphType<>();
productID = new HashSet<>();
userID = new HashSet<>();
review = new ArrayList<>();
counter = 0;
}
public int numReviews(){
return review.size();
}
public int numProducts(){
return productID.size();
}
public int numUsers(){
return userID.size();
}
public void setupGraph(){
Scanner fileScanner;
String line = "";
try{
fileScanner = new Scanner (new File (fileName), "UTF-8");
String pr = "";
while(fileScanner.hasNextLine()){
line = fileScanner.nextLine();
String[] reviewInfo = line.split(": ");
String productInfo = reviewInfo[1];
System.out.println(productInfo);
}
}
catch (IOException e){
System.out.println(e);
}
}
public static void main(String[] args){
Reviews review = new Reviews();
review.setupGraph();
System.out.println("Number of Reviews:" + review.numReviews());
System.out.println("Number of Products:" + review.numProducts());
System.out.println("Number of Users:" + review.numUsers());
}
}
Whenever I run the code, looking in the array reviewInfo at 1, it only prints one set of data, but if I change it to 0 it seems to print all the information (just not the info that I need). I need to create this graph and get the info from the data but I am really just super stuck, and any tips or help would be very appreciated!
Here is a sample of the data:
product/productId: B001E4KFG0
review/userId: A3SGXH7AUHU8GW
review/profileName: delmartian
review/helpfulness: 1/1
review/score: 5.0
review/time: 1303862400
review/summary: Good Quality Dog Food
review/text: I have bought several of the Vitality canned dog food products and have found them all to be of good quality. The product looks more like a stew than a processed meat and it smells better. My Labrador is finicky and she appreciates this product better than most.
product/productId: B00813GRG4
review/userId: A1D87F6ZCVE5NK
review/profileName: dll pa
review/helpfulness: 0/0
review/score: 1.0
review/time: 1346976000
review/summary: Not as Advertised
review/text: Product arrived labeled as Jumbo Salted Peanuts...the peanuts were actually small sized unsalted. Not sure if this was an error or if the vendor intended to represent the product as "Jumbo".
product/productId: B000LQOCH0
review/userId: ABXLMWJIXXAIN
review/profileName: Natalia Corres "Natalia Corres"
review/helpfulness: 1/1
review/score: 4.0
review/time: 1219017600
review/summary: "Delight" says it all
review/text: This is a confection that has been around a few centuries. It is a light, pillowy citrus gelatin with nuts - in this case Filberts. And it is cut into tiny squares and then liberally coated with powdered sugar. And it is a tiny mouthful of heaven. Not too chewy, and very flavorful. I highly recommend this yummy treat. If you are familiar with the story of C.S. Lewis' "The Lion, The Witch, and The Wardrobe" - this is the treat that seduces Edmund into selling out his Brother and Sisters to the Witch.
product/productId: B000UA0QIQ
Initial approach of your design is right, but you should structure it a little more:
Method setupGraph should be splitted in little specific and parametrized methods:
Since the users and products are part of the class' state, I deem it better that the class' constructor receives the scanner as an input parameter. Then, after initializing the state variables, it should call setupGraph (which should be private) passing the input scanner.
setupGraph shall receive an input scanner and take the responsibility of reading lines from it, and give a proper treatment to the IOExceptions that might arise. On each line, it should merely call another private method for processing the read line. If you want to count all the read lines, this is where you should place the increment.
The processing line method shall receive an input string, and take the responsibility of deciding if it contains a product data, a user data, a score data, or none. This must be done through properly parsing its contents.
Here is where you can use String.split() to get the name and value of each line, and then evaluate the name to decide where to store the value. And if you want to count all the processed lines, this is where you should place the increment.
Last, main method shall take the responsability of instancing the scanner and passing it when constructing the Reviews object. In this way, you could receive the file name as input argument from the command line, so your program would become flexible.
Realise that the only public methods of your class should be the constructor and the getters. And state variables shuld be private.
Related
I'd like some help with a Java assignment, if it's no problem. We've just been getting started, but my teacher wants us to do a bunch of research on our own and I can't figure out how to do the homework.
We have an assignment where he's given us the lines to 10 different speeches, and we have to use objective oriented coding to display the entire thing. I figured out so far how to set up variables to link to the first file and have things displayed on the screen, but he wants us to limit how many characters are on each line so he doesn't have to scroll sideways forever to read a speech on a single line. This leaves me in a position where I'd be making new variables for every sentence of every speech for the next few hours, and I figure there has to be a more efficient way. So, I asked my friend (who took the class last year) for advice, and he recommended using a for loop to scan for spaces after a certain amount of characters and jump to the next line to continue, but I have no idea how to do any of this. All I have so far is the base file that our teacher told us to use, and the beginning of the first of 10 speeches.
/**
* TextWriter is a program that uses objective coding to display 10 political speeches
* #author ()
* #version (10/12/16)
*/
public class TextWriter {
private String textToDisplay;//text to be displayed
public TextWriter() {
textToDisplay = "";
}
public TextWriter(String inputText) {
textToDisplay = inputText;
}
public void clearTextToDisplay() {
textToDisplay = "";
}
public void setTextToDisplay(String inputText) {
textToDisplay = inputText;
}
public String getTextToDisplay() {
return textToDisplay;
}
public void display() {
System.out.println(textToDisplay);
}
}
and the second one,
/**
* Displays Washington's Farewell speech using objective oriented coding.
* #author ()
* #version (10/12/16)
*/
public class WashingtonFarewellDriver {
public static void main(String[] args) {
TextWriter wf1;
wf1 = new TextWriter();
wf1.setTextToDisplay("Friends and Citizens: The period for a new election of a citizen to administer the executive government of the United States being not far distant, and the time actually arrived when your thoughts must be employed in designating the person who is to be clothed with that important trust, it appears to me proper, especially as it may conduce to a more distinct expression of the public voice, that I should now apprise you of the resolution I have formed, to decline being considered among the number of those out of whom a choice is to be made.");
wf1.display();
TextWriter wf2;
wf2 = new TextWriter("I beg you, at the same time, to do me the justice to be assured that this resolution has not been taken without a strict regard to all the considerations appertaining to the relation which binds a dutiful citizen to his country; and that in withdrawing the tender of service, which silence in my situation might imply, I am influenced by no diminution of zeal for your future interest, no deficiency of grateful respect for your past kindness, but am supported by a full conviction that the step is compatible with both.");
wf2.display();
TextWriter wf3;
wf3 = new TextWriter("The acceptance of, and continuance hitherto in, the office to which your suffrages have twice called me have been a uniform sacrifice of inclination to the opinion of duty and to a deference for what appeared to be your desire. I constantly hoped that it would have been much earlier in my power, consistently with motives which I was not at liberty to disregard, to return to that retirement from which I had been reluctantly drawn.");
wf3.display();
}
}
(hopefully that's formatted right)
I hope that it's ok that I'm asking for homework help, because it does seem to be kind of looked down upon, but I'm pretty confused and hopefully someone can explain what's going on a little more than my teacher.
Thank you! If there's any questions, I might be able to answer them too.
Loop thru the string character by character using String.charAt(). Keep track of how many characters you've put out. After say 25 characters the next time you see a space spit out a newline character, reset your counter to 0, and start printing it out again.
String in = "This is a run on sentence that is too long for a single line and should be broken up into multiple lines because I said so. This is a run on sentence that is too long for a single line and should be broken up into multiple lines because I said so.";
int counter=0;
for(int i=0;i<in.length();i++){
Char c=in.charAt(i);
counter++;
System.out.print(c+"");
if((counter>25)&&(c=' ')){
System.out.println();
counter=0;
}
}
There are many ways to approach this.
You can add this function in your TextWriter class for adding lines something like this:
public void addLines(int maxChars){
int lines = 1;
String[] lineStrings;
if(maxChars <= textToDisplay.length()){
if(textToDisplay.length() % maxChars > 0) lines = textToDisplay.length()/maxChars + 1;
else lines = textToDisplay.length()/maxChars;
lineStrings = new String[lines];
for(int i = 0; i < lines; i++){
if(i == (lines - 1)) lineStrings[i] = textToDisplay.substring(i*maxChars, i*maxChars + (textToDisplay.length() % maxChars)) + "\r\n";
else lineStrings[i] = textToDisplay.substring(i*maxChars, i*maxChars + maxChars) + "\r\n";
}
textToDisplay = "";
for(int i=0; i < lines; i++){
textToDisplay += lineStrings[i];
}
}
}
and in your Main function, maybe:
public class WashingtonFarewellDriver {
public static void main(String[] args) {
TextWriter wf1;
wf1 = new TextWriter();
wf1.setTextToDisplay("Friends and Citizens: The period for a new election of a citizen to administer the executive government of the United States being not far distant, and the time actually arrived when your thoughts must be employed in designating the person who is to be clothed with that important trust, it appears to me proper, especially as it may conduce to a more distinct expression of the public voice, that I should now apprise you of the resolution I have formed, to decline being considered among the number of those out of whom a choice is to be made.");
wf1.addLines(50);
wf1.display();
TextWriter wf2;
wf2 = new TextWriter("I beg you, at the same time, to do me the justice to be assured that this resolution has not been taken without a strict regard to all the considerations appertaining to the relation which binds a dutiful citizen to his country; and that in withdrawing the tender of service, which silence in my situation might imply, I am influenced by no diminution of zeal for your future interest, no deficiency of grateful respect for your past kindness, but am supported by a full conviction that the step is compatible with both.");
wf2.addLines(50);
wf2.display();
TextWriter wf3;
wf3 = new TextWriter("The acceptance of, and continuance hitherto in, the office to which your suffrages have twice called me have been a uniform sacrifice of inclination to the opinion of duty and to a deference for what appeared to be your desire. I constantly hoped that it would have been much earlier in my power, consistently with motives which I was not at liberty to disregard, to return to that retirement from which I had been reluctantly drawn.");
wf3.addLines(50);
wf3.display();
}
}
This should work, but some words will be cut off, because this just roughly separates lines by a maximum characters in a line.
thanks for all the feedback, it helped me, but ultimately there was another pretty easy way my that friend walked me through using the main.org.apache.commons.lang3.text.WordUtils package that he downloaded!
import java.io.IOException;
import org.apache.commons.lang3.text.WordUtils;
public class WashingtonFarewellDriver {
public static void main(String[] args) throws IOException {
int wwl = 110;
TextWriter wf1;
wf1 = new TextWriter(WordUtils.wrap("long sentences",wwl));
wf1.display();
}
}
I am having a problem with what should be an extremely easy task. I have a very large program that stretches across 10-15 classes. The entire program centers around a Buffered Reader/Writer with a GUI. The users input determines how a file is read and then converted.
Anyway, currently I set the file location with this line.
bw = new BufferedWriter(new FileWriter(NachaMain.saveFile.getSelectedFile()+"\\NachaOutput.ACH"));
As you can see I used a constant file name. Some of the data analysts have asked me to make the name dynamic, so I am trying to add a random number. This is how I added the random number:
int newNum = 1 + (int)(Math.random() * ((99 - 1) + 1));
String randomNumber = Integer.toString(newNum);
String location = "//"+randomNumber+"NachaOutput.ACH";
bw = new BufferedWriter(new FileWriter(NachaMain.saveFile.getSelectedFile()+location));
So far so good. When I test the "location" string at this stage it works perfectly. The problem lies in that I must call this file again for buffered readers in two different classes. I have a "FileValidation" class that takes the completed buffered writer file and analyzes it for errors. I attempted to call this "location" variable by making it static like this:
public static String location;
I attempt to call it in the validation class like this:
br = new BufferedReader(new FileReader(NachaMain.saveFile.getSelectedFile()+MainWriter.location));
The file location and everything is correct the problem is that in testing the "location" variable comes up null.
I do not understand this. I set the variable as a static in my "NachaMain" class and then changed it using a random number. Why then is the other class coming up null even though it's accessing a static variable that has already been changed?
If anyone has a solution I would appreciate it. Sorry I can't post more code but I can't see an easy way to isolate this code and there is too much to post my entire program.
Duplicate Notes: This question has been flagged as a duplicate. However the duplicate question was simply describing how to initialize a variable and my answer was much simpler, the problem with naming a variable with it's type declaration twice. I did not find a solution in that post however I got my answer here.
First off - your random looks strange:
// Last I checked, 99-1 + 1 was 99 ;-)
int newNum = 1 + (int)(Math.random() * ((99 - 1) + 1));
String randomNumber = Integer.toString(newNum);
Why not simply
String randomNumber = Integer.toString(new Random().nextInt(100)+1);
But then to your main problem:
String location = "//"+randomNumber+"NachaOutput.ACH";
That's an assignment to a local variable not to a static instance variable
Change it to
location = "//"+randomNumber+"NachaOutput.ACH";
this way, it accesses to static member of the same name. And you have to would have to make sure that location does not change "suddenly". Maybe once per program run is enough? Then add a nullcheck:
if(null == location) {
location = "//"+randomNumber+"NachaOutput.ACH";
}
Advice on things not asked
If I told a developer to make the name "dynamic", I'd expect a program, where I could somehow define the name that's stored.
Ways to do that (some, not all)
Use a System.property for the filename with default
if(null == location) {
location = "//"+System.getProperty("nacha.file", "NachaOutput.ACH");
}
Use a setting that can be changed in the UI. Like a menu "Settings". And then persist choice made in a Preferences
You are trying to assign a value to the static field location by declaring its type:
String location = "//"+randomNumber+"NachaOutput.ACH";
This is likely within a method, and likely gives the location variable method-scope.
In turn, your static String location is never assigned, thus it's null (default String value).
Just remove the type String before declaration, to assign your static field instead.
Unrelated, but worth noting...
The idiom:
int newNum = 1 + (int)(Math.random() * ((99 - 1) + 1));
... only generates pseudo-randoms, and doesn't leverage java.util.Random#next....
I would look into the java.util.UUID.randomUUID() idiom, or java.util.Random#next... just in case.
The following requisites are those for the program I'm currently having an issue with:
The program must be able to open any text file specified by the user, and analyze the frequency of verbal ticks in the text. Since there are many different kinds of verbal ticks (such as "like", "uh", "um", "you know", etc) the program must ask the user what ticks to look for. A user can enter multiple ticks, separated by commas.
The program should output:
the total number of tics found in the text
the density of tics (proportion of all words in the text that are tics)
the frequency of each of the verbal tics
the percentage that each tic represents out of all the total number of tics
Here is my program:
public class TextfileHW2 {
// initiate(
public static int[] initiate(int[] values){
for (int z=0; z<keys.length; z++){
values[z] = 0;
}
return values;
processing(values);
}
// processing(values)
public static int[] processing(int[] valuez){
while (input.hasNext()){
String next = input.next();
totalwords++;
for (int x = 0; x<keys.length; x++){
if (next.toLowerCase().equals(keys[x])){
valuez[x]+=1;
}
}
return valuez;
output();
}
for (Integer u : valuez){
totalticks += u;
}
}
public static void output(){
System.out.println("Total number of tics :"+totalticks);
System.out.printf("Density of tics (in percent): %.2f \n", ((totalticks/totalwords)*100));
System.out.println(".........Tick Breakdown.......");
for (int z = 0; z<keys.length; z++){
System.out.println(keys[z] + " / "+ values[z]+" occurences /" + (values[z]*100/totalticks) + "% of all tics");
}
sc.close();
input.close();
}
public static void main(String[] args) throws FileNotFoundException {
static double totalwords = 0; // double so density (totalwords/totalticks) returned can be double
static int totalticks = 0;
System.out.println("What file would you like to open?");
static Scanner sc = new Scanner(System.in);
static String files = sc.nextLine();
static Scanner input = new Scanner(new File(files));
System.out.println("What words would you like to search for? (please separate with a comma)");
static String ticks = sc.nextLine(), tics = ticks.toLowerCase();
static String[] keys = tics.split(",");
static int[] values = new int[keys.length];
initiate(values);
}
My program should be logically right as I wrote it and successfully ran it for a while last week, but the difference with this one (which doesn't work) is that I must use separate methods for each component of the analysis, which shouldn't be too difficult a task considering the program was working before So I naturally tried to split up my program such that I can call my first method (which I called initiate) then my 2nd and 3rd methods called processing and output.
First of all, what does static really mean? I remember my teacher saying that it represents a global variable which I can use anywhere in the program. As you can see I changed every variable to static to perhaps make my task easier.
Also, do I strictly need to use public static + type returned if I'm going to change something?
Let's say I want to change the values of an array (like I do in my program and use public static void) do I need to return something to actually change the values of the array or is it ok to use public static void?
If anyone also has any general pointers for what concerns my methods I would really appreciate it.
Your problem is in your initiate method:
return values;
processing(values);
Once you call return, your method stops. If you are using Eclipse (which I highly recommend), you should have gotten an error saying "Unreachable code," because there is simply no way for the program to execute your processing method.
I also saw this flaw in your output method.
First of all, what does static really mean? I remember my teacher
saying that it represents a global variable which I can use anywhere
in the program. As you can see I changed every variable to static to
perhaps make my task easier.
It depends on the context. There is a good overall description here. The meaning is different when applied to methods, fields, and classes. To say it makes variables "global" is a bit simplified.
Also, do I strictly need to use public static + type returned if I'm going to change something?
I'm a little confused about what you mean. A method declared as public static *return_type* has three separate, independent qualities:
public: It is accessible by any other class.
static: It does not require an instance of the class to function (see above link).
*return_type*: This is, of course, the return type.
These properties aren't really related to "changing something". Unless I misunderstood your question, the answer is: No, the method specifiers and return type have no impact on its ability to change something with the exception that static methods cannot modify non-static fields or call non-static methods of this (there is no this in static methods).
Let's say I want to change the values of an array (like I do in my program and use public static void) do I need to return something to actually change the values of the array or is it ok to use public static void?
What you do in the function is entirely independent of the access specifier and static-ness of it (with the above-mentioned exception that this does not exist in static methods). If your function has any side-effects like changing the values in an array (or any values for that matter), then it does it regardless of public, or static, or its return type.
Check out the More on Classes section of the official language tutorial. It is concise and well-written and should help complete your understanding of the general concepts you're asking about. Check out some of the other tutorials there as well if you'd like.
I have an assignment that requires me to take a large dataset, store it in an array, and then create methods that interpret the data in various ways. The file data I am given is in the form like so:
0 138
0 139
0 140
0 141
0 142
0 799
4 1
4 10
4 12
4 18
etc... (it is very large)
This data is supposed to represent a social network of people, with the numbers representing individuals. Each line contains a person on the left who has 'trusted' the person on the right. I am supposed to interpret this data so that I can find all the persons a particular person trusts, how many people trust a particular person, and how to find the most trusted person. However, I am at a complete loss as to how to write these methods, and so I was wondering if you guys could help me out. Here's the code I have so far:
public class SocialNetwork {
static Scanner scanner = new Scanner(System.in);
static void findTrusted()
{
System.out.println("Please input person number you would like to find Trustees for");
trustee = (scanner.next());
}
public static void main(String[] args){
File inData = new File("dataset.txt");
ArrayList<Integer> links = new ArrayList<Integer>();
try
{
Scanner in = new Scanner(inData);
in.nextLine();
in.nextLine();
in.nextLine();
in.nextLine();
while (in.hasNext())
{
int trustee = in.nextInt();
int trusted = in.nextInt();
links.add(trustee);
links.add(trusted);
}
in.close();
}
catch (FileNotFoundException e){
e.printStackTrace();
}
}
}
As you can see, my findTrustee method has very little in it. I just don't know where to even start. I have come up with a little pseudocode to try and dissect what needs to be done:
prompt user for input on which person(integer) to find his/her trustees
search arraylist links for person(integer) inputted
print all persons(integers) on the right side of the lines that begin with person requested
However, I just don't quite know how to do this.
The structure links doesn't really help you. It has no idea of "from" and "to". You are storing Persons as numbers, but not storing any relationships between two people. You're really working in graph theory, and when you can you should look at reference works and Java libraries for graph theory.
So, what is a trust link? It is an object that has two people, the trustee and trusted people. Create a class for this:
public class Trust {
private final int trustee;
private final int trusted;
public Trust(final int trustee, final int trusted) {
this.trustee = trustee;
this.trusted = trusted;
}
// Getters, equals, hashCode, toString, formatted output for humans.
}
Have your class SocialNetwork be able to create these. By the way, create a SocialNetwork instance in your main method, and stop using static for everything else.
public Trust createTrust(Scanner scanner) {
int trustee = scanner.nextInt();
int trusted = scanner.nextInt();
return new Trust(trustee, trusted);
}
You might need to add exception handling and end of file handling.
Make links a list of Trust objects, and then write methods that scan that list as needed.
/**
Return a list of all the people who trustee trusts.
#param trustee A person in the system.
#return a list of the people trustee trusts.
*/
public List<Integer> trusting(int trustee) {
final List<Integer> trusted = new ArrayList<>();
for (Trust link: links) {
// Add something from link to trusted if it should.
// This looks like homework; I'm not doing everything for you.
}
return trusted;
}
Write other methods as you need them. Then, think about whether these data structures are efficient for this problem. Could Maps be better? MultiMaps from other libraries? An open source graph theory library of some sort? Perhaps you should use a database instead. Perhaps you should have a Person class instead of using just integers; that way you can label people with their names.
I think there are quite a number of ways you can implement this (regardless of performance). For example, you can use HashMap, array of array (or list of lists if you really like list...)
I will give an example using list maybe, since you seem using it... (although I think this is a bit odd)
Say, you have a list holding the people on the left.
ArrayList<ArrayList> leftList = new ArrayList<ArrayList>();
For leftList,loop through it till you reach the max no. of the left column (now you may see why an array/HashMap is better...) by doing something like:
leftList.add(new ArrayList());
in each loop.
Then all you have to do now is to read the file and plug the list of trustees to rightList corresponding to the truster. E.g. I have 1 3, 1 4 and 2 3; your implementation will achieve sth like:
leftList.get(1).add(3) / leftList.get(1).add(4) / leftList.get(2).add(3)
depending which line you are reading.
With this setup, I guess you can solve those three questions quite easily? Otherwise, just look for more advice here. But make sure you think through it first!
Hope my answer gives you some ideas.
I'm concerned about my Java client directly connecting to the MySQL server due to all of the issues that could occur, and the security risks I believe it could pose. Such as someone being able to decompile the file and get the login details for the database. As beautiful as it would be, I'm too scared to take that risk. I've written a PHP script to echo data that the client can interpret. The PHP script is what connects to the MySQL.
It's rather simple: Java->PHP->MySQL
I'm going to provide screenshots of the MySQL structure, so you may better understand when trying to visualize this.
id: possibly tid/sid
tid: teacher id, used to link to the teacher
sid: student id, used to link to the student
gid: grade id
aid: assignment id
gp: gained points
pp: possible points
Grading rows are for each assignment per student. So for example if a teacher had 30 students assigned to one assignment, there would be 30 rows in the grading tab and one in the assignments. Duplicate assignment names are NOT allowed.
When the client is requesting the data, I just use a buffered reader & URL to download the string. This is the example output of when the client receives the assignment names.
Test Assignment;Secondary Test Assignment;
This is what it looks like to the client once the column names are downloaded:
As you can see the first two columns are there by default, the last two are assignment names.
I want each row in the table to be a student. However, here is where my trouble comes in. I'm trying to receive the proper data from grading. I don't know how I'm going to do this. I have about 3 months experience with Java, so you could definitely call me a newbie.
Here is my idea, but I didn't think it was so great of an idea:
Search through all of the column names and insert the value into the proper column in that row where assignment name matches.
I didn't know how difficult that would be. I'm guessing the nice people who developed swing built something in for that, but I can't find any resources.
Does anyone have any recommendations on what to do in this situation? I feel lost.
Let's start with the Java client. Here is some code that reads from a php page and that creates a JTable out of it. (actually it's reading from a String for simplicity but you can easily change the code to match your real case, see the comment in the code).
public static void main(String[] args) throws Exception {
String receivedFromPHP = "Student ID;Student Name;Test Assignment;Secondary Test Assignment;\n"
+ "1;Luc;Test assignment 1;Secondary Test assignment 1;\n"
+ "2;Vador;Test assignment 2;Secondary Test assignment 2;";
BufferedReader br = new BufferedReader(new StringReader(receivedFromPHP));
// For real: br = new BufferedReader(new InputStreamReader(new URL("http://localhost/yourPhpPage.php").openStream()));
DefaultTableModel dtm = new DefaultTableModel();
String line;
boolean headersReceived = false;
while ((line = br.readLine()) != null) {
String[] columns = line.split(";");
if (!headersReceived) {
dtm.setColumnIdentifiers(columns);
headersReceived = true;
} else {
dtm.addRow(columns);
}
}
JTable table = new JTable(dtm);
JFrame f = new JFrame();
f.add(new JScrollPane(table));
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
Nothing really difficult until now. The real thing is to write the php page with the proper query. Obviously, you know better what you want your page to output but I guess your are going for something like this:
<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "pinkfluf_dvonx");
/* check connection */
if ($mysqli->connect_errno) {
printf("Connect failed: %s\n", $mysqli->connect_error);
exit();
}
/* Select queries return a resultset */
if ($result = $mysqli->query("SELECT Name FROM City LIMIT 10")) {
printf("Select returned %d rows.\n", $result->num_rows);
/* free result set */
$result->close();
}
/* If we have to retrieve large amount of data we use MYSQLI_USE_RESULT */
if ($result = $mysqli->query('SELECT u.id AS "Student ID", u.username AS "Student Name", ... FROM members u, grading g, assignments a WHERE ...')) {
while($row = $result->fetch_array(MYSQLI_NUM)) {
for ($i=0; $i<sizeof($row); $i++) {
echo $row[$i] . ";";
}
echo "\n";
}
$result->close();
}
$mysqli->close();
?>
Of course, the code I give here is very approximative (given the information I could extract from your question) so it's certain that you'll need to adapt the code to make it work as you'd like to but I hope it can help you getting started (keep going :)).
As far as securing your database, I'd recommend creating a locked down user that can only execute stored procedures - then you don't have to worry about someone decompiling your code. They'd only be able to access what they can access through your code. Here's a tutorial on how to do that.
As far as your main question goes, I would recommend all your data gathering/sorting be done in your SQL query. If you're doing that in the JTable, you end up mixing your Model and View (see MVC for more detail).
So essentailly you want your data coming back from the query in this form:
Student; Student Name; Test Assignment; Secondary Test Assignment
Which means,
You need to add a relation between your grade table and your assignment table (most likely addding aid to the grading table)
You're going to need to come up with a slightly more complicated SQL Query - something like this:
Select g.sid, g.name, a.name from ASSIGNMENTS a
join GRADING g on a.aid = g.aid
where g.tid = 123123 order by g.name
Create a 2D array based on the data and put it in the table (If you're still using your PHP interface, you'll want to split the strings on your delimiters to create a 2D array.)
((DefaultTableModel)table.getModel).setDataVector(data, columnNames);
EDIT
If you're convinced you just want to search through the rows for a value, and then update a column in the row you found - this should get you in the right direction:
Integer searchStudentID = 123123;
int searchColumn = 0;
String updateValue = "Value";
int updateColumn = 3;
//Look through the table for the right row
Vector<Vector<Object>> data = ((DefaultTableModel)table.getModel()).getDataVector();
for(Vector<Object> row : data){
// If on the right row, update it
if(row.elementAt(searchColumn).equals(searchStudentID)){
row.setElementAt(updateValue, updateColumn);
}
}