speak text as Type - animation

Javafx:How can text-to speech is done on animated text; I have applied a typewriter effect on text to make animated text, and now i want that it will speak word by word as typed. P.S. for Text-to-Speech iam using the "FreeTTS is a speech synthesis engine"
here is code snippet of my project
public void AnimattedTextToSpeech()
{
// Text to Speech
Voice voice;
VoiceManager vm=VoiceManager.getInstance();
voice=vm.getVoice("kevin16");
voice.allocate();
// TypeWritter Effect to the text
String str="Welcome! This is the Lesson number one";
final IntegerProperty i = new SimpleIntegerProperty(0);
Timeline timeline = new Timeline();
KeyFrame keyFrame = new KeyFrame(Duration.seconds(0.1), event2 -> {
if (i.get() > str.length()) {
timeline.stop();
} else {
textArea.setText(str.substring(0, i.get()));
i.set(i.get() + 1);
textArea.requestFocus();
textArea.end();
}
});
voice.speak(str);
timeline.getKeyFrames().add(keyFrame);
timeline.setCycleCount(Animation.INDEFINITE);
timeline.play();
}
But it is speaking every character as it is typing. But i want it speak word by word.

This works but it seems like you need to run the speech on a different thread.
import com.sun.speech.freetts.Voice;
import com.sun.speech.freetts.VoiceManager;
import java.util.concurrent.atomic.AtomicInteger;
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.Duration;
/**
*
* #author blj0011
*/
public class FreeTTTS extends Application
{
#Override
public void start(Stage primaryStage)
{
TextArea textArea = new TextArea();
// Text to Speech
Voice voice;
VoiceManager vm = VoiceManager.getInstance();
voice = vm.getVoice("kevin16");
voice.allocate();
// TypeWritter Effect to the text
String str = "Welcome! This is the Lesson number one";
final IntegerProperty i = new SimpleIntegerProperty(0);
Timeline timeline = new Timeline();
AtomicInteger startIndex = new AtomicInteger();
AtomicInteger endIndex = new AtomicInteger();
KeyFrame keyFrame = new KeyFrame(Duration.seconds(0.1), event2 -> {
if (i.get() >= str.length()) {
timeline.stop();
startIndex.set(endIndex.get());
endIndex.set(i.get());
String word = str.substring(startIndex.get(), endIndex.get()).trim().replaceAll("[^a-zA-Z ]", "");
System.out.println(word);
voice.speak(word);
}
else {
textArea.appendText(Character.toString(str.charAt(i.get())));
if (str.charAt(i.get()) == ' ') {
if (endIndex.get() == 0) {
endIndex.set(i.get());
String word = str.substring(startIndex.get(), endIndex.get()).trim().replaceAll("[^a-zA-Z ]", "");
System.out.println(word);
voice.speak(word);
}
else {
startIndex.set(endIndex.get());
endIndex.set(i.get());
String word = str.substring(startIndex.get(), endIndex.get()).trim().replaceAll("[^a-zA-Z ]", "");
System.out.println(word);
voice.speak(word);
}
}
i.set(i.get() + 1);
}
});
//voice.speak(str);
StackPane root = new StackPane(textArea);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
timeline.getKeyFrames().add(keyFrame);
timeline.setCycleCount(Animation.INDEFINITE);
timeline.play();
//voice.speak("Hello World");
}
/**
* #param args the command line arguments
*/
public static void main(String[] args)
{
launch(args);
}
}

I imagine you should divide text into strings, and start TTS the moment you start TypeWritter effect for each string.
Like this:
String str1 = "Welcome! This is the Lesson number one";
String[] temp = str1.split(" ");
final IntegerProperty i = new SimpleIntegerProperty(0);
Timeline timeline = new Timeline();
for (String str : temp) {
KeyFrame keyFrame = new KeyFrame(Duration.seconds(0.1), event2 -> {
if (i.get() > str.length()) {
timeline.stop();
} else {
textArea.setText(str.substring(0, i.get()));
i.set(i.get() + 1);
textArea.requestFocus();
textArea.end();
}
});
voice.speak(str);
timeline.getKeyFrames().add(keyFrame);
timeline.setCycleCount(Animation.INDEFINITE);
timeline.play();
}

