Java 如何防止选择分隔符列表。JList中的分隔符?

Java 如何防止选择分隔符列表。JList中的分隔符?,java,overriding,selection,jlist,glazedlists,Java,Overriding,Selection,Jlist,Glazedlists,我使用GrazedLists创建了一个JList,特别是一个事件列表,然后我将它传递到一个带有自定义比较器的分隔列表中,该比较器对我的事件列表元素进行排序。 我使用DefaultEventListModel作为JList模型,传入我的分隔符列表。 我正在使用一个定制的CellRenderer来装饰分隔列表。分隔单元格。所有这些都显示得很好,我看到一个格式很好的列表,按我喜欢的方式分组,类似于HTML SELECT元素中的OPTGROUP 现在我想阻止选择分隔单元格 我看到了如何覆盖Default

我使用GrazedLists创建了一个JList,特别是一个事件列表,然后我将它传递到一个带有自定义比较器的分隔列表中,该比较器对我的事件列表元素进行排序。 我使用DefaultEventListModel作为JList模型,传入我的分隔符列表。 我正在使用一个定制的CellRenderer来装饰分隔列表。分隔单元格。所有这些都显示得很好,我看到一个格式很好的列表,按我喜欢的方式分组,类似于HTML SELECT元素中的OPTGROUP

现在我想阻止选择分隔单元格

我看到了如何覆盖DefaultComboxModel的示例。但是,我不知道如何覆盖DefaultListSelectionModel或DefaultEventListModel

以下是我到目前为止的一些示例代码:

public class MyFrame extends javax.swing.JFrame {
    private final EventList<BibleVersion> bibleVersions;
    private final SeparatorList<BibleVersion> versionsByLang;

    public MyFrame(){
        bibleVersions = new BasicEventList<>();
        bibleVersions.add(new BibleVersion("CEI2008", "Testo della Conferenza Episcopale Italiana", "2008", "Italian"));
        bibleVersions.add(new BibleVersion("LUZZI", "Diodati Nuova Riveduta - Luzzi", "1927", "Italian"));
        bibleVersions.add(new BibleVersion("NVBSE", "Nova Vulgata - Bibliorum Sacrorum Editio", "1979", "Latin"));
        bibleVersions.add(new BibleVersion("NABRE", "New American Bible - Revised Edition", "2011", "English"));
        bibleVersions.add(new BibleVersion("KJV", "King James Version", "1611", "English"));
        versionsByLang = new SeparatorList<>(bibleVersions, new VersionComparator(),1, 1000);
        jList = new javax.swing.JList();
        jList.setModel(new DefaultEventListModel<>(versionsByLang));
        jList.setCellRenderer(new VersionCellRenderer());

    }

    public static class BibleVersion {
        private String abbrev;
        private String fullname;
        private String year;
        private String lang;

        public BibleVersion(String abbrev, String fullname, String year, String lang) {
            this.abbrev = abbrev;
            this.fullname = fullname;
            this.year = year;
            this.lang = lang;
        }        

        public String getAbbrev() {
            return abbrev;
        }

        public void setAbbrev(String abbrev) {
            this.abbrev = abbrev;
        }

        public String getFullname() {
            return fullname;
        }

        public void setFullname(String fullname) {
            this.fullname = fullname;
        }

        public String getYear() {
            return year;
        }

        public void setYear(String year) {
            this.year = year;
        }

        public String getLang() {
            return lang;
        }

        public void setLang(String lang) {
            this.lang = lang;
        }

        @Override
        public String toString() {
            return this.getAbbrev() + " — " + this.getFullname() + " (" + this.getYear() + ")"; //To change body of generated methods, choose Tools | Templates.
        }                

    }

    private static class VersionComparator implements Comparator<BibleVersion> {

        @Override
        public int compare(BibleVersion o1, BibleVersion o2) {
            return o1.getLang().compareTo(o2.getLang());
        }            

    }

    private static class VersionCellRenderer extends DefaultListCellRenderer{

        @Override
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
            JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);

            if (value instanceof SeparatorList.Separator) {
                SeparatorList.Separator separator = (SeparatorList.Separator) value;
                BibleVersion bibleversion = (BibleVersion)separator.getGroup().get(0);
                String lbl = "-- " + bibleversion.getLang() + " --";
                label.setText(lbl);
                label.setFont(label.getFont().deriveFont(Font.BOLD));
                label.setBackground(Color.LIGHT_GRAY);
                label.setBorder(BorderFactory.createEmptyBorder(0,5,0,0));
            } else {
                label.setFont(label.getFont().deriveFont(Font.PLAIN));
                label.setBorder(BorderFactory.createEmptyBorder(0,15,0,0));
            }

