簡體   English   中英

為什么使用Swing繪制在Java 8和Java 6中的表現不同?

[英]Why does painting with Swing behave differently in Java 8 and Java 6?

我正在使用Swing作為GUI開發Java應用程序。 在這個項目中,我使用的是Java 8 Update 25.我一直在用Java編寫另一個圖形應用程序,但我使用的是Java 6.在這兩個項目中,我都編寫了相同的paint()方法。 (如下所示)我也以同樣的方式稱呼'repaint()'。 在這兩個項目中,我正在繪制一個字符串。 此字符串顯示本地int,count的值; 每次調用paint()方法時,計數增加1。

當兩個項目表現不同時,我的問題出現了。 在Java 6中,屏幕更新速度非常快,應用程序的行為也很理想。 但是,在Java 7和8中,應用程序不顯示任何內容。 如果我增加重繪之間的延遲,(大約300毫秒)我能看到字符串閃爍。 但是,如果我想用Java 8開發游戲,例如,角色的閃爍和抖動是非常不可取的。

為什么不同的Java版本以這種方式表現不同? 有沒有一種方法可以使用類似的設置在Java 8中復制流暢的重繪(通過Java 6)? (如下所列)如果有,怎么樣? 如果沒有,如何實現平滑,最小的閃爍顯示? (我希望這個重繪不斷重新繪制,但它不像顯示器的流程那樣必要)

感謝您的幫助,~Rane

Java 6項目代碼:

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代碼:

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 ++;
  }
}
  • 永遠不要直接在JFrame中繪制。
  • 始終繪制JComponent,例如JPanel或JComponent。
  • 並在其paintComponent(Graphics g)覆蓋中paint(Graphics g) ,而不是在paint(Graphics g)覆蓋中以獲得自動雙緩沖的好處。
  • 請不要發布草率代碼。 如果您的類擴展了另一個類,請顯示它。 細節很重要。

例如,

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();
         }
      });
   }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM