JFILECHOOSER 사용자 정의하기
스윙에서는 외형이 사용자의 맘에 들지 않으면 단순히 변경할 수 있었다. 이번 팁에서는 JFileChooser컴포넌트의 외형과 그것의 속성을 사용자 정의하는 방법을 배우게 될 것이다. 먼저 JFileChooser의 사용법을 복습해보자. 그리고 컴포넌트를 이용한 단일/다중 선택과 파일/디렉토리의 선택, 파일의 세팅과 현재 선택된 컨텐츠를 미리 보기할 때 필요한 액세서리를 추가하는 과정, 마지막으로 파일 리스트 뷰 영역을 업데이트하는 것을 공부하기로 하겠다.
기본적인 사용법
JFileChooser 컴포넌트는 시스템에서 사용하고자 하는 파일과 디렉토리를 선택할 수 있는 방법을 제공한다. 이 컴포넌트는 하나 이상의 파일이나 디렉토리를 선택할 수 있는 다이알로그를 제공한다. JFileChooser 컴포넌트에 포함된 것들은 다이알로그의 모달 버전을 보여주기 위한 메소드들의 집합이다. 모달이란, 사용자가 어떤 항목을 선택하지 않는 한 메소드가 값을 리턴하지 않는 것을 말한다. 이러한 메소드로는 showOpenDialog, showSaveDialog, showDialog 가 있다. 이 3개의 메소드는 승인 버튼에 어떤 텍스트가 나타날 것인지를 조절한다. (즉, 이 텍스트는 다이얼로그를 이용한 작업이 끝났을 때 사용자가 선택한 사항이다.) Open 과 Save 와 같은 일반적인 옵션에 관해서는 물론 빌트인(built-in) 메소드가 존재한다. 디스플레이되는 파일 선택창 다이알로그는 현재의 룩앤필 세팅에 적절하게 맞춰져 있다. 일반적으로 다이알로그는 사용자의 플랫폼에 적합한 파일 다이알로그로 보이고, 특별히 설정된 사항이 없다면 크로스 플랫폼의 Metal 룩앤필로 설정된다.
사용자는 다이알로그에서 항목을 선택하고 Open 이나 Save 버튼을 클릭하거나 선택된 항목을 더블 클릭한다. 그러면 Show 메소드는 승인 버튼이 선택된 것인지, 아니면 사용자가 항목을 선택하지 않고 다이알로그를 닫아버렸는지(사용자가 Cancel 버튼이나 윈도우 상위 코너의 x 버튼을 클릭했을 때)를 나타내는 상태값을 리턴한다. 리턴될 수 있는 가능한 상태는 CANCEL_OPTION, APPROVE_OPTION, 혹은 ERROR_OPTION 와 같은 클래스 상수에 의해 지정된다. JFileChooser의 예제를 보자.
import java.io.File;
import javax.swing.*;
public class Basics {
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFileChooser fileChooser =
new JFileChooser(".");
int status = fileChooser.showOpenDialog(null);
if (status == JFileChooser.APPROVE_OPTION) {
File selectedFile =
fileChooser.getSelectedFile();
System.out.println("Selected: "
+ selectedFile.getParent()
+ " --- "
+ selectedFile.getName());
}
System.exit(0);
}
});
}
}
이 프로그램은 파일 선택창 다이알로그를 디스플레이한다. 사용자가 디렉토리와 파일을 선택하면 다이알로그는 디렉토리를 인식하고 파일이름을 디스플레이한다.
tt031604_Basics.gif
단일/다중 선택
JFileChooser는 단일 선택 모드를 디폴트 값으로 한다. 이는 사용자가 한번에 하나의 디렉토리나 파일만 선택할 수 있다는 것을 의미한다. 만약 한번에 여러 개의 항목을 선택할 수 있는 것을 허용한다면, multiSelectionEnabled 를 true로 설정해야 한다. 예제를 보자.
import java.io.File;
import javax.swing.*;
public class Multi {
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFileChooser fileChooser
= new JFileChooser(".");
fileChooser.setMultiSelectionEnabled(true);
int status = fileChooser.showOpenDialog(null);
if (status == JFileChooser.APPROVE_OPTION) {
File selectedFiles[] =
fileChooser.getSelectedFiles();
for (int i=0,
n=selectedFiles.length; i PREFERRED_HEIGHT) {
icon = new ImageIcon(
icon.getImage().getScaledInstance
(-1, PREFERRED_HEIGHT,
Image.SCALE_DEFAULT));
}
}
setIcon(icon);
}
}
}
}
마지막으로, 다음 Accessories 프로그램을 실행시켜 보자. 이를 실행하면 액세서리 패널을 볼 수 있다. 프로그램을 실행할 때, 이미지를 포함하는 디렉토리를 선택해야 한다는 것을 잊지 말자. 프리뷰 패널에서 이미지를 볼 수 있다. 현재 선택값이 이미지가 아니면 프리뷰 패널에는 아무것도 나타나지 않는다.
import java.io.File;
import javax.swing.*;
public class Accessories {
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFileChooser fileChooser =
new JFileChooser(".");
LabelAccessory accessory =
new LabelAccessory(fileChooser);
fileChooser.setAccessory(accessory);
fileChooser.addPropertyChangeListener
(JFileChooser.SELECTED_FILE_CHANGED_PROPERTY,
accessory);
int status = fileChooser.showOpenDialog(null);
if (status == JFileChooser.APPROVE_OPTION) {
File selectedFile =
fileChooser.getSelectedFile();
System.out.println("Selected: "
+ selectedFile.getParent()
+ " --- "
+ selectedFile.getName());
}
System.exit(0);
}
});
}
}
FileView
파일 이름이 열거되어 있는 파일 선택창 내의 영역은 추상 클래스 FileView에 의해 조정된다. 커스텀 서브클래스를 생성함으로써 파일을 열거하는 방법을 사용자 정의할 수 있다. 이 클래스는 아이콘이나 이름을 찾기 위한 5개의 메소드를 갖지만, 속성을 모두 사용자 정의할 필요는 없다. 메소드 중의 하나라도 null값을 리턴하면, 컴포넌트는 디폴트 값을 찾아내기 위해 룩앤필의 특정한 속성을 컴토하게 된다.
이를 실행시킬 때에는 자바 관련 파일들, 즉 .java files에는 파란색 아이콘, .class files에는 초록색 아이콘과 같은 특별한 아이콘들을 만들기 위해 JFileChooser 를 생성해야 한다. .java 파일에는 파일 이름에 파일 사이즈를 덧붙이자.
아이콘을 정의하고 있는 예제이다.
import javax.swing.*;
import java.awt.*;
public class DiamondIcon implements Icon {
private Color color;
private boolean selected;
private int width;
private int height;
private Polygon poly;
private static final int DEFAULT_WIDTH = 10;
private static final int DEFAULT_HEIGHT = 10;
public DiamondIcon(Color color) {
this(color, true, DEFAULT_WIDTH,
DEFAULT_HEIGHT);
}
public DiamondIcon(Color color, boolean selected) {
this(color, selected, DEFAULT_WIDTH,
DEFAULT_HEIGHT);
}
public DiamondIcon(Color color, boolean selected,
int width, int height) {
this.color = color;
this.selected = selected;
this.width = width;
this.height = height;
initPolygon();
}
private void initPolygon() {
poly = new Polygon();
int halfWidth = width/2;
int halfHeight = height/2;
poly.addPoint(0, halfHeight);
poly.addPoint(halfWidth, 0);
poly.addPoint(width, halfHeight);
poly.addPoint(halfWidth, height);
}
public int getIconHeight() {
return height;
}
public int getIconWidth() {
return width;
}
public void paintIcon(
Component c, Graphics g, int x, int y) {
g.setColor(color);
g.translate(x, y);
if (selected) {
g.fillPolygon(poly);
} else {
g.drawPolygon(poly);
}
g.translate(-x, -y);
}
}
위와 같은 특별한 아이콘들을 보여주는 JFileChooser를 생성하는 프로그램이다. 원한다면 디폴트 속성을 보기 위해 setFileView 라인을 코멘트처리할 수 있다. 그리고 파란색과 초록색 아이콘을 이용해서 사용자 정의된 FileView를 볼 수 있도록 코멘트를 다시 활성화 시킬 수 있다.(이 때 사용자의 위치는 소스와 컴파일 된 소스 파일을 포함하는 디렉토리 안으로 가정한다.)
import java.io.File;
import java.awt.*;
import javax.swing.*;
import javax.swing.filechooser.*;
public class JavaFileView extends FileView {
Icon javaIcon = new DiamondIcon(Color.blue);
Icon classIcon = new DiamondIcon(Color.green);
/**
* If .java file, add length to name
*/
public String getName(File file) {
String filename = file.getName();
if (filename.endsWith(".java")) {
filename += " : " + file.length();
return filename;
}
return null;
}
/**
* Return special icons for .java and .class files
*/
public Icon getIcon(File file) {
// default icons for all directories
if (file.isDirectory()) {
return null;
}
String filename = file.getName();
if (filename.endsWith(".java")) {
return javaIcon;
} else if (filename.endsWith(".class")) {
return classIcon;
}
return null;
}
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFileChooser fileChooser =
new JFileChooser(".");
FileView view = new JavaFileView();
fileChooser.setFileView(view);
int status = fileChooser.showOpenDialog(null);
System.exit(0);
}
});
}
}
JFileChooser 에 관한 자세한 정보는 "see the javadoc"을 참고한다. 또한 자바 튜토리얼의 "How to Use File Choosers"를 참고하자. 멀티스레딩과 스윙에 관해서는 자바 튜토리얼의 "How to Use Threads" 를 참고하기 바란다. |