How to call an array of Images - java

So, I am assigned a problem where I have to display, using JavaFX, 4 random cards and a "Refresh" button that shuffles and displays the cards.
The problem stems when I need to display the cards.
I'm not entirely sure how to show/display the images. I consulted the textbook and I can't figure out another path to solving this problem as well as consulting a classmate.
I have the deck of card images in another source file (peer's suggestion) within the java project.
Here is what I have so far:
package Images;
import java.util.Arrays;
import java.util.Collections;
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class CardRefreshButton extends Application{
Image[] deck = new Image[51];
public void add() {
for(int i = 0; i < deck.length; i++){
deck[i] = new Image(i + ".png");
}
}
public void shuffle() {
Collections.shuffle(Arrays.asList(deck));
}
#Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Shuffling Deck Program");
BorderPane bPane1 = new BorderPane();
HBox pane1 = new HBox(10);
HBox pane2 = new HBox(10);
Button refresh = new Button("Refresh");
refresh.setOnAction((event) -> {
add();
shuffle();
pane1.getChildren().clear();
start(primaryStage);
});
pane1.setAlignment(Pos.CENTER);
pane2.setAlignment(Pos.CENTER);
Image card1 = deck[0];
Image card2 = deck[1];
Image card3 = deck[2];
Image card4 = deck[3];
ImageView view1 = new ImageView(card1);
ImageView view2 = new ImageView(card2);
ImageView view3 = new ImageView(card3);
ImageView view4 = new ImageView(card4);
pane1.getChildren().addAll(view1,view2,view3,view4);
pane2.getChildren().add(refresh);
bPane1.setCenter(pane1);
bPane1.setBottom(pane2);
Scene scene1 = new Scene(bPane1, 600,650);
primaryStage.setScene(scene1);
primaryStage.show();
}
}

