Index: javax/swing/DefaultListSelectionModel.java =================================================================== RCS file: /cvsroot/classpath/classpath/javax/swing/DefaultListSelectionModel.java,v retrieving revision 1.16 diff -u -r1.16 DefaultListSelectionModel.java --- javax/swing/DefaultListSelectionModel.java 29 Jun 2005 19:28:44 -0000 1.16 +++ javax/swing/DefaultListSelectionModel.java 29 Jun 2005 19:35:40 -0000 @@ -141,13 +141,13 @@ * Used to make sure we only fireValueChanged when the BitSet * actually does change. */ - Object oldSel; + private Object oldSel; /** * Whether this call of setLeadSelectionInterval was called locally * from addSelectionInterval */ - boolean setLeadCalledFromAdd = false; + private boolean setLeadCalledFromAdd = false; /** * Gets the value of the address@hidden #selectionMode} property. @@ -393,10 +393,14 @@ /** * If the address@hidden #selectionMode} property is equal to - * SINGLE_SELECTION or - * SINGLE_INTERVAL_SELECTION, equivalent to calling - * setSelectionInterval(index1, index2); otherwise adds the - * range [index0, index1] to the selection interval set. + * SINGLE_SELECTION equivalent to calling + * setSelectionInterval(index1, index2); + * If the address@hidden #selectionMode} property is equal to + * SINGLE_INTERVAL_SELECTION and the interval being + * added is not adjacent to an already selected interval, + * equivalent to setSelectionInterval(index1, index2). + * Otherwise adds the range [index0, index1] + * to the selection interval set. * * @param index0 The beginning of the range of indices to select * @param index1 The end of the range of indices to select @@ -406,17 +410,24 @@ */ public void addSelectionInterval(int index0, int index1) { + int lo = Math.min(index0, index1); + int hi = Math.max(index0, index1); oldSel = sel.clone(); - if (selectionMode == SINGLE_SELECTION - || selectionMode == SINGLE_INTERVAL_SELECTION) + + if (selectionMode == SINGLE_SELECTION) sel.clear(); + + /* COMPAT: Like Sun (but not like IBM), we allow calls to + addSelectionInterval when selectionMode is + SINGLE_SELECTION_INTERVAL iff the interval being added + is adjacent to an already selected interval */ + if (selectionMode == SINGLE_INTERVAL_SELECTION) + if (!(isSelectedIndex(index0) || isSelectedIndex(index1) || isSelectedIndex(Math.max(lo-1,0)) || isSelectedIndex(Math.min(hi+1,sel.size())))) + sel.clear(); if (selectionMode == SINGLE_SELECTION) index0 = index1; - int lo = Math.min(index0, index1); - int hi = Math.max(index0, index1); - /* We have to update the anchorSelectionIndex and leadSelectionIndex variables */ @@ -461,6 +472,13 @@ oldSel = sel.clone(); int lo = Math.min(index0, index1); int hi = Math.max(index0, index1); + + /* if selectionMode is SINGLE_INTERVAL_SELECTION and removing the interval + (index0,index1) would leave two disjoint selection intervals, remove all + selected indices from lo to the last selected index */ + if (getMinSelectionIndex() > 0 && getMinSelectionIndex() < lo && selectionMode == SINGLE_INTERVAL_SELECTION) + hi = sel.size() - 1; + sel.clear(lo, hi+1); //update anchorSelectionIndex and leadSelectionIndex variables //TODO: will probably need MouseDragged to test properly and know if this works Index: javax/swing/plaf/basic/BasicListUI.java =================================================================== RCS file: /cvsroot/classpath/classpath/javax/swing/plaf/basic/BasicListUI.java,v retrieving revision 1.19 diff -u -r1.19 BasicListUI.java --- javax/swing/plaf/basic/BasicListUI.java 17 Jun 2005 10:12:29 -0000 1.19 +++ javax/swing/plaf/basic/BasicListUI.java 29 Jun 2005 19:35:40 -0000 @@ -200,14 +200,15 @@ if (evt.getKeyCode() == KeyEvent.VK_DOWN) { int lead = BasicListUI.this.list.getLeadSelectionIndex(); + int max = BasicListUI.this.list.getModel().getSize() - 1; if (!evt.isShiftDown()) { BasicListUI.this.list.clearSelection(); - BasicListUI.this.list.setSelectedIndex(lead+1); + BasicListUI.this.list.setSelectedIndex(Math.min(lead+1,max)); } else { - BasicListUI.this.list.getSelectionModel().setLeadSelectionIndex(lead+1); + BasicListUI.this.list.getSelectionModel().setLeadSelectionIndex(Math.min(lead+1,max)); } } else if (evt.getKeyCode() == KeyEvent.VK_UP) @@ -244,8 +245,7 @@ int index = BasicListUI.this.locationToIndex(list, click); if (index == -1) return; - boolean controlPressed = event.isControlDown(); - if (controlPressed) + if (event.isControlDown()) { if (BasicListUI.this.list.getSelectionMode() == ListSelectionModel.SINGLE_SELECTION) BasicListUI.this.list.setSelectedIndex(index); @@ -254,6 +254,22 @@ else BasicListUI.this.list.addSelectionInterval(index,index); } + else if (event.isShiftDown()) + { + if (BasicListUI.this.list.getSelectionMode() == ListSelectionModel.SINGLE_SELECTION) + BasicListUI.this.list.setSelectedIndex(index); + else if (BasicListUI.this.list.getSelectionMode() == ListSelectionModel.SINGLE_INTERVAL_SELECTION) + /*COMPAT: the IBM VM is compatible with the following line of code. However, compliance with + Sun's VM would correspond to replacing getAnchorSelectionIndex() with getLeadSelectionIndex(). + This is both unnatural and contradictory to the way they handle other similar UI interactions */ + BasicListUI.this.list.setSelectionInterval(BasicListUI.this.list.getAnchorSelectionIndex(), index); + else + /*COMPAT: both Sun and IBM are compatible instead with: + BasicListUI.this.list.setSelectionInterval(BasicListUI.this.list.getLeadSelectionIndex(),index); + Note that for IBM this is contradictory to what they did in the above situation for + SINGLE_INTERVAL_SELECTION. The most natural thing to do is the following: */ + BasicListUI.this.list.getSelectionModel().setLeadSelectionIndex(index); + } else BasicListUI.this.list.setSelectedIndex(index); }