2010년 2월 2일 화요일

자바 트레이 아이콘/java tray icon 구현/tray po...

울 채팅사이트 조이팅스토리의 태생이 본래 그러하듯....
채팅도 하고 쪽지도 보내고 화상채팅도 해야하고.....
기타등등 할 것이 많타...
이러한 프로그램을 쓰기 위해서는 당근이....
activeX형태로 프로그램을 다운로드해줘야할 것이다..
그 이후엔 사용자에게 거슬리지 않게...프로그램이 숨어서 작동해야하고
필요할 때만... 트레이에서 클릭해서 불러다 쓸 수 있도록 제공해줘야한다....
오늘도.. 기억이 가물가물해서.... 함 찾아 봤더만...
누군가 정말 잘 정리해 둔 분이 계시당! 땡스얼랏해용!!! ^0^*/
바로 아래 코드는 내가 정리한 코드인데 copy해서 붙여넣기하면 코드 오와열도 딱 맞고 나름 잘 돌아간다... ㅋㅋ

http://www.dude.co.kr

/*
 * 작성된 날짜:

 *
 * TODO 생성된 파일에 대한 템플리트를 변경하려면 다음으로 이동하십시오.
 * 창 - 환경 설정 - Java - 코드 스타일 - 코드 템플리트

 * Jerricklee(이경철)
 * tslee777@sarang.net

 * 창을 최소화 하면 트레이에 들어가고 더블클릭하면 메인APP가 튀어나오고... 팝업메뉴에서도 메인APP를 호출 가능.
 * popup menu -> 메뉴별로 작동하도록...
 */
package com.imnetpia.exbill.webmanual.app;

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

import javax.swing.event.*;
public class FullTray {
  static class ShowMessageListener implements ActionListener {
    TrayIcon trayIcon;
    String title;
    String message;
    TrayIcon.MessageType messageType;
    ShowMessageListener(
        TrayIcon trayIcon,
        String title,
        String message,
        TrayIcon.MessageType messageType) {
      this.trayIcon = trayIcon;
      this.title = title;
      this.message = message;
      this.messageType = messageType;
    }
    public void actionPerformed(ActionEvent e) {
      trayIcon.displayMessage(title, message, messageType);
    }
  }

  JFrame frame=new JFrame("System Tray Demo");
  public void test()
  {
   frame.addWindowListener(new WindowListener()
   {
    public void windowOpened(WindowEvent e){}
       public void windowClosing(WindowEvent e){}
       public void windowClosed(WindowEvent e){}
       public void windowIconified(WindowEvent e){
        frame.setVisible(false);    
        displayTrayIcon();
       }
       public void windowDeiconified(WindowEvent e){}
       public void windowActivated(WindowEvent e){
         System.out.println("windowActivated");
       }
       public void windowDeactivated(WindowEvent e){}
   });
   frame.getContentPane().add(new JButton("Hello"));
   frame.setSize(400,500);
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   frame.setVisible(true);
 }
 
 
   public void displayMainApp()
   {                                        
        frame.setVisible(true);
        frame.setExtendedState(Frame.NORMAL);
   }
 
