2014-03-12 5 views
0

이 간단한 예제에서와 같이 점진적으로 Java JFrame 디자인 구조를 수정하고 싶습니다. 루프에서 나는 JPanel의 preferredWidth를 증가시키고 pack() 메소드를 사용합니다. 그러나 팩 방법은 무시됩니다. 루프에서 팩을 꺼내서 한 번만 사용하면 작업이됩니다. 누구나 이유와 가능한 해결책을 알고 있습니까?루프에서 JFrame.pack() 사용

public class Calculadora extends JFrame { 

private JPanel pnl = new JPanel(); 
private boolean flag; 

public Calculadora() { 
    JPanel pnlPrincipal = new JPanel(); 
    pnlPrincipal.setPreferredSize(new Dimension(300, 300)); 
    pnlPrincipal.setBackground(Color.BLACK); 
    JButton btnAnexo = new JButton("Anexo"); 
    btnAnexo.addActionListener(new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      if (flag) { 
       closeAnexo(); 
       flag = false; 
      } else { 
       openAnexo(); 
       flag = true; 
      } 
     } 
    }); 
    pnlPrincipal.add(btnAnexo); 
    this.pnl.setBackground(Color.WHITE); 
    this.pnl.setPreferredSize(new Dimension(0, 300)); 
    this.add(pnl, BorderLayout.EAST); 
    this.add(pnlPrincipal, BorderLayout.CENTER); 
    this.pack(); 
    this.setVisible(true); 
} 

private void openAnexo() { 
    new Thread() { 
     @Override 
     public void run() { 
      for (int i = pnl.getWidth(); i <= 200; i++) { 
       pnl.setPreferredSize(new Dimension(i, 300)); 
       pack(); 
      } 
     } 
    }.start(); 
} 

private void closeAnexo() { 
    new Thread() { 
     @Override 
     public void run() { 
      for (int i = pnl.getWidth(); i >= 0; i--) { 
       pnl.setPreferredSize(new Dimension(i, 300)); 
       pack(); 
      } 
     } 
    }.start(); 
} 

public static void main(String[] args) { 
    new Calculadora(); 
} 
} 

답변

3

:

private void openAnexo() { 
    new Thread() { 
     @Override 
     public void run() { 
      for (int i = pnl.getWidth(); i <= 200; i++) { 
       pnl.setPreferredSize(new Dimension(i, 300)); 
       pack(); 
      } 
     } 
    }.start(); 
} 

스윙 구성 요소가 Event Dispatch Thread 업데이트/작성해야합니다. 이렇게 말하면 GUI가 EDT를 차단하여 GUI가 응답하지 않게됩니다. SwingUtilities.invokeLater()을 사용하여이 새 스레드를 EDT와 동기화해야합니다. 또는이 모든 동시성 작업을 처리하는 편의 클래스 인 Swing Timer을 사용하여 반복적 인 작업을 수행 할 수 있습니다. 예를 들어

:

private void openAnexo() { 
    javax.swing.Timer timer = new javax.swing.Timer(200, new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      int width = pnl.getWidth(); 
      if(width > 200) { 
       ((javax.swing.Timer)e.getSource()).stop(); 
      } else { 
       pnl.setPreferredSize(new Dimension(width + 1, 300)); 
       Calculadora.this.pack(); 
      } 

     } 
    }); 
    timer.setRepeats(true); 
    timer.setDelay(200); 
    timer.start(); 
} 

더 나은 설명은 How to Use Swing Timers 튜토리얼을 살펴 보자.

나는 이것을 달성하기 위해 무엇을 시도하고 있는지 알지 못하지만, 이것에 유의해야한다 : Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing? (그래야한다).

+0

정말 고마워요! 그것은 작동합니다! –

+0

@ user2308270 당신은 환영합니다 :) – dic19

0

당신은 사용해야 적절한이 경우 layout manager, BorderLayout : 여기

JPanel pnlPrincipal = new JPanel(); 
pnlPrincipal.setLayout(new BorderLayout()); 

// or 

JPanel pnlPrincipal = new JPanel(new BorderLayout()); 
+0

문제가 지속됩니다. 왜냐하면 두 번째 JPanel을이 JPanel이 아닌 JFrame에 추가하기 때문입니다. 따라서 레이아웃은 아무런 차이가 없습니다. –