4

私は、一連の JPanels をPrintableに印刷する作業を行っています。これは、印刷したいものを描画する Graphics オブジェクトを提供する基本的な印刷インターフェイスです。「ライブ」JPanel がある場合、それは UI のどこかにあり、すべてがうまく機能します。

しかし、JPanel を作成して UI に追加しないと、printAll() はまったく何もしないように見えます。コードを SSCCE に縮小する:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class SSCCEPaintInvisible
{
    public static void main(String[] args)
    {
        /* Create an JPanel with a JLabel */
        JPanel panel = new JPanel();
        //panel.setLayout(new FlowLayout());
        JLabel label = new JLabel("Hello World");
        panel.add(label);
        //label.invalidate();
        //panel.invalidate();

        /* Record a picture of the panel */
        BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_4BYTE_ABGR);
        Graphics g = image.getGraphics();

        /* Draw something to ensure we're drawing */
        g.setColor(Color.BLACK);
        g.drawLine(0, 0, 100, 100);

        /* Attempt to draw the panel we created earlier */ 
        panel.paintAll(g);  // DOES NOTHING. :(

        /* Display a frame to test if the graphics was captured */
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JLabel label2 = new JLabel( new ImageIcon(image) );
        frame.add(label2);
        frame.pack();

        frame.setVisible(true);
            // shows ONLY the black line we drew in the Graphics
    }
}

パネルの JFrame を作成し、パネルを JFrame に追加して、paintAll() を呼び出す前に JFrame を表示すると、コードは期待どおりに UI を Graphic にキャプチャします。もちろん、これは画面上の JFrame をフラッシュして印刷します。

UIに追加されたことのないJPanelをGraphicsオブジェクトにレンダリングする方法はありますか? ありがとう!

4

1 に答える 1

3

@Kleopatra の回答のヒントから。

SSCCEPaintInvisible

import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;

public class SSCCEPaintInvisible
{
    public static void main(String[] args)
    {
        /* Create an JPanel with a JLabel */
        JPanel panel = new JPanel();

        JLabel label = new JLabel("Hello World");
        panel.add(label);
        // Next 3 are very important!
        panel.setSize(panel.getPreferredSize());
        panel.addNotify();
        panel.doLayout();

        /* Record a picture of the panel */
        BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_4BYTE_ABGR);
        Graphics g = image.getGraphics();

        /* Draw something to ensure we're drawing */
        g.setColor(Color.BLACK);
        g.drawLine(0, 0, 100, 100);

        /* Attempt to draw the panel we created earlier */
        panel.paintAll(g);  // DOES NOTHING. :(

        /* Display a frame to test if the graphics was captured */
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JLabel label2 = new JLabel( new ImageIcon(image) );
        frame.add(label2);
        frame.pack();

        frame.setVisible(true);
            // shows ONLY the black line we drew in the Graphics
    }
}

@GagandeepBali が指摘したように、この GUI は EDT では作成されません。GUI への変更が EDT で行われない場合、結果は予測できません。詳細については、Swing の同時実行と特に初期スレッドを参照してください。

于 2013-01-08T13:52:33.170 に答える