2014-07-04 3 views
1

내가 JFrame의에서 JButton의 격자를 찍은하는 작은 게임을 코딩하고 내가하는 JFrame의,에 포함 된 버튼의 색상을 새로 고칠 이미 visible.As는JFrame에 포함 된 버튼의 색상을 새로 고치는 방법은 무엇입니까?

void foo(){ 
    mainFrame.setVisible(true);//mainFrame is defined at class level. 
    //color update code for the buttons. 
    mainFrame.setVisible(true); 
} 

아래에 설명 결과 나는 예상대로되지 않고 화면이 정지합니다. 내가 원하는 것을 성취하는 것이 옳은 방법입니까? 편집 내가, 나는이 클래스가 achieve.i 원하는 것을 상세하게 설명하고 확인 : -

import javax.swing.*; 
import java.awt.*; 
import java.util.*; 
class Brick extends JButton{ 
     public void setRandomColors(){ 
      int random = (int) (Math.random()*50); 
      if(random%13==0){ 
       this.setBackground(Color.MAGENTA); 
      } 
      else if(random%10==0){ 
       this.setBackground(Color.red); 
      } 
      else if(random%9==0){ 

       this.setBackground(Color.yellow); 
      } 
      else if(random%7==0){ 
       this.setBackground(Color.orange); 
      } 
      else if(random%2==0){ 
       this.setBackground(Color.cyan); 
      } 
      else{ 
       this.setBackground(Color.PINK); 
      } 
    } 
    public void setBlackColor(){ 
      this.setBackground(Color.black); 
    } 
} 
class Grid { 
    JFrame mainGrid = new JFrame(); 
    ArrayList<Brick> bunchOfBricks = new ArrayList<>(); 
    int gridLength = 8;//gridlenth is equals to gridweight as i have considered a Square grid. 
    int totalBricks = gridLength*gridLength; 
    public void formBunchOfBricks(){ 
      for(int i=0;i<totalBricks;i++){ 
         bunchOfBricks.add(new Brick()); 
      } 
    } 
    public void formColoredGrid(){ 
      Brick aBrick; 
      mainGrid.setLayout(new GridLayout(8,8)); 
      for(int i=0;i<totalBricks;++i){ 
         aBrick = (bunchOfBricks.get(i)); 
         aBrick.setRandomColors(); 
         mainGrid.add(aBrick); 
      } 
      mainGrid.setVisible(true);//its ok upto here iam getting randomly colored Frame of Bricks or so called JButtons. 
      delay(15);//Sorry for this one,i warn you not to laugh after looking its defination. 

    } 
/* 
I want following function to do following things:- 
1.it should firstly display the Grid whose all buttons are black Colored. 
2.After some time the original colored,first Row of grid formed by formColoredGrid should be       displayed and all the rest Rows should be black. 
3.Then second row turns colored and all other rows should be black......and so on upto last row of Grid. 
*/ 
    public void movingRows(){ 
      setGridBlack(); 
      delay(1);//see in upper method,for this horrible thing. 
      for(int i=0;i<gridLength;++i){ 
       setGridBlack(); 
       for (int j=0;j<gridLength;++j){ 
        Brick aBrick = bunchOfBricks.get((gridLength*i)+j); 
        aBrick.setRandomColors();//Bricks are colored Row by Row. 
       } 
      delay(5);//already commented this nonsense. 
      mainGrid.setVisible(true);//using setVisible again,although this frame is already visible,when i called formColoredGrid. 

      setGridBlack(); 
     } 
//oh! disappointing,i have almost broken my arm slamming it on table that why the function result in a screen full of black buttons. 
    } 
    public void setGridBlack(){ 
      for(int i=0;i<totalBricks;i++){ 
        bunchOfBricks.get(i).setBlackColor(); 
      } 
    } 
    public void delay(int a){ 
     for (int i=0;i<90000000;++i){ 
      for(int j=0;j<a;++j){ 

      } 
     } 
    } 
    public static void main(String args[]){ 
      Grid g1 = new Grid(); 
      g1.formBunchOfBricks(); 
      g1.formColoredGrid(); 
      g1.movingRows(); 
} 

}

밖으로 방법이 무엇인지 제발 도와주세요?

+0

