I have to rewrite existing app, with SWT.
I'm adding FXCanvas class with JavaFX components on it.
I noticed that somehow my panes (usually, HBox'es) do not change size when I maximize window, for example.
My code is:
final Display display = parent.getDisplay();
shell = new Shell(display);
Group group = new Group();
scene = new Scene(group, Color.rgb(shell.getBackground().getRed(), shell.getBackground().getGreen(),
shell.getBackground().getBlue()));
fxCanvas = new FXCanvas(shell, SWT.NONE) {
#Override
public Point computeSize(int wHint, int hHint, boolean changed) {
getScene().getWindow().sizeToScene();
int width = (int) getScene().getWidth();
int height = (int) getScene().getHeight();
return new Point(width, height);
}
};
fxCanvas.setScene(scene);
HBox hbox = new HBox();
hbox.setPadding(new Insets(15, 12, 15, 12));
hbox.setSpacing(20); // Gap between nodes
group.getChildren().add(hbox);
Please advise.
Related
I have the following code
Image img = new Image(getClass().getResource("1.png").toExternalForm(), tg.getWidth(), tg.getHeight(), false, true, true);
ImageView view = new ImageView(img);
tg.setGraphic(view);
(where tg is a toggle button)
and I get this
I want the image to fit perfectly into the button but whatever I do I'm unable to accomplish this. I've already tried using view.setFit methods but it doesn't seem to have any effect
Edit:
This is the code that creates the GridPane
this.gameBoard = new GridPane();
this.gameBoard.setPrefSize(600, 600);
this.gameCards = new ToggleButton[this.boardSize * this.boardSize];
EventHandler<ActionEvent> cardSelectedHandler = this::onCardSelected;
for (int i = 0; i < this.gameCards.length; i++) {
this.gameCards[i] = new ToggleButton;
this.gameCards[i].setPrefSize(Region.USE_COMPUTED_SIZE, Region.USE_COMPUTED_SIZE);
this.gameCards[i].setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
this.gameCards[i].setOnAction(cardSelectedHandler);
this.gameBoard.add(this.gameCards[i], i % this.boardSize, i / this.boardSize);
GridPane.setHgrow(this.gameCards[i], Priority.ALWAYS);
GridPane.setVgrow(this.gameCards[i], Priority.ALWAYS);
}
private void onCardSelected(ActionEvent event) {
ToggleButton tg = (ToggleButton) event.getTarget();
Image img = new Image(getClass().getResource("1.png").toExternalForm(), tg.getWidth(), tg.getHeight(), false, true, true);
ImageView view = new ImageView(img);
tg.setGraphic(view);
EDIT 2:
doing some change
private void onCardSelected(ActionEvent event) {
ToggleButton tg = (ToggleButton) event.getTarget();
Image img = new Image(getClass().getResource("1.png").toExternalForm());
ImageView view = new ImageView(img);
view.setFitHeight(150);
view.setFitWidth(150);
view.setPreserveRatio(false);
tg.setAlignment(Pos.TOP_LEFT);
tg.setGraphic(view);
I now get
but I still get this button resize
I want to make a border pane with two HBoxes on top and bottom and a GridPane in the center... I wrote what I needed, attached the labels but I can't run the code
Exception in Application start method
java.lang.reflect.InvocationTargetException is what I get as an error... the code is below, any help is welcome :) thanks
public class labelBorder extends Application {
#Override
public void start(Stage primaryStage) {
BorderPane bp = new BorderPane();
bp.setPrefSize(400, 400);
HBox hb1 = new HBox();
Label lb1 = new Label("");
lb1.setPrefWidth(200);
lb1.setBorder(new Border(new BorderStroke(Color.AQUAMARINE,BorderStrokeStyle.SOLID,null,new BorderWidths(5))));
Label lb2 = new Label("");
lb2.setPrefWidth(200);
lb2.setBorder(new Border(new BorderStroke(Color.BLUEVIOLET,BorderStrokeStyle.SOLID,null,new BorderWidths(5))));
HBox hb2 = new HBox();
URI foto = Paths.get("D:\\Barca.jpg").toUri();
Label lb3 = new Label();
lb3.setGraphic(new ImageView(foto.toString()));
lb3.autosize();
GridPane gp = new GridPane();
Label lb4 = new Label("");
Label lb5 = new Label("");
Label lb6 = new Label("");
Label lb7 = new Label("");
gp.add(lb4, 0, 0);
gp.add(lb5, 0, 1);
gp.add(lb6, 1, 0);
gp.add(lb7, 1, 1);
gp.getChildren().addAll(lb4,lb5,lb6,lb7);
hb1.getChildren().addAll(lb1,lb2);
hb2.getChildren().addAll(lb3);
bp.setTop(hb1);
bp.setCenter(gp);
bp.setBottom(hb2);
bp.getChildren().addAll(hb1,hb2,gp);
Scene scene = new Scene(bp);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
You should NOT add the duplicate children controls to your parent layout(pane). Your code must be throwing,
java.lang.IllegalArgumentException: Children: duplicate children added
To overcome your issue remove these lines,
gp.getChildren().addAll(lb4,lb5,lb6,lb7);
And,
bp.getChildren().addAll(hb1,hb2,gp);
As those controls have already been added to your corresponding layout.
Note: Adding children with pane.getChildren().addAll(...) on BorderPane is irrelevant and will be ignored while rendering the added controls.
Sorry, I have just begun learning javaFX and cannot figure out how to get all of my icons on buttons the same size. I tried a couple things but could not get it working, all help is appreciated. Thank you!
Wont let me post my question unless I add more details but I cant think of anything else to put so just ignore this whole paragraph as I ramble on so I can post my question and continue coding my game.
public class Main extends Application {
Stage window;
Button button;
Scene scene1, scene2;
public static final int ROCK = 0;
public static final int PAPER = 1;
public static final int SCISSORS = 2;
public static int userChoice;
public static void main(String [] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception
{
window = primaryStage;
//Layout 1
VBox layout = new VBox(20);
Label label = new Label("Rock Paper Scissors");
Button myButton = new Button("Start");
myButton.setOnAction(e -> window.setScene(scene2));
Button exit = new Button("Exit");
exit.setOnAction(e -> System.exit(0));
layout.getChildren().addAll(label, myButton, exit);
layout.setAlignment(Pos.CENTER);
scene1 = new Scene(layout, 300, 300);
//Layout 2
BorderPane border = new BorderPane();
VBox layout1 = new VBox(10);
Label label1 = new Label("Choose One");
layout1.setAlignment(Pos.CENTER);
//Layout 3
HBox layout2 = new HBox(10);
//Rock Image Button
Image rockIm = new Image(getClass().getResourceAsStream("Rock2.png"));
Button rock = new Button();
rock.setGraphic(new ImageView(rockIm));
rock.setOnAction(e -> userChoice = ROCK);
//Paper Image Button
Image paperIm = new
Image(getClass().getResourceAsStream("Paper2.png"));
Button paper = new Button();
paper.setGraphic(new ImageView(paperIm));
paper.setOnAction(e -> userChoice = PAPER);
//Scissor Image Button
Image scissorIm = new
Image(getClass().getResourceAsStream("Scissor2.png"));
Button scissors = new Button();
scissors.setGraphic(new ImageView(scissorIm));
scissors.setOnAction(e -> userChoice = SCISSORS);
Button quit = new Button("Return");
quit.setOnAction(e -> window.setScene(scene1));
layout2.getChildren().addAll(rock, paper, scissors, quit);
layout2.setAlignment(Pos.CENTER);
scene2 = new Scene(layout2, 300, 300);
window.setTitle("Rock Paper Scissors");
window.setScene(scene1);
window.show();
}
}
My program takes a user value and passes the value through a method before returning a message on the GUI. I am wondering how I could be able to recursively move this message (called displayResult) value down along the Y axis in order to make room for new messages when the user calls the method again.
public class GuessingGameController extends Tab {
Scene sceneOne;
Scene sceneTwo;
int choice;
int generatedNumber;
//private GuessingGame resetGuessingGame;
public int generateRandomNumber() {
Random randomNumber = new Random();
int number = randomNumber.nextInt(50) + 1;
return number;
}
GuessingGameController(Stage primaryStage) {
GuessingGame guess = new GuessingGame();
generatedNumber = generateRandomNumber();
Label labelOne = new Label("WELCOME TO THE GUESSING GAME");
setText("GuessingGame");
Pane paneLayoutOne = new StackPane();
Pane paneLayoutTwo = new StackPane();
Button playButton = new Button("Click to Play!");
Button quitButton = new Button("Quit");
paneLayoutOne.getChildren().addAll(labelOne, playButton, quitButton);
labelOne.setTranslateX(0);
labelOne.setTranslateY(-100);
playButton.setTranslateX(0);
playButton.setTranslateY(0);
quitButton.setTranslateX(0);
quitButton.setTranslateY(50);
setContent(paneLayoutOne);
sceneOne = new Scene(paneLayoutOne, 400, 400);
quitButton.setOnAction(e -> System.exit(0));
playButton.setOnAction(e -> primaryStage.setScene(sceneTwo));
Label userMessage = new Label("Please enter your guess here");
TextField userInput = new TextField();
Button guessButton = new Button("Guess");
Button resetButton = new Button("Reset Game");
Button backButton = new Button("Back");
userMessage.setTranslateX(0);
userMessage.setTranslateY(-160);
userInput.setTranslateX(0);
userInput.setTranslateY(-120);
guessButton.setTranslateX(0);
guessButton.setTranslateY(-80);
resetButton.setTranslateX(0);
resetButton.setTranslateY(-40);
backButton.setTranslateX(0);
backButton.setTranslateY(0);
guessButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
int choice = Integer.parseInt(userInput.getText());
guess.startGuessingGame(choice, generatedNumber);
String endResult;
endResult = guess.startGuessingGame(choice, generatedNumber);
Label displayResult = new Label(endResult);
displayResult.setTranslateX(0);
displayResult.setTranslateY(150);
paneLayoutTwo.getChildren().add(0, displayResult);
}
});
//resetButton.setOnAction(e -> resetGuessingGame.resetForm(this));
backButton.setOnAction(e -> primaryStage.setScene(sceneOne));
paneLayoutTwo.getChildren().addAll(userMessage, userInput, guessButton, resetButton, backButton);
sceneTwo = new Scene(paneLayoutTwo, 400, 400);
}
}
I'm trying to combine 3 features into a single JavaFX class. My first feature displays "WELCOME TO JAVA" around in a circle. The second displays a 10x10 matrix of random 1's and 0's. The third displays a smiley face. They should be displayed one after the other in a single pane. I have the first and third features but the matrix one is throwing me off. Although everything is supposed to be in a single pane to display on the same GUI window (per professor), I don't see how else I could've done the matrix other than creating the gridPane. It displays fine without the size constraints, but then it takes up the entire screen and my other 2 features aren't visible. When I add the constraints, it gets small and the numbers aren't visible. I'm not sure how I can fix this. Can someone please help?
Pane pane = new Pane();
// Create a circle and set its properties
Circle circle = new Circle();
circle.setCenterX(100);
circle.setCenterY(100);
circle.setRadius(50);
circle.setStroke(null);
circle.setFill(null);
pane.getChildren().add(circle); // Add circle to the pane
//Display WELCOME TO JAVA with the text forming a circle
int i = 0;
String phrase = "WELCOME TO JAVA ";
double degree = 360 / phrase.length();
for (double degrees = 0; i < phrase.length(); i++, degrees += degree) {
double pointX = circle.getCenterX() + circle.getRadius() *
Math.cos(Math.toRadians(degrees));
double pointY = circle.getCenterY() + circle.getRadius() *
Math.sin(Math.toRadians(degrees));
Text letter = new Text(pointX, pointY, phrase.charAt(i) + "");
letter.setFill(Color.BLACK);
letter.setFont(Font.font("Times New Roman", FontWeight.BOLD, 20));
letter.setRotate(degrees + 90);
pane.getChildren().add(letter); }
//Create a 10x10 matrix of 1s and 0s
GridPane pane2 = new GridPane();
pane2.setHgap(1);
pane2.setVgap(1);
Button[][] matrix;
int length = 10;
int width = 10;
ArrayList<TextField> textFields = new ArrayList<>();
for (int y = 0; y < length; y++) {
ColumnConstraints colConst = new ColumnConstraints();
colConst.setPercentWidth(10);
pane2.getColumnConstraints().add(colConst);
for (int x = 0; x < width; x++) {
RowConstraints rowConst = new RowConstraints();
rowConst.setPercentHeight(10);
pane2.getRowConstraints().add(rowConst);
Random rand = new Random();
int random1 = rand.nextInt(2);
TextField textf = new TextField();
textf.setText("" + random1);
textf.setPrefSize(15, 15);
pane2.setRowIndex(textf, x);
pane2.setColumnIndex(textf, y);
pane2.getChildren().add(textf);
}}
//Create a smiley face
Circle circle2 = new Circle();
circle2.setCenterX(600.0f);
circle2.setCenterY(100.0f);
circle2.setRadius(50.0f);
circle2.setStroke(Color.BLACK);
circle2.setFill(null);
pane.getChildren().add(circle2);
Circle leftInnerEye = new Circle();
leftInnerEye.setCenterX(580.0f);
leftInnerEye.setCenterY(85.0f);
leftInnerEye.setRadius(5);
leftInnerEye.setStroke(Color.BLACK);
pane.getChildren().add(leftInnerEye);
Ellipse leftOutterEye = new Ellipse();
leftOutterEye.setCenterX(580.0f);
leftOutterEye.setCenterY(85.0f);
leftOutterEye.setRadiusX(11.0f);
leftOutterEye.setRadiusY(8.0f);
leftOutterEye.setStroke(Color.BLACK);
leftOutterEye.setFill(null);
pane.getChildren().add(leftOutterEye);
Circle rightEye = new Circle();
rightEye.setCenterX(620.0f);
rightEye.setCenterY(85.0f);
rightEye.setRadius(5);
rightEye.setStroke(Color.BLACK);
pane.getChildren().add(rightEye);
Ellipse rightOutterEye = new Ellipse();
rightOutterEye.setCenterX(620.0f);
rightOutterEye.setCenterY(85.0f);
rightOutterEye.setRadiusX(11.0f);
rightOutterEye.setRadiusY(8.0f);
rightOutterEye.setStroke(Color.BLACK);
rightOutterEye.setFill(null);
pane.getChildren().add(rightOutterEye);
Polygon nose = new Polygon();
nose.getPoints().setAll(
600d, 90d,
588d, 115d,
612d, 115d );
nose.setStroke(Color.BLACK);
nose.setFill(null);
pane.getChildren().add(nose);
Arc mouth = new Arc(600, 115, 30, 16, 180, 180);
mouth.setFill(null);
mouth.setType(ArcType.OPEN);
mouth.setStroke(Color.BLACK);
pane.getChildren().add(mouth);
HBox hbox = new HBox(pane, pane2);
hbox.autosize();
hbox.setAlignment(Pos.BASELINE_LEFT);
hbox.setPadding(new Insets(20));
// Create a scene and place it in the stage
Scene scene = new Scene(hbox, 1000, 500);
primaryStage.setTitle("Laura's Chapter 14"); // Set the stage title
primaryStage.setScene(scene); // Place the scene in the stage
primaryStage.show(); // Display the stage
}
catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
Create a pane for each feature and then add the features to either a VBox or HBox, that will root pane of the scene. That way you can have a GridPane for your second feature. There are different layouts available in JavaFX and they behave differently. Take a look at this documentation and its sub documentations.