Repeat, Repeat All, No Repeat in Media Player in javafx - javafx

This is my Code.
boolean repeat=false, repeatall=false;
static List<MediaPlayer> players = new ArrayList<>();
if(!players.isEmpty()){
for (int i = 0; i < players.size(); i++) {
MediaPlayer currentPlayer=players.get(i);
//MediaPlayer nextPlayer=players.get((i+1) % players.size());
int j=i;
currentPlayer.setOnEndOfMedia(new Runnable() {
#Override
public void run() {
currentPlayer.stop();
if(repeat){
currentPlayer.stop();
mediaView.setMediaPlayer(currentPlayer);
currentPlayer.play();
}else if(repeatall){
MediaPlayer nextPlayer=players.get((j+1) % players.size());
mediaView.setMediaPlayer(nextPlayer);
nextPlayer.play();
}else if(!repeatall){
if(j<players.size()){
MediaPlayer nextPlayer=players.get((j+1)); //Error Here. When Players is playing last index
mediaView.setMediaPlayer(nextPlayer);
nextPlayer.play();
}
}
}
});
}
}
This is my Media Player Code, But it is Showing some Error.
The Error showing
MediaPlayer nextPlayer=players.get((j+1));
on this line
When Players is last index
Exception in thread "JavaFX Application Thread" java.lang.IndexOutOfBoundsException: Index: 2, Size: 2
at java.util.ArrayList.rangeCheck(ArrayList.java:653)
at java.util.ArrayList.get(ArrayList.java:429)
at am.fx.main.node.audioPlayer.PlayMenus$12.run(PlayMenus.java:243) \\That Line
at com.sun.javafx.application.PlatformImpl.lambda$null$170(PlatformImpl.java:295)
at com.sun.javafx.application.PlatformImpl$$Lambda$48/1294163646.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
Can you please Help me to correct this code.

I Have solved my issue.
if(j<players.size()-1){
MediaPlayer nextPlayer=players.get((j+1));
mediaView.setMediaPlayer(nextPlayer);
nextPlayer.play();
}
Problem Solved.

Related

Exception in Application constructor, JavaFX [duplicate]

