1

GroupLayoutにレイアウトされたJFrameがあります。ユーザーがボタンをクリックしたときに、この JFrame 内の 2 つのコンポーネントの位置を交換したいと思います。GroupLayoutのメソッドを使用しreplace()て、一方を他方に置き換えました。2つのボタンの位置を交換したいコードは次のとおりです:buttons[0]buttons[1]:

groupLayout.replace(buttons[1], buttons[2]);
groupLayout.replace(buttons[2], buttons[1]);

ただし、これを実行するとプログラムがスローNullPointerExceptionされます。例外は、役立つ情報を提供しません。

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at javax.swing.GroupLayout$ComponentInfo.setBounds(Unknown Source)
    at javax.swing.GroupLayout.layoutContainer(Unknown Source)
    at java.awt.Container.layout(Unknown Source)
    at java.awt.Container.doLayout(Unknown Source)
    at java.awt.Container.validateTree(Unknown Source)
    at java.awt.Container.validateTree(Unknown Source)
    at java.awt.Container.validateTree(Unknown Source)
    at java.awt.Container.validate(Unknown Source)
    at javax.swing.RepaintManager$2.run(Unknown Source)
    at javax.swing.RepaintManager$2.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at javax.swing.RepaintManager.validateInvalidComponents(Unknown Source)
    at javax.swing.RepaintManager$ProcessingRunnable.run(Unknown Source)
    at java.awt.event.InvocationEvent.dispatch(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$200(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)

(最初は、buttons[2] が既に削除されているためだと思ってい replace(buttons[1],buttons[3])ましたが、groupLayout に追加されていなかったところを試してみたところ、何も問題が発生しなかったため、何が問題なのかわかりませんでした。)

次に、後で操作できるように、変更したいコンポーネントのみを含むグループへの参照を維持するというアイデアを思いつきました。これが私のコードです:

if(count % 2 == 1) {
    groupLayout.replace(buttons[1], buttons[2]);
    button2HorizontalGroup.addComponent(buttons[1]);
    button2VerticalGroup.addComponent(buttons[1]);
}else {
    groupLayout.replace(buttons[2], buttons[1]);
    button2HorizontalGroup.addComponent(buttons[2]);
    button2VerticalGroup.addComponent(buttons[2]);
}

しかし、これは解決策というよりハックかもしれません。さらに、大量のコンポーネントを交換する場合は面倒です。GroupLayout でコンポーネントを交換するためのより良い解決策はありますか? (他のレイアウトのソリューションも大歓迎です:))

ありがとう。


アップデート:

@ user1803551: これが私のコードです (GroupLayoutTest は JFrame を拡張するクラスです):

public GroupLayoutTest() {
    // Allow group layout to automatically creat the gap between components and containers.
    groupLayout.setAutoCreateGaps(true);
    groupLayout.setAutoCreateContainerGaps(true);
    setLayout(groupLayout);


    buttons = new JButton[4];
    buttons[0] = new JButton("small 1");
    buttons[1] = new JButton("medium 2");
    buttons[2] = new JButton("big 3");

    buttons[1].addActionListener(replaceHandler);
    buttons[2].addActionListener(replaceHandler);

    button1HorizontalGroup.addComponent(buttons[1]);
    button1VerticalGroup.addComponent(buttons[1]);
    button2HorizontalGroup.addComponent(buttons[2]);
    button2VerticalGroup.addComponent(buttons[2]);

    groupLayout.setHorizontalGroup(
            groupLayout.createParallelGroup()
            .addGroup(groupLayout.createSequentialGroup()
                    .addGap(39)
                    .addComponent(buttons[0])
                    // Make it like a Spring
                    .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGap(10)
                    .addGroup(button1HorizontalGroup)
                    .addGap(52))
            .addGroup(groupLayout.createSequentialGroup()
                    .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGap(0)
                    .addGroup(button2HorizontalGroup)
                    .addContainerGap(GroupLayout.DEFAULT_SIZE, 160))
    );
    groupLayout.setVerticalGroup(
            groupLayout.createSequentialGroup()
            .addContainerGap(50, 50)
            .addGroup(groupLayout.createParallelGroup()
                    .addComponent(buttons[0])
                    .addGroup(button1VerticalGroup) )
            .addGap(10)
            .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addGroup(button2VerticalGroup)
            .addContainerGap(168, 168));

    groupLayout.linkSize(SwingConstants.HORIZONTAL, buttons[1],buttons[2]);
    pack();
    setLocationRelativeTo(null);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

private class ReplaceHandler implements ActionListener {

    private int count = 0;
    @Override
    public void actionPerformed(ActionEvent e) {
        count += 1;
        if(count % 2 == 1) {
            groupLayout.replace(buttons[1], buttons[2]);
            button2HorizontalGroup.addComponent(buttons[1]);
            button2VerticalGroup.addComponent(buttons[1]);
        }else {
            groupLayout.replace(buttons[2], buttons[1]);
            button2HorizontalGroup.addComponent(buttons[2]);
            button2VerticalGroup.addComponent(buttons[2]);
        }
        groupLayout.linkSize(SwingConstants.HORIZONTAL, buttons[1],buttons[2]);
    }

}

@camickr: 上記のコードからわかるように、私は GroupLayout の最初の経験を楽しんでいます。1つのボタン(「中」と「小」)をクリックすると、互いに入れ替わるようにしたいと思います。結局のところ、あなたのアドバイスに感謝します。:)

4

1 に答える 1