Here's a modified version of your code:
first you load the images
then you create the ImageView nodes and put them in the HBox
in your refresh code you shuffle the list and assign the images to the existing ImageView nodes
The code:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class CardRefreshButton extends Application {
List<Image> deck = new ArrayList<>();
public void load() {
for (int i = 0; i < 52; i++) {
deck.add(new Image(getClass().getResource(i + ".png").toExternalForm()));
}
}
#Override
public void start(Stage primaryStage) {
load();
primaryStage.setTitle("Shuffling Deck Program");
BorderPane bPane1 = new BorderPane();
HBox pane1 = new HBox(10);
HBox pane2 = new HBox(10);
ImageView view0 = new ImageView(deck.get(0));
ImageView view1 = new ImageView(deck.get(1));
ImageView view2 = new ImageView(deck.get(2));
ImageView view3 = new ImageView(deck.get(3));
Button refresh = new Button("Refresh");
refresh.setOnAction((event) -> {
Collections.shuffle( deck);
view0.setImage(deck.get(0));
view1.setImage(deck.get(1));
view2.setImage(deck.get(2));
view3.setImage(deck.get(3));
});
pane1.setAlignment(Pos.CENTER);
pane2.setAlignment(Pos.CENTER);
pane1.getChildren().addAll(view0, view1, view2, view3);
pane2.getChildren().add(refresh);
bPane1.setCenter(pane1);
bPane1.setBottom(pane2);
Scene scene1 = new Scene(bPane1, 600, 650);
primaryStage.setScene(scene1);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}

You can use clean coding too:
Main.java file:
package sample;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
primaryStage.setTitle("Display Random Images");
primaryStage.setScene(new Scene(root, 900, 500));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Controller.java file:
package sample;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import java.util.Random;
public class Controller {
#FXML
private Button btnRefresh
#FXML
private TextField txtShow;
#FXML
private ImageView imgAni;
#FXML
public void initialize(){
btnRefresh.setText(" Refresh ");
}
#FXML
public void btnLoad(ActionEvent event){vImage();}
void vImage(){
Image img1 = new Image("sample/res/tiger.jpg");
Image img2= new Image("sample/res/horse.jpg");
Image img3 = new Image("sample/res/lion.jpg");
//imgAni.setImage(img1);*/
Image[] img = {img1,img2,img3};
Random rand = new Random();
for (int i = 0; i < img.length; i++){
imgAni.setImage(img[rand.nextInt(img.length)]);
}
}
}
sample.fxml file:
<AnchorPane prefHeight="484.0" prefWidth="599.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="sample.Controller">
<children>
<Button fx:id="btnRefresh" layoutX="155.0" layoutY="187.0" mnemonicParsing="false" onAction="#btnLoad" prefHeight="50.0" prefWidth="90.0" text="" />
<TextField fx:id="txtShow" layoutX="136.0" layoutY="74.0" prefWidth="200.0" />
<ImageView fx:id="imgAni" fitHeight="400.0" fitWidth="221.3334615803972" layoutX="363.0" layoutY="21.0" pickOnBounds="true" preserveRatio="true" />
</children>
</AnchorPane>
I'm in support of breaking your programs into different files,classes and modules.
my pictures are in a package called res inside sample. Have a great coding day

Related

why JOptionPane.showMessageDialog just working in main?

I'm using NetBeans last version and macOS. I try this is my code and JOptionPane.showMessageDialog not working. It's working if I put the syntax in the main. Please tell me why. I try vscode, and I have same problem
import javax.swing.*;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
import javafx.scene.control.RadioButton;
import javafx.scene.control.TextField;
import javafx.scene.control.TextInputDialog;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
public class App extends Application {
TextField txt;
public void start(Stage primaryStage) {
Label lb1 = new Label();
TextField txt = new TextField("Type here");
RadioButton rb1 = new RadioButton();
RadioButton rb2 = new RadioButton();
Button bt = new Button("click");
Button bt1 = new Button("anas aljaghbeer");
MyHandlerClass handler1 = new MyHandlerClass();
bt.setOnAction(handler1);
txt.setPrefSize(10, 10);
lb1.setText("Enter here");
txt.getText();
VBox box = new VBox();
Scene scene = new Scene(box, 1000, 1000);
box.getChildren().addAll(lb1, txt, bt);
primaryStage.setTitle("anas");
primaryStage.setScene(scene);
primaryStage.show();
}
class MyHandlerClass implements EventHandler<ActionEvent> {
#Override
public void handle(ActionEvent e) {
JOptionPane.showMessageDialog(null, " Hello");
}
}
public static void main(String[] args) {
Application.launch(args);
}
}
JOptionPane.showMessageDialog()…It's working if I put the syntax in the main. Please tell me why.
When you invoke JOptionPane.showMessageDialog() in main(), it executes on the initial thread. In a Swing program, you would invoke it from main() like this:
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
JOptionPane.showMessageDialog(null, "Click to continue…");
…
});
}
In a JavaFX program you are well advised not to "mix Swing and JavaFX," unless you account for JavaFX-Swing Interoperability. Instead, evoke an Alert as shown here and below:
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class App extends Application {
TextField txt;
#Override
public void start(Stage primaryStage) {
Label label = new Label();
TextField text = new TextField("Type here");
Button button = new Button("Click");
MyHandlerClass handler = new MyHandlerClass();
button.setOnAction(handler);
text.setPrefSize(10, 10);
label.setText("Enter here");
text.getText();
VBox box = new VBox();
box.getChildren().addAll(label, text, button);
Scene scene = new Scene(box, 320, 240);
primaryStage.setScene(scene);
primaryStage.setTitle("anas");
primaryStage.show();
}
class MyHandlerClass implements EventHandler<ActionEvent> {
#Override
public void handle(ActionEvent e) {
Alert alert = new Alert(Alert.AlertType.INFORMATION, "You clicked the button.");
alert.showAndWait();
}
}
public static void main(String[] args) {
Application.launch(args);
}
}

How to open another screen in JavaFX (not FXML file)