This question already has answers here:
getResourceAsStream returns null
(26 answers)
How do I determine the correct path for FXML files, CSS files, Images, and other resources needed by my JavaFX Application?
(1 answer)
Closed 1 year ago.
first of all, I'm a complete begginer in Java and JavaFX, using IntelliJ Idea for that.
I have tried to download and run a piece of game's code but ran into a problem that I can't pinpoint the cause of.
I have this in my VM options:
--module-path
${PATH_TO_FX};${OUTPUT}
--add-modules
javafx.controls,javafx.fxml
Error message itself:
Exception in Application constructor
java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:465)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:364)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1071)
Caused by: java.lang.RuntimeException: Unable to construct Application instance: class gg.game.Game
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:891)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:196)
at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$8(LauncherImpl.java:803)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:484)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:457)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:456)
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:184)
... 1 more
Caused by: java.lang.NullPointerException: Input stream must not be null
at javafx.graphics/javafx.scene.image.Image.validateInputStream(Image.java:1142)
at javafx.graphics/javafx.scene.image.Image.<init>(Image.java:705)
at gg.game/gg.game.Game.<init>(Game.java:19)
... 14 more
Exception running application gg.game.Game
Game's code:
package gg.game;
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import java.util.ArrayList;
import java.util.HashMap;
public class Game extends Application {
public static ArrayList<Block> platforms = new ArrayList<>();
private HashMap<KeyCode,Boolean> keys = new HashMap<>();
Image backgroundImg = new Image(getClass().getResourceAsStream("background.png"));
public static final int BLOCK_SIZE = 45;
public static final int MARIO_SIZE = 40;
public static Pane appRoot = new Pane();
public static Pane gameRoot = new Pane();
public Character player;
int levelNumber = 0;
private int levelWidth;
private void initContent(){
ImageView backgroundIV = new ImageView(backgroundImg);
backgroundIV.setFitHeight(14*BLOCK_SIZE);
backgroundIV.setFitWidth(212*BLOCK_SIZE);
levelWidth = LevelData.levels[levelNumber][0].length()*BLOCK_SIZE;
for(int i = 0; i < LevelData.levels[levelNumber].length; i++){
String line = LevelData.levels[levelNumber][i];
for(int j = 0; j < line.length();j++){
switch (line.charAt(j)){
case '0':
break;
case '1':
Block platformFloor = new Block(Block.BlockType.PLATFORM, j * BLOCK_SIZE, i * BLOCK_SIZE);
break;
case '2':
Block brick = new Block(Block.BlockType.BRICK,j*BLOCK_SIZE,i*BLOCK_SIZE);
break;
case '3':
Block bonus = new Block(Block.BlockType.BONUS,j*BLOCK_SIZE,i*BLOCK_SIZE);
break;
case '4':
Block stone = new Block(Block.BlockType.STONE,j * BLOCK_SIZE, i * BLOCK_SIZE);
break;
case '5':
Block PipeTopBlock = new Block(Block.BlockType.PIPE_TOP,j * BLOCK_SIZE, i * BLOCK_SIZE);
break;
case '6':
Block PipeBottomBlock = new Block(Block.BlockType.PIPE_BOTTOM,j * BLOCK_SIZE, i * BLOCK_SIZE);
break;
case '*':
Block InvisibleBlock = new Block(Block.BlockType.INVISIBLE_BLOCK,j * BLOCK_SIZE, i * BLOCK_SIZE);
break;
}
}
}
player =new Character();
player.setTranslateX(0);
player.setTranslateY(400);
player.translateXProperty().addListener((obs,old,newValue)->{
int offset = newValue.intValue();
if(offset>640 && offset<levelWidth-640){
gameRoot.setLayoutX(-(offset-640));
backgroundIV.setLayoutX(-(offset-640));
}
});
gameRoot.getChildren().add(player);
appRoot.getChildren().addAll(backgroundIV,gameRoot);
}
private void update(){
if(isPressed(KeyCode.UP) && player.getTranslateY()>=5){
player.jumpPlayer();
}
if(isPressed(KeyCode.LEFT) && player.getTranslateX()>=5){
player.setScaleX(-1);
player.animation.play();
player.moveX(-5);
}
if(isPressed(KeyCode.RIGHT) && player.getTranslateX()+40 <=levelWidth-5){
player.setScaleX(1);
player.animation.play();
player.moveX(5);
}
if(player.playerVelocity.getY()<10){
player.playerVelocity = player.playerVelocity.add(0,1);
}
player.moveY((int)player.playerVelocity.getY());
}
private boolean isPressed(KeyCode key){
return keys.getOrDefault(key,false);
}
#Override
public void start(Stage primaryStage) throws Exception {
initContent();
Scene scene = new Scene(appRoot,1200,620);
scene.setOnKeyPressed(event-> keys.put(event.getCode(), true));
scene.setOnKeyReleased(event -> {
keys.put(event.getCode(), false);
player.animation.stop();
});
primaryStage.setTitle("Mini Mario");
primaryStage.setScene(scene);
primaryStage.show();
AnimationTimer timer = new AnimationTimer() {
#Override
public void handle(long now) {
update();
}
};
timer.start();
}
public static void main(String[] args) {
launch(args);
}
}
I would be grateful to any kind of response. Thank you.

Java FX UI blocked by ExecutorService

