Apakah repaint() bebas arg lebih baik daripada repaint() dengan args?

Saya ingin melukis beberapa hal di JPanel dan membaca serta mempelajari Performing Custom Pelajaran melukis. Saat memperbarui kotak menggunakan repaint Saya merasa menggunakan konstruksi ini

private void moveSquare(int x, int y) {
  if ((squareX != x) || (squareY != y)) {
     squareX = x;
     squareY = y;
     repaint();
  }
}

memberikan contoh spesifik ini kinerja cat yang jauh lebih baik dibandingkan dengan yang direkomendasikan ini

private void moveSquare(int x, int y) {
  int OFFSET = 1;
  if ((squareX != x) || (squareY != y)) {
     repaint(squareX, squareY, squareW + OFFSET, squareH + OFFSET);
     squareX = x;
     squareY = y;
     repaint(squareX, squareY, squareW + OFFSET, squareH + OFFSET);
  }
}

Jika saya menggunakan yang terakhir, kotaknya terlihat agak 'tergencet' saat proses drag.

Saya tahu, ini adalah contoh yang sangat mendasar, tetapi ini membuat agak takut dengan kinerja Java Graphics secara umum.


person DaJunkie    schedule 07.09.2020    source sumber


Jawaban (2)


Melakukan pengecatan ulang dua kali adalah hal yang tidak wajar.

Dan kapan hanya mengecat ulang penyatuan kotak lama dan baru?

private void moveSquare(int x, int y) {
  if (squareX != x || squareY != y) {
     final int OFFSET = 1;
     int minx = Math.min(x, squareX);
     int miny = Math.min(y, squareY);
     int dx = Math.abs(x - squareX);
     int dy = Math.abs(y - squareY);

     squareX = x;
     squareY = y;
     repaint(minx, miny, squareW + dx + OFFSET, squareH + dy + OFFSET);
  }
}

Ini akan menjadi lebih halus bila perseginya relatif kecil atau di luar area yang ditunjukkan (kliping).

person Joop Eggen    schedule 07.09.2020
comment
Sepertinya ini meningkatkan rendering saat bergerak ke kanan atau ke bawah. Bergerak ke kiri atau ke atas masih akan menekan persegi panjang. Saya akan menyelidikinya lebih lanjut nanti. - person DaJunkie; 07.09.2020

Perbedaan antara no-arg paint() dan yang berargumen adalah bahwa yang berargumen akan menyetel wilayah kliping pada panggilan berikutnya ke paint(). Perbedaan kinerja pengecatan, jika ada, akan bergantung pada apakah metode paint() benar-benar memperhitungkan wilayah kliping, atau hanya mengecat seluruh area gambar dan meninggalkan platform untuk menentukan apakah wilayah tersebut perlu diperbarui atau tidak.

Banyak komponen Java AWT/Spring mengabaikan wilayah kliping, dan hanya mengecat seluruh area. Terkadang lebih cepat melakukan hal itu, daripada memikirkan cara mengecat ulang bagian tertentu dari area tampilan. Jika komponennya adalah komponen yang Anda tulis sendiri, dan Anda tahu bahwa Anda tidak menguji wilayah kliping di paint(), maka Anda tahu tidak ada bedanya apakah Anda memanggil repaint() dengan argumen atau tidak.

Di sisi lain, jika Anda mengalami banyak masalah dengan implementasi paint(), untuk mengetahui cara mengecat ulang sub-wilayah dengan tepat, maka Anda berhutang pada diri Anda sendiri untuk mencoba mencari cara terbaik untuk memanggil repaint().

Jika Anda tidak menulis komponennya, mungkin ada yang tahu apakah yang terbaik adalah menentukan area pengecatan ulang atau tidak kecuali dengan menguji, atau memeriksa kode sumber dengan cermat, jika Anda memilikinya.

Jika menggunakan repaint() dengan argumen menyebabkan gambar terdistorsi, itu mungkin menunjukkan implementasi paint() yang rusak.

person Kevin Boone    schedule 07.09.2020
comment
Saya menggunakan Swing dan mengimplementasikan paintComponent() saja. Sejauh yang saya pahami, ini adalah 'Jalan Ayun' yang disukai. Saya membaca bahwa tidak disarankan menerapkan cat di bawah Swing. - person DaJunkie; 07.09.2020
comment
paintComponent() hanyalah Swing yang setara dengan paint(). Baik Anda menggunakan AWT atau Swing, objek Graphics yang diteruskan ke metode berisi persegi panjang kliping. Apa pun kasusnya, Anda dapat menggunakan persegi panjang yang akan dipotong, atau mengabaikannya -- itu terserah Anda. - person Kevin Boone; 07.09.2020
comment
Terima kasih atas informasi tentang bentuk kliping. Saya benar-benar baru dalam melukis dan tidak mengetahuinya sebelumnya. Sayangnya hal ini tidak membuat perbedaan: Menggunakan repaint() bebas arg 'terlihat lebih baik' daripada hanya memperbarui persegi panjang kliping. Saya akan mencoba memberikan contoh lengkap, dengan semua solusi yang disebutkan. - person DaJunkie; 07.09.2020