将JPanel绘制到BufferedImage或将其打印出来,而不先将其渲染到屏幕上 [英] Paint a JPanel to a BufferedImage or Print it without rendering it to screen first

查看:229
本文介绍了将JPanel绘制到BufferedImage或将其打印出来,而不先将其渲染到屏幕上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

图片这是一个程序GUI JFrame,分为2,EAST和WEST。第一个JPanel只是一个打印预览屏幕。 JFrame的EAST端是用户可以创建1 2或3尺寸图像的位置。用户点击添加按钮,右侧的定义图像转到左侧的面板。因此,如果用户点击添加3次不同大小的图像,面板使用FlowLayout来组织添加在左侧的面板图像。



当你运行这个代码,你可以看到我想要的东西。真的有什么更好的是创建所有这些在屏幕外并称之为MainPanel。然后让printPreview扩展MainPanel并将其缩小以进行屏幕视图。然后让Printable方法将MainPanel绘制到打印方法中,这将是一个正确的大小。



所以我的问题...
- 你可以复制或绘制一个JPanel在它被呈现在屏幕上之前?
- 是否有更好的方法来做我想做的事情,我FlowLayout解决了我想要的令人惊讶的事情,所以JPanel似乎是答案,除非有我不知道的东西。



现在好了,那是照片。我已经构建了一些与SSCCE相关的代码,正如我所能得到的。



在New To Java论坛中,我尝试过问这个问题,他们只是不回答,我我不是故意重复发布的,我完全从头开始重写。


import java.awt。*;
import java.awt.image。*;
import java.awt.print。*;
import java.awt.event。*;

public class PrintGrid extends JFrame {

Paper paper = new Paper();

PrintGrid(){
super(检出此网格面板);
setSize(672,750);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);



add(纸);
setVisible(true);

} //结束PrintGrid构造函数



// ****************** ********
// ****** PAPER CLASS *******
// *************** ***********
private class Paper extends JPanel {

final int PAPER_X = 672,PAPER_Y = 975,UNIT = 12,DPI = 72;
X1 x1a = new X1(),x1b = new X1(),x1c = new X1();
X2 x2a = new X2(),x2b = new X2(),x2c = new X2();
X3 x3a = new X3(),x3b = new X3(),x3c = new X3();

Paper(){
setPreferredSize(new Dimension(PAPER_X,PAPER_Y));
setBackground(Color.GRAY);
setLayout(new FlowLayout(FlowLayout.LEADING));

//用户将手动为此工作表添加不同的尺寸。
add(x1a);
add(x2a);
add(x3a);
add(x1b);
add(x1c);
add(x2b);
add(x3b);
}


// ******* GridUnits的父类*******
抽象类GridUnit扩展JPanel {

MouseListen ml = new MouseListen();
float alpha = 1.0f;

GridUnit(){
this.addMouseListener(ml);
}

public void paintComponent(Graphics g){
super.paintComponent(g);
this.setBackground(Color.BLACK);

Graphics2D g2 =(Graphics2D)g;
g2.setComposite(makeComposite(alpha));

g.setColor(Color.WHITE);
g.drawRect(0,0,this.getWidth() - 1,this.getHeight() - 1);

g.setColor(Color.darkGray);
g.fillRect(15,15,this.getWidth() - 30,this.getHeight() - 30);

} //结束paintComponent。

private AlphaComposite makeComposite(float alpha){
int type = AlphaComposite.SRC_OVER;
return(AlphaComposite.getInstance(type,alpha));
}

void click(){
setVisible(false);
}
void entered(){
alpha = 0.8f;
repaint();

}
void exited(){
alpha = 1.0f;
repaint();
}

class MouseListen extends MouseAdapter {
public void mouseEntered(MouseEvent event){
entered();
}
public void mouseExited(MouseEvent event){
exited();

public void mousePressed(MouseEvent event){
click();

}

} //结束GridUnit类

类X1扩展GridUnit {
X1(){
setPreferredSize (新维(UNIT * 13,UNIT * 18));
}
} // end X1 Class

class X2 extends GridUnit {
X2(){
setPreferredSize(new Dimension(UNIT * 26,UNIT * 18));
}
} // end X1 Class
$ b $ class X3 extends GridUnit {
X3(){
setPreferredSize(new Dimension(UNIT * 39,UNIT * 18));
}
} // end X1 Class

} // end Paper class。



public static void main(String [] args){
new PrintGrid();
} //结束main方法。

} //结束PrintGrid类。


解决方案

将任何Java组件绘制到离屏图像,您可以根据自己的喜好进行操作,包括将部分图像或缩放图像复制到最终目标。

子类JComponent并覆盖 void paintComponent (Graphics g)。绘制到 BufferedImage ,然后将图像复制到目标组件。关闭我的脑袋,像这样:

