3

すべてFrame単色ですが、隅にテキストがあります。色を設定し、実際にモニターから色を読み取り、それらの測定値に基づいて計算を行います。

問題は、呼び出しrepaint()により、測定を行ったFrameにがペイントされることです。これは EDT への委任が原因であると想定していますが、実際の塗装作業の前/最中に測定が行われたため、誤った結果が得られています。repaint()

私の最初の考えは、ペイント完了にリスナーを配置することでしたが、色よりも頻繁にテキストを更新するために再ペイントし、それらのイベントをリッスンしたくありません。測定を行う前に、実際の塗装作業が完了するのをどのように待つことができますか?

4

2 に答える 2

0

あなたが見つけることができる素晴らしいもの...

EventQueue.invokeLater(new Runnable() {
    @Override
    public void run() {

        Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
            @Override
            public void eventDispatched(AWTEvent event) {

                PaintEvent pe = (PaintEvent) event;

                String type = "";
                if (pe.getID() == PaintEvent.PAINT) {
                    type = "PAINT";
                } else if (pe.getID() == PaintEvent.PAINT_FIRST) {
                    type = "PAINT_FIRST";
                } else if (pe.getID() == PaintEvent.PAINT_LAST) {
                    type = "PAINT_LAST";
                } else if (pe.getID() == PaintEvent.UPDATE) {
                    type = "UPDATE";
                }

                System.out.println(type + "; pe.UpdateRec = " + pe.getUpdateRect() + "; pe.component = " + pe.getComponent());

            }
        }, AWTEvent.PAINT_EVENT_MASK);

        JFrame frame = new JFrame("Testing");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(200, 200);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);


    }
});

さて、塗り直しのリクエストは考えてすぐに来ることができるので、最後のリクエストが完了した直後に発生する小さな「遅延」を配置したくなるでしょう...

private Timer updateTimer;

// ...

EventQueue.invokeLater(new Runnable() {
    @Override
    public void run() {

        updateTimer = new Timer(250, new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                // Update compulations here...
            }
        });
        updateTimer.setRepeats(false);
        updateTimer.setCoalesce(true);

        Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {

            @Override
            public void eventDispatched(AWTEvent event) {
                updateTimer.restart();
            }
        }, AWTEvent.PAINT_EVENT_MASK);
    }
}

アイデアは、最後の再描画要求とコンパイルの開始の間に少なくとも250ミリ秒を見込むことです。これらの値を少し試して、自分に合った値を確認することをお勧めします...

アップデート

あなたも試すことができますJComponent.paintImmediately

このコンポーネントの指定された領域と、その領域と重なるすべての子孫をすぐにペイントします。

このメソッドを呼び出す必要はめったにありません。ほとんどの場合、repaintを呼び出す方が効率的です。これにより、実際のペイントが延期され、冗長なリクエストが1つのペイント呼び出しにまとめられる可能性があります。このメソッドは、現在のイベントがディスパッチされている間に表示を更新する必要がある場合に役立ちます。

于 2012-09-25T06:49:57.110 に答える