سؤال

أنا أتصل بإعادة رسم مجموعة من المرات من المستمعين، لكن الطريقة التي صممتها وظيفة الطلاء هي إعادة رسم واحد فقط. أنا توليد مجموعة من الطعون، لأنه مدمن مخدرات في مستمع Motion Motion الخاص بي.

هل هناك طريقة لإلغاء جميع الطعون في انتظار مكون معين؟ لا يمكنني البدء فقط في تجاهل إعادة الطعون، لأن البعض سصالا مثل عند تغيير حجم الإطار أو استعادته من التقليل من الحد الأدنى.

لماذا أهتم؟ لأن كود الطلاء ثقيل للغاية ولا أستطيع القيام بالاعتماد الكامل في FPS مرتفع للغاية.

هل كانت مفيدة؟

المحلول

ستجمع التأرجح بين الطعون من أجلك: انظر "اللوحة في AWT وتأرجح" على موقع الشمس. إذا قمت بجدولة عدد من الطعون في الخلافة السريعة، فسوف يتم دمجهم في مكالمة واحدة إلى paintialy ().

نصائح أخرى

يتم وضع طلبات إعادة رسم متكررة تلقائيا في واحدة. أفضل طريقة لتحسين هذا ليس لإعادة رسم كل شيء، ولكن استدعاء إعادة رسم مع إحداثيات منطقة محددة. هذا يعني أنك إعادة رسم المنطقة فقط التي تغيرت في الواقع.

فهمي هو ذلك repaint() قم ببساطة بجدول إعادة رسم عن طريق إضافة منطقة من المكون إلى قائمة انتظار إعادة رسم. إذا تم طلب إعادة رسم بالفعل على أحد مكونات، فإن منطقة إعادة رسم جديدة ستتونت فقط بالمناطق المطلوبة سابقا. لا يتم تنفيذ عملية إعادة الرسم فعليا حتى يتم التعامل مع جميع الأحداث الأخرى في قائمة انتظار الأحداث. لذلك، قد لا تجعل أعمائكم الإضافية الخاصة بك الكثير من الفرق، أي سيتم تنفيذ رمز اللوحة الخاص بك مرة واحدة فقط. يرى jcomponent.repaint. و repaintmanager.adddirtyregion..

لقد قمت اخترق شيء مماثل معا لتحسين كيفية قرر JFreechART الطلاء عندما يجعل الكثير من المكالمات لإعادة رسم.

أساسا أقوم بما يلي:

  • إنشاء ScheduledExecutorService كحقل في الفصل
  • تلقي طلب إعادة رسم الأول و submit إلى المنفذ لتشغيله على EDT في أقول 50ms استعادة المستقبل
  • تلقي الطلب الثاني - اختبار لمعرفة ما إذا كان إعادة رسمية السابقة قد انتهت (fut.isDone()) وإذا كان الأمر كذلك لجدولة إعادة الطلاء التالي؛ لا تفعل شيئا خلاف ذلك.

وبهذه الطريقة يجب أن تحصل على طلب 20 مسبلات في الثانية.

لقد فعلت أشياء مماثلة لخلع عدد المكالمات fireDataTableChanged عندما تحدث الكثير من التغييرات في نفس الوقت.

أنا أسمع ما تقول. يمكنك بالفعل إعادة رسم قسم فقط من المنطقة. في "أداء أمثلة اللوحة المخصصة" على موقع Sun على موقع الويب، وجدت مثالا مفيدا يوضح كيفية رسم مستطيل تم سحبه، ثم إعادة رسم تلك المنطقة فقط عندما يتحرك الماوس أو إصداره.

هنا هو القسم ذي الصلة من التعليمات البرمجية ...

public void mouseDragged(MouseEvent e) {
            updateSize(e);
        }

        public void mouseReleased(MouseEvent e) {
            updateSize(e);
        }

        /* 
         * Update the size of the current rectangle
         * and call repaint.  Because currentRect
         * always has the same origin, translate it
         * if the width or height is negative.
         * 
         * For efficiency (though
         * that isn't an issue for this program),
         * specify the painting region using arguments
         * to the repaint() call.
         * 
         */
        void updateSize(MouseEvent e) {
            int x = e.getX();
            int y = e.getY();
            currentRect.setSize(x - currentRect.x,
                                y - currentRect.y);
            updateDrawableRect(getWidth(), getHeight());
            Rectangle totalRepaint = rectToDraw.union(previousRectDrawn);
            repaint(totalRepaint.x, totalRepaint.y,
                    totalRepaint.width, totalRepaint.height);
        }

هذا الرمز يخضع لحقوق النشر (انظر هنا للحصول على رمز كامل وإشعار حقوق الطبع والنشر)

يرى هنا للحصول على آخر قوائم

قيل للحقيقة، أواجه قضية مماثلة على FPS، ولكن هذا قد يكون بسبب سوء الشفرة حاليا! لقد تعلمت الكثير خلال الأشهر القليلة الماضية، أن أقوم الآن بإجراء رمزي أكثر كفاءة للغاية. نأمل أن أتمكن من التغلب على مشكلة FPS عندما يبطئ أكثر من 2 "أشخاص" رسوماتي! Hummmm ... لقد قمت فقط بتنفيذ التعليمات البرمجية أعلاه لنفس القسم في التعليمات البرمجية الخاصة بي، وليس غيرها، ولكن بكل الوسائل تعطيه جربا!

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top