2

実験の結果、Swing の GroupLayout は、GUI 全体での再利用を目的としたコンポーネントを失う傾向があるようです。

しかし、この使い捨てルールを明確にするドキュメントは見たことがありません。これは、私が間違いを犯したのか、それとも私が下手な読者なのか疑問に思います.

たとえば、JButton("Foo") の GroupLayout を使用して JPanel を作成します。次に、「Bar」という名前に変更された同じ JButton の GroupLayout を持つ別の JPanel を作成します。

JFrame.setContentPane を使用して 2 番目の 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();
}

}

4

1 に答える 1

2

すべてのコードを調べたわけではありませんが、単一の Swing コンポーネントを複数の親に追加することは不可能です。各コンポーネントは、Swing 階層内の 1 つの場所にのみ存在できます。だからコード

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

button両方ではなく、一方のパネルにのみ含まれます。これは とは関係ありませんGroupLayout

関連するSO の質問には、これを説明するSwing チュートリアルへのリンクが含まれています。

各 GUI コンポーネントは 1 回だけ含めることができます。コンポーネントがすでにコンテナにあり、それを別のコンテナに追加しようとすると、コンポーネントは最初のコンテナから削除され、次に 2 番目のコンテナに追加されます。

于 2012-04-20T19:26:04.650 に答える