Java-单击JComponent向Jframe添加新图像

Java-单击JComponent向Jframe添加新图像,java,multithreading,swing,netbeans,graphics2d,Java,Multithreading,Swing,Netbeans,Graphics2d,我使用netbeans拖放设计器创建了一个Jframe。询问后,我可以在我的Draw类的新线程上从recList和paint(g)更改某些项目的颜色后进行颜色更改 现在我想添加另一个JComponent,比如DrawCar,它将car图像添加到Jframe中。我想要这个新的JComponent,因为如果背景中的方块改变颜色,我不想重新渲染“汽车” 因此,我使用paint()方法创建了DrawCar,如下所示: public void paint(Graphics g) { //Thi

我使用netbeans拖放设计器创建了一个Jframe。询问后,我可以在我的
Draw
类的新线程上从
recList
paint(g)
更改某些项目的颜色后进行颜色更改

现在我想添加另一个JComponent,比如
DrawCar
,它将
car
图像添加到Jframe中。我想要这个新的JComponent,因为如果背景中的方块改变颜色,我不想重新渲染“汽车”

因此,我使用
paint()
方法创建了
DrawCar
,如下所示:

  public void paint(Graphics g) {
    //This to make the (0,0) at the bottom-left not top-left as default.
    Graphics2D g2 = (Graphics2D)g;
    AffineTransform at = g2.getTransform();
    at.translate(0, getHeight());
    at.scale(1, -1);
    g2.setTransform(at);


    //Below is to draw the car
    try {
            image = ImageIO.read(new File("car.png"));
        } catch (IOException ex) {
            Logger.getLogger(Car.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
    g.drawImage(image, 245, 0, null); 
}
如果我将这些代码放在
Draw
类的
paint()
方法中渲染汽车,它会工作,因此此代码没有问题

容器
(带有GUI的类)类中,我有一个按钮处理程序。我希望在单击该按钮时显示汽车,因此我尝试使用

private void starter_btnActionPerformed(java.awt.event.ActionEvent evt) {
        Thread reDraw = new Thread(new Runnable() {
        @Override
        public void run() {
            //draw1 below is the instance of "Draw" class
            //draw1.paint2(draw1.getGraphics());     //This code works with repainting the square with new color as mentioned before

            DrawCar draw2 = new DrawCar();
            repaint();
            revalidate();
            }

        });
        reDraw.start();

 }  
但这行不通,我不知道我错过了什么。也许有一些方法可以将
DrawCar
添加到当前JFrame

谢谢你抽出时间


编辑: 我只是做了一个简单的项目来说明。我创建了一个名为
Test
的JFrame,并在其中放置了一个按钮,当我单击它时,它将显示图片。都是自动生成的代码

现在我创建了一个新的类调用
MyClass

public class MyClass extends JComponent{
private BufferedImage image;

MyClass(){
    try {
            image = ImageIO.read(new File("D://pic.jpg"));
        } catch (IOException ex) {
                   Logger.getLogger(this.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
}

    public void paintComponent(Graphics g){
        super.paintComponent(g);
        g.drawImage(image, 50, 50, null); 
    }
}
测试中
,按钮的事件处理程序如下所示:

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
    // TODO add your handling code here:
    MyClass mc = new MyClass();
    add(mc);
    repaint();
    revalidate();
} 
我点了一下,什么也没发生。图片应该在点击时显示。我该怎么做?多谢各位


编辑2:


这是我想要实现的图像,它是底部的绿色小车,应该只有在我单击“开始”时才会出现。

我看到您的代码中有很多常见问题,包括:

  • 永远不要重写paint方法,而要重写JPanel或JComponent的paintComponent方法
  • 几乎总是调用super的方法
  • 切勿从绘图方法中读取文件
  • 您的代码公然违反了Swing线程规则——大多数Swing调用都应该在Swing事件线程上进行,而不是像您所做的那样离开它
  • 最好创建并发布您的or,这样我们就可以运行实际运行的代码 至于您的具体问题,您正在创建一个DrawCar组件实例,但您似乎从未将其添加到GUI中,因此它将永远不会显示,因为它从来不是顶级窗口(如JFrame、JApplet或JDialog)的一部分


    再次评论:

    虽然paint()和paintComponent()是相同的,但只是一个调用另一个

    不,他们不是。
    paint(…)
    方法是这两种方法中比较“原始”的一种,因为它基于旧的AWT代码库。它不会自动执行双缓冲(与paintComponent不同),并负责绘制组件、组件的边界以及组件持有的所有子组件。出于后一个原因,您希望避免覆盖它,因为如果您把它弄糟了,您可能会出现错误绘制的风险,而不仅仅是组件

    回到我的问题,我这样做
    drawcardraw2=newdrawcar();增加(附图2);draw2.setVisible(真);重新验证();重新油漆()我不知道我在添加之前是否遗漏了“前缀”,代码是自动生成的,因此我找不到任何JFrame=new JFrame();要使frame.add(draw2)像其他人一样处理他们的代码,我们是否有可能发现一些逻辑问题

    由于新的DrawCar类再次出现在主GUI中,因此出现了严重的结构问题

    所以我猜你的主要GUI已经有了一个DrawCar组件,你的目标是让它在按下按钮的时候画一辆车(你从来没有说过!)。如果是这样的话,那么为什么不让DrawCar持有一个JPanel并简单地用你的图像设置它的图标呢。我自己,我会在程序启动时阅读图像,如果这是我的目标的话,我也会在那个时候翻转它


    同样,如果您仍然存在问题,请将问题隔离到最小的可编译可运行代码,然后让我们测试它。

    对不起,我刚开始使用Swing一两天。虽然
    paint()
    paintComponent()
    是相同的,但只是一个调用另一个。。。我会尽力把它修好。谢谢你的建议。回到我的问题,我这样做
    drawcardraw2=newdrawcar();增加(附图2);draw2.setVisible(真);重新验证()重新绘制();我不知道我是否错过了
    add
    之前的“前缀”,代码是自动生成的,因此我找不到任何
    JFrame=new JFrame()
    制作
    frame.add(draw2)
    像其他人一样处理他们的代码,我们会发现一些逻辑问题吗?据我所知,我的主GUI中没有
    DrawCar
    。这就是为什么我调用
    DrawCar draw2=newdrawcar()你的意思是这样的吗?:
    ImageIcon image=newimageicon(“image/pic1.jpg”);JLabel标签=新的JLabel(“,图像,JLabel.CENTER);JPanel panel=newjpanel(newborderlayout());panel.add(标签、BorderLayout.CENTER)@TranHoaiNam:用任何新代码更新您的原始问题。同样,我们更希望你发布一个帖子(同样,请阅读链接)。@TranHoaiNam:正如我们在美国所说,“细节是魔鬼”。虽然您的新代码看起来运行良好,但我仍然无法运行或测试它。同样,我们要求您创建并发布最小的可运行程序来演示您的问题。例如,请查看中的我的代码,让您了解我们在寻找什么。如果您需要显示图像,请使用可以在线获得的图像,如。@TranHoaiNam:如果您可以提供您试图用GUI完成的操作的图像,也会有所帮助。