프레임을 숨기거나 표시 할 필요가 없습니다. 버튼의 색상 만 변경하면됩니다. 화면이 멈 추면 Event Dispatch Thread를 차단하고 GUI가 다시 칠하는 것을 방지하는 다른 코드가있을 것입니다. 문제를 보여주는 [SSCCE] (http://sscce.org/)를 게시하십시오. – camickr

+0

http://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html –

+0

@peeskillet이 내 문제를 해결합니다. – YakRangi

답변

5

귀하의 문제가 코드에 여기에 표시하지 :

//color update code for the buttons. 

당신은 가능성이 가능성이 끝없는 스윙 이벤트 스레드에서 결코 끝나지 않아 루프를 실행하는 동안 루프 여론 조사 무언가의 상태 (즉, 추측) GUI를 고정시킵니다. 해결책 : 이렇게하지 마십시오. 연속 폴링 루프를 사용하지 마십시오. 대신 스윙이 이벤트 기반이므로 응답에 따라 색상을 이벤트으로 변경하십시오.

자세한 도움이 필요하면 문제 코드를 표시하고 프로그램에 대해 자세히 알려주십시오.


편집

하나 행진 아래 보드 하나, 색의 행을 보여주기 위해 노력하고, 다음 내 생각이 옳다, 당신은 스윙 타이머, 하나를 사용하는 것이 좋습니다 경우 그 int 인덱스를 사용하여 어떤 행이 컬러로 표시되는지 나타냅니다. Timer의 ActionPerformed 클래스 내부에서 인덱스를 증가시킨 다음 모든 행이 표시되면 Timer를 중지합니다. 예를 들면 다음과 같습니다.

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.GridLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.HashMap; 
import java.util.Map; 
import java.util.Random; 

import javax.swing.*; 

@SuppressWarnings("serial") 
public class MyGrid extends JPanel { 
    private static final int GRID_LENGTH = 8; 
    private static final Color BTN_BACKGROUND = Color.BLACK; 
    private static final Color[] COLORS = { Color.MAGENTA, Color.CYAN, 
     Color.RED, Color.YELLOW, Color.ORANGE, Color.PINK, Color.BLUE, 
     Color.GREEN }; 
    private static final int PREF_W = 400; 
    private static final int PREF_H = PREF_W; 
    private static final int TIMER_DELAY = 800; 
    private JButton[][] buttonGrid = new JButton[GRID_LENGTH][GRID_LENGTH]; 
    private Map<JButton, Color> btnColorMap = new HashMap<>(); 
    private Random random = new Random(); 

    public MyGrid() { 
     setLayout(new GridLayout(GRID_LENGTH, GRID_LENGTH)); 
     for (int row = 0; row < buttonGrid.length; row++) { 
     for (int col = 0; col < buttonGrid[row].length; col++) { 
      JButton btn = new JButton(); 
      btn.setBackground(BTN_BACKGROUND); 
      // !! add action listener here? 

      add(btn); 
      buttonGrid[row][col] = btn; 
     } 
     } 

     new Timer(TIMER_DELAY, new TimerListener()).start(); 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     return new Dimension(PREF_W, PREF_H); 
    } 

    public void resetAllBtns() { 
     for (JButton[] row : buttonGrid) { 
     for (JButton btn : row) { 
      btn.setBackground(BTN_BACKGROUND); 
     } 
     } 
    } 

    private class TimerListener implements ActionListener { 
     private int row = 0; 

     @Override 
     public void actionPerformed(ActionEvent e) { 
     resetAllBtns(); // make all buttons black 

     if (row != buttonGrid.length) { 
      for (int c = 0; c < buttonGrid[row].length; c++) { 
       int colorIndex = random.nextInt(COLORS.length); 
       Color randomColor = COLORS[colorIndex]; 
       buttonGrid[row][c].setBackground(randomColor); 

       // !! not sure if you need this 
       btnColorMap.put(buttonGrid[row][c], randomColor); 
      } 

      row++; 
     } else { 
      // else we've run out of rows -- stop the timer 
      ((Timer) e.getSource()).stop(); 
     } 
     } 
    } 

    private static void createAndShowGui() { 
     MyGrid mainPanel = new MyGrid(); 

     JFrame frame = new JFrame("MyGrid"); 
     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGui(); 
     } 
     }); 
    } 
} 

Swing Timer Tutorial도 확인하십시오.


enter image description here


편집 2
당신은 질문 :

하지만이 프로그램의 실패 원인은 무엇인가, 그것은 쓸모 지연 기능입니까?

귀하의 지연 방법은 스윙 이벤트 스레드에서 아무것도하지만 바쁜 계산을하지 않습니다 :

public void delay(int a) { 
    for (int i = 0; i < 90000000; ++i) { 
    for (int j = 0; j < a; ++j) { 

    } 
    } 
} 

그것은 Thread.sleep(...) 전화에서 원유 시도에서 조금 다른, 그리고 명시 적으로 기간을 제어 할 수 없기 때문에 원유입니다 스레드 수면과 함께 실행됩니다. 다시 말하지만, 문제는 Swing 이벤트 발송 스레드 또는 EDT (모든 Swing 그리기 및 사용자 상호 작용을 담당하는 단일 스레드)에서 이러한 호출을하고 있다는 것입니다.이 스레드를 차단하면 프로그램이 실행되지 않거나 정지됩니다.

+0

예, 색상 업데이트에서 루프를 사용하고 있습니다. – YakRangi

+0

그런 다음 출구는 무엇입니까? – YakRangi

+0

@Bayant_singh : 다시 루프를 사용하지 마십시오. 진지하게, 당신은 당신의 질문을 향상시키고, 더 많은 코드를 보여주고, 당신이하고자하는 것을 더 자세하게 기술 할 필요가 있습니다. 귀하의 의견'/ 색상 업데이트 ...'우리가 아무것도 이해할 수 있도록 충분하지 않습니다. 당신은'// 그리고 여기에 어떤 마법이 생기게 될지도 모른다. ' –

관련 문제