I'm writing for a university project a software in java - javafx but I have some problems in implementing a vote function graphically speaking.
I have a political party icon like this:
I want in java put a X letter above this icon, to obtain something like this:
My solution could be the possibility to draw one line and other line above the Image, but I don't know how to do.
package unimi.sysvotes.elettore;
import java.io.File;
import java.io.IOException;
import javafx.fxml.FXML;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
public class VotoController {
@FXML Pane listaUnoCandidatoUninominale;
@FXML ImageView listaUnoSimboloUno;
@FXML
private void initialize() {
File fileUno = new File("C:\\Users\\Administrator\\Desktop\\progettazione\\simboli\\popoloDellaLiberta.jpg");
Image imageUno = new Image("file:///" fileUno.getAbsolutePath());
listaUnoSimboloUno.setImage(imageUno);
}
@FXML
private void listaUnoSimboloUnoAction(MouseEvent me) throws IOException {
System.out.println("Votato");
/*
How put Two line above ImageView popolo?
*/
Line lineOne = new Line(10, 10, 80, 80);
lineOne.setFill(null);
lineOne.setStroke(Color.BLACK);
lineOne.setStrokeWidth(2);
Line lineTwo = new Line(80, 10, 10, 80);
lineTwo.setFill(null);
lineTwo.setStroke(Color.BLACK);
lineTwo.setStrokeWidth(2);
}
}
CodePudding user response:
I used StackPane
.
I put a canvas and ImageView in stack and then draw line in canvas. I also change order of nodes in stackpane.
public class VotoController {
@FXML Pane listaUnoCandidatoUninominale;
@FXML StackPane listaUnoSimboloUnoStack;
@FXML ImageView listaUnoSimboloUno;
@FXML Canvas listaUnoSimboloUnoX;
@FXML
private void initialize() {
File fileUno = new File("C:\\Users\\Administrator\\Desktop\\progettazione\\simboli\\popoloDellaLiberta.jpg");
Image imageUno = new Image("file:///" fileUno.getAbsolutePath());
listaUnoSimboloUno.setImage(imageUno);
}
@FXML
private void votoCandidatoUninominalAction(MouseEvent me) throws IOException {
System.out.println("Votato");
listaUnoCandidatoUninominale.setStyle("-fx-background-image: url('file:C:/Users/Administrator/Desktop/progettazione/voto/backgroundcandidatouninominale.jpg');");
}
@FXML
private void listaUnoSimboloUnoAction(MouseEvent me) throws IOException {
System.out.println("Votato");
GraphicsContext gc = listaUnoSimboloUnoX.getGraphicsContext2D();
Line lineOne = new Line(10, 10, 40, 40);
lineOne.setFill(null);
lineOne.setStroke(Color.BLACK);
lineOne.setStrokeWidth(2);
gc.beginPath();
gc.setLineWidth(5);
gc.moveTo(0, 0);
gc.lineTo(0, 0);
gc.lineTo(50, 50);
gc.stroke();
gc.beginPath();
gc.setLineWidth(5);
gc.moveTo(50, 0);
gc.lineTo(50, 0);
gc.lineTo(0, 50);
gc.stroke();
ObservableList<Node> childs = listaUnoSimboloUnoStack.getChildren();
if (childs.size() > 1) {
//
Node topNode = childs.get(childs.size()-1);
topNode.toBack();
}
}
}
CodePudding user response:
Here is an alternate solution based upon a Pane.
A Pane is used rather than a Group so that the Pane can be styled with CSS. If that wasn't needed, then a Group could be used instead.
The layering is accomplished implicitly by the
The X is added to the pane's children on top of the image with the following code.
public SelectableImageView(Image image) {
imageView = new ImageView(image);
getChildren().add(imageView);
selectionMark = createSelectionMark();
// ... additional listener and initialization code here.
}
private Node[] createSelectionMark() {
double w = imageView.getImage().getWidth();
double h = imageView.getImage().getHeight();
Line l1 = new Line(INSET, INSET, w - INSET, h - INSET);
l1.setStrokeWidth(INSET * .75);
l1.setStrokeLineCap(StrokeLineCap.ROUND);
Line l2 = new Line(INSET, h - INSET, w - INSET, INSET);
l2.setStrokeWidth(INSET * .75);
l2.setStrokeLineCap(StrokeLineCap.ROUND);
return new Node[] { l1, l2 };
}
private void addSelection() {
getChildren().addAll(selectionMark);
}
Executable Example
import javafx.application.Application;
import javafx.beans.property.*;
import javafx.geometry.Insets;
import javafx.scene.*;
import javafx.scene.image.*;
import javafx.scene.layout.*;
import javafx.scene.shape.*;
import javafx.stage.Stage;
import java.util.*;
import java.util.stream.Collectors;
public class SelectableImagesApp extends Application {
private static final double PADDING = 20;
@Override
public void start(Stage stage) throws Exception {
TilePane imageTiles = new TilePane(PADDING, PADDING);
imageTiles.setPadding(
new Insets(PADDING)
);
imageTiles.getChildren().addAll(
createSelectableImages()
);
imageTiles.setPrefColumns(ImageNames.values().length);
stage.setScene(new Scene(imageTiles));
stage.show();
}
public enum ImageNames {
Medusa,
Dragon,
Treant,
Unicorn
}
private List<SelectableImageView> createSelectableImages() {
return Arrays.stream(ImageNames.values())
.map(m ->
new SelectableImageView(
new Image(
Objects.requireNonNull(
SelectableImagesApp.class.getResource(
m "-icon.png"
)
).toExternalForm()
)
)
).collect(Collectors.toList());
}
public static void main(String[] args) {
launch(args);
}
}
class SelectableImageView extends Pane {
private final ImageView imageView;
private final Node[] selectionMark;
private BooleanProperty selected = new SimpleBooleanProperty(false);
private final double INSET = 10;
public SelectableImageView(Image image) {
imageView = new ImageView(image);
getChildren().add(imageView);
selectionMark = createSelectionMark();
selected.addListener((observable, wasSelected, isSelected) -> {
if (isSelected) {
addSelection();
} else {
removeSelection();
}
});
this.setStyle("-fx-background-color: lightblue;");
this.setPickOnBounds(true);
this.setOnMouseClicked(e -> {
selected.set(!selected.get());
});
}
private Node[] createSelectionMark() {
double w = imageView.getImage().getWidth();
double h = imageView.getImage().getHeight();
Line l1 = new Line(INSET, INSET, w - INSET, h - INSET);
l1.setStrokeWidth(INSET * .75);
l1.setStrokeLineCap(StrokeLineCap.ROUND);
Line l2 = new Line(INSET, h - INSET, w - INSET, INSET);
l2.setStrokeWidth(INSET * .75);
l2.setStrokeLineCap(StrokeLineCap.ROUND);
return new Node[] { l1, l2 };
}
private void addSelection() {
getChildren().addAll(selectionMark);
}
private void removeSelection() {
getChildren().removeAll(selectionMark);
}
public boolean isSelected() {
return selected.get();
}
public BooleanProperty selectedProperty() {
return selected;
}
public void setSelected(boolean selected) {
this.selected.set(selected);
}
}