如何使用FontAwesomeIconView对象作为舞台的图标?

时间:2018-11-07 22:29:28

标签: javafx font-awesome

我在整个应用程序中对许多图标使用FontAwesomeFX。我也想将它们用作我的Stage的图标。

由于FontAwesomeIconView扩展了GlyphIcon并扩展了Text,所以我不能直接将其用作Image

是否有一种方法可以从Image对象创建可用的Text

我尝试使用snapshot,但是我对这种方法并不熟悉,最终在舞台上出现了标准的“空”图标。

这是我到目前为止拥有的MCVE:

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();
    }
}

结果:

screenshot


是否可以将节点快照用作阶段图标?还是为此目的转换FontAwesomeIconView的更好方法?

  

编辑:

我已经尝试了Sedrick和JKostikiadis的方法,并且都为我提供了相似的结果。


Sedrick:

    // 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();
    }

screenshot


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);

screenshot


我相信他们基本上都完成了同一件事(Image的大小导致了不同的显示图标)。

我现在不明白的是,为什么这是它为我而不是他们为我生成的图标……

  

我正在运行Windows 7和JDK 1.8.0_161。

2 个答案:

答案 0 :(得分:3)

我只是想通了。目的是获得一个InputStream。我能够使用SwingFXUtils.fromFXImage(icon, null);来获取bufferedImage。从那里,我用ImageIO.write(bImage, "png", s);得到了一个byte array。我曾经byte array得到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);
        }
    }    
}

enter image description here enter image description here

从Javadoc中值得注意。

  

图像应该是同一图像的不同尺寸,并且将选择最佳尺寸。 16x16、32x32。

答案 1 :(得分:2)

除了Sedrick的回答,另一个(较短的)解决方案可能是只创建一个Image(javafx程序包)并将其添加为舞台图标:

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可以在这里找到相关职位:Snapshot Image can't be used as stage icon

修改

出于某种原因,FontawesomeFx的版本8.15要求将FontAwesomeIconView添加到场景中以初始化其内容,而对于最新版本的FontawesomeFx则不需要这样做。因此,我认为,您必须升级FontawesomeFx版本或在场景上添加FontAwesomeIconView,然后再拍摄快照。像这样:

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);

结果如下(使用8.5版本):

enter image description here