2010-02-11 12 views
1

J'ai un JPanel sur lequel je dessine un certain nombre de composants JComponents personnalisés en utilisant la méthode habituelle 'paintComponent (Graphics g)'. J'utilise un JLayeredPane pour contrôler l'ordre d'affichage des composants personnalisés, comme suit:Redimensionner JComponent pour l'exportation de fichier

public Class MyPanel extends JPanel { 
    private JLayeredPane layeredPane = new JLayeredPane(); 
    private JComponent component1; 
    private JComponent component2; 

    public MyPanel() { 
     super(); 
     setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS)); 

     component1 = new CustomComponent1(); 
     layeredPane.add (component1, new Integer(0)); 

     component2 = new CustomComponent2(); 
     layeredPane.add (component2, new Integer(1)); 

     add (layeredPane); 
    } 

    public void resizePanel(Graphics g, int newWidth, int newHeight) { 
     component1.setBounds (f(x), f(y), f(newWidth), f(newHeight)); 
     component2.setBounds (f(x), f(y), f(newWidth), f(newHeight)); 
    } 

    public void paintComponent(Graphics g) { 
     if ((getWidth() != oldWidth) || (getHeight() != oldHeight)) { 
      oldWidth = getWidth(); 
      oldHeight = getHeight(); 
      resizePanel (g, getWidth(), getHeight()); 
     } 
     super.paintComponent(g); 
    } 

Maintenant, je voudrais exporter ce panneau dans un fichier JPEG, mais avec une taille différente. Lorsque j'utilise le code suivant, il crée/exporte avec succès un fichier JPEG de la taille désirée, mais il met également à jour la version de mon écran de l'écran à la nouvelle taille! Yikes! Comment puis-je «dessiner» une image appropriée pour l'exportation, mais ne pas réellement faire afficher cette nouvelle image?

Merci!


Eh bien, je suis de retour à nouveau ce problème .....

La scène que je peins comprend un texte et maintenant l'utilisateur final veut le graphique exporté dans un aspect « portrait » rapport. Comme je ne repeint pas la scène dans les nouvelles dimensions, mais que je redimensionne simplement l'image, le texte est sérieusement écrasé horizontalement.

Quoi qu'il en soit?

+0

Croisement posté: http://forums.sun.com/thread.jspa?threadID=5427732&tstart=0 – camickr

+0

Ce qui suggère correctement l'utilisation de javax.imageio: http://java.sun.com/javase/6/docs/ api/javax/imageio/package-summary.html – trashgod

Répondre

1

Ne redimensionnez pas votre panneau du tout; Il suffit de créer un BufferedImage qui est la taille actuelle du panneau et le peindre. Une fois que vous avez l'instantané, mettez-le à l'échelle dans les dimensions désirées dans un second BufferedImage en utilisant drawImage() ou AffineTransformOp.

Additif: L'un des avantages de AffineTransformOp est le contrôle de rotation, l'interpolation, l'échelle et le rapport d'aspect:

BufferedImage image = ... 
int w = image.getWidth(); 
int h = image.getHeight(); 
AffineTransform scaleTransform = new AffineTransform(); 
// last-in-first-applied: rotate, scale 
scaleTransform.scale(scaleX, scaleY); 
scaleTransform.rotate(Math.PI/2, w/2, h/2); 
AffineTransformOp scaleOp = new AffineTransformOp(
     scaleTransform, AffineTransformOp.TYPE_BILINEAR); 
BufferedImage new = scaleOp.filter(image, null); 
+0

Eh bien, cette méthode semble légèrement mieux que de faire le 'g2.scale()' n redessiner les composants, mais le texte est encore froissé horizontalement un peu. Je vais aller avec cette méthode pour le moment. Merci encore. R – redBeard

1

dirait une seconde excellente solution. La solution finale je ressemble à ce qui suit:

public void export(File file, int width, int height) 
throws IOException 
{ 
    BufferedImage scaledImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); 
    Graphics2D g2 = scaledImage.createGraphics(); 
    g2.scale(((double) width)/((double)getWidth()), ((double) height)/((double)getHeight())); 
    paintComponents(g2); 
    try { 
     ImageIO.write(scaledImage, "jpg", file);    
    } catch (FileNotFoundException e) { 
     throw new IOException ("Unable to export chart to (" 
     + file.getAbsolutePath() + "): " + e.getLocalizedMessage()); 
    } finally { 
     g2.dispose(); 
    } 
} 
+0

Voir aussi http://forums.sun.com/thread.jspa?threadID=5427732&tstart=0 – trashgod

0

Eh bien, la seule façon que je pouvais obtenir tout ce qu'il faut OK (par exemple, aucune mise à l'échelle du texte après qu'il a été pixellisé) est de dessiner l'image sur un nouveau graphisme contexte en utilisant la nouvelle taille. Voici ma nouvelle méthode 'export()'.

public void export(File file, final int width, final int height) 
    throws IOException 
{ 

    BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); 
    final Graphics2D g2 = image.createGraphics(); 

    // Must wait for the bloody image to be drawn as Swing 'paint()' methods 
    // merely schedule painting events. The 'draw()' below may not complete 
    // the painting process before the 'write()' of the image is performed. 

    // thus, we wait.... 

    try { 
     SwingUtilities.invokeAndWait(new Runnable() { 
      public void run() { 
       draw (g2, new Rectangle (0, 0, width, height)); 
      } 
     }); 
     ImageIO.write(image, "png", file); 
    } catch (Exception e) { 
     throw new IOException ("Unable to export chart to (" 
       + file.getAbsolutePath() + "): " + e.getLocalizedMessage()); 
    } finally { 
     g2.dispose(); 
    } 
} 

La méthode « draw() » méthode appelée appelle au-dessus des « setbounds() » sur l'ensemble de mes sous-composants qui les tire sur la nouvelle image en mémoire tampon. Un peu de travail, mais le résultat est exactement ce dont j'ai besoin.