Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/macosx/classes/sun/lwawt/LWListPeer.java
38827 views
/*1* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.lwawt;2627import javax.swing.*;28import javax.swing.event.*;29import java.awt.*;30import java.awt.event.*;31import java.awt.peer.ListPeer;32import java.util.Arrays;3334/**35* Lightweight implementation of {@link ListPeer}. Delegates most of the work to36* the {@link JList}, which is placed inside {@link JScrollPane}.37*/38final class LWListPeer extends LWComponentPeer<List, LWListPeer.ScrollableJList>39implements ListPeer {4041/**42* The default number of visible rows.43*/44private static final int DEFAULT_VISIBLE_ROWS = 4; // From java.awt.List,4546/**47* This text is used for cell bounds calculation.48*/49private static final String TEXT = "0123456789abcde";5051LWListPeer(final List target, final PlatformComponent platformComponent) {52super(target, platformComponent);53if (!getTarget().isBackgroundSet()) {54getTarget().setBackground(SystemColor.text);55}56}5758@Override59ScrollableJList createDelegate() {60return new ScrollableJList();61}6263@Override64void initializeImpl() {65super.initializeImpl();66setMultipleMode(getTarget().isMultipleMode());67final int[] selectedIndices = getTarget().getSelectedIndexes();68synchronized (getDelegateLock()) {69getDelegate().setSkipStateChangedEvent(true);70getDelegate().getView().setSelectedIndices(selectedIndices);71getDelegate().setSkipStateChangedEvent(false);72}73}7475@Override76public boolean isFocusable() {77return true;78}7980@Override81Component getDelegateFocusOwner() {82return getDelegate().getView();83}8485@Override86public int[] getSelectedIndexes() {87synchronized (getDelegateLock()) {88return getDelegate().getView().getSelectedIndices();89}90}9192@Override93public void add(final String item, final int index) {94synchronized (getDelegateLock()) {95getDelegate().getModel().add(index, item);96revalidate();97}98}99100@Override101public void delItems(final int start, final int end) {102synchronized (getDelegateLock()) {103getDelegate().getModel().removeRange(start, end);104revalidate();105}106}107108@Override109public void removeAll() {110synchronized (getDelegateLock()) {111getDelegate().getModel().removeAllElements();112revalidate();113}114}115116@Override117public void select(final int index) {118synchronized (getDelegateLock()) {119getDelegate().setSkipStateChangedEvent(true);120getDelegate().getView().setSelectedIndex(index);121getDelegate().setSkipStateChangedEvent(false);122}123}124125@Override126public void deselect(final int index) {127synchronized (getDelegateLock()) {128getDelegate().getView().getSelectionModel().129removeSelectionInterval(index, index);130}131}132133@Override134public void makeVisible(final int index) {135synchronized (getDelegateLock()) {136getDelegate().getView().ensureIndexIsVisible(index);137}138}139140@Override141public void setMultipleMode(final boolean m) {142synchronized (getDelegateLock()) {143getDelegate().getView().setSelectionMode(m ?144ListSelectionModel.MULTIPLE_INTERVAL_SELECTION145: ListSelectionModel.SINGLE_SELECTION);146}147}148149@Override150public Dimension getPreferredSize() {151return getMinimumSize();152}153154@Override155public Dimension getMinimumSize() {156return getMinimumSize(DEFAULT_VISIBLE_ROWS);157}158159@Override160public Dimension getPreferredSize(final int rows) {161return getMinimumSize(rows);162}163164@Override165public Dimension getMinimumSize(final int rows) {166synchronized (getDelegateLock()) {167final Dimension size = getCellSize();168size.height *= rows;169// Always take vertical scrollbar into account.170final JScrollBar vbar = getDelegate().getVerticalScrollBar();171size.width += vbar != null ? vbar.getMinimumSize().width : 0;172// JScrollPane and JList insets173final Insets pi = getDelegate().getInsets();174final Insets vi = getDelegate().getView().getInsets();175size.width += pi.left + pi.right + vi.left + vi.right;176size.height += pi.top + pi.bottom + vi.top + vi.bottom;177return size;178}179}180181private Dimension getCellSize() {182final JList<String> jList = getDelegate().getView();183final ListCellRenderer<? super String> cr = jList.getCellRenderer();184final Component cell = cr.getListCellRendererComponent(jList, TEXT, 0,185false, false);186return cell.getPreferredSize();187}188189private void revalidate() {190synchronized (getDelegateLock()) {191getDelegate().getView().invalidate();192getDelegate().validate();193}194}195196@SuppressWarnings("serial")// Safe: outer class is non-serializable.197final class ScrollableJList extends JScrollPane implements ListSelectionListener {198199private boolean skipStateChangedEvent;200201private final DefaultListModel<String> model =202new DefaultListModel<String>() {203@Override204public void add(final int index, final String element) {205if (index == -1) {206addElement(element);207} else {208super.add(index, element);209}210}211};212213private int[] oldSelectedIndices = new int[0];214215ScrollableJList() {216getViewport().setScrollMode(JViewport.SIMPLE_SCROLL_MODE);217final JList<String> list = new JListDelegate();218list.addListSelectionListener(this);219220getViewport().setView(list);221222// Pull the items from the target.223final String[] items = getTarget().getItems();224for (int i = 0; i < items.length; i++) {225model.add(i, items[i]);226}227}228229public boolean isSkipStateChangedEvent() {230return skipStateChangedEvent;231}232233public void setSkipStateChangedEvent(boolean skipStateChangedEvent) {234this.skipStateChangedEvent = skipStateChangedEvent;235}236237@Override238@SuppressWarnings("unchecked")239public void valueChanged(final ListSelectionEvent e) {240if (!e.getValueIsAdjusting() && !isSkipStateChangedEvent()) {241final JList<?> source = (JList<?>) e.getSource();242for(int i = 0 ; i < source.getModel().getSize(); i++) {243244final boolean wasSelected = Arrays.binarySearch(oldSelectedIndices, i) >= 0;245final boolean isSelected = source.isSelectedIndex(i);246247if (wasSelected == isSelected) {248continue;249}250251final int state = !wasSelected && isSelected ? ItemEvent.SELECTED: ItemEvent.DESELECTED;252253LWListPeer.this.postEvent(new ItemEvent(getTarget(), ItemEvent.ITEM_STATE_CHANGED,254i, state));255}256oldSelectedIndices = source.getSelectedIndices();257}258}259260@SuppressWarnings("unchecked")261public JList<String> getView() {262return (JList<String>) getViewport().getView();263}264265public DefaultListModel<String> getModel() {266return model;267}268269@Override270public void setEnabled(final boolean enabled) {271getView().setEnabled(enabled);272super.setEnabled(enabled);273}274275@Override276public void setOpaque(final boolean isOpaque) {277super.setOpaque(isOpaque);278if (getView() != null) {279getView().setOpaque(isOpaque);280}281}282283@Override284public void setFont(Font font) {285super.setFont(font);286if (getView() != null) {287getView().setFont(font);288LWListPeer.this.revalidate();289}290}291292private final class JListDelegate extends JList<String> {293294JListDelegate() {295super(model);296}297298@Override299public boolean hasFocus() {300return getTarget().hasFocus();301}302303@Override304protected void processMouseEvent(final MouseEvent e) {305super.processMouseEvent(e);306if (e.getID() == MouseEvent.MOUSE_CLICKED && e.getClickCount() == 2) {307final int index = locationToIndex(e.getPoint());308if (0 <= index && index < getModel().getSize()) {309LWListPeer.this.postEvent(new ActionEvent(getTarget(), ActionEvent.ACTION_PERFORMED,310getModel().getElementAt(index), e.getWhen(), e.getModifiers()));311}312}313}314315@Override316protected void processKeyEvent(final KeyEvent e) {317super.processKeyEvent(e);318if (e.getID() == KeyEvent.KEY_PRESSED && e.getKeyCode() == KeyEvent.VK_ENTER) {319final String selectedValue = getSelectedValue();320if(selectedValue != null){321LWListPeer.this.postEvent(new ActionEvent(getTarget(), ActionEvent.ACTION_PERFORMED,322selectedValue, e.getWhen(), e.getModifiers()));323}324}325}326327//Needed for Autoscroller.328@Override329public Point getLocationOnScreen() {330return LWListPeer.this.getLocationOnScreen();331}332}333}334}335336337