「JPanelでComboBoxItem-to-renderと一緒にJSeparatorを追加する」 -ListCellRendererアプローチを使用して、JComboBoxにセパレーターを表示しています。
ポップアップで選択したアイテムを垂直方向に中央揃えにする MacOS のアルゴリズムが、JSeparator-ComboBoxItems の高さの変更によって混乱することに気付きました。
このスクリーンショットの右側に表示されるポップアップの間違った位置を修正する方法はありますか? "Spain"-Item を選択すると、ペイントが少し高すぎます。「車」-項目が高すぎます。
ソースコード:
import java.awt.BorderLayout;
import java.awt.Component;
import java.util.Arrays;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.ListCellRenderer;
public class JComboBoxSeparatorMacOs {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JComboBox<String>("A,Normal,Combo Box,without Separators".split(",")), BorderLayout.WEST);
JComboBox<String> comboBox = new JComboBox<String>("Spain,Italy,Car,Peru".split(","));
ListCellRenderer<String> renderer = new SeparatorListCellRenderer<String>(comboBox.getRenderer(), 0);
comboBox.setRenderer(renderer);
frame.add(comboBox);
frame.pack();
frame.setVisible(true);
}
}
class SeparatorListCellRenderer<E> implements ListCellRenderer<E> {
private final ListCellRenderer<? super E> delegate;
private final int[] indexes;
private final JPanel panel = new JPanel(new BorderLayout());
public SeparatorListCellRenderer(ListCellRenderer<? super E> delegate, int... indexes) {
Arrays.sort(indexes);
this.delegate = delegate;
this.indexes = indexes;
panel.setOpaque(false); //for rendering of selected item on MSWindows
}
@Override
public Component getListCellRendererComponent(JList list, E value, int index, boolean isSelected, boolean cellHasFocus) {
panel.removeAll();
panel.add(delegate.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus));
if (Arrays.binarySearch(indexes, index) >= 0)
panel.add(new JSeparator(), BorderLayout.PAGE_END);
return panel;
}
}