Index: src/main/java/common/javax/swing/plaf/basic/BasicComboBoxUI.java =================================================================== --- src/main/java/common/javax/swing/plaf/basic/BasicComboBoxUI.java (revision 478546) +++ src/main/java/common/javax/swing/plaf/basic/BasicComboBoxUI.java (working copy) @@ -64,6 +64,7 @@ import javax.swing.plaf.ComponentUI; import javax.swing.plaf.UIResource; +import org.apache.harmony.x.swing.ExtendedListElement; import org.apache.harmony.x.swing.StringConstants; import org.apache.harmony.x.swing.Utilities; @@ -190,7 +191,24 @@ oldModel.removeListDataListener(listDataListener); newModel.addListDataListener(listDataListener); } else if (StringConstants.COMPONENT_ORIENTATION.equals(event.getPropertyName())) { - listBox.setComponentOrientation((ComponentOrientation)event.getNewValue()); + listBox.setComponentOrientation((ComponentOrientation) event.getNewValue()); + } else if (StringConstants.EXTENDED_SUPPORT_ENABLED_PROPERTY + .equals(event.getPropertyName())) { + listBox.putClientProperty( + StringConstants.EXTENDED_SUPPORT_ENABLED_PROPERTY, + event.getNewValue()); + if (((Boolean) event.getNewValue()).booleanValue()) { + for (int i = 0; i < comboBox.getModel().getSize(); i++) { + Object element = comboBox.getModel().getElementAt(i); + if (!(element instanceof ExtendedListElement) + || ((ExtendedListElement) element) + .isChoosable()) { + + comboBox.setSelectedIndex(i); + break; + } + } + } } else if (StringConstants.IS_TABLE_EDITOR.equals(event.getPropertyName())) { isTableEditor = ((Boolean)event.getNewValue()).booleanValue(); } else if (StringConstants.EDITOR_PROPERTY_CHANGED.equals(event.getPropertyName())) { @@ -245,15 +263,19 @@ String beginPart = keySequence.toString().toUpperCase(); int selectedIndex = getIndex(model.getSelectedItem(), model); for (int i = selectedIndex + 1; i < model.getSize(); i++) { - String item = model.getElementAt(i).toString(); - if (item.toUpperCase().startsWith(beginPart)) { + Object item = model.getElementAt(i); + if (item.toString().toUpperCase().startsWith(beginPart) + && isChoosable(item)) { + return i; } } for (int i = 0; i <= selectedIndex; i++) { - String item = model.getElementAt(i).toString(); - if (item.toUpperCase().startsWith(beginPart)) { + Object item = model.getElementAt(i); + if (item.toString().toUpperCase().startsWith(beginPart) + && isChoosable(item)) { + return i; } } @@ -274,6 +296,13 @@ return -1; } + + private boolean isChoosable(final Object element) { + return !((BasicListUI) listBox.getUI()).extendedSupportEnabled + || !(element instanceof ExtendedListElement) + || ((ExtendedListElement) element).isChoosable(); + } + } @@ -304,7 +333,7 @@ private FocusListener editorFocusListener; private ActionListener editorActionListener; private Object selectedValue; - + private static final String PROTOTYPE_VALUE_FOR_EDITABLE_COMBOBOX = "wwwwwwwwww"; public static ComponentUI createUI(final JComponent comboBox) { Index: src/main/java/common/javax/swing/plaf/basic/BasicComboPopup.java =================================================================== --- src/main/java/common/javax/swing/plaf/basic/BasicComboPopup.java (revision 478546) +++ src/main/java/common/javax/swing/plaf/basic/BasicComboPopup.java (working copy) @@ -183,8 +183,11 @@ } public void mouseReleased(final MouseEvent e) { - comboBox.setPopupVisible(false); - comboBox.setSelectedIndex(list.getSelectedIndex()); + BasicListUI ui = (BasicListUI)list.getUI(); + if (!ui.extendedSupportEnabled || ui.isChoosable(list.getSelectedIndex())) { + comboBox.setPopupVisible(false); + comboBox.setSelectedIndex(list.getSelectedIndex()); + } } } Index: src/main/java/common/javax/swing/plaf/basic/BasicListKeyboardActions.java =================================================================== --- src/main/java/common/javax/swing/plaf/basic/BasicListKeyboardActions.java (revision 478546) +++ src/main/java/common/javax/swing/plaf/basic/BasicListKeyboardActions.java (working copy) @@ -75,11 +75,15 @@ return; } - list.setValueIsAdjusting(true); - list.clearSelection(); - list.addSelectionInterval(list.getAnchorSelectionIndex(), previousIndex); - list.setValueIsAdjusting(false); - list.ensureIndexIsVisible(previousIndex); + if (list.isSelectionEmpty()) { + list.setSelectedIndex(previousIndex); + } else { + list.setValueIsAdjusting(true); + list.clearSelection(); + list.addSelectionInterval(list.getAnchorSelectionIndex(), previousIndex); + list.setValueIsAdjusting(false); + list.ensureIndexIsVisible(previousIndex); + } } }; @@ -121,11 +125,15 @@ return; } - list.setValueIsAdjusting(true); - list.clearSelection(); - list.addSelectionInterval(list.getAnchorSelectionIndex(), nextIndex); - list.setValueIsAdjusting(false); - list.ensureIndexIsVisible(nextIndex); + if (list.isSelectionEmpty()) { + list.setSelectedIndex(nextIndex); + } else { + list.setValueIsAdjusting(true); + list.clearSelection(); + list.addSelectionInterval(list.getAnchorSelectionIndex(), nextIndex); + list.setValueIsAdjusting(false); + list.ensureIndexIsVisible(nextIndex); + } } }; @@ -231,8 +239,21 @@ return; } - list.setSelectedIndex(0); - list.ensureIndexIsVisible(0); + int candidateIndex = 0; + BasicListUI ui = (BasicListUI)list.getUI(); + if (ui.extendedSupportEnabled) { + while (candidateIndex < list.getModel().getSize()) { + if (ui.isChoosable(candidateIndex)) { + break; + } + candidateIndex++; + } + if (candidateIndex < list.getModel().getSize()) { + return; + } + } + list.setSelectedIndex(candidateIndex); + list.ensureIndexIsVisible(candidateIndex); } }; @@ -277,9 +298,22 @@ return; } - int lastIndex = list.getModel().getSize() - 1; - list.setSelectedIndex(lastIndex); - list.ensureIndexIsVisible(lastIndex); + int candidateIndex = list.getModel().getSize() - 1; + BasicListUI ui = (BasicListUI)list.getUI(); + if (ui.extendedSupportEnabled) { + while (candidateIndex >= 0) { + if (ui.isChoosable(candidateIndex)) { + break; + } + candidateIndex--; + } + if (candidateIndex == -1) { + return; + } + } + + list.setSelectedIndex(candidateIndex); + list.ensureIndexIsVisible(candidateIndex); } }; @@ -562,24 +596,37 @@ return -1; } + BasicListUI ui = (BasicListUI)list.getUI(); + + int currectSelection = list.getLeadSelectionIndex(); if (currectSelection == -1 || currectSelection >= list.getModel().getSize()) { - list.setSelectedIndex(0); - return -1; + currectSelection = 0; + if (!ui.extendedSupportEnabled || ui.isChoosable(currectSelection)) { + return currectSelection; + } } - BasicListUI ui = (BasicListUI)list.getUI(); ui.maybeUpdateLayoutState(); BasicListUI.LayoutStrategy strategy = ui.layouter.getLayoutStrategy(); - int selectedRow = strategy.getRow(currectSelection); - int selectedColumn = strategy.getColumn(currectSelection); - if (selectedRow < strategy.getRowCount() - 1 && strategy.getIndex(selectedRow + 1, selectedColumn) < list.getModel().getSize()) { - return strategy.getIndex(selectedRow + 1, selectedColumn); - } else if (list.getLayoutOrientation() == JList.VERTICAL_WRAP && selectedColumn < strategy.getColumnCount() - 1 && strategy.getIndex(0, selectedColumn + 1) < list.getModel().getSize()) { - return strategy.getIndex(0, selectedColumn + 1); + int candidateIndex = currectSelection; + while(candidateIndex < list.getModel().getSize()) { + int selectedRow = strategy.getRow(candidateIndex); + int selectedColumn = strategy.getColumn(candidateIndex); + if (selectedRow < strategy.getRowCount() - 1 && strategy.getIndex(selectedRow + 1, selectedColumn) < list.getModel().getSize()) { + candidateIndex = strategy.getIndex(selectedRow + 1, selectedColumn); + } else if (list.getLayoutOrientation() == JList.VERTICAL_WRAP && selectedColumn < strategy.getColumnCount() - 1 && strategy.getIndex(0, selectedColumn + 1) < list.getModel().getSize()) { + candidateIndex = strategy.getIndex(0, selectedColumn + 1); + } else { + return -1; + } + + if (ui.isChoosable(candidateIndex)) { + return candidateIndex; + } } - + return -1; } @@ -588,22 +635,34 @@ return -1; } + BasicListUI ui = (BasicListUI)list.getUI(); int currectSelection = list.getLeadSelectionIndex(); if (currectSelection == -1 || currectSelection >= list.getModel().getSize()) { - list.setSelectedIndex(list.getModel().getSize() - 1); - return -1; + currectSelection = list.getModel().getSize() - 1; + if (!ui.extendedSupportEnabled || ui.isChoosable(currectSelection)) { + return currectSelection; + } } - BasicListUI ui = (BasicListUI)list.getUI(); ui.maybeUpdateLayoutState(); BasicListUI.LayoutStrategy strategy = ui.layouter.getLayoutStrategy(); - int selectedRow = strategy.getRow(currectSelection); - int selectedColumn = strategy.getColumn(currectSelection); - if (selectedRow > 0) { - return strategy.getIndex(selectedRow - 1, selectedColumn); - } else if (list.getLayoutOrientation() == JList.VERTICAL_WRAP && selectedColumn > 0) { - return strategy.getIndex(strategy.getRowCount() - 1, selectedColumn - 1); + int candidateIndex = currectSelection; + while(candidateIndex >= 0) { + int selectedRow = strategy.getRow(candidateIndex); + int selectedColumn = strategy.getColumn(candidateIndex); + + if (selectedRow > 0) { + candidateIndex = strategy.getIndex(selectedRow - 1, selectedColumn); + } else if (list.getLayoutOrientation() == JList.VERTICAL_WRAP && selectedColumn > 0) { + candidateIndex = strategy.getIndex(strategy.getRowCount() - 1, selectedColumn - 1); + } else { + return -1; + } + + if (ui.isChoosable(candidateIndex)) { + return candidateIndex; + } } return -1; @@ -624,14 +683,25 @@ ui.maybeUpdateLayoutState(); BasicListUI.LayoutStrategy strategy = ui.layouter.getLayoutStrategy(); - int selectedRow = strategy.getRow(currectSelection); - int selectedColumn = strategy.getColumn(currectSelection); - if (selectedColumn < strategy.getColumnCount() - 1) { - if (strategy.getIndex(selectedRow, selectedColumn + 1) < list.getModel().getSize()) { - return strategy.getIndex(selectedRow, selectedColumn + 1); + int candidateIndex = currectSelection; + while(candidateIndex < list.getModel().getSize()) { + int selectedRow = strategy.getRow(candidateIndex); + int selectedColumn = strategy.getColumn(candidateIndex); + if (selectedColumn < strategy.getColumnCount() - 1) { + if (strategy.getIndex(selectedRow, selectedColumn + 1) < list.getModel().getSize()) { + candidateIndex = strategy.getIndex(selectedRow, selectedColumn + 1); + } else { + candidateIndex = list.getModel().getSize() - 1; + } + } else if (list.getLayoutOrientation() == JList.VERTICAL_WRAP && selectedRow < strategy.getRowCount() - 1 && strategy.getIndex(selectedRow + 1, selectedColumn) < list.getModel().getSize()) { + return strategy.getIndex(selectedRow + 1, selectedColumn); } else { - return list.getModel().getSize() - 1; + return -1; } + + if (ui.isChoosable(candidateIndex)) { + return candidateIndex; + } } return -1; @@ -652,10 +722,21 @@ ui.maybeUpdateLayoutState(); BasicListUI.LayoutStrategy strategy = ui.layouter.getLayoutStrategy(); - int selectedRow = strategy.getRow(currectSelection); - int selectedColumn = strategy.getColumn(currectSelection); - if (selectedColumn > 0) { - return strategy.getIndex(selectedRow, selectedColumn - 1); + int candidateIndex = currectSelection; + while(candidateIndex >= 0) { + int selectedRow = strategy.getRow(candidateIndex); + int selectedColumn = strategy.getColumn(candidateIndex); + if (selectedColumn > 0) { + candidateIndex = strategy.getIndex(selectedRow, selectedColumn - 1); + } else if (list.getLayoutOrientation() == JList.VERTICAL_WRAP && selectedRow > 0) { + candidateIndex = strategy.getIndex(selectedRow - 1, selectedColumn); + } else { + return -1; + } + + if (ui.isChoosable(candidateIndex)) { + return candidateIndex; + } } return -1; @@ -666,10 +747,11 @@ return -1; } + int candidateIndex; int currentSelection = list.getLeadSelectionIndex(); int lastVisible = list.getLastVisibleIndex(); if (lastVisible != currentSelection || lastVisible == list.getModel().getSize() - 1) { - return lastVisible; + candidateIndex = lastVisible; } else { Rectangle visibleRect = list.getVisibleRect(); int i = lastVisible + 1; @@ -677,8 +759,25 @@ i++; } - return i; + candidateIndex = i; } + + BasicListUI ui = (BasicListUI)list.getUI(); + if (!ui.extendedSupportEnabled) { + return candidateIndex; + } + for (int i = candidateIndex; i < list.getModel().getSize(); i++) { + if (ui.isChoosable(i)) { + return i; + } + } + for (int i = candidateIndex; i > currentSelection; i--) { + if (ui.isChoosable(i)) { + return i; + } + } + + return -1; } private static int getScrollUpIndex(final JList list) { @@ -686,11 +785,12 @@ return -1; } + int candidateIndex; int currentSelection = list.getLeadSelectionIndex(); int firstVisible = list.getFirstVisibleIndex(); if (firstVisible != currentSelection || firstVisible == 0) { - return firstVisible; + candidateIndex = firstVisible; } else { Rectangle visibleRect = list.getVisibleRect(); int i = firstVisible - 1; @@ -698,7 +798,24 @@ i--; } - return i; + candidateIndex = i; } + + BasicListUI ui = (BasicListUI)list.getUI(); + if (!ui.extendedSupportEnabled) { + return candidateIndex; + } + for (int i = candidateIndex; i >= 0; i--) { + if (ui.isChoosable(i)) { + return i; + } + } + for (int i = candidateIndex; i < currentSelection; i++) { + if (ui.isChoosable(i)) { + return i; + } + } + + return -1; } } Index: src/main/java/common/javax/swing/plaf/basic/BasicListUI.java =================================================================== --- src/main/java/common/javax/swing/plaf/basic/BasicListUI.java (revision 478546) +++ src/main/java/common/javax/swing/plaf/basic/BasicListUI.java (working copy) @@ -65,6 +65,8 @@ import javax.swing.plaf.UIResource; import javax.swing.text.Position; +import org.apache.harmony.x.swing.ExtendedListElement; +import org.apache.harmony.x.swing.ExtendedListFactory; import org.apache.harmony.x.swing.StringConstants; import org.apache.harmony.x.swing.Utilities; @@ -94,7 +96,9 @@ private ComponentListener componentListener; private KeyListener keyListener; + boolean extendedSupportEnabled; + final ListLayouter layouter = new ListLayouter(); public class FocusHandler implements FocusListener { @@ -270,6 +274,16 @@ } } + if (StringConstants.EXTENDED_SUPPORT_ENABLED_PROPERTY.equals(changedProperty)) { + extendedSupportEnabled = ((Boolean)event.getNewValue()).booleanValue(); + if (extendedSupportEnabled) { + list.setCellRenderer(ExtendedListFactory.getFactory().createExtendedRenderer()); + } else { + list.setCellRenderer((ListCellRenderer)UIManager.get("List.cellRenderer")); + } + updateLayoutStateNeeded = updateLayoutStateNeeded | otherChanged; + } + list.revalidate(); list.repaint(); } @@ -313,7 +327,7 @@ startIndex = 0; } - int nextIndex = list.getNextMatch(searchPrefix.toString(), startIndex, Position.Bias.Forward); + int nextIndex = getNextMatch(startIndex); if (nextIndex == -1) { if (searchPrefix.length() > 1) { resetSearch(); @@ -322,7 +336,7 @@ if (startIndex >= list.getModel().getSize()) { startIndex = 0; } - nextIndex = list.getNextMatch(searchPrefix.toString(), startIndex, Position.Bias.Forward); + nextIndex = getNextMatch(startIndex); } } if (nextIndex != -1) { @@ -335,6 +349,30 @@ } } + private int getNextMatch(final int startIndex) { + int candidateIndex = list.getNextMatch(searchPrefix.toString(), startIndex, Position.Bias.Forward); + if (candidateIndex == -1 || !extendedSupportEnabled) { + return candidateIndex; + } + + int firstFoundIndex = candidateIndex; + do { + Object value = list.getModel().getElementAt(candidateIndex); + if (!(value instanceof ExtendedListElement) + || ((ExtendedListElement)value).isChoosable()) { + + return candidateIndex; + } + int nextStartIndex = candidateIndex + 1; + if (nextStartIndex == list.getModel().getSize()) { + nextStartIndex = 0; + } + candidateIndex = list.getNextMatch(searchPrefix.toString(), nextStartIndex, Position.Bias.Forward); + } while(firstFoundIndex != candidateIndex); + + return -1; + } + private void resetSearch() { searchPrefix.delete(0, searchPrefix.length()); searchTimer.stop(); @@ -647,6 +685,16 @@ return new PropertyChangeHandler(); } + + boolean isChoosable(final int index) { + if (!extendedSupportEnabled) { + return true; + } + Object value = list.getModel().getElementAt(index); + return (value instanceof ExtendedListElement) ? ((ExtendedListElement)value).isChoosable() : true; + } + + private ComponentListener createComponentListener() { return new ComponentReshapeHandler(); } Index: src/main/java/common/org/apache/harmony/x/swing/AbstractExtendedListElement.java =================================================================== --- src/main/java/common/org/apache/harmony/x/swing/AbstractExtendedListElement.java (revision 0) +++ src/main/java/common/org/apache/harmony/x/swing/AbstractExtendedListElement.java (revision 0) @@ -0,0 +1,77 @@ +/* + * Copyright 2005 - 2006 The Apache Software Software Foundation or its licensors, as applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @author Anton Avtamonov + * @version $Revision: $ + */ +package org.apache.harmony.x.swing; + +import java.awt.Font; + +public abstract class AbstractExtendedListElement implements ExtendedListElement { + private final Object value; + private final Font font; + + private boolean enabled = true; + private boolean choosable = true; + private String toolTipText; + private int indentationLevel; + + public AbstractExtendedListElement(final Object value, final Font font) { + this.value = value; + this.font = font; + } + + public Font getFont() { + return font; + } + + public void setChoosable(final boolean choosable) { + this.choosable = choosable; + } + + public boolean isChoosable() { + return choosable && isEnabled(); + } + + public void setIndentationLevel(final int level) { + indentationLevel = level; + } + + public int getIndentationLevel() { + return indentationLevel; + } + + public void setEnabled(final boolean enabled) { + this.enabled = enabled; + } + + public boolean isEnabled() { + return enabled; + } + + public void setToolTipText(final String toolTip) { + toolTipText = toolTip; + } + + public String getToolTipText() { + return toolTipText; + } + + public String toString() { + return value != null ? value.toString() : ""; + } +} Index: src/main/java/common/org/apache/harmony/x/swing/ExtendedListCellRenderer.java =================================================================== --- src/main/java/common/org/apache/harmony/x/swing/ExtendedListCellRenderer.java (revision 0) +++ src/main/java/common/org/apache/harmony/x/swing/ExtendedListCellRenderer.java (revision 0) @@ -0,0 +1,75 @@ +/* + * Copyright 2005 - 2006 The Apache Software Software Foundation or its licensors, as applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @author Anton Avtamonov + * @version $Revision: $ + */ +package org.apache.harmony.x.swing; + +import java.awt.Component; +import java.awt.Font; + +import javax.swing.DefaultListCellRenderer; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JList; + +public class ExtendedListCellRenderer extends DefaultListCellRenderer { + private static final String SUB_ELEMENT_INDENT = " "; + + public Component getListCellRendererComponent(JList list, Object value, + int index, + boolean isSelected, + boolean cellHasFocus) { + + if (value instanceof ExtendedListElement) { + ExtendedListElement extendedElement = (ExtendedListElement)value; + JComponent result = (JComponent)super.getListCellRendererComponent(list, value, index, + isSelected && extendedElement.isChoosable(), + cellHasFocus && extendedElement.isChoosable()); + tuneRenderer(result, extendedElement); + return result; + } else { + return super.getListCellRendererComponent(list, value, index, + isSelected, cellHasFocus); + } + } + + protected void tuneRenderer(final JComponent renderingComponent, final ExtendedListElement element) { + Font font = element.getFont(); + if (font != null) { + renderingComponent.setFont(font); + } + if (element.getIndentationLevel() > 0) { + JLabel labelRenderer = (JLabel)renderingComponent; + labelRenderer.setText(createIndentation(element.getIndentationLevel()) + labelRenderer.getText()); + } + if (!element.isEnabled()) { + renderingComponent.setEnabled(false); + } + renderingComponent.setToolTipText(element.getToolTipText()); + } + + + private static String createIndentation(final int indentationLevel) { + StringBuffer result = new StringBuffer(); + for (int i = 0; i < indentationLevel; i++) { + result.append(SUB_ELEMENT_INDENT); + } + + return result.toString(); + } +} Index: src/main/java/common/org/apache/harmony/x/swing/ExtendedListElement.java =================================================================== --- src/main/java/common/org/apache/harmony/x/swing/ExtendedListElement.java (revision 0) +++ src/main/java/common/org/apache/harmony/x/swing/ExtendedListElement.java (revision 0) @@ -0,0 +1,30 @@ +/* + * Copyright 2005 - 2006 The Apache Software Software Foundation or its licensors, as applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @author Anton Avtamonov + * @version $Revision: $ + */ +package org.apache.harmony.x.swing; + +import java.awt.Font; + +public interface ExtendedListElement { + Font getFont(); + boolean isChoosable(); + int getIndentationLevel(); + boolean isEnabled(); + String getToolTipText(); +} Index: src/main/java/common/org/apache/harmony/x/swing/ExtendedListFactory.java =================================================================== --- src/main/java/common/org/apache/harmony/x/swing/ExtendedListFactory.java (revision 0) +++ src/main/java/common/org/apache/harmony/x/swing/ExtendedListFactory.java (revision 0) @@ -0,0 +1,123 @@ +/* + * Copyright 2005 - 2006 The Apache Software Software Foundation or its licensors, as applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Anton Avtamonov + * @version $Revision: $ + */ + +package org.apache.harmony.x.swing; + +import java.awt.Font; +import java.util.ArrayList; +import java.util.List; + +import javax.swing.JList; +import javax.swing.ListCellRenderer; +import javax.swing.UIManager; + +public class ExtendedListFactory { + private static ExtendedListFactory factory; + + public static ExtendedListFactory getFactory() { + if (factory == null) { + factory = new ExtendedListFactory(); + } + return factory; + } + + public static void setFactory(final ExtendedListFactory factory) { + ExtendedListFactory.factory = factory; + } + + + public AbstractExtendedListElement createGroupElement(final Object value) { + return createGroupElement(value, getGroupFont()); + } + + public AbstractExtendedListElement createGroupElement(final Object value, final Font font) { + return createGroupElement(value, font, 0); + } + + public AbstractExtendedListElement createGroupElement(final Object value, final int level) { + return createGroupElement(value, getGroupFont(), level); + } + + public AbstractExtendedListElement createGroupElement(final Object value, final Font font, final int level) { + return new AbstractExtendedListElement(value, font) { + public boolean isChoosable() { + return false; + } + + public int getIndentationLevel() { + return level; + } + }; + } + + public AbstractExtendedListElement createItemElement(final Object value) { + return createItemElement(value, getItemFont()); + } + + public AbstractExtendedListElement createItemElement(final Object value, final int level) { + return createItemElement(value, getItemFont(), level); + } + + public AbstractExtendedListElement createItemElement(final Object value, final Font font) { + return createItemElement(value, font, 0); + } + + public AbstractExtendedListElement createItemElement(final Object value, final Font font, final int level) { + return new AbstractExtendedListElement(value, font) { + public int getIndentationLevel() { + return level; + } + }; + } + + public ListCellRenderer createExtendedRenderer() { + return new ExtendedListCellRenderer(); + } + + public Object[] getSelectedValues(final JList list) { + Object[] allSelectedValues = list.getSelectedValues(); + List selectedValues = new ArrayList(allSelectedValues.length); + for (int i = 0; i < allSelectedValues.length; i++) { + Object selectedValue = allSelectedValues[i]; + if (!(selectedValue instanceof ExtendedListElement) + || ((ExtendedListElement)selectedValue).isChoosable()) { + + selectedValues.add(selectedValue); + } + } + + return selectedValues.toArray(new Object[selectedValues.size()]); + } + + + protected ExtendedListFactory() { + } + + + + private static Font getGroupFont() { + return UIManager.getFont("List.font").deriveFont(Font.BOLD | Font.ITALIC); + } + + private static Font getItemFont() { + return UIManager.getFont("List.font").deriveFont(Font.PLAIN); + } +} Index: src/main/java/common/org/apache/harmony/x/swing/StringConstants.java =================================================================== --- src/main/java/common/org/apache/harmony/x/swing/StringConstants.java (revision 478546) +++ src/main/java/common/org/apache/harmony/x/swing/StringConstants.java (working copy) @@ -105,5 +105,8 @@ String INDETERMINATE_PROPERTY = "indeterminate"; String VALUE_PROPERTY_NAME = "value"; + + String EXTENDED_SUPPORT_ENABLED_PROPERTY = "extendedSupportEnabled"; + String LIGHTWEIGHT_POPUP_ENABLED_PROPERTY_CHANGED = "lightWeightPopupEnabled"; }