Related

Why are my validations not working from input file?

Full respect for your talents, please ignore how awful my code is. I am no natural and appreciate many of you will find my coding offensive!
I am wanting to create a GUI that 1 -chooses a text file, 2- displays the text to text panel and 3- validates the code ( i have a valid and invalid text file to demonstrate the validations work).
I can get points 1 and 2 to work but none of my validations are erroring when i select an invalid text file.
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.Scanner;
import java.awt.Color;
import java.awt.Container;
import java.awt.GridLayout;
import java.awt.Image;
public class MainClass extends JFrame implements ActionListener {
#SuppressWarnings("deprecation")
public static void main(String[] args) {
// Creates new Window Frame with title and sets app to close on clicking cross
JFrame frame = new JFrame("SE2 - Graphics Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Creates JFrame as top level container in hierarchy
Container toplevelContainer = frame.getContentPane();
// Sets Grid Layout
GridLayout layout = new GridLayout(1, 0);
frame.setLayout(layout);
// Splits Panel into 2 halves and sets parameters for text panel and area
String str = "This is the area your imported text will be displayed";
JTextArea TextPanel = new JTextArea(str);
TextPanel.setBackground(Color.YELLOW);
TextPanel.setEditable(false);
TextPanel.setLineWrap(true);
TextPanel.setWrapStyleWord(true);
frame.add(TextPanel);
// calls graphicspanel class
GraphicsPanel grp = new GraphicsPanel();
toplevelContainer.add(grp);
grp.drawLine(Color.BLACK, 100, 100, 200, 100);
grp.drawLine(Color.BLACK, 200, 100, 200, 200);
grp.drawLine(Color.BLACK, 200, 200, 100, 200);
grp.drawLine(Color.BLACK, 100, 200, 100, 100);
// adds graphic panel to frame
frame.pack();
frame.setVisible(true);
// Creates new menubar within frame
JMenuBar menubar = new JMenuBar();
frame.setJMenuBar(menubar);
// Creates new menu with new jmenuitems for File (load,save,exit) with shortcuts
JMenu file = new JMenu("File");
menubar.add(file);
JMenuItem load = new JMenuItem("Load");
load.setIcon(new ImageIcon("Images/Looad.png"));
load.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_L, KeyEvent.SHIFT_MASK));
file.add(load);
// enables user to browse and choose files to load from filepath
load.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
JFileChooser chooser = new JFileChooser();
chooser.showOpenDialog(null);
File f = chooser.getSelectedFile();
String filename = f.getAbsolutePath();
try
{
// reads file and displays in text panel
FileReader reader = new FileReader(filename);
BufferedReader br = new BufferedReader(reader);
TextPanel.read(br, null);
br.close();
TextPanel.requestFocus();
File Fileobject = new File(filename);
#SuppressWarnings("resource")
Scanner fileReader = new Scanner(Fileobject);
fileReader = new Scanner(Fileobject);
while (fileReader.hasNext())
{
String line = fileReader.nextLine();
String[] splitArray = line.split(" ");
String command = splitArray[0];
if (command.contains ("MOVE"))
{
String MOVE = splitArray[0];
String x1 = splitArray[1];
String y1 = splitArray[2];
if (isNumeric(MOVE))
{
JOptionPane.showMessageDialog(null, "Command cannot be a number");
}
if(isLetter(x1))
{
JOptionPane.showMessageDialog(null, "Must be integer value");
}
if(isLetter(y1))
{
JOptionPane.showMessageDialog(null, "Must be integer value");
}
else if (command.contains("LINE"))
{
String LINE = splitArray[0];
String x2 = splitArray[1];
String y2 = splitArray[2];
if (isNumeric(LINE))
{
JOptionPane.showMessageDialog(null, "Command cannot be a number");
}
if(isLetter(x2))
{
JOptionPane.showMessageDialog(null, "Must be integer value");
}
if(isLetter(y2))
{
JOptionPane.showMessageDialog(null, "Must be integer value");
}
else if(command.contains("CIRCLE"))
{
String CIRCLE =splitArray[0];
int r = Integer.parseInt(splitArray[1]);
if(r < 0)
{
JOptionPane.showMessageDialog(null, "Must be positive number");
}
JOptionPane.showMessageDialog(null, "Must be integer value");
}
else if (command.contains("SOLID_CIRCLE"))
{
String SOLID_CIRCLE = splitArray[0];
try {
int r = Integer.parseInt(splitArray[1]);
if(r<0)
{
JOptionPane.showMessageDialog(null, "Must be positive number");
}
}
catch(NumberFormatException e) {
}
JOptionPane.showMessageDialog(null, "Must be integer value");
}
else if (command.contains("CLEAR"))
{
JOptionPane.showMessageDialog(null, "Commands have been cleared");
}
else if (command.contains("COLOUR"))
{
String Colour = splitArray[0];
int red = Integer.parseInt(splitArray[1]);
int green = Integer.parseInt(splitArray[2]);
int blue = Integer.parseInt(splitArray[3]);
if(red>255)
if(red<0)
if (green>255)
if(green<0)
if(blue>255)
if(blue<0)
{
JOptionPane.showMessageDialog(null, "Colour values must range between 0 and 255");
}
else if (command.contains("TEXT"))
{
String text = null;
if(isNumeric(text))
{
JOptionPane.showMessageDialog(null, "Text must not contain numbers");
}
if (!contains(""))
{
JOptionPane.showMessageDialog(null, "Text must contain double quotation marks");
}
}
}
}
}
}}
//confirm checks are complete for user
catch (Exception e) {
JOptionPane.showMessageDialog(null, "Error Check Complete");
}
}
private boolean contains(String string) {
// TODO Auto-generated method stub
return false;
}
private boolean isLetter(String string) {
// TODO Auto-generated method stub
return false;
}
private boolean isNumeric(String command) {
// TODO Auto-generated method stub
return false;
}
});
// adds image icon and shortcut keys to JMenuItems
JMenuItem save = new JMenuItem("Save");
save.setIcon(new ImageIcon("Images/Saveas.png"));
save.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, KeyEvent.SHIFT_MASK));
// Attempt at requirement 4 to add functionality to save JMENUITEM
// save.addActionListener(new ActionListener() {
// public void actionPerformed(ActionEvent ae) {
// JFileChooser fc = new JFileChooser();
// fc.showSaveDialog(this);
// encoder.encode(image);
// byte[] jpgData = bos.toByteArray();
// FileOutputStream fos = new FileOutputStream(fc.getSelectedFile()+".jpeg");
// fos.write(jpgData);
// fos.close();
file.add(save);
JMenuItem exit = new JMenuItem("Exit");
exit.setIcon(new ImageIcon("Images/Exiit.png"));
exit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_E, KeyEvent.SHIFT_MASK));
file.add(exit);
JMenu help = new JMenu("Help");
menubar.add(help);
JMenuItem about = new JMenuItem("About");
about.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, KeyEvent.SHIFT_MASK));
help.add(about);
// Adds Action listener to display dialog box with app description
about.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
JOptionPane.showMessageDialog(about,
"This Application allows you to import, save and display graphical content from a file containing a set of instructions.",
"About", JOptionPane.INFORMATION_MESSAGE);
}
});
frame.setVisible(true);
class exitaction implements ActionListener {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
}
exit.addActionListener(new exitaction());
}
protected static int isEmpty() {
// TODO Auto-generated method stub
return 0;
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
}

