PaintComponent没有被称为Java [英] PaintComponent is not being called-Java

查看:161
本文介绍了PaintComponent没有被称为Java的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的代码应该在随机位置绘制三次随机大小的图像。出于某种原因,当我使用BlueJ运行此代码时,显示的所有内容都是灰色屏幕。我认为这是因为没有调用PaintComponent,但我不太确定。我的代码出了什么问题,如何解决?

  class PanelHolder扩展JPanel {//类PanelHolder扩展JPanel 
//变量
public boolean threesharks;
public int xcoord;
public int ycoord;
公共比率;
public Image i;
public int w;
public int h;
public boolean background = true;
颜色水=新颜色(136,180,231);


public PanelHolder(){//构造函数

i = Toolkit.getDefaultToolkit()。getImage($ harkz.png);

}
public void randomxy(){
for(int x = 0; x< 3; x ++){
threesharks = true;
ycoord =(int)(Math.random()* 300 + 200); //使用math.random计算坐标并调整大小
xcoord =(int)(Math.random()* 1000 +0); //创建循环
ratio =(int)(Math.random()* 5 + 1);
w =比率* 523;
h =比率* 195;
repaint();
System.out.println(我在随机);

//每次
//调用repaint()三次后,make threesharks = false
}
threesharks = false;
}
public void paintComponent(Graphics g){
if(threesharks){
setBackground(water);
System.out.print(hi!);
if(background){
super.paintComponent(g); // set backgroun
background = false;
}
g.drawImage(i,xcoord,ycoord,w,h,this);
}
}

}

解决方案

你似乎对绘画在Swing中的运作方式有误解。当它认为你的组件需要重新绘制时,Swing会调用你的 paintComponent ,这可能由于许多不同的原因而发生,其中许多是你无法控制的。



Swing中的绘画是破坏性的,也就是说,每次调用 paintComponent 方法时,都需要重新绘制整个从零开始的组件状态,绘画不是很准确。



这意味着你需要以一些有意义的方式存储你想要绘制的东西的状态并重新使用这些值是必需的。



看看

  import java.awt.Color; 
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