            return label;
        }
    }

}
公共类MyFrame扩展了javax.swing.JFrame{
私人最终事件列表bibleVersions;
私有最终分离主义版本;
公共MyFrame(){
bibleVersions=新的基本事件列表();
增加(新圣经版本(“CEI2008”,“Testo della Conferenza主教意大利”,“2008”,“意大利语”));
bibleVersions.添加(新BibleVersion(“LUZZI”、“Diodati Nuova Riveduta-LUZZI”、“1927”、“意大利语”);
新增(新版圣经(“NVBSE”、“Nova Vugata-骶骨编辑图书馆”、“1979年”、“拉丁语”);
增加(新圣经版本(“NABRE”,“新美国圣经-修订版”,“2011”,“英语”);
增加(新圣经版本(“KJV”,“詹姆斯国王版本”,“1611”,“英语”);
versionsByLang=新分隔符列表(bibleVersions,new VersionComparator(),1,1000);
jList=newjavax.swing.jList();
jList.setModel(新的DefaultEventListModel(versionsByLang));
setCellRenderer(新版本CellRenderer());
}
公共静态类BibleVersion{
私有字符串缩写;
私有字符串全名;
私人弦年;
私人串郎;
公共BibleVersion(字符串缩写、字符串全名、字符串年份、字符串语言){
this.abbrev=abbrev;
this.fullname=fullname;
今年=年;
this.lang=lang;
}        
公共字符串getAbbrev(){
返回abbrev;
}
公共void setAbbrev(字符串abbrev){
this.abbrev=abbrev;
}
公共字符串getFullname(){
返回全名;
}
public void setFullname(字符串fullname){
this.fullname=fullname;
}
公共字符串getYear(){
回归年;
}
公共无效设置年(字符串年){
今年=年;
}
公共字符串getLang(){
还郎;
}
公共void setLang(字符串lang){
this.lang=lang;
}
@凌驾
公共字符串toString(){
返回this.getAbbrev()。
}                
}
私有静态类VersionComparator实现Comparator{
@凌驾
公共整数比较(BibleVersionO1,BibleVersionO2){
返回o1.getLang().compareTo(o2.getLang());
}            
}
私有静态类VersionCellRenderer扩展了DefaultListCellRenderer{
@凌驾
公共组件getListCellRenderComponent(JList列表、对象值、int索引、布尔isSelected、布尔cellHasFocus){
JLabel=(JLabel)super.getListCellRenderComponent(列表、值、索引、isSelected、cellHasFocus);
if(SeparatorList.Separator的值实例){
SeparatorList.Separator Separator=(SeparatorList.Separator)值;
BibleVersion BibleVersion=(BibleVersion)分隔符.getGroup().get(0);
字符串lbl=“--”+bibleversion.getLang()+“--”;
label.setText(lbl);
label.setFont(label.getFont().deriveFont(Font.BOLD));
标签.立根(颜色:浅灰色);
label.setboorder(BorderFactory.createEmptyByOrder(0,5,0,0));
}否则{
label.setFont(label.getFont().deriveFont(Font.PLAIN));
label.setboorder(BorderFactory.createEmptyByOrder(0,15,0,0));
}
退货标签;
}
}
}

现在如何验证DefaultEventListModel(或ListSelectionModel)?我需要覆盖哪一个,或者可能是DefaultListSelectionModel?ListSelectionModel似乎有许多需要重写的方法,用于处理多个\u间隔选择(这是我的情况)。我不太确定从哪里开始…

通过一些尝试和错误,基于我在中找到的代码建议并在这些建议的基础上进一步完善,我能够将一些现在运行得相当好的东西组合起来。我不得不改变链接示例中的逻辑。基本上,我在所选索引之间来回走动,逐个检查它们是否是“已启用”索引,如果是,我只为该索引“addSelectionInterval”。我对setSelectionInterval方法和addSelectionInterval方法都这样做。因此,基本上你永远不会将一个选择添加为一个块,总是一次添加一个,通过循环选择块并逐个检查它们是否启用了选择

public class MyFrame extends javax.swing.JFrame {
    private final EventList<BibleVersion> bibleVersions;
    private final SeparatorList<BibleVersion> versionsByLang;
    private boolean[] enabledFlags;

    public MyFrame(){
        bibleVersions = new BasicEventList<>();
        bibleVersions.add(new BibleVersion("CEI2008", "Testo della Conferenza Episcopale Italiana", "2008", "Italian"));
        bibleVersions.add(new BibleVersion("LUZZI", "Diodati Nuova Riveduta - Luzzi", "1927", "Italian"));
        bibleVersions.add(new BibleVersion("NVBSE", "Nova Vulgata - Bibliorum Sacrorum Editio", "1979", "Latin"));
        bibleVersions.add(new BibleVersion("NABRE", "New American Bible - Revised Edition", "2011", "English"));
        bibleVersions.add(new BibleVersion("KJV", "King James Version", "1611", "English"));
        versionsByLang = new SeparatorList<>(bibleVersions, new VersionComparator(),1, 1000);
        int listLength = versionsByLang.size();
        enabledFlags = new boolean[listLength];

        ListIterator itr = versionsByLang.listIterator();
        while(itr.hasNext()){
            enabledFlags[itr.nextIndex()] = !(itr.next().getClass().getSimpleName().equals("GroupSeparator"));
        }
        jList = new javax.swing.JList();
        jList.setModel(new DefaultEventListModel<>(versionsByLang));
        jList.setCellRenderer(new VersionCellRenderer());
        jList.setSelectionModel(new DisabledItemSelectionModel());
        ListSelectionModel listSelectionModel = jList.getSelectionModel();
        listSelectionModel.addListSelectionListener(new SharedListSelectionHandler());

    }

    public static class BibleVersion {
        private String abbrev;
        private String fullname;
        private String year;
        private String lang;

        public BibleVersion(String abbrev, String fullname, String year, String lang) {
            this.abbrev = abbrev;
            this.fullname = fullname;
            this.year = year;
            this.lang = lang;
        }        

        public String getAbbrev() {
            return abbrev;
        }

        public void setAbbrev(String abbrev) {
            this.abbrev = abbrev;
        }

        public String getFullname() {
            return fullname;
        }

        public void setFullname(String fullname) {
            this.fullname = fullname;
        }

        public String getYear() {
            return year;
        }

        public void setYear(String year) {
            this.year = year;
        }

        public String getLang() {
            return lang;
        }

        public void setLang(String lang) {
            this.lang = lang;
        }

        @Override
        public String toString() {
            return this.getAbbrev() + " — " + this.getFullname() + " (" + this.getYear() + ")"; //To change body of generated methods, choose Tools | Templates.
        }                

    }

    private static class VersionComparator implements Comparator<BibleVersion> {

        @Override
        public int compare(BibleVersion o1, BibleVersion o2) {
            return o1.getLang().compareTo(o2.getLang());
        }            

    }

    private static class VersionCellRenderer extends DefaultListCellRenderer{

        @Override
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
            JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);

            if (value instanceof SeparatorList.Separator) {
                SeparatorList.Separator separator = (SeparatorList.Separator) value;
                BibleVersion bibleversion = (BibleVersion)separator.getGroup().get(0);
                String lbl = "-- " + bibleversion.getLang() + " --";
                label.setText(lbl);
                label.setFont(label.getFont().deriveFont(Font.BOLD));
                label.setBackground(Color.decode("#004400"));
                label.setBorder(BorderFactory.createEmptyBorder(0,5,0,0));
                label.setEnabled(false);
            } else {
                label.setFont(label.getFont().deriveFont(Font.PLAIN));
                label.setBorder(BorderFactory.createEmptyBorder(0,15,0,0));
            }

            return label;
        }
    }

private class DisabledItemSelectionModel extends DefaultListSelectionModel {

    private static final long serialVersionUID = 1L;

    @Override
    public void setSelectionInterval(int index0, int index1) {
        if(index0 < index1){
            for (int i = index0; i <= index1; i++){
                if(enabledFlags[i]){
                    super.addSelectionInterval(i, i);
                }
            }
        }
        else if(index1 < index0){
            for (int i = index1; i <= index0; i++){
                if(enabledFlags[i]){
                    super.addSelectionInterval(i, i);
                }
            }
        }
        else if(index0 == index1){
            if(enabledFlags[index0]){ super.setSelectionInterval(index0,index0); }
        }
    }

    @Override
    public void addSelectionInterval(int index0, int index1) {
        if(index0 < index1){
            for (int i = index0; i <= index1; i++){
                if(enabledFlags[i]){
                    super.addSelectionInterval(i, i);
                }
            }
        }
        else if(index1 < index0){
            for (int i = index1; i <= index0; i++){
                if(enabledFlags[i]){
                    super.addSelectionInterval(i, i);
                }
            }
        }
        else if(index0 == index1){
            if(enabledFlags[index0]){ super.addSelectionInterval(index0,index0); }
        }
    }        

}

private class SharedListSelectionHandler implements ListSelectionListener {
    @Override
    public void valueChanged(ListSelectionEvent e) {
        ListSelectionModel lsm = (ListSelectionModel)e.getSource();
        StringBuilder output = new StringBuilder();
        int firstIndex = e.getFirstIndex();
        int lastIndex = e.getLastIndex();
        boolean isAdjusting = e.getValueIsAdjusting();
        output.append("Event for indexes ");
        output.append(firstIndex);
        output.append(" - ");
        output.append(lastIndex);
        output.append("; isAdjusting is ");
        output.append(isAdjusting);
        output.append("; selected indexes:");

        if (lsm.isSelectionEmpty()) {
            output.append(" <none>");
        } else {
            // Find out which indexes are selected.
            int minIndex = lsm.getMinSelectionIndex();
            int maxIndex = lsm.getMaxSelectionIndex();
            for (int i = minIndex; i <= maxIndex; i++) {
                if (lsm.isSelectedIndex(i)) {
                    output.append(" ");
                    output.append(i);
                }
            }
        }
        output.append(System.getProperty("line.separator"));
        System.out.println(output.toString());
    }
}


}
公共类MyFrame扩展了javax.swing.JFrame{
私人最终事件列表bibleVersions;
私有最终分离主义版本;
私有布尔[]启用标签;
公共MyFrame(){
bibleVersions=新的基本事件列表();
增加(新圣经版本(“CEI2008”,“Testo della Conferenza主教意大利”,“2008”,“意大利语”));
bibleVersions.添加(新BibleVersion(“LUZZI”、“Diodati Nuova Riveduta-LUZZI”、“1927”、“意大利语”);
bibleVersions.添加(新BibleVer)