2

リストの各項目にサブリストと呼ぶと思われるものを追加しようとしています。以下の出力を提供するカスタムレンダラーを構築しました。ご覧のとおり、ここで何かが正しくないため、問題の答えを突き止めることができませんでした。正しい結果を得るには、パネルのレイアウトで何かを変更する必要があると思いますが、何がわかりません。

http://i.stack.imgur.com/jCKjJ.jpg

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.GridLayout;
import java.util.Random;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.ListCellRenderer;
import javax.swing.border.EmptyBorder;

public class GAListRendererAdv extends Container implements ListCellRenderer {
private static final long serialVersionUID = 1L;
private JPanel pnl = new JPanel();
private Random rnd = new Random();

public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,
        boolean cellHasFocus) {

    pnl.setLayout(new BorderLayout(0, 0));

    JCheckBox chckbxSomething = new JCheckBox("something");
    pnl.add(chckbxSomething, BorderLayout.NORTH);

    JSeparator separator = new JSeparator();
    pnl.add(separator, BorderLayout.CENTER);

    JPanel panel_1 = new JPanel();
    panel_1.setBorder(new EmptyBorder(0, 35, 0, 0));
    pnl.add(panel_1, BorderLayout.SOUTH);
    panel_1.setLayout(new GridLayout(0, 1, 0, 0));

    int rndNum = rnd.nextInt(5) + 1;

    for (int i = 0; i < rndNum; i ++) {
    JLabel lblNewLabel2 = new JLabel("New label");
    panel_1.add(lblNewLabel2);
    }

    return pnl;
}
}
4

1 に答える 1

4

まず、CellRenderersSwingでは「ラバースタンプ」として使用されていることを忘れないでください。これは、メモリを節約し、パフォーマンスを向上させるために行われます。これにより、などJListのコンポーネントは、レンダラーへの単一の参照を維持しながら、リスト内のすべてのアイテムをペイントできます。

つまり、getListCellRendererComponent呼び出されると、レンダラーは最後に呼び出されたときと同じ状態になります。

あなたのコードから私が知ることができることから、これは、レンダラーが呼び出されるたびに、ANOTHERチェックボックス、ANOTHERセパレーターANOTHERパネル、およびさらに多くのラベルを追加することを意味します...

第二に、レンダラーでは、可能な限り何も作成しないようにしてくださいgetListCellRendererComponent。これにより、メモリ使用量が増えるだけです(コードの一部に選択肢がない場合があります)。

第三に、JList私が前に述べた理由により、エディターをサポートしていません。レンダラーはエディターではありません。

第四に。すべての要素をパネルに追加する前に、パネルの「本体」部分からコンテンツを削除してみてください。

// Don't use Container, use JPanel instead, mixing heavy and light weight components
// is never a good idea :P
public class GAListRendererAdv extends JPanel implements ListCellRenderer {
    private static final long serialVersionUID = 1L;
    private JPanel pnl = new JPanel();
    private Random rnd = new Random();

    private JCheckBox checkBox;

    public GAListRendererAdv() {

        setLayout(new BorderLayout(0, 0));            
        checkBox = new JCheckBox();

        add(checkBox, BorderLayout.NORTH);
        add(new JSeparator(), BorderLayout.CENTER);

        pnl = new JPanel(new GridLayout(0, 1, 0, 0));
        pnl.setBorder(new EmptyBorder(0, 35, 0, 0));

        add(pnl BorderLayout.SOUTH); // Don't forget to add the panel :P

    }

    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {

        pnl.removeAll();
        int rndNum = rnd.nextInt(5) + 1;

        for (int i = 0; i < rndNum; i ++) {
            JLabel lblNewLabel2 = new JLabel("New label");
            pnl.add(lblNewLabel2);
        }

        return this;
    }
于 2012-08-01T01:21:08.917 に答える