I'm making an application at the moment and now I need to fill a comboBox with all the values that I get from another class in an arrayList type.
This is the code that I use to fill my combobox:
public void setComboBox(){
MessageConsole mc = new MessageConsole(textArea);
//The redirectOut will redirect the text from the System.out.prtnln to the text area.
mc.redirectOut();
List<String> arrayList = new ArrayList<String>();
if(gf.loadCombo("config") != null){
arrayList.addAll(gf.loadCombo("config"));
for (int i = 0; i < arrayList.size(); i++) {
String s = arrayList.get(i);
configName.removeItem(s);
configName.addItem(s);
}
}
}
This is the code from the other class:
public Collection<String> loadCombo(String property) {
//Check if the property file is present in the given directory.
if(cf.checkProperty()==true){
//Check is there are any properties saved in the property file.
if(cf.getProperty() != null){
Properties prop = new Properties();
FileInputStream fis;
try {
fis = new FileInputStream("config.properties");
prop.load(fis);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//Check if the properties match with the entered configuration.
List<String> arrayList = new ArrayList<String>();
arrayList.addAll(cf.getProperty());
Collection<String> propertyList = new ArrayList<String>();
for (int i = 0; i < arrayList.size(); i++) {
String s = arrayList.get(i);
if(s.startsWith(property)){
System.out.println("This value has been added to the arrayList from the other class: "+s);
propertyList.add(cf.getPropertyValue(s));
}
}
return propertyList;
}
//The system prints a message of the missing properties.
else{
System.out.println("You need to save a configuration first.");
}
}
//The system prints a message of the missing property file.
else{
System.out.println("The property file is either missing or could not be found. in de Load class");
}
return null;
}
Following is a screenshot of the result:
As you can see all the values are added as 1 long String"[3, 2, 1]" in the comboBox. Could anyone tell me why this happens?
Thanks in advance,
Lordarnoud
P.S. I hope this is the correct way to ask my question and I hope my question is clear enough for everyone to understand.
At a first look it appears the problem could be one of two things:
The value "[3 2 1]" is returned from the loadCombo method. More specifically from the cf.getProperty(). It is not clear from the context provided what cf is.
The value "[3 2 1]" was added to your combobox at some other point in you code. If this might be case, try using configName.removeAllItems() instead of removing then adding each item in your collection.
Additionally in your loadCombo method you load the config.properties file into a Properties object and then do nothing with it. It seems your intentions were to load the config properties from that file instead of the cf object.
Related
I'm trying to create a csv file where only 1 team name is shown per row, so when you click the button twice it will only add the team name if its not already there. currently it adds the team "UWE" every single time you press the button. the code for this is below:
public void showStats(ActionEvent event){
try {
File matchFile = new File("src/sample/matchData.csv");
File scoreFile = new File("src/sample/scoreData.csv");
Scanner matchReader = new Scanner(matchFile);
Scanner scoreReader = new Scanner(scoreFile);
while (matchReader.hasNextLine()) {
String data = matchReader.nextLine();
List<String> matchList = Arrays.asList(data.split(","));
while (scoreReader.hasNextLine()) {
String dataScore = scoreReader.nextLine();
List<String> dataScoreList = Arrays.asList(dataScore.split(","));
if (dataScoreList.get(0).equals(matchList.get(0))) {
//
} else {
writeExcel("scoreData", matchList.get(0)) ;
}
System.out.println(dataScoreList);
}
System.out.println(matchList);
}
matchReader.close();
scoreReader.close();
} catch (FileNotFoundException e) {
System.out.println("An error occurred.");
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
The csv file "matchData" contains:
UWE,KCC,Jin,Julia,Chris,Ryan,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,5,0
The csv file "scoreData" has one empty line in it
You can first go through your source CSV file and put in a map only the lines that contain unique team key....
while (matchReader.hasNextLine()) {
String data = matchReader.nextLine();
String[] record = data.split(",", 2);
Map<String, String> matchList = new TreeMap<>();
matchList.putIfAbsent(record[0], record[1]); // only unique keys are entered.
}
// TODO write to Excel each entry in the map (you don't need to check for unique keys)
Notice that writing to Excel is done after the map is complete. This is the best approach; or at least better than what you showed in your original post. With this approach, you are letting the data structure simplify your process (and no nested loops).
UPDATE:
I forgot to mention that matchList.putIfAbsent(K, V) works with Java 8 and later. If using Java 7 or older (should upgrade Java ASAP), then you will have to do the following:
String value = matchList.get(record[0]);
if (value == null) {
matchList.put(record[0], record[1]);
}
This is because Map#get(K) returns null is no entry is found OR the map allowed for null values to be entered for a given key. Otherwise, it will return the previous value. The new method introduced in Java 8 does this check automatically.
I have spring boot application where the user sends parameter and based on this parameter, there are configuration should be get.
I created file name configuration type “Configration_Types.properies” , now how can I read the configuration based on parameter pass I don't want to create database to lookup it?
Type1=Type1
Type1.width=60
Type1.heght=715
Type2=Type2
Type2.width=100
Type2.heght=720
Type3=Type3
Type3.width=100
Type3.heght=700
Type4=Type4
Type4.width=450
Type4.heght=680
Type5=Type5
Type5.width=270
Type5.heght=750
for example pass type4 should get configuration
Type4
450
680
The function could be like that :
public void readPropertyByType(String type)
{
InputStream input = null;
try
{
Properties prop = new Properties();
// if your type is Type4, the typeKey will be Type4. for compare data
String typeKey = type + ".";
String filename = "config.properties";
input = new FileInputStream(filename);
prop.load(input);
String typeInformation = "";
Enumeration< ? > e = prop.propertyNames();
while (e.hasMoreElements())
{
String key = (String)e.nextElement();
if (key.indexOf(typeKey) > 0)
{
typeInformation = typeInformation + prop.getProperty(key);
}
}
System.out.println("The data of type " + type + "is :" + typeInformation);
}
catch (IOException ex)
{
ex.printStackTrace();
}
finally
{
if (input != null)
{
try
{
input.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
But you make a better design for your property file.
In case the order of property file never change, you can stop the
function when you get all expected data, don't need to loop whole
file.
Hope it help.
---UPDATE---
The property file could be like that :
Option 1
Type4.width=450
Type4.heght=680
Type5.width=450
Type5.heght=680
Option 2
Type4=450, 680
Type5=450, 680
Depend on each option, you can break the while loop when you got the expected data.
If you can modified your property file Configration_Types.properies like:-
type[0].width=60
type[0].heght=715
type[1].width=100
type[1].heght=720
type[2].width=100
type[2].heght=700
type[3].width=450
type[3].heght=680
type[4].width=270
type[4].heght=750
And your class for consume property values from property file would be:-
#Component
#ConfigurationProperties("type") // prefix type, find type.* values
public class GlobalProperties {
private List<Type> type = new ArrayList<Type>();
//getters and setters
public static class Type
{
private int width;
private int heght;
// getter setter
}
And As based on user params you can access the value from arraylist.
hope this help:
I have to start of with saying that I'm a super noob when it comes to Java and programming in general.
My issue:
I have a problem with parsing a textfile and putting the data of the file into subrecords. The key whether to put the data into a new subrecord or not is in my case based on the name of the tag in the file.
Here's an example of a file that I want to parse/split into subrecords.
SHP
DATA 1
DATA 2
DATA 3
ITEM A
DATA B
DATA C
ITEM A
DATA B
DATA C
SHP
So basically when I encounter the first occurrence of SHP I want to create a new SHP Class and then map the following tags (DATA in this example) into fields of the new SHP Object. However if the next tag is ITEM, I then need to create a new ITEM Object in SHP and then map the following DATA tags until a new ITEM tag is found... What makes it worse is that number of SHP tags can also be multiple in the file that I'm parsing.
What I've done so far is to put all the contents of the file into a ArrayList and then I iterate over this list and depending of the value of the current "record" I then create a new Object or map the value of the record in the list.
However I get totally lost with all my loops and I need some help! :)
Is there a good way of doing this? How can I easily fetch chunks of data from an ArrayList and extract and map this into new objects depending on the value of the current record?
I'm thinking that the same questions would appear if you would to create a parser from scratch that maps the data from an XML file and puts this into Objects, right?
Extended version of issue with real examples
Maybe it's easier if I provide some real examples and real data to illustrate my issue. Initially I just thought that it would make it harder to understand but hopefully this will be easier.
The file and the content:
Example file
So what I have done so far is to create some classes that should represent the data in the file. I even names the fields/variables of the class so that it would be easier for me to map.
Here are the classes:
public class REQUEST {
public SHIPMENT[] SHIPMENTS;
}
public class SHIPMENT {
public String IVNO;
public String CNNAME;
public String CNADDRESS1;
public String CNPC;
public String CNCITY;
public PACKAGE[] PACKAGES;
public ITEM[] ITEMS;
}
public class PACKAGE {
public String GOODSLINE;
public String GOODSDESCR;
public String GRWEIGHT;
}
public class ITEM {
public String ITEMLINE;
public String ARTNO;
public String GRWEIGHT;
}
And below is the code that I've done that doesn't work properly. I manage to create multiple SHIPMENT's and also create the ITEM's but for some reason the data isn't mapped. I also before calling this mapMethod put the entire content of the file into an ArrayList. One fiel row per record in the ArrayList.
Ok, so here it is in it's total and please be gentle with me :)
public REQUEST mapRequest(ArrayList<String> inputfile)
throws IllegalArgumentException, IllegalAccessException {
REQUEST request = new REQUEST();
ArrayList<SHIPMENT> shipments = new ArrayList<>();
for (int i = 0; i < inputfile.size(); i++) {
String recordIdentifier = getRecordIdentifier(inputfile.get(i));
if (StringUtils.equals(recordIdentifier, "IVNO")) {
SHIPMENT shipment = new SHIPMENT();
ArrayList<ITEM> items = new ArrayList<>();
int j = 0;
for (j = i; j < inputfile.size(); j++) {
String currShpRecIdentifier = getRecordIdentifier(inputfile.get(j));
String nextShpRecIdentifier = StringUtils.EMPTY;
if (j + 1 < inputfile.size()) {
nextShpRecIdentifier = getRecordIdentifier(inputfile.get(j + 1));
}
try {
Field field = shipment.getClass().getField(currShpRecIdentifier);
String shipmentRecordValue = getRecordValue(inputfile.get(j));
field.set(shipment, shipmentRecordValue);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
if (StringUtils.equals(nextShpRecIdentifier, "ITEMLINE")) {
ITEM item = new ITEM();
int k = 0;
for (k = j; k < inputfile.size(); k++) {
String currItemRecIdentifier = getRecordIdentifier(inputfile.get(k));
String nextItemRecIdentifier = StringUtils.EMPTY;
if (k + 1 < inputfile.size()) {
nextItemRecIdentifier = getRecordIdentifier(inputfile
.get(k + 1));
}
try {
Field field = item.getClass().getField(currItemRecIdentifier);
String itemRecordValue = getRecordValue(inputfile.get(k));
field.set(item, itemRecordValue);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
if (StringUtils.equals(nextItemRecIdentifier, "ITEMLINE")) {
break;
}
}
items.add(item);
j = k;
}
if (StringUtils.equals(nextShpRecIdentifier, "IVNO")) {
break;
}
}
shipment.ITEMS = items.toArray(new ITEM[items.size()]);
shipments.add(shipment);
i = j;
}
}
request.SHIPMENTS = shipments.toArray(new SHIPMENT[shipments.size()]);
return request;
}
private String getRecordIdentifier(String in) {
return StringUtils.left(in, 15).trim();
}
private String getRecordValue(String in) {
return StringUtils.substring(in, 16).trim();
}
I don't really get where you're having trouble with that.
FileReader input = new FileReader(filePathToYourFile);
BufferedReader bufRead = new BufferedReader(input);
String readLine = null;
String shp = "SHP"; //or define them as "constants" with static final
String item = "ITEM";
String data = "DATA";
ArrayList<SHPType> listOfSHPObjects = new ArrayList<SHPType>();
SHPType lastSHP;
ItemType lastItem;
while ( (readLine = bufRead.readLine()) != null)
{
String[] splittedLine = readLine.split(" ");
if(splittedLine[0].equals(shp))
{ //if it's an SHP, make an SHP object, and add it to a list.
lastSHP = new SHPType();
listOfSHPObjects.add(lastshp);
}
if(splittedLine[0].equals(data) && lastSHP != null)
{ //if it's a data object, either add it to the property/field/list/collection of the latest SHP, or if you have found an item, add it to the item.
//of course if you haven't found any SHP objects, discard it, as it doesn't belong anywhere
if(lastItem == null)
lastSHP.CollectionThatHoldsData.add(new DataType());
else
lastItem.CollectionThatHoldsData.add(new DataType());
}
if(splittedLine[0].equals(item) && lastSHP != null)
{
//create a new last item and add it to the item list of the last SHP found. New data will be added to this item
lastItem = new ItemType();
lastSHP.CollectionThatHoldsItems.add(lastItem);
}
}
//close the file etc...
This assumes that if you find the following:
DATA
ITEM
SHP
etc
The first DATA and ITEM are meaningless. If you want to assign them to the first SHP that you have found, store them in a waitingForSHP arrayList, and as soon as you find the first SHP, add them there.
Also, if you want to create an SHP/Item/Data based on the second value (fe in DATA 5, meaning 5), pass the 5 (splittedLine[1] variable in my example) as an argument to the constructor of the SHPType/ItemType/DataType object. It will be a string, so if you want to pass it as an integer, you will have to convert it ( Integer.parseInt(splittedLine[1]) ).
I'm having problems with my try-catch exception here. Actually what it does is to prompt the user for the name of a text file say, Robot.txt but if say the file does not exist, I have to make sure that the application reprompts the user for the file name. Hope you guys can understand I'm still a newbie here so please feel free to provide suggestions or advices on my coding etc. Cheers!
Main method class:
import java.io.*;
import java.util.Scanner;
import java.util.Vector;
class TestVector3 {
public static void main(String [] args)
{
System.out.println("Please enter the name of the text file to read: ");
Scanner userInput = new Scanner(System.in);
Vector <KillerRobot> robotDetails = new Vector <KillerRobot>();
KillerRobot robot;
Scanner fileInput = null;
try
{
File textFile = new File(userInput.nextLine());
fileInput = new Scanner(textFile);
}
catch (FileNotFoundException e)
{
System.out.println("Error - file not found!");
System.out.println("Re-enter file name :"); //Reprompt user for name of the text file
fileInput = new Scanner(userInput.nextLine());
}
while(fileInput.hasNext())
{
robot = new KillerRobot();
String first = fileInput.next();
robot.setName(first);
String second = fileInput.next();
robot.setMainWeapon(second);
int third = fileInput.nextInt();
robot.setNumberOfKills(third);
robotDetails.add(robot);
}
for(KillerRobot i : robotDetails)
{
System.out.println(i);
}
fileInput.close();
}
}
KillerRobot class file:
class KillerRobot {
private String name;
private String mainWeapon;
private int numberOfKills;
KillerRobot()
{
}
public String getName()
{
return name;
}
public String getMainWeapon()
{
return mainWeapon;
}
public int getNumberOfKills()
{
return numberOfKills;
}
public String toString()
{
return name + " used a " + mainWeapon + " to destroy " + numberOfKills + " enemies ";
}
public void setName(String a)
{
name = a;
}
public void setMainWeapon(String b)
{
mainWeapon = b;
}
public void setNumberOfKills(int c)
{
numberOfKills = c;
}
}
As you state that you are a beginner, let us first look at the relevant part of your code, to make sure that we talk about the same thing:
Scanner fileInput = null;
try {
File textFile = new File(userInput.nextLine());
fileInput = new Scanner(textFile);
}
catch (FileNotFoundException e) {
System.out.println("Error - file not found!");
System.out.println("Re-enter file name :");
fileInput = new Scanner(userInput.nextLine());
}
You have an input and you want to check this input for a condition and require a new input until this condition is fulfilled. This problem can be solved using a loop like the following:
Scanner fileInput = null;
do {
System.out.println("Enter file name :");
try {
fileInput = new Scanner(new File(userInput.nextLine()));
} catch (FileNotFoundException e) {
System.out.println("Error - file not found!");
}
} while(fileInput == null);
So finally, why does this work? The fileInput variable is set to null and will remain null until the given file is successfully read from standard input because an exception is thrown otherwise what prevents the fileInput variable to be set. This procedure can be repeated endlessly.
On a side note, for performance reasons, it is normally not a good idea to implement control flow that is based on exceptions. It would be better to check for a condition if a file exists via File::exists. However, if you read the file after checking for its existence, it might have been deleted in the meantime which introduces a racing condition.
Answer to your comment: In Java (or almost any programming language), you can inline expressions. This means that instead of calling two methods in two different statements as in
Foo foo = method1();
Bar bar = method2(foo);
you can simply call
Bar bar = method2(method1());
This way, you save yourself some space (what becomes more and more important if your code gets longer) as you do not need the value that you saved in foo at any other place in your code. Similarly, you can inline (which is how this pattern is called) from
File file = new File(userInput.nextLine())
fileInput = new Scanner(file);
into
fileInput = new Scanner(new File(userInput.nextLine()));
as the file variable is only read when creating the Scanner.
Try putting the try-catch in a loop like below:
Scanner fileInput = null;
while (fileInput==null)
{
try
{
System.out.println("Please enter the file name.");
File textFile = new File(userInput.nextLine());
fileInput = new Scanner(textFile);
}
catch (FileNotFoundException e)
{
System.out.println("Error - file not found!");
}
}
Next you could think of moving the File creation part into separate method, so that the code was cleaner.
Do not fall for try-catch instead add this as your functionality. Exceptions are naturally for run time error handling not for logic building.
Check if file exists at given location.
File textFile = new File(userInput.nextLine());
// Check if file is present and is not a directory
if(!textFile.exists() || textFile.isDirectory()) {
System.out.println("Error - file not found!");
//Reprompt user for name of the text file
System.out.println("Re-enter file name :");
fileInput = new Scanner(userInput.nextLine());
}
You can put while loop instead of if loop if you want to continuously prompt user until correct path is entered.
You can call back your main(), like following
try
{
File textFile = new File(userInput.nextLine());
fileInput = new Scanner(textFile);
}
catch (FileNotFoundException e)
{
System.out.println("Error - file not found!");
main(args); // recursively call main() method
}
Now if user first attempt wrong then your code will asked to re enter file name.
How to check isFile exist?
File file = new File(filePathString);
if(file.exists() && !file.isDirectory()){
System.out.println("file exist");
}
This really is an XY problem because you assumed the only way to check for a file existence is by catching a FileNotFoundException (hence asking about try-catch exception handling) whereas other means exist to help you avoid a try-catch idiom in an elegant manner.
To check if a file exists at the given path or not you can simply use the File.exists method. Please also see the File.isFile method and/or the File.isDirectory method to verify the nature of the targeted File object.
EDIT : As stated by raphw, this solution is best used in simple scenario since it can incur a race condition in the case of concurrent file deletion happening during the file existence check. See his answer for handling more complex scenario.
I need to save some data into text file. I'm using class Files with its method write().
If such file doesn't exist - everything alright. The problem is if such file already exists it appends new data to the end of the file. And I need to clear it first. The code is:
public static void main(String[] args) {
DepoList test0 = new DepoList();
test0.init();
ArrayList<Depo> list0 = test0.getList();
Collections.sort(list0);
for (Depo depo : list0) {
String str = String.format("sum = %1$8.2f interest = %2$7.2f\n", depo.getSum(), depo.getIncome());
System.out.format(str);
try {
Files.write(Paths.get("depo.txt"), str.getBytes(), StandardOpenOption.CREATE, StandardOpenOption.APPEND);
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println();
I think I need to add some another StandardOpenOperation. How to clear the file before putting data there?
Remove StandardOpenOption.CREATE,Standardoption.APPEND this just appends your new data to the existing one
Use Files.write((Paths.get("depo.txt"), str.getBytes());