JavaFX - Cannot call setOnAction() on ChoiceBox? - java

Simple question:
I've DEFINITELY used setOnAction for ChoiceBox<T> before, but it claims there is no such method of the ChoiceBox class. I'm using a different computer and have installed the Ex(fx)clipse plugin. At the bottom of this thread are my imports. I also have proof that I have used this method of ChoiceBox before. What is wrong? It must be something outrageously simple. I don't understand how I was able to write it before and yet I don't see it in the JavaFX API page.
Edit:
Runnable version of my class here.
Instance Variables
private VBox root;
private Scene scene;
private static Stage stage;
private Label consoleTitle;
private static TextArea console;
private Button startBtn, endBtn, calibrateBtn, calibrateAreaBtn;
private ChoiceBox<String> lureCB;
private CheckBox lureCKB;
private HBox buttonHB, lureHB;
Code block in my method body:
// ChoiceBox for the type of lures.
lureCB = new ChoiceBox<>();
lureCB.getItems().addAll("Test",
"Test",
"Test",
"Test",
"Test",
"Test");
lureCB.setVisible(false);
lureCB.setOnAction(e ->
{
});
My Imports
package gui;
import java.awt.AWTException;
import java.awt.Robot;
import java.time.LocalTime;
import program.*;
import javafx.application.Application;
import javafx.scene.control.Button;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
import javafx.geometry.Insets;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.control.Tooltip;
import javafx.scene.text.Font;
import javafx.geometry.Pos;
import javafx.scene.paint.Color;

EDIT:
It turned out that the setOnAction method was only added to the ChoiceBox API starting from the 8u60 version of the JDK.

Related

How do I change a scene in javaFX without a button?

How can I change a scene without directly interacting with it (like using a button). What I would like for my program to do is change scene, and then using the Initializable class, the program would wait 1.5 seconds then change scene.
I am currently using a PauseTransition to do this, however I get a ClassCastException. Also, I do not understand what Intellij is trying to tell me about the Node. It says 'Find why 'event.getSource()' could be javafx.animation.PauseTransition (not-null)'.
Thanks in advance.
Stack Trace:
Exception in thread "JavaFX Application Thread" java.lang.ClassCastException: class javafx.animation.KeyFrame cannot be cast to class javafx.scene.Node (javafx.animation.KeyFrame and javafx.scene.Node are in module javafx.graphics of loader 'app')
at Dice.Game/sample.RoundCounterController.lambda$initialize$0(RoundCounterController.java:54)
at javafx.graphics/com.sun.scenario.animation.shared.TimelineClipCore.visitKeyFrame(TimelineClipCore.java:239)
at javafx.graphics/com.sun.scenario.animation.shared.TimelineClipCore.playTo(TimelineClipCore.java:180)
at javafx.graphics/javafx.animation.Timeline.doPlayTo(Timeline.java:177)
at javafx.graphics/javafx.animation.AnimationAccessorImpl.playTo(AnimationAccessorImpl.java:39)
at javafx.graphics/com.sun.scenario.animation.shared.SingleLoopClipEnvelope.timePulse(SingleLoopClipEnvelope.java:99)
at javafx.graphics/javafx.animation.Animation.doTimePulse(Animation.java:1101)
at javafx.graphics/javafx.animation.Animation$1.lambda$timePulse$0(Animation.java:186)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at javafx.graphics/javafx.animation.Animation$1.timePulse(Animation.java:185)
at javafx.graphics/com.sun.scenario.animation.AbstractMasterTimer.timePulseImpl(AbstractMasterTimer.java:344)
at javafx.graphics/com.sun.scenario.animation.AbstractMasterTimer$MainLoop.run(AbstractMasterTimer.java:267)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:515)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:499)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulseFromQueue(QuantumToolkit.java:492)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$11(QuantumToolkit.java:320)
at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
at java.base/java.lang.Thread.run(Thread.java:829)
RoundCountController.java
import javafx.animation.KeyFrame;
import javafx.animation.PauseTransition;
import javafx.animation.Timeline;
import javafx.animation.Transition;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
import javafx.util.Duration;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
public class RoundCounterController implements Initializable {
#FXML private Label roundLabel;
private static int roundCounter = 0;
#FXML private AnchorPane pane;
private Stage stage;
private Scene scene;
private Parent root;
#Override
public void initialize(URL url, ResourceBundle resourceBundle) {
PauseTransition pauseTransition = new PauseTransition(Duration.seconds(1.5));
pauseTransition.setOnFinished(event -> {
try {
Parent root = FXMLLoader.load(getClass().getResource("p1GameScene.fxml"));
} catch (IOException e) {
e.printStackTrace();
}
stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
scene = new Scene(root);
stage.setScene(scene);
stage.show();
});
pauseTransition.play();
}
}

JavaFX Media Player Only Playing One Second of MP3