 public void displayTrayIcon()
 {
  Runnable runner = new Runnable()
  {
   public void run()
   {
    if(SystemTray.isSupported())
    {
     MenuItem item;
         
     final SystemTray tray = SystemTray.getSystemTray();
     Image image = Toolkit.getDefaultToolkit().getImage("D:/myproject/JRun4/servers/manual/src/com/imnetpia/exbill/webmanual/app/gifIcon.gif");
    
     PopupMenu popup = new PopupMenu();
     final TrayIcon trayIcon = new TrayIcon(image, "The Tip Text", popup);
    
     ActionListener actionListener = new ActionListener()
     {
      public void actionPerformed(ActionEvent e)
      {
       trayIcon.displayMessage("Action Event",
         "An Action Event Has Been Peformed!",
         TrayIcon.MessageType.INFO);
      }
     };
            
     MouseListener mouseListener = new MouseListener()
     {               
      public void mouseClicked(MouseEvent e)
      {
       System.out.println("Tray Icon - Mouse clicked!");                
      }
      public void mouseEntered(MouseEvent e)
      {
       System.out.println("Tray Icon - Mouse entered!");                
      }
      public void mouseExited(MouseEvent e)
      {
       System.out.println("Tray Icon - Mouse exited!");                
      }
      public void mousePressed(MouseEvent e)
      {
       if(e.getClickCount() == 2)
       {
        tray.remove(tray.getTrayIcons()[0]);
        displayMainApp();
       }      
      }
      public void mouseReleased(MouseEvent e)
      {
       System.out.println("Tray Icon - Mouse released!");                
      }
     };
    
     ActionListener viewApp = new ActionListener()
     {
      public void actionPerformed(ActionEvent e)
      {
       tray.remove(tray.getTrayIcons()[0]);                                          
       displayMainApp();
      }
     };
     item = new MenuItem("Main APP");
     item.addActionListener(viewApp);
     popup.add(item);
     item.addActionListener(new ShowMessageListener(trayIcon,"Error Title", "Error", TrayIcon.MessageType.ERROR));
     popup.add(item);
     item = new MenuItem("Warning");
     item.addActionListener(new ShowMessageListener(trayIcon,"Warning Title", "Warning", TrayIcon.MessageType.WARNING));
     popup.add(item);
     item = new MenuItem("Info");
     item.addActionListener(new ShowMessageListener(trayIcon,"Info Title", "Info", TrayIcon.MessageType.INFO));
     popup.add(item);
     item = new MenuItem("None");
     item.addActionListener(new ShowMessageListener(trayIcon,"None Title", "None", TrayIcon.MessageType.NONE));
     popup.add(item);
     item = new MenuItem("Close");
          
     item.addActionListener(new ActionListener()
     {
      public void actionPerformed(ActionEvent e)
      {     
       tray.remove(trayIcon);
      }
     });
     popup.add(item);
     try
     {
      tray.add(trayIcon);
               trayIcon.setImageAutoSize(true);
               trayIcon.addActionListener(actionListener);
               trayIcon.addMouseListener(mouseListener);
     }catch(AWTException e)
     {
      System.err.println("Can't add to tray");
     }
           }
           else
           {
             System.err.println("Tray unavailable");
           }
         }
      };
      EventQueue.invokeLater(runner);
   
 }

 
 public static void main(String args[])
 {
  new FullTray().test();
 }
}


---------------------------------------------------------------------------------------------------------
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
/**
* @author mrityunjoy_saha
*/

public class MyApp{
JFrame frame=new JFrame("System Tray Demo");
public void test(){
frame.addWindowListener(new WindowListener(){
public void windowOpened(WindowEvent e){}
    public void windowClosing(WindowEvent e){}
    public void windowClosed(WindowEvent e){}
    public void windowIconified(WindowEvent e){
    frame.setVisible(false);    
    displayTrayIcon();
    }
    public void windowDeiconified(WindowEvent e){}
    public void windowActivated(WindowEvent e){
    System.out.println("windowActivated");
    }
    public void windowDeactivated(WindowEvent e){}
});
frame.getContentPane().add(new JButton("Hello"));
frame.setSize(400,500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public void displayTrayIcon(){
        final TrayIcon trayIcon;
        if (SystemTray.isSupported()) {
            final SystemTray tray = SystemTray.getSystemTray();
            Image image = Toolkit.getDefaultToolkit().getImage("tray.gif");
          
            MouseListener mouseListener = new MouseListener() {               
                public void mouseClicked(MouseEvent e) {
                    System.out.println("Tray Icon - Mouse clicked!");                
                }
                public void mouseEntered(MouseEvent e) {
                    System.out.println("Tray Icon - Mouse entered!");                
                }
                public void mouseExited(MouseEvent e) {
                    System.out.println("Tray Icon - Mouse exited!");                
                }
                public void mousePressed(MouseEvent e) {
                tray.remove(tray.getTrayIcons()[0]);                                          
                frame.setVisible(true);
                frame.setExtendedState(Frame.NORMAL);               
                }
                public void mouseReleased(MouseEvent e) {
                    System.out.println("Tray Icon - Mouse released!");                
                }
            };
            ActionListener exitListener = new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    System.out.println("Exiting...");
                    System.exit(0);
                }
            };           
            PopupMenu popup = new PopupMenu();
            MenuItem defaultItem = new MenuItem("Exit");
            defaultItem.addActionListener(exitListener);
            popup.add(defaultItem);
            trayIcon = new TrayIcon(image, "Tray Demo", popup);
            ActionListener actionListener = new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    trayIcon.displayMessage("Action Event",
                        "An Action Event Has Been Peformed!",
                        TrayIcon.MessageType.INFO);
                }
            };
           
