2008-10-20 4 views
38

간단히 말하면, 거기에 몇 가지 구성 요소가있는 JFrame으로 구성된 간단한 자바 스윙 앱이 있습니다. 구성 요소 중 하나는 사용자 작업에서 다른 JPanel로 대체 될 JPanel입니다.JFrame 내부에서 JPanel을 어떻게 변경합니까?

그런 일을하는 올바른 방법은 무엇입니까? 시도했습니다.

panel = new CustomJPanelWithComponentsOnIt(); 
parentFrameJPanelBelongsTo.pack(); 

하지만 작동하지 않습니다. 너는 무엇을 제안 하겠는가?

답변

47

사용 사례는 CardLayout에 적합합니다.

카드 레이아웃에서는 같은 장소에 여러 패널을 추가 할 수 있지만 한 번에 한 패널 씩 표시하거나 숨길 수 있습니다.

+3

CardLayout을 사용하는 경우 레이아웃을 사용하는 패널의 기본 크기는 레이아웃에서 가장 큰 패널의 크기가됩니다. 공간을 재사용하려면 setVisible (false) 및 setPreferredSize (새 Dimension (0,0))를 사용하여 구성 요소를 숨기십시오. –

+0

전에 CardLayout에 대해 들어 보지 못했습니다. 감사합니다. 내가해야 할 일에 완벽했습니다. – I82Much

+0

예. 이것은 적절한 방법입니다. 어쩌면 최고 일 것입니다. – FaithReaper

17
frame.setContentPane(newContents()); 
frame.revalidate(); // frame.pack() if you want to resize. 

Java는 '값에 의한 복사 참조'인수 전달을 사용합니다. 따라서 변수를 변경하면 다른 메소드로 전달 된 참조 사본이 변경되지 않습니다.

참고 JFrame은 유용성의 이름으로 매우 혼란 스럽습니다. 구성 요소를 추가하거나 레이아웃을 설정하면 (일반적으로) 내용 분할 창에서 조작이 수행됩니다. 이상하게도 레이아웃을 얻는 것은 프레임의 레이아웃 관리자를 제공합니다.

+0

톰, 감사 할 필요가 없습니다 당신의 (jpanel1), frame.add (jpanel2), frame과 같은 배치 된 jpanel을 교체하려고하는 것이 아닙니다.add (jpanel3)). 코드에서 정상적인 솔루션을 제안 할 수 있습니까? – yanchenko

+0

Hey John, 사용 사례가 CardLayout에 적합합니다. http://java.sun.com/docs/books/tutorial/uiswing/layout/card.html 카드 레이아웃에서는 같은 장소에 여러 개의 패널을 추가 할 수 있지만 한 곳에서 하나의 패널을 표시하거나 숨길 수 있습니다. 시각. –

+0

@swapnonil : 투표 할 수 있도록 답변 해주세요. :) –

0

프레임 생성시 두 패널을 모두 추가 한 다음 두 패널에서 setVisible (true/false)를 호출하여 보이는 패널을 변경하는 것이 좋습니다. setVisible을 호출하면 부모에게 알림이 전송되고 자체 다시 칠해 줄 것을 요청합니다.

JFrame frame=new JFrame(); 
frame.getContentPane().add(new JPanel()); 

2) 패널 교체 :

frame.getContentPane().removeAll(); 
frame.getContentPane().add(new JPanel()); 

은 또한 당신이 SwingUtilities.invokeLater 또는 이벤트의 스레드에서이 작업을 수행해야합니다이 사용할 수 있도록 통지를 첫 번째 패널을 설정

1

다른 사람들이 질문에 대답했다. 내용을 바꾸는 대신 JTabbedPane을 사용하는 것이 좋습니다. 일반적으로 응용 프로그램의 시각적 요소가 사라지거나 다른 내용으로 대체되는 것은 좋지 않습니다. 물론 모든 규칙에는 예외가 있으며 사용자와 사용자 커뮤니티 만 최선의 방법을 결정할 수 있습니다.

3

