2025. 1. 24. 17:05ㆍJava/Eclipse RCP
이클립스 UI 플러그인 개발 시 참고할만한 내용.
자바 Swing (JFC) 개발할 때도 마찬가지이지만, UI 에서 DB조회 이벤트를 발생시킬 때 해당 코드를 스레드로 감싸지 않으면 조회결과로 (주로 Table) UI 를 채울 때까지 프로그램은 멈춘 듯이 보인다. 그렇게 보이는 이유는 비UI 작업을 UI 에서 실행하려고 하다 보니 UI가 멈추는 것이다. SWT (standard widget toolkit) 에서 이것을 해결하는 방법으로 여러가지가 있겠지만 여기서는 UIJob 으로 해결하는 방법을 다루려고 한다.
아래의 소스는 이클립스 플러그인 개발 위저드에서 제공하는 TableViewer 샘플코드에 기반하며 이벤트 발생을 위해 Button 과 UIJob 을 추가하였다.
package myplugin;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.progress.UIJob;
import jakarta.inject.Inject;
public class View extends ViewPart {
public static final String ID = "MyPlugin.view";
@Inject IWorkbench workbench;
private TableViewer viewer;
private class StringLabelProvider extends ColumnLabelProvider {
@Override
public Image getImage(Object obj) {
return workbench.getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT);
}
}
@Override
public void createPartControl(Composite parent) {
viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
viewer.getTable().setLinesVisible(true);
TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE);
column.setLabelProvider(new StringLabelProvider());
viewer.getTable().getColumn(0).setWidth(200);
viewer.setContentProvider(ArrayContentProvider.getInstance());
// 여기서부터 추가한 코드
Button actionBtn = new Button(parent, SWT.PUSH);
actionBtn.setText("set");
actionBtn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
readData();
}
});
}
// 스레드 내부 스코프에서 액세스할 수 있도록 전역변수로 지정
List<String> dataObj = new ArrayList<>();
void readData() {
// UI 안에서 쓸 수 있게 UIJob 을 생성함
UIJob job = new UIJob("데이터 가져오는 중...") {
@Override
public IStatus runInUIThread(IProgressMonitor monitor) {
// 이 부분은 DB 조회 또는 통신과 관련된 코드로 대체할 수 있다.
dataObj.clear();
dataObj.add("One");
dataObj.add("Two");
dataObj.add("Three");
// IStatus 를 반환해야 하기에...
IStatus status = new Status(IStatus.OK, Activator.PLUGIN_ID, IStatus.OK, "", null);
return status;
}
};
/* 여기가 핵심이다 */
job.addJobChangeListener(new JobChangeAdapter() {
// Job 수행이 끝날 때 처리하는 로직
@Override
public void done(IJobChangeEvent event) {
viewer.setInput(dataObj);
}
});
// 이건 Product 로 생성할 때 ProgressBar 를 팝업처럼 띄우는 기능임.
job.setUser(true);
job.schedule();// job을 시동하는 코드
}
@Override
public void setFocus() {
viewer.getControl().setFocus();
}
private List<String> createInitialDataModel() {
return Arrays.asList("One", "Two", "Three");
}
}
UIJob 에서 호출하는 runInThread() 메서드 안에 비즈니스 로직을 넣고 해당 결과를 UI 에 적용하는 코드는 JobChangeListener 의 done() 이벤트 메서드 안에 넣어야 한다. 빠른 설명을 위해 List<String> 형 변수에 데이터를 채우는 방식으로 코드를 작성하였다. (단순히 One, Two, Three 요 데이터들을 TableViewer 에 넣는 작업만 할 때는 UIJob 을 쓸 필요도 없다. 이 부분이 DB조회처럼 타 시스템를 거쳐서 오는 작업을 할 때 필요한 것이다)
위 코드에서 tableviewer.setInput(dataObj); 라인을 runInThread() 메서드 안에 넣으면 TableViewer 에 데이터가 채워지지 않는 것을 확인할 수 있다. 아래 영상은 완성된 코드를 실행한 영상임.
'Java > Eclipse RCP' 카테고리의 다른 글
Eclipse Plugin 단축키 (0) | 2025.01.08 |
---|