            trayIcon.setImageAutoSize(true);
            trayIcon.addActionListener(actionListener);
            trayIcon.addMouseListener(mouseListener);

                try {
                      tray.add(trayIcon);
                } catch (AWTException e) {
                    System.err.println("TrayIcon could not be added.");
                }
        } else {
            System.err.println("System tray is currently not supported.");
        }
}
public static void main(String args[]){
new MyApp().test();
}
}

[출처] TrayIcon 적용하기 |작성자 잭니콜
--------------------------------------------------------------------------------------------------------- 
트레이 아이콘을 구현하기
자바에서는 어떻게 트레이 아이콘을 구현 할 수 있을까요?

자바에서는 어떻게 트레이 아이콘을 구현 할 수 있을까요?
MFC를 해 보신 분들은 아시겠지만 Windows에서 트레이 아이콘을 구현하는 것은 아주 쉽습니다(?) 하지만 자바의 경우는 특정 플랫폼을 위한 언어가 아니기 때문에 특정 플랫폼에 종속적인 기능 같은 경우는 자바 프레임 웍 내부에서 아직 지원하지 않는 경우가 더러 있죠? 트레이 아이콘도 마찬가지인데요. 검색을 통해 알아보니 트레이 아이콘의 경우 윈도우즈와 리눅스의 Gnome 등 몇몇 데스크 탑의 고유 기능이라고 합니다. 그래서 그런지 자바의 5.0버전까지는 트레이 아이콘을 지원하지 않습니다. 결국 상용 또는 오픈 소스 라이브러리를 통해 구현해야하죠. 하지만 자바 6.0부터는 트레이 아이콘를 지원하고 있습니다.

그럼, 답이 나왔습니다. 자바 1.5버전 이하는 상용 또는 오픈 소스 라이브러리를 구해야하고, 자바 1.6부터는 지원하는 API를 사용하면 됩니다. 자바 1.5버전 이하의 경우  JDesktop 통합 컴포넌트(JDIC)를 사용하도록 하겠습니다.

JDesktop 통합 컴포넌트(JDIC)란 ?

JDesktop 통합 컴포넌트(JDIC)는 자바 애플리케이션이 native desktop에 통합할 수 있게 하며, 이 애플리케이션들이 웹브라우저나 이메일툴과 같은 운영시스템 지정 프로그램에서 제공되는 기능의 이점을 사용할 수 있게 하기 위한 The JDesktop Integration Components (JDIC) project에 의해서 만들어졌는데요. 쉽게 이야기 하면 특정 플랫폼에 종속적인 API를 사용할 수 있도록 해주는 컴포넌트 라이브러리라고 할수 있겠네요. 앞으로 JDesktop 통합 컴포넌트를 설명하는데 있어서 JDIC라는 명칭으로 통일해서 부르도록 하겠습니다. 이 프로젝트는 JDK 6.0을 위해 SUN에서 진행중인 프로젝트라고 하네요 ~ 뒤에 나올  자바 6.0버전에서 트레이 아이콘을 구현하는 방법을 소개할 때 사용할 API가 이 프로젝트를 통해서 만들어진거죠 ^^

트레이 아이콘 동작 방식에 대해서 ..

JDIC를 이용하거나 자바 6.0의 트레이 아이콘 API를 이용하던지 트레이 아이콘의 동작 방식은 똑같습니다. 윈도우가 실행되면 트레이 아이콘이 생성되고 윈도우가 화면에 나타납니다. (보통 메신저, 백신등의 프로그램을 보면 이런 식으로 동작하는 것을 알 수 있습니다.) 그리고 윈도우의 'X' 버튼 또는 Alt+F4등의 단축키를 이용해서 윈도우를 파괴하려고 하면 윈도우는 화면에서 사라지고 트레이 아이콘만 남게 되지요. 그리고 트레이 아이콘을 클릭하면 다시 윈도우가 나타나게 됩니다. 간단하죠 ^^

