2009-12-29 3 views
4

Voici la situation: Ma page 'metrics.jsp' soumet quelques variables qui sont nécessaires pour créer le graphique. Le 'ProjectActionBean.java' appelle à quelques autres classes Java qui créent le JFreeChart. Je peux afficher le graphique dans une fenêtre contextuelle, mais je veux qu'il s'affiche dans la fenêtre du navigateur d'origine.Comment puis-je afficher un JFreeChart dans un navigateur web avec Stripes Framework

JFreeChart placeChart = ChartFactory.createBarChart(
            "ChartName", 
       "",    //x-axis label 
       "",    //y-axis label 
       dataset, 
       PlotOrientation.VERTICAL, 
       false,   //legend 
       true,   //tooltype 
       false);   //generate urls 
     ChartFrame frame = new ChartFrame(name, placeChart); 
     frame.pack(); 
     frame.setVisible(true); 

Répondre

5

J'ai écrit une demande comme ça, donc je peux vous assurer qu'il est possible :)

D'abord, vous devez vous débarrasser de tout ce qui est l'interface graphique. Vous n'avez simplement pas d'interface graphique sur le serveur. Cela signifie que votre ChartFrame frame est vidée. Ma routine principale pour la création d'un tableau ressemble à ceci:

private void createChart(XYPlot plot, String fileName, String caption) throws IOException { 
     JFreeChart chart = new JFreeChart(caption, plot); 
     chart.addSubtitle(this.subtitle); 
     if (plot.getRangeAxis() instanceof LogarithmicAxis) { 
     chart.addSubtitle(1, new TextTitle("(logarithmische Skala)")); 
     } 
     File file = new File(fileName); 
     file.delete(); 
     ChartUtilities.saveChartAsPNG(file, chart, CHART_WIDTH, CHART_HEIGHT); 
    } 

Cela crée un fichier que vous pouvez servir comme un <img> de votre page Web. Alternativement (mais un peu plus avancé), vous pouvez utiliser ChartUtilities pour créer un flux que vous pouvez servir en réponse à une requête pour l'URL de l'image.

Un autre élément magique est de dire à Java que vous exécutez du code graphique sans interface graphique. Vous devez définir la variable d'environnement

-Djava.awt.headless=true 

Pour un serveur d'application Web tel que Tomcat, cela se trouve dans le script de démarrage de Tomcat.


Mise à jour

ok ouais ne pas le 'ChartUtilities.saveChartAsPNG();' suffit d'enregistrer le graphique sur le système de fichiers? Je souhaite que l'utilisateur puisse entrer les variables et qu'un graphique leur soit directement affiché dans le navigateur.

Tant que vous n'avez qu'un seul utilisateur, écrire les images sur le système de fichiers fonctionnera correctement pour le scénario que vous décrivez. En fait, c'est ainsi que ma première version a fonctionné: J'avais 4 étiquettes <img> dans ma page de réponse HTML du formulaire où l'utilisateur a spécifié les paramètres; et ceux pointés sur les noms des 4 fichiers avec mes images. Tant que vous avez fini d'écrire ces fichiers avant de renvoyer la réponse à l'utilisateur, cela fonctionne très bien.

Des problèmes apparaissent lorsque vous avez plusieurs utilisateurs. Ils peuvent finir par voir les graphiques spécifiés par l'autre utilisateur. Il existe des solutions de contournement possibles avec l'encodage de l'ID ou de la session de l'utilisateur dans les noms de fichier de diagramme, mais cela devient vraiment horrible. Il y a un meilleur moyen, basé sur la génération dynamique à la demande de chaque image, individuellement.

Je ne sais pas ce que vous savez sur le langage HTML/HTTP, donc j'espère que je ne vais pas vous ennuyer avec ceci:

Pour toute requête HTTP donné, vous ne pouvez retourner un seul flux de Les données. Typiquement, c'est une page HTML, c'est-à-dire un flux de texte. Si vous voulez des images dans votre page HTML, vous insérez <img> liens avec différentes URLs dans votre page HTML, et vous êtes encore juste en retournant une page pleine de texte. Le navigateur puis va de l'avant et demande les images en envoyant des requêtes pour les URL mentionnées dans les balises <img>. C'est assez facile lorsque vos images ne sont que des fichiers dans le système de fichiers.Si vous voulez des images générées dynamiquement comme des graphiques, alors vous devez imaginer une URL pour chaque type d'image que vous voulez générer, et mapper chacune de ces URL à une servlet qui sait comment générer une telle image.

Mon application comportait 4 graphiques différents sur une page. Ma page HTML comportait donc 4 balises <img> avec 4 URL différentes mappées à la même servlet génératrice de graphiques, mais certains paramètres de l'URL indiquaient au servlet type de tableau était voulu. Lors de la réception de la requête, la servlet effectuera la magie JFreeChart et utilisera ChartUtilities.writeChartAsPNG() pour vider l'image générée dans le flux de sortie de la servlet.

+0

ok ouais DOE sn't the 'ChartUtilities.saveChartAsPNG();' suffit d'enregistrer le graphique sur le système de fichiers? Je souhaite que l'utilisateur puisse entrer les variables et qu'un graphique leur soit directement affiché dans le navigateur. Est-ce que je peux faire cela avec le code que vous m'avez fourni? Merci beaucoup – robbie

+0

Non, c'est ce que j'ai appelé l'option "avancée". Je vais mettre à jour ma réponse avec quelques conseils. –

2

Vous devez écrire une servlet qui écrit une image (flux d'octets) dans le flux de sortie vers le client. Il n'y a pas besoin de créer des fichiers. Fondamentalement, quelque chose comme cela devrait fonctionner:

public class ChartServlet extends HttpServlet { 
    @Override 
    protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException { 

     JFreeChart chart = .. // create your chart 
     ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
    ChartUtilities.writeChartAsPNG(bos, chart, width, height); 

      response.setContentType("image/png"); 
      OutputStream out = new BufferedOutputStream(response.getOutputStream()); 
      out.write(bos.toByteArray()); 
      out.flush(); 
      out.close(); 
    } 
} 

carte ensuite à une url dans votre web.xml et utiliser de tag « img » en HTML/JSP. Évidemment, vous pouvez passer des paramètres à ce etc.

1

Si vous voulez rester dans le cadre Stripes vous pouvez utiliser une extension personnalisée de la StreamingResolution, ainsi:

Créer une nouvelle implémentation ActionBean normale qui représentera l'URL votre tableau (à inclure dans votre balise img):

@DefaultHandler 
public Resolution view() { 
    JFreeChart chart = ... 
    return new ChartStreamingResolution(chart); 
} 

Le StreamingResolution personnalisé ressemble alors à ceci:

public class ChartStreamingResolution extends StreamingResolution { 
    private JFreeChart chart; 
    public ChartStreamingResolution(JFreeChart chart) { 
     super("image/png"); 
     this.chart = chart; 
    } 

    @Override 
    public void stream(HttpServletResponse response) { 
     try { 
      ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
      ChartUtilities.writeChartAsPNG(bos, chart, 400, 200); 
      OutputStream out = new BufferedOutputStream(response.getOutputStream()); 
      out.write(bos.toByteArray()); 
      out.flush(); 
      out.close(); 
     } catch (Exception e) { 
      //something sensible 
     } 
    } 
} 
Questions connexes