How to show Image as tooltip in JavaFX? - java

I would like to show an image as a tooltip. It works OK but at some random points it shows fluctuation. I want to show it normally without getting fluctuate.
I show a new scene (in which i added my image-view with image) on mouse enter event and close it on mouse leave event event
// MOUSE ENTER PHOTO CORRECTIO
#FXML
private void mouseEnterPhotoCorrection(MouseEvent event) {
if (f_ShowToolTip) {
Stage stg = funShowImageTooltip();
double x, y;
x = event.getScreenX();
y = event.getScreenY();
stg.setX(x);
stg.setY(y);
stg.show();
f_ShowToolTip = false;
}
}
// MOUSE LEAVE PHOTO CORRECTIO
#FXML
private void mouseLeavePhotoCorrection(MouseEvent event) {
funHideImageTooltip();
f_ShowToolTip = true;
}
/****************************** FUNCTIONS *******************************/
Stage s;
boolean f_ShowToolTip;
// FUNCTION TO SET INITAL STATE OF PHOTOS AND CORRECTION
private void funInitPhotosCorrection()
{
f_ShowToolTip = true;
}
private Stage funShowImageTooltip()
{
try {
s = new Stage();
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("frmImageToolTip.fxml"));
Parent root = (Parent) fxmlLoader.load();
Scene scene = new Scene(root);
s.setScene(scene);
s.setResizable(false);
s.initModality(Modality.WINDOW_MODAL);
s.initStyle(StageStyle.UNDECORATED);
s.setResizable(false);
double x, y;
//x = btn_Red.
s.show();
}catch(Exception e1)
{
}
return s;
}
private void funHideImageTooltip()
{
try {
s.close();
} catch (Exception e) {
}
}

If you just simply want to have a tooltip over a Node (a Button in your case), it is reasonable to use a Tooltip and its graphicProperty rather than showing a different Stage.
// Load the image with the needed size
Image image = new Image("...", 150, 150, true, true);
// Place it over a Button
Button button = new Button();
Tooltip tooltip = new Tooltip();
tooltip.setGraphic(new ImageView(image));
button.setTooltip(tooltip);

Related

javafx reopen minimized window via stage(?) method