I'm very new to JavaFX. I want to communication between two window in my program, but I don't know how to do it. For example: after login successfully, another screen will pop up (but I don't want to load the file FXML because I used the loop to generate the toggle buttons in this window instead of dragging-dropping in FXML file). I don't know whether it makes sense or not. If not please forgive me :(
Main.java
package sample;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception{
Parentroot=FXMLLoader.load(getClass().getResource("sample.fxml"));
primaryStage.setTitle("Login");
primaryStage.setScene(new Scene(root, 400,300));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Controller.java
import javafx.scene.control.TextField;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import java.io.IOException;
public class Controller {
#FXML
private TextField usernameField;
#FXML
private TextField passwordField;
#FXML
public void login(){
if(usernameField.getText().equals("admin") && passwordField.getText().equals("123")){
successLogin();
}
}
public void successLogin(){
try {
Parent root = FXMLLoader.load(getClass().getResource("anotherscene.fxml"));
Stage stage = new Stage(StageStyle.DECORATED);
stage.show();
}catch (IOException e){
e.printStackTrace();
}
}
}
AnotherScene.java
package sample;
import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ToggleButton;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
public class AnotherScene implements Initializable {
ToggleButton[][] matrix;
private static final int SIZE = 10;
private static int length = SIZE;
private static int width = SIZE;
#FXML
private BorderPane borderPane;
#Override
public void initialize(URL url, ResourceBundle resourceBundle) {
Parent root = null;
try{
root = FXMLLoader.load(getClass().getResource("anotherscene.fxml"));
}catch (IOException e){
e.getStackTrace();
}
Stage stage = new Stage();
VBox vBox = new VBox();
vBox.getChildren().add(new Label("Seat Number: "));
borderPane.setLeft(vBox);
GridPane gridPane = new GridPane();
gridPane.setHgap(10);
gridPane.setVgap(10);
borderPane.setCenter(gridPane);
matrix = new ToggleButton[length][width];
for(int row = 0; row < length; row++){
for(int col = 0; col < width; col++){
matrix[row][col] = new ToggleButton();
matrix[row][col].setText(row + "" +col);
matrix[row][col].setPrefWidth(40);
gridPane.add(matrix[row][col], row, col);
}
}
// Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
stage.setTitle("Hello World");
Scene scene = new Scene(root, 700, 500);
stage.setScene(scene);
stage.show();
}
}

how to create this type of button in javafx

In javafx can I create this type of button? I tried a splitmenubutton but it contais the button with the arrow. In this picture the button contains an arrow with text and an image (not just the arrow).
Here is an example using MenuButton. I found an option image and a down-arrow image.
Key code
//Use a VBox to stack the different nodes
menuButton.setGraphic(new VBox(new StackPane(imageView), label, new StackPane(imageView2)));
***The attached CSS file removes the default down-arrow.****
Full code
import javafx.application.Application;
import javafx.geometry.Side;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuButton;
import javafx.scene.control.MenuItem;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
/**
*
* #author Sedrick
*/
public class JavaFXApplication9 extends Application {
#Override
public void start(Stage primaryStage) {
MenuItem menuItem1 = new Menu("One");
MenuItem menuItem2 = new Menu("Two");
MenuButton menuButton = new MenuButton();
ImageView imageView = new ImageView(new Image(getClass().getResourceAsStream("options.png")));
imageView.setFitWidth(25);
imageView.setFitHeight(25);
ImageView imageView2 = new ImageView(new Image(getClass().getResourceAsStream("arrow.png")));
imageView2.setFitWidth(25);
imageView2.setFitHeight(15);
Label label = new Label("Options");
menuButton.setGraphic(new VBox(new StackPane(imageView), label, new StackPane(imageView2)));
menuButton.getItems().addAll(menuItem1, menuItem2);
menuButton.setPopupSide(Side.BOTTOM);
StackPane root = new StackPane();
root.getChildren().add(menuButton);
Scene scene = new Scene(root, 300, 250);
scene.getStylesheets().add(getClass().getResource("myCss.css").toString());
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
CSS File
Code from here.
.menu-button > .arrow-button {
-fx-padding: 0;
}
.menu-button > .arrow-button > .arrow {
-fx-padding: 0;
}
Results

JavaFX - Weird Behavior When Adding Node To Parent

I have created a simple app to simulate dynamic node creation with JAVAFX.
This app has the ability to create a new window whenever user want it by clicking the "New" button.
User can add a new node which is TitledPane to the window by clicking "Add Task" button and then clicking "Add" button on the dialog window.
There are an unexpected behavior which I want to fix. This app is only add new node (TitledPane in this case) to the last created window.
And the all of the nodes on the previous window will vanish.
You can see the following video to better understand what I mean.
VIDEO
https://youtu.be/eaWmu3zuuhE
NETBEANS PROJECT
Just in case you want to play with it.
https://drive.google.com/file/d/0B4Sbb8Ym-lcZLUIyWHV5ZXRSZE0/view?usp=sharing
CODES:
TasksList.java
package taskslist;
import javafx.application.Application;
import javafx.scene.Parent;
import javafx.stage.Stage;
public class TasksList extends Application {
DisplayWhich display = new DisplayWhich();
Stage primaryStage;
Parent startWindow;
#Override
public void start(Stage primaryStage) throws Exception {
this.primaryStage = primaryStage;
initStart();
}
private void initStart(){
display.showDialogWindow();
}
public static void main(String[] args) {
launch(args);
}
}
TheList.java
package taskslist.view;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextField;
import javafx.scene.control.TitledPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Modality;
import javafx.stage.Stage;
import taskslist.DisplayWhich;
public class TheList extends BorderPane {
public static VBox listWrapper;
public static ScrollPane listScroller;
public ObservableList<TitledPane> tasks;
private List<String> titles = new ArrayList<>();
public TheList(){
tasks = FXCollections.observableArrayList();
listWrapper = new VBox(5);
listScroller = new ScrollPane(listWrapper);
}
public void setTitles(String... title){
titles = Arrays.asList(title);
}
public List<String> getTitles(){
return titles;
}
public void loadSavedList(){
for(int i=0; i<getTitles().size();i++){
String ttlString = getTitles().get(i);
this.createTask(ttlString);
}
// Display Tasks
listWrapper.getChildren().addAll(this.tasks);
}
// Dialong for adding a new task and also editing a task
private void addTaskDialog(){
GridPane container = new GridPane();
Scene scene = new Scene(container, 150, 50);
Stage addNewTask = new Stage();
addNewTask.initModality(Modality.APPLICATION_MODAL);
addNewTask.setTitle("Add Task");
TextField title = new TextField();
Button confirm = new Button("Add");
// Create Task
confirm.setOnAction((ev) -> {
String ttlString = title.getText();
this.createTask(ttlString);
listWrapper.getChildren().clear();
listWrapper.getChildren().addAll(this.tasks);
addNewTask.close();
});
container.add(title, 0, 1);
container.add(confirm, 0, 5);
addNewTask.setScene(scene);
addNewTask.showAndWait();
}
// Assemble all this.tasks list components
public void render(){
setCenter(listScroller);
loadSavedList();
Button newProject = new Button("New");
Button addTask = new Button("Add Task");
BorderPane listBottom = new BorderPane();
HBox bottomLeft = new HBox();
bottomLeft.getChildren().add(newProject);
listBottom.setLeft(bottomLeft);
HBox bottomRight = new HBox();
bottomRight.getChildren().add(addTask);
listBottom.setRight(bottomRight);
newProject.setOnAction((evt) -> {
DisplayWhich display = new DisplayWhich();
display.showDialogWindow();
});
addTask.setOnAction((e) -> {
addTaskDialog();
});
setBottom(listBottom);
}
// Cteate task from strings
private void createTask(String... strings){
String taskTitle = strings.length > 0 ? strings[0] : "";
TitledPane task = new TitledPane();
task.setPrefWidth(647);
task.setExpanded(false);
task.setText(taskTitle);
this.tasks.add(task);
}
}
NewDialog.java
package taskslist.view;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.Parent;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
import taskslist.DisplayWhich;
public class NewDialog {
DisplayWhich display = new DisplayWhich();
Stage stage = new Stage();
Parent startWindow = new AnchorPane();
#FXML
private Button cancelNew;
#FXML
private Button confirmCreation;
/**
* Initializes the controller class.
*/
#FXML
private void initialize() {
}
#FXML
private void cancelNewCreation(ActionEvent event) {
((Stage)cancelNew.getScene().getWindow()).close();
}
#FXML
private void confirmCreateNew(ActionEvent event) {
((Stage)confirmCreation.getScene().getWindow()).close();
TheList wrap = new TheList();
TheWindow window = new TheWindow();
window.makeWindow(wrap);
wrap.setTitles("one", "two", "three", "four");
wrap.render();
}
}
DisplayWhich.java
package taskslist;
import java.io.IOException;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Modality;
import javafx.stage.Stage;
import taskslist.view.TheList;
public class DisplayWhich {
Stage stage = new Stage();
Parent startWindow = new AnchorPane();
public DisplayWhich(){}
public Stage showDialogWindow(){
try {
stage.initModality(Modality.APPLICATION_MODAL);
stage.setTitle("Create New Project");
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("/taskslist/view/newDialog.fxml"));
startWindow = loader.load();
Scene scene = new Scene(startWindow);
stage.setScene(scene);
stage.setOnCloseRequest((event) -> {
System.out.println("test");
});
stage.showAndWait();
} catch (IOException ex) {
ex.printStackTrace();
}
return stage;
}
}
TheWindow.java
package taskslist.view;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class TheWindow {
public TheWindow(){}
public void makeWindow(BorderPane group) {
Stage mainWindow = new Stage();
Scene scene = new Scene(group, 650, 550);
mainWindow.setScene(scene);
mainWindow.setTitle("Task List");
mainWindow.centerOnScreen();
mainWindow.show();
}
}
Why that weird behavior happening and how to fix it so it only adds new node to the same window where the clicked "Add Task" button is located?
These fields should not be static:
public static VBox listWrapper;
public static ScrollPane listScroller;

HBox not showing up

So, I can't seem to make the HBox show up in my application. The Button shows up, but the HBox does not. Can someone please let me know what I'm doing wrong?
package cyanlauncher;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
public class Main extends Application {
private int numApps = 0;
private float btnSize = 48;
private float btnSpacing = 12;
#Override
public void start(Stage primaryStage) {
primaryStage.initStyle(StageStyle.TRANSPARENT);
primaryStage.setTitle("CyanLauncher");
Button quitBtn = new Button();
Pane root = new Pane();
root.getChildren().add(addHBox());
quitBtn.setGraphic(new ImageView(new Image(getClass().getResourceAsStream("./../data/exit.png"))));
quitBtn.setLayoutX(10 + ((btnSize + btnSpacing) * numApps));
quitBtn.setLayoutY(7);
quitBtn.setPadding(new Insets(0,0,0,0));
quitBtn.setPrefSize(btnSize, btnSize);
quitBtn.setOnAction(new EventHandler<ActionEvent>(){
#Override
public void handle(ActionEvent event){
System.exit(0);
}
});
root.getChildren().add(quitBtn);
Scene scene = new Scene(root,64,64);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
scene.setFill(null);
primaryStage.setScene(scene);
primaryStage.show();
}
public HBox addHBox() {
HBox hbox = new HBox();
hbox.setPrefSize(64, 64);
hbox.setLayoutX(10);
hbox.setLayoutY(7);
return hbox;
}
public static void main(String[] args) {
launch(args);
}
}
And here is my CSS:
/* JavaFX CSS - Leave this comment until you have at least create one rule which uses -fx-Property */
.root {
-fx-background-color: rgba(0,255,0,1);
}
.button {
-fx-background-color: rgba(0,0,255,1);
}
.hbox {
-fx-background-color: rgba(255,0,0,1);
}
HBox has no style class by default (see docs). So you need to do hbox.getStyleClass().add("hbox") in your (really badly named) addHBox() method.

Categories

Resources