My professor really threw us into this project with a blindfold on. We didn't go into depth on using and inserting files into Java. I'm getting a ton of errors, which are most likely due to my incorrect insertion of the file. I saved the text file in the same place the class file is saved on my computer, assuming that would be necessary. I've moved it around multiple places on my computer trying to get it to work. Here is the main program. I'm sorry if it's completely incorrect.
To explain what we're supposed to be doing further, here is the link to the prompt with the pseudocode. I haven't attempted to do all the actions listed because I haven't gotten the file to insert correctly yet.
http://jcsites.juniata.edu/faculty/rhodes/cs1/projects/program9Gen.html
Edit: This is the whole program in its glory. The class was created in a separate project as our introduction to Java classes. We were just told to use it again and insert the main program at the bottom just for ease of grading.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class GenSeq
{
private String seq;
private String species;
private String startCodon;
private String stopCodon;
private String shape;
private String chromosomeLocation;
public GenSeq (String seq, String species, String startCodon, String stopCodon,
String shape, String chromosomeLocation){
this.seq = seq;
this.species = species;
this.startCodon = startCodon;
this.stopCodon = stopCodon;
this.shape = shape;
this.chromosomeLocation = chromosomeLocation;
}
//Allowing the program to later set constructors
//Creating all the appropriate getters and setters for the instance variables
public void setSpecies(String newSpecies){
species = newSpecies;
}
public String getSpecies(){
return species;
}
public void setStartCodon(String newStartCodon){
startCodon = newStartCodon;
}
public String getStartCodon(){
return startCodon;
}
public void setStopCodon(String newStopCodon){
stopCodon = newStopCodon;
}
public String getStopCodon(){
return stopCodon;
}
public void setShape(String newShape){
shape = newShape;
}
public String getShape(){
return shape;
}
public void setChromosomeLocation(String newChromosomeLocation){
chromosomeLocation = newChromosomeLocation;
}
public String getChromosomeLocation(){
return chromosomeLocation;
}
public String toString(){
return "Sequence length: " + seq.length() +
"\nSpecies: "+ species +
"\nStart Codon: "+ startCodon +
"\nStart Codon: "+ stopCodon+
"\nShape: "+ shape +
"\nChromosomal Location: " + chromosomeLocation;
//Creating a toString method to hold all the class data
}
}
public static void main (String args[ ])
{
GenSeq seqA = null;
//Setting constructor to default if not set
//Opening the file
Scanner inputStream = null;
String seq;
try
{
inputStream = new Scanner (new File ("W:\jcsites.junata.edu\students\morrian14\seq.txt"));
}
catch (FileNotFoundException e)
{
System.out.println ("Error opening the file ");
System.exit (0);
}
do{
inputStream = inputStream.trim();
if ('>' == inputStream.charAt(0)){
seq = inputStream.nextLine();
}
}
while (inputStream.hasNextLine());
inputStream.close();
}
The error is this same one repeated continuously
File: C:\LEXIPC\Users\Alexis\GenSeq.java [line: 83]
Error: class, interface, or enum expected
One obvious issue, the last line is clearly meant to have been written as inputStream.close(); and not input.Stream.close(); you will probably need a try .. catch ... around closing the stream too
What exactly is your question? A few notes though...
Get rid of the do{} while() and just do something like this:
while(inputStream.hasNextLine(){
if('>' == inputStream.charAt(0))
seq = inputStream.nextLine();
}
inputStream.close();
I am a bit confused as to why you are recycling seq to read from the file, as that is what you are using as your file's name. A better way to do this would be to use a File class for your file names. Consider: File seq = new File(.../filename.txt).
Also, if you find that you are using too many try/catch blocks, consider using an exception handling class to clean up your code.
Related
I am using Spring-Shell and I would like to mask the input when typing the password field for a particular method.
Looking on the internet and here in the forum, I found many people suggesting to use the console.readPassword() command but, creating the console from inside the IDE gives me a null result.
Scanner in= new Scanner(System.in)
-------------------------------OR------------------------------------
BufferedReader in = new BufferedReader(new InputStreamReader(System.in)
these are the code lines I tried to get the input from the user, but I can't find a way to mask the input, so when someone types the password it shows on the screen.
Looking around I found out that to make the console command work I could use an external terminal instead of the IDE but, when starting SpringBoot (a Spring-Shell project) I get the Jline Warning:
"Unable to create a system terminal, creating a dumb terminal (enable debug logging for more information)".
So is there an easy way to mask the password using the scanner/BufferedReader classes, or do I need to enable the system terminal to use the console?
Thank you
You can use org.jline.reader.LineReader from JLine library which you get by default in a Spring Shell application.
Here's some example code:
import org.jline.reader.LineReader;
public class InputReader {
private static final Character DEFAULT_MASK = '*';
private Character mask;
private LineReader lineReader;
public InputReader(LineReader lineReader) {
this(lineReader, null);
}
public InputReader(LineReader lineReader, Character mask) {
this.lineReader = lineReader;
this.mask = mask != null ? mask : DEFAULT_MASK;
}
public String prompt(String prompt) {
return prompt(prompt, true);
}
public String prompt(String prompt, boolean echo) {
String answer;
if (echo) {
answer = lineReader.readLine(prompt + ": ");
} else {
answer = lineReader.readLine(prompt + ": ", mask);
}
return answer;
}
}
Then, make it a bean:
#Bean
public InputReader inputReader(#Lazy LineReader lineReader) {
return new InputReader(lineReader);
}
and finally use it in your app:
#ShellComponent
public class YourShellComponent {
private final InputReader inputReader;
#Autowired
public YourShellComponent(InputReader inputReader) {
this.inputReader = inputReader;
}
#ShellMethod(value = "connect")
public void connect() throws Exception {
String username = this.inputReader.prompt("Username");
String password = this.inputReader.prompt("Password", false);
// other code
}
}
I am trying to write test methods in Intellij with jUnit. I can succesfully write to the file, however, I need to show that I can write a test method for this. I push in the write direction would be great. My ServerController class write to a file, checks a file for a username, and verifies username and password. This project is for a class and it appears that the most important lesson is learning about documentation (requirements, design, and testing). So, here I am trying to test.
package appLayer;
import java.io.*;
import java.util.Scanner;
public class ServerController {
public void writetoFile(String writeUsername, String writePassword) throws IOException {
PrintWriter fileWriting = new PrintWriter(new FileOutputStream("/Users/dannielsotelo/Documents/database.txt", true));
fileWriting.println(writeUsername + "," + writePassword); //
System.out.println(writeUsername + " was saved to database.txt");
fileWriting.close();
}
public boolean findUsername(String fUsername) {
File file = new File("/Users/dannielsotelo/Documents/database.txt");
try{
Scanner scanner = new Scanner(file);
int lineNum = 0;
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
lineNum++;
if(line.contains(fUsername))
return true;
}
} catch (FileNotFoundException e) {
System.out.println("File not found");
}
return false;
}
public boolean verifyCredentials(String lUsername, String lPassword) {
File file = new File("/Users/dannielsotelo/Documents/database.txt");
try{
Scanner scanner = new Scanner(file);
int lineNum = 0;
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
lineNum++;
if(line.contains(lUsername) && line.contains(lPassword))
return true;
}
} catch (FileNotFoundException e) {
System.out.println("File not found");
}
return false;
}
}
and my ServerControllerTest class
package appLayer;
import org.junit.Test;
import static org.junit.Assert.*;
public class ServerControllerTest {
#Test
public void testwritetoFile() {
}
#Test
public void findUsername() {
}
#Test
public void verifyCredentials() {
}
}
First, you should get rid of the redundant code when scanning the files. It would be sufficient to have one method that searches for arbitrary strings since technically it doesn't matter if you search for a username or a password.
Second, for testing purposes you really should not hard-code the database file. When writing JUnit tests you don't want your actual file to be written or read. Pass the file or the path to it as a constructor parameter.
Writing a test method is quite straight-forward. Write a value to the database, then read it and check if the previously written data is there. It's a good idea to start with a blank file for every test.
PS.: In terms of security, the approach of checking if a line contains username and password is a little disaster :D
Search this forum for testing void methods. But anyway your code is not really testable in sensible way. While you can test methods that return some value, you don't give it enough starting conditions to be sure they do what you want.
Don't hardcode path to files in the method, you'll be better off if it's an argument to the method. Then in tests you can be sure that if you create file with a specified content the method will do this or that or throw an exception if you don't create the file at all.
I need help with a small mars lander video-game I'm making for my computer science class. We have to read a game config text file using scanner and use it as the rules for the different aspects of our game (Gravity, amount of fuel you have, etc.) She gave us different text files and they all have different difficulties and values, but they all have the same format, so I need to be able to simply call the different text file and have a new level ready to play. My question is:
How do I get the input from the file into separate variables so that I can manipulate them to create the game?
Here's the code for reading the text file, it also prints it out to the console
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class MarsLander {
public static void main(String [] args) {
try {
Scanner sc = new Scanner(new File("gameConfig.txt"));
while (sc.hasNext()){
String s = sc.next();
System.out.println(s);
}
sc.close();
}
catch (FileNotFoundException e) {
System.out.println("Failed to open file!");
}
}
}
Here is one of the text game config files:
1000 500
mars_sky.jpg
ship.png ship_bottom.png ship_left.png ship_right.png ship_landed.png ship_crashed.png
20 50
500.0 400.0
100
thrust.wav yay.wav explosion.wav
-0.1
2.0
0.5
500 50
In my solution, I was thinking about something slightly more generic. Let me first show you the piece of code I wrote. I will then explain its behaviour and particularities.
public class GameExample {
private static class Game {
private Long x, y;
private List<String> images = new ArrayList<>();
private Game(final Long x, final Long y, final List<String> images) {
this.x = x;
this.y = y;
this.images = images;
}
public Long getX() {
return x;
}
public Long getY() {
return y;
}
public List<String> getImages() {
return images;
}
public static class Builder {
// Parsing methods used by the builder to read the files and build the configuration
// TODO: add here builder methods for each line of the file
private final List<BiFunction<String, Game.Builder, Game.Builder>> parsingMethods = Arrays.asList(
(str, builder) -> builder.withPositions(str),
(str, builder) -> builder.withImages(str));
private Long x, y;
private List<String> images = new ArrayList<>();
private Builder withPositions(final String str) {
String[] positions = str.split(" ");
x = Long.valueOf(positions[0]);
y = Long.valueOf(positions[1]);
return this;
}
private Builder withImages(final String str) {
Stream.of(str.split(" ")).forEach(imgStr -> images.add(imgStr));
return this;
}
public Game build(final String filename) throws IOException {
Scanner sc = null;
try {
// Read the file line by line
List<String> lines = Files.lines(Paths.get(filename)).collect(Collectors.toList());
// Iterate over each line and call the configured method
IntStream.range(0, lines.size()).forEach(
index -> parsingMethods.get(index)
.apply(lines.get(index), this));
// Build an instance of the game
return new Game(x, y, images);
} catch (IOException e) {
e.printStackTrace();
throw e;
} finally {
if (sc != null) sc.close();
}
}
}
}
public static void main(String[] args) throws IOException {
final Game.Builder builder = new Game.Builder();
Game game = builder.build("file.txt");
System.out.println(game.getX() + ":" + game.getY());
System.out.println(game.getImages());
}
}
This piece of code would output:
10:15
test.jpg
with a given configuration file containing:
10 15
test.jpg
Let me explain what was done. We define a Game builder that has only one public method with the signature Game build(final String filename). It takes the filename and will build the game from the content of this file. The cornerstone of this approach is that the builder defines a list that determine which method of the builder is used for each line of the file:
private final List<BiFunction<String, Game.Builder, Game.Builder>> parsingMethods = Arrays.asList(
(str, builder) -> builder.withPositions(str),
(str, builder) -> builder.withImages(str));
This list says:
Use the method withPositions for the first line
Use the method withImages for the second line
Now, in the build method, it implements the logic that executes the methods on the lines:
// Iterate over each line and call the configured method
IntStream.range(0, lines.size()).forEach(
index -> parsingMethods.get(index)
.apply(lines.get(index), this));
We can therefore easily parse a new line of data by doing the following:
Add a new private method in the builder describing how to parse the line;
Add this method in the list called parsingMethods.
I have a few classes and one main method. The program is used to connect to an Access database and retrieve information.
I have a class which deals with the GUI only (to display the results) in one JTextArea box. Another class runs a while loop and pulls in data from the database and assigns it to a String as such:
line = (line+upid+"\t"+StreetNum+"\t"+suburb+"\t"+area+"\t"+price+"\t"+agentID+"\t"+numBeds+"\t"+numBaths+"\t"+spool+"\t"+numGarages+"\t"+date+"\t"+ownerID+"\t"+SaleOrRent+"\n");
Basically my question is how do I access the String line from the GUI Class so that I can use txtArea.setTextto display line bearing in mind the GUI has no Main Method?
EDIT:
To try get around this, I have created a LineObject which takes line in as a parameter. I then call the getLine from the void addComponents but it gives a nullPointerException?
Here is the searchProps class:
import java.awt.Container;
import java.sql.*;
import java.util.*;
import javax.swing.*;
public class searchProps
{
protected String price, area, query, suburb, date, SaleOrRent, strQuery, out, line="";
protected int agentID, upid, StreetNum, numBeds, numBaths, numGarages, ownerID, size;
protected boolean spool;
PropertyObject PropertyArray[] = new PropertyObject[3];
LineObject obj;
JFrame jf;
JTextArea txtArea = new JTextArea();
{
initialFrame();
addComponents();
}
public searchProps(int propID) //search using UPID only
{
try
{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection conn = DriverManager.getConnection("jdbc:odbc:PropertyOracleDatabase");
Statement s = conn.createStatement();
query = ("SELECT * FROM Properties WHERE UPID = "+propID);
// Fetch table
s.execute(query);
ResultSet rs = s.getResultSet();
while((rs!=null) && (rs.next()))
{
upid=rs.getInt(1);
StreetNum=rs.getInt(2);
suburb=rs.getString(3);
area=rs.getString(4);
price=rs.getString(5);
agentID= rs.getInt(6);
numBeds=rs.getInt(7);
numBaths=rs.getInt(8);
spool=rs.getBoolean(9);
numGarages=rs.getInt(10);
date=rs.getString(11);
ownerID=rs.getInt(12);
SaleOrRent=rs.getString(13);
size++;
line = (line+upid+"\t"+StreetNum+"\t"+suburb+"\t"+area+"\t"+price+"\t"+agentID+"\t"+numBeds+"\t"+numBaths+"\t"+spool+"\t"+numGarages+"\t"+date+"\t"+ownerID+"\t"+SaleOrRent+"\n");
obj= new LineObject(line);
System.out.println(line);
String out = obj.getLine();
System.out.println(out);
}
// close and cleanup
s.close();
conn.close();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
void initialFrame()
{
jf=new JFrame();
jf.setSize (1300,700);
jf.setTitle("Property Oracle | Results Page");
jf.setVisible(true);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
void addComponents()
{
Container con = jf.getContentPane();
con.setLayout(null);
txtArea.setBounds(20,30,1200,600);
con.add(txtArea);
txtArea.setText("UPID\tStreetNum\tSuburb\tArea\tPrice\tAgentID\tBedrooms\tBathrooms\tSwimming Pool\tGarages\tDate\tOwner\tSale/Rent\n");
out = obj.getLine();
System.out.println(out);
}
}
And here is the LineObject class:
public class LineObject
{
protected String line;
public LineObject(String a)
{
line = a;
}
public String getLine()
{
return line;
}
}
I will assume your database access code runs in a separate thread, otherwise typical latency would block the event dispatch thread (EDT). Pass a reference to your JTextArea as a parameter to your database code. Use the reference to update the JTextArea on the EDT:
final String line = …
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
ta.append(line);
}
});
A related example is seen here.
Make line a private class field of your class (the one that runs the while loop).
public LoopingClass {
private String line;
public void loopMethod() {
line = //...
}
}
Then create a public getter to this variable.
public LoopingClass {
private String line;
public void loopMethod() {
line = //...
}
public String getLine() {
return line;
}
}
Then from your GUI, call the getter of the object instance.
// somewhere in your GUI class
loopingClassInstance.getLine();
Take a look at the MVC pattern: it's always good practice to decouple the business logic (putting data in a database and building the string "line") from the frontend (GUI).
By the way, since you're building the string by appending more data to it, you should consider using a StringBuilder instead:
StringBuilder lineBuilder = new StringBuilder();
// append data:
lineBuilder.append(someString);
// create a string only when you need it:
String line = lineBuilder.toString();
In this way you are not continuosly creating new strings (which can be expensive in the long run especially if the string keeps growing), but using the buffer provided by the StringBuilder and then creating an actual string only when you need it, e.g., when you need to update your JTextArea.
Hands up, I'm struggling with a programming question for M257 at OU, its formative and carries no marks and is due in a few days. I can't call the constructor from the test class and have struggled for several hours to no avail, the class compiles in Netbeans 6.91 fine but the constructor won't create the object. What am I doing wrong?
I had no problem with first question but am totally stuck here, obviously missing something significant - guidance please. The idea is to pass in the name of the file to the class, I can do the rest once I know the file is open and scanner initialised.
===============
/**
* Title: WordCounter class
* Description: M257 TMA01, Q2 - word counter class as described in instructions
* #author Andrew Broxholme
*/
package tma01q2;
import java.io.*;
import java.util.*;
public class WordCounter
{
//Class instance variables
public static int totalWords;
public static int totalEven;
public static int totalOdd;
public static int totalLetters;
private Scanner fileScanner;
String sourceFile;
String line; //The lines of the text file
//Single argument constructor, accepts source filename
public boolean WordCounter(String fileToRead)
{
sourceFile = fileToRead;
try
{
openRead();
while (fileScanner.hasNext())
{
// Process each line of the text file
line = fileScanner.nextLine();
System.out.println(line);
// countWords();
}
return true;
}
catch (Exception exp)
{
return false;
}
finally
{
fileScanner.close();
}
}
//openRead, opens the file and processes each line of the file until finished
private boolean openRead() throws IOException
{
try
{
fileScanner = new Scanner(sourceFile);
return true;
}
catch (Exception exp)
{
return false;
}
}
// More methods to be added
}
/*
* TestWordCounter.
* Description: Tests the WordCounter class as per TMA01q2 instructions
* #author Andrew Broxholme
* V1.0 30th April 2011
*/
package tma01q2;
public class TestWordCounter
{
//Create a WordCounter to process the specified text file.
public static void main(String[] args)
{
String testFile = "haiku.txt";
WordCounter fileStats = new WordCounter(testFile);
}
}
When I try to comiple this is what it passes back.
Compiling 1 source file to C:\M257\TMA01\TMA01Q2\build\classes
C:\M257\TMA01\TMA01Q2\src\tma01q2\TestWordCounter.java:18: cannot find symbol
symbol : constructor WordCounter(java.lang.String)
location: class tma01q2.WordCounter
WordCounter fileStats = new WordCounter(testFile);
1 error
C:\M257\TMA01\TMA01Q2\nbproject\build-impl.xml:246: The following error occurred while executing this line:
C:\M257\TMA01\TMA01Q2\nbproject\build-impl.xml:113: Compile failed; see the compiler error output for details.
I haven't given up on this and will update question if I find the answer first.
8th May 2011: The answers were helpful but in the end although in the end I gave up on this question as the further I got I realised I just didn't know enough about how subclasses inherit from superclasses and need to try some simpler (and to me more meaningful) examples to deepen my understanding. The problem though was that NetBeans is too good at suggesting what you need without telling you exactly why its doing what it is doing, fine if your an experienced java developer, but not so good if your starting out.
I'm already started (i.e read the brief) for TMA02 and will give myself a full two months, much more sensible one thinks!
This is not a constructor. Remove the boolean as return type - constructors don't have return types. So:
public WordCounter(String fileToRead)
instead of
public boolean WordCounter(String fileToRead)
And that's what the error tells you - the compiler cannot find a constructor with that name.
See: constructors
the signature of the constructor is wrong.
public WordCounter(String fileToRead)
{
sourceFile = fileToRead;
try
{
openRead();
while (fileScanner.hasNext())
{
// Process each line of the text file
line = fileScanner.nextLine();
System.out.println(line);
// countWords();
}
return true;
}
catch (Exception exp)
{
return false;
}
finally
{
fileScanner.close();
}
}
use constructor like this. Replace the signature of constructor to
public WordCounter(String fileToRead)