아래는 제가 구현한 샘플 프로그램의 클래스 다이어그램 입니다. 소스 다운로드 받으셔서 보실 때 편하게 분석하시라고 그려봤어요 ^^
이미지를 클릭하시면 원본크기로 보실수 있습니다.

JDIC_TrayIconMain은 TrayIconFrame을 실행시키는데 TrayIconFrame은 윈도우입니다. TrayIconApp는 트레이 아이콘이구요.
위에 설명한데로 프로그램이 실행되며 TrayIconFrame이 나타나고 TrayIconApp가 작업표시줄에 나타납니다. 그리고 TrayIconFrame을 파괴하려고 하면 TrayIconFrame을 화면에서 숨기고 TrayIconApp를 클릭하면 다시 TrayIconFrame을 화면에 보여줍니다. ^^


J2SE 5.0이하에서 트레이 아이콘 구현하기 ~

JDIC를 사용하기 위해서는 우선 JDesktop 통합 컴포넌트(JDIC) 웹사이트에 방문하셔서 JDIC를 다운로드 받으셔야 합니다.
저 같은 경우 Eclipse 3.4 / J2SE 5.0 / jdic-0.9.1-bin-windows.zip 을 이용하여 샘플 프로그램을 작성하였습니다.

1. 먼저 이클립스에 자바 프로젝트를 추가하시고 트레이 아이콘에 사용할 images폴더를 만드시고 이미지 파일을 넣어둡니다. 그리고 lib폴더를 만듭니다. jdic-0.9.1-bin-windows.zip을 다운로드 받으신 후에 압축을 푸시면 폴더 안에 jdic.jar과 tray.dll 파일을 보실 수 있는데요 이 녀석들이 트레이 아이콘을 구현하는데 사용되는 패키지와 DLL입니다. 이 녀석들을 lib폴더에 복사해 둡니다.






이미지를 클릭하시면 원본크기로 보실수 있습니다.
2. 프로젝트를 마우스 오른쪽 버튼으로 클릭하여 Properties 메뉴를 클릭합니다.

이미지를 클릭하시면 원본크기로 보실수 있습니다.
3. 대화상자가 나타나면 왼쪽 트리 목록에서 "Java Build Path"를 클릭하시고 오른쪽에 나타나는 탭 패인에서 "Libraries"를 선택하신 후 "Add External JARs" 버튼을 클릭하여 먼저 만들어 두었던 lib폴더의 "jdic.jar"를 선택합니다.

이미지를 클릭하시면 원본크기로 보실수 있습니다.
이미지를 클릭하시면 원본크기로 보실수 있습니다.
4. 모든 과정을 맞히면 Package Explorer에 다음과 같이 jdic.jar가 포함 됩니다. 이제 코딩만 하면 되죠 ^^

이미지를 클릭하시면 원본크기로 보실수 있습니다.

아래는 TrayIconApp의 일부 소스 입니다. 주석을 달아 놓았으면 보시면 금방 아실꺼예요 ~


 
// 이 녀석들이 JDIC에서 제공하는 트레이 아이콘 관련 클래스 들입니다. 
import org.jdesktop.jdic.tray.SystemTray;
import org.jdesktop.jdic.tray.TrayIcon;

public class TrayIconApp
{
  // SystemTray클래스를 얻어옵니다.
  private SystemTray m_tray = SystemTray.getDefaultSystemTray();
  private TrayIcon m_ti;    

  // 트레이 아이콘의 초기설정을 해줍니다.
  private void initTray()
  {
     // 트레이 아이콘의 아이콘 역할을 할 이미지 입니다. 
     ImageIcon i = new ImageIcon("images/duke.gif");

     
// TrayIcon을 생성합니다.
     m_ti = new TrayIcon(i, m_strTrayTitle, createPopupMenu())
;
     m_ti.setIconAutoSize(true);

     
// 트레이 아이콘 자체를 클릭했을때 일어날 이벤트에 대한 동작을 구현합니다. 현재 동작은 TrayIconFrame 윈도우가 숨겨져 있으면 보여주고, 나타나 있으면 숨겨줍니다 :)
      m_ti.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
            m_frame.setVisible(!m_frame.isVisible());
         }
      });

      