Whenever I use the Text object in JavaFX, all object overlap the text, even subsequent text objects

Update: I am using JavaFX 13
This problem happens across all my JavaFX programs, but this is one example. A user is supposed to be able to select options for a custom milkshake then get a receipt when they checkout. All of the object referencing and MVC works as it is supposed to, but when displaying the information using Text objects (javafx.scene.text.Text), they are overlapped by other objects around them. In the second and third images, I have the occurrences circled.
First launch of the program. The first image
Here is the code for the text pane in the second image:
After adding a few selections. The second Image
import Controllers.Controller;
import Entities.Milkshake;
import Interfaces.Observer;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import java.util.ArrayList;;
public class TextSummaryView extends AnchorPane implements Observer<Milkshake> {
private Milkshake model;
private Controller controller;
private VBox iceCreamOptions;
private VBox toppingOptions;
private Text totalCost;
private final double minHeight = 100.0;
private final double minWidth = 50.0;
public TextSummaryView() {
super();
iceCreamOptions = new VBox();
toppingOptions = new VBox();
totalCost = new Text("$0.00");
Button checkout = new Button("Checkout");
checkout.setOnAction(e -> controller.checkout());
Text iceCreamText = new Text("Click '-' to remove\nCurrent Ice Cream Selections:");
Text toppingText = new Text("Current Topping Selections");
iceCreamOptions.getChildren().add(iceCreamText);
toppingOptions.getChildren().add(toppingText);
this.getChildren().addAll(checkout, iceCreamOptions, toppingOptions, totalCost);
// Setting position of elements
setBottomAnchor(checkout, this.getHeight()-5.0);
setRightAnchor(checkout, this.getWidth()-5.0);
setLeftAnchor(totalCost, 5.0);
setBottomAnchor(totalCost, this.getHeight()-5.0);
setTopAnchor(iceCreamOptions, 5.0);
setLeftAnchor(iceCreamOptions, 5.0);
setTopAnchor(toppingOptions, Math.max(40.0, iceCreamOptions.getHeight() + 10.0));
setLeftAnchor(toppingOptions, 5.0);
this.setMinHeight(minHeight);
this.setMinWidth(minWidth);
}
/**
* Sets what the observer will watch
* #param obs An object that extends the Observable interface
*/
public void setTarget(Milkshake obs){
this.model = obs;
}
/**
* Removes the object from target
*/
public void removeTarget(){
this.model = null;
}
/**
* Called by observables to update the observer's data
*/
public void update(){
this.iceCreamOptions.getChildren().remove(1, this.iceCreamOptions.getChildren().size());
this.toppingOptions.getChildren().remove(1, this.toppingOptions.getChildren().size());
// Get Data
ArrayList<String> iceCreams = model.getIceCreams();
ArrayList<String> toppings = model.getToppings();
// Update the ice cream selections
int iceCreamIndex = 0;
for (String ic: iceCreams) {
AnchorPane selection = new AnchorPane();
Button removeButton = new Button("-");
Text iceCream = new Text(ic + ":");
Text cost = new Text("$1.00");
final int iceIndexFin = iceCreamIndex;
removeButton.setOnAction(e -> controller.removeIceCream(iceIndexFin));
selection.getChildren().addAll(removeButton, iceCream, cost);
setLeftAnchor(removeButton, 5.0);
setLeftAnchor(iceCream, 50.0);
setTopAnchor(iceCream, selection.getHeight()/3);
setLeftAnchor(cost, selection.getWidth()-5.0);
setTopAnchor(cost, selection.getHeight()/3);
this.iceCreamOptions.getChildren().add(selection);
iceCreamIndex ++;
}
// Update the topping selections
int toppingIndex = 0;
for (String top: toppings) {
AnchorPane selection = new AnchorPane();
Button removeButton = new Button("-");
Text topping = new Text(top + ":");
Text cost = new Text("$0.50");
final int topIndexFin = toppingIndex;
removeButton.setOnAction(e -> controller.removeTopping(topIndexFin));
selection.getChildren().addAll(removeButton, topping, cost);
setLeftAnchor(removeButton, 5.0);
setLeftAnchor(topping, 50.0);
setTopAnchor(topping, selection.getHeight()/3);
setLeftAnchor(cost, selection.getWidth()-5.0);
setTopAnchor(cost, selection.getHeight()/3);
this.toppingOptions.getChildren().add(selection);
toppingIndex ++;
}
setTopAnchor(iceCreamOptions, 5.0);
setLeftAnchor(iceCreamOptions, 5.0);
setTopAnchor(toppingOptions, Math.max(40.0, iceCreamOptions.getHeight() + 10.0));
setLeftAnchor(toppingOptions, 5.0);
this.totalCost.setText( "$" + this.model.getCost() + "0");
}
public void setController(Controller controller){
this.controller = controller;
}
}
Here is the code for the checkout screen. Pressing the checkout button. All are different text objects in a VBox. The third image
import Entities.Milkshake;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import java.util.ArrayList;
public class CheckoutView extends Stage {
VBox root = new VBox();
public CheckoutView(Milkshake ms) {
super();
// Get Data
ArrayList<String> iceCreams = ms.getIceCreams();
ArrayList<String> toppings = ms.getToppings();
// Update the ice cream selections
int iceCreamIndex = 0;
for (String ic: iceCreams) {
AnchorPane selection = new AnchorPane();
Text iceCream = new Text(ic + ":");
Text cost = new Text("$1.00");
final int iceIndexFin = iceCreamIndex;
selection.getChildren().addAll(iceCream, cost);
AnchorPane.setLeftAnchor(iceCream, 50.0);
AnchorPane.setLeftAnchor(cost, this.getWidth()-5.0);
this.root.getChildren().add(selection);
iceCreamIndex ++;
}
// Update the topping selections
int toppingIndex = 0;
for (String top: toppings) {
AnchorPane selection = new AnchorPane();
Text topping = new Text(top + ":");
Text cost = new Text("$0.50");
selection.getChildren().addAll(topping, cost);
AnchorPane.setLeftAnchor(topping, 50.0);
AnchorPane.setLeftAnchor(cost, this.getWidth()-5.0);
this.root.getChildren().add(selection);
toppingIndex ++;
}
AnchorPane total = new AnchorPane();
Text costTotal = new Text("$" +ms.getCost() + "0");
total.getChildren().add(costTotal);
AnchorPane.setLeftAnchor(total, this.getMaxWidth()-costTotal.getX());
BorderPane exitOptions = new BorderPane();
Button pay = new Button("Finish and Pay");
Button ret = new Button("Return to Order");
pay.setOnAction(e -> Platform.exit());
ret.setOnAction(e -> this.close());
exitOptions.setLeft(ret);
exitOptions.setRight(pay);
root.getChildren().add(exitOptions);
this.setTitle("Checkout");
this.setScene(new Scene(root));
}
public static void checkout(Milkshake ms) {
CheckoutView check = new CheckoutView(ms);
check.show();
}
}
Thank you in advance for all your help! :)

