6

標準の Java GUI コンポーネントを使用せずに独自のレンダリングを実装する場合、AWT フレームと Swing JFrame を使用する場合の主な違いは何ですか?

これは、前の質問からの続きです。

AWT カスタム レンダリング - スムーズなサイズ変更をキャプチャし、サイズ変更のちらつきをなくします

フレームのみを使用しているため、Swing と AWT の典型的な論点は当てはまらないようです。たとえば、ヘビーウェイトとライトウェイトは窓の外に出ます(そしてJFrameはFrameを拡張します)。

この状況では、JFrame と Frame のどちらが最適ですか? 意味のある違いはありますか?

注: このシナリオは、EDT でのレンダリングが望ましくないシナリオです。EDT にリンクされていないアプリケーション ワークフローがあり、EDT の外部で必要に応じてレンダリングが行われます。レンダリングを EDT と同期させると、レンダリングにレイテンシが追加されます。フレームまたは JFrame (または、最適な場合は同封の JPanel/Component/etc) 以外の Swing または AWT コンポーネントをレンダリングしていません。

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.image.BufferStrategy;
import java.awt.Frame;

public class SmoothResize extends Frame {

public static void main(String[] args) {
    Toolkit.getDefaultToolkit().setDynamicLayout(true);
    System.setProperty("sun.awt.noerasebackground", "true");
    SmoothResize srtest = new SmoothResize();
    //srtest.setIgnoreRepaint(true);
    srtest.setSize(100, 100);
    srtest.setVisible(true);
}

public SmoothResize() {
    render();
}

private Dimension old_size = new Dimension(0, 0);
private Dimension new_size = new Dimension(0, 0);

public void validate() {
    super.validate();
    new_size.width = getWidth();
    new_size.height = getHeight();
    if (old_size.equals(new_size)) {
        return;
    } else {
        render();
    }
}

public void paint(Graphics g) {
    validate();
}

public void update(Graphics g) {
    paint(g);
}

public void addNotify() {
    super.addNotify();
    createBufferStrategy(2);
}

protected synchronized void render() {
    BufferStrategy strategy = getBufferStrategy();
    if (strategy == null) {
        return;
    }
    // Render single frame
    do {
        // The following loop ensures that the contents of the drawing buffer
        // are consistent in case the underlying surface was recreated
        do {
            Graphics draw = strategy.getDrawGraphics();
            Insets i = getInsets();
            int w = (int)(((double)(getWidth() - i.left - i.right))/2+0.5);
            int h = (int)(((double)(getHeight() - i.top - i.bottom))/2+0.5);
            draw.setColor(Color.YELLOW);
            draw.fillRect(i.left, i.top + h, w,h);
            draw.fillRect(i.left + w, i.top, w,h);
            draw.setColor(Color.BLACK);
            draw.fillRect(i.left, i.top, w, h);
            draw.fillRect(i.left + w, i.top + h, w,h);
            draw.dispose();

            // Repeat the rendering if the drawing buffer contents 
            // were restored
        } while (strategy.contentsRestored());

        // Display the buffer
        strategy.show();

        // Repeat the rendering if the drawing buffer was lost
    } while (strategy.contentsLost());
}

}
4

2 に答える 2

2

Swing はデフォルトでダブル バッファリングされるため、通常は描画に集中するだけで済みます。

Swing バージョンは次のとおりです。

import java.awt.*;
import javax.swing.*;

public class SwingResize extends JPanel
{
    protected void paintComponent(Graphics g)
    {
        int w = (int)(((double)(getWidth()))/2+0.5);
        int h = (int)(((double)(getHeight()))/2+0.5);
        g.setColor(Color.YELLOW);
        g.fillRect(0, h, w,h);
        g.fillRect(w, 0, w,h);
        g.setColor(Color.BLACK);
        g.fillRect(0, 0, w, h);
        g.fillRect(w, h, w,h);
    }

    public static void main(String[] args)
    {
//      Toolkit.getDefaultToolkit().setDynamicLayout(true);
//      System.setProperty("sun.awt.noerasebackground", "true");

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        frame.add( new SwingResize() );
        frame.setSize(100, 100);
        frame.setLocationRelativeTo( null );
        frame.setVisible(true);
    }

}
于 2011-08-01T14:48:54.553 に答える
2

@camickr's answerを拡張すると、「欠落している詳細」JRootPaneであり、contentPane. JFrame"addとそのバリアントについては、必要に応じて に転送するようにオーバーライドされているremoveことに注意してください。" 「新しい a[n]d を作成し、その としてa[n]d を設定します。」実装の詳細として、それは. これは of にいくつかの結果をもたらします:setLayoutcontentPaneJRootPane#createContentPane()JComponentBorderLayoutLayoutManagerJComponentnew JPanel()contentPaneJFrame

  • contentPane、デフォルトでダブル バッファリングされます。
  • にはcontentPaneがありますがBorderLayoutJPanel通常は がデフォルトFlowLayoutです。
  • にはcontentPane、通常は から派生した L&F 固有の UI デリゲートPanelUIがあり、外観とジオメトリに影響を与える可能性があります。
于 2011-08-01T15:16:17.813 に答える