March 30th, 2008
별도 process의 applet plugin은 어떻게 구현할까?

Note) 이 글에는 동영상이 포함되어 있으나 RSS reader에서 생략되었을 수 있습니다.

아직 정식 출시는 안되었지만 새 Java browser plugin은 브라우져와 별도의 프로세스로 뜨게 해 주어 브라우져의 안정성과 애플릿에 충분한 heap을 제공해 주는등 몇가지를 개선하였다.

다른 프로세스에서 자바컴포넌트를 삽입하는것이 어려워 보일 수 있지만
사실은 Sun JVM에서는 진작 부터 이를 쉽게 구현할 수 있는 방법이 있었다.
다음은 윈도우 탐색기에 별도 JVM에서 띄운 AWT Button을 넣는 예제이다.

예제에서는 MS Window 버젼 Sun JVM에만 있는 WEmbeddedFrame이라는 클래스를 사용하였는데
리눅스및 솔라리스에도 이에 해당되는 클래스가 있는데 슬쩍 관심만 있으면 찾을 수 있다.

WEmbeddedFrame을 사용하려면 어느 네이티브 윈도우에 삽입할지를 지정해야 하는데 이 값은 물론 Window handle이다.
이를 알아내기 위해 MS Visual Studio에 있는 Spy++이라는 툴을 사용해야겠지만 난 VS가 없는 탓에 WinID라는 무료툴을 사용하였다.
거의 유일하게 답글을 달아주시는 어떤분이 동영상 캡춰에 감동하셨다고 해서 한판 더!!

hwnd값을 보면 0x5F02c2 이다.

arg

다음 예제를 컴파일 하고 실행 인자에 핸들을 넣어주면 끝. 예제는 너무 간단해서 설명 생략

JAVA:
  1. package net.hanjava.awt;
  2.  
  3. import java.awt.BorderLayout;
  4. import java.awt.Button;
  5. import java.awt.event.ActionEvent;
  6. import java.awt.event.ActionListener;
  7.  
  8. import sun.awt.windows.WEmbeddedFrame;
  9.  
  10. public class EmbeddingTest {
  11.     static final String[] msgs = {"한자바", "두자바", "세자바"};
  12.     private static int currMsgIndex = 0;
  13.  
  14.     private static String nextMsg() {
  15.         return msgs[ currMsgIndex++ % msgs.length ];
  16.     }
  17.  
  18.     public static void main(String[] args) {
  19.         long containerHwnd = Long.decode(args[0]);
  20.         WEmbeddedFrame eFrame = new WEmbeddedFrame(containerHwnd);
  21.         final Button button = new Button(nextMsg());
  22.         button.addActionListener(new ActionListener() {
  23.             @Override
  24.             public void actionPerformed(ActionEvent e) {
  25.                 button.setLabel( nextMsg() );
  26.             }
  27.         });
  28.         eFrame.add( BorderLayout.CENTER, button );
  29.         eFrame.validate();
  30.     }
  31. }

March 29th, 2008
GTK에서 SWT/Swing bridge 사용시 유의점

swt

Sun에서 나온 Java 6나 Java 5최신 업데이트 버젼은 GtkLookAndFeel에서 최대한 네이티브 환경과 유사하게 보이기 위해 Gtk 렌더링 코드를 직접 사용한다.
그냥 Swing만 사용할 때는 만족스러운 결과를 내는데
SWT_AWT 클래스를 사용하는 경우는 'unexprected async reply'라는 메시지가 나타난다.
SWT_AWT는 SWT 3.0 이후부터 들어간 클래스인데 SWT 컴포넌트에 AWT/Swing 컴포넌트를 넣거나 그 반대를 가능케 하는 유틸리티 클래스이다.

위의 오류는 X call이 여러 thread에 동시에 발생할때 나타난다.

SWT_AWT를 사용하면 SWT event thread와 AWT event thread가 동시에 수행되기 때문이다.

동시에 수행되지 않도록 다음과 같은 코드를 처음에 실행하면 얼추 된다.

JAVA:
  1.     public void paintDirtyRegions() {
  2.         Platform.lock.lock();
  3.         super.paintDirtyRegions();
  4.         Platform.lock.unlock();
  5.     }
  6. };
  7. RepaintManager.setCurrentManager(rm);

'이런팁은 사내 기밀 아닌가요?' 라고 물으신다면
'이정도는 삽질에 끼지도 못해요' 라고 답해 드리겠습니다.