2012-12-26 2 views
2

다음 코드가 작동하지 않는 이유는 무엇입니까? 기본적으로 이것은 좀 더 어려운 프로그램의 단순화 된 버전으로 다른 실행 파일에 링크 된 버튼이있는 선택 항목으로 실행 가능한 초기 화면을 만들려고 시도하지만 예상대로 실행되지 않습니다.다른 Runnable 내부에서 Runnable을 실행하는 Java가 작동하지 않음

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

public class Runnables { 
    static Runnable runone; 
    static Runnable runtwo; 
    static JFrame frame = new JFrame(); 
    static JButton button1 = new JButton("Initial screen"); 
    static JButton button2 = new JButton("After button click screen"); 

    public static void main(String[] args) { 
     runone = new Runnable() { 
      @Override 
      public void run() { 
       frame.removeAll(); 
       frame.revalidate(); 
       frame.repaint(); 
       frame.add(button2); 
      } 

     }; 
     runtwo = new Runnable() { 
      @Override 
      public void run() { 
       frame.setSize(800, 600); 
       frame.setVisible(true); 
       button1.addActionListener(new ActionListener() { 
        @Override 
        public void actionPerformed(ActionEvent arg0) { 
         runone.run(); 
         System.out 
           .println("This is performed, but the button doesnt change"); 
        } 
       }); 
       frame.add(button1); 
      } 
     }; 
     runtwo.run(); 
    } 
} 
+0

당신은 당신의 Runnable를 처음으로 확인하는에 디버그 문을 추가 시도? 서면으로, 그것은 곧바로 함수 호출, 그것에 대해 특별한 아무것도 아니에요 ... – Krease

답변

4

Runnable에 대한 특별한 조치가 필요하지 않습니다. 코드 샘플 약자로, 다음은 동일합니다

public void actionPerformed(ActionEvent arg0) { 
    frame.removeAll(); 
    frame.revalidate(); 
    frame.repaint(); 
    frame.add(button2); 
    System.out.println("This is performed, but the button doesnt change"); 
} 

코드를 촬영하고 runone.run 내부 System.out.println 디버그 문을 추가

public void actionPerformed(ActionEvent arg0) { 
    runone.run(); 
    System.out.println("This is performed, but the button doesnt change"); 
} 

는 실행되는 사실에 있음을 보여줍니다.

코드 샘플은 간단한 문제 데모로 가정합니다. 당신은 처음에 '평범한 함수'(위에서 두 번째 예제, Runnables가 결합 된 곳)로 원하는 것을 수행하고, 이후에 다른 Runnables로 분리 할 수 ​​있습니다.

편집가 - 귀하의 예제가 작동하도록하기 위해 기억해야 할 것은 JFrame가 아이를 호스트 할의 contentPane를 사용한다는 것입니다 - frame.add은 (javadoc for JFrame 기준)의 contentPane에 추가의 편의를 위해 존재하지만 removeAll (지금 당장 나와 함께 연주하는 것에 기초하여) 이것을하지 않습니다. 또한 버튼을 추가 한 후 validate을 호출하면 두 번째 버튼이 표시되도록 하위 구성 요소가 제대로 다시 레이아웃됩니다.

이 하나 runone의 당신의 정의를 교체하고 샘플 작동합니다 :

runone = new Runnable() { 
    @Override 
    public void run() { 
     frame.getContentPane().removeAll(); 
     frame.add(button2); 
     frame.validate(); 
    } 
}; 
+0

이게 저의 작은 사건에 대한 올바른 해결책입니다.하지만 더 큰 경우에는 여러 개의 버튼이있는 창에서 만든 다음 다른 언어로 게임을 시작하는 각 버튼이 runnable.run()과 함께 작동하지 않습니다. 또는 SwingUtilities.InvokeLater (실행 가능); –

+0

디버거에서 단계별 실행을 시도하십시오. Runnables의 명령문이 실행됩니다 (중단 점 또는 디버그 명령문을 추가하여이를 증명합니다). 일반적으로 문제가되는 내용의 정확성입니다. 좋은 디버거를 사용하면 코드 흐름을보다 명확하게 볼 수 있으며 다양한 지점에서의 상태와 잘못된 점에 집중할 수 있습니다. – Krease

3

먼저 Thread 객체 내에서 Runnable 객체를 캡슐화해야하고 start()를 호출하여 스레드를 시작합니다. 예를 들면 :

Runnable r = ...; 
Thread thread = new Thread(r); 
thread.start(); 


편집 :

당신은 당신의 Runnable의이 EDT에서 호출 할 수 있는지 확인해야합니다. 예를 들면 :

SwingUtilties.invokeLater(r); 

아니면 스윙 코드와 관련된 집중적 인 작업을 처리하기위한 SwingWorker을 사용할 수 있습니다. SwingWorker의 작동 방식을 이해하려면 this answer을 참조하십시오.

+0

당신은 이것이 어떻게 생겼는지에 대한 간단한 예를 들려 줄 수 있습니까? –

+0

@ user268396 답변을 업데이트했습니다. 한번보세요. –

+0

답변을 변경 했으므로 스레드 대화는 유효한 지점을 모호하게합니다. – user268396

관련 문제