I have a fontawesomeicon. If I press the button btStart a red circle should flash on the Fontawesomeicon (see GIF). If I press the button btStop it should be disabled.
I tried it with a label.
When I press the button btStart, the label changes in a time interval with SetVisible(true) and setVisible(false).
Can someone offer me a solution? Thank you in advance.
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{
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Controller.java
package sample;
import de.jensd.fx.glyphs.fontawesome.FontAwesomeIconView;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import java.awt.*;
public class Controller {
#FXML
private FontAwesomeIconView iconCamera;
#FXML
private Button btStart;
#FXML
private Button btStop;
#FXML
void mouseCklicked(ActionEvent event) {
System.out.println("sad");
}
}
sample.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import de.jensd.fx.glyphs.fontawesome.FontAwesomeIconView?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<GridPane alignment="center" hgap="10" vgap="10" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.141" fx:controller="sample.Controller">
<columnConstraints>
<ColumnConstraints />
</columnConstraints>
<rowConstraints>
<RowConstraints />
</rowConstraints>
<children>
<AnchorPane prefHeight="387.0" prefWidth="573.0">
<children>
<FontAwesomeIconView fx:id="iconCamera" glyphName="VIDEO_CAMERA" layoutX="130.0" layoutY="123.0" size="36" />
<Button layoutX="253.0" layoutY="93.0" mnemonicParsing="false" onAction="#mouseCklicked" text="Start" />
<Button layoutX="354.0" layoutY="93.0" mnemonicParsing="false" text="Stop" />
</children>
</AnchorPane>
</children>
</GridPane>
Create an Image (PNG) without the red dot.
Create a GIF with the red dot blinking effect.
Import both images in to your project.
On pressing the start set the image to *.GIF.
On pressing stop set the image to *.PNG.
Simple. Don't make things complicated!
Related
I want to select a picture on the HDD with the help of JFileChooser and display it in the GUI. The problem is that I can't set the selected image to the ImageView. I think I'm doing something completely wrong but I also tried various other ways to display it for example with BufferedImage but nothing worked for me. I don't get behind this, please help me.
Controller:
package application;
import java.io.File;
import java.net.MalformedURLException;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileSystemView;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.image.ImageView;
public class WindowController {
#FXML private Button btn_load;
#FXML private TextField text_path;
#FXML private ImageView img_frame;
public Main main;
public void setMain(Main main) {
this.main = main;
}
#FXML
public void handle_load() throws MalformedURLException{
JFileChooser chooser = new JFileChooser(FileSystemView.getFileSystemView().getHomeDirectory());
int returnValue = chooser.showOpenDialog(null);
if (returnValue == JFileChooser.APPROVE_OPTION) {
text_path.setText(chooser.getSelectedFile().getAbsolutePath());
File file = new File(chooser.getSelectedFile().getAbsolutePath());
String localURL = file.toURI().toURL().toString();
img_frame.setImage(localURL);
}
}
}
And the fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.image.*?>
<?import javafx.scene.text.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane prefHeight="700.0" prefWidth="900.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.WindowController">
<children>
<ImageView fx:id="img_frame" fitHeight="516.0" fitWidth="627.0" layoutX="142.0" layoutY="114.0" pickOnBounds="true" preserveRatio="true" AnchorPane.bottomAnchor="97.0" AnchorPane.leftAnchor="142.0" AnchorPane.rightAnchor="142.0" AnchorPane.topAnchor="114.0" />
<HBox layoutX="14.0" layoutY="14.0" prefHeight="25.0" prefWidth="885.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="12.0">
<children>
<Button fx:id="btn_load" mnemonicParsing="false" onAction="#handle_load" text="Load Image" HBox.hgrow="NEVER" />
<TextField fx:id="text_path" prefHeight="25.0" prefWidth="0.0" HBox.hgrow="SOMETIMES" />
</children>
</HBox>
</children>
</AnchorPane>
instead of adding it to a url, just add
img_view.setImage(new Image(url));
It will fix your problem
I've developed an application using JavaFX that, in part, uses a WebView. However, I've noticed that when either by the user or programmatically via JS, the WebView is scrolled to the bottom or just near the bottom, strange things seem to happen. I am specifically hoping for some way to stop this behavior, and still need to allow scrolling in both senses. It's similar to this question but they are not the same. The rest of my post explains what is happening.
If you scroll to the bottom and resize the window to be larger than previously and hover over other JavaFX controls in the window, they become white boxes.
To illustrate, suppose you have the following window:
Scroll to the bottom and resize the window to be larger than previously and then hover over the JavaFX button and TextBox, who both disappear when you do so:
This happens on at least Windows 10 with Java8u111 and Java8u51. I've made an example to demonstrate this:
example.Main.java
package example;
import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws IOException {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("Example.fxml"));
BorderPane rootWindow = (BorderPane) loader.load();
Scene scene = new Scene(rootWindow);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
example.ExampleController.java
package example;
import javafx.concurrent.Worker;
import javafx.fxml.FXML;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
public class ExampleController {
#FXML private WebView webView;
#FXML
private void initialize() {
WebEngine engine = webView.getEngine();
engine.load("https://stackoverflow.com");
engine.getLoadWorker().stateProperty().addListener( (o, oldVal, newVal) -> {
if (newVal == Worker.State.SUCCEEDED) {
engine.executeScript("window.scrollTo(0, document.body.scrollHeight);");
}
});
}
}
example.Example.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.web.WebView?>
<BorderPane prefHeight="400.0" prefWidth="500.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.111" fx:controller="example.ExampleController">
<center>
<WebView fx:id="webView" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<BorderPane.margin>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</BorderPane.margin>
</WebView>
</center>
<bottom>
<HBox BorderPane.alignment="CENTER">
<children>
<TextField HBox.hgrow="ALWAYS" />
<Button alignment="TOP_LEFT" mnemonicParsing="false" text="Button" />
</children>
</HBox>
</bottom>
</BorderPane>
Is there a way I can stop this from happening or at least mitigate it?
I also encountered the same problem, and I found a solution:
Add a parameter to jvm:-Dprism.order=sw
see:https://news.kynosarges.org/2016/04/09/javafx-and-java_tool_options/?tdsourcetag=s_pctim_aiomsg
How do i center this image horizontally? I've tried putting in a HBox like so, however it does not work...
<HBox alignment="CENTER">
<ImageView fitWidth="300" preserveRatio="true">
<image>
<Image url="#Logo.png"/>
</image>
</ImageView>
</HBox>
Here a little MCVE with a FXML file:
Application:
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
/**
*
* #author Naoghuman
*/
public class CenterImageInHBox extends Application {
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
FXML file:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.image.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="center.image.in.hbox.FXMLDocumentController">
<children>
<VBox layoutX="60.0" prefHeight="200.0" prefWidth="100.0" spacing="7.0" style="-fx-background-color: YELLOWGREEN;" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0">
<children>
<ToolBar prefHeight="40.0" prefWidth="200.0">
<items>
<Button mnemonicParsing="false" onAction="#onActionLeft" text="Left" />
<Button mnemonicParsing="false" onAction="#onActionCenter" text="Center" />
<Button mnemonicParsing="false" onAction="#onActionRight" text="Right" />
</items>
</ToolBar>
<HBox fx:id="hbImage" alignment="TOP_CENTER" VBox.vgrow="ALWAYS">
<children>
<ImageView fx:id="ivImage" fitHeight="128.0" fitWidth="128.0" pickOnBounds="true" preserveRatio="true" />
</children>
</HBox>
</children>
</VBox>
</children>
</AnchorPane>
and the Controller:
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.geometry.Pos;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
/**
*
* #author Naoghuman
*/
public class FXMLDocumentController implements Initializable {
#FXML private HBox hbImage;
#FXML private ImageView ivImage;
#Override
public void initialize(URL url, ResourceBundle rb) {
Image img = new Image("http://icons.iconarchive.com/icons/evermor-design/galaxian/128/Movie-Clip-icon.png");
ivImage.setImage(img);
}
public void onActionCenter() {
hbImage.setAlignment(Pos.TOP_CENTER);
}
public void onActionLeft() {
hbImage.setAlignment(Pos.TOP_LEFT);
}
public void onActionRight() {
hbImage.setAlignment(Pos.TOP_RIGHT);
}
}
When you click on the buttons in the application then you will see that the image is aligned left, center or right depends from your the choosen action.
Well, my question is simple.
I am building an application with Java Fx, and I have a TabPane.
When I open a new Tab, that Tab gets it's content by a fxml file.
tab.setContent((Node)FXMLLoader.load(this.getClass().getResource("/main/textEditor.fxml")))
Fine, that works well, it always loads the same file on all Tabs, so, all textarea on all tabs have the same id.
The problem is, with java, I can only get the information of the textarea of the first Tab.
How can i edit specifically the textarea of one tab in particular?
An example of what i want to do :
Main
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Rectangle2D;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Screen;
import javafx.stage.Stage;
public class Main extends Application{
public static void main(String[] args) {
Application.launch(Main.class, args);
}
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("/tabPane/test.fxml"));
Screen screen = Screen.getPrimary();
Rectangle2D bounds = screen.getVisualBounds();
stage.setScene(new Scene(root));
stage.show();
}
}
test.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.net.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<?import javafx.scene.layout.AnchorPane?>
<VBox prefHeight="400.0" prefWidth="640.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="tabPane.controller">
<children>
<MenuBar VBox.vgrow="NEVER">
<menus>
<Menu mnemonicParsing="false" onAction="#test" text="File">
<items>
<MenuItem fx:id="insert" mnemonicParsing="false" onAction="#test" text="Insert" />
</items>
</Menu>
</menus>
</MenuBar>
<AnchorPane maxHeight="-1.0" maxWidth="-1.0" prefHeight="-1.0" prefWidth="-1.0" VBox.vgrow="ALWAYS">
<children>
<Label alignment="CENTER" layoutX="155.0" layoutY="177.0" style="
" text="Drag components from Library here…" textAlignment="CENTER" textFill="#9f9f9f" wrapText="false">
<font>
<Font size="18.0" />
</font>
</Label>
<TabPane fx:id="tabPane" prefHeight="375.0" prefWidth="640.0" tabClosingPolicy="UNAVAILABLE">
<tabs>
<Tab text="Untitled Tab 1">
<content>
<TextArea fx:id="textarea" prefHeight="200.0" prefWidth="200.0" text="a" />
</content>
</Tab>
<Tab text="Untitled Tab 2">
<content>
<TextArea fx:id="textarea1" prefHeight="200.0" prefWidth="200.0" text="a" />
</content>
</Tab>
</tabs>
</TabPane>
</children>
</AnchorPane>
</children>
<stylesheets>
<URL value="#../../../../BasicApplicatio11n_css/BasicApplication.css" />
controller.java
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TextArea;
public class controller implements Initializable{
#FXML
private TextArea textarea;
#Override
public void initialize(URL arg0, ResourceBundle arg1) {
}
public void test(ActionEvent event){
textarea.appendText("Text");
}
}
There are two tabs on this example, when the button is pressed, I want to add the text on the current selected tab.
There are a few different ways to do this. One way is to let the controller for the tab content expose the textProperty from the text area. Then in your "main controller", create a StringProperty field. When you create a new tab, just observe its selected property and update the string property field to point to the one from the current controller. Then you can easily load text into the "current" pane.
Here's a simple example of this:
EditorController:
import javafx.beans.property.StringProperty;
import javafx.fxml.FXML;
import javafx.scene.control.TextArea;
public class EditorController {
#FXML
private TextArea textArea ;
public StringProperty textProperty() {
return textArea.textProperty() ;
}
}
with textEditor.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.control.TextArea?>
<BorderPane xmlns:fx="http://javafx.com/fxml/1" fx:controller="EditorController">
<center>
<TextArea fx:id="textArea"/>
</center>
</BorderPane>
And then the MainController could look like:
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import javafx.beans.property.StringProperty;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.stage.FileChooser;
public class MainController {
#FXML
private TabPane tabPane ;
private StringProperty currentText ;
public void initialize() throws IOException {
// load an initial tab:
newTab();
}
#FXML
private void newTab() throws IOException {
Tab tab = new Tab("Untitled text");
FXMLLoader loader = new FXMLLoader(getClass().getResource("textEditor.fxml"));
tab.setContent(loader.load());
EditorController controller = loader.getController() ;
tab.selectedProperty().addListener((obs, wasSelected, isNowSelected) -> {
if (isNowSelected) {
currentText = controller.textProperty();
}
});
tabPane.getTabs().add(tab);
tabPane.getSelectionModel().select(tab);
}
#FXML
private void load() {
FileChooser chooser = new FileChooser();
File file = chooser.showOpenDialog(tabPane.getScene().getWindow());
if (file != null) {
Path path = file.toPath();
try {
currentText.set(String.join("\n", Files.readAllLines(path)));
} catch (IOException e) {
Alert alert = new Alert(AlertType.ERROR);
alert.setContentText("Unable to load file "+path);
alert.setTitle("Load error");
alert.showAndWait();
}
tabPane.getSelectionModel().getSelectedItem().setText(path.getFileName().toString());
}
}
}
with main.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.control.Button?>
<?import javafx.geometry.Insets?>
<BorderPane xmlns:fx="http://javafx.com/fxml/1" fx:controller="MainController">
<center>
<TabPane fx:id="tabPane"/>
</center>
<bottom>
<HBox alignment="CENTER" spacing="5">
<padding>
<Insets top="5" right="5" left="5" bottom="5" />
</padding>
<Button text="Load..." onAction="#load" />
<Button text="New" onAction="#newTab"/>
</HBox>
</bottom>
</BorderPane>
For completeness, a simple application class:
import java.io.IOException;
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 IOException {
Parent root = FXMLLoader.load(getClass().getResource("main.fxml"));
Scene scene = new Scene(root, 800, 800);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
There are other approaches, e.g. you could just change the button's onAction property when the tab selection changes, etc.
I have this controller:
package cz.vutbr.feec.bmds.cv2;
import java.awt.Button;
import java.awt.TextField;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Slider;
public class TestGuiController {
private int buttonPressed = 0;
#FXML
private Button tlacitko;
#FXML
private TextField textovePole;
#FXML
private Slider slider;
public void buttonPressed(ActionEvent e) {
buttonPressed++;
textovePole.setText(Integer.toString(buttonPressed));
}
}
this fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.BorderPane?>
<AnchorPane prefHeight="200.0" prefWidth="200.0" xmlns:fx="http://javafx.com/fxml" fx:controller="cz.vutbr.feec.bmds.cv2.TestGuiController">
<children>
<Button fx:id="tlacitko" layoutX="30.0" layoutY="40.0" mnemonicParsing="false" onTouchPressed="#buttonPressed" text="Button" />
<Slider fx:id="slider" layoutX="157.0" layoutY="17.0" orientation="VERTICAL" />
<TextField fx:id="textovePole" layoutX="14.0" layoutY="89.0" prefWidth="134.0" />
</children>
</AnchorPane>
and this is my main class:
package cz.vutbr.feec.bmds.cv2;
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("TestGui.fxml"));
primaryStage.setTitle("Titulek");
primaryStage.setScene(new Scene(root,300,275));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
When I run this through ant I get message box with error (exception during running application). I tried simple fxml without controller and it works so I am guesing I do something wrong with controller. What I must change to have it working?
I must answer my own question. Problem was in TestGuiController where I used java.awt.Button and java.awt.TextField instead of javafx.scene.control.Button and javafx.scene.control.TextField.
I'm not 100% sure but try:
in FXML: Button: onAction instead of onTouchPressed
Please provide the exact Exception message.