2

JComboBox にカスタムの BasicComboBoxRenderer を使用しており、ドロップダウン リストの項目の外観を変更しました。ただし、これらの変更は、コンボボックスに表示される単一のトップ項目にも適用されます (呼び出し方がわからない)。

可能であれば、一番上のアイテムをリスト内の他のアイテムから独立させたいです。また、フォーカスされているときに一番上のアイテムの青い色を取り除きたいと思います(setFocusable(false)は私が望むものではありません)。

「レンダラー インデックス」(-1) を使用してトップ アイテムに影響を与えようとしましたが、効果がないようです。

何か案は?

PS 残念ながら、画像を追加してより明確にすることはできませんでした (評判なし)。

編集: 一番上の項目をドロップダウン リストの他のすべての項目から独立させたいと言うとき、私は常に残りの項目とは異なって見えることを意味します。たとえば、私のカスタム BasicComboBoxRenderer では、選択した項目に別の背景を設定しましたが、この背景は一番上の項目にも適用されます (選択した項目がコンボボックスの一番上の項目になるため)。

編集 2: トップ項目 = コンボボックスの表示領域を意味していたので、ドロップダウン リストの最初の項目ではなく、表示領域に表示される項目に影響を与えたいと考えています。コンボボックス自体で setBackground と setFocusable(false) を使用してこれを行うことができました (フォーカスメカニズムを維持したいので、これはあまり役に立ちません)。しかし、問題は (フォーカスの問題を除いて) たとえば、カスタムの BasicComboBoxRenderer または ListCellRenderer クラスを介してリスト内の各項目に境界線を設定すると、この同じ境界線が表示領域に表示される項目に表示されることです。したがって、ここに2つの質問があります:

--ドロップダウン リストのアイテムと表示領域の単一アイテムのレイアウトを区別する方法はありますか?

-- ボタンで setFocusPainted(false) を使用するときのように、フォーカス メカニズムを無効にせずにコンボボックスのフォーカス カラーを無効にする方法はありますか? (また、コンボボックスにカスタム FocusListener を追加しようとしましたが、focusGained() によって背景に加えられた変更はボタンのみに影響し、表示領域に表示されるアイテムには影響しません)。

混乱と複数の編集で申し訳ありません...

4

1 に答える 1

5

編集

BasicComboBoxRendererまたはListCellRendererはこの方法でそれを行うことができます

import java.awt.*;
import javax.swing.*;

public class TestHighLightRow {

    public void makeUI() {
        Object[] data = {"One", "Two", "Three"};
        JComboBox comboBox = new JComboBox(data);
        comboBox.setPreferredSize(comboBox.getPreferredSize());
        comboBox.setRenderer(new HighLightRowRenderer(comboBox.getRenderer()));
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(comboBox);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

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

            @Override
            public void run() {
                new TestHighLightRow().makeUI();
            }
        });
    }

    public class HighLightRowRenderer implements ListCellRenderer {

        private final ListCellRenderer delegate;
        private int height = -1;

        public HighLightRowRenderer(ListCellRenderer delegate) {
            this.delegate = delegate;
        }

        @Override
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
            Component component = delegate.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
            Dimension size = component.getPreferredSize();
            if (index == 0) {
                component.setBackground(Color.red);
                if (component instanceof JLabel) {
                    ((JLabel) component).setHorizontalTextPosition(JLabel.CENTER);
                }
            }
            return component;
        }
    }
}

EDIT2

JComboBoxには2つの状態があります

  • 編集可能

  • non_editable

基本的に、すべての値はUIManager、ショートカットからアクセスできます。

import java.awt.*;
import java.util.Vector;
import javax.swing.*;
import javax.swing.UIManager;
import javax.swing.plaf.ColorUIResource;
import javax.swing.plaf.metal.MetalComboBoxButton;

public class MyComboBox {

    private Vector<String> listSomeString = new Vector<String>();
    private JComboBox someComboBox = new JComboBox(listSomeString);
    private JComboBox editableComboBox = new JComboBox(listSomeString);
    private JComboBox non_EditableComboBox = new JComboBox(listSomeString);
    private JFrame frame;

    public MyComboBox() {
        listSomeString.add("-");
        listSomeString.add("Snowboarding");
        listSomeString.add("Rowing");
        listSomeString.add("Knitting");
        listSomeString.add("Speed reading");
//
        someComboBox.setPrototypeDisplayValue("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
        someComboBox.setFont(new Font("Serif", Font.BOLD, 16));
        someComboBox.setEditable(true);
        someComboBox.getEditor().getEditorComponent().setBackground(Color.YELLOW);
        ((JTextField) someComboBox.getEditor().getEditorComponent()).setBackground(Color.YELLOW);
//
        editableComboBox.setPrototypeDisplayValue("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
        editableComboBox.setFont(new Font("Serif", Font.BOLD, 16));
        editableComboBox.setEditable(true);
        JTextField text = ((JTextField) editableComboBox.getEditor().getEditorComponent());
        text.setBackground(Color.YELLOW);
        JComboBox coloredArrowsCombo = editableComboBox;
        Component[] comp = coloredArrowsCombo.getComponents();
        for (int i = 0; i < comp.length; i++) {
            if (comp[i] instanceof MetalComboBoxButton) {
                MetalComboBoxButton coloredArrowsButton = (MetalComboBoxButton) comp[i];
                coloredArrowsButton.setBackground(null);
                break;
            }
        }
//
        non_EditableComboBox.setPrototypeDisplayValue("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
        non_EditableComboBox.setFont(new Font("Serif", Font.BOLD, 16));
//
        frame = new JFrame();
        frame.setLayout(new GridLayout(0, 1, 10, 10));
        frame.add(someComboBox);
        frame.add(editableComboBox);
        frame.add(non_EditableComboBox);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocation(100, 100);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        UIManager.put("ComboBox.background", new ColorUIResource(Color.yellow));
        UIManager.put("JTextField.background", new ColorUIResource(Color.yellow));
        UIManager.put("ComboBox.selectionBackground", new ColorUIResource(Color.magenta));
        UIManager.put("ComboBox.selectionForeground", new ColorUIResource(Color.blue));
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                MyComboBox aCTF = new MyComboBox();
            }
        });
    }
}
于 2012-07-10T19:20:24.883 に答える