// 위에서 얻어온 SystemTray에 방금 막 생성한 TrayIcon의 인스턴스를 인자로 넣어주면 완성 ~~
      m_tray.addTrayIcon(m_ti);
    
}
}


실행을 시켜보면 아래와 같이 실행되는 화면을 보실 수 있습니다. ^^

이미지를 클릭하시면 원본크기로 보실수 있습니다.
이미지를 클릭하시면 원본크기로 보실수 있습니다.

빨간 동그라미의 아이콘이 트레이 아이콘입니다 ~~


J2SE 6.0에서 트레이 아이콘 구현하기 ~

J2SE 6.0에서는 위 5.0에서 처럼 복잡하게(사실 위에 방법도 실제로 해보시면 정말 간단합니다. 새삼 바쁘신 중에도 오픈 소스 프로젝트에 참여해주시는 많은 개발자 여러분께 감사드립니다 ㅡㅜ) 다운로드 받고 이클립스에 jar 설정을 해줄 필요없이 일반 자바 프로그램 짜듯이 트레이 아이콘 관련 패키지만 import 해주시면 됩니다. 처음에 알려드렸다시피 이미 JDIC가 J2SE 6.0에 포함 되었기 때문에 패키지 이름이나 메소드 명이 약간 바뀌었을 뿐 사용하는 방법은 JDIC와 똑같습니다. 다만 JDIC의 경우 JPopupMenu를 지원했는데 J2SE 6.0에서는 JPopupMenu를 지원하지 않아 PopupMenu를 사용해야 하네요 ;;

아래 소스는 JDIC를 사용한 TrayIconApp 클래스의 일부 소스입니다. 차이를 비교해 보시면 패키지 명과 메소드 명이 달른 것 이외에 거의 차이가 없다는 것을 아실 수 있으실 거예요 ~~

// 이 녀석들이 SE 6.0에서 제공하는 트레이 아이콘 관련 클래스 들입니다. 
import java.awt.SystemTray;
import java.awt.TrayIcon;

public class TrayIconApp implements ActionListener
{

  // SystemTray클래스를 얻어옵니다.
  private SystemTray m_tray = SystemTray.getSystemTray();
  private TrayIcon m_ti;    

  // 트레이 아이콘의 초기설정을 해줍니다.
  private void initTray()
  {
     // 트레이 아이콘의 아이콘 역할을 할 이미지 입니다. 
     Image image = Toolkit.getDefaultToolkit().getImage("images/duke.gif")
;

     
// TrayIcon을 생성합니다.
     m_ti = new TrayIcon(image, m_strTrayTitle, createPopupMenu())
;
     m_ti.setImageAutoSize(true);

     
// 트레이 아이콘 자체를 클릭했을때 일어날 이벤트에 대한 동작을 구현합니다. 현재 동작은 TrayIconFrame 윈도우가 숨겨져 있으면 보여주고, 나타나 있으면 숨겨줍니다 :)

      m_ti.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
              m_frame.setVisible(!m_frame.isVisible());
            }
       });

      // 위에서 얻어온 SystemTray에 방금 막 생성한 TrayIcon의 인스턴스를 인자로 넣어주면 완성 ~~
      try 
      {
          m_tray.add(m_ti);
      
      catch (AWTException e1
      {
          // TODO Auto-generated catch block
          e1.printStackTrace();
      }
   
}
}


실행 결과는 위와 같습니다. 다만 테스트 중 안건데 JDIC를 사용한 샘플은 트레이 아이콘을 한 번만 클릭해도 윈도우가 나타나는데 자바 6.0 API를 사용한 샘플은 더블 클릭을 해야 나타나내요;; 무슨 차이인지 모르겠네요 ^^


※ 위 글에 대한 잘못된 부분이나 궁금하신 부분에 대한 피드백은 언제나 환영입니다 ~ 물론, 퍼가신다면 영광이구요.
 우리나라의 모든 개발자 분들께서 바쁘시지만 서로 자신의 귀중한 경험과 지식을 공유해서 함께 발전해 나갈 수 있었으면 합니다 ^^


http://www.dude.co.rk


P 이경철님의 파란블로그에서 발행된 글입니다.

댓글 없음:

댓글 쓰기