Java 在JPanel中绘制组装的图像

Java 在JPanel中绘制组装的图像,java,swing,graphics,bufferedimage,paintcomponent,Java,Swing,Graphics,Bufferedimage,Paintcomponent,我正在编写一个程序,可以用来在全班同学面前展示主题。虽然MS Powerpoint和类似的程序很不错,但我觉得它们在某些方面有所欠缺。我不是在尝试重新创建这些程序,我只是在尝试制作一个程序,在这个程序中,我可以将文本键入字符串数组,添加图像,并将它们全部放在屏幕上 目前,我的程序打开一个全屏黑色窗口,左上角有一个小X,单击该窗口将关闭程序 下面是类文件: import java.awt.Color; import java.awt.Graphics; import java.awt.Graphi

我正在编写一个程序,可以用来在全班同学面前展示主题。虽然MS Powerpoint和类似的程序很不错,但我觉得它们在某些方面有所欠缺。我不是在尝试重新创建这些程序,我只是在尝试制作一个程序,在这个程序中,我可以将文本键入字符串数组,添加图像,并将它们全部放在屏幕上

目前,我的程序打开一个全屏黑色窗口,左上角有一个小X,单击该窗口将关闭程序

下面是类文件:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.MouseInfo;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Scanner;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;


public class Main {

    static JFrame frame;
    static MyPanel panel;
    static MouseListener listener;

    static final int letterWidth = 6;
    static final int letterHeight = 9;
    static final int letterRow = 10;
    static final int letterCol = 11;
    static final int letterNum = 110;

    static String[] textA = {"Hello World,",
                "Here is a test",
                "of what I can do.",
                "Isn't it neat?!"
                };
    static int textX = 100;
        static int textY = 100;

    public static void main(String[] args){
        System.out.println("Welcome to Presenter");
        System.out.println("Beginning loading");
        frame = new JFrame();
        panel = new MyPanel();

        listener = new MouseListener(){
            public void mouseClicked(MouseEvent arg0) {
                if(arg0.getButton() ==MouseEvent.BUTTON1){

                        //Close button
                    int x = (int) MouseInfo.getPointerInfo().getLocation().getX();
                        int y = (int) MouseInfo.getPointerInfo().getLocation().getY();
                    if(x>20 && x<48 && y>20 && y<56){
                        frame.dispose();
                            System.exit(0);
                    }


                }
             }

            public void mouseEntered(MouseEvent arg0) {}

            public void mouseExited(MouseEvent arg0) {}

            public void mousePressed(MouseEvent arg0) {}

            public void mouseReleased(MouseEvent arg0) {}
        };


        frame.setUndecorated(true);
        frame.setVisible(true);
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH); 
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setFocusable(true);
        frame.add(panel);
            frame.addMouseListener(listener);
            System.out.println("");
        System.out.println("Loading Complete");
    }



public static class MyPanel extends JPanel{
    private static final long serialVersionUID = 1L;

    HashMap<String, BufferedImage> iLetters;
    static BufferedImage exitButton = new BufferedImage(28, 36, BufferedImage.TYPE_INT_ARGB);
    static BufferedImage letters = new BufferedImage(120, 198, BufferedImage.TYPE_INT_ARGB);
    Scanner lightbulb;
    static boolean point = false;
    int x;
    int y;
    BufferedImage textBox;
    int boxW, boxH;

    public MyPanel(){
        //pictures
        File a = new File("Exit.png");
        try { exitButton = ImageIO.read(a); } catch (IOException e) {e.printStackTrace();}
        a = new File("Letters.png");
        try { letters = ImageIO.read(a); } catch (IOException e) {e.printStackTrace();}
        //letter index
        try { lightbulb = new Scanner(new File("letters.txt")); } catch (FileNotFoundException e) {e.printStackTrace();}

        System.out.println("Files Read");



        //create letters
        System.out.println("Beginning tiling");
        iLetters = new HashMap<String, BufferedImage>();
        BufferedImage[] pics = new BufferedImage[letterNum];
        int count = 0;
        for(int x=0; x<letterCol; x++){
            for(int y=0; y<letterRow; y++){
                pics[count] = new BufferedImage(letterWidth, letterHeight, BufferedImage.TYPE_INT_ARGB);

                Graphics2D gr = pics[count++].createGraphics();
                gr.drawImage(letters, 0, 0, letterWidth, letterHeight, letterWidth * y, letterHeight * x, letterWidth * y + letterWidth, letterHeight * x + letterHeight, null);
                gr.dispose();
            }
            System.out.println("Row " + x + " tiled.");
        }
        System.out.println("Completed Tiling");

        System.out.println("Beginning indexing");
        int loc = 0;
        String key = "";
        while(lightbulb.hasNext()){
            loc = lightbulb.nextInt()-1;
            key = lightbulb.next();
            iLetters.put(key, pics[loc]);
        }
        System.out.println("Indexing Complete");

        System.out.println("Making Text Boxes");
        makeTextBox(textA);

        System.out.println("Text Boxes Made");

    }

    public void paintComponent(Graphics g){
        super.paintComponent(g);
        this.setBackground(new Color(0, 0, 10));
        g.drawImage(exitButton, 20, 20, null);
//          g.drawImage(iLetters.get("A"), 100, 100, null);
        drawTexts(g);
    }

    public void drawTexts(Graphics g){
        g.drawImage(textBox, textX, textY, textX+(boxW*2), textY+(boxH*2), null);
    }

    public int findLongest(String[] text){
        int longest = 0;
        for(int i=0; i<text.length; i++){
            if(text[i].length() > longest)
            longest = text[i].length();
        }
        return longest;
    }

