1 /* 2 * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 27 package sun.lwawt; 28 29 import java.awt.Checkbox; 30 import java.awt.CheckboxGroup; 31 import java.awt.Component; 32 import java.awt.Dimension; 33 import java.awt.event.ItemEvent; 34 import java.awt.event.ItemListener; 35 import java.awt.peer.CheckboxPeer; 36 import java.beans.Transient; 37 38 import javax.swing.JCheckBox; 39 import javax.swing.JComponent; 40 import javax.swing.JRadioButton; 41 import javax.swing.JToggleButton; 42 import javax.swing.SwingUtilities; 43 44 final class LWCheckboxPeer 45 extends LWComponentPeer<Checkbox, LWCheckboxPeer.CheckboxDelegate> 46 implements CheckboxPeer, ItemListener { 47 48 LWCheckboxPeer(final Checkbox target, 49 final PlatformComponent platformComponent) { 50 super(target, platformComponent); 51 } 52 53 @Override 54 protected CheckboxDelegate createDelegate() { 55 return new CheckboxDelegate(); 56 } 57 58 @Override 59 protected Component getDelegateFocusOwner() { 60 return getDelegate().getCurrentButton(); 61 } 62 63 @Override 64 void initializeImpl() { 65 super.initializeImpl(); 66 setLabel(getTarget().getLabel()); 67 setState(getTarget().getState()); 68 setCheckboxGroup(getTarget().getCheckboxGroup()); 69 } 70 71 @Override 72 public void itemStateChanged(final ItemEvent e) { 73 // group.setSelectedCheckbox() will repaint the component 74 // to let LWCheckboxPeer correctly handle it we should call it 75 // after the current event is processed 76 SwingUtilities.invokeLater(new Runnable() { 77 @Override 78 public void run() { 79 boolean postEvent = true; 80 final CheckboxGroup group = getTarget().getCheckboxGroup(); 81 if (group != null) { 82 if (e.getStateChange() == ItemEvent.SELECTED) { 83 if (group.getSelectedCheckbox() != getTarget()) { 84 group.setSelectedCheckbox(getTarget()); 85 } else { 86 postEvent = false; 87 } 88 } else { 89 postEvent = false; 90 if (group.getSelectedCheckbox() == getTarget()) { 91 // Don't want to leave the group with no selected 92 // checkbox. 93 getTarget().setState(true); 94 } 95 } 96 } else { 97 getTarget().setState(e.getStateChange() 98 == ItemEvent.SELECTED); 99 } 100 if (postEvent) { 101 postEvent(new ItemEvent(getTarget(), 102 ItemEvent.ITEM_STATE_CHANGED, 103 getTarget().getLabel(), 104 e.getStateChange())); 105 } 106 } 107 }); 108 } 109 110 @Override 111 public void setCheckboxGroup(final CheckboxGroup g) { 112 synchronized (getDelegateLock()) { 113 getDelegate().getCurrentButton().removeItemListener(this); 114 getDelegate().setRadioButton(g != null); 115 getDelegate().getCurrentButton().addItemListener(this); 116 } 117 repaintPeer(); 118 } 119 120 @Override 121 public void setLabel(final String label) { 122 synchronized (getDelegateLock()) { 123 getDelegate().setText(label); 124 } 125 } 126 127 @Override 128 public void setState(final boolean state) { 129 synchronized (getDelegateLock()) { 130 getDelegate().setSelected(state); 131 } 132 repaintPeer(); 133 } 134 135 @Override 136 public boolean isFocusable() { 137 return true; 138 } 139 140 final class CheckboxDelegate extends JComponent { 141 142 private final JCheckBox cb; 143 private final JRadioButton rb; 144 145 CheckboxDelegate() { 146 super(); 147 cb = new JCheckBox() { 148 @Override 149 public boolean hasFocus() { 150 return getTarget().hasFocus(); 151 } 152 }; 153 rb = new JRadioButton() { 154 @Override 155 public boolean hasFocus() { 156 return getTarget().hasFocus(); 157 } 158 }; 159 setLayout(null); 160 setRadioButton(false); 161 add(rb); 162 add(cb); 163 } 164 165 @Override 166 public void setEnabled(final boolean enabled) { 167 super.setEnabled(enabled); 168 rb.setEnabled(enabled); 169 cb.setEnabled(enabled); 170 } 171 172 @Override 173 public void setOpaque(final boolean isOpaque) { 174 super.setOpaque(isOpaque); 175 rb.setOpaque(isOpaque); 176 cb.setOpaque(isOpaque); 177 } 178 179 @Override 180 @Deprecated 181 public void reshape(final int x, final int y, final int w, 182 final int h) { 183 super.reshape(x, y, w, h); 184 cb.setBounds(0, 0, w, h); 185 rb.setBounds(0, 0, w, h); 186 } 187 188 @Override 189 public Dimension getPreferredSize() { 190 return getCurrentButton().getPreferredSize(); 191 } 192 193 @Override 194 @Transient 195 public Dimension getMinimumSize() { 196 return getCurrentButton().getMinimumSize(); 197 } 198 199 void setRadioButton(final boolean showRadioButton) { 200 rb.setVisible(showRadioButton); 201 cb.setVisible(!showRadioButton); 202 } 203 204 @Transient 205 JToggleButton getCurrentButton() { 206 return cb.isVisible() ? cb : rb; 207 } 208 209 void setText(final String label) { 210 cb.setText(label); 211 rb.setText(label); 212 } 213 214 void setSelected(final boolean state) { 215 cb.setSelected(state); 216 rb.setSelected(state); 217 } 218 } 219 }