【问题标题】:Drawing imageS in java using AWT使用 AWT 在 java 中绘制图像
【发布时间】:2017-05-08 07:06:30
【问题描述】:

编辑:第一个问题已解决,请参阅 Roberto Attias 's answer 并可能阅读评论。还有第二个问题。

我必须用 Java 做一个小型 2D 游戏,我想尽可能坚持使用 AWT,(所以除非绝对必要,否则不要使用 SWING 或 Java2D)。

我有一个窗口,可以在上面绘制图像,但有两个问题。 首先,我不能绘制多个图像。事实上,通过调试时的一些测试,我可以看到我的程序将绘制我的两个图像只是为了删除它们并重新绘制第一个图像。 其次,重新绘制的第一张图像不在应有的坐标上(略在左侧和下方)

现在我有类似的东西:

public class AwtManager {
    private Frame frame;
    private Panel panel;
    public AwtManager(){
        frame = new Frame("a");
        frame.setSize(800,600);
        frame.setLocation(100, 100);
        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent windowEnvent){
                System.exit(0);
            }
        });

    panel = new Panel();
    // here I tried to setBounds to solve my second issue, it didn't work
    //panel.setBounds(0, 0, 800, 600);
    frame.add(panel);
    frame.setVisible(true);
    }

这部分打开了我的窗口并且工作得很好,但我的第二个问题似乎是由我的框架/面板的边框引起的,所以这里可能需要做一些改变。

    public void showMytwoImagesFFS(ArrayList<ImageComponent> images){
        for (int i = 0; i < images.size(); i++) {
            panel.add(images.get(i);
            //And this is where I'm lost

        }
        // or here maybe
        frame.setVisible(true);
    }
}

在第二部分中,我尝试了我能想到的 Component.paint(g)、Component.update(g)、Component.repaint()、Component.setVisible(true) 的所有组合。

我的对象 ImageComponent 就是这样的:

public class ImageComponent extends Component {
    private static final long serialVersionUID = 1L;
    private BufferedImage img;
    private int x;
    private int y;

    public ImageComponent(String path,int x, int y){
        try{
            img = ImageIO.read(new File(path));
            this.x = x;
            this.y = y;
        }
        catch (IOException e){
            e.printStackTrace();
        }
    }

这个函数 getPreferredSize() 像地狱一样打扰我,它应该返回 ImageComponent 的首选大小,但显然我必须输入我的框架/面板的大小,否则它将无法工作。

    public Dimension getPreferredSize(){
        return new Dimension(800,600);
    }

最后是我的绘画、更新、重绘:

    public void paint(Graphics g){
        g.drawImage(img, x, y,null);    
    }

    public void update(Graphics g){
        super.update(g);
    }

    public void repaint(){
        this.getGraphics().drawImage(img, x, y, null);
    }
}

我非常怀疑这三个看起来应该是什么,但我发现有关该主题的文档很难理解。

所以请你帮我解决这些问题,顺便说一下,如果你知道 Component.setVisible(boolean) 是如何工作的,我想知道,因为在调试模式中,这个函数让我松了一些头发。

编辑:

这是我的窗口的屏幕截图,知道我要求两个红色正方形(图像不是矩形),一个是 0,0,另一个是 200、200。

编辑 2: 这是一个完全可运行的代码(我认为):

import java.awt.*;
import java.util.*;
import java.awt.event.*;

public class AwtManager {
    private Frame frame;
    private Panel panel;

    public static void main(String args[]) {
        new AwtManager();
        ArrayList<ImageComponent> images = new ArrayList<>();
        images.add(new ImageComponent("myimage.jpg", 0, 0));
        images.add(new ImageComponent("myimage.jpg", 200, 200));
        showMytwoImagesFFS(images); 
    }  


    public AwtManager(){
        frame = new Frame("a");
        frame.setSize(800,600);
        frame.setLocation(100, 100);
        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent windowEnvent){
                System.exit(0);
            }
        });

        panel = new Panel();
        frame.add(panel);
        frame.setVisible(true);
    }

    public void showMytwoImagesFFS(ArrayList<ImageComponent> images){
        for (int i = 0; i < images.size(); i++) {
            panel.add(images.get(i));
        }
        frame.setVisible(true);
    }
}

import java.io.*;
import java.awt.*;
import java.awt.image.*;
import javax.imageio.ImageIO;
public class ImageComponent extends Component {
    private static final long serialVersionUID = 1L;
    private BufferedImage img;
    private int x;
    private int y;