    public void makeTextBox(String[] text){
        int longest = findLongest(text);
        boxW = (longest*6)+(longest-1);
        boxH = (text.length*9)+(text.length-1);
        textBox = new BufferedImage(boxW, boxH, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = textBox.createGraphics();
        char[] line;
        int drawX = 0;
        int drawY = 0;


        for(int i=0; i<text.length; i++){
            line = text[i].toCharArray();
            for(int j=0; j<line.length; j++){
                if(j<line.length-1){
                    g2d.drawImage(iLetters.get(line[j]), drawX, drawY, null);
                    drawX += letterWidth + 1;
                }
                else{
                    g2d.drawImage(iLetters.get(line[j]), drawX, drawY, null);
                }
            }
            if(i<text.length-1){
                drawY += letterHeight + 1;
            }
            else{
                drawY += letterHeight;
            }
        }
        g2d.dispose();
    }






}

}
导入java.awt.Color;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.MouseInfo;
导入java.awt.event.MouseEvent;
导入java.awt.event.MouseListener;
导入java.awt.image.buffereImage;
导入java.io.File;
导入java.io.FileNotFoundException;
导入java.io.IOException;
导入java.util.HashMap;
导入java.util.Scanner;
导入javax.imageio.imageio;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
公共班机{
静态JFrame;
静态MyPanel;
静态鼠标侦听器;
静态最终整型字体宽度=6;
静态最终整数字母高度=9;
静态最终整数字母行=10;
静态最终整数=11;
静态最终int-letterNum=110;
静态字符串[]textA={“Hello World,”,
“这是一个测试”,
“我能做什么。”,
“这不是很整洁吗?!”
};
静态int textX=100;
静态int textY=100;
公共静态void main(字符串[]args){
System.out.println(“欢迎来到演示者”);
系统输出打印项次(“开始加载”);
frame=新的JFrame();
panel=新的MyPanel();
侦听器=新的鼠标侦听器(){
公共无效鼠标单击(鼠标事件arg0){
if(arg0.getButton()==MouseEvent.BUTTON1){
//关闭按钮
int x=(int)MouseInfo.getPointerInfo().getLocation().getX();
int y=(int)MouseInfo.getPointerInfo().getLocation().getY();

如果(x>20&&x20&&y正常,这可能需要一些时间

共有10列11行,这些都是错误的方向

static final int letterRow = 10;
static final int letterCol = 11;

我想你不明白gr.drawImage(字母,0,0,letterWidth,letterHeight,letterWidth*y,letterHeight*x,letterWidth*y+letterWidth,letterHeight*x+letterHeight,null);
实际上在做什么,你真正想要的是
BuffereImage#getSubImage

BufferedImage subimage = letters.getSubimage(letterWidth * x, letterHeight * y, letterWidth, letterHeight);
您正在按行/列顺序读取
Letters.png
文件,但正在构建映射,就像它是按列/行顺序一样

而不是

for (int x = 0; x < letterCol; x++) {
    for (int y = 0; y < letterRow; y++) {
另外,在每一行中,您都没有使用
drawX
变量,因此文本一直在运行…事实上,我只是重新编写了循环,使其看起来更像

BufferedImage img = iLetters.get(Character.toString(line[j]));
for (int i = 0; i < text.length; i++) {
    line = text[i].toCharArray();
    for (int j = 0; j < line.length; j++) {
        BufferedImage img = iLetters.get(Character.toString(line[j]));
        g2d.drawImage(img, drawX, drawY, null);
        if (j < line.length - 1) {
            drawX += letterWidth + 1;
        }
    }
    drawX = 0;
    if (i < text.length - 1) {
        drawY += letterHeight + 1;
    } else {
        drawY += letterHeight;
    }
}
for(int i=0;i
是的,它可以简化得更多,但步骤很小


可能还有很多其他的东西,但这应该会让你更接近……

我认为你不明白什么是
drawImage(图像img,int dx1,int dy1,int dx2,int sx1,int sy1,int sx2,int sy2,ImageObserver)
事实上是这样的你是对的,我不知道。我会去看看。编辑:现在我明白了它的作用。看看
BufferedImage#getSubImage
,我想它会做你想做的;)哦,这更干净了,谢谢你,它创建了新的错误。我会尝试解决它们,但现在我不确定这是否解决了我原来的问题。我将
drawImage()
更改为
lets.getSubimage()
,现在我在线程“main”java.awt.image.RasterFormatException:(x+width)中得到了错误
异常位于sun.awt.image.ByteInterleveDraster.createWritableChild(未知源)的光栅外部,位于主$MyPanel的java.awt.image.BuffereImage.getSubimage(未知源)处。(Main.java:117)位于Main.Main(Main.java:43)
,它以前工作过,我要求它打印单个字符。我重新更改了它,现在它可以正常打印。我将查看是否可以获取
getSubimage()
要工作,但如果没有,我会坚持其他我更改了很多东西,可能遗漏了一些东西…确保您已正确更新了
letterRow
letterCol
值;)我成功了!现在唯一的问题是文本在右侧和底部被截断我正在使用您的循环。此外,我更改了drawImage()将DrawText改为
g.drawImage(textBox,textX,textY,(boxW)*2,(boxH)*2,null);
,这消除了文本扭曲的奇怪方式。编辑:这一更改修复了我的问题
for (int i = 0; i < text.length; i++) {
    line = text[i].toCharArray();
    for (int j = 0; j < line.length; j++) {
        BufferedImage img = iLetters.get(Character.toString(line[j]));
        g2d.drawImage(img, drawX, drawY, null);
        if (j < line.length - 1) {
            drawX += letterWidth + 1;
        }
    }
    drawX = 0;
    if (i < text.length - 1) {
        drawY += letterHeight + 1;
    } else {
        drawY += letterHeight;
    }
}