2011-08-01 3 views
6

표준 Java GUI 구성 요소를 사용하지 않고 자체 렌더링을 구현할 때 AWT 프레임과 Swing JFrame을 사용하는 것의 주된 차이점은 무엇입니까?EDT 외부 렌더링을위한 Swing/JFrame 대 AWT/Frame

이것은 이전 질문에서에 따라 수 있습니다 : AWT 대 스윙에

AWT custom rendering - capture smooth resizes and eliminate resize flicker

전형적인 논점 우리는 프레임을 사용하고 있기 때문에 적용하지 않는 것. 예를 들어 Heavyweight와 Lightweight가 창 밖으로 나옵니다 (JFrame은 Frame을 확장합니다).

따라서 가장 좋은 점은 의 경우 인 JFrame 또는 프레임입니까? 의미있는 차이가 있습니까?

참고 :이 시나리오는 EDT에서 렌더링이 바람직하지 않은 경우입니다.. EDT와 연결되지 않은 응용 프로그램 워크 플로가 있으며 EDT 외부의 필요에 따라 렌더링이 수행됩니다. 렌더링을 EDT와 동기화하려면 렌더링에 대기 시간이 추가됩니다. Frame 또는 JFrame 이외의 Swing 또는 AWT 컴퍼넌트는 렌더링하지 않습니다 (JPanel/Component/등).

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

} 
+0

'Frame'의 일부 Nested 및 Inherit 메소드는 JFrame API에서 직접 구현됩니다. http://download.oracle.com/javase/6/docs/api/javax/swing/JFrame.html, – mKorbel

+0

'Frame'과'JFrame'과'MsExcell'과'MozillaFirefox' 사이에 차이점을 볼 수 없으며 완료되면'notify'를 제거합니다 (i3/530/3,43Gb RAM, WinXP, onBoard GPU/no sharedMemory/compiled JDK1.6.22) – mKorbel

+0

@mKorbel : MsExcel과 MozillaFirefox는 무엇을해야합니까? –

답변

2

는 @ camickr의 answer에 확장의 "missing detail"JRootPane되면, contentPane 관리 : 여기

는 스윙 버전입니다. JFrame의 경우 " add 및 그 변형, removesetLayout은 필요에 따라 contentPane으로 전달하도록 무시되었습니다." JRootPane#createContentPane() "은 JComponent [n] d를 새로 작성하여 BorderLayoutLayoutManager으로 설정합니다." 구현 세부 사항으로 JComponentnew JPanel() 일 수 있습니다.

  • contentPane 기본적으로 이중 버퍼링이는 JFramecontentPane에 대한 몇 가지 결과를 초래한다.
  • JPanel은 보통 FlowLayout이지만, contentPaneBorderLayout입니다.
  • contentPane에는 모양과 구조에 영향을 줄 수있는 PanelUI에서 파생 된 L & F 특정 UI 대리인이 있습니다.
+0

내가 모호한 것 같지만 이것은 완전히 사용자 정의 렌더링 사이클입니다. EDT에서 수행 할 때 대기 시간이나 해커 또는 둘 다를 포함하기 때문에 위임자, L & F, 포장 프레임 (또는 JFrame 또는 기타 원하는 것) 및 EDT 밖에서 렌더링이 없습니다. –

+0

[* AWT 및 스윙의 페인팅 : 이중 버퍼링 지원 *] (http://java.sun.com/products/jfc/tsc/articles/painting/index.html#db)은 " 그 설정은 최상 정도의 Swing 컴퍼넌트의 아래의 모든 것의 더블 버퍼링을 유효하게하기 때문에, 「JRootPane」에 관한 문제가 있습니다. 나는 그것을 꺼야 할 이유가 없었습니다. AFAIK, 현존하는 모든 호스트 렌더링 엔진은 단일 스레드입니다. EDT를 사용하지 않는 이유는 무엇입니까? – trashgod

+0

응용 프로그램 구조 및 대기 시간. 문제의 응용 프로그램에는 자체 스크립팅 및 레이아웃 엔진이 있으며 통합되어 구동 렌더링됩니다. 렌더링 요구 사항 측면에서 볼 때 응용 프로그램이 아니라 게임이라고 생각하십시오 (후자 임에도 불구하고). 주문형 백 버퍼로 렌더링 한 다음 화면에 그립니다. 동일한 이미지 (backbuffer)로 작업하는 EDT와 응용 프로그램 스레드는 사소한 문제를 일으키는 경향이 있습니다. –

2

스윙은 기본적으로 이중 버퍼링되므로 일반적으로 그림에만 집중하면됩니다.

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

} 
+0

내 잘못이지만이 질문을 너무 모호하게 만들었고 후속 해답이 그 지점을 놓치고 Swing render-in-EDT 패러다임을 강요합니다. 이것은 스윙이나 AWT가 필요없는 커스텀 UI를위한 것이다.EDT의 페인팅은 응용 프로그램주기와 렌더링주기를 저글링해야하므로이 시나리오에서는 그리 바람직하지 않습니다. 렌더링이 완전히 사용자 정의 된 경우입니다. –