I'm creating some code that prints a message to console with a border around it to reinforce my programming knowledge. I'm having issues with this specific snippet of code that should be splitting a large string into an array of strings which can then be printed
//splits message into multiple parts
//lines is an integer representing how many lines the text would take up within the provided border
//panewidth is an integer representing the desired size of the window created by the borders
String[] MessageParts = new String[lines];
for (int i = 0; i < lines; i++){
MessageParts[i] = (message.substring(i*(panewidth-2), (i+1)*(panewidth - 2)));
//
//HACK
System.out.println(MessageParts[i]);
//
}
Full code:
ChrisMadeaGame Class:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package chrismadeagame;
/**
*
* #author 570694
*/
public class ChrisMadeaGame {
/**
* #param args the command line arguments
*/
//Generates a statholder object for score
StatHolder Score = new StatHolder();
StatHolder Turns = new StatHolder();
public static void main(String[] args) {
// TODO code application logic here
ChrisMadeaGame ChrisMadeaGame = new ChrisMadeaGame();
ChrisMadeaGame.display("Test");
}
public void display(String message) {
//Width of pane goes here
final int panewidth = 80;
//The character used for the border
final String BorderChar = "*";
//The character used for whitespace
final String WhitespaceChar = " ";
//Calculates how many lines will be necessary to print the message. Always rounds up to an integer
final int lines = (int) Math.ceil((panewidth - 2)/message.length());
//
//HACK
System.out.println(lines);
System.out.println(message.length());
System.out.println(panewidth);
System.out.println((panewidth - 2)/message.length());
//
//splits message into multiple parts
String[] MessageParts = new String[lines];
for (int i = 0; i < lines; i++){
MessageParts[i] = (message.substring(i*(panewidth-2), (i+1)*(panewidth - 2)));
//
//HACK
System.out.println(MessageParts[i]);
//
}
//Prints out the top border
for (int i = 0; i < panewidth; i++){
System.out.print(BorderChar);
}
System.out.println("");
//Prints the score line
System.out.print(BorderChar);
System.out.print("");
//Figures out how much whitespace there needs to be after printing the score info
System.out.print("Score: " + Score.get() + " Turns: " + Turns.get());
for (int i = 0; i < panewidth -17 - Score.length() - Turns.length(); i++){
System.out.print(WhitespaceChar);
}
System.out.print(BorderChar);
System.out.println("");
//prints the message
for (int i = 0; i < lines; i++){
System.out.print(BorderChar);
System.out.print(MessageParts[i]);
System.out.print(BorderChar);
System.out.println("");
}
}
}
StatHolder Class:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package chrismadeagame;
/**
*
* #author 570694
*/
public class StatHolder{
//Generic object for holding a single integer
private int stat;
//Constructor
public StatHolder(int newStat){
stat = newStat;
}
public StatHolder(){
stat = 0;
}
//Methods
public void set(int stat){};
public int get(){return stat;};
public int length(){
return String.valueOf(stat).length();
}
};
Stack Trace:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 78
at java.lang.String.substring(String.java:1907)
at chrismadeagame.ChrisMadeaGame.display(ChrisMadeaGame.java:50)
at chrismadeagame.ChrisMadeaGame.main(ChrisMadeaGame.java:25)
Java Result: 1
As you can see there is java.lang.StringIndexOutOfBoundsException: String index out of range: 78 There is no 78th position in your array.
Please check the value for the number of lines because that's what is the size of the array you are defining:
String[] MessageParts = new String[lines];
It actually depends on the length of your message:
final int lines = (int) Math.ceil((panewidth - 2)/message.length());
what kind of exception do you get? IndexOutOfBOunds?
If that is the case then the string that you pass as parameter can not be sliced in so many parts as the number "lines"
Related
I have been learning about arrays and an interesting question popped up in my head.
I was wondering that with the current Java version, is there a way for me to print a character string n and make it appear for a brief moment at every index of an array consisting of only "", and then towards the end of the array, it can stop when it reaches the end index of the array.
For example if here is the given array and string n = "2" :
[2,"","","",""]
the code will continously update like
["2","","","",""]
["","2","","",""]
["","","2","",""]
["","","","2",""]
["","","","","2"]
and the end result would be
["","","","","2"]
I would like to see the whole movement of "2" being played out without printing any excess arrays ( no more than one array should be in the output).
Is this possible? If yes, can you please suggest what should I look over to learn how to do this?
You can do this with Java but you won't be able to do it reliably within all consoles or terminals. You can however do it reliably if you utilize a GUI mechanism like a JOptionPane or JDialog and display that during console operation, for example:
The above example is a JDialog. Below is the code (read comments within):
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Rectangle2D;
import java.util.Arrays;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
public class AnimatedMoveArrayElementDemo {
/* Default. The length of the Array to animate.
Can be changed via command-line (/L:n) argument. */
private int lengthOfArray = 8;
/* Default. The Array value to move from beginning to end.
Can be changed via command-line (/N:n) argument. */
private int arrayValueToMove = 2;
/* In Milliseconds (1000 = 1 Second).
Can be changed via command-line (/S:n) argument. */
private int animationSpeed = 1000;
/* Default. The dialog display font size.
Can be changed via command-line (/F:n) argument. */
private int displayFontSize = 24;
private String[] stringArray = {};
int arrayIndex = 0;
Timer animationTimer;
JButton startButton;
JLabel arrayLabel;
public static void main(String[] args) {
// App started this way to avoid the need for statics
new AnimatedMoveArrayElementDemo().startApp(args);
}
private void startApp(String[] args) {
if (args.length > 0) {
readCommandLineArguments(args);
}
fillArray();
createAndShowDialog();
}
private void createAndShowDialog() {
JDialog dialog = new JDialog();
dialog.setTitle("Moving Array Element To The End Position");
dialog.setBackground(Color.white);
dialog.getContentPane().setBackground(Color.white);
dialog.setAlwaysOnTop(true);
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.setModal(true);
arrayLabel = new JLabel();
resetDisplayLabel();
arrayLabel.setOpaque(false);
arrayLabel.setHorizontalAlignment(JLabel.CENTER);
arrayLabel.setVerticalAlignment(JLabel.CENTER);
arrayLabel.setFont(new Font(arrayLabel.getFont().getFamily(),
arrayLabel.getFont().getStyle(), displayFontSize));
dialog.add(arrayLabel, BorderLayout.NORTH);
int calculatedWidth = getStringPixelWidth(arrayLabel.getFont(),
arrayLabel.getText().replaceAll("<.+?>", "")) + 50;
int calculatedHeight = getStringPixelHeight(arrayLabel.getFont(),
arrayLabel.getText().replaceAll("<.+?>", "")) + 100;
dialog.setPreferredSize(new Dimension(calculatedWidth, calculatedHeight));
JPanel buttonPanel = new JPanel();
buttonPanel.setOpaque(false);
startButton = new JButton("Start Animation");
startButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("Start Animation")) {
if (arrayIndex > stringArray.length - 1) {
resetDisplayLabel();
arrayIndex = 0;
}
startButton.setActionCommand("Stop Animation");
// Using a Swing Timer...for animation
ActionListener performTask = new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
arrayIndex++;
if (arrayIndex > stringArray.length - 1) {
animationTimer.stop();
startButton.setText("Restart Animation");
startButton.setActionCommand("Start Animation");
return;
}
stringArray[arrayIndex - 1] = "\"\"";
stringArray[arrayIndex] = String.valueOf(arrayValueToMove);
String arrayString = "<html>" + Arrays.toString(stringArray) + "</html>";
arrayString = arrayString.replace(String.valueOf(arrayValueToMove),
"\"<font color=red>" + String.valueOf(arrayValueToMove)
+ "</font>\"");
arrayLabel.setText(arrayString);
}
};
animationTimer = new Timer(animationSpeed, performTask);
animationTimer.start();
startButton.setText("Stop Animation");
}
else {
animationTimer.stop();
startButton.setText("Start Animation");
startButton.setActionCommand("Start Animation");
}
}
});
buttonPanel.add(startButton);
dialog.add(buttonPanel, BorderLayout.SOUTH);
dialog.pack();
dialog.setLocationRelativeTo(null);
java.awt.EventQueue.invokeLater(() -> {
dialog.setVisible(true);
});
}
private void fillArray() {
stringArray = new String[lengthOfArray];
for (int i = 0; i < stringArray.length; i++) {
if (i == 0) {
stringArray[i] = "\"" + arrayValueToMove + "\"";
}
else {
stringArray[i] = "\"\"";
}
}
}
private void resetDisplayLabel() {
fillArray();
String arrayString = "<html>" + Arrays.toString(stringArray) + "</html>";
arrayString = arrayString.replace(String.valueOf(arrayValueToMove),
"<font color=red>" + String.valueOf(arrayValueToMove)
+ "</font>");
arrayLabel.setText(arrayString);
}
/**
* This application can currently accept four specific integer command-line
* arguments prefixed with a specific Command related to that argument.
*
* #param args (Command-Line varArgs [optional])<pre>
*
* Length Of Array: The length (# of elements) of the String[] Array
* to animate. The longer the array the smaller the
* Command: /L font size you <u>may</u> want to use so to fit the array
* into the display window. The display window will
* automatically size itself to try and accommodate
* the array length. The default is 8.
*
* Examples of acceptable command-line commands for
* this argument are: /L{value}, /L:{value}, etc.
* Basically, The command can be anything as long as
* it starts with /L (or /l) and contains no spaces
* or digit(s). Digits are reserved for the actual
* argument value passed along with the command, for
* example: /L:8 (/L: 8 is not acceptable) or you
* could use: /Length=8. Anything can be between the
* /L and the integer argument value. Either will tell
* the application the the length of the Array to
* display will contain 8 elements. No whitespaces
* are permitted within a Command-Line Command.
*
* Array Value To Move: This would be the integer value that is placed
* within the first element of the String Array at
* Command: /N index 0. The default value is: <b>2</b> however
* you can change this value to whatever you like.
*
* Examples of acceptable command-line commands for
* this argument are: /N{value}, /N:{value}, etc.
* Basically, The command can be anything as long as
* it starts with /N (or /n) and contains no spaces
* or digit(s). Digits are reserved for the actual
* argument value passed along with the command, for
* example: /N:8 (/N: 8 is not acceptable) or you
* could use: /Number=8. Anything can be between the
* /N and the integer argument value. Either will tell
* the application the the number within the Array to
* display will be the number 8. No whitespaces are
* permitted within a Command-Line Command.
*
* Animation Speed: Default is a value of 1000 milliseconds which is
* basically equivalent to 1 second. You can set the
* Command: /S animation speed to whatever you like but do keep
* in mind that you could set a speed that will be so
* fast that you can't tell there is any animation.
*
* The value passed with this command would be an
* integer value representing Milliseconds.
*
* Examples of acceptable command-line commands for
* this argument are: /S{value}, /S:{value}, etc.
* Basically, The command can be anything as long as
* it starts with /S (or /s) and contains no spaces
* or digit(s). Digits are reserved for the actual
* argument value passed along with the command, for
* example: /S:800 (/S: 800 is not acceptable) or you
* could use: /Speed=800. Anything can be between the
* /S and the integer argument value. Either will tell
* the application that the animation speed for the
* Array display will be 800ms. No whitespaces are
* permitted within a Command-Line Command.
*
* Display Font Size: Default is a font size of 24 but any font size can
* be used to display the Animation and the display
* Command: /F window will automatically size accordingly.
*
* Examples of acceptable command-line commands for
* this argument are: /F{value}, /F:{value}, etc.
* Basically, The command can be anything as long as
* it starts with /F (or /f) and contains no spaces
* or digit(s). Digits are reserved for the actual
* argument value passed along with the command, for
* example: /F:36 (/F: 36 is not acceptable) or you
* could use: /Font=36. Anything can be between the
* /F and the integer argument value. Either will tell
* the application that the animation Font size for the
* Array display will be 36pt. No whitespaces are allowed
* within a Command-Line Command.</pre>
*/
private void readCommandLineArguments(String[] args) {
String command = "";
int value;
for (String arg : args) {
// Split Alpha and Numeric.
String[] argParts = arg.split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)");
command = argParts[0].substring(0, 2);
value = 0;
if (argParts.length == 2) {
value = Integer.parseInt(argParts[1]);
}
switch (command.toUpperCase()) {
case "/L":
this.lengthOfArray = value;
break;
case "/N":
this.arrayValueToMove = value;
break;
case "/S":
this.animationSpeed = value;
break;
case "/F":
this.displayFontSize = value;
break;
default:
System.err.println("Unknown Command-Line Argument!");
}
}
}
/**
* Returns the pixel width of the supplied String.<br>
*
* #param font (Font) The String Font to base calculations from.<br>
*
* #param characterString (String) The string to get the pixel width for.<br>
*
* #return (int) The pixel width of the supplied String.
*/
public int getStringPixelWidth(Font font, String characterString) {
FontMetrics metrics = new FontMetrics(font) {
private static final long serialVersionUID = 1L;
};
Rectangle2D bounds = metrics.getStringBounds(characterString, null);
return (int) bounds.getWidth();
}
/**
* Returns the pixel height of the supplied String.<br>
*
* #param font (Font) The String Font to base calculations from.<br>
*
* #param characterString (String) The string to get the pixel height for.<br>
*
* #return (int) The pixel height of the supplied String.
*/
public int getStringPixelHeight(Font font, String characterString) {
FontMetrics metrics = new FontMetrics(font) {
private static final long serialVersionUID = 1L;
};
Rectangle2D bounds = metrics.getStringBounds(characterString, null);
return (int) bounds.getHeight();
}
}
import java.io.*;
import java.util.Arrays;
public class MyClass {
public static void main(String args[]) {
String n = "2";
String array[] = new String[10];
Arrays.fill(array, "");
array[0] = n;
int i = 0;
System.out.println(Arrays.toString(array));
while(i < array.length-1){
// swap
String temp = array[i+1];
array[i+1] = array[i];
array[i] = temp;
System.out.println(Arrays.toString(array));
i++;
}
}
}
You could try something like the following:
public static void main(String[] args) throws InterruptedException {
annimate("2");
}
private static void annimate(String uniqueElement) throws InterruptedException {
String[] array = new String[]{"2", "", "", "", ""};
int uniqueElemIndex = 0;
while (uniqueElemIndex < array.length) {
System.out.println(Arrays.toString(array));
for (int i = 0; i < array.length; i++) {
if (array[i].equals(uniqueElement)) {
uniqueElemIndex = i;
break;
}
}
if (uniqueElemIndex + 1 < array.length) {
String elem = array[uniqueElemIndex];
array[uniqueElemIndex + 1] = elem;
array[uniqueElemIndex] = "";
}
uniqueElemIndex++;
Thread.sleep(500);
}
}
This outputs the following:
[2, , , , ]
[, 2, , , ]
[, , 2, , ]
[, , , 2, ]
[, , , , 2]
Im stuck on a homework assignment and I was hoping someone could point me in the right direction. I created an array of usernames and passwords but my instructions are
"Traverse the data using a traditional “For” loop, and print the information to the screen.
Search for Steve Rogers and print his information again at the end of the list."
I am able to have the code print the list to the screen but I dont know how to make it print one value at the end. Can someone guide me to how I would accomplish this? Code listed below:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package javaapplication1;
/**
*
* #author Administrator
*/
public class JavaApplication1 {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
String names[] = {"Admin","Vale.Vicky","Lane.Lois","Kent.Clark","Wayne.Bruce","Parker.Peter","Rogers.Steve","Luther.Lex","Osborn.Harry","Prince.Diana","Linda.Zoel"};
String password[] = {"Password1","ZZZZZZZZ","VVVVVVVV","AAAAAAAA","FFFFFFFF","RRRRRRRR","QQQQQQQQ","GGGGGGGG","YYYYYYYY","LLLLLLLL","PPPPPPPP"};
for (int i = 0; i < names.length; i++)
System.out.println(names[i]+ " "+password[i]);
}
}
When you are looping through the arrays, look for Rogers.Steve and when you find it store the index.
int index = -1;
for (int i = 0; i < names.length; i++) {
System.out.println(names[i] + " " + password[i]);
if (names[i].equals ("Rogers.Steve")) index = i;
}
// now print it
if (index != -1)
System.out.println(names[index] + " " + password[index]);
else
System.out.println ("Not found");
I am having some trouble understanding how to properly add to an array. What I am trying to accomplish is adding the results from the a method into an array and then run through the array.
Here is an example of what I need, or assume I need:
array{"websiteaddress","websiteaddress","websiteaddress","websiteaddress","websiteaddress"}
but instead I'm getting:
websiteaddress
websiteaddress
websiteaddress
websiteaddress
websiteaddress
websiteaddress
Here is the code I am working with:
private static final String webSiteURL = "https://websitename.com/";
//The path of the folder that you want to save the images to
private static final String folderPath = "C://path/";
private static final ArrayList<String> webPages = new ArrayList<>();
public static String[] thisIsAStringArray = {"https://websitename.com/"};
public static String[] tempArray = new String[ thisIsAStringArray.length + 1 ];
/**
*
* Method description:
* Date: Mar 17, 2018
* #param args
* #return void
*/
public static void main(String[] args) {
String path = folderPath + getPageTitle(webSiteURL).replaceAll(" ", "-");
pageLinks(webSiteURL);
System.out.println(thisIsAStringArray);
for(String web : thisIsAStringArray)
{
for(int n = 0; n < thisIsAStringArray.length - 1; n++)
{
System.out.println(thisIsAStringArray[n]);
getPageTitle(web);
pageLinks(web);
creatDirectory(folderPath, getPageTitle(web));
getsImagesAndSaves(path, web);
n++;
}
}
}
/**
*
* Method description: Get all the links on the page and put them into an array
* Date: Mar 16, 2018
* #param src
* #return void
*/
public static void pageLinks(String src)
{
try
{
URL url = new URL(src);
Document doc = Jsoup.parse(url, 3*1000);
Elements links = doc.select("a[href]"); // a with href
for (Element link : links)
{
System.out.println(link.attr("abs:href"));
String noHref = link.attr("abs:href");
for(int i = 0; i < thisIsAStringArray.length; i++)
{
tempArray[i] = thisIsAStringArray[i];
}
//thisIsAStringArray[i] = noHref;
tempArray[thisIsAStringArray.length] = noHref;
}
thisIsAStringArray = tempArray;
}
catch(Exception error)
{
System.out.println(error + " Something went wrong getting the links!");
}
}
}
Any help would be greatly appreciated and thank you in advance!
You have 2 arrays: thisIsAStringArray with size 1 and tempArray with size 2. Their size is fixed and cannot be changed! Now you have a loop:
for (Element link : links)
{
...
for(int i = 0; i < thisIsAStringArray.length; i++)
{
tempArray[i] = thisIsAStringArray[i];
}
}
which reads - for each link you've found, i loops from zero to one (which means that inside the inner loop i will have only the value 0) and than adds the link to the first place (with index 0).
You cannot change the size of an array in runtime. If you cannot tell ahead how many items you will have, you must use a List. Try something like this:
ArrayList<String> myList = new ArrayList<>();
for (Element link : links)
myList.add(link);
I am studying Java and I have an assignment to do. Here are the requirements.
There are two classes
Runner
MarathonAdmin
We have to create a runners list which holds the instances of Runner class
and have to assign values to instances name, age and agegroup taken from another txt file.
In another part there is requirement that create random numbers between 90 to 180 inclusive and iterate over each runner and assign random number value to runner's time instance.
I am stuck in last part. I am not getting how to iterate over each runner in runners list. I am including code I have done so far.
I need help with runMarathon() method whose requirement states
Write a public method for the MarathonAdmin class called runMarathon() that takes no arguments and returns no value. The method should iterate over runners, and for each runner generate a random number between 90 and 180 (inclusive) which should be used to set the time (in minutes) for that runner.
import java.util.*;
import java.io.*;
import ou.*;
import java.util.Random;
/**
* Write a description of class MarathonAdmin here.
*
* #author (your name)
* #version (a version number or a date)
*/
public class MarathonAdmin
{
// instance variables - replace the example below with your own
private List<Runner> runners;
private String ageGroup;
private String age;
private Random randomNumber;
private String result;
String ageRunner;
String ageGrouprunners;
Scanner lineScanner;
int ans;
Runner runnerobj = new Runner();
/**
* Constructor for objects of class MarathonAdmin
*/
public MarathonAdmin()
{
// initialise instance variables
runners = new ArrayList<>();
}
/**
* An example of a method - replace this comment with your own
*
* #param y a sample parameter for a method
* #return the sum of x and y
*/
public void readInRunners()
{
String pathName = OUFileChooser.getFilename();
File aFile = new File(pathName);
String nameRunner;
BufferedReader bufferedFileReader = null;
try
{
bufferedFileReader = new BufferedReader(new FileReader(aFile));
String currentLine = bufferedFileReader.readLine();
while ( currentLine != null)
{
lineScanner = new Scanner(currentLine);
lineScanner.useDelimiter(",");
nameRunner = lineScanner.next();
ageRunner = lineScanner.next();
ageGrouprunners = result;
int size = runners.size();
if (Integer.parseInt(ageRunner) < 18)
{
result = "junior";
System.out.println(currentLine +" category" + " : Junior");
}
if (Integer.parseInt(ageRunner) > 55)
{
result = "senior";
System.out.println(currentLine +" category"+ " : Senior");
}
if (Integer.parseInt(ageRunner) > 18 && Integer.parseInt(ageRunner) < 55)
{
result = "standard";
System.out.println(currentLine +" category"+ " : Standard");
}
Runner runnerobj = new Runner();
runnerobj.setName(nameRunner);
runnerobj.setAgeGroup(ageGrouprunners);
System.out.println(runnerobj); //rough test
runners.add(runnerobj);
currentLine = bufferedFileReader.readLine();
}
}
catch (Exception anException)
{
System.out.println("Error: " + anException);
}
finally
{
try
{
bufferedFileReader.close();
}
catch (Exception anException)
{
System.out.println("Error: " + anException);
}
}
}
public void runMarathon()
{
int size = runners.size();
for ( int runnersIndex = 0; runnersIndex <= size; runnersIndex ++ )
{
this.randomNumber = new Random();
ans = randomNumber.nextInt(190 - 80 +1 ) + 90 ;
System.out.println(ans);
String runnerTime;
for( String nameRunner :)
{
}
}
}
}
Your call to .nextInt() is not going to give you the range you expect because the calculation is wrong. You also don't need to do a calculation - just provide the upper bound.
The way you've set up your loop with the runnersIdx, all you need to do is access the runner with the index. See the documentation for List since that's what you used (List<Runner>).
Whenever you're learning a programming language, you'll want to bookmark the documentation website and reference it frequently. The docs for java 7 are here: http://docs.oracle.com/javase/7/docs/api/
You may also find the Java Tutorials to be helpful.
Your loop in runMarathon() function. You'll want to retrieve each runner from your List and assign a time.
for ( int runnersIndex = 0; runnersIndex <= size; runnersIndex ++ ) {
this.randomNumber = new Random();
ans = randomNumber.nextInt(190 - 80 +1 ) + 90 ;
Runner runner = runners.get(runnersIndex);
runner.setTime(ans); //make sure you create the getters/setters for this value
}
I'm using some code from my university's lecturer for a new project and everything seems to be working except for that one little piece, where I want to import "data.Frame" and I just don't know what's missing so my code would function. If anyone knows the solution or could give me an alternative so I could import the needed "Frame" - would be awesome!
I'm using eclipse!
The code is:
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import data.Frame; // HERE IS THE PROBLEM!
/**
* Compares the annotations of two or more annotators and groups them together,
* before they are written to a csv file.
*/
public class ComparisonWriter
{
private String content;
private final int A1 = 1;
private final int A2 = 2;
private final int A3 = 3;
// private final int A4 = 4;
private int numberOfAnnotators = 3;
String outputFileName = "data/200Saetze/Gruppe 1/comparison_buchpreis2_alle.csv";
String inputA1 = "data/200Saetze/Gruppe 1/Daniela/buchpreis2.xml";
String inputA2 = "data/200Saetze/Gruppe 1/Inga/buchpreis2.xml";
String inputA3 = "data/200Saetze/Gruppe 1/Stefan/buchpreis2.xml";
public ComparisonWriter()
{
content = "SatzID;Annotator;Frame;SE;exact;partial;Source;Annotator;SourceString;" +
"exact;exact ohne leer;exact ohne leer (SE);partial;koreferent;SourceFlag;exact;Target;Annotator;" +
"TargetString;exact;exact ohne leer;exact ohne leer (SE);partial;koreferent;TargetFlag;;FrameFlag";
AnnotationReader annotationReaderA1 = new AnnotationReader(inputA1);
Map<String, List<Frame>> seAnnotator1 = annotationReaderA1.getAllSubjectiveExpressions();
AnnotationReader annotationReaderA2 = new AnnotationReader(inputA2);
Map<String, List<Frame>> seAnnotator2 = annotationReaderA2.getAllSubjectiveExpressions();
AnnotationReader annotationReaderA3 = new AnnotationReader(inputA3);
Map<String, List<Frame>> seAnnotator3 = annotationReaderA3.getAllSubjectiveExpressions();
Set<String> sentences = seAnnotator1.keySet();
for (String sentence : sentences)
{
//add leading zeros
content += "\n\n" + sentence + ";" + annotationReaderA1.sentenceStrings.get(sentence);
//add the annotations in a sorted order
Map<Integer, List<Frame>> allFramesInSentence = new HashMap<Integer, List<Frame>>();
allFramesInSentence.put(A1, seAnnotator1.get(sentence));
allFramesInSentence.put(A2, seAnnotator2.get(sentence));
allFramesInSentence.put(A3, seAnnotator3.get(sentence));
// allFramesInSentence.put(A4, seAnnotator4.get(sentence));
//
//get the one with the most annotations
int largest = getIndexOfLargestList(allFramesInSentence);
if(largest == 0)
continue;
for (int i = 0; i < allFramesInSentence.get(largest).size(); i++)
{
Frame frame = allFramesInSentence.get(largest).get(i);
content += "\n\n;A" + largest + ";" + frame;
frame.setConsidered(true);
findOverlappingAnnotations(allFramesInSentence, largest, frame);
}
//Check, if there are not considered annotations in one of the frame lists for that sentence.
for (int a = 1; a <= 4; a++)
{
List<Frame> frameList = allFramesInSentence.get(a);
if(a != largest && frameList != null)
{
for (Frame frame : frameList)
{
if(frame.isConsidered() == false)
{
content += "\n\n;A" + a + ";" + frame;
frame.setConsidered(true);
findOverlappingAnnotations(allFramesInSentence, a, frame);
}
}
}
}
}
writeContentToFile(content, outputFileName, false);
}
/**
* Find overlapping annotations.
* #param frames - list of frames, potentially overlapping with the given one.
* #param largest
* #param frame - frame in question.
*/
private void findOverlappingAnnotations(Map<Integer, List<Frame>> frames,
int largest, Frame frame)
{
for (int a = 1; a <= 4; a++)
{
//If j is not the current largest frame list and there are annotated frames
//in from this annotator (a)
if(a != largest && frames.get(a) != null)
{
for (Frame compareFrame : frames.get(a))
{
addOverlappingAnnotations2Conent(frame, a, compareFrame);
}
}
}
}
/**
* Add overlapping Annotations (measured by matching ids) to the content attribute.
* #param frame
* #param a - Annotator index
* #param compareFrame
*/
private void addOverlappingAnnotations2Conent(Frame frame, int a,
Frame compareFrame)
{
List<String> terminalIDs = compareFrame.getTerminalIDs();
for (String id : terminalIDs)
{
if(compareFrame.isConsidered())
break;
if(frame.getTerminalIDs().contains(id))
{
//Write it to the content
content += "\n;A" + a + ";" + compareFrame;
compareFrame.setConsidered(true);
break;
}
}
}
/**
* Get the index of the largest frame list in the map.
* #param frames - a map with all the frames for each annotator (key: annotator)
* #return The index of the largest frame list.
*/
private int getIndexOfLargestList(Map<Integer, List<Frame>> frames)
{
int size = 0;
int largest = 0;
for(int a = 0; a <= numberOfAnnotators; a++)
{
if(frames.get(a) != null)
{
if(frames.get(a).size() > size)
largest = a;
}
}
return largest;
}
You basically need Frame class in your classpath. If you have this class in some jar, then add that jar to your classpath.
You need to get a copy of the source code or class file for the Frame class and add it to your project. The source code should be in a file called Frame.java.