I have a problem how to correctly update Java FX UI. I'm moving from Swing to FX for the first time and also ExecutorService. Problem is I need to show gif file and update progress bar during code execution but instead I get white screen with mouse loading icon. The gif and progressbar are eventually showed but after finishing this for cycle: for (int i = 0; i < futures.size(); i++)
I thought that running tasks in ExecutorService is in separate thread and using Platform.runLater for progressbar will separate UI from long running code in ExecutorService. Can you give me some explanation what is going on please?
Controller.java:
public void initialize() {
ivGif.setImage(new Image(Main.class.getResourceAsStream("/test/loading.gif")));
}
public void synchronizeFiles() {
Platform.runLater(() -> pbDownloading.setVisible(true));
ExecutorService pool = Executors.newFixedThreadPool(1);
ArrayList<Future<Boolean>> futures = new ArrayList<>();
File localFile = new File(simplified code here);
Future<Boolean> f = pool.submit(new DownloadTask(new URL(simplified code here), localFile));
futures.add(f);
for (int i = 0; i < futures.size(); i++) {
final int position = i;
Platform.runLater(() -> {
pbDownloading.setProgress(position / (double) futures.size());
});
if (!futures.get(i).get(600, TimeUnit.SECONDS)) {
System.out.println("ShutdownNow");
pool.shutdownNow();
}
}
}
DownloadTask.java:
public class DownloadTask implements Callable<Boolean> {
protected Category cat = Category.getInstance(DownloadTask.class.getName());
private URL fileURL;
private File toPath;
public DownloadTask(URL fileURL, File toPath) {
this.fileURL = fileURL;
this.toPath = toPath;
}
private void downloadFile(URL fileURL, File toPath) throws IOException {
ReadableByteChannel readableByteChannel = Channels.newChannel(fileURL.openStream());
if (!toPath.getParentFile().exists()) {
if (!toPath.getParentFile().mkdirs()) throw new IOException("Unable to create parent dirs for file: "+toPath.getAbsolutePath());
}
FileOutputStream fileOutputStream = new FileOutputStream(toPath);
fileOutputStream.getChannel().transferFrom(readableByteChannel, 0, Long.MAX_VALUE);
URLConnection urlConnection = fileURL.openConnection();
if (!toPath.setLastModified(urlConnection.getLastModified())) cat.error("Unable to write modified time stamp for file: "+toPath.getAbsolutePath());
}
#Override
public Boolean call() {
try {
downloadFile(fileURL, toPath);
} catch (IOException e){
System.out.println(e);
cat.error(e, e);
return false;
}
return true;
}
}
Thank you
EDIT: I didn't realize that the main class is running from FX Application Thread. So I had reverse threads and just applied the new thread (() -> {...}).Start(); in the main class in the start method and it's ok.

Trying to use a JavaFX connect4 game with a server for school

