Why does the Swing picture behave differently in Java 8 and Java 6?

I am working on a Java application using Swing as a GUI. In this project, I used Java 8 Update 25. I wrote another graphical application in Java, but I used Java 6. In both projects, I wrote the same paint () method. (See below) I also called "repaint ()" in the same way. In both projects, I draw a line. This line displays the value of the local int, count; The graph is incremented by one each time the paint () method is called.

My question arises when two projects behave differently. In Java 6, the screen updates quickly and the application behaves as desired. However, in Java 7 and 8, the application does not display anything. If I increase the delay between repaints, (up to about 300 milliseconds), I can see the line flicker. However, if I wanted to develop a game in Java 8, the flickering and trembling movement of the character, for example, would be very undesirable.

Why do different versions of Java behave differently? Is there a way that I can replicate smooth redraws (in Java 6) in Java 8 using a similar setting? (as indicated below) If so, how? If not, how would you achieve a smooth, minimal flickering display? (I would prefer that this repainting be constantly repainted, but this is not as necessary as the display stream)

Thanks for your help in advance, ~ Rane

Java 6 project code:

public class App {

static AppDisplay display = new AppDisplay();

  public static void main(String args[]) {

    display.setup();

    Thread graphics = new Thread() {
      public void run() {
        while(true) {
          display.repaint();
          try {
            Thread.sleep(17); // This is the delay I am talking about above
          } catch (Exception e) {
            e.printStackTrace();
          }
        }
      }
    };
    graphics.start();


  }
}

public class AppDisplay() extends JFrame {
  private static final long serialVersionUID = 1L;

  int count = 0;

  public void setup() {
    this.setSize(600, 600);
    this.setTitle("Application");
    this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    this.setVisible(true);
  }

  public void paint(Graphics g) {
    super.paint(g);
    g.drawString("Count: " + count);
    count ++;
  }
}

Java 8 code:

public class App {

static AppDisplay display = new AppDisplay();

  public static void main(String args[]) {

    display.setup();

    Thread graphics = new Thread() {
      public void run() {
        while(true) {
          display.repaint();
          try {
            Thread.sleep(17); // Delay
          } catch (Exception e) {
            e.printStackTrace();
          }
        }
      }
    };
    graphics.start();


  }
}

public class AppDisplay() extends JFrame {
  private static final long serialVersionUID = 1L;

  int count = 0;

  public void setup() {
    this.setSize(600, 600);
    this.setTitle("Application");
    this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    this.setVisible(true);
  }

  public void paint(Graphics g) {
    super.paint(g);
    g.drawString("Count: " + count);
    count ++;
  }
}
+4
source share
1 answer
  • Never draw directly in JFrame.
  • Always draw a JComponent like JPanel or JComponent.
  • And draw in your paintComponent(Graphics g)override rather than override paint(Graphics g)to take advantage of automatic double buffering.
  • Please do not post inaccurate code. If your class extends another class, show it. Details matter.

eg.

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class MyApp extends JPanel {

   private static final int PREF_W = 600;
   private static final int PREF_H = 400;
   private static final int DELAY = 17;
   private int count = 0;

   public MyApp() {
      new Timer(DELAY, new ActionListener() {

         @Override
         public void actionPerformed(ActionEvent e) {
            count++;
            repaint();
         }
      }).start();
   }

   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      g.drawString("Count = " + count, 20, 20);
   }

   private static void createAndShowGUI() {
      MyApp paintEg = new MyApp();

      JFrame frame = new JFrame("MyApp");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(paintEg);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGUI();
         }
      });
   }
}
+5
source

Source: https://habr.com/ru/post/1569257/


All Articles