公共类测试{

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

public Test(){
EventQueue.invokeLater(new Runnable(){
@Override
public void run(){
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch(ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex){
ex.printStackTrace();
}

JFrame frame = new JFrame(Testing);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new PanelHolder());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}

class PanelHolder扩展JPanel {//类PanelHolder扩展JPanel
//变量

public boolean threesharks;
public BufferedImage i;
public boolean background = true;
颜色水=新颜色(136,180,231);

私人Point []积分;
private Image []图片;

public PanelHolder(){
// constructor

try {
i = ImageIO.read(...);
} catch(IOException ex){
ex.printStackTrace();
}

randomxy();
}

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

public void randomxy(){
points = new Point [3];
images = new Image [3];
for(int x = 0; x< 3; x ++){
points [x] = new Point();

双倍比率=(Math.random()* 6d)+ 0.1d;
int width =(int)(ratio * i.getWidth());
int height =(int)(ratio * i.getHeight());
points [x] .y = Math.max(0,(int)(Math.random()* 800) - height); //使用math.random来计算坐标并调整
点的大小[x] .x = Math.max(0,(int)(Math.random()* 800) - width); //制作循环

images [x] = i.getScaledInstance(宽度,高度,Image.SCALE_SMOOTH);

}
}

public void paintComponent(Graphics g){
super.paintComponent(g); // set backgroun
g .setColor(水);
g.fillRect(0,0,getWidth(),getHeight());
if(points!= null&& images!= null){
for(int index = 0; index< points.length; index ++){
g.drawImage(images [index],points [index] .x,points [index] .y,this);
}
}
}
}

}

这是一个粗略的例子,它使用 Image#getScaledInstance ,这通常不推荐,但适用于该示例。



看看 Image.getScaledInstance()的危险性更多细节



看看调整大小非常低的图像质量 - Java Java:保持JPanel背景图像的纵横比可能(缩放)替代方案



我还要看看读取/加载图像以获得更好的加载图像的机制


My code is supposed to draw a random sized image three times in random locations. For some reason, when I run this code using BlueJ, all that shows up is a gray screen. I think it is because PaintComponent isn't being called, but I am not quite sure. What went wrong with my code and how can I fix it?

class PanelHolder extends JPanel{//class PanelHolder extends JPanel
//variables
public boolean threesharks;
public int xcoord;
public int ycoord;
public int ratio;
public Image i;
public int w;
public int h;
public boolean background=true;
Color water = new Color(136, 180, 231);


public PanelHolder(){//constructor

    i = Toolkit.getDefaultToolkit().getImage("$harkz.png");

}
public void randomxy(){
    for(int x=0;x<3;x++){
        threesharks=true;
        ycoord=(int)(Math.random()*300+200);//use math.random to figure out coordinates and sizing
        xcoord=(int)(Math.random()*1000+0);//make a loop
        ratio=(int)(Math.random()*5+1);
        w=ratio*523;
        h=ratio*195;
        repaint();
        System.out.println("I'm in randomxy");

        //call repaint() each time
        //after three times, make threesharks=false
    }
    threesharks=false;
}
public void paintComponent(Graphics g){
    if(threesharks){
        setBackground(water);
        System.out.print("hi!");
        if(background){
            super.paintComponent(g);//set backgroun
            background=false;
        }
        g.drawImage(i, xcoord, ycoord, w, h, this);
    }
    }

}

解决方案

You seem to have a misunderstanding with how painting works in Swing. Swing will call your paintComponent when ever it thinks your component needs to be repainted, this might occur for many different reasons, many of which you don't have control over.

Painting in Swing is destructive, that is, each time your paintComponent method is called, you are expected to repaint the entire state of the component from scratch, painting is not accumalitive.

This means that you need to store the state of things you want to paint in some meaningful manner and re-use these values are needed.

Have a look at Painting in AWT and Swing and Performing Custom Painting for more details about how painting works in Swing

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

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

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new PanelHolder());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    class PanelHolder extends JPanel {//class PanelHolder extends JPanel
//variables

        public boolean threesharks;
        public BufferedImage i;
        public boolean background = true;
        Color water = new Color(136, 180, 231);

        private Point[] points;
        private Image[] images;

        public PanelHolder() {
            //constructor

            try {
                i = ImageIO.read(...);
            } catch (IOException ex) {
                ex.printStackTrace();
            }

            randomxy();
        }

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

        public void randomxy() {
            points = new Point[3];
            images = new Image[3];
            for (int x = 0; x < 3; x++) {
                points[x] = new Point();

                double ratio = (Math.random() * 6d) + 0.1d;
                int width = (int) (ratio * i.getWidth());
                int height = (int) (ratio * i.getHeight());
                points[x].y = Math.max(0, (int) (Math.random() * 800) - height);//use math.random to figure out coordinates and sizing
                points[x].x = Math.max(0, (int) (Math.random() * 800) - width);//make a loop

                images[x] = i.getScaledInstance(width, height, Image.SCALE_SMOOTH);

            }
        }

        public void paintComponent(Graphics g) {
            super.paintComponent(g);//set backgroun
            g.setColor(water);
            g.fillRect(0, 0, getWidth(), getHeight());
            if (points != null && images != null) {
                for (int index = 0; index < points.length; index++) {
                    g.drawImage(images[index], points[index].x, points[index].y, this);
                }
            }
        }
    }

}

This is a rough example, which uses Image#getScaledInstance which is not generally recommended, but works for the example.

Have a look at The Perils of Image.getScaledInstance() for more details

Have a look at Quality of Image after resize very low -- Java and Java: maintaining aspect ratio of JPanel background image for possible (scaling) alternatives

I'd also have a look at Reading/Loading an Image for a better mechanism for loading images

这篇关于PaintComponent没有被称为Java的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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