I am trying to get a mp3 file to play on JavaFX's MediaPlayer from a downloaded file. It is really weird because when I run my code, I hit the play button and it only plays for a second. When I hit the rewind button though, then the mp3 plays. I am not sure if I am doing something wrong.
I have tried using the URL from where I got the mp3 from, but I get an error saying that https protocol is not supported.
Here is my code:
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Region;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.stage.Stage;
import javafx.util.Duration;
import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.Path;
import java.nio.file.Files;
import java.net.URL;
import java.io.InputStream;
import java.nio.file.StandardCopyOption;
import static java.nio.file.Files.createTempFile;
public class JavaFXApplet extends Application{
//private static final String MEDIA_URL = "https://www.bensound.com/bensound-music/bensound-summer.mp3";
#Override
public void start(Stage primaryStage) {
Media media = new Media("file:///Users/mycomputer/Downloads/bensound-summer.mp3");
//Media media = new Media(MEDIA_URL);
MediaPlayer mediaPlayer = new MediaPlayer(media);
MediaView mediaView = new MediaView(mediaPlayer);
Button playButton = new Button(">");
playButton.setOnAction(e -> {mediaPlayer.play();});
Button pauseButton = new Button("||");
pauseButton.setOnAction(e-> mediaPlayer.pause());
Button rewindButton = new Button("<<");
rewindButton.setOnAction(e -> mediaPlayer.seek(Duration.ZERO));
Slider slVolume = new Slider();
slVolume.setPrefWidth(150);
slVolume.setMaxWidth(Region.USE_PREF_SIZE);
slVolume.setMinWidth(30);
slVolume.setValue(50);
mediaPlayer.volumeProperty().divide(100);
HBox hBox = new HBox(10);
hBox.setAlignment(Pos.CENTER);
hBox.getChildren().addAll(playButton, pauseButton, rewindButton, new Label("Volume"), slVolume);
BorderPane pane = new BorderPane();
pane.setCenter(mediaView);
pane.setBottom(hBox);
Scene scene = new Scene(pane, 650, 500);
primaryStage.setTitle("Test Player");
primaryStage.setScene(scene);
primaryStage.show();
primaryStage.setOnCloseRequest(windowEvent -> {
mediaPlayer.stop();
});
}
public static void main(String[] args) {
launch(args);
}
}
I am using a Mac with IntelliJ, and I have tried using Eclipse as well without any success.
I'm open to any suggestions on how to get this to work properly or how to get the URL to work.
So I ended up figuring this out on my own after some research.
I found this JDK bug post that sounded just like my issue: https://bugs.openjdk.java.net/browse/JDK-8138754
What I ended up doing was adding this into my code to get my mediaPlayer to work:
mediaPlayer.setCycleCount(MediaPlayer.INDEFINITE);
I hope that this will help out someone with the same issue someday.

javaFX circle in a layout not visible

I made a circle and added as a child to a group. then I added the group as a child to a layout(Region). I added Region to the scene. I made both with different colours but I cannot see the circle
Analog_clock.java
package analog_clock;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
public class Analog_clock extends Application {
#Override
public void start(Stage primaryStage) {
Circle circle = new Circle();
circle.setCenterX(100.0f);
circle.setCenterY(100.0f);
circle.setRadius(50.0f);
circle.setFill(Color.ALICEBLUE);
Group g = new Group();
g.getChildren().add(circle);
Background_region_ bg = new Background_region_();
bg.getChildrenUnmodifiable().add(g);
Scene scene = new Scene(bg, 300, 250);
scene.getStylesheets().add(this.getClass().getResource("style.css").toExternalForm());
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Background_Region_.java
package analog_clock;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class Background_region_ extends Region
{
//CONSTRUCTOR
public Background_region_()
{
setStyle("-fx-background-color: #ACACE6");
}
}
style.css
.circle{-fx-stroke: #cdd0d7;}
The problem is the Region Class only has an Unmodifiable List of children via its public API, that means, the only way to add children to it is to subclass it (e.g Pane). So use Pane or another subclass, something like this for example:
Pane bg = new Pane();
bg.setBackground(new Background(new BackgroundFill(Color.web("#ACACE6"), null,null)));
bg.getChildren().add(g);
Use Pane instead of Region. Region is a special parent class for control's developers.
Next line throws exception in your code:
bg.getChildrenUnmodifiable().add(g);
Note word "Unmodifiable". It means your are not supposed and can't modify this list.

Trigger action on default value Combo Box JavaFX

I am trying to trigger an action on default value of the combo box when it is initialized but I'm only able to find the method to trigger an action when the value is changed using method print() set in OnAction of ComboBox.
Here is my presenter of the FXML file:
package tre;
import java.net.URL;
import java.util.ResourceBundle;
import javax.swing.event.ChangeListener;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
public class presenter implements Initializable {
public #FXML ComboBox<String> combo;
private final ObservableList<String> statistic = FXCollections.observableArrayList("Logged In", "Anonymous",
"Logged Off");
#Override
public void initialize(URL location, ResourceBundle resources) {
// TODO Auto-generated method stub
combo.setItems(statistic);
combo.setValue("Anonymous");
//TODO When Anonymous is displayed as default value in the combo box, it will print it.
}
public #FXML void print(){
String sel = combo.getSelectionModel().getSelectedItem();
System.out.println(sel);
}
}
Is there a solution for it? Thanks

addAll() method not working?

so maybe I'm not using the method how it's intended to be used but a video I watched by youtube user thenewboston used it exactly like this and it worked just fine. Help would be appreciated
package checkers;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.FlowLayout;
import javafx.scene.Scene ;
import javafx.scene.control.*;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.application.*;
import javafx.stage.*;
public class Checkers extends Application {
Stage window;
public void start(Stage primaryStage) throws Exception {
window = primaryStage;
window.setTitle("Title");
HBox layout = new HBox();
Button startButton = new Button("Start");
Button quitButton = new Button("Quit");
layout.getChildren().addAll(startButton, quitButton);
Scene startScene = new Scene(layout, 400, 300);
window.setScene(startScene);
window.show();
}
public static void main(String[] args) {
launch(args);
}
}
`
The error I am receiving is as follows -
"The method addAll(int, Collection) in the type List is not applicable for the arguments (Button, Button)"
You imported the wrong type of Button. You want import javafx.scene.control.Button; not import java.awt.Button;

Categories