2013-05-09 1 views
1

사용자가 화면에 버튼을 추가하거나 제거 할 수있는 앱을 만들고 있습니다. 아직 구현 된 옵션이 없습니다. 그래서, 지금은 for() 루프를 수동으로 채우고 수동으로 버튼 중 하나를 제거하고 있습니다. 내 문제는 버튼을 제거한 후 (메인()의 제거 작업), 그냥 빈 자리가 있다는 것입니다. 나는 그 버튼들 중 하나를 제거한 후에 화면을 다시 칠할 수 있기를 원합니다. 이 예제에서는 인덱스 2 (블록 # 3)가 제거되어 빈 공간이 남았습니다. 이전에는 ... 어디에서 다시 그리는 지 잘 모릅니다. 프로그램의 다른 위치에서 유효성 검사 또는 다시 칠을 시도했지만 성공하지 못했습니다.특정 요소가 제거 된 후 GUI를 다시 그리는 방법은 무엇입니까?

코드는 다음과 같습니다 (PS) 내 코드가 내가 시도하는 것을 달성하는 데 가장 효율적인 방법이 아니며 선호하는 방법이 아닌 setLayout (null)을 사용하고 있지만 지금은 단지 어떤 일을 배우려고하고 자신과 코드를) 더 나은 해당에 확장 : NullLayout를 사용하는

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.ArrayList; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.border.LineBorder; 

class TestApp extends JFrame{ 
    JFrame frame = new JFrame("Test Program"); 
    ArrayList<JButton> grid = new ArrayList<JButton>(); 

    private int w = 14; 
    private static int amount = 102; 
    private static int counter = 0; 

    //Default Constructor (sets up JFrame) 
    TestApp(){ 
     frame.setLayout(null); 
     frame.setPreferredSize(new Dimension(1186, 880));  
     frame.setDefaultCloseOperation(EXIT_ON_CLOSE); 
     frame.setResizable(false); 
     paintGrid(); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public void newWindow() 
    { 
     JFrame select_win = new JFrame("Selected Frame"); 
     JPanel select_panel = new JPanel(); 
     select_panel.setPreferredSize(new Dimension(600, 800)); 
     select_panel.setBackground(Color.ORANGE); 
     select_win.add(select_panel); 
     select_win.pack(); 
     select_win.setResizable(false); 
     select_win.setVisible(true); 
     select_win.setLocationRelativeTo(null); 
    } 

    private void paintGrid() 
    { 
     for(int i = 0, y = 4; i < ((amount/w) + (amount % w)); i++, y += 104) 
     { 
      for(int j = 0, x = 4; j < w && (counter < amount); j++, x += 84) 
      { 
       addBlock(counter, x, y); 
       counter++; 
      } 
     } 
    } 

    //Adds a block 
    private void addBlock(int index, int x, int y){ 
     int height = 100; 
     int width = 80; 

     grid.add(new JButton("counter: " + (counter + 1))); 
     (grid.get(index)).addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       javax.swing.SwingUtilities.invokeLater(new Runnable() { 
        @Override 
        public void run() { 
         newWindow(); 
        } 
       }); 
      } 
     }); 
     (grid.get(index)).setBorder(new LineBorder(Color.BLACK)); 
     (grid.get(index)).setBackground(Color.YELLOW); 
     (grid.get(index)).setVisible(true); 
     (grid.get(index)).setBounds(x, y, width, height); 

     frame.add(grid.get(index)); 
    } 

    //Removes a block 
    private void removeBlock(int index){ 
     frame.remove(grid.get(index)); 
     grid.remove(index); 
     amount--; 
     counter--; 
    } 

    public static void main(String [] args) { 
     javax.swing.SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       TestApp app = new TestApp(); 

       //testing block removal 
       app.removeBlock(2); 
      } 
     }); 
    } 
} 
+2

체크 아웃 [레이아웃 매니저에 대한 비주얼 가이드] (http://docs.oracle.com/javase/tutorial/uiswing/layout을이 알 것이라고 생각합니다 /visual.html) 레이아웃 관리자에 대한 자세한 내용은 [레이아웃 관리자 사용] (http://docs.oracle.com/javase/tutorial/uiswing/layout/using.html)을 참조하십시오. – MadProgrammer

+0

@MadProgrammer 네, 그걸 목표로 ... 여전히 무서워, 왜, 롤 –

+1

레이아웃 관리자는 많은 정보를 신속하게 그리고 그것은 약간의 발굴로 시작할 수 있지만 마음에서 끝으로 시작하고 그것을 달성하기 위해 여러 복합 레이아웃을 사용하는 것을 두려워하지 마십시오 당신이 원한다면 – MadProgrammer

답변

1

당신이 말한 것처럼 것은 좋지 않다. 다음과 같이 생성자에 FlowLayout

변경 레이아웃 : 문제를 해결하려면 두 변경을 할 필요가

frame.setLayout(new FlowLayout()); 

변경하려면 setPreferredSizesetBounds 전화 :

(grid.get(index)).setPreferredSize(new Dimension(width, height)); 

이제 FlowLayout은 자동으로 항목을 정렬하므로 더 이상 걱정할 필요가 없습니다.

재 검증() 메소드는이 구성 요소와 그 위의 모든 부모가 배치해야 할 필요가있는 것으로 표시되어있는 레이아웃 관리자에 통지() 재 검증 :

+1

X/Y 위치 지정을 사용하면 GridBagLayout과 같은 것을 사용하는 것이 더 좋을 수 있지만 아기 단계가 호출 될 수 있습니다. – MadProgrammer

+0

실제로는 꽤 잘 돌아 갔고 레이아웃이 더 좋았습니다. 멋지게 조정되었습니다. @MadProgrammer heh, 예, 저는 다른 몇 명의 사람들이 LayoutManager를 다른 질문에서 언급 한 후에 GridBagLayout을 눈으로 보았습니다. :) –

3

적절한 방법이 될 것이다. 즉, 레이아웃 관리자가 구성 요소를 재정렬하려고 시도합니다. 구성 요소를 제거한 후 자주 사용됩니다.

나는 당신이 실제로 스윙을 사용하는 경우에만

+0

코드에 어디에 넣으시겠습니까? 그것은 주 및 removeBlock 메서드에서 시도한 후에 나에게 적합하지 않았습니다. 다행히도 FlowLayout은 저를 위해 그것을 바로 잡는 멋진 일을합니다 ... 여전히 레이아웃 매니저의 도움 없이는 그렇게하지 않는 이유가 궁금합니다. –

+0

내 코드가 조금 바뀌었고 실제로 제안을 사용합니다. 고맙습니다. –

관련 문제