SO, I have a JavaFX application with an already implemented Tray that needs 1 option to reopen the window/stage minimized by this GuiController function, which is called by the fxml:
`public void minimizeImageViewClick(MouseEvent mouseEvent) {
if (mouseEvent.getSource() == minimizeImageView) {
stage = (Stage) ((ImageView) mouseEvent.getSource()).getScene().getWindow();
stage.setIconified(true);
}
if(mouseEvent.getSource() == minimizePane){
stage = (Stage) ((Pane) mouseEvent.getSource()).getScene().getWindow();
stage.setIconified(true);
}
}`
There is also one to maximize, implemented by the same means:
public void maximizeImageViewClick(MouseEvent mouseEvent) {
if (mouseEvent.getSource() == maximizeImageView) {
if (ExamAlertStateController.getInstance().getWindowSizeState() == WindowSizeState.INIT) {
stage = (Stage) ((ImageView) mouseEvent.getSource()).getScene().getWindow();
stage.setMaximized(true);
update();
ExamAlertStateController.getInstance().setWindowSizeState(WindowSizeState.MAXIMIZED);
} else {
stage = (Stage) ((ImageView) mouseEvent.getSource()).getScene().getWindow();
stage.setMaximized(false);
update();
ExamAlertStateController.getInstance().setWindowSizeState(WindowSizeState.INIT);
}
}
}`
A piece of the Tray, with the Open (Abrir) option I need to implement and another which only change the screen and the state, as all the other after that:
# SpringBootApplication
public class Application {
//private final MenuItem menuItemSelectedFile;
//Stage stage;
private SystemTray systemTray;
public static final URL MULTI_LOGO = Application.class.getResource("source.png");
private Timer evaluatorTimer;
public static void main(String[] args) {
* code *
}
public Application() {
Log.i(this.getClass().getName(),"Text");
SystemTray.FORCE_GTK2=true;
SystemTray.DEBUG = true;
CacheUtil.clear();
this.systemTray = SystemTray.get();
if (systemTray == null) {
throw new RuntimeException("text!");
}
systemTray.setTooltip("text");
systemTray.setImage(MULTI_LOGO);
systemTray.setStatus("TEXT");
Menu mainMenu = systemTray.getMenu();
MenuItem openMenuItem = new MenuItem("Abrir", new ActionListener() {
#Override
public void actionPerformed(final ActionEvent e) {
}
});
openMenuItem.setTooltip("Abrir programa");
mainMenu.add(openMenuItem);
mainMenu.add(new Separator());
MenuItem loginMenuItem = new MenuItem("Login", new ActionListener() {
#Override
public void actionPerformed(final ActionEvent e) {
ExamAlertStateController.getInstance().setWindowState(WindowState.LOGIN);
}
});
loginMenuItem.setTooltip("Login Text");
mainMenu.add(loginMenuItem);
mainMenu.add(new Separator());
The stage creation in the View file:
public class eaView extends Application {
private static final long ONE_SECOND = 1000;
private static double xOffset = 0;
private static double yOffset = 0;
private boolean ignore;
private Timer updaterTimer;
#Override
public void start(Stage stage) throws Exception {
FXMLLoader loader = new FXMLLoader();
URL urlLoadingScreen = getClass().getResource("/fxml/source.fxml");
loader.setLocation(urlLoadingScreen);
GridPane gridLoadingScreen = loader.load();
Scene scene = new Scene(gridLoadingScreen);
stage.initStyle(StageStyle.UTILITY);
stage.setOpacity(0);
stage.setHeight(0);
stage.setWidth(0);
stage.show();
Stage mainStage = new Stage();
//stage.setResizable(false);
//mainStage.setResizable(false);
mainStage.initOwner(stage);
mainStage.initStyle(StageStyle.UNDECORATED);
mainStage.setScene(scene);
mainStage.show();
So, I wasn't able to to call the maximizeImageViewClick function to it - I can by making it static, but it calls an update() method which contains a lot of FXML objects which cannot be altered, couldn't found the proper stage way of doing it (the attempts:
stage.setScene(scene);
stage.setMaxHeight(0);
stage.setMaxWidth(0);
stage.setOpacity(0);
stage.setIconified(true);
//ExamAlertView.
System.out.println("foi");
//ExamAlertView.
//System.out.println(stage.getProperties());
stage.show();
//if (ExamAlertStateController.getInstance().getWindowSizeState() == WindowSizeState.INIT) {
//stage = (Stage) ((ImageView) e.getSource()).getScene().getWindow();
//stage.setIconified(false);
//stage.setMaximized(true);
//stage.show();
//ImageView
//ExamAlertGuiController.setMinimizeImageView(ExamAlertGuiController.maximizeImageView);
System.out.println("foi2");
//ExamAlertGuiController.update();
ExamAlertStateController.getInstance().setWindowSizeState(WindowSizeState.MAXIMIZED);
/* } else {
stage = (Stage) ((ImageView) e.getSource()).getScene().getWindow();
stage.setMaximized(false);
stage.setIconified(false);
//ExamAlertGuiController.update();
ExamAlertStateController.getInstance().setWindowSizeState(WindowSizeState.INIT);
}*/
//System.out.println(stage.isIconified());
) which was only possible by making
public static Stage stage;
public static Scene scene;
in the GuiController file.
Really out of ideas here. Already did read the javafx.stage class the best I could.
Maybe I'm trying to access the wrong stage - stage UTILITY to remove taskbar button, mainStage UNDECORATED is the real deal, yet can't reach it - but I dont know....
How do I do this?
Thanks in advance.

Open every window only once

I have a chart. A double click on a table row opens a window in which I can edit the information of the row. Double-clicking on another line opens the corresponding window. Everything works as it should, except that each window should open only once. If it is already open, the window should return to the foreground. Unfortunately I can't see what's wrong here and would be grateful for a hint
private void loadTable() {
// I omitted the part where the table is populated.
mytable.setOnMousePressed(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
if (event.isPrimaryButtonDown() && event.getClickCount() == 2) {
TableItem table_item = table_view.getSelectionModel().getSelectedItem();
try {
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(getClass().getResource("/application/Popup.fxml"));
Scene scene = new Scene(fxmlLoader.load());
Stage stage = new Stage();
stage.setScene(scene);
MyController controller = fxmlLoader.<MyController>getController();
boolean result = controller.init(stage, table_item);
if (stage.isShowing()) {
stage.toFront();
System.out.println("Show this popup.");
} else {
if (result) {
stage.show();
System.out.println("Open this popup.");
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
}
Try adding
stage.initModality(Modality.WINDOW_MODAL);
after
Stage stage = new Stage();
This will make the Parent stage unclickable until this stage is closed.

How to change the position of a RadioButton's label?

By default RadioButtons have their text label to the right of the button. I want the label to appear below the button instead. I found an old discussion on the Oracle forums but the solutions aren't great or just don't work.
I can create a custom component with a text-less radio button and a separate text label and position them as in a VBox. But then only the button itself responds to user events and not the whole thing.
Is there no simple way to reposition the label?
There is no "simple" way to do this (simple means setting a single property or something like this).
As a workaround you could do something like you mentioned with a VBox, but with a Label: You can set the RadioButton as the graphic of the Label and set the contentDisplayProperty to TOP (RadioButton is placed on top of the Label). And then you can add an event handler on the Label to select the RadioButton on click.
An example with this approach
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
try {
BorderPane root = new BorderPane();
Scene scene = new Scene(root, 400, 400);
HBox hbox = new HBox();
hbox.getChildren().add(createRadioLabel("Radio on the left", ContentDisplay.LEFT));
hbox.getChildren().add(createRadioLabel("Radio on the top", ContentDisplay.TOP));
hbox.getChildren().add(createRadioLabel("Radio on the bottom", ContentDisplay.BOTTOM));
hbox.getChildren().add(createRadioLabel("Radio on the right", ContentDisplay.RIGHT));
hbox.setSpacing(30);
root.setCenter(hbox);
primaryStage.setScene(scene);
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
private Label createRadioLabel(String text, ContentDisplay cd) {
Label label = new Label(text);
label.setGraphic(new RadioButton());
label.setContentDisplay(cd);
label.addEventHandler(MouseEvent.MOUSE_CLICKED, e -> {
RadioButton radioButton = (RadioButton) ((Label) e.getSource()).getGraphic();
radioButton.requestFocus();
radioButton.setSelected(!radioButton.isSelected());
});
return label;
}
public static void main(String[] args) {
launch(args);
}
}
And the produced RadioButtons:
Alternatively, if you want to have the text of the RadioButton rotated around the dot, you can use CSS rotations, with the attribute -fx-rotate:
.radio-button { -fx-rotate:180; }
.radio-button > .text { -fx-rotate: 180; }
The first selector will rotate the whole RadioButton, so as result the text will be placed on the left side of the "dot", upside down. The second selector rotates the text back to the normal direction.
Example
This example shows a RadioButton whose Text can be placed to any side of the "dot" specified by a ComboBox selection.
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
try {
BorderPane root = new BorderPane();
Scene scene = new Scene(root, 400, 400);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
RadioButton rb = new RadioButton("In all directions);
ComboBox<PseudoClass> combo = new ComboBox<>();
combo.getItems().addAll(PseudoClass.getPseudoClass("left"),
PseudoClass.getPseudoClass("top"),
PseudoClass.getPseudoClass("right"),
PseudoClass.getPseudoClass("bottom"));
combo.valueProperty().addListener((obs, oldVal, newVal) -> {
if (oldVal != null)
rb.pseudoClassStateChanged(oldVal, false);
rb.pseudoClassStateChanged(newVal, true);
});
root.setTop(combo);
root.setCenter(rb);
primaryStage.setScene(scene);
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
application.css
.radio-button:left > .text { -fx-rotate: 180; }
.radio-button:left { -fx-rotate:180; }
.radio-button:right > .text { -fx-rotate: 0; }
.radio-button:right { -fx-rotate:0; }
.radio-button:top > .text { -fx-rotate: 0; }
.radio-button:top { -fx-rotate:-90; }
.radio-button:bottom > .text { -fx-rotate: 0; }
.radio-button:bottom { -fx-rotate:90; }
And the displayed RadioButton:

How do you call graphics class from main class in JavaFX?

I'm a really new programmer so idk if this question sounds really stupid but..
This is my main:
package culminating;
import javafx.application.Application;
& all other necessary imports...
public class CulminatingMAIN extends Application {
//Set Global variables
int count = 0;
String name;
String gender = "Boy";
Label testLabel = new Label(gender + " has been selected");
#Override
public void start(Stage primaryStage) throws Exception {
/**
* ************************ SCENE 1 WORK *************************
*/
TextField nameTextField = new TextField();
nameTextField.setMaxWidth(100);
Label nameLabel = new Label("Please enter your name.");
Label genderLabel = new Label();
Label titleLabel = new Label("Math Adventure!");
titleLabel.setFont(Font.font("Arial", FontWeight.BOLD, 30));
Rectangle titleRectangle = new Rectangle();
titleRectangle.setFill(Color.TOMATO);
titleRectangle.setWidth(280);
titleRectangle.setHeight(60);
titleRectangle.setStroke(Color.BLACK);
titleRectangle.setStrokeWidth(2.0);
StackPane root = new StackPane(titleRectangle, titleLabel);
//Set VBox properties
VBox vbox1 = new VBox(25);
vbox1.setAlignment(Pos.TOP_CENTER);
vbox1.setPadding(new Insets(60, 0, 0, 0));
vbox1.setStyle("-fx-background-color: lightskyblue");
HBox genderBtnBox = new HBox(25);
genderBtnBox.setAlignment(Pos.CENTER);
//Set Scene 1 buttons
Button enterNameBtn = new Button("Enter");
Button goToScene2Btn = new Button("Continue");
//Set Radio Button functionality here
final ToggleGroup genderGroup = new ToggleGroup();
RadioButton rb1 = new RadioButton("Boy");
rb1.setToggleGroup(genderGroup);
rb1.setUserData("Boy");
rb1.setSelected(true);
RadioButton rb2 = new RadioButton("Girl");
rb2.setToggleGroup(genderGroup);
rb2.setUserData("Girl");
//Add panes, labels and buttons to the VBox
vbox1.getChildren().addAll(root, nameLabel, nameTextField, enterNameBtn, genderLabel, genderBtnBox);
Scene scene = new Scene(vbox1, 500, 500);
primaryStage.setScene(scene);
primaryStage.setTitle("Culminating Project");
primaryStage.show();
/**
* ************************ SCENE 2 WORK *************************
*/
//THIS IS ROUGH WORK SO FAR
//Here, testing out new scene to see that it loads properly (and it does)
Circle testCircle = new Circle();
testCircle.setRadius(30);
testCircle.setFill(Color.YELLOW);
StackPane testPane = new StackPane(testCircle, testLabel);
Scene scene2 = new Scene(testPane, 500, 500);
/**
* ************************ EVENTS *************************
*/
//Stores user-entered name and prompts for user gender. Adds Continue button
enterNameBtn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
if ((count < 1) && (!nameTextField.getText().isEmpty())) {
name = nameTextField.getText();
genderLabel.setText("Hi " + name + "! Please select whether you are a boy or girl.");
genderBtnBox.getChildren().addAll(rb1, rb2);
vbox1.getChildren().add(goToScene2Btn);
count++;
}
}
});
//When pressed, changes the scene so that scene 2 is set instead
goToScene2Btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
primaryStage.setScene(scene2);
}
});
//Radio button selection is stored in gender variable
genderGroup.selectedToggleProperty().addListener(new ChangeListener<Toggle>() {
#Override
public void changed(ObservableValue<? extends Toggle> ov,
Toggle old_toggle, Toggle new_toggle) {
if (genderGroup.getSelectedToggle() != null) {
gender = genderGroup.getSelectedToggle().getUserData().toString();
testLabel.setText(gender + " has been selected");
}
}
});
if (gender.equals("boy")){
{
}
}
else if (gender.equals("girl")){
{
}
}
}
public static void main(String[] args) {
launch(args);
}
}
Now I have another class called CharacterGraphic, which I want to call and make the graphic I created in it appear.
package culminating;
& all the other imports
public class CharacterGraphic extends Culminating_JavaFX {
public void start(Stage primaryStage) throws Exception {
String gender = "boy";
Pane pane = new Pane();
pane.setStyle("-fx-background-color: LIGHTBLUE");
pane.setPrefSize(200, 200);
Circle head = new Circle();
head.setRadius(50);
head.setCenterX(240);
head.setCenterY(120);
head.setFill(Color.BURLYWOOD);
etc etc (all other graphics i made)
How do I do this???? And where would I do this?? Any answers really, really appreciated!

How to configure Progress Bar and Progress Indicator of javaFx?

I am trying to add a slider on my page like progress bar. But my code is not working well.
My task is when I am going to copy something from one location to another I want to display a progress bar on my page.
So in javaFx I wrote following task but it is not working well. That code runs but I want show the work in percentage like 30%, 50% and "finish". But my code fails to gives me like requirement so please help me.
My code is:
1.Declaration of progress bar and progress indicator
#FXML
final ProgressBar progressBar = new ProgressBar();
#FXML
final ProgressIndicator progressIndicator = new ProgressIndicator();
2.Assign values when I click on copy button.
#FXML
private void handleOnClickButtonAction(MouseEvent event) {
if (fromLabel.getText().isEmpty()
|| toLabel.getText().isEmpty()
|| fromLabel.getText().equalsIgnoreCase("No Directory Selected")
|| toLabel.getText().equalsIgnoreCase("No Directory Selected")) {
// Nothing
} else {
progressBar.setProgress(0.1f);
progressIndicator.setProgress(progressBar.getProgress());
this.directoryCount.setText("Please Wait !!!");
}
}
This code shows me only 10% completion an then directly shows "done", but I want whole process in percentage like 10,20,30,.. etc and then "done".
My copy code:
double i = 1;
while (rst.next()) {
File srcDirFile = new File(fromLabel.getText() + "/" + rst.getString("nugget_media_files"));
File dstDirFile = new File(toLabel.getText() + "/" + rst.getString("nugget_media_files"));
File dstDir = new File(toLabel.getText() + "/" + rst.getString("nugget_directory"));
if (srcDirFile.lastModified() > dstDirFile.lastModified()
|| srcDirFile.length() != dstDirFile.length()) {
copyDirectory(srcDirFile, dstDirFile, dstDir);
}
this.currentNuggetCount = i / this.nuggetFolderSize;
System.out.println("Nugget Count : " + this.currentNuggetCount);
Platform.runLater(new Runnable() {
#Override
public void run() {
progressBar.setProgress(1.0f);
progressIndicator.setProgress(progressBar.getProgress());
}
});
++i;
}
This is the copyDirectory method:
private static void copyDirectory(File srcDir, File dstDir,File destNugget) {
System.out.println(srcDir+" >> "+dstDir);
if(!destNugget.exists()) {
destNugget.mkdirs();
}
if (srcDir.isDirectory()) {
if (!dstDir.exists()) {
dstDir.mkdirs();
}
String[] children = srcDir.list();
for (int i=0; i<children.length; i++) {
copyDirectory(new File(srcDir, children[i]),
new File(dstDir, children[i]),
destNugget);
}
} else {
InputStream in = null;
try {
in = new FileInputStream(srcDir);
OutputStream out = new FileOutputStream(dstDir);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
} catch (IOException ex) {
System.out.println("Exceptio "+ex);
} finally {
try {
in.close();
} catch (IOException ex) {
System.out.println("Exceptio "+ex);
}
}
}
}
Try this code. It will give you Progress bar with progress indicator which depends on the slider control.
public class Main extends Application {
#Override
public void start(Stage stage) {
Group root = new Group();
Scene scene = new Scene(root);
stage.setScene(scene);
stage.setTitle("Progress Controls");
final Slider slider = new Slider();
slider.setMin(0);
slider.setMax(50);
final ProgressBar pb = new ProgressBar(0);
final ProgressIndicator pi = new ProgressIndicator(0);
slider.valueProperty().addListener(new ChangeListener<Number>() {
public void changed(ObservableValue<? extends Number> ov,
Number old_val, Number new_val) {
pb.setProgress(new_val.doubleValue()/50);
pi.setProgress(new_val.doubleValue()/50);
}
});
final HBox hb = new HBox();
hb.setSpacing(5);
hb.setAlignment(Pos.CENTER);
hb.getChildren().addAll(slider, pb, pi);
scene.setRoot(hb);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
You must enter your code inside a Task and set within UpdateProgress method. Before you run the Task you have to set progressBar.progressProperty (). Bind (task.progressProperty ());
This is an example:
TaskTest

Categories