在中断多年后回到java,并在向内部库添加一些代码的过程中完成了一半。所讨论的类是jcombobox的扩展,它确保禁用的项变灰并且不可选择。有些代码是基于https://www.algosome.com/articles/enable-disable-jcombobox.html. 我们的想法是:(1)有一个数据模型,确保只能选择已启用的项;(2)有一个自定义呈现器,将已禁用的项显示为灰色:
代码正在运行,但是编译器对我的泛型不太满意。我真的希望有一个快乐的编译器,但我不知道如何在这种情况下实现这一点。下面是一个sscce,它生成上面的组合框。很抱歉这么长时间;这真是我能买到的最短的了。外部类包含几个内部类;图书馆里所有的班级都有 Lib
在他们的名字前面; MyComboBox
只是为了演示代码。
import java.awt.*;
import javax.swing.*;
import javax.swing.plaf.basic.BasicComboBoxRenderer;
public class SSCCE extends JPanel
{
//--------------------LIB CB ITEM--------------------------------------------------
private class LibCBItem extends JMenuItem
{
private LibCB myComboBox;
LibCBItem(String title, LibCB parent)
{
super(title);
myComboBox = parent;
}
public void setEnabled(boolean b)
{
boolean changeSelection = false;
if (!b && isEnabled() && this.equals(myComboBox.getSelectedItem())) {
int enabledCount = myComboBox.getEnabledItemCount();
if (enabledCount == 2)
changeSelection = true;
else if (enabledCount == 1)
System.out.println("setEnabled(FALSE) on final remaining enabled item");
else
System.out.println("setEnabled(FALSE) of selected item with " + enabledCount + " enabled items: must change selection before disabling");
}
super.setEnabled(b);
if (changeSelection)
myComboBox.selectEnabledItem();
}
public String toString()
{
return getText();
}
}
//--------------------LIB CB DATA MODEL--------------------------------------------------
private class LibCBDataModel<T extends LibCBItem> extends DefaultComboBoxModel<T>
{
public void setSelectedItem(Object o)
{
LibCBItem item = (LibCBItem) o;
if (item != null) {
if (item.isEnabled())
super.setSelectedItem(item);
}
else {
super.setSelectedItem(null);
}
}
}
//--------------------LIB CB RENDERER--------------------------------------------------
private class LibCBRenderer extends BasicComboBoxRenderer
{
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
{
JLabel c = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
LibCBItem item = (LibCBItem) value;
if (item.isEnabled()) {
c.setBackground(super.getBackground());
c.setForeground(super.getForeground());
if (isSelected) // is the mouse over it?
c.setText("√ " + c.getText());
else
c.setText(" " + c.getText());
}
else {
if (isSelected) // is the mouse over it?
c.setBackground(UIManager.getColor("ComboBox.background"));
else
c.setBackground(super.getBackground());
c.setForeground(Color.lightGray);
c.setText(" " + c.getText());
}
return c;
}
}
//--------------------LIB CB--------------------------------------------------
private class LibCB<T extends LibCBItem> extends JComboBox<T>
{
LibCB()
{
super();
setModel(new LibCBDataModel<>());
setRenderer(new LibCBRenderer());
//Warning:(127, 36) java: unchecked method invocation: method setRenderer in class javax.swing.JComboBox is applied to given types
// required:
// javax.swing.ListCellRenderer<? super E>
// found:
// SSCCE.LibCBRenderer
//Warning:(127, 37) java: unchecked conversion
// required:
// javax.swing.ListCellRenderer<? super E>
// found:
// SSCCE.LibCBRenderer
}
int getEnabledItemCount()
{
int returnVal = 0;
for (int i = 0; i < getItemCount(); i++) {
if (getItemAt(i).isEnabled())
returnVal++;
}
return returnVal;
}
void selectEnabledItem()
{
boolean selectedOne = false;
for (int i = 0; i < getItemCount(); i++) {
if (getItemAt(i).isEnabled()) {
setSelectedIndex(i);
selectedOne = true;
break;
}
}
if (!selectedOne)
System.out.println("selectEnabledItem() with 0 enabled items in combo box");
}
}
//--------------------MY COMBO BOX--------------------------------------------------
private class MyComboBox extends LibCB<LibCBItem>
{
MyComboBox()
{
LibCBItem item1 = new LibCBItem("1st", this);
addItem(item1);
LibCBItem item2 = new LibCBItem("2nd", this);
addItem(item2);
LibCBItem item3 = new LibCBItem("3rd", this);
addItem(item3);
item2.setEnabled(false);
}
}
//--------------------SSCCE--------------------------------------------------
SSCCE()
{
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setOpaque(true);
frame.setContentPane(this);
frame.add(new MyComboBox());
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args)
{
javax.swing.SwingUtilities.invokeLater(() -> new SSCCE());
}
}
编译器在同一行上给了我两个警告 LibCB()
它叫什么 JComboBox.setRenderer()
. 我已将警告的文本粘贴到内联。为了便于参考:
Warning:(127, 36) java: unchecked method invocation: method setRenderer in class javax.swing.JComboBox is applied to given types
required:
javax.swing.ListCellRenderer<? super E>
found:
SSCCE.LibCBRenderer
Warning:(127, 37) java: unchecked conversion
required:
javax.swing.ListCellRenderer<? super E>
found:
SSCCE.LibCBRenderer
有没有人能给我指出解决这些问题的方向,让编译器满意?Java8,以防万一。非常感谢!
1条答案
按热度按时间yqyhoc1h1#
主要问题是
BasicComboBoxRenderer
,因为该类没有ListCellRenderer
接口,但是JComboBox
类期望广义aRenderer
变量,请参见代码段:作为解决方法,我可以建议从
BasicComboBoxRenderer
您自己的自定义类,并为添加泛型类型ListCellRenderer
,该方法将解决编译过程中的警告问题。