Can't get my String switch statement to hit anything but default

I am trying to use a switch statement to pass a LinkedHashMap to the correct class constructor for a school project(I just added the rest of the code).
The code reads takes in a txt file and based off the first word in the text sends the hash map.
I can't seem to get a hit on the case report I am testing.
I have even tried just making everything into an if-else-if structure,
and that still didn't work out,
I've tried using a private enum method to no avail.
I am at a loss here.
I am running Java 8.
I am open to any suggestion on optimizing the code as well.
Thanks.
package linkedlist;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
/**
*
* #author admin
*/
public class TextReaderGUI extends javax.swing.JFrame {
JFileChooser fileChooser = new JFileChooser();
String rawText;
String[] text;
public String listType;
private JButton fileChooserButton;
private JLabel statusLabel;
/**
* Creates new form TextReaderGUI
*/
public TextReaderGUI() {
initComponents();
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
fileChooserButton = new javax.swing.JButton();
statusLabel = new javax.swing.JLabel();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
fileChooserButton.setText("File Chooser");
fileChooserButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
fileChooserButtonActionPerformed(evt);
}
});
statusLabel.setText("Status: ");
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(layout
.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup().addGap(14, 14, 14).addComponent(fileChooserButton))
.addGroup(layout.createSequentialGroup().addGap(36, 36, 36).addComponent(statusLabel)))
.addContainerGap(264, Short.MAX_VALUE)));
layout.setVerticalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup().addGap(16, 16, 16).addComponent(fileChooserButton)
.addGap(18, 18, 18).addComponent(statusLabel).addContainerGap(221, Short.MAX_VALUE)));
pack();
}// </editor-fold>
private void fileChooserButtonActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
try {
int returnVal = fileChooser.showOpenDialog(this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File file = fileChooser.getSelectedFile();
rawText = "";
BufferedReader reader = new BufferedReader(new FileReader(file));
StringBuilder stringb = new StringBuilder();
String s;
while ((s = reader.readLine()) != null) {
stringb.append(s);
stringb.append("\n"); // this makes sure that java sees when a new line has started
}
rawText = stringb.toString();
statusLabel.setText("Status: " + file.getName());
}
} catch (IOException e) {
statusLabel.setText("Status" + e);
}
text = rawText.split("\n"); // creating a string array split at each line break
Map<String, String> lines = new LinkedHashMap<>();
for (int i = 0; i < text.length; i++) { // this sets the first word of the line = key
String[] currentLine = text[i].split("\\s+"); // splits the words in the current line to an array
if (i == 0) {
listType = currentLine[0].replaceAll("\n", "").replaceAll("\\s+", ""); // determines listType to pass
}
if (currentLine.length > 1 && i > 0) {
lines.put(currentLine[0] + " " + i, currentLine[1]); // if two words exist on a line
// the first is the key second is the value
} else if (currentLine.length == 1 && i > 0) { // keeps list type out of key values
lines.put(currentLine[0] + " " + i, ""); // " " + i is used to ensure that each command is unique key
}
}
lines.keySet().forEach((name) -> {// Testing to see if document was correctly placed into the HashMap
String key = name;
String value = lines.get(name);
System.out.println(key + " " + value + "\n");
});
System.out.println(listType); // testing to see if list type was correctly stored
switch (listType) {
case "stack":
Stack stack = new Stack((LinkedHashMap) lines);
break;
case "queue":
Queue queue = new Queue((LinkedHashMap) lines);
break;
case "dll":
Dll dll = new Dll((LinkedHashMap) lines);
break;
case "sll":
System.out.println("almost there");
Sll sll = new Sll((LinkedHashMap) lines);
break;
case "cll":
Cll cll = new Cll((LinkedHashMap) lines);
break;
default:
System.out.println("something went wrong here");
break;
}
}
}

