问题
I am using FontAwesomeFX for many icons throughout my application. I would like to use them as icons for my Stage
as well.
Since FontAwesomeIconView
extends GlyphIcon
which extends Text
, I can not use it as an Image
directly.
Is there a way to create a usable Image
from a Text
object?
I have tried to use snapshot
, but I am not familiar with that method and end up with the standard "empty" icon on my stage.
Here is the MCVE I have so far:
import de.jensd.fx.glyphs.fontawesome.FontAwesomeIcon;
import de.jensd.fx.glyphs.fontawesome.FontAwesomeIconView;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.SnapshotParameters;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class FontAwesomeIconExample extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
// Simple Interface
VBox root = new VBox(10);
root.setAlignment(Pos.CENTER);
root.setPadding(new Insets(10));
// Convert the FontAwesomeIconView node to an Image
FontAwesomeIconView iconView = new FontAwesomeIconView(FontAwesomeIcon.ID_CARD_ALT);
WritableImage icon = iconView.snapshot(new SnapshotParameters(), null);
primaryStage.getIcons().add(icon);
// Show the stage
primaryStage.setWidth(300);
primaryStage.setHeight(100);
primaryStage.setScene(new Scene(root));
primaryStage.setTitle("Sample");
primaryStage.show();
}
}
And the result:
Is it possible to use a node snapshot as a stage icon? Or is there a better method of converting the FontAwesomeIconView
for this purpose?
EDIT:
I have tried both Sedrick's and JKostikiadis's methods and both give similar results for me.
Sedrick's:
// Convert the FontAwesomeIconView node to an Image
FontAwesomeIconView iconView = new FontAwesomeIconView(FontAwesomeIcon.AMAZON);
WritableImage icon = iconView.snapshot(new SnapshotParameters(), null);
java.awt.image.BufferedImage bImage = SwingFXUtils.fromFXImage(icon, null);
ByteArrayOutputStream s = new ByteArrayOutputStream();
try {
javax.imageio.ImageIO.write(bImage, "png", s);
} catch (IOException e) {
e.printStackTrace();
}
JKostikiadis's:
FontAwesomeIconView iconView = new FontAwesomeIconView(FontAwesomeIcon.AMAZON);
WritableImage writableImg = iconView.snapshot(null, null);
Image img = SwingFXUtils.toFXImage(SwingFXUtils.fromFXImage(writableImg, null), null);
primaryStage.getIcons().add(img);
I believe they both accomplish essentially the same thing (with the sizing of the Image
resulting in different displayed icons).
What I do not understand now, is why this is the icon it is producing for me and not them...
I am running Windows 7 and JDK 1.8.0_161.
回答1:
In addition to Sedrick's answer, another (shorter) solution could be to just create an Image (javafx package) and add it stage icons :
FontAwesomeIconView iconView = new FontAwesomeIconView(FontAwesomeIcon.AMAZON);
WritableImage writableImg = iconView.snapshot(null, null);
Image img = SwingFXUtils.toFXImage(SwingFXUtils.fromFXImage(writableImg, null), null);
primaryStage.getIcons().add(img);
P.S A relative post could be found here : Snapshot Image can't be used as stage icon
Edit:
For some reason, the version 8.15 of the FontawesomeFx require the FontAwesomeIconView to be added on a Scene in order to initialize its content, something that is not necessary to do on the newest version of FontawesomeFx. So, in my opinion, you have to either upgrade your FontawesomeFx version or to add the FontAwesomeIconView on a Scene and after to take the snapshot. Like this :
FontAwesomeIconView iconView = new FontAwesomeIconView(FontAwesomeIcon.ID_CARD_ALT);
Scene scene = new Scene(new StackPane(iconView));
WritableImage writableImg = iconView.snapshot(null, null);
Image img = SwingFXUtils.toFXImage(SwingFXUtils.fromFXImage(writableImg, null), null);
Here is the result (using 8.5 version):
回答2:
I just figured it out. The goal is to get an InputStream
. I was able to do that using SwingFXUtils.fromFXImage(icon, null);
to get a bufferedImage. From there I used ImageIO.write(bImage, "png", s);
to get a byte array
. I used to byte array
to get an InputStream
.
import de.jensd.fx.glyphs.fontawesome.FontAwesomeIcon;
import de.jensd.fx.glyphs.fontawesome.FontAwesomeIconView;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.embed.swing.SwingFXUtils;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.SnapshotParameters;
import javafx.scene.image.Image;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javax.imageio.ImageIO;
public class FontAwesomeIconExample extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
try {
// Simple Interface
VBox root = new VBox(10);
root.setAlignment(Pos.CENTER);
root.setPadding(new Insets(10));
// Convert the FontAwesomeIconView node to an Image
FontAwesomeIconView iconView = new FontAwesomeIconView(FontAwesomeIcon.AMAZON);
WritableImage icon = iconView.snapshot(new SnapshotParameters(), null);
BufferedImage bImage = SwingFXUtils.fromFXImage(icon, null);
ByteArrayOutputStream s = new ByteArrayOutputStream();
ImageIO.write(bImage, "png", s);
InputStream is = new ByteArrayInputStream(s.toByteArray());
primaryStage.getIcons().add(new Image(is, 16, 16, false, false));
// Show the stage
primaryStage.setWidth(300);
primaryStage.setHeight(100);
primaryStage.setScene(new Scene(root));
primaryStage.setTitle("Sample");
primaryStage.show();
} catch (IOException ex) {
Logger.getLogger(FontAwesomeIconExample.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
This is worth noting from the javadoc.
The images should be different sizes of the same image and the best size will be chosen, eg. 16x16, 32x32.
来源:https://stackoverflow.com/questions/53198858/how-to-use-a-fontawesomeiconview-object-as-a-stages-icon