简体   繁体   English

为什么我的 Java repaint() 方法不起作用?

[英]Why does my Java repaint() method not work?

Heyo, for my college homework I need to draw some images and race them, but I am stuck even at drawing the images (or in this case, icons).嘿,对于我的大学作业,我需要绘制一些图像并进行竞赛,但我什至无法绘制图像(或者在这种情况下,是图标)。 I want to draw ANYTHING (that's why I have the drawLine method, just to test it out) as of right now on one of many JPanels, but my repaint() method does not call my paintComponent method, why?我想现在在许多 JPanel 之一上绘制任何东西(这就是为什么我有 drawLine 方法,只是为了测试它),但是我的 repaint() 方法没有调用我的paintComponent方法,为什么?

import java.awt.*;  
import javax.swing.*;  
import java.lang.Math; 


public class Races{
   private int numberOfRacers;

   public Races(int numberOfRacers){
      this.numberOfRacers = numberOfRacers;
      JFrame frame = new JFrame("Races - Name Surname");

      Icon icon = new ImageIcon("races.jpg");
      frame.setLayout(new GridLayout(numberOfRacers, 1));
      frame.setSize(icon.getIconWidth()*20, (icon.getIconWidth()*2)*numberOfRacers);
      frame.setVisible(true);
      frame.setLocationRelativeTo(null);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

      try{
         Thread.sleep(1000);  // Sleeping 1 sec 
         System.out.println("Sleeping one second for the user!");
      }catch(InterruptedException ie){
         System.out.println(ie);
      }


      for(int i = 0; i < numberOfRacers; i++){
         innerRacer racer = new innerRacer();
         frame.add(racer.panel);
         //JLabel iconLabel = new JLabel(icon);
         //iconLabel.setHorizontalAlignment(JLabel.LEFT);
         //panel.add(iconLabel);
         Thread t = new Thread(racer);
         t.start();

      }
   }

   public static void main(String args[]){

      if(args.length > 0 && Integer.parseInt(args[0]) > 0 && Integer.parseInt(args[0]) < 100){
         Races races = new Races(Integer.parseInt(args[0]));   // From command line number of racers
         System.out.println("Number of racers: " + args[0]);
      }else{
         Races races = new Races(5);      // Default number of racers
         System.out.println("Number of racers: 5");
      }
   }

   public class innerRacer extends JPanel implements Runnable{ 
      JPanel panel;
      Icon icon;
      public innerRacer(){
         panel = new JPanel();
         panel.setBackground(Color.WHITE);

         icon = new ImageIcon("races.jpg");
      } //end of innerRacer constructor

      @Override
         public void run(){
            repaint();     
            System.out.println("TEST");  
         }
     @Override
     public void paintComponent(Graphics g){
         super.paintComponent(g);
         g.drawLine(10, 20, 30, 40);
         System.out.println("Why is this one not called?");
         icon.paintIcon(panel, g, 0, 0);
     } 

   } // end of innerRacer class
} //end of Races class

Thanks in advance.提前致谢。

You've added the JPanel that innerRacer contains rather than the JPanel that innerRacer is.您已经添加JPanelinnerRacer包含而不是JPanelinnerRacer是。

Change:改变:

     frame.add(racer.panel);

to:到:

     frame.add(racer);

Also I see you are adding components to the frame after setting it to visible.另外我看到您在将组件设置为可见后向框架添加组件。 When you do this in AWT/Swing they wont get automatically laid out or painted.当您在 AWT/Swing 中执行此操作时,它们不会自动布局或绘制。 You will need to follow with the line:您将需要遵循以下行:

  frame.revalidate(); 

Alternatively, the setVisible line could be moved down.或者,可以向下移动setVisible线。

As general notes:作为一般说明:

  • It's a good idea to stick to Java naming conventions - always initial caps for types.坚持 Java 命名约定是一个好主意 - 总是类型的初始大写。
  • JPanel panel; in innerRacer can be deleted.innerRacer中可以删除。
  • Swing components should always be accessed from the AWT Event Dispatch Thread (EDT). Swing 组件应始终从 AWT 事件调度线程 (EDT) 访问。 Use java.awt.EventQueue.invokeLater .使用java.awt.EventQueue.invokeLater
  • Lots of tutorials suggest overriding JPanel without adding any components if you want to paint anything.如果您想绘制任何内容,许多教程建议在不添加任何组件的情况下覆盖JPanel This appears to be because it is opaque by default.这似乎是因为它默认是不透明的。 Neither the API docs for JPanel nor even the OpenJDK source code mention opaqueness. JPanel的 API 文档甚至 OpenJDK 源代码都没有提到不透明性。 Indeed, it isn't guaranteed.确实,不能保证。 It's just a hack.这只是一个黑客。 Prefer setOpaque(true) to make a component opaque.更喜欢setOpaque(true)使组件不透明。
  • Having a class extend another and implement an interface (or implement multiple interfaces (not markers, Comparable , etc)) isn't great.让一个类扩展另一个类并实现一个接口(或实现多个接口(不是标记、 Comparable等))并不是很好。 Use a lambda method, method reference, inner class or just another outer class as appropriate.根据需要使用 lambda 方法、方法引用、内部类或仅另一个外部类。

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

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