Java 如何在MacOS上使用分隔符固定JComboBox弹出窗口的垂直位置?
我使用“将JSepator与ComboBoxItem一起添加到JPanel上渲染”ListCellRenderer方法在JComboBox中显示分隔符 我注意到,MacOS上垂直居中弹出窗口中所选项目的算法被JSepator ComboxItems的高度变化搞糊涂了 有没有办法修复此屏幕截图右侧显示的弹出窗口的错误位置?如果选择了“西班牙”-项目,则该项目的油漆稍微过高;“汽车”-项目太高了 源代码:Java 如何在MacOS上使用分隔符固定JComboBox弹出窗口的垂直位置?,java,macos,swing,jcombobox,separator,Java,Macos,Swing,Jcombobox,Separator,我使用“将JSepator与ComboBoxItem一起添加到JPanel上渲染”ListCellRenderer方法在JComboBox中显示分隔符 我注意到,MacOS上垂直居中弹出窗口中所选项目的算法被JSepator ComboxItems的高度变化搞糊涂了 有没有办法修复此屏幕截图右侧显示的弹出窗口的错误位置?如果选择了“西班牙”-项目,则该项目的油漆稍微过高;“汽车”-项目太高了 源代码: import java.awt.BorderLayout; import java.awt.
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;
}
}
导入java.awt.BorderLayout;
导入java.awt.Component;
导入java.util.array;
导入javax.swing.JComboBox;
导入javax.swing.JFrame;
导入javax.swing.JList;
导入javax.swing.JPanel;
导入javax.swing.jsepator;
导入javax.swing.ListCellRenderer;
公共类JComboxSeparatorMacos{
公共静态void main(字符串[]args){
JFrame=新JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(新的JComboBox(“A,普通,组合框,不带分隔符”).split(“,”),BorderLayout.WEST);
JComboBox组合框=新的JComboBox(“西班牙、意大利、汽车、秘鲁”)。拆分(“,”);
ListCellRenderer=new SeparatorListCellRenderer(comboBox.getRenderer(),0);
setRenderer(渲染器);
frame.add(组合框);
frame.pack();
frame.setVisible(true);
}
}
类分隔符ListCellRenderer实现ListCellRenderer{
私人最终清单
- 我认为这个问题与本机操作系统的外观无关
JComboBox
,JPopup
可以/不能被限制、更改或覆盖某些Swing GUI构建器中的某些方法
- 对于
@camickr
- 也许
Renderer
中的jsepator
可能有点不同
a) 查看ActionListener
或itemstener
b) 请注意,对于添加到派生的JList
(可能不重要)中的正确KeyListener
,此功能不起作用
图像
代码
import java.util.*;
导入java.awt.*;
导入java.awt.event.*;
导入javax.swing.*;
导入javax.swing.border.*;
公共类ComboBoxWithSeparator扩展JFrame{
私有静态最终长serialVersionUID=1L;
最终字符串分隔符=“分隔符”;
公共ComboxWithSeparator(){
超级(“块组合框示例”);
字符串[][]str={{“A”、“B”、“C”}、{“1”、“2”、“3”}、{“abc”、“def”、“ghi”};
JComboBox组合=新的JComboBox(makeVectorData(str));
setRenderer(新的ComboBoxRenderer());
addActionListener(新的BlockComboListener(combo));
combo.setPrototypeDisplayValue(“XXXXXXXXXXXXXXXXXX”);
setLayout(新的FlowLayout());
JComboBox combo1=新的JComboBox(makeVectorData(str));
combo1.setRenderer(新的ComboBoxRenderer());
combo1.addActionListener(新的BlockComboListener(combo));
combo1.setPrototypeDisplayValue(“XXXXXXXXXXXXXX”);
BoundsPopupMenuListener侦听器=新的BoundsPopupMenuListener(true,true);
combo1.addPopupMenuListener(侦听器);
combo1.setPrototypeDisplayValue(“ItemWWW”);
添加(组合);
增加(1);
包装();
setVisible(真);
}
专用向量makeVectorData(字符串[][]str){
布尔值=false;
向量数据=新向量();
对于(int i=0;iimport java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
public class ComboBoxWithSeparator extends JFrame {
private static final long serialVersionUID = 1L;
final String SEPARATOR = "SEPARATOR";
public ComboBoxWithSeparator() {
super("Block ComboBox Example");
String[][] str = {{"A", "B", "C"}, {"1", "2", "3"}, {"abc", "def", "ghi"}};
JComboBox combo = new JComboBox(makeVectorData(str));
combo.setRenderer(new ComboBoxRenderer());
combo.addActionListener(new BlockComboListener(combo));
combo.setPrototypeDisplayValue("XXXXXXXXXXXXXXXXX");
setLayout(new FlowLayout());
JComboBox combo1 = new JComboBox(makeVectorData(str));
combo1.setRenderer(new ComboBoxRenderer());
combo1.addActionListener(new BlockComboListener(combo));
combo1.setPrototypeDisplayValue("XXXXXXXXXXXXXXXXX");
BoundsPopupMenuListener listener = new BoundsPopupMenuListener(true, true);
combo1.addPopupMenuListener(listener);
combo1.setPrototypeDisplayValue("ItemWWW");
add(combo);
add(combo1);
pack();
setVisible(true);
}
private Vector<String> makeVectorData(String[][] str) {
boolean needSeparator = false;
Vector<String> data = new Vector<String>();
for (int i = 0; i < str.length; i++) {
if (needSeparator) {
data.addElement(SEPARATOR);
}
for (int j = 0; j < str[i].length; j++) {
data.addElement(str[i][j]);
needSeparator = true;
}
}
return data;
}
public static void main(String args[]) {
try {
for (UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(laf.getName())) {
UIManager.setLookAndFeel(laf.getClassName());
//UIManager.getLookAndFeelDefaults().put("Panel.background", Color.white);
//UIManager.getLookAndFeelDefaults().put("Button.contentMargins", new InsetsUIResource(0,0,0,0));
}
}
} catch (Exception e) {
e.printStackTrace();
}
ComboBoxWithSeparator frame = new ComboBoxWithSeparator();
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
private class ComboBoxRenderer extends JLabel implements ListCellRenderer {
private static final long serialVersionUID = 1L;
private JSeparator separator;
public ComboBoxRenderer() {
setOpaque(true);
setBorder(new EmptyBorder(1, 1, 1, 1));
separator = new JSeparator(JSeparator.HORIZONTAL);
}
@Override
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {
String str = (value == null) ? "" : value.toString();
if (SEPARATOR.equals(str)) {
return separator;
}
if (isSelected) {
setBackground(list.getSelectionBackground());
setForeground(list.getSelectionForeground());
} else {
setBackground(list.getBackground());
setForeground(list.getForeground());
}
setFont(list.getFont());
setText(str);
return this;
}
}
private class BlockComboListener implements ActionListener {
private JComboBox combo;
private Object currentItem;
BlockComboListener(JComboBox combo) {
this.combo = combo;
combo.setSelectedIndex(0);
currentItem = combo.getSelectedItem();
}
@Override
public void actionPerformed(ActionEvent e) {
String tempItem = (String) combo.getSelectedItem();
if (SEPARATOR.equals(tempItem)) {
combo.setSelectedItem(currentItem);
} else {
currentItem = tempItem;
}
}
}
}
new JComboBox("<html><b>Spain</b></html>,Italy,Car,Peru"…