I have a leftover project from school that I could not get working as intended. The class had a Connect4 text game, then a GUI (using JavaFX), then a server-client for it.
My standalone GUI will go until the game is won by player, but it crashes at that point if green wins(Long error message but seems to end in IllegalArgumentException related to java's Parent class)
Also I don't know if it is plausible to do a JavaFX server interaction for this, or if I should scrap and do swing, but I really wanted to get this working for my peace of mind. Right now I am struggling with the idea of backend and GUI logic for winning, but it is the only design I could get working to this extent, poor design as it is...
Please let me know if more information is needed, I know this program is a mess as I have not done GUIs before and I am afraid to clean up the program before fixing it. The source file is long but the error seems to be related to an illegal argument exception with a Parent object.
#Override
public void start(Stage primaryStage)
{
GridPane rectangleRoot = new GridPane();
GridPane circleRoot = new GridPane();
makeCircleBoard(rectangleRoot, circleRoot, playerColor);
rectangleRoot.setAlignment(Pos.CENTER);
circleRoot.setAlignment(Pos.CENTER);
Scene scene = new Scene(rectangleRoot, 1000, 1000);
Rectangle gameBoardSpace = new Rectangle(scene.getWidth() / 2, scene.getHeight()
/2, Color.DARKBLUE);
rectangleRoot.getChildren().add(gameBoardSpace);
rectangleRoot.getChildren().add(circleRoot);
primaryStage.setTitle("Connect4");
primaryStage.setScene(scene);
primaryStage.show();
}
public GridPane makeCircleBoard(GridPane rectangleRoot, GridPane circleRoot, String colorPassed)
{
int rowPerCol[] = new int[7]; //for back end 2D array
int turn = 1; //game logic
for(int i = 0; i < ROWMAX; i++)
{
for(int j = 0; j < COLMAX; j++)
{
gridLayout[i][j] = ' ';
}
}
for(int row = 0; row < 6; row++)
{
for(int col = 0; col < 7; col++)
{
GameSlot newCircle = new GameSlot(30, Color.WHITE);
newCircle.setStrokeType(StrokeType.OUTSIDE);
newCircle.setStroke(Color.web("black", 1.0));
newCircle.setStrokeWidth(4);
newCircle.setLocationRow(row);
newCircle.setLocationCol(col);
newCircle.setOnMouseClicked(new EventHandler<MouseEvent>()
{
#Override
public void handle(MouseEvent e)
{
if(newCircle.getOccupied() == false)
{
if(playerColor.equals("Yellow"))
{
gridLayout[newCircle.getLocationRow()][newCircle.getLocationCol()] = 'Y';
playerColor = "Green";
newCircle.setFill(Color.YELLOW);
newCircle.setOccupiedTrue();
}
else
{
gridLayout[newCircle.getLocationRow()][newCircle.getLocationCol()] = 'G';
playerColor = "Yellow";
newCircle.setFill(Color.GREEN);
newCircle.setOccupiedTrue();
}
}
if(gameWon(gridLayout))
{
if(playerColor.equals("Green"))
{
final Text actiontarget = new Text();
actiontarget.setFill(Color.CRIMSON);;
actiontarget.setText("YELLOW WON!!!");
actiontarget.setScaleX(10);
actiontarget.setScaleY(10);
actiontarget.setTranslateX(rectangleRoot.getWidth() / 5);
rectangleRoot.getChildren().add(actiontarget);
}
else
{
final Text actiontarget = new Text();
actiontarget.setFill(Color.CRIMSON);;
actiontarget.setText("GREEN WON!!!");
rectangleRoot.getChildren().add(actiontarget);
actiontarget.setScaleX(10);
actiontarget.setScaleY(10);
actiontarget.setTranslateX(rectangleRoot.getWidth() / 5);
rectangleRoot.getChildren().add(actiontarget);
}
}
} //end handle()
});
//circle.setId(Integer.toString(i));
circleRoot.add(newCircle, row, col);
//newCircle.isWon(row, col);
}
}
The checks for Green and Yellow are the same. It checks the different directions for the color characters opposite of the color who is up next. I see no errors for Yellow in any win condition and they have the index checking in gridLayout2.
Exception in thread "JavaFX Application Thread"
java.lang.IllegalArgumentException: Children: duplicate children added: parent = Grid hgap=0.0, vgap=0.0, alignment=CENTER
at javafx.scene.Parent$2.onProposedChange(Parent.java:454)
at com.sun.javafx.collections.VetoableListDecorator.add(VetoableListDecorator.java:206)
at Connect4.ui.Connect4GUI$1.handle(Connect4GUI.java:128)
at Connect4.ui.Connect4GUI$1.handle(Connect4GUI.java:1)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$ClickGenerator.postProcess(Scene.java:3470)
at javafx.scene.Scene$ClickGenerator.access$8100(Scene.java:3398)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3766)
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:381)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$353(GlassViewEventHandler.java:417)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:416)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:937)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$147(WinApplication.java:177)
at java.lang.Thread.run(Thread.java:748)
The error you're getting is an IllegalArgumentException saying you are attempting to add a Node to the same Parent more than once—this is not allowed in JavaFX. If you look at the stack trace, you'll see where in your code this is happening.
java.lang.IllegalArgumentException: Children: duplicate children added: parent = Grid hgap=0.0, vgap=0.0, alignment=CENTER
at javafx.scene.Parent$2.onProposedChange(Parent.java:454)
at com.sun.javafx.collections.VetoableListDecorator.add(VetoableListDecorator.java:206)
at Connect4.ui.Connect4GUI$1.handle(Connect4GUI.java:128)
at Connect4.ui.Connect4GUI$1.handle(Connect4GUI.java:1)
The first frame that is not internal JavaFX code is Connect4.ui.Connect4GUI$1.handle(Connect4GUI.java:128) stating that the error is occurring on line 128 of your Connect4GUI class, inside a method named handle. You don't specify what line is line 128 but based on your code and the above information we know to focus on this part of your code:
newCircle.setOnMouseClicked(new EventHandler<MouseEvent>()
{
#Override
public void handle(MouseEvent e)
{
if(newCircle.getOccupied() == false)
{
if(playerColor.equals("Yellow"))
{
gridLayout[newCircle.getLocationRow()][newCircle.getLocationCol()] = 'Y';
playerColor = "Green";
newCircle.setFill(Color.YELLOW);
newCircle.setOccupiedTrue();
}
else
{
gridLayout[newCircle.getLocationRow()][newCircle.getLocationCol()] = 'G';
playerColor = "Yellow";
newCircle.setFill(Color.GREEN);
newCircle.setOccupiedTrue();
}
}
if(gameWon(gridLayout))
{
if(playerColor.equals("Green"))
{
final Text actiontarget = new Text();
actiontarget.setFill(Color.CRIMSON);;
actiontarget.setText("YELLOW WON!!!");
actiontarget.setScaleX(10);
actiontarget.setScaleY(10);
actiontarget.setTranslateX(rectangleRoot.getWidth() / 5);
rectangleRoot.getChildren().add(actiontarget);
}
else
{
final Text actiontarget = new Text();
actiontarget.setFill(Color.CRIMSON);;
actiontarget.setText("GREEN WON!!!");
rectangleRoot.getChildren().add(actiontarget);
actiontarget.setScaleX(10);
actiontarget.setScaleY(10);
actiontarget.setTranslateX(rectangleRoot.getWidth() / 5);
rectangleRoot.getChildren().add(actiontarget);
}
}
} //end handle()
});
Looking at the code, the issue can be located inside the else block that is within the if(gameWon(gridLayout)) block:
else
{
final Text actiontarget = new Text();
actiontarget.setFill(Color.CRIMSON);;
actiontarget.setText("GREEN WON!!!");
rectangleRoot.getChildren().add(actiontarget); // DUPLICATE LINE BELOW
actiontarget.setScaleX(10);
actiontarget.setScaleY(10);
actiontarget.setTranslateX(rectangleRoot.getWidth() / 5);
rectangleRoot.getChildren().add(actiontarget); // DUPLICATE: Must be line 128
}
Remove one of those statements and the code should no longer throw the IllegalArgumentException. Notice that the stack trace points you right at the offending line of code, by the way.

