¿Por qué tengo que llamar a GraphicsEnvorinment.registerFont () incluso si mi fuente se creó a partir de un archivo?

Estoy desarrollando una aplicación web que usa JFreeChart para renderizar gráficos. Sin embargo, cuando la dosis del servidor no tiene ninguna fuente china instalada, la dosis de JFreeChart no muestra el carácter chino aunque haya establecido la fuente.

Luego escribo un pequeño código de prueba y descubro que agregar esta línea de código antes de dibujar la tabla puede resolver el problema.

GraphicsEnvironment.getLocalGraphicsEnvironment().registerFont(font);

Así que mis preguntas son ...

¿Por qué tengo que registrar la fuente en JVM incluso si creo mi fuente desde un archivo? ¿Eso significa que JFreeChart no usa la fuente que establezco directamente?

Cuando implemento mi programa en el servidor, incluso si agrego esta línea de código, no muestra caracteres chinos.¿Cómo hago para que use siempre la fuente que configuré para mostrar el carácter correctamente en todos los entornos?

Sé que puedo hacer unfallback directorio en$JAVA_HOME/jre/lib y poner mi fuente en ella. Pero esa dosis no explica por qué JFreeChart no puede mostrarse con la fuente que configuré.

ACTUALIZAR

Estoy bastante seguro de que la fuente se carga correctamente, y por lo tanto la dosisregisterFont() devuelve true cuando despliegue el programa en Tomcat.

ACTUALIZACIÓN 2

De acuerdo aPreguntas frecuentes sobre JAVA 2D, ahora me doy cuenta que tengo que llamarregisterFont() para hacer mi propia fuente "instalada" en JVM, y mi fuente estará disponible a través deFont constructor.

A partir de Java SE 6, hay un método: GraphicsEnvironment.registerFont () que le brinda la capacidad de hacer que una fuente "creada" esté disponible para los constructores de fuentes y que se incluya a través de las API de enumeración de fuentes. Font.createFont () y este método se combinan para proporcionar una manera de "instalar" una fuente en el JRE en ejecución, de modo que esté disponible al igual que las fuentes instaladas de O / S. Sin embargo, esta fuente no persiste en las invocaciones de JRE.

Pero, como ya tengoFont instancias creadas / derivadas decreateFont(), ¿por qué dosen mi programa todavía necesita crear otrosFont ?

A continuación se muestra el código que usé, simplemente muestra un gráfico en formato PNG. Si desea ejecutar el código, debe cambiar la ubicación de salida y la fuente para que se ajusten a sus necesidades, yAquí está el enlace de SourceForge Para la fuente china que utilizo en el código.

import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.io.File;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.StandardChartTheme;
import org.jfree.data.general.DefaultPieDataset;
import org.jfree.data.general.PieDataset;

public class Problem {

  public static void main(String[] args) throws Exception {
    setJFreeChartTheme();

    PieDataset dataset = createDataSet();
    JFreeChart chart = ChartFactory.createPieChart(
        "Chinese Testing", dataset, true, true, false);
    ChartUtilities.saveChartAsJPEG(new File("/tmp/output.png"), 
        chart, 800, 600);

    System.out.println("Done");
  }

  private static void setJFreeChartTheme() throws Exception {
    Font font = loadFont();
    //==================================================================
    GraphicsEnvironment.getLocalGraphicsEnvironment().registerFont(font);
    //==================================================================
    StandardChartTheme theme = new StandardChartTheme("Chinese font", true);
    theme.setExtraLargeFont(font.deriveFont(Font.BOLD, 20));
    theme.setLargeFont(font.deriveFont(Font.BOLD, 16));
    theme.setRegularFont(font.deriveFont(Font.PLAIN, 14));
    theme.setSmallFont(font.deriveFont(Font.PLAIN, 12));
    ChartFactory.setChartTheme(theme);
  }

  private static Font loadFont() throws Exception {
    File file = new File("/tmp/wqy-zenhei.ttc");
    return Font.createFont(Font.TRUETYPE_FONT, file);
  }

  private static PieDataset createDataSet() {
    DefaultPieDataset dataset = new DefaultPieDataset();
    dataset.setValue("種類1", Integer.valueOf(1));
    dataset.setValue("種類2", Integer.valueOf(2));
    dataset.setValue("種類3", Integer.valueOf(3));
    return dataset;
  }
}

Respuestas a la pregunta(3)

Su respuesta a la pregunta