2008-09-22 38 views
5

我有一個快速的問題。如何獲得由JComponent.paint或paintComponent生成的圖像?如何獲取圖像paint/paintComponent生成的圖像?

我有一個JComponent,我用它作爲'工作區',並將paintComponent方法覆蓋到我自己的位置。問題是我的工作空間JComponent也有孩子,他們有自己的paintComponent方法。

因此,當Swing渲染我的工作區組件時,它呈現工作區圖形,然後渲染其子節點。

但是,我想要得到我的工作區組件生成的圖像(其中包括工作區圖形和兒童圖形)。

我該怎麼做?

我試圖通過使用我自己的圖形自己調用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; 
} 

歡迎任何想法或意見! :)

回答

3

如果您太早調用getImage,您的組件將不會被顯示,仍然會有一個0寬度和高度。你有沒有確保你在晚些時候給它打電話?嘗試將組件的大小打印到標準輸出並查看其尺寸。

+0

方法'getImage'由用戶調用,這意味着應用程序有足夠的時間。 – user20298 2008-09-22 09:12:59

1

看起來像這個問題是由於如何創建BufferedImage。使用時:

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

反而它工作。我也必須改變從paintComponent切換到繪畫來渲染孩子。

問題解決了,但是如果有人知道的話。爲什麼我的:

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

總是渲染一個黑色的圖像? Offtopic,但可能會有趣的知道:)

+0

我有一個類似的問題 - 將新的BufferedImage類型更改爲BufferedImage.TYPE_INT_RGB解決了問題。 – 2010-09-02 14:05:04

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的「解決方案」與實際問題無關。我建議你刪除它。

+0

_不要從外面調用paint()只是錯誤的。你當然可以從任何你想調用的paint--這是一個沒有任何限制的公共方法。 – kleopatra 2012-01-13 11:25:42

0

將新的BufferedImage更改爲TYPE_INT_RGB爲我解決了這個問題。我不能給出解釋 - 只是一個擺動的奧祕。

public BufferedImage getImage() { 

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

    return hello; 
}