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]
Recently I'm trying to solve an algorithm exercise on Hangdian OJ(1001).
When I eventually write System.out.println(a+"\n") , the OJ responsed Presentation Error(means wrong format for outputing) to me.
However, it's amazingly OK after I changed the codes to System.out.println(a); System.out.println();
I just don't understand the differences bettween theses 2 sentences-In my mind their functions are absolutely quite the same.
Ask for help, please.
Here are the exercise descriptions and my codes:
package forJava.HangdianOJ.AplusBPractices.AplusB1001;
/**
**#description
**Hey,welcome to HDOJ(Hangzhou Dianzi University Online Judge).
**
**In this problem,your task is to calculate SUM(n)=1+2+3+...+n.
**
**
**Input
**The input will consist of a series of integers n,one integer per line.
**
**
**Output
**For each case,output SUM(n)in one line,followed by a blank line.
**You may assume the result will be in the range of 32-bit signed integer.
**
**
* Sample Input
* 1
* 100
*
*
* Sample Output
* 1
*
* 5050
*/
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int a = 0;
while (scanner.hasNextInt()) {
// System.out.println(sumOfSeries(scanner.nextInt())+"\n"); // ——wrong
// ——OK
System.out.println(sumOfSeries(scanner.nextInt()));
System.out.println();
}
}
private static int sumOfSeries(int n) {
int sum = 0;
for (int i = 1; i <= n; i++) {
sum+=i;
}
return sum;
}
}
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 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"
I need to create two class files for creating a multiplication table based upon what size the user specifies (<=15) and use the following for the assignment. I was on Thanksgiving Break and was not able to retrieve the instructions for creating the two classes so I wrote one program that prompts the user and now I am not sure how I can break that into two classes. One class is the Table, which specifies the table size and the other class is the Table App. Here are the instructions that I didn't have access to:
The smallest allowed table size is a 2x2 table; and the largest is a 15x15 table. The number of rows and columns will always be the same (i.e., the program won't create a 5x10 table).
It won't let me post a picture here but the table goes from 1 to 15 along the column headers which are separated by dashes. Then the row header is separated by dashes as it goes from 1 to 15
The number in each cell of the table is the product of the column heading above it, and the row label to its left. All of the numbers should be right-justified.
The table shall be generated by a class named Table. This class can consist of as many methods as you feel it appropriate to create, but must include at least the following:
(constructor)--Takes one input parameter: the size of the table. Valid values range from 2 to 15 (inclusive).
print---No input parameters and no return value. This is the method that will display the multiplication table.
printLine---Takes one input parameter: the number of dashes to print in line form. This is a helper method that you'll use from the print method. It is for creating the three horizontal lines in the table.
Without having the instructions I wrote the code to make the table a variable size and width based on the user input and did not make it inclusive to 2 to 15. I am still very new to Java and I was very proud of the code I wrote until I was able to get to the internet and see the instructions.
This is the code that I wrote and it creates the table but I can't get the dashes perfect like the picture and I did not create two class files..I just wrote it in one. Can someone please help me??
import java.util.Scanner;
public class Table {
private static Scanner s;
public static void main(String[] args)
{
s = new Scanner(System.in);
System.out.print("How big is the table: ");
int size = s.nextInt();
int formatStringLength = Integer.toString(size*size).length();
int axesFormatStringLength = Integer.toString(size).length();
String formatString = String.format("%%%ds", formatStringLength);
String axesFormatString = String.format("%%%ds",
axesFormatStringLength);
System.out.println();
System.out.println();
System.out.print("* | ");
for (int i = 1; i <= size; i++)
{
//System.out.print(i + " ");
System.out.printf(formatString + " ", i);
}
System.out.print("\n----");
//for (int i = 1; i <= size; i++)
for (int i = 1; i <= size*formatStringLength; i++)
{
System.out.print("--");
}
System.out.println();
for (int i = 1; i <= size; i++) {
System.out.printf(axesFormatString + " | ", i);
for (int j = 1; j <= size; j++) {
System.out.printf(formatString + " ", i * j);
}
System.out.println();
}
}
}
You should really follow instruction and make two classes. You need to create a class named Table then create a runnable application class to run use the Table class
Table.java
public class Table{
private int size;
// constructor
public Table(int size){
this.size = size;
}
public int getSize(){
return size;
}
public void print(){
// do some printing
printline(20);
// do some more printing
printline(20);
// do some more printing
printline(20);
// do some more printing
}
public void printLine(int dashes){
// loop to print number of dashes
}
}
TestTable.java Example run
public class TextTable{
public static void main(String[] args){
// create an instance of Table
Table table = new Table(5);
// print table
table.print();
}
}
This is a basic outline/template of what your code should look like, as per the instructions.