5

簡単な質問があります。JComponent.paint または paintComponent によって生成された画像を取得するにはどうすればよいですか?

「ワークスペース」として使用する JComponent があり、paintComponent メソッドを独自のものに上書きしました。問題は、私のワークスペース JComponent には、独自の paintComponent メソッドを持つ子もあるということです。

そのため、Swing がワークスペース コンポーネントをレンダリングすると、ワークスペース グラフィックスがレンダリングされ、次にその子がレンダリングされます。

ただし、ワークスペース コンポーネントが生成するイメージ (ワークスペース グラフィックスと子のグラフィックスを含む) を取得したいと考えています。

それ、どうやったら出来るの?

独自の Graphics を使用して paintComponent/paint-method を自分で呼び出そうとしましたが、黒い画像が返されました。これが私が試したことです。

public void paintComponent(Graphics g) {

    if (bufferedImage != null) {
        g.drawImage(bufferedImage, 0, 0, this);
    }
    else {
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, bufferedImage.getWidth(), bufferedImage.getHeight());
    }
}

public BufferedImage getImage() {

    BufferedImage hello = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
    Graphics g = hello.getGraphics();
    paintComponent( g );

    return hello;
}

ご意見やご感想は大歓迎です!:)

4

4 に答える 4

3

getImage の呼び出しが早すぎると、コンポーネントがまだ表示されず、幅と高さが 0 のままになります。十分に遅い時間に呼び出していることを確認しましたか? コンポーネントのサイズを stdout に出力してみて、そのサイズを確認してください。

于 2008-09-22T09:04:38.203 に答える
1

問題は BufferedImage の作成方法が原因だったようです。使用時:

BufferedImage hello = bufferedImage.getSubimage(0,0, getWidth(), getHeight());

代わりに、それは機能しました。また、子をレンダリングするために、スイッチを paintComponent から paint に変更する必要がありました。

問題は解決しましたが、誰かが知っていれば。なぜ私は:

 BufferedImage hello = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);

常に黒のイメージをレンダリングしますか? トピック外ですが、知っておくと面白いかもしれません:)

于 2008-09-22T09:46:34.730 に答える
0

新しい BufferedImage を TYPE_INT_RGB に変更すると、これが解決されます。説明はできませんが、Swing の謎にすぎません。

public BufferedImage getImage() {

    BufferedImage hello = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
    Graphics g = hello.getGraphics();
    paintComponent( g );

    return hello;
}
于 2010-09-02T14:06:59.613 に答える
0

外部から paintComponent() または paint() を呼び出さないでください。代わりに、それらの (上書きされた) メソッド内でイメージを作成してください。そうすれば、イメージにコンポーネントのペイントされたコンテンツが実際に含まれていることを確認できます。

これがアプリケーションの例です。ImagePanel は実際には、コンポーネントが描画されるたびにコンポーネントのグラフィックス コンテンツを取得しますが、これは少し無駄になる可能性があるため、これを行う頻度を調整することをお勧めします。

public class SomeApp extends JFrame {

    private static class ImagePanel extends JPanel {
        private BufferedImage currentImage;
        public BufferedImage getCurrentImage() {
            return currentImage;
        }
        @Override
        public void paint(Graphics g) {
            Rectangle tempBounds = g.getClipBounds();
            currentImage = new BufferedImage(tempBounds.width, tempBounds.height, BufferedImage.TYPE_INT_ARGB);
            super.paint(g);
            super.paint(currentImage.getGraphics());
        }
    }

    public SomeApp() {
        setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        setSize(800,600);
        int matrixSize = 4;
        setLayout(new BorderLayout());
        add(new JLabel("Wonderful Application"), BorderLayout.NORTH);
        final ImagePanel imgPanel = new ImagePanel();
        imgPanel.setLayout(new GridLayout(matrixSize,matrixSize));
        for(int i=1; i<=matrixSize*matrixSize; i++) {
            imgPanel.add(new JButton("A Button" + i));
        }
        add(imgPanel, BorderLayout.CENTER);
        final JPanel buttonPanel = new JPanel();
        buttonPanel.add(new JButton(new AbstractAction("get image") {

            @Override
            public void actionPerformed(ActionEvent e) {
                JOptionPane.showMessageDialog(SomeApp.this, new ImageIcon(imgPanel.getCurrentImage()));
            }

        }));
        add(buttonPanel, BorderLayout.SOUTH);
    }

    public static void main(String[] args) {
        System.setProperty("swing.defaultlaf", UIManager.getSystemLookAndFeelClassName());
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new SomeApp().setVisible(true);
            }
        });
    }
}

Martijn が言ったように、コンポーネントがまだペイント/表示されていないため、画像はおそらく黒でした。表示されたときに通知される ComponentListener を追加できます。getSubimage を使用した「解決策」は、実際の問題とは何の関係もありません。外すことをお勧めします。

于 2008-09-22T14:04:12.867 に答える