JavaFx Call another panel and transmits values

My program is structured package and control on the interface as follows
**+ Browser : BrowserController.class**
-#FXML
private SplitPane spHTMLParser;
#FXML
private TextField txtURL;
#FXML
private Button btnSearch;
#FXML
private WebView browser;
**+ Browser/Console : ConsoleController.class**
#FXML
private Label lblURL;
In the browser page when the user clicks the btnSearch,I will show webview site with user input url. When the process is complete I want to show the Console.fxml in Browser.fxml with SplitPane and When the console is displayed, I'd label can get value url . Please help me!
#FXML
void btnSearch(ActionEvent event) {
String url = txtURL.getText().trim();
if (!url.isEmpty()) {
WebEngine webEngine = browser.getEngine();
progressBar.progressProperty().bind(webEngine.getLoadWorker().progressProperty());
webEngine.load(url);
webEngine.getLoadWorker().stateProperty().addListener((ObservableValue<? extends Worker.State> observable, Worker.State oldValue, Worker.State newValue) -> {
switch (newValue) {
case SUCCEEDED:
if (count++ != 0) {
btnNext.setDisable(false);
}
btnBack.setDisable(false);
progressBar.setVisible(false);
{
try {
FXMLLoader fxmlLoader = new FXMLLoader();
Pane pnConsole = fxmlLoader.load(getClass().getResource("console/Console.fxml").openStream());
spHTMLParser.getItems().add(pnConsole);
spHTMLParser.setDividerPositions(0.5);
} catch (IOException ex) {
Logger.getLogger(BrowserController.class.getName()).log(Level.SEVERE, null, ex);
}
}
break;
}
});
}
}
Load events url successful work exactly but I got an error when trying to call the other pane via fxml
Its error messages with commands
Pane pnConsole = fxmlLoader.load(getClass().getResource("console/Console.fxml").openStream());
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
at publishers.controllers.resources.browser.BrowserController.lambda$webView$4(BrowserController.java:144)
at com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:182)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
at javafx.beans.property.ReadOnlyObjectPropertyBase.fireValueChangedEvent(ReadOnlyObjectPropertyBase.java:74)
at javafx.beans.property.ReadOnlyObjectWrapper.fireValueChangedEvent(ReadOnlyObjectWrapper.java:102)
at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:112)
at javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:146)
at javafx.scene.web.WebEngine$LoadWorker.updateState(WebEngine.java:1260)
at javafx.scene.web.WebEngine$LoadWorker.dispatchLoadEvent(WebEngine.java:1371)
at javafx.scene.web.WebEngine$LoadWorker.access$1200(WebEngine.java:1253)
at javafx.scene.web.WebEngine$PageLoadListener.dispatchLoadEvent(WebEngine.java:1240)
at com.sun.webkit.WebPage.fireLoadEvent(WebPage.java:2400)
at com.sun.webkit.WebPage.fwkFireLoadEvent(WebPage.java:2244)
at com.sun.webkit.network.URLLoader.twkDidFinishLoading(Native Method)
at com.sun.webkit.network.URLLoader.notifyDidFinishLoading(URLLoader.java:838)
at com.sun.webkit.network.URLLoader.lambda$didFinishLoading$96(URLLoader.java:829)
at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
at java.lang.Thread.run(Thread.java:745)

