Android-тост в JavaFX
Я новичок в JavaFX, и мне интересно, есть ли какой-то эквивалент Android Toast?
Я видел класс Notification
, но не похоже, что он может отображаться только в приложении. Я также нашел, что могу пользователь Timer
и сделать затенение Label
, но если есть какой-то класс для использования, я бы лучше!
Спасибо!
Ответы
Ответ 1
Попробуйте третью сторону Панель уведомлений или уведомлений ControlsFX.
"Элемент управления NotificationPane позволяет вам уведомлять своих пользователей о чем-то, не требуя их немедленного ввода (что вы можете сделать с помощью API-интерфейсов ControlsFX). NotificationPane будет анимировать и выходить из вида"
![toast1]()
Уведомления "покажет сообщение уведомления пользователям в одном из девяти мест на экране... После установленной продолжительности уведомление будет исчезать."
![toast2]()
Ответ 2
Я знаю, что прошло много времени с тех пор, как вы опубликовали это сообщение, но я только что сделал андроидальное сообщение для тоста для javafx, поэтому отправлю его здесь, если кому-то нужен такой код.
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.util.Duration;
public final class Toast
{
public static void makeText(Stage ownerStage, String toastMsg, int toastDelay, int fadeInDelay, int fadeOutDelay)
{
Stage toastStage=new Stage();
toastStage.initOwner(ownerStage);
toastStage.setResizable(false);
toastStage.initStyle(StageStyle.TRANSPARENT);
Text text = new Text(toastMsg);
text.setFont(Font.font("Verdana", 40));
text.setFill(Color.RED);
StackPane root = new StackPane(text);
root.setStyle("-fx-background-radius: 20; -fx-background-color: rgba(0, 0, 0, 0.2); -fx-padding: 50px;");
root.setOpacity(0);
Scene scene = new Scene(root);
scene.setFill(Color.TRANSPARENT);
toastStage.setScene(scene);
toastStage.show();
Timeline fadeInTimeline = new Timeline();
KeyFrame fadeInKey1 = new KeyFrame(Duration.millis(fadeInDelay), new KeyValue (toastStage.getScene().getRoot().opacityProperty(), 1));
fadeInTimeline.getKeyFrames().add(fadeInKey1);
fadeInTimeline.setOnFinished((ae) ->
{
new Thread(() -> {
try
{
Thread.sleep(toastDelay);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
Timeline fadeOutTimeline = new Timeline();
KeyFrame fadeOutKey1 = new KeyFrame(Duration.millis(fadeOutDelay), new KeyValue (toastStage.getScene().getRoot().opacityProperty(), 0));
fadeOutTimeline.getKeyFrames().add(fadeOutKey1);
fadeOutTimeline.setOnFinished((aeb) -> toastStage.close());
fadeOutTimeline.play();
}).start();
});
fadeInTimeline.play();
}
}
Вы можете сделать сообщение с тостом из любого класса с помощью этого кода:
String toastMsg = "some text...";
int toastMsgTime = 3500; //3.5 seconds
int fadeInTime = 500; //0.5 seconds
int fadeOutTime= 500; //0.5 seconds
Toast.makeText(primarystage, toastMsg, toastMsgTime, fadeInTime, fadeOutTime);
Ответ 3
Чтобы создать собственный тост, используя собственный макет fxml:
package controllers;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.Control;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.util.Duration;
import java.io.IOException;
public class ToastController {
public static final int TOAST_SUCCESS = 11;
public static final int TOAST_WARN = 12;
public static final int TOAST_ERROR = 13;
@FXML
private HBox containerToast;
@FXML
private Label textToast;
private void setToast(int toastType, String content){
textToast.setText(content);
switch (toastType){
case TOAST_SUCCESS:
containerToast.setStyle("-fx-background-color: #9FFF96");
break;
case TOAST_WARN:
containerToast.setStyle("-fx-background-color: #FFCF82");
break;
case TOAST_ERROR:
containerToast.setStyle("-fx-background-color: #FF777C");
break;
}
}
public static void showToast(int toastTyoe, Control control, String text){
Stage dialog = new Stage();
dialog.initOwner(control.getScene().getWindow());
dialog.initModality(Modality.APPLICATION_MODAL);
dialog.setResizable(false);
dialog.initStyle(StageStyle.UNDECORATED);
double dialogX = dialog.getOwner().getX();
double dialogY = dialog.getOwner().getY();
double dialogW = dialog.getOwner().getWidth();
double dialogH = dialog.getOwner().getHeight();
double posX = dialogX + dialogW/2;
double posY = dialogY + dialogH/6 *5;
dialog.setX(posX);
dialog.setY(posY);
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(ToastController.class.getResource("/fxml/toastPopup.fxml"));
loader.load();
ToastController ce = loader.getController();
ce.setToast(toastTyoe,text);
dialog.setScene(new Scene(loader.getRoot()));
dialog.show();
new Timeline(new KeyFrame(
Duration.millis(1500),
ae -> {
dialog.close();
})).play();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
FXML:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.text.Font?>
<HBox fx:id="containerToast" alignment="CENTER" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controllers.ToastController">
<children>
<Label fx:id="textToast" text="TEST" textAlignment="CENTER">
<font>
<Font name="System Bold" size="16.0" />
</font>
</Label>
</children>
<padding>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
</padding>
</HBox>
чтобы запустить тост, просто используйте:
Один из 3 видов тостов:
ToastController.TOAST_ERROR
ToastController.TOAST_SUCCESS
ToastController.TOAST_WARN
@FXML
private Label idOfAnyControl;
showToast(ToastController.TOAST_WARN,idOfAnyControl,"ERROR TEXT")
если вы хотите, вы можете извлечь 2 дополнительных параметра путем внедрения зависимости (время и положение тоста)
Ответ 4
Отличная работа @alcoolis! Спасибо! Работайте нормально для меня, если я изменю параметр primaryStage на null. Я не знаю причину:
//это работает
Toast.makeText(null, toastMsg, toastMsgTime, fadeInTime, fadeOutTime);
Ответ 5
@alcoolis эквивалент в котлине
Toast.makeText(primaryStage, "No data selected!")
class Toast {
companion object {
fun makeText(stage: Stage, message: String, displayTime: Int = 3000, fadeInDelay: Int = 500, fadeOutDelay: Int = 500, size: Double = 15.0, opacity: Double = 5.0) {
val toastStage = Stage()
toastStage.initOwner(stage)
toastStage.isResizable = false
toastStage.initStyle(StageStyle.TRANSPARENT)
val text = Text(message)
text.font = Font.font("Verdana", size)
text.fill = Color.RED
val root = StackPane(text)
root.style = "-fx-background-radius: 20; -fx-background-color: rgba(0, 0, 0, 0.2); -fx-padding: 50px;"
root.opacity = opacity
val scene = Scene(root)
scene.fill = Color.TRANSPARENT
toastStage.scene = scene
toastStage.show()
val fadeInTimeline = Timeline()
val fadeInKey1 =
KeyFrame(Duration.millis(fadeInDelay.toDouble()), KeyValue(toastStage.scene.root.opacityProperty(), 1))
fadeInTimeline.keyFrames.add(fadeInKey1)
fadeInTimeline.setOnFinished {
Thread {
try {
Thread.sleep(displayTime.toLong())
} catch (e: InterruptedException) {
// TODO Auto-generated catch block
e.printStackTrace()
}
val fadeOutTimeline = Timeline()
val fadeOutKey1 =
KeyFrame(
Duration.millis(fadeOutDelay.toDouble()),
KeyValue(toastStage.scene.root.opacityProperty(), 0)
)
fadeOutTimeline.keyFrames.add(fadeOutKey1)
fadeOutTimeline.setOnFinished { toastStage.close() }
fadeOutTimeline.play()
}.start()
}
fadeInTimeline.play()
}
}
}