모두 어떻게 사용되는지에 따라 다릅니다. 이 두 패널간에 앞뒤로 전환하려면 CardLayout을 사용하십시오. 첫 번째에서 두 번째로 한 번 전환하고 다시 시도하지 않는 경우 telcontar 제안을 사용하고 대신 바꿉니다. 프레임에서 JPanel이 유일한 것이 아니라면 removeAll 대신 remove(java.awt.Component)을 사용할 것입니다.

이 두 경우 사이의 어딘가에 있다면 기본적으로 시간 공간 상충 관계입니다. CardLayout을 사용하면 시간을 절약 할 수 있지만이 전체 패널을 항상 메모리에 유지해야하므로 더 많은 메모리를 차지합니다. 그러나 필요에 따라 패널을 교체하고 필요에 따라 구성하면 그 주변을 돌아 다닐 필요가 없지만 전환하는 데 더 많은 시간이 걸립니다.

또한 대신 탭을 사용하는 JTabbedPane에 시도 할 수있는 사용자 행동에

5

(이 automitically 숨어 보여주는를/처리하기 때문에 CardLayout보다 쉽게 ​​자사) : // 당신이 함께 뭔가를

myJFrame.getContentPane().removeAll() 
myJFrame.getContentPane().invalidate() 

myJFrame.getContentPane().add(newContentPanel) 
myJFrame.getContentPane().revalidate() 

다음으로 필요에 따라 창 크기를 조정할 수 있습니다.

6

이 코드를 사용하면 JFrame에서 jPanels을 변경하는 방법을 알 수 있기를 바랍니다.

public class PanelTest extends JFrame { 

     Container contentPane; 

     public PanelTest() { 
      super("Changing JPanel inside a JFrame"); 
      contentPane=getContentPane(); 
     } 

     public void createChangePanel() { 
      contentPane.removeAll(); 
      JPanel newPanel=new JPanel(); 
      contentPane.add(newPanel); 
      System.out.println("new panel created");//for debugging purposes 
      validate(); 
      setVisible(true); 
     } 
} 
1

정확히 같은 문제가 발생했습니다. 깨달을 수있는 !! 내가 찾은 해결책은 다음과 같습니다.

  1. 모든 구성 요소 (JPanels)를 컨테이너에 추가합니다.
  2. 모두에 setVisible (false) 메서드 사용.
  3. 사용자 작업에서 setVisible (true)을 으로 표시하려는 패널로 설정합니다.
// Hiding all components (JPanels) added to a container (ex: another JPanel) 
for (Component component : this.container.getComponents()) { 
     component.setVisible(false); 
}
// Showing only the selected JPanel, the one user wants to see 
panel.setVisible(true); 

없음 재 검증한다(), 아니 유효성 검사는(), 더 CardLayout는 필요하지 않습니다.

0
class Frame1 extends javax.swing.JFrame { 

    remove(previouspanel); //or getContentPane().removeAll(); 

    add(newpanel); //or setContentPane(newpanel); 

    invalidate(); validate(); // or ((JComponent) getContentPane()).revalidate(); 

    repaint(); //DO NOT FORGET REPAINT 

} 

경우에 따라 다시 검증을 사용하지 않고도 작업을 수행 할 수 있으며 때로 다시 페인트를 사용하지 않아도됩니다. 두 가지를 모두 사용하는 것이 좋습니다.

0

그냥 같이 (아마 세 이상 java 1.7을)는 ContentPane을 설정 한 후) (를하는 방법 팩을 호출

JFrame frame = new JFrame(); 
JPanel panel1 = new JPanel(); 
JPanel panel2 = new JPanel(); 
.... 
frame.setContentPane(panel1); 
frame.pack(); 
... 

frame.setContentPane(panel2); 
frame.pack(); 
... 
-1

당신은이 레이아웃의 방법을 대체 할 수 있습니다 :

layout.replace(existingComponent, newComponent) 

기존 구성 요소와 새로운 구성 요소도 JPanel이 될 수 있습니다.

1

layout.replace() 응답 만 존재/GroupLayout Manager에서 작동합니다.

다른 LayoutManagers (등 CardLayout, BoxLayout에서는)이 기능을 지원하지만, 먼저 RemoveLayoutComponent (및 AddLayoutComponent (다시. :-) [그냥 설정 기록 스트레이트]에 대한

관련 문제