I'm a beginner, I have got a txt file that user will imported into java, I'm going to read txt file line be line then set variable base on each line and add them to the current record
public void importTXT() {
JFileChooser fc = new JFileChooser();
fc.setAcceptAllFileFilterUsed(false);
fc.setMultiSelectionEnabled(false);
FileNameExtensionFilter filter = new FileNameExtensionFilter(
"TEXT FILES", "txt", "text");
fc.setFileFilter(filter);
int returnVal = fc.showOpenDialog(CollectionFrame.this);
String[] numstrs = null;
if (returnVal == JFileChooser.APPROVE_OPTION) {
File importedFile = fc.getSelectedFile();
try {
Scanner sc = new Scanner(importedFile);
while (sc.hasNextLine()) {
numstrs = sc.nextLine().split("\\s+"); // split by white
// space
}
} catch (IOException e) {
}
// add new collection
Collection newCollection = new Collection(numstrs[0]);
allRecord.addCollection(newCollection);
// add art consignment information
String consignmentName = numstrs[3];
String description = numstrs[4];
I received a ArrayIndexOutOfBoundsException at the second last line
String consignmentName = numstrs[3];
The content of the text file is like:
Richman’s Estate Collection
5
ART
Water Lilies
A superb piece in great condition
Can someone tell me what's wrong?
EDIT:
you are currently reading all lines and replacing each time the value of numstrs
so when you leave the loop, you just got the value of the last line in it.
i think you want to save ALL lines - see below.
END EDIT
you should use an arraylist.
like this:
ArrayList<String[]> numstrsList = new ArrayList<String[]>();
if (returnVal == JFileChooser.APPROVE_OPTION) {
File importedFile = fc.getSelectedFile();
try {
Scanner sc = new Scanner(importedFile);
while (sc.hasNextLine()) {
numstrsList.add(sc.nextLine().split("\\s+")); // split by white
// space
}
} catch (IOException e) {
}
}
you can catch the values of your arraylist with:
for(int i=0:i<numstrsList.size();i++){
String[] oneLineStrArray = numstrsList.get(index)
//do something
}
you should post the text data, otherwise we cant help you about the OutOfBounds error.
Also, i am wondering how you can instantiate a Collection.
As previous comments already has suggested, the file obviously does not contain the information in the form you expect.
I suggest that you add som error handling to it after the scanner read.
if (numstrs.length < 5){
///TODO: add some handling here, exception or error dialog
}
Here, first go through ArrayIndexOutOfBoundsException
Check numstrs length before you try to access index value(s). You can do
String consignmentName = null, description = null;
if (numstrs.length >= 4) {
consignmentName = numstrs[3];
}
if (numstrs.length >= 5) {
description = numstrs[4];
}
Also, as pointed out by one of the comment - numstrs will always have the values returned by the last line.
Related
I have a Problem with my saving Loop of my .txt-Files. It always saves the last File twice (if I put in 2 for the for loop)
Currently I tried using int writingLength = fc.getSelectedFiles().length;, which then results in
no saving Option in total. Appreciate any thought that could help me to solve my problem, since I'm fairly new to Java.
Here the whole code snipped to give a better overview of my code:
private void prepareTDDExcelDoc() {
fc.setMultiSelectionEnabled(true);
fc.resetChoosableFileFilters();
fc.setAcceptAllFileFilterUsed(false);
final FileNameExtensionFilter filter = new FileNameExtensionFilter("Excel document (*.csv)", "csv");
fc.setFileFilter(filter);
int writingLength = fc.getSelectedFiles().length;
for(int i=0;i<writingLength;i++) {
final String suggestedFilename = reportName.replaceAll("\\W+", "_") + ".xlsx";
fc.setSelectedFile(new File(suggestedFilename));
final int returnVal = fc.showSaveDialog(frmCognosTddBuilder);
if (returnVal == JFileChooser.APPROVE_OPTION) {
try {
enableUserInteraction(false);
outputFilename = fc.getSelectedFile().getCanonicalPath();
final ExportedOutputInterface exportedExcelOutput = new ExcelOutput(this, outputFilename);
progressMonitor = new ProgressMonitor(getFrame(), "Builing TDD", "", 0, 100);
task = new ReportDataExtracter(this, exportedExcelOutput);
task.addPropertyChangeListener(new PropertyChangeListener() {
#Override
public void propertyChange(final PropertyChangeEvent evt) {
if ("progress" == evt.getPropertyName()) {
final int progress = (Integer) evt.getNewValue();
progressMonitor.setProgress(progress);
final String message = String.format("Completed %d%%.\n", progress);
progressMonitor.setNote(message);
if (progressMonitor.isCanceled() || task.isDone()) {
if (progressMonitor.isCanceled()) {
task.cancel(true);
} else {
progressMonitor.close();
}
}
}
}
});
task.execute();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
I see this "reportName" variable, which doesn't appear to be declared in this function, so I suppose it's an instance variable. In any case, you're doing a small transformation on that value and setting it as the output file name for ALL the entries of the list. I imagine the output file is only ever going to have the last file in the list.
It's really helpful to execute code like this in the debugger, so you can step through it and watch the values of variables. As your code is creating UI components, you'll probably need to use two displays. It's been a few years since I had to debug UI code.
Hi I need to import a text file into a Jtable. I have to store each column into a separate array so I was thinking to create a 2D array for the table, and 1D array for each column inside. (9 columns, 20 rows total)
All i've managed to do so far is import the text file and display it in the Jtable.
The data types i have to use are int, string and double(or float) as I have to create as student table where their I.D numbers (int )names, address ect (string) and grades (double) will be shown and ill have to be able to do calculations with the grades.
private void formWindowOpened(java.awt.event.WindowEvent evt) {
// When the window is opened, the information from the text file will be loaded into the table (tblStudentDetails)
try {
BufferedReader br = new BufferedReader(new FileReader ("C:\\Users\\XXX\\NetBeansProjects\\StudentDetailsJava\\lib\\StudentDetails.txt"));
//Get the first line
//Get the columns name from the first line
// Set columns name to the tblStudentDetails model
String firstLine = br.readLine().trim(); // Reading the file line (row) of the text file
// while(firstLine !=null) {
String[] columnsName = firstLine.split("\t"); // The coloums are split by tab
DefaultTableModel model = (DefaultTableModel)tblStudentDetails.getModel();
model.setColumnIdentifiers(columnsName);
// Get lines from txt file
Object[] tableLines = br.lines().toArray();
// Extract data from lines
// Set data to tblStudentsData model
for (Object tableLine : tableLines) {
String line = tableLine.toString().trim();
String[] dataRow = line.split("\t");
{
model.addRow(dataRow);
}
}
br.close();
} catch (Exception ex) {
Logger.getLogger(StudentTable.class.getName()).log(Level.SEVERE, null, ex);
}
}
Here's what I have so far, and before you all kill me, i've spent the past 3 days trying to get this to work and i've tried nearly every solution I can find on this site to no avail.
I've been able to create a 2D array but I haven't been able to actually make it work when reading the text file, or importing it to the Jtable. Someone help!
first year student so I'm definitely a newbie and my assignment is due soon, I cant move on without solving this!
thanks! - Mrs x
Also
The text file looks like this (separated by tab so the first row is too long, but it imports into the Jtable just fine)
enter image description here
try this code:
Scanner input = new Scanner(new File(FILE_NAME));
int rows = 0;
String[] columnsName = null;
if (input.hasNext()) {
columnsName = input.nextLine().split("\t");
} else {
return;
}
while (input.hasNextLine()) {
input.nextLine();
++rows;
}
String[][] a = new String[rows][columnsName.length];
input.close();
input = new Scanner(new File(FILE_NAME));
if (input.hasNextLine()) {
input.nextLine();
}
for (int i = 0; i < rows; i++) {
a[i] = input.nextLine().split("\t");
}
JTable jt = new JTable(a, columnsName);
OK here is my question, I am in an introductory course in Java so I cannot use any advanced code. I am needing to read in a large text file and store each paragraph as an address in an array list. So I am needing to read in the file and split on the carriage return. What I have so far is posted below. Thanks in advance.
public static void fileReader(String x)throws FileNotFoundException{
String fileName = (x + ".txt");
File input= new File(fileName);
Scanner in =new Scanner(input);
ArrayList<String> linesInFile = new ArrayList<>();
while (in.hasNextLine()){
if ( != '/n'){ //this is where i'm losing it
String line = in.nextLine();
linesInFile.add(line);
}
}
in.close();
If the text file contains paragraphs (doesn't contain any line-breaks within the paragraph), then you don't have to check "/n".
while (in.hasNextLine()){
String line = in.nextLine();
linesInFile.add(line);
}
This would suffice
I'm trying to write a method that simply reads in a CSV file and stores the data from the file. Here is a link to a screenshot of the CSV file I am trying to read in, and the code for this method:
http://i.imgur.com/jsGTg.png
public static void correctPrices(String correctfile) {
String data;
Date date;
SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
File correctedfile = new File(correctfile);
Scanner correct;
try {
correct = new Scanner(correctedfile);
correct.nextLine(); //to avoid reading the heading
ArrayList<Date> correctdate = new ArrayList<Date>();
ArrayList<String> correctdata = new ArrayList<String>();
while (correct.hasNext()) {
correctdata.add(correct.nextLine());
//data = correct.nextLine();
//String[] corrected = correct.nextLine().split(",");
//date = formatter.parse(corrected[0]);
//correctdate.add(date);
}
for (int i = 0; i < correctdata.size(); i++) {
System.out.println(correctdata.get(i));
}
}
catch (FileNotFoundException ex) {
Logger.getLogger(DataHandler.class.getName()).log(Level.SEVERE, null, ex);
}
}
As expected, this code would output the last 2 lines of the file. However, when I un-comment data = correct.nextLine(); in the while loop, the output will only return the second line of the CSV, and not the last line. I'm a little baffled by this? All I've tried to do was to store the line into another variable, why would the last line be omitted? Thanks for your help and time, let me know if you need any additional info!
The problem is, when you call correct.nextLine(), it reads in a line and then increments a pointer in the file to where you are reading. Since you call that multiple times in the loop, it increments the pointer multiple times, skipping lines. What you should do is just read the line once, in the beginning of the while loop using
data = correct.nextLine();
and then replace correct.nextLine() everywhere else it appears in the loop with data.
In other words, your while loop would look like
while (correct.hasNext())
{
data = correct.nextLine();
correctdata.add(data);
String[] corrected = data.split(",");
date = formatter.parse(corrected[0]);
correctdate.add(date);
}
I'm reading 2 csv files: store_inventory & new_acquisitions.
I want to be able to compare the store_inventory csv file with new_acquisitions.
1) If the item names match just update the quantity in store_inventory.
2) If new_acquisitions has a new item that does not exist in store_inventory, then add it to the store_inventory.
Here is what i have done so far but its not very good. I added comments where i need to add taks 1 & 2.
Any advice or code to do the above tasks would be great! thanks.
File new_acq = new File("/src/test/new_acquisitions.csv");
Scanner acq_scan = null;
try {
acq_scan = new Scanner(new_acq);
} catch (FileNotFoundException ex) {
Logger.getLogger(mainpage.class.getName()).log(Level.SEVERE, null, ex);
}
String itemName;
int quantity;
Double cost;
Double price;
File store_inv = new File("/src/test/store_inventory.csv");
Scanner invscan = null;
try {
invscan = new Scanner(store_inv);
} catch (FileNotFoundException ex) {
Logger.getLogger(mainpage.class.getName()).log(Level.SEVERE, null, ex);
}
String itemNameInv;
int quantityInv;
Double costInv;
Double priceInv;
while (acq_scan.hasNext()) {
String line = acq_scan.nextLine();
if (line.charAt(0) == '#') {
continue;
}
String[] split = line.split(",");
itemName = split[0];
quantity = Integer.parseInt(split[1]);
cost = Double.parseDouble(split[2]);
price = Double.parseDouble(split[3]);
while(invscan.hasNext()) {
String line2 = invscan.nextLine();
if (line2.charAt(0) == '#') {
continue;
}
String[] split2 = line2.split(",");
itemNameInv = split2[0];
quantityInv = Integer.parseInt(split2[1]);
costInv = Double.parseDouble(split2[2]);
priceInv = Double.parseDouble(split2[3]);
if(itemName == itemNameInv) {
//update quantity
}
}
//add new entry into csv file
}
Thanks again for any help. =]
Suggest you use one of the existing CSV parser such as Commons CSV or Super CSV instead of reinventing the wheel. Should make your life a lot easier.
Your implementation makes the common mistake of breaking the line on commas by using line.split(","). This does not work because the values themselves might have commas in them. If that happens, the value must be quoted, and you need to ignore commas within the quotes. The split method can not do this -- I see this mistake a lot.
Here is the source of an implementation that does it correctly:
http://agiletribe.purplehillsbooks.com/2012/11/23/the-only-class-you-need-for-csv-files/
With help of the open source library uniVocity-parsers, you could develop with pretty clean code as following:
private void processInventory() throws IOException {
/**
* ---------------------------------------------
* Read CSV rows into list of beans you defined
* ---------------------------------------------
*/
// 1st, config the CSV reader with row processor attaching the bean definition
CsvParserSettings settings = new CsvParserSettings();
settings.getFormat().setLineSeparator("\n");
BeanListProcessor<Inventory> rowProcessor = new BeanListProcessor<Inventory>(Inventory.class);
settings.setRowProcessor(rowProcessor);
settings.setHeaderExtractionEnabled(true);
// 2nd, parse all rows from the CSV file into the list of beans you defined
CsvParser parser = new CsvParser(settings);
parser.parse(new FileReader("/src/test/store_inventory.csv"));
List<Inventory> storeInvList = rowProcessor.getBeans();
Iterator<Inventory> storeInvIterator = storeInvList.iterator();
parser.parse(new FileReader("/src/test/new_acquisitions.csv"));
List<Inventory> newAcqList = rowProcessor.getBeans();
Iterator<Inventory> newAcqIterator = newAcqList.iterator();
// 3rd, process the beans with business logic
while (newAcqIterator.hasNext()) {
Inventory newAcq = newAcqIterator.next();
boolean isItemIncluded = false;
while (storeInvIterator.hasNext()) {
Inventory storeInv = storeInvIterator.next();
// 1) If the item names match just update the quantity in store_inventory
if (storeInv.getItemName().equalsIgnoreCase(newAcq.getItemName())) {
storeInv.setQuantity(newAcq.getQuantity());
isItemIncluded = true;
}
}
// 2) If new_acquisitions has a new item that does not exist in store_inventory,
// then add it to the store_inventory.
if (!isItemIncluded) {
storeInvList.add(newAcq);
}
}
}
Just follow this code sample I worked out according to your requirements. Note that the library provided simplified API and significent performance for parsing CSV files.
The operation you are performing will require that for each item in your new acquisitions, you will need to search each item in inventory for a match. This is not only not efficient, but the scanner that you have set up for your inventory file would need to be reset after each item.
I would suggest that you add your new acquisitions and your inventory to collections and then iterate over your new acquisitions and look up the new item in your inventory collection. If the item exists, update the item. If it doesnt, add it to the inventory collection. For this activity, it might be good to write a simple class to contain an inventory item. It could be used for both the new acquisitions and for the inventory. For a fast lookup, I would suggest that you use HashSet or HashMap for your inventory collection.
At the end of the process, dont forget to persist the changes to your inventory file.
As Java doesn’t support parsing of CSV files natively, we have to rely on third party library. Opencsv is one of the best library available for this purpose. It’s open source and is shipped with Apache 2.0 licence which makes it possible for commercial use.
Here, this link should help you and others in the situations!
For writing to CSV
public void writeCSV() {
// Delimiter used in CSV file
private static final String NEW_LINE_SEPARATOR = "\n";
// CSV file header
private static final Object[] FILE_HEADER = { "Empoyee Name","Empoyee Code", "In Time", "Out Time", "Duration", "Is Working Day" };
String fileName = "fileName.csv");
List<Objects> objects = new ArrayList<Objects>();
FileWriter fileWriter = null;
CSVPrinter csvFilePrinter = null;
// Create the CSVFormat object with "\n" as a record delimiter
CSVFormat csvFileFormat = CSVFormat.DEFAULT.withRecordSeparator(NEW_LINE_SEPARATOR);
try {
fileWriter = new FileWriter(fileName);
csvFilePrinter = new CSVPrinter(fileWriter, csvFileFormat);
csvFilePrinter.printRecord(FILE_HEADER);
// Write a new student object list to the CSV file
for (Object object : objects) {
List<String> record = new ArrayList<String>();
record.add(object.getValue1().toString());
record.add(object.getValue2().toString());
record.add(object.getValue3().toString());
csvFilePrinter.printRecord(record);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
fileWriter.flush();
fileWriter.close();
csvFilePrinter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
You can use Apache Commons CSV api.
FYI this anwser : https://stackoverflow.com/a/42198895/6549532
Read / Write Example