简体   繁体   English

将组合图像绘制到JPanel

[英]Drawing an assembled image to the JPanel

I am working on a program that I can use to present topics in front of my class. 我正在开发一个程序,可以用来在课堂前介绍主题。 While MS Powerpoint and similar programs are nice, I feel like they are lacking in some areas. 虽然MS Powerpoint和类似程序很好,但我感觉在某些方面缺少它们。 I am not trying to re-create these programs, I am only trying to make a program where I can type text into String arrays, add images, and position them all on the screen. 我不是在尝试重新创建这些程序,而是在尝试创建一个程序,可以在其中将文本键入String数组,添加图像并将它们全部放置在屏幕上。

Currently my program opens a fullscreen dark window with a little X in the top left, which when clicked will close the program. 目前,我的程序打开了一个全屏暗窗口,在左上角有一个小X,单击该窗口将关闭程序。

Here is the class file: 这是类文件:

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();
    }






}

}

The rest of the files needed for it to run are here http://www.mediafire.com/?jq8vi4dm3t4b6 运行它所需的其余文件位于http://www.mediafire.com/?jq8vi4dm3t4b6

2 PNGs and 1 text file. 2个PNG和1个文本文件。

The program runs fine with no errors. 该程序运行正常,没有错误。 The only problem is the drawTexts() method. 唯一的问题是drawTexts()方法。 When the method is called, the lines of text do not appear anywhere on screen, when they should be appearing at (100, 100) at 2x the size of the letters in the file. 调用该方法时,文本行不应出现在屏幕上的任何位置,而应以文件中字母大小的2倍出现在(100,100)处。

It's been a while since I did graphics. 自从我做图形以来已经有一段时间了。 I remember needing to call repaint() somewhere, but I cannot remember if I need it here, and if I do, where it goes. 我记得需要在某个地方调用repaint(),但是我不记得在这里是否需要它,如果需要的话,它在哪里。

Okay, this might take some time... 好吧,这可能需要一些时间...

快报

There are 10 columns and 11 rows, these are around the wrong way... 一共有10列和11行,这些都绕错了方向...

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

I don't think you understand what gr.drawImage(letters, 0, 0, letterWidth, letterHeight, letterWidth * y, letterHeight * x, letterWidth * y + letterWidth, letterHeight * x + letterHeight, null); 我不认为您了解什么gr.drawImage(letters, 0, 0, letterWidth, letterHeight, letterWidth * y, letterHeight * x, letterWidth * y + letterWidth, letterHeight * x + letterHeight, null); is actually doing, what you really want is BufferedImage#getSubImage ... 实际上是在做,您真正想要的是BufferedImage#getSubImage ...

BufferedImage subimage = letters.getSubimage(letterWidth * x, letterHeight * y, letterWidth, letterHeight);

You're reading the Letters.png file in row/column order, but building the mapping as if it was in column/row order... 您正在按行/列顺序阅读Letters.png文件,但要像按列/行顺序构建映射一样...

Instead of... 代替...

for (int x = 0; x < letterCol; x++) {
    for (int y = 0; y < letterRow; y++) {

You should be using... 您应该使用...

for (int y = 0; y < letterRow; y++) {
    for (int x = 0; x < letterCol; x++) {

The lightbulb Scanner is not reading the file...I'm don't use Scanner that often, but when I changed it to lightbulb = new Scanner(new BufferedReader(new FileReader("letters.txt"))); lightbulb Scanner不会读取文件...我不经常使用Scanner ,但是当我将其更改为lightbulb = new Scanner(new BufferedReader(new FileReader("letters.txt"))); it worked... 有效...

In your makeTextBox method you are trying to retrieve the image using a char instead of String , this means the lookup fails as the two keys are incompatible. 在您的makeTextBox方法中,您尝试使用char而不是String检索图像,这意味着查找失败,因为两个键不兼容。 You need to use something more like... 您需要使用更多类似...

BufferedImage img = iLetters.get(Character.toString(line[j]));

Also, on each new line, you are not resting the drawX variable, so the text just keeps running off...In fact, I just re-wrote the loop to look more like... 另外,在每一行中,您都没有drawX变量,因此文本一直在运行……事实上,我只是重新编写了循环,使其看起来更像...

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;
    }
}

And yes, it could be simplified more, but little steps... 是的,可以进一步简化,但只需很少的步骤...

There might be a bunch of other things, but that should get you a step closer... 可能还有很多其他事情,但这应该使您更接近……

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM