요즘 애플릿에 대한 논의가 많지는 않으나 J2SE 1.4에
정보 저장을 위한 메인 메소드는
스트림이 저장된 후에는 싱글 스트림 또는 스트림 전체를 이용하여 이를 검색할 수 있다. 싱글 스트림을 얻으려면

다음은 사용자 인터페이스 생성에 사용되는 코드이다.
서는 java.applet 패키지의 AppletContext 클래스에 세 가지 메소드가 추가되었다. 많은 사람들이 추가된 사실을 알아채지 못할 수도 있지만, 이 메소드들은 유용한 기능을 제공한다. 즉, 데이터를 스트림에 저장하고 각 스트림을 지정된 키(named key)에 매핑하는 것이다. 정보 저장을 위한 메인 메소드는
setStream()이다. public void setStream(String name, InputStream stream)스트림은 저장 시 키값 (Map과 유사한) 구조의 키에 연결되고, 매핑은 애플릿의 코드베이스에 한정된다. 이 말은 하나의 호스트에서 나온 애플릿이 다른 호스트의 스트림에 액세스하지 못한다는 것을 의미한다.
스트림이 저장된 후에는 싱글 스트림 또는 스트림 전체를 이용하여 이를 검색할 수 있다. 싱글 스트림을 얻으려면
getStream() 메소드를 이용하여 이름별로 요청을 한다. public InputStream getStream(String name)getStreamKeys() 메소드를 이용하여 모든 스트림을 검색하는데, 이 작업을 수행할 때는
Map으로 돌아가지 않는다. 대신, 다음과 같은 String 이름의 Iterator를 얻는다. public Iterator사용자가 원하는 특정 스트림의 키 이름을 얻은 후에는getStreamKeys()
getStream() 메소드를 이용하여 해당 스트림을 얻는다. 이 때, 일반적으로 사용되는 패턴은 다음과 같다. Iterator이들이 인풋 스트림이라는 점을 유념할 것. 문자로 작업하고자 하는 경우에는 반드시 문자 세트를 이용해야 한다. 예를 들어iter = getAppletContext().getStreamKeys(); if (iter != null) { while (iter.hasNext()) { String name = iter.next(); InputStream stream = getAppletContext().getStream(name); // read stream... } }
String 오브젝트를 저장하려면 바이트를 얻어 AppletContext 내의 ByteArrayInputStream에 저장한다. String message = ...;
ByteArrayInputStream bais =
new ByteArrayInputStream(message.getBytes("UTF-8"));
getAppletContext().setStream("key-name", bais);
이 오브젝트를 읽으려면 스트림을 얻어 이를 InputStreamReader로 변환할 때 동일 문자 세트를 전달한다. Reader 오브젝트를 얻은 후에는 다음 예제처럼 문자를 읽을 수 있다. InputStream stream =
getAppletContext().getStream("key-name");
InputStreamReader isr =
new InputStreamReader(stream, "UTF-8");
BufferedReader reader = new BufferedReader(isr);
String line = reader.readLine();
API는 사실상 이것이 전부라 할 수 있다. 'setStream() 메소드를 이용하여 새로운 스트림을 저장하고, getStream()을 이용하여 스트림을 되돌린다. getStreamKeys()를 이용하여 스트림 키 세트를 얻는다. ' 이것이 스트림에 관해 알아 두어야 할 전부인 것처럼 보일지 모르지만, 그렇다면 스트림 컨텐츠를 제거하려면 어떻게 해야 할까? 그 답은 다음과 같다. 특정 키와 연결된 InputStream으로 null을 전달한다. 이렇게 하면 스트림의 컨텐츠가 시스템에서 제거된다. getAppletContext().setStream("key-name", null);
이번에는 API의 데모를 살펴보기로 하자. 먼저, 프로그램 로더인 HTML 파일을 생성해야 한다. 200x200의 디스플레이 면적을 필요로 하는 StreamsApplet으로 명명된 애플릿의 경우, HTML 파일에는 다음과 같은 애플릿 태그가 포함되어야 한다. <applet code=StreamsApplet width=200 height=200> </applet>
StreamsApplet 애플릿은 키값 쌍을 위해 2개의 텍스트 필드를 제공하는데, 이 때 키는 lookup name이며 값은 저장될 InputStream 컨텐츠이다. 아울러 애플릿은 2개의 버튼을 디스플레이한다. 첫 번째 버튼은 명명된 스트림을 추가하고(또는 기존의 것을 업데이트한다), 두 번째 버튼은 명명된 스트림을 제거한다. 애플릿은 JList에 현재의 이름 세트를 표시한다. 
다음은 사용자 인터페이스 생성에 사용되는 코드이다.
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
public class StreamsApplet extends JApplet {
private static final String CHARSET = "UTF-8";
JButton add;
JButton remove;
JList list;
JTextField key;
JTextField value;
public void init() {
JLabel keyLabel = new JLabel("Key");
keyLabel.setDisplayedMnemonic('K');
key = new JTextField();
keyLabel.setLabelFor(key);
JLabel valueLabel = new JLabel("Value");
valueLabel.setDisplayedMnemonic('V');
value = new JTextField();
valueLabel.setLabelFor(value);
JPanel topPanel = new JPanel(new GridLayout(2,2));
topPanel.add(keyLabel);
topPanel.add(key);
topPanel.add(valueLabel);
topPanel.add(value);
add(topPanel, BorderLayout.NORTH);
list = new JList();
list.setSelectionMode
(ListSelectionModel.SINGLE_SELECTION);
JScrollPane pane = new JScrollPane(list);
add(pane, BorderLayout.CENTER);
add = new JButton("Add/Update");
add.setDisplayedMnemonic('A');
remove = new JButton("Remove");
remove.setDisplayedMnemonic('R');
JPanel bottomPanel = new JPanel();
bottomPanel.add(add);
bottomPanel.add(remove);
add(bottomPanel, BorderLayout.SOUTH);
}
}
이제 스트림 추가와 업데이트를 위한 액션을 추가해 보자. Add/Update 버튼 뒤의 ActionListener는 각각의 텍스트 필드에서 이름과 스트림 컨텐츠를 획득한 다음 이를 AppletContext에 저장해야 한다. 스트림을 추가한 후에는 JList에 스트림 목록이 표시되고 ActionListener가 텍스트 필드를 소거해야 한다. String keyText = key.getText();
String valueText = value.getText();
try {
ByteArrayInputStream bais =
new ByteArrayInputStream(valueText.getBytes(CHARSET));
getAppletContext().setStream(keyText, bais);
} catch (IOException ioe) {
JOptionPane.showMessageDialog(StreamsApplet.this,
"Unable to save", "Error", JOptionPane.ERROR_MESSAGE);
}
updateList();
key.setText("");
value.setText("");
updateList() 메소드는 상당히 간단한데, 단순히 이름 목록을 얻어 이를 JList에 넣기만 하면 된다. DefaultListModel model = new DefaultListModel();
Iterator<String> iter = getAppletContext().getStreamKeys();
if (iter != null) {
while (iter.hasNext()) {
model.addElement(iter.next());
}
}
list.setModel(model);
Remove 버튼 뒤의 ActionListener는 키 텍스트 필드의 모든 이름에 대해 단순히 스트림을 null로 설정한다. 이 경우에도 제거 후에 이름 목록을 업데이트하고 텍스트 필드를 소거해야 한다. String keyText = key.getText();
try {
getAppletContext().setStream(keyText, null);
} catch (IOException ioe) {
JOptionPane.showMessageDialog(StreamsApplet.this,
"Unable to clear", "Error", JOptionPane.ERROR_MESSAGE);
}
updateList();
key.setText("");
value.setText("");
이것으로 작업이 모두 완료된 것은 아니다. 목록에서 이름을 선택하면 현재의 값이 표시되는데, 이 작업은 ListSelectionListener를 통해 이루어진다. 리스너는 JList에서 선택된 값을 획득한 다음 애플릿 컨텍스트에서 스트림을 룩업한다. 이름을 찾을 수 없으면 getStream() 메소드는 null을 리턴한다. 단, JList에는 스트림과 일치하는 이름만 포함되므로 확인 작업이 필요하지는 않다. String selection = (String)list.getSelectedValue();
try {
InputStream stream =
getAppletContext().getStream(selection);
InputStreamReader isr =
new InputStreamReader(stream, CHARSET);
BufferedReader reader = new BufferedReader(isr);
String line = reader.readLine();
key.setText(selection);
value.setText(line);
} catch (IOException ioe) {
JOptionPane.showMessageDialog(StreamsApplet.this,
"Unable to read", "Error", JOptionPane.ERROR_MESSAGE);
}
이것을 모두 합치면 애플릿 컨텍스트에 명명된 스트림을 저장할 완벽한 애플릿이 구현된다. 다음은 모든 리스너를 각각의 해당 컴포넌트에 첨부하기 위한 소스의 전체 내용이다. import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
public class StreamsApplet extends JApplet {
private static final String CHARSET = "UTF-8";
JButton add;
JButton remove;
JList list;
JTextField key;
JTextField value;
public void init() {
JLabel keyLabel = new JLabel("Key");
keyLabel.setDisplayedMnemonic('K');
key = new JTextField();
keyLabel.setLabelFor(key);
JLabel valueLabel = new JLabel("Value");
valueLabel.setDisplayedMnemonic('V');
value = new JTextField();
valueLabel.setLabelFor(value);
JPanel topPanel = new JPanel(new GridLayout(2,2));
topPanel.add(keyLabel);
topPanel.add(key);
topPanel.add(valueLabel);
topPanel.add(value);
add(topPanel, BorderLayout.NORTH);
list = new JList();
list.setSelectionMode(
ListSelectionModel.SINGLE_SELECTION);
JScrollPane pane = new JScrollPane(list);
add(pane, BorderLayout.CENTER);
add = new JButton("Add/Update");
add.setMnemonic('A');
remove = new JButton("Remove");
remove.setMnemonic('R');
JPanel bottomPanel = new JPanel();
bottomPanel.add(add);
bottomPanel.add(remove);
add(bottomPanel, BorderLayout.SOUTH);
ActionListener addListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
String keyText = key.getText();
String valueText = value.getText();
try {
ByteArrayInputStream bais =
new ByteArrayInputStream(
valueText.getBytes(CHARSET));
getAppletContext().setStream(keyText, bais);
} catch (IOException ioe) {
JOptionPane.showMessageDialog(StreamsApplet.this,
"Unable to save", "Error",
JOptionPane.ERROR_MESSAGE);
}
updateList();
key.setText("");
value.setText("");
}
};
add.addActionListener(addListener);
ActionListener removeListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
String keyText = key.getText();
try {
getAppletContext().setStream(keyText, null);
} catch (IOException ioe) {
JOptionPane.showMessageDialog(StreamsApplet.this,
"Unable to clear", "Error",
JOptionPane.ERROR_MESSAGE);
}
updateList();
key.setText("");
value.setText("");
}
};
remove.addActionListener(removeListener);
ListSelectionListener selectListener =
new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
String selection = (String)list.getSelectedValue();
try {
InputStream stream =
getAppletContext().getStream(selection);
InputStreamReader isr =
new InputStreamReader(stream, CHARSET);
BufferedReader reader = new BufferedReader(isr);
String line = reader.readLine();
key.setText(selection);
value.setText(line);
} catch (IOException ioe) {
JOptionPane.showMessageDialog(StreamsApplet.this,
"Unable to read", "Error",
JOptionPane.ERROR_MESSAGE);
}
}
};
list.addListSelectionListener(selectListener);
updateList();
}
private void updateList() {
DefaultListModel model = new DefaultListModel();
Iterator<String> iter =
getAppletContext().getStreamKeys();
if (iter != null) {
while (iter.hasNext()) {
model.addElement(iter.next());
}
}
list.setModel(model);
}
}
Java 플러그인 기술 덕분에, 대부분의 데스크톱에서도 애플릿을 브라우저에서 실행할 수 있게 되었다. 최신 자바 소프트웨어를 확인하고 새로운 애플릿을 시험해보고 싶다면 java.com을 방문하기 바란다."Java SE" 카테고리의 다른 글
- 리스너 리스트를 위한 WEAKHASHMAP 사용하기 (댓글 1개 / 트랙백 0개) 2006/03/08
- J2SE 5.0의 Java 2D API 기능 강화 (댓글 2개 / 트랙백 0개) 2006/05/12
- 3D 화면(scene)에 빛 효과 주기 (댓글 1개 / 트랙백 0개) 2004/07/30
- 다이얼로그 Modality (댓글 1개 / 트랙백 0개) 2006/06/09
- 쿠키 처리 (댓글 22개 / 트랙백 3개) 2007/07/23
- 사용자 데이터그램 프로토콜의 프로그래밍 (댓글 1개 / 트랙백 0개) 2004/06/30
- 락(LOCKS) (댓글 1개 / 트랙백 0개) 2005/09/22
- Java Web Start 퍼시스턴스 (댓글 3개 / 트랙백 0개) 2006/12/24
- AFFINETRANSFORM 이해하기 (댓글 3개 / 트랙백 0개) 2003/09/09
- 사용자 인터페이스에서 Action 사용하기 (댓글 5개 / 트랙백 2개) 2007/02/22
2006/04/21 09:45
2006/04/21 09:45
댓글을 달아 주세요
재밋는 자료인것같습니다. 나중에 응용된 먼가를 만들면 유용할꺼같네요...
2007/09/18 10:16좋은 정보 감사해요~
2007/09/19 04:41