  void paintComponent(Graphics g){
BufferedImage img = new BufferedImage (的getWidth(),的getHeight(),BufferedImage.TYPE_INT_ARGB);
Graphics2D gph =(Graphics2D)img.getGraphics();

//在此处绘制gph
gph.dispose();

g.drawImage(img); //将img的内容绘制到组件的图形上下文中。
}


Picture this... A program GUI JFrame that is split in 2, EAST and WEST. The first JPanel is just a print preview screen. The EAST side of the JFrame is where the user can create a 1 2 or 3 size image. The user clicks the "Add" button and the defined image on the right goes to the panel on the left. So if the user clicks "Add" 3 times with different size images, then the panel uses FlowLayout to organize the added panel images added on the left.

When you run this code, you can see a sorta idea of what I want. Really what would be nice is to create all this off-screen and call it MainPanel. Then have printPreview extend MainPanel and scale it down for screen view. And have the Printable method paint the MainPanel into the print method which would be a correct size.

So my question... -Can you copy or paint a JPanel before it is rendered on the screen? -Is there a better way to do what I want, I FlowLayout solves what I want amazingly, so a JPanel seems to be the answer unless there is something I do not know of.

Ok now that that is pictured. I have built some code that is about as SSCCE as I can get.

Guys I have tried asking this question at New To Java forums and they just do not respond, I am not double posting on purpose, I completely rewrote this from scratch.

import javax.swing.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.print.*;
import java.awt.event.*;

public class PrintGrid extends JFrame {

    Paper paper = new Paper();

    PrintGrid() {
        super("Check out this grid panel");
        setSize(672, 750);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);



        add(paper);
        setVisible(true);

    } // end PrintGrid constructor



    // **************************
    // ****** PAPER CLASS *******
    // **************************
    private class Paper extends JPanel {

        final int PAPER_X = 672, PAPER_Y = 975, UNIT = 12, DPI = 72;
        X1 x1a = new X1(), x1b = new X1(), x1c = new X1();
        X2 x2a = new X2(), x2b = new X2(), x2c = new X2();
        X3 x3a = new X3(), x3b = new X3(), x3c = new X3();

        Paper() {
            setPreferredSize(new Dimension(PAPER_X, PAPER_Y));
            setBackground(Color.GRAY);
            setLayout(new FlowLayout(FlowLayout.LEADING));

            //Users will manually add different sizes to this sheet.
            add(x1a);
            add(x2a);
            add(x3a);
            add(x1b);
            add(x1c);
            add(x2b);
            add(x3b);
        }


        // ******* Parent Class for GridUnits *******
        abstract class GridUnit extends JPanel {

            MouseListen ml = new MouseListen();
            float alpha = 1.0f;

            GridUnit() {
                this.addMouseListener(ml);
            }

            public void paintComponent(Graphics g) {
                super.paintComponent(g);
                this.setBackground(Color.BLACK);

                Graphics2D g2 = (Graphics2D) g;
                g2.setComposite(makeComposite(alpha));

                g.setColor(Color.WHITE);
                g.drawRect(0, 0, this.getWidth()-1, this.getHeight()-1);

                g.setColor(Color.darkGray);
                g.fillRect(15, 15, this.getWidth()-30, this.getHeight()-30);

            } // end paintComponent.

            private AlphaComposite makeComposite(float alpha) {
                int type = AlphaComposite.SRC_OVER;
                return(AlphaComposite.getInstance(type, alpha));
            }

            void click() {
                setVisible(false);
            }
            void entered() {
                alpha = 0.8f;
                repaint();

            }
            void exited() {
                alpha = 1.0f;
                repaint();
            }

            class MouseListen extends MouseAdapter {
                public void mouseEntered(MouseEvent event) {
                    entered();
                }
                public void mouseExited(MouseEvent event) {
                    exited();
                }
                public void mousePressed(MouseEvent event) {
                    click();
                }
            }

        } // end GridUnit class

        class X1 extends GridUnit {
            X1() {
                setPreferredSize(new Dimension(UNIT*13, UNIT*18));
            }
        } // end X1 Class

        class X2 extends GridUnit {
            X2() {
                setPreferredSize(new Dimension(UNIT*26, UNIT*18));
            }
        } // end X1 Class

        class X3 extends GridUnit {
            X3() {
                setPreferredSize(new Dimension(UNIT*39, UNIT*18));
            }
        } // end X1 Class

    } // end Paper class.



    public static void main(String[] args) {
        new PrintGrid();
    } // end main method.

} //  end PrintGrid class.

解决方案

It's quite trivial to paint any Java component to an offscreen image, from which you can do as you please, including copying a portion or scaled image to a final target.

Subclass JComponent and override void paintComponent(Graphics g). Paint to a BufferedImage, then copy the image to the target component. Off the top of my head, something like:

void paintComponent(Graphics g) {
    BufferedImage img=new BufferedImage(getWidth(),getHeight(),BufferedImage.TYPE_INT_ARGB);
    Graphics2D    gph=(Graphics2D)img.getGraphics();

    // paint to gph here
    gph.dispose();

    g.drawImage(img);  // paints the contents of img to the component's graphics context.
    }

这篇关于将JPanel绘制到BufferedImage或将其打印出来,而不先将其渲染到屏幕上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