JavaFX: When the user presses the mouse within a panel, its color should be changed randomly?

I am having trouble with my code. I had to make a chessboard for a previous problem. Now I have to use that same code to display 8X8 grids which are initially white. Once clicked on, they should, they should change color randomly. Can someone please help, here is a copy of my code.
import javafx.application.Application;
import javafx.geometry.HPos;
import javafx.geometry.VPos;
import javafx.scene.Scene;
import javafx.scene.control.Control;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.RowConstraints;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.scene.layout.Pane;
import javafx.scene.input.MouseEvent;
import javafx.scene.shape.Rectangle;
import javafx.event.EventHandler;
import javafx.scene.paint.Paint;
import javafx.scene.paint.Color;
public class ChessBoardColor extends Application {
#Override
public void start(Stage primaryStage) {
GridPane pane = new GridPane();
int size = 8 ;
for (int row = 0; row < size; row++) {
for (int color = 0; color < size; color ++) {
StackPane panel = new StackPane();
String boxcolor ;
if ((row + color) % 2 == 0) {
boxcolor = "red";
} else {
boxcolor = "black";
}
panel.setStyle("-fx-background-color:#FFFFFF;");
pane.add(panel, color, row);
pane.setOnMouseClicked(e -> {
pane.setStroke();
});
}
}
}
for (int i = 0; i < size; i++) {
pane.getColumnConstraints().add(new ColumnConstraints(5, Control.USE_COMPUTED_SIZE, Double.POSITIVE_INFINITY, Priority.ALWAYS, HPos.CENTER, true));
pane.getRowConstraints().add(new RowConstraints(5, Control.USE_COMPUTED_SIZE, Double.POSITIVE_INFINITY, Priority.ALWAYS, VPos.CENTER, true));
}
primaryStage.setScene(new Scene(pane, 500, 500));
primaryStage.show();
public static void main(String[] args) {
launch(args);
}
}
look at this code simply find the node where the user click and apply style like you know:
public class ChessBoardColor extends Application {
#Override
public void start(Stage primaryStage) {
GridPane pane = new GridPane();
int size = 8;
for (int row = 0; row < size; row++) {
for (int color = 0; color < size; color++) {
StackPane panel = new StackPane();
String boxcolor; //initial box color = "white" if you want it white initialy
if ((row + color) % 2 == 0) {//I suppose it's your chessboard color
boxcolor = "red";
} else {
boxcolor = "black";
}
panel.setStyle("-fx-background-color:" + boxcolor + ";");
pane.add(panel, color, row);
pane.setOnMouseClicked(e -> {
Node target = (Node) e.getTarget(); // you find where the user click
if (target instanceof StackPane) {
String radomColor = getRandomColor(); // choose a random color
((StackPane) target).setStyle("-fx-background-color:" + radomColor + ";"); // apply it like you already know
}
});
}
}
for (int i = 0; i < size; i++) {
pane.getColumnConstraints().add(new ColumnConstraints(5, Control.USE_COMPUTED_SIZE,
Double.POSITIVE_INFINITY, Priority.ALWAYS, HPos.CENTER, true));
pane.getRowConstraints().add(new RowConstraints(5, Control.USE_COMPUTED_SIZE, Double.POSITIVE_INFINITY,
Priority.ALWAYS, VPos.CENTER, true));
}
primaryStage.setScene(new Scene(pane, 500, 500));
primaryStage.show();
}
private String getRandomColor() { // simple random color generator
String colors[] = new String[] {"blue", "yellow", "green", "purple"};
Random ran = new Random();
int randomColourIndex = ran.nextInt(4);
return colors[randomColourIndex];
}
public static void main(String[] args) {
launch(args);
}
}

