How to use a FontAwesomeIconView object as a Stage's icon?

风流意气都作罢 提交于 2020-01-04 02:38:45

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!