Je factoriser le code serait de dessin de la méthode paintComponent()
de votre mise en œuvre de JPanel
à une méthode protégée public/paquet dans ce panneau qui peut attirer un objet Graphics
arbitraire, de toute largeur/hauteur (sans doute que le code de dessin est assez général).
Cet exemple a une trame, contenant un panneau, qui a une certaine logique de dessin (un grand X, la taille du panneau). La méthode principale de cet exemple vous montre un moyen d'obtenir une image et de l'écrire dans un fichier, même si la taille de l'image est différente de la taille du panneau.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MockFrame extends JFrame {
// throws Exception, as just an example (not really advised to do this)
public static void main(String[] args) throws Exception {
MockFrame frame = new MockFrame();
frame.setVisible(true);
// different sizes from the frame
int WIDTH = 500;
int HEIGHT = 500;
BufferedImage b = new BufferedImage(WIDTH, HEIGHT,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = (Graphics2D) b.getGraphics();
// should set some background, as the panel's background
// is dealt with by super.paintComponent()
g2d.setBackground(Color.white);
frame.getPanel().drawingLogic(b.getGraphics(), WIDTH, HEIGHT);
ImageIO.write(b, "png", new File("test.png"));
}
private MockPanel panel;
public MockFrame() {
this.setSize(200, 200);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
panel = new MockPanel();
getContentPane().add(panel);
}
public MockPanel getPanel() {
return panel;
}
private class MockPanel extends JPanel {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
drawingLogic(g, getWidth(), getHeight());
}
public void drawingLogic(Graphics g, int width, int height) {
g.setColor(Color.black);
g.drawLine(0, 0, width, height);
g.drawLine(0, height, width, 0);
}
}
}
Cela permet aux objets externes à l'interface graphique de se connecter à son algorithme de dessin. Un inconvénient que je vois est que vous allez créer une dépendance entre n'importe quel objet voulant imprimer le panneau à l'implémentation réelle du panneau. Mais il est encore mieux que le redimensionnement du panneau à la volée (je l'ai essayé et semble avoir quelques problèmes - je pense qu'il faut un certain temps pour le setSize()
changement de propager
EDIT:.
En réponse aux commentaires, j'ai fourni une version modifiée de l'extrait de code ci-dessus.Il n'est probablement pas la meilleure façon de le faire, et pas très convivial (donc je ne l'utiliserait pas dans une application d'utilisateur final), mais il redimensionne tout dans le cadre selon les règles du gestionnaire de disposition.
/* This code snippet describes a way to resize a frame for printing at
* a custom size and then resize it back.
*
* Copyright (C)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
import java.awt.Container;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class MockFrame extends JFrame {
// throws Exception, as just an example (not really advised to do this)
public static void main(String[] args) throws Exception {
final MockFrame frame = new MockFrame();
frame.setVisible(true);
// different sizes from the frame
final int WIDTH = 500;
final int HEIGHT = 700;
final BufferedImage b = new BufferedImage(WIDTH, HEIGHT,
BufferedImage.TYPE_INT_ARGB);
final Graphics2D g2d = (Graphics2D) b.getGraphics();
final int previousWidth = frame.getWidth();
final int previousHeight = frame.getHeight();
frame.setSize(WIDTH, HEIGHT);
frame.repaint();
JOptionPane.showMessageDialog(null,
"Press OK when the window has finished resizing");
frame.print(g2d);
frame.setSize(previousWidth, previousHeight);
ImageIO.write(b, "png", new File("test.png"));
}
public MockFrame() {
this.setSize(200, 200);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
boolean shouldFill = true;
boolean shouldWeightX = true;
Container pane = getContentPane();
// code from
// http://java.sun.com/docs/books/tutorial/uiswing/layout/gridbag.html
// just to add some components in the frame... :)
// left out in here for brevity
}
}
Le code redimensionne essentiellement le cadre, montre à l'utilisateur un message de confirmation de sorte que le fil peut être bloqué jusqu'à ce que le repeindre est fait (qui pourrait être fait par Thread.sleep()
, mais il est plus transparent à l'aide d'un message). Ensuite, il imprime le cadre et le redimensionne à sa forme d'origine. Un peu hacky, mais ça marche.
-- Flaviu Cipcigan
le composant est sous le contrôle d'un gestionnaire de disposition, et n'a donc aucun contrôle sur sa propre taille. Appeler cela ne fera rien. –