    public ImageComponent(String path,int x, int y){
        try{
            img = ImageIO.read(new File(path));
            this.x = x;
            this.y = y;
        }
        catch (IOException e){
            e.printStackTrace();
        }
    }

    public Dimension getPreferredSize(){
        return new Dimension(800,600);
    }

    public void paint(Graphics g){
        g.drawImage(img, x, y,null);    
    }

    public void update(Graphics g){
        super.update(g);
    }

    public void repaint(){
        this.getGraphics().drawImage(img, x, y, null);
    }
}

【问题讨论】:

  • “第一个问题解决了”,你不给不分??恕我直言,你是个失败者
  • 对不起,我忘了我可以给出点,我专注于“接受的回应”,遗憾的是我现在不能给出,知道我仍然有问题。无论如何,感谢上帝,您注意到我对 SO(只有其中的 11 个神圣点)提出问题还很陌生,并且没有被称为“失败者”。
  • 显然我不能给出点,我需要15个,我该怎么办?

标签: java image graphics awt


【解决方案1】:

快速思考一下,但您知道每个图像在该 ArrayList 中的可见性吗?即

public void showMytwoImagesFFS(ArrayList<ImageComponent> images){
    for (int i = 0; i < images.size(); i++) {
        images.get(i).setVisible(true);//is the visibility actually true?
        panel.add(images.get(i);

    }
    // or here maybe
    frame.setVisible(true);
}

另外,你有你的程序目前的截图吗?对于 gui 问题,如果我能看到发生了什么,我发现它们会更容易解决。

【讨论】:

  • 我只是看了看,如果我问: images.get(i).isVisible() ;我的两张图片都正确,我将在几秒钟内添加屏幕截图。
【解决方案2】:

这是您的代码,稍作修改即可运行。将来,请发布完全可运行的示例。

import java.awt.*;
import java.util.*;
import java.awt.event.*;

public class AwtManager {
    private Frame frame;
    private Panel panel;

    public static void main(String args[]) {
      new AwtManager();
    }


    public AwtManager(){
        frame = new Frame("a");
        frame.setSize(800,600);
        frame.setLocation(100, 100);
        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent windowEnvent){
                System.exit(0);
            }
        });

    panel = new Panel();
    // here I tried to setBounds to solve my second issue, it didn't work
    //panel.setBounds(0, 0, 800, 600);
    frame.add(panel);
    ArrayList<ImageComponent> images = new ArrayList<>();
    images.add(new ImageComponent("myimage.jpg", 0, 0));
    showMytwoImagesFFS(images);
    frame.setVisible(true);
  }

   public void showMytwoImagesFFS(ArrayList<ImageComponent> images){
        for (int i = 0; i < images.size(); i++) {
            panel.add(images.get(i));
        }
    }
}

import java.io.*;
import java.awt.*;
import java.awt.image.*;
import javax.imageio.ImageIO;

public class ImageComponent extends Component {
    private static final long serialVersionUID = 1L;
    private BufferedImage img;
    private int x;
    private int y;

    public ImageComponent(String path,int x, int y){
        try{
            img = ImageIO.read(new File(path));
            this.x = x;
            this.y = y;
        }
        catch (IOException e){
            e.printStackTrace();
        }
    }

   public Dimension getPreferredSize(){
        return new Dimension(800,600);
    }
   public void paint(Graphics g){
        g.drawImage(img, x, y,null);
    }

    public void update(Graphics g){
        super.update(g);
    }

    public void repaint(){
        this.getGraphics().drawImage(img, x, y, null);
    }
}

【讨论】:

  • 对不起,我认为这不是问题,我将在问题中添加一个完全可运行的代码。在您的版本中,您在构造函数中调用 showMyTwoImagesFFS(ArrayList),在第一个 frame.setVisible() 之前,这可能在这种情况下有效,但是,如果我希望图像在几秒钟后弹出,任何原因那个?
  • 我不确定您打算何时添加这些内容。在大多数情况下,UI 是在初始化时布局的。如果您需要在可视化后修改 UI 外观(添加/删除组件、更改布局管理器等),您可能需要调用 revalidate()
  • 哦,我不知道,我会做一些测试
  • 我做了一些测试,我可以一次显示几张图片,谢谢。现在我只有坐标的问题。
猜你喜欢
  • 1970-01-01
  • 2018-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-02
  • 2011-10-26
相关资源
最近更新 更多