I am trying to build a JavaFX application in which I am unable to move the rectangle with the help of the keyboard with the help of controls buttons it works fine but with the keyevent handler it seems that it is not even calling the function.
here is my controller class code
please do give some suggestions
sorry for the inconvenient language i actually dont know how to ask questions
thankyou
package sample;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.Initializable;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.Shape;
import javafx.scene.shape.Shape3D;
import javafx.util.Duration;
import java.awt.*;
import java.net.URL;
import java.util.ResourceBundle;
import static javafx.scene.paint.Color.*;
public class Controller implements Initializable {
public Circle circle;
public Button b1;
public Button b2;
public Rectangle rectangle;
public Pane pane;
double dx = 4;
double dy = 4;
int count = 0;
#Override
public void initialize(URL url, ResourceBundle resourceBundle) {
KeyFrame k = new KeyFrame(Duration.millis(100),
e - > {
circle.setLayoutX(circle.getLayoutX() + dx);
circle.setLayoutY(circle.getLayoutY() + dy);
if (circle.getLayoutX() < 30 | circle.getLayoutX() >= 600) {
dx = -dx;
}
if (circle.getLayoutY() < 30 | circle.getLayoutY() >= 400) {
dy = -dy;
}
//condition for collision with rectangle
Shape intersect = Shape.intersect(circle, rectangle);
if (intersect.getBoundsInParent().getWidth() != -1) {
dy = -dy;
}
}
);
Timeline t = new Timeline(k);
t.setCycleCount(Timeline.INDEFINITE);
t.play();
}
public void move(KeyEvent keyEvent) {
switch (keyEvent.getCode()) {
case A:
rectangle.setX(rectangle.getX() + 10);
break;
case B:
rectangle.setX(rectangle.getX() + 10);
break;
}
}
}
Try..
public void move(KeyEvent keyEvent) {
switch (keyEvent.getCode()) {
case A:
Platform.runLater(()->rectangle.setX(rectangle.getX() + 10));
break;
case B:
Platform.runLater(()->rectangle.setX(rectangle.getX() + 10));
break;
}
}
Related
MY TASK : Write a JavaFX GUI application that allows the user to pick a set of pizza toppings using a set of check boxes. Assuming each topping cost 50 cents, and a plain pizza costs $10, display the cost of the pizza. Note that, once a topping is checked or unchecked, the cost of pizza should update automatically.
FIX REQUEST : my pizza cost calculator fails to add cost for topping properly
For example, Extracheese checked and unchecked resulted in below base price $10 (ie; $7)
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.scene.layout.HBox;
import javafx.scene.transform.Scale;
import javafx.stage.Stage;
import javafx.scene.text.Text;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.text.Font;
import javafx.scene.text.FontPosture;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
class PizzaCost extends VBox {
private CheckBox ExtraCheeseCheckBox;
private CheckBox GreenPepperCheckBox;
private Label TotalPizzaCost;
public double pizzaCost = 10.0;
public PizzaCost(){
Font font = new Font(13);
ExtraCheeseCheckBox = new CheckBox("Extra Cheese");
ExtraCheeseCheckBox.setOnAction(this::processCheckBoxAction);
GreenPepperCheckBox = new CheckBox("GreenPepper");
GreenPepperCheckBox.setOnAction(this::processCheckBoxAction);
TotalPizzaCost = new Label(pizzaCost +"");
TotalPizzaCost.setFont(font);
HBox options = new HBox(ExtraCheeseCheckBox,GreenPepperCheckBox);
getChildren().addAll(options,TotalPizzaCost);
}
public void processCheckBoxAction (ActionEvent event){
if (ExtraCheeseCheckBox.isSelected()){
pizzaCost += 0.5;
}
else {
pizzaCost -= 0.5;
}
TotalPizzaCost.setText(pizzaCost+"");
}
}
The following code works for me. The pizza cost never goes below $10.
import java.text.NumberFormat;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;
public class PizzaCost extends Application {
private static final double TOPPING_COST = 0.5d;
private static final NumberFormat COST_FORMAT = NumberFormat.getCurrencyInstance();
private static final String PIZZA_COST = "Pizza Cost: ";
private double pizzaCost = 10.0d;
private Label totalPizzaCostLabel;
#Override
public void start(Stage primaryStage) throws Exception {
CheckBox extraCheesCheckBox = getCheckBox("Extra Cheese");
CheckBox greenPepperCheckBox = getCheckBox("Green Pepper");
HBox hBox = new HBox(20.0d, extraCheesCheckBox, greenPepperCheckBox);
totalPizzaCostLabel = new Label(PIZZA_COST + COST_FORMAT.format(pizzaCost));
totalPizzaCostLabel.setFont(new Font(13.0d));
VBox root = new VBox(20.0d, hBox, totalPizzaCostLabel);
root.setAlignment(Pos.CENTER);
root.setPadding(new Insets(40.0d));
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.setTitle("Pizza Cost");
primaryStage.show();
}
private CheckBox getCheckBox(String text) {
CheckBox cb = new CheckBox(text);
cb.setOnAction(this::processCheckBoxAction);
return cb;
}
private void processCheckBoxAction(ActionEvent event) {
CheckBox cb = (CheckBox) event.getSource();
if (cb.isSelected()) {
pizzaCost += TOPPING_COST;
}
else {
pizzaCost -= TOPPING_COST;
}
totalPizzaCostLabel.setText(PIZZA_COST + COST_FORMAT.format(pizzaCost));
}
public static void main(String[] args) {
launch(args);
}
}
I'm currently following a tutorial on YouTube to make a photo slide show in JavaFX. Here is my controller code:
import java.net.URL;
import java.time.Duration;
import java.util.ArrayList;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import java.util.ResourceBundle;
public class Controller implements Initializable {
#FXML ImageView imageView;
int count;
public void slideshow()
{
ArrayList<Image> images= new ArrayList<Image>();
images.add(new Image("b1.jpg"));
images.add(new Image("b2.jpg"));
images.add(new Image("b3.jpg"));
Timeline timeline=new Timeline(new KeyFrame(Duration.ofSeconds(5), event->{
imageView.setImage(images.get(count));
count++;
if (count==3)
count=0;
}));
timeline.setCycleCount(Timeline.INDEFINITE);
timeline.play();
}
#Override
public void initialize(URL location,ResourceBundle recourses)
{
slideshow();
}
}
I have an error on this line:
Timeline timeline=new Timeline(new KeyFrame(Duration.ofSeconds(5), event->{
I want the application to display the next image after every 5 seconds.
I´m trying to implement a very basic, simple and quiet typical dialog showing a list of checkboxes and a button for selecting all these checkboxes of the list.
The actual selection is working as expected. I also change the background color of the actual box showing the check symbol. But this color is only applied to the checkboxes visible without scrolling the list. When scrolling down the list you can see that all checkboxes are selected but the color is not set.
I´m using JDK10.
How can I force applying the color?
EDIT:
When first scrolling down and then clicking "select all" all colors of the previous checkboxes are also set correctly. But still not the following ones.
EDIT:
The same effect occurs when filtering the boxes using instanceof and change the colors by Region#setBackground(...).
package javafxcssbroken;
import java.util.StringJoiner;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ListView;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class JavaFXCssBroken extends Application {
#Override
public void start(Stage primaryStage) {
ListView<CheckBox> listView = new ListView();
for (int i = 0; i < 100; i++) {
listView.getItems().add(new CheckBox("Element " + i));
}
Button markAll = new Button("Select all");
markAll.setOnAction(aevt -> {
Color newColor = Color.BLUE;
listView.getItems().stream()
.forEach(checkbox -> {
checkbox.setSelected(true);
checkbox.getChildrenUnmodifiable().stream()
.forEach(child -> child.setStyle(new StringJoiner(", ", "-fx-background-color: rgba(", ")")
.add(Double.toString(255 * newColor.getRed()))
.add(Double.toString(255 * newColor.getGreen()))
.add(Double.toString(255 * newColor.getBlue()))
.add(Double.toString(newColor.getOpacity()))
.toString()));
});
});
VBox vbox = new VBox(listView, markAll);
StackPane root = new StackPane();
root.getChildren().add(vbox);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("JavaFXCssBroken");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
EDIT:
So a solution should be to introduce a class representing the data itself and also its associations discussed in the comments.
JavaFXCssBroken.java
package javafxcssbroken;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javax.swing.text.StyleConstants;
/**
* #param <I> The type of the items to display.
* #param <G> The type of the groups to associate items with.
*/
public class JavaFXCssBroken<I, G> extends Application {
private ListView<AssociatedItem<I, G>> listView;
private Set<I> items;
private Map<G, Color> groups;
private Optional<G> currentGroup;
public JavaFXCssBroken(Set<I> items, Map<G, Color> groups, Optional<G> initialGroup){
this.items = items;
this.groups = groups;
this.currentGroup = initialGroup;
}
#Override
public void start(Stage primaryStage) {
listView = new ListView();
listView.setCellFactory(lv -> {
ListCell<AssociatedItem<I, G>> cell = new ListCell<>();
cell.itemProperty().addListener((obs, oldVal, newVal) -> {
if(!cell.isEmpty() && newVal != null && newVal.getGroup().isPresent()){
cell.setBackground(new Background(
new BackgroundFill(groups.get(newVal.getGroup().get()), CornerRadii.EMPTY, Insets.EMPTY)));
}
});
cell.emptyProperty().addListener((obs, oldVal, newVal) -> {
if(newVal){
cell.setBackground(Background.EMPTY);
}
});
return cell;
});
items.stream().forEach(item -> listView.getItems().add(new AssociatedItem(item)));
Button markAll = new Button("Select all");
markAll.setOnAction(aevt -> {
listView.getItems().stream()
.forEach(item -> item.setGroup(currentGroup));
});
VBox vbox = new VBox(listView, markAll);
StackPane root = new StackPane();
root.getChildren().add(vbox);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("JavaFXCssBroken");
primaryStage.setScene(scene);
primaryStage.show();
}
}
AssociatedItem.java
package javafxcssbroken;
import java.util.Optional;
public class AssociatedItem<I, G> {
private I item;
private Optional<G> group;
public AssociatedItem(I item) {
this.item = item;
group = Optional.empty();
}
public I getItem() {
return item;
}
public void setItem(I item) {
this.item = item;
}
public Optional<G> getGroup() {
return group;
}
public void setGroup(Optional<G> group) {
this.group = group;
}
#Override
public String toString() {
return item.toString();
}
}
Main.java
package javafxcssbroken;
import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import javafx.application.Application;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class Main extends Application{
#Override
public void start(Stage primaryStage) {
Map<Integer, Color> groups = Map.of(0, Color.RED, 1, Color.BLUE);
Set<String> items = new HashSet<>();
for (int i = 0; i < 100; i++) {
items.add("Elements " + i);
}
new JavaFXCssBroken(items, groups, Optional.of(0)).start(primaryStage);
}
public static void main(String[] args) {
launch(args);
}
}
At this point colors are set to all elements but the update of the colors is only applied when starting to scroll. Is it enough to introduce AssociatedItems as Observable?
Kleopatra is right. But assuming it is a simple example or training (even if you should take the good practice as soon as possible i.e even during the training), just use the css strength, create a stylesheet with this content :
StyleCheckbox.css
.check-box:selected > .box {
-fx-background-color:blue;
}
And modify your exisiting code by commenting the useless mechanic, and by adding the stylesheet you just create. :
markAll.setOnAction(aevt -> {
// Color newColor = Color.BLUE;
listView.getItems().stream().forEach(checkbox -> {
checkbox.setSelected(true);
// checkbox.getChildrenUnmodifiable().stream()
// .forEach(child -> child.setStyle(new StringJoiner(", ", "-fx-background-color:
// rgba(", ")")
// .add(Double.toString(255 * newColor.getRed()))
// .add(Double.toString(255 * newColor.getGreen()))
// .add(Double.toString(255 *
// newColor.getBlue())).add(Double.toString(newColor.getOpacity()))
// .toString()));
});
});
VBox vbox = new VBox(listView, markAll);
vbox.getStylesheets().add(this.getClass().getResource("StyleCheckbox.css").toExternalForm());
As kleopatra suggested overriding updateItem(...) and using an extractor works.
Main.java remains the same as in the last edit of the question.
AssociatedItem.java
package javafxcssbroken;
import java.util.Optional;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
public class AssociatedItem<I, G> {
private final ObjectProperty<I> item = new SimpleObjectProperty<>();
private final ObjectProperty<Optional<G>> group = new SimpleObjectProperty<>();
public AssociatedItem(I item) {
this.item.set(item);
group.set(Optional.empty());
}
public ObjectProperty<I> itemProperty() {
return item;
}
public I getItem() {
return itemProperty().get();
}
public void setItem(I item) {
this.item.set(item);
}
public ObjectProperty<Optional<G>> groupProperty() {
return group;
}
public Optional<G> getGroup() {
return groupProperty().get();
}
public void setGroup(Optional<G> group) {
this.group.set(group);
}
}
JavaFXCssBroken.java
package javafxcssbroken;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import javafx.application.Application;
import javafx.beans.Observable;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ObservableObjectValue;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
/**
* #param <I> The type of the items to display.
* #param <G> The type of the groups to associate items with.
*/
public class JavaFXCssBroken<I, G> extends Application {
private ListView<AssociatedItem<I, G>> listView;
private Set<I> items;
private ObservableValue<ObservableList<AssociatedItem<I, G>>> associatedItems
= new SimpleObjectProperty<>(
FXCollections.observableArrayList(i -> new Observable[]{i.itemProperty(), i.groupProperty()}));
private Map<G, Color> groups;
private Optional<G> currentGroup;
public JavaFXCssBroken(Set<I> items, Map<G, Color> groups, Optional<G> initialGroup) {
this.items = items;
this.groups = groups;
this.currentGroup = initialGroup;
}
#Override
public void start(Stage primaryStage) {
listView = new ListView();
listView.setCellFactory(lv -> new ListCell<AssociatedItem<I, G>>() {
#Override
protected void updateItem(AssociatedItem<I, G> item, boolean empty) {
super.updateItem(item, empty);
if (item == null || empty) {
setBackground(Background.EMPTY);
} else {
item.getGroup().ifPresent(group -> {
setBackground(new Background(
new BackgroundFill(groups.get(group), CornerRadii.EMPTY, Insets.EMPTY)));
});
setText(item.getItem().toString());
}
}
});
listView.itemsProperty().bind(associatedItems);
items.stream().forEach(item -> {
associatedItems.getValue().add(new AssociatedItem<>(item));
});
Button markAll = new Button("Select all");
markAll.setOnAction(aevt -> {
listView.getItems().stream()
.forEach(item -> item.setGroup(currentGroup));
});
VBox vbox = new VBox(listView, markAll);
StackPane root = new StackPane();
root.getChildren().add(vbox);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("JavaFXCssBroken");
primaryStage.setScene(scene);
primaryStage.show();
}
}
I hope you can help me. I'm trying to round a image retrieved from my database. In the next image you can see the image is correctly displayed in a imageview. User selects a new item in the table and the image change to display the correct image, this is working, no problems here.
This is the program
I try with this code in the gestionarEventos :
imgfotovisi.imageProperty().bind(imageRetrievalService.valueProperty());
Image im = imgfotovisi.getImage();
circulo.setFill(new ImagePattern(im));
But java say :
... 58 more
Caused by: java.lang.NullPointerException: Image must be non-null.
at javafx.scene.paint.ImagePattern.<init>(ImagePattern.java:235)
The program runs if I delete the lines below the
imgfotovisi.imageProperty().bind(imageRetrievalService.valueProperty());
line.
When it runs, I don't know why says the image is null, when I can see clearly there.
This is ver_visitantes class:
import java.net.URL;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.ResourceBundle;
import java.util.function.Predicate;
import javafx.beans.property.ReadOnlyStringWrapper;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;
import javafx.collections.transformation.SortedList;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.InputEvent;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.paint.ImagePattern;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
public class ver_visitantes implements Initializable {
#FXML private TableView<visitantes> tbvisitantes;
#FXML private TableColumn<visitantes, String> clcedula,clnombres,clapellidos,clapartamento,clcelular,clobservaciones;
#FXML private ImageView imgfotovisiact,imgfotoact,imgfotovisi,imgfoto;
#FXML private TextField txtcedula,txtnombres,txtapto,txtapellidos,txtapt,txtcelular,txtobservaciones;
#FXML private Label lblinfovisiact,lblusuario,lblstatusvisi;
#FXML private Circle circulo;
private ObservableList<visitantes> visitorlist;
#Override
public void initialize(URL arg0, ResourceBundle arg1) {
ConexionSQL cnt = new ConexionSQL();
cnt.conexion();
visitorlist = FXCollections.observableArrayList();
visitantes.llenarlistavisitas(cnt.conexion(), visitorlist);
tbvisitantes.setItems(visitorlist);// llenar table view con la lista
clcedula.setCellValueFactory(cellData -> new ReadOnlyStringWrapper(cellData.getValue().getcedula()));
clnombres.setCellValueFactory(cellData -> new ReadOnlyStringWrapper(cellData.getValue().getnombres()));
clapellidos.setCellValueFactory(cellData -> new ReadOnlyStringWrapper(cellData.getValue().getapellidos()));
clapartamento.setCellValueFactory(cellData -> new ReadOnlyStringWrapper(cellData.getValue().getapartamento()));
clcelular.setCellValueFactory(cellData -> new ReadOnlyStringWrapper(cellData.getValue().getcelular()));
clobservaciones.setCellValueFactory(cellData -> new ReadOnlyStringWrapper(cellData.getValue().getobservaciones()));
gestionarEventos();
tbvisitantes.getSelectionModel().selectFirst();
}
public void gestionarEventos() {
tbvisitantes.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<visitantes>() {
#Override
public void changed(ObservableValue<? extends visitantes> arg0, visitantes valorAnterior,
visitantes valorSeleccionado) {
imgfoto.setVisible(false);
btnmodificar.setDisable(false);
btncancelar.setDisable(false);
btneliminar.setDisable(false);
imageRetrievalService.restart();
if (valorSeleccionado != null) {
txtcedula.setText(String.valueOf(valorSeleccionado.getcedula()));
txtnombres.setText(valorSeleccionado.getnombres());
txtapellidos.setText(valorSeleccionado.getapellidos());
txtapto.setText(String.valueOf(valorSeleccionado.getapartamento()));
txtcelular.setText(String.valueOf(valorSeleccionado.getcelular()));
txtobservaciones.setText(String.valueOf(valorSeleccionado.getobservaciones()));
}
}
});
imgfotovisi.imageProperty().bind(imageRetrievalService.valueProperty());
}
private final Service<Image> imageRetrievalService = new Service<Image>() {// cargar imagen en visitantes
#Override
protected Task<Image> createTask() {
final String id;
final visitantes visitante = tbvisitantes.getSelectionModel().getSelectedItem();
if (visitante == null) {
id = null;
} else {
id = visitante.getcedula();
}
return new Task<Image>() {
#Override
protected Image call() throws Exception {
if (id == null) {
return null;
}
return visitante.getImageById(id);
}
};
}
};
}
this is the visitantes class,called from the imageRetrievalService to get the image:
package application;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.ObservableList;
import javafx.scene.image.Image;
public class visitantes {
private StringProperty cedula;
private StringProperty nombres;
private StringProperty apellidos;
private StringProperty apartamento;
private StringProperty celular;
private StringProperty observaciones;
public visitantes(String cedula,String nombres,String apellidos,String apartamento,String celular,String observaciones){
this.cedula = new SimpleStringProperty(cedula);
this.nombres = new SimpleStringProperty(nombres);
this.apellidos = new SimpleStringProperty(apellidos);
this.apartamento = new SimpleStringProperty(apartamento);
this.celular = new SimpleStringProperty(celular);
this.observaciones = new SimpleStringProperty(observaciones);
}
public String getnombres(){
return nombres.get();
}
public void setnombres(String nombres){
this.nombres = new SimpleStringProperty(nombres);
}
public String getcedula(){
return cedula.get();
}
public void setcedula(String cedula){
this.cedula = new SimpleStringProperty(cedula);
}
public String getapellidos(){
return apellidos.get();
}
public void setapellidos(String apellidos){
this.apellidos = new SimpleStringProperty(apellidos);
}
public String getapartamento(){
return apartamento.get();
}
public void setapartamento(String apartamento){
this.apartamento = new SimpleStringProperty(apartamento);
}
public String getcelular(){
return celular.get();
}
public void setcelular(String celular){
this.celular = new SimpleStringProperty(celular);
}
public Image getImageById(String id) throws SQLException, IOException {
try (
ConexionSQL cn = new ConexionSQL();
Connection con = cn.conexion();
PreparedStatement ps = con.prepareStatement(
"SELECT foto_visi FROM visitantes WHERE cedula_visi = ?");
) {
ps.setString(1, id);
ResultSet results = ps.executeQuery();
Image img = null ;
if (results.next()) {
Blob foto = results.getBlob("foto_visi");
InputStream is = foto.getBinaryStream();
img = new Image(is) ; // false = no background loading
is.close();
}
results.close();
return img ;
} catch (Throwable e) {
String info = e.getMessage();
System.out.println(info);
}
return null;
}
}
I think the problem is here:
imgfotovisi.imageProperty().bind(imageRetrievalService.valueProperty());
I don't know if the retrieved image is loaded in the imageivew in this line. Looks like yes, but if I do
Image im = imgfotovisi.getImage();
Java says it is null. Then I can't get the image into the circle.
Thanks in advance :)
bind isn't going to load an image itself, it will just bind so that one variable will change when the source changes (in this case the value property of the service), which isn't going to happen straight away as the service is running asynchronously. So, if you query the value straight away after issuing the bind statement, you won't get the result you are expecting, as the source hasn't yet changed.
Instead you need to take action only once the image is actually available.
For instance:
imageRetrievalService.valueProperty().addListener((obs, oldVal, newVal) ->
if (newVal != null)
circulo.setFill(new ImagePattern(newVal))
);
Or, if you don't want a direct linkage to the service, and given that the imgfotovsi image property is already bound to the service value:
imgfotovisi.imageProperty().addListener((obs, oldVal, newVal) ->
if (newVal != null)
circulo.setFill(new ImagePattern(newVal))
);
I'm making game using javafx and chick image is my main player. I display chick image using Imageview. I want this chick to constantly spnining and when I pressed UP arrow, I want it to stop spinning and move toward the direction it's facing.
I use setRotate to spin my chick. When I execute code, my chick spin just fine but when I pressed UP arrow keyboard, it moves toward a random direction. How can I fix it?
package javagame;
import java.util.ArrayList;
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.NodeOrientation;
import javafx.geometry.Point3D;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.StackPane;
import javafx.scene.transform.Rotate;
import javafx.stage.Stage;
public class JavaGame extends Application {
#Override
public void start(Stage primaryStage) {
Chick test = new Chick(1);
test.setPosition(300,200);
StackPane root = new StackPane();
root.getChildren().addAll(test);
Scene scene = new Scene(root, 900, 700);
ArrayList<String> input = new ArrayList<String>();
scene.setOnKeyPressed(
new EventHandler<KeyEvent>()
{
public void handle(KeyEvent e)
{
String code = e.getCode().toString();
if ( !input.contains(code) )
input.add( code );
}
});
scene.setOnKeyReleased(
new EventHandler<KeyEvent>()
{
public void handle(KeyEvent e)
{
String code = e.getCode().toString();
input.remove( code );
}
});
new AnimationTimer(){
public void handle(long now){
System.out.println(test.getNodeOrientation());
System.out.println("effective " +test.getEffectiveNodeOrientation());
if(input.contains("UP")){
test.move();
System.out.println(test.getAngle());
System.out.println(test.getPosition());
System.out.println("getRotate " +test.getRotate());
System.out.println("local" +test.getLocalToSceneTransform());
System.out.println("parent" +test.getLocalToParentTransform());
}
else{
test.stop();
System.out.println(test.getAngle());
System.out.println(test.getPosition());
System.out.println("local" +test.getLocalToSceneTransform());
System.out.println("parent" +test.getLocalToParentTransform());
}
}
}.start();
primaryStage.setTitle("java game");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
And here's the class that I created about player
package javagame;
import static java.lang.Math.cos;
import static java.lang.Math.sin;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.layout.Pane;
import javafx.util.Duration;
public class Chick extends Pane{
private Image [] img = {new Image("file:img/0.png"),
new Image("file:img/pcTop.png"), new Image("file:img/rcTop.png"),
new Image("file:img/ycTop.png"),new Image("file:img/gcTop.png")};
private ImageView imageView;
private double x;
private double y;
private double vx=1;
private double vy=1;
private double angle=0;
private double q;
private double toAngle = 1;
private Timeline rotateAnimation;
private Timeline translateAnimation;
public Chick(){
}
public Chick(int num){
imageView = new ImageView(img[num]);
//vx=5; vy=5;
getChildren().clear();
getChildren().addAll(imageView);
rotateAnimation = new Timeline(
new KeyFrame( Duration.millis(100), e ->{ spin();} ) );
rotateAnimation.setCycleCount(Timeline.INDEFINITE);
rotateAnimation.play();
translateAnimation = new Timeline(
new KeyFrame( Duration.millis(20), e ->{ move();} ) );
translateAnimation.setCycleCount(Timeline.INDEFINITE);
}
public void setPosition(double x, double y){
this.x = x;
this.y = y;
imageView.setTranslateX(x);
imageView.setTranslateY(y);
}
public String getPosition(){
return "( " +x+ ", " +y+ " )";
}
public double getQuardant(){
if(angle>0 && angle<90)q=1;
if(angle>90 && angle<180)q=2;
if(angle>180 && angle<270)q=3;
if(angle>270 && angle<360)q=4;
else q=0;
return q;
}
public void move(){
translateAnimation.play();
rotateAnimation.stop();
x += vx*cos(angle);
y += vy*sin(360-angle);
setPosition(x,y);
//this.relocation(x,y);
}
public void stop(){
rotateAnimation.play();
translateAnimation.stop();
}
public void spin(){
if(angle < 359)angle += toAngle;
else angle=0;
imageView.setRotate(angle);
}
public double getAngle(){
return angle;
}
public void setToAngle(double d){
toAngle = d;
}
}
Before you compute your sin and cos you have to convert the angle to radians. (Math.toRadians())