JavaFX : How to detect if a key is being held down?

I'm working with Timelines and was hoping to hook up some KeyPress events to the stage that could alter the way the timeline changes the properties over the course it runs.
I know how to differentiate between what key was pressed and for what keys I want to listen, but need to know how I can determine if a key has just been pressed once, like typing, or if a key is being held down for a longer period of time, so that I can have the program make more rapid adjustments the longer the key is held down.
When a key is being held down, you keep on getting KEY_PRESSED events. You can count how many presses of the same key you get in a row:
SimpleIntegerProperty aCount = new SimpleIntegerProperty(0);
SimpleIntegerProperty bCount = new SimpleIntegerProperty(0);
KeyCombination a = new KeyCodeCombination(KeyCode.A);
KeyCombination b = new KeyCodeCombination(KeyCode.B);
scene.setOnKeyPressed(ke -> {
aCount.set(a.match(ke) ? aCount.get() + 1 : 0);
bCount.set(b.match(ke) ? bCount.get() + 1 : 0);
});
scene.setOnKeyReleased(ke -> {
if(a.match(ke)) { aCount.set(0); }
else if(b.match(ke)) { bCount.set(0); }
});
Here is a simple test application:
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyCodeCombination;
import javafx.scene.input.KeyCombination;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class KeySpeedTest extends Application {
#Override
public void start(Stage primaryStage) {
SimpleIntegerProperty aCount = new SimpleIntegerProperty(0);
SimpleIntegerProperty bCount = new SimpleIntegerProperty(0);
KeyCombination a = new KeyCodeCombination(KeyCode.A);
KeyCombination b = new KeyCodeCombination(KeyCode.B);
Label aLabel = new Label();
Label bLabel = new Label();
aLabel.textProperty().bind(Bindings.concat(" A: ", aCount));
bLabel.textProperty().bind(Bindings.concat(" B: ", bCount));
HBox root = new HBox(aLabel, bLabel);
Scene scene = new Scene(root, 300, 250);
scene.setOnKeyPressed(ke -> {
aCount.set(a.match(ke) ? aCount.get() + 1 : 0);
bCount.set(b.match(ke) ? bCount.get() + 1 : 0);
});
scene.setOnKeyReleased(ke -> {
if(a.match(ke)) { aCount.set(0); }
else if(b.match(ke)) { bCount.set(0); }
});
primaryStage.setScene(scene);
primaryStage.setTitle("Key Speed Test");
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}

Resources