2012-04-20 5 views
2

실험 후 Swing의 GroupLayout은 GUI에서 재사용 할 수있는 구성 요소를 잃는 경향이 있습니다.Swing의 GroupLayout 및 setContentPane - 구성 요소가 손실됩니까?

그러나이 단일 사용 규칙을 명확하게 만드는 문서에서는 아무것도 보지 못했습니다. 이것은 제가 실수를 저 지르거나 내가 가난한 독자 일지 궁금하게 만듭니다.

예를 들어 JButton ("Foo")의 GroupLayout을 사용하여 JPanel을 만듭니다. 그런 다음 동일한 JButton의 GroupLayout이 "Bar"로 바뀌면서 또 다른 JPanel을 만듭니다.

JFrame.setContentPane을 사용하여 두 번째 JPanel에서 첫 번째 JPanel로 다시 전환하면 첫 번째 JPanel에서 JButton이 손실됩니다.

누구나 잃어버린 이유를 설명 할 수 있습니까? 더 나아가 구성 요소를 잃는 경향을 극복 할 수있는 방법을 제공 할 수 있습니까? 여기

문제 보여주는 완벽한 SSCCE입니다 :

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

public class GroupLayoutTest { 

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

static JPanel firstPanel; 
static JButton jbtnActionLog; 
static JFrame systemFrame; 

public static void deployGroupLayoutTest() { 
    systemFrame = new JFrame("Group Layout Test"); 
    systemFrame.setSize(300, 300); 

    firstPanel = new JPanel(); 

    JMenuBar jmbSystem = new JMenuBar(); 

    JMenu jmuAction = new JMenu("Action"); 

    JMenuItem jmiActionLog = new JMenuItem("Login"); 
    jmuAction.add(jmiActionLog); 

    jmbSystem.add(jmuAction); 

    jbtnActionLog = new JButton("Login"); 
    jbtnActionLog.addActionListener(new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      setContentPaneToSecondPanel(); 
     } 
    }); 

    systemFrame.setJMenuBar(jmbSystem); 

    GroupLayout gl = new GroupLayout(firstPanel); 
    firstPanel.setLayout(gl); 
    gl.setAutoCreateContainerGaps(true); 
    gl.setAutoCreateGaps(true); 

    GroupLayout.ParallelGroup hGroup = gl.createParallelGroup(GroupLayout.Alignment.CENTER); 
    hGroup 
      .addComponent(jbtnActionLog); 

    gl.setHorizontalGroup(hGroup); 

    GroupLayout.SequentialGroup vGroup = gl.createSequentialGroup(); 
    vGroup 
      .addComponent(jbtnActionLog); 
    gl.setVerticalGroup(vGroup); 

    systemFrame.getContentPane().add(firstPanel); 
    systemFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    systemFrame.setLocationByPlatform(true); 
    systemFrame.setVisible(true); 

} 

public static void setContentPaneToSecondPanel() { 
    jbtnActionLog.setText("Logout"); 
    ActionListener[] listenerList = jbtnActionLog.getActionListeners(); 
    jbtnActionLog.removeActionListener(listenerList[0]); 
    jbtnActionLog.addActionListener(new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      systemFrame.setContentPane(firstPanel); 
      systemFrame.revalidate(); 
     } 
    }); 

    JPanel secondPanel = new JPanel(); 

    GroupLayout gl = new GroupLayout(secondPanel); 
    secondPanel.setLayout(gl); 
    gl.setAutoCreateContainerGaps(true); 
    gl.setAutoCreateGaps(true); 

    GroupLayout.ParallelGroup hGroup = gl.createParallelGroup(GroupLayout.Alignment.CENTER); 
    hGroup 
      .addComponent(jbtnActionLog); 

    gl.setHorizontalGroup(hGroup); 

    GroupLayout.SequentialGroup vGroup = gl.createSequentialGroup(); 
    vGroup 
      .addComponent(jbtnActionLog); 
    gl.setVerticalGroup(vGroup); 

    systemFrame.setContentPane(secondPanel); 
    systemFrame.revalidate(); 
} 

} 나는 모든 코드를 통과하지 않은

답변

2

을하지만, 여러 부모들에게 하나의 스윙 구성 요소를 추가하는 단순히 수 없습니다 . 각 컴퍼넌트는, Swing 계층의 1 개의 위치에 밖에 존재할 수 없습니다. 그래서 코드

JPanel firstPanel = ...; 
JPanel secondPanel = ...; 
JButton button = ...; 
firstPanel.add(button); 
secondPanel.add(button); 

는 모두 패널 중 하나에 포함하지 button가 발생합니다. 이것은 GroupLayout와는 아무런 관련이 없습니다.

각각의 GUI 구성 요소가 한 번만 포함 할 수 있습니다

관련 SO question

이를 설명하는 Swing tutorial에 대한 링크가 포함되어 있습니다. 구성 요소가 이미 컨테이너에 있고 다른 컨테이너에 추가하려고하면 해당 구성 요소가 첫 번째 컨테이너에서 제거 된 다음 두 번째 컨테이너에 추가됩니다.

+0

Aha! 이 문제에 대해 설명해 주셔서 감사합니다. 그 문제에 대한 해답은 새 구성 요소를 생성하는 것과 같지만 동일한 Action 또는 ActionListener ... +1을 사용하여 명확하고 유익한 대답을 얻는 것입니다. – Arvanem

관련 문제