我試圖將JScrollPane(大於屏幕)的主視口和標題保存爲PNG圖像文件。我創建了3個類擴展JPanel(MainTablePanel,MapsHeaderPanel和ItemsHeaderPanel)並將它們設置爲視口。他們每個人都有這個方法:JScrollPane內容到圖像
public BufferedImage createImage() {
BufferedImage bi = new BufferedImage(getSize().width, getSize().height, BufferedImage.TYPE_INT_ARGB);
Graphics g = bi.createGraphics();
paint(g);
g.dispose();
return bi;
}
每個班級也有一個paint方法,其繪製背景,然後調用super.paint()畫一些標籤。例如:
public void paint(Graphics g){
g.setColor(Color.BLACK);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(new Color(255, 255, 0, 50));
// for loop that paints some vertical yellow lines
for(int i=0; i<getWidth(); i+=K.mW){
g.fillRect(i-1, 0, 2, getHeight());
if(i%(K.mW*5)==0){
g.fillRect(i-2, 0, 4, getHeight());
}
}
// called to pain some rotated JLabels
super.paint(g);
}
來自外部的JFrame我又試圖將其保存爲PNG文件,使用此代碼:
BufferedImage tableImg = mainTableP.createImage();
BufferedImage topImg = mapsHeaderP.createImage();
BufferedImage leftImg = itemsHeaderP.createImage();
ImageIO.write(tableImg, "png", new File(s.homeDir+"/table.png"));
ImageIO.write(topImg, "png", new File(s.homeDir+"/top.png"));
ImageIO.write(leftImg, "png", new File(s.homeDir+"/left.png"));
這是應用程序運行的截圖:screenshot
而且這是導出的頭文件:top
如果我評論「super.paint(g)」指令,我得到一個正確的圖像(因此沒有所有JLables,cl早)。 看起來像第二個paint(super.paint(g))被繪製到BufferedImage中,並將元素放在它的JPanel之外。有人可以解釋我這種行爲?謝謝。
==========編輯SSCCE ================================= ===
這應該編譯。你可以按原樣執行它,並在c:\中找到兩個圖像(top.png和left.png),它們應該與兩個標題相同。不幸的是,他們不是。背景不繪。此外(特別是如果你看看left.png),你可以看到標籤被塗刷兩次並移位(例如,注意「Left test 21」)。
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.*;
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setLayout(null);
frame.setSize(800, 600);
JScrollPane scrollP = new JScrollPane();
scrollP.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scrollP.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
MyPanel top = new MyPanel();
for(int i=0; i<30; i++){
JLabel label = new JLabel("Test "+i);
label.setOpaque(false);
label.setBounds(50*i, 40, 50, 20);
label.setForeground(Color.GREEN);
top.add(label);
}
top.setLayout(null);
top.setOpaque(false);
top.setPreferredSize(new Dimension(50*30, 200));
top.validate();
MyPanel left = new MyPanel();
for(int i=0; i<30; i++){
JLabel label = new JLabel("Left test "+i);
label.setBounds(0, 50*i, 100, 20);
label.setForeground(Color.RED);
left.add(label);
}
left.setLayout(null);
left.setOpaque(false);
left.setPreferredSize(new Dimension(200, 50*30));
MyPanel center = new MyPanel();
center.setLayout(null);
center.setOpaque(false);
center.setPreferredSize(new Dimension(50*30, 50*30));
scrollP.setViewportView(center);
scrollP.setColumnHeaderView(top);
scrollP.setRowHeaderView(left);
scrollP.setBounds(0, 50, 750, 500);
frame.add(scrollP);
frame.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
try{
BufferedImage topImg = top.createImage();
ImageIO.write(topImg, "png", new File("C:/top.png"));
BufferedImage leftImg = left.createImage();
ImageIO.write(leftImg, "png", new File("C:/left.png"));
}catch(Exception e){
e.printStackTrace();
}
}
}
class MyPanel extends JPanel{
public void paint(Graphics g){
g.setColor(Color.BLACK);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(new Color(255, 255, 0, 50));
for(int i=0; i<getWidth(); i+=50){
g.fillRect(i-1, 0, 2, getHeight());
}
super.paint(g); // COMMENT this line to obtain background images
}
public BufferedImage createImage() {
BufferedImage bi = new BufferedImage(getSize().width, getSize().height, BufferedImage.TYPE_INT_ARGB);
Graphics g = bi.createGraphics();
paint(g);
g.dispose();
return bi;
}
}
如果你調用'super.paint(g);'作爲'paint();'中的第一行呢? –
@Nikolay Kuznetsov可能不是關於視口 – mKorbel
@塞巴斯蒂安Ikaros Rizzo這個問題是不能回答,以更好的幫助更快發佈[SSCCE](http://sscce.org/),短,可運行,編譯 – mKorbel