为渲染EDT以外的Swing / VS的JFrame AWT /帧 [英] Swing/JFrame vs AWT/Frame for rendering outside the EDT

查看:203
本文介绍了为渲染EDT以外的Swing / VS的JFrame AWT /帧的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

什么是实现自己的渲染时使用AWT框架和一个Swing的JFrame,而不是使用标准的Java GUI组件之间的主要区别?

这是从previous问题上遵循:

<一个href=\"http://stackoverflow.com/questions/6824756/awt-custom-rendering-capture-smooth-resizes-and-eliminate-resize-flicker/6893310#comment-8211192\">AWT定制渲染 - 捕捉顺利尺寸并消除大小调整闪烁

似乎在Swing VS AWT典型的谈话要点不要因为我们只使用框架提出申请。重量级VS轻量级就走出了窗外(和扩展的JFrame框架),例如

因此​​,这是最好的,或者的JFrame框架的这种情况下?这有什么意义区别?

注意:此方案是其中的渲染在EDT是不可取。有未链接到EDT和渲染是在美国东部时间之外的AS-需求的基础上完成的应用程序的工作流程。要同步与EDT渲染会增加延迟到渲染。我们不是渲染比Frame或JFrame的其他任何Swing或AWT组件(或封闭的JPanel /组件/等,如果它是最好的)。

 进口java.awt.Color中;
进口java.awt.Dimension中;
进口java.awt.Graphics;
进口java.awt.Insets中;
进口java.awt.Toolkit中;
进口java.awt.image.BufferStrategy;
进口java.awt.Frame中;公共类SmoothResize扩展框架{公共静态无效的主要(字串[] args){
    。Toolkit.getDefaultToolkit()setDynamicLayout(真);
    System.setProperty(sun.awt.noerasebackground,真);
    SmoothResize srtest =新SmoothResize();
    //srtest.setIgnoreRepaint(true);
    srtest.setSize(100,100);
    srtest.setVisible(真);
}公共SmoothResize(){
    渲染();
}私人尺寸old_size =新的Dimension(0,0);
私人尺寸new_size =新的Dimension(0,0);公共无效的validate(){
    super.validate();
    new_size.width =的getWidth();
    new_size.height =的getHeight();
    如果(old_size.equals(new_size)){
        返回;
    }其他{
        渲染();
    }
}公共无效漆(图形G){
    验证();
}公共无效更新(图形G){
    油漆(G);
}公共无效信息addNotify(){
    super.addNotify();
    createBufferStrategy(2);
}保护同步无效渲染(){
    BufferStrategy中的策略= getBufferStrategy();
    如果(战略== NULL){
        返回;
    }
    //渲染单帧
    做{
        //以下循环确保了绘图缓冲器的内容
        //是一致的情况下,底层表面重建
        做{
            图形绘制= strategy.getDrawGraphics();
            插图I =的getInsets();
            INT W =(int)的(((双)(的getWidth() - i.left - i.right))/ 2 + 0.5);
            INT H =(int)的(((双)(的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();            //重复渲染如果绘图缓冲区的内容
            //被恢复
        }而(strategy.contentsRestored());        //显示缓冲区
        strategy.show();        //重复绘制如果绘制缓冲区已丢失
    }而(strategy.contentsLost());
}}


解决方案

拓展上@ camickr的<一个href=\"http://stackoverflow.com/questions/6899004/swing-jframe-vs-awt-frame-for-custom-rendering-custom-gui/6900182#6900182\">answer, 丢失细节是的 的JRootPane ,该管理的contentPane 。请注意, 的JFrame 添加及其变种,删除 setLayout的已覆盖转发给的contentPane 是必要的。 <一href=\"http://download.oracle.com/javase/6/docs/api/javax/swing/JRootPane.html#createContentPane%28%29\"相对=nofollow> 的JRootPane#createContentPane() 创建一个新的的JComponent A [N] D设定一个的BorderLayout 的LayoutManager 。作为一个实现细节,即的JComponent 恰好是一个新JPanel()。这有几个后果的contentPane 的JFrame 的:


  • 的contentPane 是双默认缓存。

  • 的contentPane 有一个的BorderLayout ,虽然的JP​​anel 通常默认为的FlowLayout

  • 的contentPane 有一个L&安培;˚F特定UI委托,通常 PanelUI Panel的导出,可能影响外观和几何。

What are the principle differences between using an AWT Frame and a Swing JFrame when implementing your own rendering and not using standard Java GUI components?

This is a follow on from a previous question:

AWT custom rendering - capture smooth resizes and eliminate resize flicker

The typical talking points on Swing vs AWT don't seem to apply because we're only using frames. Heavyweight vs Lightweight goes out the window (and JFrame extends Frame), for example.

So which is best, JFrame or Frame for this situation? Does it make any meaningful difference?

Note: this scenario is one where rendering in the EDT is not desirable. There is an application workflow which is not linked to the EDT and rendering is done on an as-needs basis outside of the EDT. To synchronize rendering with the EDT would add latency to the rendering. We are not rendering any Swing or AWT components other than the Frame or JFrame (or an enclosed JPanel/Component/etc if it is best).

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());
}

}

解决方案

Expanding on @camickr's answer, the "missing detail" is JRootPane, which manages the contentPane. Note that for JFrame "add and its variants, remove and setLayout have been overridden to forward to the contentPane as necessary." JRootPane#createContentPane() "creates a new JComponent a[n]d sets a BorderLayout as its LayoutManager." As an implementation detail, that JComponent happens to be a new JPanel(). This has several consequences for the contentPane of JFrame:

  • The contentPane is double buffered by default.
  • The contentPane has a BorderLayout, although JPanel ordinarily defaults to FlowLayout.
  • The contentPane has a L&F specific UI delegate, typically derived from PanelUI, that may affect appearance and geometry.

这篇关于为渲染EDT以外的Swing / VS的JFrame AWT /帧的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