Tambahkan area dekoratif di sekitar node, yang berperilaku seperti Efek

Untuk permainan kartu, yang sedang saya tulis, saya membuat "kontrol" khusus yang mewakili sebuah kartu. Itu dapat dibalik, diseret, dipilih, dan akan diskalakan, diterjemahkan, dan sebagainya selama permainan berlangsung.

Salah satu fitur inti kartu adalah dapat "disorot" dengan berbagai cara. Bentuk penyorotan paling dasar adalah menampilkan batas bercahaya (animasi) di sekeliling kartu.

Saya mulai dengan efek JavaFX di sini (DropShadow dengan penyebaran/radius animasi) tetapi dengan cepat meninggalkannya, karena kinerjanya ternyata sangat buruk.

Jadi, saya mengganti efeknya dengan animasi ImageView "di belakang" kartu (animasi sprite dasar dari sprite sheet dengan animasi cahaya yang telah dirender sebelumnya). Ini memecahkan masalah kinerja, tetapi menimbulkan banyak masalah lain yang saat ini saya coba atasi...

Karena, saya tidak ingin "titik jangkar" menjadi sudut kiri atas cahaya di sekitar kartu tetapi sudut kiri atas kartu itu sendiri, saya mencoba mengimbangi ImageView di dalam simpul kartu dengan -X/ -Y.

(Sorotan yang berbeda dapat "memperluas" simpul dengan jumlah yang berbeda, hal ini tidak akan mempengaruhi lokasi simpul, dan ketika mengatur lokasi simpul, Anda tidak perlu peduli dengan potensi offset atau sorotan sorotan yang berbeda sama sekali.)

Pada awalnya ini tampak bagus, tapi ini masih mempengaruhi batas-batas seluruh node. Misalnya, jika saya menambahkan pendengar peristiwa mouse ke node, ia akan aktif ketika mengklik di area "bersinar", meskipun saya menyetel ImageView ke mouse transparan. Saya harus membuat metode "proksi" untuk semua metode acara pada node khusus dan meneruskannya ke node kartu "dalam". Yang tentu saja mungkin - tapi sejujurnya bukan solusi yang saya harapkan.

Node kartu saat ini pada dasarnya memiliki struktur berikut:

   public class Card extends Pane {

        // the view that will contain the border glow (blue area in image below)
        private ImageView effectView;

        // stand-in for the rest of the card stuff (image etc)
        private Rectangle placeholderForCardContent;

        public Card() {
            effectView = new ImageView();
            effectView.setMouseTransparent(true);

            placeholderForCardContent = new Rectangle();

            getChildren().addAll(effectView, placeholderForCardContent);
        }

        @Override
        protected void layoutChildren() {
            // offsets are defined by the current highlight
            effectView.setLayoutX(-50); 
            effectView.setLayoutY(-50);
            effectView.setFitWidth(getWidth() + 100);
            effectView.setFitHeight(getHeight() + 100);

            placeholderForCardContent.setLayoutX(0);
            placeholderForCardContent.setLayoutY(0);
            placeholderForCardContent.setWidth(getWidth());
            placeholderForCardContent.setHeight(getHeight());
        }
    }

Contoh: new Card().setOnMouseClick() dan sejenisnya seharusnya hanya memengaruhi area yang saat ini sama dengan placeHolderForCardContent, namun tidak meluas ke effectView. Sederhananya, itu harus berperilaku seperti Efek dari node...

Gambar berikut menunjukkan apa yang saya coba buat:

masukkan deskripsi gambar di sini

Bagaimana hal seperti ini dilakukan dengan benar di JavaFX? Bisakah itu dilakukan dengan benar?


person Roman Flückiger    schedule 25.07.2016    source sumber


Jawaban (1)


setMouseTransparent(true) berfungsi dengan baik untuk effectView.

Namun, batas induk (Pane) masih menyertakan effectView dan menghasilkan peristiwa mouse. Dan karena pickOnBounds untuk Regions disetel ke true secara default (yang merupakan hal yang saya lewatkan, karena default umum, menurut dokumen Java, adalah false) kita perlu menyetelnya ke false.

Kemudian itu berhasil.

person Roman Flückiger    schedule 25.07.2016