I have a problem with clearing the TextField using setText(" ") method.
I'm trying to check if specific value can be entered in tile and if it can't be then I just want to set it to blank space. It actually works if I put any other value there so I think its not the logic problem? It only doesn't work if I want to set it to blank space.
Tile class
That is the class where the problem takes place.
package com.company;
import javafx.application.Platform;
import javafx.scene.control.TextField;
import javafx.scene.control.TextFormatter;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import static com.company.Game.TILE_SIZE;
public class Tile extends StackPane {
private int x;
private int y;
private static int[][] tab = new int[][]
{
{0, 8, 0, 0, 0, 0, 0},
{0, 0, 0, 5, 0, 0, 0},
{0, 11, 0, 0, 0, 0, 8},
{0, 0, 10, 0, 7, 0, 0},
{0, 9, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 6, 0},
{0, 11, 0, 0, 0, 7, 0},
{0, 0, 10, 0, 0, 0, 6}
};
private Utility utility = new Utility();
private Rectangle border = new Rectangle(TILE_SIZE - 8, TILE_SIZE - 8);
public TextField text = new TextField();
public Tile(int x, int y) {
Utility utility= new Utility();
this.x = x;
this.y = y;
border.setStroke(Color.BLACK);
text.setStyle("-fx-text-inner-color: black;" +
"-fx-control-inner-background: green;"
+"-fx-display-caret: false;");
text.setTextFormatter (new TextFormatter<Integer>(c -> {
if (c.getControlNewText().matches("^\\d{1,2}")) {
return c ;
} else {
return null ;
}
}));
text.focusedProperty().addListener((arg0, oldValue, newValue) ->
{
if (!newValue) {
if (text.getText().length() > 0)
{
String cos = text.getText();
int cos2 = Integer.parseInt(cos);
if(utility.isWon(tab))
{
Platform.exit();
System.exit(0);
}
else
{
if (!utility.isMoveValid(tab, this.y, this.x, cos2))
{
text.setText(""); //it works if it's not a blank string
} else {
tab[this.y][this.x] = cos2;
}
}
}
}
});
text.setFont(Font.font(50));
getChildren().addAll(border, text);
setTranslateX(this.x*TILE_SIZE);
setTranslateY(this.y*TILE_SIZE);
}
}
The regex in the lambda for the UnaryOperator text change filter that you have defined on the text formatter for your text field is preventing the text field from being set to an empty value.
From the javadoc:
The filter itself is an UnaryOperator that accepts TextFormatter.Change object. It should return a TextFormatter.Change object that contains the actual (filtered) change. Returning null rejects the change.
You define your formatter filter to require a match of "^\\d{1,2}", which isn't going to match an empty string "", so it will disallow setting the text field to an empty string:
text.setTextFormatter (new TextFormatter<Integer>(c -> {
if (c.getControlNewText().matches("^\\d{1,2}")) {
return c ;
} else {
return null ;
}
}));
You need to fix the regular expression for the match to allow an empty string or provide some other fix which will allow an empty string value in the field. For example:
text.setTextFormatter (new TextFormatter<Integer>(c -> {
String newText = c.getControlNewText();
if ("".equals(newText) || newText.matches("^\\d{1,2}")) {
return c ;
} else {
return null ;
}
}));
Related
I'm using DatePicker control in my xamarin.forms application which shows a bottom line for date picker in android devices but idon't want that line. How can I remove that line??
I've try to remove the line by using some custom renders but it doesn't work. The renderer I've tried to apply is:
public class BorderlessDatePickerRenderer:DatePickerRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<DatePicker> e)
{
base.OnElementChanged(e);
if (e.OldElement == null)
{
Control.Background = null;
var layoutParams = new MarginLayoutParams(Control.LayoutParameters);
layoutParams.SetMargins(0, 0, 0, 0);
LayoutParameters = layoutParams;
Control.LayoutParameters = layoutParams;
Control.SetPadding(0, 0, 0, 0);
SetPadding(0, 0, 0, 0);
}
}
}
Can someone please help me with this.
Thank you.
You can set the background to empty and it should work:
Control.SetBackgroundResource(0);
Update:
[assembly: ExportRenderer(typeof(BorderlessDatePicker), typeof(BorderlessDatePickerRenderer))]
public class BorderlessDatePickerRenderer : DatePickerRenderer
{
public static void Init() { }
protected override void OnElementChanged(ElementChangedEventArgs<DatePicker> e)
{
base.OnElementChanged(e);
if (e.OldElement == null)
{
Control.Background = null;
var layoutParams = new MarginLayoutParams(Control.LayoutParameters);
layoutParams.SetMargins(0, 0, 0, 0);
LayoutParameters = layoutParams;
GradientDrawable gd = new GradientDrawable();
gd.SetStroke(0, Android.Graphics.Color.LightGray);
Control.SetBackgroundDrawable(gd);
Control.LayoutParameters = layoutParams;
Control.SetPadding(0, 0, 0, 0);
SetPadding(0, 0, 0, 0);
}
}
}
In case of queries feel free to revert
You can use a transparent gradiant into OnElementChanged
var gd = new GradientDrawable();
gd.SetStroke(0, Android.Graphics.Color.Transparent);
Control.SetBackground(gd);
I am trying to create a gridpane that is toggled/untoggled as the user clicks on specific cells. For example, when the user clicks on a cell with the content "*", I would like the content of that specific cell to be changed into a blank cell " ". Similarly, if the user clicks on a cell with a blank content " ", I would like the content of that cell to be changed into a cell with the content "*".
Basically, I am starting out with a grid that is partly input as follows:
My gridpane is initially input as follows, I am keeping track of a matrix of booleans that represents whether there should be a "*" in one cell of the matrix. If there is a "*" in cell [i, j] of the gridpane, then the value of matrix[i,j] should be true, otherwise it should be false.
boolean matrix[][] = new boolean[StateList.size()+1][RequirementList.size()+1];
for( InstanceArtifact li: ListOfLinks) {
int y=1;
for(InstanceArtifact re: RequirementList) {
int x=1;
for(InstanceArtifact state: StateList) {
if(li.getPropertyValue("linksource").equals(re) && li.getPropertyValue("linktarget").equals(state)) {
link= new Label(" * ");
//tick in cell (1,1)
grid.add(link, y, x);
matrix[x][y]= true;
}
else {
link= new Label(" ");
//tick in cell (1,1)
grid.add(link, y, x);
}
x++;
}
y++;
}
}
}
What I would like to do is toggle/untoggle the stars, this is what I am trying to do with the code below, as we are clicking on a cell containing "*", meaning that matrix[i][j]=true, I am removing the corresponding label in the grid and I am adding a new label with an empty text. I also do the same thing in the opposite situation in which the label text is blank and I need to replace it with a label containing a star.
grid.getChildren().forEach(element -> {
element.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
int matrixX= GridPane.getRowIndex(element);
int matrixY= GridPane.getColumnIndex(element);
if(element!=null && matrixX!=0 && matrixY!=0) {
System.out.println("matrixX: "+matrixX+" matrixY: "+matrixY);
System.out.println("matrixY: "+matrixY+" "+ matrix[matrixX][matrixY]);
if(matrix[matrixX][matrixY]==true && matrixX!=0 && matrixY!=0) {
System.out.println("HEY I AM HERE FIRSTTTTTTTTT");
Node newnode= new Label(" ");
GridPane.clearConstraints(element);
// grid.getChildren().remove(element);
grid.add(newnode, matrixY, matrixX);
matrix[matrixX][matrixY]=false;
/*for(int l=0; l<RequirementList.size(); l++) {
for(int p=0; p<StateList.size(); p++) {
System.out.println(l + " "+p +" "+matrix[l][p]);
}
}*/
//grid.add(mynode, matrixY+1, matrixX+1, 1, 1);
}
else if(matrix[matrixX][matrixY]==false && matrixX!=0 && matrixY!=0){
System.out.println("HEY I AM HERE SECONDDDDDDD ");
/* for(int l=0; l<RequirementList.size(); l++) {
for(int p=0; p<StateList.size(); p++) {
System.out.println(l + " "+p +" "+matrix[l][p]);
}
}*/
Node falsenode= new Label(" * ");
GridPane.clearConstraints(element);
// grid.getChildren().remove(element);
grid.add(falsenode, matrixY, matrixX);
matrix[matrixX][matrixY]=true;
}
// System.out.println("Row: " + GridPane.getRowIndex(element));
// System.out.println("Column: " + GridPane.getColumnIndex(element));
}
}
});
});
My code is not behaving as expected, I would like the cell to be toggled/untoggled whenever the user clicks on a cell, the code is executed only the first time the user clicks on a given cell, if the user clicks on the same cell multiple times (more than once), then nothing happens.
Also, the line of code in which I am trying to remove a label is not working:
grid.getChildren().remove(element);
This could be better served with ToggleButton. Comments in code.
import java.util.ArrayList;
import java.util.List;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ToggleButton;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
/**
*
* #author Sedrick
*/
public class JavaFXApplication60 extends Application {
#Override
public void start(Stage primaryStage) {
//Start create GUI
Label lblRequirement11 = new Label("Requirement1");
Label lblRequirement12 = new Label("Requirement2");
Label lblRequirement13 = new Label("Requirement3");
GridPane.setConstraints(lblRequirement11, 1, 0);
GridPane.setConstraints(lblRequirement12, 2, 0);
GridPane.setConstraints(lblRequirement13, 3, 0);
Label lblState1 = new Label("State1");
ToggleButton toggleButton11 = new ToggleButton();
toggleButton11.setMaxWidth(Double.MAX_VALUE);
ToggleButton toggleButton12 = new ToggleButton();
toggleButton12.setMaxWidth(Double.MAX_VALUE);
ToggleButton toggleButton13 = new ToggleButton();
toggleButton13.setMaxWidth(Double.MAX_VALUE);
GridPane.setConstraints(lblState1, 0, 1);
GridPane.setConstraints(toggleButton11, 1, 1);
GridPane.setConstraints(toggleButton12, 2, 1);
GridPane.setConstraints(toggleButton13, 3, 1);
Label lblState2 = new Label("State2");
ToggleButton toggleButton21 = new ToggleButton();
toggleButton21.setMaxWidth(Double.MAX_VALUE);
ToggleButton toggleButton22 = new ToggleButton();
toggleButton22.setMaxWidth(Double.MAX_VALUE);
ToggleButton toggleButton23 = new ToggleButton();
toggleButton23.setMaxWidth(Double.MAX_VALUE);
GridPane.setConstraints(lblState2, 0, 2);
GridPane.setConstraints(toggleButton21, 1, 2);
GridPane.setConstraints(toggleButton22, 2, 2);
GridPane.setConstraints(toggleButton23, 3, 2);
Label lblState3 = new Label("State3");
ToggleButton toggleButton31 = new ToggleButton();
toggleButton31.setMaxWidth(Double.MAX_VALUE);
ToggleButton toggleButton32 = new ToggleButton();
toggleButton32.setMaxWidth(Double.MAX_VALUE);
ToggleButton toggleButton33 = new ToggleButton();
toggleButton33.setMaxWidth(Double.MAX_VALUE);
GridPane.setConstraints(lblState3, 0, 3);
GridPane.setConstraints(toggleButton31, 1, 3);
GridPane.setConstraints(toggleButton32, 2, 3);
GridPane.setConstraints(toggleButton33, 3, 3);
GridPane root = new GridPane();
root.setVgap(5);
root.setHgap(5);
root.getChildren().addAll(lblRequirement11, lblRequirement12, lblRequirement13);
root.getChildren().addAll(lblState1, toggleButton11, toggleButton12, toggleButton13);
root.getChildren().addAll(lblState2, toggleButton21, toggleButton22, toggleButton23);
root.getChildren().addAll(lblState3, toggleButton31, toggleButton32, toggleButton33);
//End create GUI
//Start create ToggleButtons' event handlers.
List<ToggleButton> toggleButtonList = new ArrayList();
toggleButtonList.add(toggleButton11);
toggleButtonList.add(toggleButton12);
toggleButtonList.add(toggleButton13);
toggleButtonList.add(toggleButton21);
toggleButtonList.add(toggleButton22);
toggleButtonList.add(toggleButton23);
toggleButtonList.add(toggleButton31);
toggleButtonList.add(toggleButton32);
toggleButtonList.add(toggleButton33);
for(ToggleButton tempToggleButton : toggleButtonList)
{
tempToggleButton.setOnAction(actionEvent -> {
if(tempToggleButton.isSelected())
{
tempToggleButton.setText("*");
}
else
{
tempToggleButton.setText("");
}
});
}
////End create ToggleButtons' event handlers.
Scene scene = new Scene(root, 400, 300);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
I created a custom renderer for searchbar to change its UI. The custom renderer is as below. Issue is when I click n cancel button, it gives an object reference error. Can someone tell me what I should do?
[assembly: ExportRendererAttribute(typeof(TransparentSearchBar),typeof(TransparentSearchBarRenderer))]
namespace AmerisureMobile.iOS
{
public class TransparentSearchBarRenderer : SearchBarRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<SearchBar> e)
{
base.OnElementChanged(e);
UISearchBar bar = this.Control;
bar.BarTintColor = UIColor.FromRGBA(155, 155, 155, 155);
bar.SetSearchFieldBackgroundImage(null, UIControlState.Normal);
bar.AutocorrectionType = UITextAutocorrectionType.No;
bar.TintColor = UIColor.FromRGBA(0, 0, 0, 0);
bar.BackgroundColor = UIColor.FromRGBA(0, 0, 0, 0);
bar.SearchBarStyle = UISearchBarStyle.Minimal;
bar.SetBackgroundImage(new UIImage(), UIBarPosition.TopAttached, UIBarMetrics.Default);
bar.SetImageforSearchBarIcon(new UIImage(), UISearchBarIcon.Clear, UIControlState.Disabled);
UITextField txSearchField = (UITextField)Control.ValueForKey(new Foundation.NSString("searchField"));
txSearchField.BackgroundColor = UIColor.White;
txSearchField.BorderStyle = UITextBorderStyle.None;
txSearchField.Layer.BorderWidth = 1.0f;
txSearchField.Layer.CornerRadius = 2.0f;
txSearchField.Layer.BorderColor = UIColor.LightGray.CGColor;
}
}
}
Try to override the method with click event by adding delegate to searchbar.
//***
bar.Delegate = new MySearchBarDelegate();
class MySearchBarDelegate: UISearchBarDelegate
{
public override void CancelButtonClicked(UISearchBar searchBar)
{
//debug here
}
}
I'm fairly new to programming, and I've been working on a two player Pong game with JavaFX. One player uses W/S to move his "paddle" and the other player uses the Up/Down arrows for his. The problem I keep having is that only one player can move his paddle at a time. I can't figure out how to get it so they can each move their individual paddles at the same time. I had one keyboard event handler control both paddles, I thought that was the problem. I made two separate keyboard handlers, but got another set of problems tat I think is caused by the built in setFocusTraversable methods. I hope what I'm trying to do makes sense. Any ideas?
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.scene.shape.Rectangle;
public class Game{
Rectangle leftPaddle;
double leftPaddleY = 260;
Rectangle rightPaddle;
double rightPaddleY = 260;
public void createGame(Group gameDisplay){
//creates background
Rectangle background = new Rectangle(0,0,800,600);
background.getStyleClass().add("background");
//draws field lines
Canvas game = new Canvas(800, 600);
GraphicsContext gc = game.getGraphicsContext2D();
gc.setStroke(Paint.valueOf("WHITE"));
gc.setLineWidth(5);
gc.strokeLine(400, 0, 400, 600);
gc.strokeOval(300, 200, 200, 200);
gc.strokeRect(0, 150, 100, 300);
gc.strokeRect(700, 150, 100, 300);
gc.setStroke(Paint.valueOf("BLACK"));
gc.setLineWidth(8);
gc.strokeRect(0, 0, 800, 600);
//creates red paddle
leftPaddle = new Rectangle(30, leftPaddleY, 20, 70);
leftPaddle.setOnKeyPressed(paddleMovement);
leftPaddle.setFocusTraversable(true);
leftPaddle.setFill(Color.RED);
//creates blue paddle
rightPaddle = new Rectangle(750, rightPaddleY, 20, 70);
rightPaddle.setOnKeyPressed(paddleMovement);
rightPaddle.setFocusTraversable(true);
rightPaddle.setFill(Color.BLUE);
gameDisplay.getStylesheets().add(getClass().getResource("GameDisplay.css").toExternalForm());
gameDisplay.getChildren().addAll(background, game, leftPaddle, rightPaddle);
}
public EventHandler<KeyEvent> paddleMovement = new EventHandler<KeyEvent>(){
#Override
public void handle(KeyEvent event) {
//red paddle movement
if(event.getCode().equals(KeyCode.W)){
leftPaddle.setY(leftPaddleY -= 6);
if(leftPaddle.getY() < 0){
leftPaddle.setY(0);
leftPaddleY = 0;
}
}
if(event.getCode().equals(KeyCode.S)){
leftPaddle.setY(leftPaddleY += 6);
if(leftPaddle.getY() < 0){
leftPaddle.setY(0);
leftPaddleY = 0;
}
}
//blue paddle movement
if(event.getCode().equals(KeyCode.UP)){
rightPaddle.setY(rightPaddleY -= 6);
if(rightPaddle.getY() < 0){
rightPaddle.setY(0);
rightPaddleY = 0;
}
}
if(event.getCode().equals(KeyCode.DOWN)){
rightPaddle.setY(rightPaddleY += 6);
if(rightPaddle.getY() < 0){
rightPaddle.setY(0);
rightPaddleY = 0;
}
}
}
};
}
The keyPressed event will only be triggered repeatedly for the last key pressed.
To work around this, just "remember" the desired movement for each paddle and listen to the keyReleased event too. You can execute the movements using a AnimationTimer to execute the updates every frame (you could also use a Timeline instead to have more control over the frequency of the updates).
Furthermore I recommend being a bit more restrictive with the visibility of your member variables, since usually you do not want other classes to be able to directly write to the fields of your class. Also I recommend handling the events in a single Node. Only one Node can have focus at a time and handling the event in different places just results in duplicate code.
public class Game {
private Rectangle leftPaddle;
private double leftPaddleY = 260;
private Rectangle rightPaddle;
private double rightPaddleY = 260;
private double leftPaddleDY;
private double rightPaddleDY;
private AnimationTimer timer = new AnimationTimer() {
#Override
public void handle(long now) {
// update paddle positions
leftPaddleY += leftPaddleDY;
rightPaddleY += rightPaddleDY;
if (leftPaddleY < 0) {
leftPaddleY = 0;
}
if (rightPaddleY < 0) {
rightPaddleY = 0;
}
leftPaddle.setY(leftPaddleY);
rightPaddle.setY(rightPaddleY);
}
};
public void createGame(Group gameDisplay) {
//creates background
Rectangle background = new Rectangle(0, 0, 800, 600);
background.getStyleClass().add("background");
//draws field lines
Canvas game = new Canvas(800, 600);
GraphicsContext gc = game.getGraphicsContext2D();
gc.setStroke(Paint.valueOf("WHITE"));
gc.setLineWidth(5);
gc.strokeLine(400, 0, 400, 600);
gc.strokeOval(300, 200, 200, 200);
gc.strokeRect(0, 150, 100, 300);
gc.strokeRect(700, 150, 100, 300);
gc.setStroke(Paint.valueOf("BLACK"));
gc.setLineWidth(8);
gc.strokeRect(0, 0, 800, 600);
//creates red paddle
leftPaddle = new Rectangle(30, leftPaddleY, 20, 70);
leftPaddle.setFill(Color.RED);
//creates blue paddle
rightPaddle = new Rectangle(750, rightPaddleY, 20, 70);
rightPaddle.setFill(Color.BLUE);
// register event handlers to Canvas
game.setFocusTraversable(true);
game.setOnKeyPressed(keyPressed);
game.setOnKeyReleased(keyReleased);
gameDisplay.getStylesheets().add(getClass().getResource("GameDisplay.css").toExternalForm());
gameDisplay.getChildren().addAll(background, game, leftPaddle, rightPaddle);
// start updates of paddle positions
timer.start();
}
private EventHandler<KeyEvent> keyReleased = new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent event) {
// set movement to 0, if the released key was responsible for the paddle
switch (event.getCode()) {
case W:
case S:
leftPaddleDY = 0;
break;
case UP:
case DOWN:
rightPaddleDY = 0;
break;
}
}
};
private EventHandler<KeyEvent> keyPressed = new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent event) {
// start movement according to key pressed
switch (event.getCode()) {
case W:
leftPaddleDY = -6;
break;
case S:
leftPaddleDY = 6;
break;
case UP:
rightPaddleDY = -6;
break;
case DOWN:
rightPaddleDY = 6;
break;
}
}
};
}
I asked a previous question here, and got excellent feedback. I am back with one more issue in the same program. My output file is always blank, and I figured out why, but I don't know how to correct it. In getArray, I set totalEmployees to the value entered in the stage2 textField. This is supposed to be the array size declaration, but when i test the code, the array size is always set to 0, therefore giving me a blank text doc. This is because the array size is set to totalEmployees before the value is saved to totalEmployees. I am not quite sure how to go about correcting this. Here is the code that I have:
import java.io.*;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.layout.GridPane;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.geometry.HPos;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
public class companyParoll extends Application
{
private TextField tfNumOfEmployees = new TextField();
private TextField tfEmpFirstName = new TextField();
private TextField tfEmpLastName = new TextField();
private TextField tfEmpPayRate = new TextField();
private TextField tfEmpHoursWorked = new TextField();
private Button btEnterNum = new Button("Submit");
private Button btNextEmp = new Button("Add Employee");
private Button btRunReport = new Button("Run Report");
private Button btQuit = new Button("Quit");
//Declare Variables
int totalEmployees;
int index = 0;
String[] firstName = new String[totalEmployees];
String[] lastName = new String[totalEmployees];
double[] payRate = new double[totalEmployees];
double[] hoursWorked = new double[totalEmployees];
Stage stage2 = new Stage();
#Override // Override the start method in the Application class
public void start(Stage primaryStage)
{
//Create the UI
GridPane gridPane =new GridPane();
GridPane gridPane2 = new GridPane();
gridPane.setHgap(75);
gridPane.setVgap(15);
gridPane.add(new Label("Employee's First Name:"), 0, 0);
gridPane.add(tfEmpFirstName, 1, 0);
gridPane.add(new Label("Employee's Last Name:"), 0, 1);
gridPane.add(tfEmpLastName, 1, 1);
gridPane.add(new Label("Employee's Hourly Pay Rate:"), 0, 2);
gridPane.add(tfEmpPayRate, 1, 2);
gridPane.add(new Label("Hours Worked by Employee"), 0, 3);
gridPane.add(tfEmpHoursWorked, 1, 3);
gridPane.add(btNextEmp, 1, 4);
gridPane.add(btQuit, 0, 6);
gridPane.add(btRunReport, 1, 6);
//Set properties
gridPane.setAlignment(Pos.CENTER);
tfEmpFirstName.setAlignment(Pos.BOTTOM_RIGHT);
tfEmpLastName.setAlignment(Pos.BOTTOM_RIGHT);
tfEmpPayRate.setAlignment(Pos.BOTTOM_RIGHT);
tfEmpHoursWorked.setAlignment(Pos.BOTTOM_RIGHT);
GridPane.setHalignment(btQuit, HPos.LEFT);
GridPane.setHalignment(btRunReport, HPos.RIGHT);
GridPane.setHalignment(btNextEmp, HPos.RIGHT);
gridPane2.setHgap(75);
gridPane2.setVgap(15);
gridPane2.add(new Label("Enter the Number of Employees:"), 0, 0);
gridPane2.add(tfNumOfEmployees,0 ,1);
gridPane2.add(btEnterNum, 0, 2);
gridPane2.setAlignment(Pos.CENTER);
tfNumOfEmployees.setAlignment(Pos.BOTTOM_RIGHT);
GridPane.setHalignment(btEnterNum, HPos.CENTER);
btEnterNum.setOnAction(e -> getArraySize());
btRunReport.setOnAction(e -> outputReport());
btNextEmp.setOnAction(e -> addEmployeeData());
btQuit.setOnAction(e -> quitApplication());
// Create a scene and place it in the stage
Scene scene= new Scene(gridPane, 400, 250) ;
primaryStage.setTitle("Payroll Calculator"); // Set title
primaryStage.setScene(scene); // Place the scene in t he stage
primaryStage.show(); // Display the stage
//Create new window to get number of employees
Scene scene2 = new Scene(gridPane2, 200, 150);
stage2.setTitle("Number of Employees");
stage2.setScene(scene2);
stage2.show();
}
public void getArraySize()
{
totalEmployees = Integer.parseInt(tfNumOfEmployees.getText());
stage2.close();
}
public void addEmployeeData()
{
while (index < firstName.length)
{
firstName[index] = tfEmpFirstName.getText();
lastName[index] = tfEmpLastName.getText();
payRate[index] = Double.parseDouble(tfEmpPayRate.getText());
hoursWorked[index] = Integer.parseInt(tfEmpHoursWorked.getText());
index ++;
break;
}
tfEmpFirstName.clear();
tfEmpLastName.clear();
tfEmpPayRate.clear();
tfEmpHoursWorked.clear();
}
public void outputReport()
{
try
{
PrintWriter empPayroll = new PrintWriter("Payroll.txt");
double regularHours = 0;
double overtimeHours = 0;
double regularPay = 0;
double overtimePay = 0;
double totalPay = 0;
for (index = 0; index < firstName.length; index++)
{
if (hoursWorked[index] >= 40)
regularHours = 40;
else
regularHours = hoursWorked[index];
if (hoursWorked[index] > 40)
overtimeHours = hoursWorked[index] - 40;
else
overtimeHours = 0;
regularPay = (payRate[index] * regularHours);
overtimePay = ((payRate[index] * 1.5) * overtimeHours);
totalPay = regularPay + overtimePay;
empPayroll.println("\nName: " + firstName[index] + " " + lastName[index]);
empPayroll.println("Pay Rate: " + payRate[index]);
empPayroll.println("Regular Hours Worked: " + regularHours);
empPayroll.println("Overtime Hours Worked: " + overtimeHours);
empPayroll.println("Regular Pay: " + regularPay);
empPayroll.println("Overtime Pay: " + overtimePay);
empPayroll.println("Total Gross Pay: " + totalPay);
}
empPayroll.close();
}
catch (IOException exp)
{
exp.printStackTrace();
}
System.out.println(firstName.length);
}
public void quitApplication()
{
Platform.exit(); //Close application
}
public static void main(String[] args)
{
Application.launch();
}
}
It looks like you're only using "totalEmployees" to instantiate those arrays.
Assuming that those arrays are not used anytime before the user clicks btEnterNum (Which is important because trying to do so would result in a Null Pointer Exception),
you could just declare the arrays, and instantiate them in your getArraySize() method.
private String[] firstName;
private String[] lastName;
private double[] payRate;
private double[] hoursWorked;
public void getArraySize() {
totalEmployees = Integer.parseInt(tfNumOfEmployees.getText());
firstName = new String[totalEmployees];
lastName = new String[totalEmployees];
payRate = new double[totalEmployees];
hoursWorked = new double[totalEmployees];
stage2.close();
}
On the other hand, however, if you do need to use those arrays first, then you could try an ArrayList instead. HTH