저는 GUI를 프로그래밍 중이 었습니다. 버튼을 누르면 계산 시간이 길어졌습니다. 계산이 실행되는 동안, 여전히 실행중인 계산의 중간 결과를 사용하여 JLabel에 기록하고자했습니다. 그러나 GUI는 계산이 완료되기 전에 사용자가 조작 할 수 없습니다. 이 같은 에서 처음으로 내가하고 있던 일 : 계산이 완료된 후GUI를 차단하는 동안 스윙 구성 요소를 업데이트
(1)
public class GUI extends JFrame {
JLabel label = new JLabel("Status: ");
public GUI(){...}
public void calculate() {
for(int i = 0; i < 10; i++) {
String one = calculationPartOne(i);
label.setText("Status: " + one);
label.repaint(); //*
calculationPartTwo(i);
}
}
}
이 작동하지 않았다, JLabel의 만 업데이트 할 것입니다. 또한 주석 처리 된 행에 관련된 모든 구성 요소를 .repaint() 및 .validate()하려고 시도했지만 아무 것도 수행하지 않았습니다. 그래서 Google/StackoOverflow를 시도하고 검색 한 후에 마침내 해결책을 찾았지만 위의 이유가 이해되지 않습니다. GUI를 차단하기를 원했기 때문에 당연히 같은 스레드에서 계산을 실행했습니다. 그러나 GUI를 다시 그리는 메소드를 호출하면 (계산이 중지되는 동안 계산이 중지됨) 작동하지 않으며 그 이유를 이해할 수 없습니다. 누군가 설명 할 수 있습니까?
결국, 나는 계산을 할 때 SwingWorker 클래스를 사용했고 계산하는 동안 JLabel을 업데이트하는 함수를 사용했습니다. 그러나 GUI를 차단해야 할 때 SwingWorker를 실행하기 전에 구성 요소를 모두 비활성화하고 SwingWorker에서 계산을 마친 후 모든 구성 요소를 다시 활성화 할 수있게되었습니다. 그래서 SwingWorker를 사용하여 EDT를 차단하지 않고 모든 것을 비활성화하여 EDT를 차단합니다. 이것은 나에게 정말로 역설적 인 것처럼 보인다.
public class GUI extends JFrame {
JLabel label = new JLabel("Status: ");
//I didn't use a list, but it works to illustrate it here
List<Component> GUIComponents = ...;
public GUI() {...}
public void calculate() {
SwingWorker<Void, String> worker = new SwingWorker<Void, String>() {
protected Void doInBackground() throws Exception {
for(int i = 0; i < 10; i++) {
String one = calculationPartOne(i);
publish(one);
calculationPartTwo(i); //**
}
}
protected void done() {
setEnableGUI(true);
}
protected void process(List<String> chunk) {
label.setText(chunk.get(chunk.size() - 1));
}
};
setEnableGUI(false);
worker.execute();
}
public void setEnableGUI(boolean e) {
for(Component c : GUIComponents) {
c.setEnabled(e);
}
}
//**
public void calculationPartTwo() {...}
}
이 작동 : 여기
내가 지금 무슨의 개요입니다.누군가가 분명히 밝힐 수 있기를 바랍니다. 이 솔루션은 잘못되었습니다.
SwingWorkers 메서드가 처리하고 게시하는 similair Q & A는 무리가 있습니다. setProgress가 가능하면 모든 가능한 모서리에서 JComponent를 스윙한다고 올바르게 알립니다. – mKorbel