Moving marker in a Grid Pane

I have created a Grid Pane with a number of rows. A marker should only be moveable on 1 row. When moving the mouse it should move sideways only, left or right. When you click on the marker it should be locked, no more movement. It should be highlighted with a different color.
How can I achive this?
If you know any tutorials or examples please add, thanks.
Message Output:
Executing
C:\Users\s22380\Desktop\temp\JavaFXApplication9\dist\run269988000\JavaFXApplication9.jar
using platform C:\Program Files\Java\jdk1.8.0_92\jre/bin/java
Exception in Application constructor
java.lang.reflect.InvocationTargetException at
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498) at
com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
at
com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498) at
sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Unable to construct Application
instance: class javafxapplication9.JavaFXApplication9 at
com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:907)
at
com.sun.javafx.application.LauncherImpl.lambda$launchApplication$155(LauncherImpl.java:182)
at java.lang.Thread.run(Thread.java:745) Caused by:
java.lang.reflect.InvocationTargetException at
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at
com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$161(LauncherImpl.java:819)
at
com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)
at
com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method) at
com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
at
com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method) at
com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
... 1 more Caused by: java.lang.NullPointerException at
sample.Controller.(Controller.java:33) at
javafxapplication9.JavaFXApplication9.(JavaFXApplication9.java:19)
... 13 more Exception running application
javafxapplication9.JavaFXApplication9 Java Result: 1 Deleting
directory
C:\Users\s22380\Desktop\temp\JavaFXApplication9\dist\run269988000
jfxsa-run: BUILD SUCCESSFUL (total time: 1 second)
How about this: 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
{
Controller controller = new Controller(10,10);
#Override
public void start(Stage primaryStage) throws Exception{
FXMLLoader loader = new FXMLLoader(getClass().getResource("sample.fxml"));
loader.setController(this.controller);
Parent root = (Parent)loader.load();
this.controller.InitUi();
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 300, 275));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
This is basically the sample code when you say new JavaFX project in IntelliJ. I changed it to explicitly set the controller. But that is just personal preference.
The xaml for that
<?import javafx.scene.layout.*?>
<GridPane fx:id="mainGrid" alignment="center" gridLinesVisible="true" hgap="10" vgap="10" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
</children>
</GridPane>
Again. Basically the default stuff.
I also added a style sheet to define the different lock for the not movable state.
redStyle.css
.button {
-fx-text-fill: #006464;
-fx-background-color: #DFB951;
-fx-border-radius: 20;
-fx-background-radius: 20;
-fx-padding: 5;
}
Now for the controller.
It will do a few things:
Listen to the mouse events of the object I want to push around. If the delata is big enough I will move it => if the mouse is moved fast enough
When the button is pressed I will switch out the style sheet to get the different look. Right now this style works on all buttons in the scene. It could be changed to work only on a specific one.
package sample;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.RowConstraints;
import javafx.scene.shape.Rectangle;
public class Controller
{
#FXML
private GridPane mainGrid;
#FXML
private Button movable;
private final int sizeX;
private final int sizeY;
private final double minMoveDistanc = 3;
private boolean canMove = true;
private Double lastX = null;
private Double lastY = null;
private String redButtonStyle = Controller.class.getResource("redStyle.css").toExternalForm();
public Controller(int sizeX, int sizeY)
{
this.sizeX = sizeX;
this.sizeY = sizeY;
}
public void InitUi()
{
if (this.mainGrid != null)
{
final int numCols = sizeX;
final int numRows = sizeY;
for (int i = 0; i < numCols; i++)
{
ColumnConstraints colConst = new ColumnConstraints();
this.mainGrid.getColumnConstraints().add(colConst);
}
for (int i = 0; i < numRows; i++)
{
RowConstraints rowConst = new RowConstraints();
this.mainGrid.getRowConstraints().add(rowConst);
}
// add rectangle to keep grid in size
for (int i = 0; i < numCols; i++)
{
for (int j = 0; j < numRows; j++)
{
Rectangle rect = new Rectangle();
rect.setWidth(50);
rect.setHeight(50);
this.mainGrid.add(rect,i,j);
}
}
// ad movable object (Button)
this.movable = new Button("Hallo");
this.movable.setPrefWidth(50);
this.movable.setPrefHeight(50);
this.movable.setOnAction(new EventHandler<ActionEvent>()
{
#Override
public void handle(ActionEvent actionEvent)
{
canMove = ! canMove;
movable.setText(canMove? "move" : "stop");
if (canMove)
{
movable.getScene().getStylesheets().remove(redButtonStyle);
}
else
{
movable.getScene().getStylesheets().add(redButtonStyle);
}
}
});
this.mainGrid.add(this.movable,5,5);
}
if (this.movable != null)
{
this.movable.setOnMouseEntered(new EventHandler<MouseEvent>()
{
#Override
public void handle(MouseEvent mouseEvent)
{
lastX = null;
lastY = null;
}
});
this.movable.setOnMouseExited(new EventHandler<MouseEvent>()
{
#Override
public void handle(MouseEvent mouseEvent)
{
lastX = null;
lastY = null;
}
});
this.movable.setOnMouseMoved(new EventHandler<MouseEvent>()
{
#Override
public void handle(MouseEvent mouseEvent)
{
if (!canMove)
{ return; }
double x = mouseEvent.getSceneX();
double y = mouseEvent.getSceneY();
if (lastX == null)
{
lastX = x;
lastY = y;
return;
}
// calculate delta
double deltaX = x - lastX;
double deltaY = y - lastY;
// remember new position
lastX = x;
lastY = y;
boolean moved = false;
// x movement
if (Math.abs(deltaX) > minMoveDistanc)
{
moved = true;
int currentColumn = GridPane.getColumnIndex(movable);
if (deltaX < 0)
{
GridPane.setColumnIndex(movable, Math.max(currentColumn -1 ,0));
}
else
{
GridPane.setColumnIndex(movable, Math.min(currentColumn + 1 ,sizeX-1));
}
}
// y movement
if (Math.abs(deltaY) > minMoveDistanc)
{
moved = true;
int currentRow = GridPane.getRowIndex(movable);
if (deltaY < 0)
{
GridPane.setRowIndex(movable, Math.max(currentRow - 1 ,0));
}
else
{
GridPane.setRowIndex(movable, Math.min(currentRow + 1 ,sizeY-1));
}
}
if (moved)
{
lastX = null;
lastY = null;
}
}
});
}
}
}

Resources