This commit is contained in:
Lana Steuck 2012-10-08 15:37:37 -07:00
commit e86fa474a7
37 changed files with 1486 additions and 216 deletions

View File

@ -28,6 +28,11 @@ LIBRARY = osxapp
PRODUCT = sun
include $(BUILDDIR)/common/Defs.gmk
GEN_DIR=$(GENSRCDIR)/sun/osxapp
ICON_DATA = $(GEN_DIR)/AWTIconData.h
CLASSES_INIT += $(ICON_DATA)
#
# Files
#
@ -63,6 +68,7 @@ OTHER_LDLIBS += \
-framework QuartzCore
CPPFLAGS += \
-I$(GEN_DIR) \
$(call NativeSrcDirList,-I,/native/sun/osxapp)
@ -70,6 +76,34 @@ ifeq ($(MILESTONE), internal)
CPPFLAGS += -DINTERNAL_BUILD
endif
clean clobber::
TEMPDIR_CLASSES = $(TEMPDIR)/classes
.PHONY:
$(TEMPDIR_CLASSES)/sun/osxapp/ToBin.class: ToBin.java
@$(prep-target)
$(BOOT_JAVAC_CMD) -d $(TEMPDIR_CLASSES) $<
ifdef OPENJDK
ICONS_PATH_PREFIX=$(PLATFORM_SRC_MACOS)
else
ICONS_PATH_PREFIX=$(CLOSED_SRC)/macosx
endif
generated.clean:
$(RM) -r $(GEN_DIR)/*.h
ICONPATH=$(ICONS_PATH_PREFIX)/native/sun/osxapp/resource/icons
ICON = $(ICONPATH)/JavaApp.icns
$(GEN_DIR)/AWTIconData.h: $(TEMPDIR_CLASSES)/sun/osxapp/ToBin.class $(ICON)
$(prep-target)
$(RM) $(ICON_DATA)
$(ECHO) "static unsigned char sAWTIconData[] = { " >> $(ICON_DATA); \
$(CAT) $(ICON) | \
$(BOOT_JAVA_CMD) -cp $(TEMPDIR_CLASSES) -Djava.awt.headless=true \
sun.osxapp.ToBin >> $(ICON_DATA); \
$(ECHO) "};" >> $(ICON_DATA);
clean clobber:: generated.clean
.PHONY: generated.clean

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.osxapp;
import java.io.*;
public class ToBin {
public static void main(String[] args) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int nRead;
byte[] data = new byte[4096];
while ((nRead = System.in.read(data, 0, data.length)) != -1) {
baos.write(data, 0, nRead);
}
baos.flush();
byte[] buf = baos.toByteArray();
for (int i = 0; i < buf.length; i++) {
System.out.print(String.format("0x%1$02X", buf[i]) + ", ");
if (i % 20 == 0) {
System.out.println();
}
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -26,26 +26,27 @@
package sun.lwawt;
import java.awt.AWTException;
import java.awt.BufferCapabilities;
import java.awt.Canvas;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GraphicsConfiguration;
import java.awt.Image;
import java.awt.peer.CanvasPeer;
import javax.swing.JComponent;
final class LWCanvasPeer extends LWComponentPeer<Component, JComponent>
implements CanvasPeer {
class LWCanvasPeer<T extends Component, D extends JComponent>
extends LWComponentPeer<T, D> implements CanvasPeer {
LWCanvasPeer(final Canvas target, PlatformComponent platformComponent) {
LWCanvasPeer(final T target, final PlatformComponent platformComponent) {
super(target, platformComponent);
}
// ---- PEER METHODS ---- //
@Override
public void createBuffers(int numBuffers, BufferCapabilities caps) {
public void createBuffers(int numBuffers, BufferCapabilities caps)
throws AWTException {
// TODO
}
@ -67,10 +68,20 @@ final class LWCanvasPeer extends LWComponentPeer<Component, JComponent>
}
@Override
public GraphicsConfiguration getAppropriateGraphicsConfiguration(
public final GraphicsConfiguration getAppropriateGraphicsConfiguration(
GraphicsConfiguration gc)
{
// TODO
return gc;
}
@Override
public final Dimension getPreferredSize() {
return getMinimumSize();
}
@Override
public final Dimension getMinimumSize() {
return getBounds().getSize();
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -185,6 +185,11 @@ final class LWCheckboxPeer
rb.setBounds(0, 0, w, h);
}
@Override
public Dimension getPreferredSize() {
return getCurrentButton().getPreferredSize();
}
@Override
@Transient
public Dimension getMinimumSize() {

View File

@ -123,7 +123,7 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
// private volatile boolean paintPending;
private volatile boolean isLayouting;
private D delegate = null;
private final D delegate;
private Container delegateContainer;
private Component delegateDropTarget;
private final Object dropTargetLock = new Object();
@ -133,6 +133,11 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
private final PlatformComponent platformComponent;
/**
* Character with reasonable value between the minimum width and maximum.
*/
static final char WIDE_CHAR = '0';
private final class DelegateContainer extends Container {
{
enableEvents(0xFFFFFFFF);
@ -267,9 +272,7 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
}
protected final D getDelegate() {
synchronized (getStateLock()) {
return delegate;
}
return delegate;
}
protected Component getDelegateFocusOwner() {
@ -698,26 +701,23 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
}
@Override
public FontMetrics getFontMetrics(Font f) {
public FontMetrics getFontMetrics(final Font f) {
// Borrow the metrics from the top-level window
// return getWindowPeer().getFontMetrics(f);
// Obtain the metrics from the offscreen window where this peer is
// mostly drawn to.
// TODO: check for "use platform metrics" settings
Graphics g = getWindowPeer().getGraphics();
try {
if (g != null) {
final Graphics g = getOnscreenGraphics();
if (g != null) {
try {
return g.getFontMetrics(f);
} else {
synchronized (getDelegateLock()) {
return delegateContainer.getFontMetrics(f);
}
}
} finally {
if (g != null) {
} finally {
g.dispose();
}
}
synchronized (getDelegateLock()) {
return delegateContainer.getFontMetrics(f);
}
}
@Override
@ -847,31 +847,46 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
}
/**
* Should be overridden in subclasses to forward the request
* to the Swing helper component, if required.
* Determines the preferred size of the component. By default forwards the
* request to the Swing helper component. Should be overridden in subclasses
* if required.
*/
@Override
public Dimension getPreferredSize() {
// It looks like a default implementation for all toolkits
return getMinimumSize();
final Dimension size;
synchronized (getDelegateLock()) {
size = getDelegate().getPreferredSize();
}
return validateSize(size);
}
/*
* Should be overridden in subclasses to forward the request
* to the Swing helper component.
/**
* Determines the minimum size of the component. By default forwards the
* request to the Swing helper component. Should be overridden in subclasses
* if required.
*/
@Override
public Dimension getMinimumSize() {
D delegate = getDelegate();
if (delegate == null) {
// Is it a correct default value?
return getBounds().getSize();
} else {
synchronized (getDelegateLock()) {
return delegate.getMinimumSize();
}
final Dimension size;
synchronized (getDelegateLock()) {
size = getDelegate().getMinimumSize();
}
return validateSize(size);
}
/**
* In some situations delegates can return empty minimum/preferred size.
* (For example: empty JLabel, etc), but awt components never should be
* empty. In the XPeers or WPeers we use some magic constants, but here we
* try to use something more useful,
*/
private Dimension validateSize(final Dimension size) {
if (size.width == 0 || size.height == 0) {
final FontMetrics fm = getFontMetrics(getFont());
size.width = fm.charWidth(WIDE_CHAR);
size.height = fm.getHeight();
}
return size;
}
@Override

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -41,7 +41,7 @@ import java.util.List;
import javax.swing.JComponent;
abstract class LWContainerPeer<T extends Container, D extends JComponent>
extends LWComponentPeer<T, D>
extends LWCanvasPeer<T, D>
implements ContainerPeer
{
// List of child peers sorted by z-order from bottom-most

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -26,37 +26,26 @@
package sun.lwawt;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Label;
import java.awt.peer.LabelPeer;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import javax.tools.annotation.GenerateNativeHeader;
/**
* Lightweight implementation of {@link LabelPeer}. Delegates most of the work
* to the {@link JLabel}.
*/
/* No native methods here, but the constants are needed in the supporting JNI code */
@GenerateNativeHeader
final class LWLabelPeer extends LWComponentPeer<Label, JLabel>
implements LabelPeer {
private static final int TEXT_XPAD = 5;
private static final int TEXT_YPAD = 1;
LWLabelPeer(final Label target, final PlatformComponent platformComponent) {
super(target, platformComponent);
}
@Override
protected JLabel createDelegate() {
final JLabel label = new JLabel();
label.setVerticalAlignment(SwingConstants.TOP);
return label;
return new JLabel();
}
@Override
@ -80,24 +69,6 @@ final class LWLabelPeer extends LWComponentPeer<Label, JLabel>
}
}
@Override
public Dimension getMinimumSize() {
int w = TEXT_XPAD;
int h = TEXT_YPAD;
final FontMetrics fm = getFontMetrics(getFont());
if (fm != null) {
final String text;
synchronized (getDelegateLock()) {
text = getDelegate().getText();
}
if (text != null) {
w += fm.stringWidth(text);
}
h += fm.getHeight();
}
return new Dimension(w, h);
}
/**
* Converts {@code Label} alignment constant to the {@code JLabel} constant.
* If wrong Label alignment provided returns default alignment.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -32,10 +32,22 @@ import java.awt.event.*;
import java.awt.peer.ListPeer;
import java.util.Arrays;
final class LWListPeer
extends LWComponentPeer<List, LWListPeer.ScrollableJList>
/**
* Lightweight implementation of {@link ListPeer}.
*/
final class LWListPeer extends LWComponentPeer<List, LWListPeer.ScrollableJList>
implements ListPeer {
/**
* The default number of visible rows.
*/
private static final int DEFAULT_VISIBLE_ROWS = 4; // From java.awt.List,
/**
* This text is used for cell bounds calculation.
*/
private static final String TEXT = "0123456789abcde";
LWListPeer(final List target, final PlatformComponent platformComponent) {
super(target, platformComponent);
if (!getTarget().isBackgroundSet()) {
@ -134,6 +146,16 @@ final class LWListPeer
}
}
@Override
public Dimension getPreferredSize() {
return getMinimumSize();
}
@Override
public Dimension getMinimumSize() {
return getMinimumSize(DEFAULT_VISIBLE_ROWS);
}
@Override
public Dimension getPreferredSize(final int rows) {
return getMinimumSize(rows);
@ -142,18 +164,28 @@ final class LWListPeer
@Override
public Dimension getMinimumSize(final int rows) {
synchronized (getDelegateLock()) {
final int margin = 2;
final int space = 1;
// TODO: count ScrollPane's scrolling elements if any.
final FontMetrics fm = getFontMetrics(getFont());
final int itemHeight = (fm.getHeight() - fm.getLeading()) + (2 * space);
return new Dimension(20 + (fm == null ? 10 * 15 : fm.stringWidth("0123456789abcde")),
(fm == null ? 10 : itemHeight) * rows + (2 * margin));
final Dimension size = getCellSize();
size.height *= rows;
// Always take vertical scrollbar into account.
final JScrollBar vbar = getDelegate().getVerticalScrollBar();
size.width += vbar != null ? vbar.getMinimumSize().width : 0;
// JScrollPane and JList insets
final Insets pi = getDelegate().getInsets();
final Insets vi = getDelegate().getView().getInsets();
size.width += pi.left + pi.right + vi.left + vi.right;
size.height += pi.top + pi.bottom + vi.top + vi.bottom;
return size;
}
}
private Dimension getCellSize() {
final JList<String> jList = getDelegate().getView();
final ListCellRenderer<? super String> cr = jList.getCellRenderer();
final Component cell = cr.getListCellRendererComponent(jList, TEXT, 0,
false, false);
return cell.getPreferredSize();
}
private void revalidate() {
synchronized (getDelegateLock()) {
getDelegate().getView().invalidate();
@ -165,10 +197,10 @@ final class LWListPeer
private boolean skipStateChangedEvent;
private DefaultListModel<Object> model =
new DefaultListModel<Object>() {
private final DefaultListModel<String> model =
new DefaultListModel<String>() {
@Override
public void add(final int index, final Object element) {
public void add(final int index, final String element) {
if (index == -1) {
addElement(element);
} else {
@ -181,7 +213,7 @@ final class LWListPeer
ScrollableJList() {
getViewport().setScrollMode(JViewport.SIMPLE_SCROLL_MODE);
final JList<Object> list = new JListDelegate();
final JList<String> list = new JListDelegate();
list.addListSelectionListener(this);
getViewport().setView(list);
@ -223,11 +255,11 @@ final class LWListPeer
}
}
public JList getView() {
return (JList) getViewport().getView();
public JList<String> getView() {
return (JList<String>) getViewport().getView();
}
public DefaultListModel<Object> getModel() {
public DefaultListModel<String> getModel() {
return model;
}
@ -254,7 +286,7 @@ final class LWListPeer
}
}
private final class JListDelegate extends JList<Object> {
private final class JListDelegate extends JList<String> {
JListDelegate() {
super(ScrollableJList.this.model);
@ -272,7 +304,7 @@ final class LWListPeer
final int index = locationToIndex(e.getPoint());
if (0 <= index && index < getModel().getSize()) {
LWListPeer.this.postEvent(new ActionEvent(getTarget(), ActionEvent.ACTION_PERFORMED,
getModel().getElementAt(index).toString(), e.getWhen(), e.getModifiers()));
getModel().getElementAt(index), e.getWhen(), e.getModifiers()));
}
}
}
@ -281,10 +313,10 @@ final class LWListPeer
protected void processKeyEvent(final KeyEvent e) {
super.processKeyEvent(e);
if (e.getID() == KeyEvent.KEY_PRESSED && e.getKeyCode() == KeyEvent.VK_ENTER) {
final Object selectedValue = getSelectedValue();
final String selectedValue = getSelectedValue();
if(selectedValue != null){
LWListPeer.this.postEvent(new ActionEvent(getTarget(), ActionEvent.ACTION_PERFORMED,
selectedValue.toString(), e.getWhen(), e.getModifiers()));
selectedValue, e.getWhen(), e.getModifiers()));
}
}
}

View File

@ -26,7 +26,6 @@
package sun.lwawt;
import java.awt.Dimension;
import java.awt.Panel;
import java.awt.peer.PanelPeer;
@ -43,9 +42,4 @@ final class LWPanelPeer extends LWContainerPeer<Panel, JPanel>
public JPanel createDelegate() {
return new JPanel();
}
@Override
public Dimension getMinimumSize() {
return getBounds().getSize();
}
}

View File

@ -27,7 +27,6 @@
package sun.lwawt;
import java.awt.Adjustable;
import java.awt.Dimension;
import java.awt.Scrollbar;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
@ -93,13 +92,6 @@ final class LWScrollBarPeer extends LWComponentPeer<Scrollbar, JScrollBar>
}
}
@Override
public Dimension getPreferredSize() {
synchronized (getDelegateLock()) {
return getDelegate().getPreferredSize();
}
}
// Peer also registered as a listener for ComponentDelegate component
@Override
public void adjustmentValueChanged(final AdjustmentEvent e) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -29,6 +29,7 @@ package sun.lwawt;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.Point;
import java.awt.TextArea;
import java.awt.event.TextEvent;
@ -41,11 +42,22 @@ import javax.swing.ScrollPaneConstants;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent;
/**
* Lightweight implementation of {@link TextAreaPeer}. Delegates most of the
* work to the {@link JTextArea} inside JScrollPane.
*/
final class LWTextAreaPeer
extends LWTextComponentPeer<TextArea, LWTextAreaPeer.ScrollableJTextArea>
implements TextAreaPeer {
/**
* The default number of visible columns.
*/
private static final int DEFAULT_COLUMNS = 60;
/**
* The default number of visible rows.
*/
private static final int DEFAULT_ROWS = 10;
LWTextAreaPeer(final TextArea target,
@ -86,27 +98,42 @@ final class LWTextAreaPeer
return getTextComponent();
}
@Override
public Dimension getPreferredSize() {
return getMinimumSize();
}
@Override
public Dimension getMinimumSize() {
return getMinimumSize(DEFAULT_ROWS, DEFAULT_COLUMNS);
}
@Override
public Dimension getMinimumSize(final int rows, final int columns) {
return getPreferredSize(rows, columns);
public Dimension getPreferredSize(final int rows, final int columns) {
return getMinimumSize(rows, columns);
}
@Override
public Dimension getPreferredSize(final int rows, final int columns) {
final Dimension size = super.getPreferredSize(rows, columns);
public Dimension getMinimumSize(final int rows, final int columns) {
final Dimension size = super.getMinimumSize(rows, columns);
synchronized (getDelegateLock()) {
final JScrollBar vbar = getDelegate().getVerticalScrollBar();
final JScrollBar hbar = getDelegate().getHorizontalScrollBar();
final int scrollbarW = vbar != null ? vbar.getWidth() : 0;
final int scrollbarH = hbar != null ? hbar.getHeight() : 0;
return new Dimension(size.width + scrollbarW,
size.height + scrollbarH);
// JScrollPane insets
final Insets pi = getDelegate().getInsets();
size.width += pi.left + pi.right;
size.height += pi.top + pi.bottom;
// Take scrollbars into account.
final int vsbPolicy = getDelegate().getVerticalScrollBarPolicy();
if (vsbPolicy == ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS) {
final JScrollBar vbar = getDelegate().getVerticalScrollBar();
size.width += vbar != null ? vbar.getMinimumSize().width : 0;
}
final int hsbPolicy = getDelegate().getHorizontalScrollBarPolicy();
if (hsbPolicy == ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS) {
final JScrollBar hbar = getDelegate().getHorizontalScrollBar();
size.height += hbar != null ? hbar.getMinimumSize().height : 0;
}
}
return size;
}
@Override

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -48,10 +48,7 @@ abstract class LWTextComponentPeer<T extends TextComponent, D extends JComponent
extends LWComponentPeer<T, D>
implements DocumentListener, TextComponentPeer, InputMethodListener {
/**
* Character with reasonable value between the minimum width and maximum.
*/
protected static final char WIDE_CHAR = 'w';
private volatile boolean firstChangeSkipped;
LWTextComponentPeer(final T target,
@ -95,18 +92,16 @@ abstract class LWTextComponentPeer<T extends TextComponent, D extends JComponent
*/
abstract JTextComponent getTextComponent();
public Dimension getPreferredSize(final int rows, final int columns) {
public Dimension getMinimumSize(final int rows, final int columns) {
final Insets insets;
synchronized (getDelegateLock()) {
insets = getDelegate().getInsets();
insets = getTextComponent().getInsets();
}
final int borderHeight = insets.top + insets.bottom;
final int borderWidth = insets.left + insets.right;
final FontMetrics fm = getFontMetrics(getFont());
final int charWidth = (fm != null) ? fm.charWidth(WIDE_CHAR) : 10;
final int itemHeight = (fm != null) ? fm.getHeight() : 10;
return new Dimension(columns * charWidth + borderWidth,
rows * itemHeight + borderHeight);
return new Dimension(fm.charWidth(WIDE_CHAR) * columns + borderWidth,
fm.getHeight() * rows + borderHeight);
}
@Override
@ -187,6 +182,7 @@ abstract class LWTextComponentPeer<T extends TextComponent, D extends JComponent
}
}
//TODO IN XAWT we just return true..
@Override
public final boolean isFocusable() {
return getTarget().isFocusable();

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -37,16 +37,10 @@ import java.awt.peer.TextFieldPeer;
import javax.swing.JPasswordField;
import javax.swing.text.JTextComponent;
import javax.tools.annotation.GenerateNativeHeader;
/* No native methods here, but the constants are needed in the supporting JNI code */
@GenerateNativeHeader
final class LWTextFieldPeer
extends LWTextComponentPeer<TextField, JPasswordField>
implements TextFieldPeer, ActionListener {
private static final int DEFAULT_COLUMNS = 1;
LWTextFieldPeer(final TextField target,
final PlatformComponent platformComponent) {
super(target, platformComponent);
@ -83,17 +77,12 @@ final class LWTextFieldPeer
@Override
public Dimension getPreferredSize(final int columns) {
return getPreferredSize(1, columns);
return getMinimumSize(columns);
}
@Override
public Dimension getMinimumSize(final int columns) {
return getPreferredSize(columns);
}
@Override
public Dimension getMinimumSize() {
return getMinimumSize(DEFAULT_COLUMNS);
return getMinimumSize(1, columns);
}
@Override

View File

@ -310,7 +310,7 @@ public abstract class LWToolkit extends SunToolkit implements Runnable {
@Override
public CanvasPeer createCanvas(Canvas target) {
PlatformComponent platformComponent = createPlatformComponent();
LWCanvasPeer peer = new LWCanvasPeer(target, platformComponent);
LWCanvasPeer<?, ?> peer = new LWCanvasPeer<>(target, platformComponent);
targetCreatedPeer(target, peer);
peer.initialize();
return peer;

View File

@ -160,6 +160,9 @@ final class CPlatformResponder {
if(isDeadChar){
testChar = (char) out[2];
if(testChar == 0){
return;
}
}
jkeyCode = out[0];

View File

@ -383,6 +383,7 @@ static unichar NsGetDeadKeyChar(unsigned short keyCode)
{
TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource();
CFDataRef uchr = (CFDataRef)TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData);
if (uchr == nil) { return; }
const UCKeyboardLayout *keyboardLayout = (const UCKeyboardLayout*)CFDataGetBytePtr(uchr);
// Carbon modifiers should be used instead of NSEvent modifiers
UInt32 modifierKeyState = (GetCurrentEventKeyModifiers() >> 8) & 0xFF;
@ -563,18 +564,18 @@ NSUInteger JavaModifiersToNsKeyModifiers(jint javaModifiers, BOOL isExtMods)
const struct _nsKeyToJavaModifier* cur;
for (cur = nsKeyToJavaModifierTable; cur->nsMask != 0; ++cur) {
jint mask = isExtMods? cur->javaExtMask : cur->javaMask;
jint mask = isExtMods? cur->javaExtMask : cur->javaMask;
if ((mask & javaModifiers) != 0) {
nsFlags |= cur->nsMask;
}
}
// special case
jint mask = isExtMods? java_awt_event_InputEvent_ALT_GRAPH_DOWN_MASK :
jint mask = isExtMods? java_awt_event_InputEvent_ALT_GRAPH_DOWN_MASK :
java_awt_event_InputEvent_ALT_GRAPH_MASK;
if ((mask & javaModifiers) != 0) {
nsFlags |= NSAlternateKeyMask;
nsFlags |= NSAlternateKeyMask;
}
return nsFlags;

View File

@ -279,7 +279,10 @@ AWT_ASSERT_APPKIT_THREAD;
return;
}
if (![self hasMarkedText] && fKeyEventsNeeded) {
NSString *eventCharacters = [event characters];
BOOL isDeadKey = (eventCharacters != nil && [eventCharacters length] == 0);
if ((![self hasMarkedText] && fKeyEventsNeeded) || isDeadKey) {
[self deliverJavaKeyEventHelper: event];
}

View File

@ -47,7 +47,10 @@ JNIEXPORT void JNICALL Java_java_awt_CheckboxMenuItem_initIDs
{
}
JNIEXPORT void JNICALL Java_java_awt_Choice_initIDs
(JNIEnv *env, jclass cls)
{
}
JNIEXPORT void JNICALL Java_java_awt_Color_initIDs
(JNIEnv *env, jclass cls)

View File

@ -33,6 +33,7 @@
#import "ThreadUtilities.h"
#import "AWT_debug.h"
#import "CSystemColors.h"
#import "NSApplicationAWT.h"
#import "sun_lwawt_macosx_LWCToolkit.h"
@ -47,7 +48,7 @@ static long eventCount;
return eventCount;
}
+ (void) eventCountPlusPlus{
+ (void) eventCountPlusPlus{
eventCount++;
}
@ -79,7 +80,6 @@ static long eventCount;
@end
/*
* Class: sun_lwawt_macosx_LWCToolkit
* Method: nativeSyncQueue
@ -90,12 +90,22 @@ JNIEXPORT jboolean JNICALL Java_sun_lwawt_macosx_LWCToolkit_nativeSyncQueue
{
int currentEventNum = [AWTToolkit getEventCount];
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){}];
NSApplication* sharedApp = [NSApplication sharedApplication];
if ([sharedApp isKindOfClass:[NSApplicationAWT class]]) {
NSApplicationAWT* theApp = (NSApplicationAWT*)sharedApp;
[theApp postDummyEvent];
[theApp waitForDummyEvent];
} else {
// could happen if we are embedded inside SWT application,
// in this case just spin a single empty block through
// the event loop to give it a chance to process pending events
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){}];
}
if (([AWTToolkit getEventCount] - currentEventNum) != 0) {
return JNI_TRUE;
}
return JNI_FALSE;
}

View File

@ -29,11 +29,15 @@
@interface NSApplicationAWT : NSApplication {
NSString *fApplicationName;
NSWindow *eventTransparentWindow;
NSTimeInterval dummyEventTimestamp;
NSConditionLock* seenDummyEventLock;
}
- (void) finishLaunching;
- (void) registerWithProcessManager;
- (void) setDockIconWithEnv:(JNIEnv *)env;
- (void) postDummyEvent;
- (void) waitForDummyEvent;
+ (void) runAWTLoopWithApp:(NSApplication*)app;

View File

@ -31,6 +31,7 @@
#import "PropertiesUtilities.h"
#import "ThreadUtilities.h"
#import "QueuingApplicationDelegate.h"
#import "AWTIconData.h"
static BOOL sUsingDefaultNIB = YES;
@ -52,6 +53,9 @@ BOOL postEventDuringEventSynthesis = NO;
AWT_ASSERT_APPKIT_THREAD;
fApplicationName = nil;
dummyEventTimestamp = 0.0;
seenDummyEventLock = nil;
// NSApplication will call _RegisterApplication with the application's bundle, but there may not be one.
// So, we need to call it ourselves to ensure the app is set up properly.
@ -255,25 +259,26 @@ AWT_ASSERT_APPKIT_THREAD;
theIconPath = [PropertiesUtilities javaSystemPropertyForKey:@"apple.awt.application.icon" withEnv:env];
}
// If the icon file wasn't specified as an argument and we need to get an icon
// we'll use the generic java app icon.
NSString *defaultIconPath = [NSString stringWithFormat:@"%@%@", SHARED_FRAMEWORK_BUNDLE, @"/Resources/GenericApp.icns"];
if (theIconPath == nil) {
// Use the path specified to get the icon image
NSImage* iconImage = nil;
if (theIconPath != nil) {
iconImage = [[NSImage alloc] initWithContentsOfFile:theIconPath];
}
// If no icon file was specified or we failed to get the icon image
// and there is no bundle's icon, then use the default icon
if (iconImage == nil) {
NSString* bundleIcon = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleIconFile"];
if (bundleIcon == nil) {
theIconPath = defaultIconPath;
NSData* iconData;
iconData = [[NSData alloc] initWithBytesNoCopy: sAWTIconData length: sizeof(sAWTIconData) freeWhenDone: NO];
iconImage = [[NSImage alloc] initWithData: iconData];
[iconData release];
}
}
// Set up the dock icon if we have an icon name.
if (theIconPath != nil) {
NSImage *iconImage = [[NSImage alloc] initWithContentsOfFile:theIconPath];
// If we failed for some reason fall back to the default icon.
if (iconImage == nil) {
iconImage = [[NSImage alloc] initWithContentsOfFile:defaultIconPath];
}
// Set up the dock icon if we have an icon image.
if (iconImage != nil) {
[NSApp setApplicationIconImage:iconImage];
[iconImage release];
}
@ -328,6 +333,45 @@ AWT_ASSERT_APPKIT_THREAD;
return event;
}
// NSTimeInterval has microseconds precision
#define TS_EQUAL(ts1, ts2) (fabs((ts1) - (ts2)) < 1e-6)
- (void)sendEvent:(NSEvent *)event
{
if ([event type] == NSApplicationDefined && TS_EQUAL([event timestamp], dummyEventTimestamp)) {
[seenDummyEventLock lockWhenCondition:NO];
[seenDummyEventLock unlockWithCondition:YES];
} else {
[super sendEvent:event];
}
}
- (void)postDummyEvent {
seenDummyEventLock = [[NSConditionLock alloc] initWithCondition:NO];
dummyEventTimestamp = [NSProcessInfo processInfo].systemUptime;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSEvent* event = [NSEvent otherEventWithType: NSApplicationDefined
location: NSMakePoint(0,0)
modifierFlags: 0
timestamp: dummyEventTimestamp
windowNumber: 0
context: nil
subtype: 0
data1: 0
data2: 0];
[NSApp postEvent: event atStart: NO];
[pool drain];
}
- (void)waitForDummyEvent {
[seenDummyEventLock lockWhenCondition:YES];
[seenDummyEventLock unlock];
[seenDummyEventLock release];
seenDummyEventLock = nil;
}
@end

View File

@ -104,7 +104,16 @@ public class Choice extends Component implements ItemSelectable, Accessible {
/*
* JDK 1.1 serialVersionUID
*/
private static final long serialVersionUID = -4075310674757313071L;
private static final long serialVersionUID = -4075310674757313071L;
static {
/* ensure that the necessary native libraries are loaded */
Toolkit.loadLibraries();
/* initialize JNI field and method ids */
if (!GraphicsEnvironment.isHeadless()) {
initIDs();
}
}
/**
* Creates a new choice menu. The menu initially has no items in it.
@ -711,6 +720,10 @@ public class Choice extends Component implements ItemSelectable, Accessible {
}
}
/**
* Initialize JNI field and method IDs
*/
private static native void initIDs();
/////////////////
// Accessibility support

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -217,6 +217,25 @@ public class ToolTipManager extends MouseAdapter implements MouseMotionListener
return exitTimer.getInitialDelay();
}
// Returns GraphicsConfiguration instance that toFind belongs to or null
// if drawing point is set to a point beyond visible screen area (e.g.
// Point(20000, 20000))
private GraphicsConfiguration getDrawingGC(Point toFind) {
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice devices[] = env.getScreenDevices();
for (GraphicsDevice device : devices) {
GraphicsConfiguration configs[] = device.getConfigurations();
for (GraphicsConfiguration config : configs) {
Rectangle rect = config.getBounds();
if (rect.contains(toFind)) {
return config;
}
}
}
return null;
}
void showTipWindow() {
if(insideComponent == null || !insideComponent.isShowing())
return;
@ -231,9 +250,25 @@ public class ToolTipManager extends MouseAdapter implements MouseMotionListener
if (enabled) {
Dimension size;
Point screenLocation = insideComponent.getLocationOnScreen();
Point location = new Point();
GraphicsConfiguration gc;
gc = insideComponent.getGraphicsConfiguration();
Point location;
Point toFind;
if (preferredLocation != null) {
toFind = new Point(screenLocation.x + preferredLocation.x,
screenLocation.y + preferredLocation.y);
} else {
toFind = mouseEvent.getLocationOnScreen();
}
GraphicsConfiguration gc = getDrawingGC(toFind);
if (gc == null) {
toFind = mouseEvent.getLocationOnScreen();
gc = getDrawingGC(toFind);
if (gc == null) {
gc = insideComponent.getGraphicsConfiguration();
}
}
Rectangle sBounds = gc.getBounds();
Insets screenInsets = Toolkit.getDefaultToolkit()
.getScreenInsets(gc);
@ -253,14 +288,13 @@ public class ToolTipManager extends MouseAdapter implements MouseMotionListener
size = tip.getPreferredSize();
if(preferredLocation != null) {
location.x = screenLocation.x + preferredLocation.x;
location.y = screenLocation.y + preferredLocation.y;
location = toFind;
if (!leftToRight) {
location.x -= size.width;
}
} else {
location.x = screenLocation.x + mouseEvent.getX();
location.y = screenLocation.y + mouseEvent.getY() + 20;
location = new Point(screenLocation.x + mouseEvent.getX(),
screenLocation.y + mouseEvent.getY() + 20);
if (!leftToRight) {
if(location.x - size.width>=0) {
location.x -= size.width;

View File

@ -57,6 +57,8 @@ class DefaultSwatchChooserPanel extends AbstractColorChooserPanel {
RecentSwatchPanel recentSwatchPanel;
MouseListener mainSwatchListener;
MouseListener recentSwatchListener;
private KeyListener mainSwatchKeyListener;
private KeyListener recentSwatchKeyListener;
public DefaultSwatchChooserPanel() {
super();
@ -151,10 +153,14 @@ class DefaultSwatchChooserPanel extends AbstractColorChooserPanel {
recentSwatchPanel.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY,
recentStr);
mainSwatchKeyListener = new MainSwatchKeyListener();
mainSwatchListener = new MainSwatchListener();
swatchPanel.addMouseListener(mainSwatchListener);
swatchPanel.addKeyListener(mainSwatchKeyListener);
recentSwatchListener = new RecentSwatchListener();
recentSwatchKeyListener = new RecentSwatchKeyListener();
recentSwatchPanel.addMouseListener(recentSwatchListener);
recentSwatchPanel.addKeyListener(recentSwatchKeyListener);
JPanel mainHolder = new JPanel(new BorderLayout());
Border border = new CompoundBorder( new LineBorder(Color.black),
@ -196,11 +202,17 @@ class DefaultSwatchChooserPanel extends AbstractColorChooserPanel {
public void uninstallChooserPanel(JColorChooser enclosingChooser) {
super.uninstallChooserPanel(enclosingChooser);
swatchPanel.removeMouseListener(mainSwatchListener);
swatchPanel.removeKeyListener(mainSwatchKeyListener);
recentSwatchPanel.removeMouseListener(recentSwatchListener);
recentSwatchPanel.removeKeyListener(recentSwatchKeyListener);
swatchPanel = null;
recentSwatchPanel = null;
mainSwatchListener = null;
mainSwatchKeyListener = null;
recentSwatchListener = null;
recentSwatchKeyListener = null;
removeAll(); // strip out all the sub-components
}
@ -209,11 +221,32 @@ class DefaultSwatchChooserPanel extends AbstractColorChooserPanel {
}
private class RecentSwatchKeyListener extends KeyAdapter {
public void keyPressed(KeyEvent e) {
if (KeyEvent.VK_SPACE == e.getKeyCode()) {
Color color = recentSwatchPanel.getSelectedColor();
setSelectedColor(color);
}
}
}
private class MainSwatchKeyListener extends KeyAdapter {
public void keyPressed(KeyEvent e) {
if (KeyEvent.VK_SPACE == e.getKeyCode()) {
Color color = swatchPanel.getSelectedColor();
setSelectedColor(color);
recentSwatchPanel.setMostRecentColor(color);
}
}
}
class RecentSwatchListener extends MouseAdapter implements Serializable {
public void mousePressed(MouseEvent e) {
if (isEnabled()) {
Color color = recentSwatchPanel.getColorForLocation(e.getX(), e.getY());
recentSwatchPanel.setSelectedColorFromLocation(e.getX(), e.getY());
setSelectedColor(color);
recentSwatchPanel.requestFocusInWindow();
}
}
}
@ -223,7 +256,9 @@ class DefaultSwatchChooserPanel extends AbstractColorChooserPanel {
if (isEnabled()) {
Color color = swatchPanel.getColorForLocation(e.getX(), e.getY());
setSelectedColor(color);
swatchPanel.setSelectedColorFromLocation(e.getX(), e.getY());
recentSwatchPanel.setMostRecentColor(color);
swatchPanel.requestFocusInWindow();
}
}
}
@ -239,18 +274,81 @@ class SwatchPanel extends JPanel {
protected Dimension numSwatches;
protected Dimension gap;
private int selRow;
private int selCol;
public SwatchPanel() {
initValues();
initColors();
setToolTipText(""); // register for events
setOpaque(true);
setBackground(Color.white);
setRequestFocusEnabled(false);
setFocusable(true);
setInheritsPopupMenu(true);
addFocusListener(new FocusAdapter() {
public void focusGained(FocusEvent e) {
repaint();
}
public void focusLost(FocusEvent e) {
repaint();
}
});
addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
int typed = e.getKeyCode();
switch (typed) {
case KeyEvent.VK_UP:
if (selRow > 0) {
selRow--;
repaint();
}
break;
case KeyEvent.VK_DOWN:
if (selRow < numSwatches.height - 1) {
selRow++;
repaint();
}
break;
case KeyEvent.VK_LEFT:
if (selCol > 0 && SwatchPanel.this.getComponentOrientation().isLeftToRight()) {
selCol--;
repaint();
} else if (selCol < numSwatches.width - 1
&& !SwatchPanel.this.getComponentOrientation().isLeftToRight()) {
selCol++;
repaint();
}
break;
case KeyEvent.VK_RIGHT:
if (selCol < numSwatches.width - 1
&& SwatchPanel.this.getComponentOrientation().isLeftToRight()) {
selCol++;
repaint();
} else if (selCol > 0 && !SwatchPanel.this.getComponentOrientation().isLeftToRight()) {
selCol--;
repaint();
}
break;
case KeyEvent.VK_HOME:
selCol = 0;
selRow = 0;
repaint();
break;
case KeyEvent.VK_END:
selCol = numSwatches.width - 1;
selRow = numSwatches.height - 1;
repaint();
break;
}
}
});
}
public boolean isFocusTraversable() {
return false;
public Color getSelectedColor() {
return getColorForCell(selCol, selRow);
}
protected void initValues() {
@ -263,11 +361,10 @@ class SwatchPanel extends JPanel {
for (int row = 0; row < numSwatches.height; row++) {
int y = row * (swatchSize.height + gap.height);
for (int column = 0; column < numSwatches.width; column++) {
g.setColor( getColorForCell(column, row) );
Color c = getColorForCell(column, row);
g.setColor(c);
int x;
if ((!this.getComponentOrientation().isLeftToRight()) &&
(this instanceof RecentSwatchPanel)) {
if (!this.getComponentOrientation().isLeftToRight()) {
x = (numSwatches.width - column - 1) * (swatchSize.width + gap.width);
} else {
x = column * (swatchSize.width + gap.width);
@ -276,6 +373,20 @@ class SwatchPanel extends JPanel {
g.setColor(Color.black);
g.drawLine( x+swatchSize.width-1, y, x+swatchSize.width-1, y+swatchSize.height-1);
g.drawLine( x, y+swatchSize.height-1, x+swatchSize.width-1, y+swatchSize.height-1);
if (selRow == row && selCol == column && this.isFocusOwner()) {
Color c2 = new Color(c.getRed() < 125 ? 255 : 0,
c.getGreen() < 125 ? 255 : 0,
c.getBlue() < 125 ? 255 : 0);
g.setColor(c2);
g.drawLine(x, y, x + swatchSize.width - 1, y);
g.drawLine(x, y, x, y + swatchSize.height - 1);
g.drawLine(x + swatchSize.width - 1, y, x + swatchSize.width - 1, y + swatchSize.height - 1);
g.drawLine(x, y + swatchSize.height - 1, x + swatchSize.width - 1, y + swatchSize.height - 1);
g.drawLine(x, y, x + swatchSize.width - 1, y + swatchSize.height - 1);
g.drawLine(x, y + swatchSize.height - 1, x + swatchSize.width - 1, y);
}
}
}
}
@ -296,10 +407,19 @@ class SwatchPanel extends JPanel {
return color.getRed()+", "+ color.getGreen() + ", " + color.getBlue();
}
public void setSelectedColorFromLocation(int x, int y) {
if (!this.getComponentOrientation().isLeftToRight()) {
selCol = numSwatches.width - x / (swatchSize.width + gap.width) - 1;
} else {
selCol = x / (swatchSize.width + gap.width);
}
selRow = y / (swatchSize.height + gap.height);
repaint();
}
public Color getColorForLocation( int x, int y ) {
int column;
if ((!this.getComponentOrientation().isLeftToRight()) &&
(this instanceof RecentSwatchPanel)) {
if (!this.getComponentOrientation().isLeftToRight()) {
column = numSwatches.width - x / (swatchSize.width + gap.width) - 1;
} else {
column = x / (swatchSize.width + gap.width);

View File

@ -88,6 +88,12 @@ Java_java_awt_CheckboxMenuItem_initIDs
{
}
JNIEXPORT void JNICALL
Java_java_awt_Choice_initIDs
(JNIEnv *env, jclass clazz)
{
}
JNIEXPORT void JNICALL
Java_java_awt_Dimension_initIDs
(JNIEnv *env, jclass clazz)

View File

@ -79,6 +79,10 @@ BOOL AwtChoice::sm_isMouseMoveInList = FALSE;
static const UINT MINIMUM_NUMBER_OF_VISIBLE_ITEMS = 8;
namespace {
jfieldID selectedIndexID;
}
/*************************************************************************
* AwtChoice class methods
*/
@ -86,7 +90,6 @@ static const UINT MINIMUM_NUMBER_OF_VISIBLE_ITEMS = 8;
AwtChoice::AwtChoice() {
m_hList = NULL;
m_listDefWindowProc = NULL;
m_selectedItem = -1;
}
LPCTSTR AwtChoice::GetClassName() {
@ -102,7 +105,6 @@ void AwtChoice::Dispose() {
AwtChoice* AwtChoice::Create(jobject peer, jobject parent) {
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
jobject target = NULL;
@ -438,10 +440,14 @@ LRESULT CALLBACK AwtChoice::ListWindowProc(HWND hwnd, UINT message,
MsgRouting AwtChoice::WmNotify(UINT notifyCode)
{
if (notifyCode == CBN_SELCHANGE) {
int selectedItem = (int)SendMessage(CB_GETCURSEL);
if (selectedItem != CB_ERR && m_selectedItem != selectedItem){
m_selectedItem = selectedItem;
DoCallback("handleAction", "(I)V", selectedItem);
int selectedIndex = (int)SendMessage(CB_GETCURSEL);
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
jobject target = GetTarget(env);
int previousIndex = env->GetIntField(target, selectedIndexID);
if (selectedIndex != CB_ERR && selectedIndex != previousIndex){
DoCallback("handleAction", "(I)V", selectedIndex);
}
} else if (notifyCode == CBN_DROPDOWN) {
@ -695,6 +701,15 @@ done:
extern "C" {
JNIEXPORT void JNICALL
Java_java_awt_Choice_initIDs(JNIEnv *env, jclass cls)
{
TRY;
selectedIndexID = env->GetFieldID(cls, "selectedIndex", "I");
DASSERT(selectedIndexID);
CATCH_BAD_ALLOC;
}
/*
* Class: sun_awt_windows_WChoicePeer
* Method: select

View File

@ -94,7 +94,6 @@ private:
static BOOL sm_isMouseMoveInList;
HWND m_hList;
WNDPROC m_listDefWindowProc;
int m_selectedItem;
static LRESULT CALLBACK ListWindowProc(HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam);
};

View File

@ -3144,7 +3144,8 @@ void AwtComponent::JavaKeyToWindowsKey(UINT javaKey,
return;
}
UINT AwtComponent::WindowsKeyToJavaKey(UINT windowsKey, UINT modifiers)
UINT AwtComponent::WindowsKeyToJavaKey(UINT windowsKey, UINT modifiers, UINT character, BOOL isDeadKey)
{
// Handle the few cases where we need to take the modifier into
// consideration for the Java VK code or where we have to take the keyboard
@ -3171,6 +3172,15 @@ UINT AwtComponent::WindowsKeyToJavaKey(UINT windowsKey, UINT modifiers)
break;
};
// check dead key
if (isDeadKey) {
for (int i = 0; charToDeadVKTable[i].c != 0; i++) {
if (charToDeadVKTable[i].c == character) {
return charToDeadVKTable[i].javaKey;
}
}
}
// for the general case, use a bi-directional table
for (int i = 0; keyMapTable[i].windowsKey != 0; i++) {
if (keyMapTable[i].windowsKey == windowsKey) {
@ -3384,14 +3394,18 @@ AwtComponent::UpdateDynPrimaryKeymap(UINT wkey, UINT jkeyLegacy, jint keyLocatio
}
}
UINT AwtComponent::WindowsKeyToJavaChar(UINT wkey, UINT modifiers, TransOps ops)
UINT AwtComponent::WindowsKeyToJavaChar(UINT wkey, UINT modifiers, TransOps ops, BOOL &isDeadKey)
{
static Hashtable transTable("VKEY translations");
static Hashtable deadKeyFlagTable("Dead Key Flags");
isDeadKey = FALSE;
// Try to translate using last saved translation
if (ops == LOAD) {
void* deadKeyFlag = deadKeyFlagTable.remove(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)));
void* value = transTable.remove(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)));
if (value != NULL) {
isDeadKey = static_cast<BOOL>(reinterpret_cast<INT_PTR>(deadKeyFlag));
return static_cast<UINT>(reinterpret_cast<INT_PTR>(value));
}
}
@ -3484,12 +3498,13 @@ UINT AwtComponent::WindowsKeyToJavaChar(UINT wkey, UINT modifiers, TransOps ops)
// instead of creating our own conversion tables, I'll let Win32
// convert the character for me.
WORD mbChar;
WORD wChar[2];
UINT scancode = ::MapVirtualKey(wkey, 0);
int converted = ::ToAsciiEx(wkey, scancode, keyboardState,
&mbChar, 0, GetKeyboardLayout());
int converted = ::ToUnicodeEx(wkey, scancode, keyboardState,
wChar, 2, 0, GetKeyboardLayout());
UINT translation;
BOOL deadKeyFlag = (converted == 2);
// Dead Key
if (converted < 0) {
@ -3508,16 +3523,16 @@ UINT AwtComponent::WindowsKeyToJavaChar(UINT wkey, UINT modifiers, TransOps ops)
} else
// the caller expects a Unicode character.
if (converted > 0) {
WCHAR unicodeChar[2];
VERIFY(::MultiByteToWideChar(GetCodePage(), MB_PRECOMPOSED,
(LPCSTR)&mbChar, 1, unicodeChar, 1));
translation = unicodeChar[0];
translation = wChar[0];
}
if (ops == SAVE) {
transTable.put(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)),
reinterpret_cast<void*>(static_cast<INT_PTR>(translation)));
deadKeyFlagTable.put(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)),
reinterpret_cast<void*>(static_cast<INT_PTR>(deadKeyFlag)));
}
isDeadKey = deadKeyFlag;
return translation;
}
@ -3537,8 +3552,9 @@ MsgRouting AwtComponent::WmKeyDown(UINT wkey, UINT repCnt,
UINT modifiers = GetJavaModifiers();
jint keyLocation = GetKeyLocation(wkey, flags);
UINT jkey = WindowsKeyToJavaKey(wkey, modifiers);
UINT character = WindowsKeyToJavaChar(wkey, modifiers, SAVE);
BOOL isDeadKey = FALSE;
UINT character = WindowsKeyToJavaChar(wkey, modifiers, SAVE, isDeadKey);
UINT jkey = WindowsKeyToJavaKey(wkey, modifiers, character, isDeadKey);
UpdateDynPrimaryKeymap(wkey, jkey, keyLocation, modifiers);
@ -3579,8 +3595,9 @@ MsgRouting AwtComponent::WmKeyUp(UINT wkey, UINT repCnt,
UINT modifiers = GetJavaModifiers();
jint keyLocation = GetKeyLocation(wkey, flags);
UINT jkey = WindowsKeyToJavaKey(wkey, modifiers);
UINT character = WindowsKeyToJavaChar(wkey, modifiers, LOAD);
BOOL isDeadKey = FALSE;
UINT character = WindowsKeyToJavaChar(wkey, modifiers, LOAD, isDeadKey);
UINT jkey = WindowsKeyToJavaKey(wkey, modifiers, character, isDeadKey);
UpdateDynPrimaryKeymap(wkey, jkey, keyLocation, modifiers);
SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_RELEASED,
@ -5628,7 +5645,8 @@ void AwtComponent::_NativeHandleEvent(void *param)
}
}
modifiedChar = p->WindowsKeyToJavaChar(winKey, modifiers, AwtComponent::NONE);
BOOL isDeadKey = FALSE;
modifiedChar = p->WindowsKeyToJavaChar(winKey, modifiers, AwtComponent::NONE, isDeadKey);
bCharChanged = (keyChar != modifiedChar);
}
break;
@ -7166,4 +7184,4 @@ void ReleaseDCList(HWND hwnd, DCList &list) {
removedDCs = removedDCs->next;
delete tmpDCList;
}
}
}

View File

@ -441,7 +441,7 @@ public:
static jint GetJavaModifiers();
static jint GetButton(int mouseButton);
static UINT GetButtonMK(int mouseButton);
static UINT WindowsKeyToJavaKey(UINT windowsKey, UINT modifiers);
static UINT WindowsKeyToJavaKey(UINT windowsKey, UINT modifiers, UINT character, BOOL isDeadKey);
static void JavaKeyToWindowsKey(UINT javaKey, UINT *windowsKey, UINT *modifiers, UINT originalWindowsKey);
static void UpdateDynPrimaryKeymap(UINT wkey, UINT jkeyLegacy, jint keyLocation, UINT modifiers);
@ -453,7 +453,7 @@ public:
enum TransOps {NONE, LOAD, SAVE};
UINT WindowsKeyToJavaChar(UINT wkey, UINT modifiers, TransOps ops);
UINT WindowsKeyToJavaChar(UINT wkey, UINT modifiers, TransOps ops, BOOL &isDeadKey);
/* routines used for input method support */
void SetInputMethod(jobject im, BOOL useNativeCompWindow);

View File

@ -0,0 +1,128 @@
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
@test
@bug 7171412
@summary awt Choice doesn't fire ItemStateChange when selecting item after select() call
@author Oleg Pekhovskiy: area=awt-choice
@library ../../regtesthelpers
@build Util
@run main ItemStateChangeTest
*/
import test.java.awt.regtesthelpers.Util;
import java.awt.*;
import java.awt.event.*;
import sun.awt.OSInfo;
public class ItemStateChangeTest extends Frame {
int events = 0;
public static void main(String args[]) {
new ItemStateChangeTest();
}
public ItemStateChangeTest() {
if (OSInfo.getOSType() != OSInfo.OSType.WINDOWS) {
return;
}
try {
final Robot robot = new Robot();
robot.setAutoDelay(20);
Util.waitForIdle(robot);
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
final Choice choice = new Choice();
choice.add("A");
choice.add("B");
choice.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
++events;
}
});
add(choice);
setSize(200, 150);
setVisible(true);
toFront();
// choose B
int y = chooseB(choice, robot, 16);
// reset to A
choice.select(0);
robot.delay(20);
Util.waitForIdle(robot);
// choose B again
chooseB(choice, robot, y);
if (events == 2) {
System.out.println("Test passed!");
}
else {
throw new RuntimeException("Test failed!");
}
}
catch (AWTException e) {
throw new RuntimeException("Test failed!");
}
}
final int chooseB(Choice choice, Robot robot, int y) {
while (true) {
// show drop-down list
Util.clickOnComp(choice, robot);
Util.waitForIdle(robot);
Point pt = choice.getLocationOnScreen();
Dimension size = choice.getSize();
// try to click B item
robot.mouseMove(pt.x + size.width / 2, pt.y + size.height + y);
Util.waitForIdle(robot);
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
Util.waitForIdle(robot);
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
Util.waitForIdle(robot);
if (choice.getSelectedIndex() == 1) {
break;
}
// if it's not B, position cursor lower by 2 pixels and try again
y += 2;
}
return y;
}
}

View File

@ -0,0 +1,158 @@
/*
* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 6366126
* @summary List throws ArrayIndexOutOfBoundsException when pressing ENTER after removing all the items, Win32
* @author Dmitry Cherepanov area=awt.list
* @run main EmptyListEventTest
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import sun.awt.SunToolkit;
public class EmptyListEventTest {
private static List list;
public static void main(String[] args) throws Exception {
SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
Robot robot = new Robot();
robot.setAutoDelay(50);
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
createAndShowGUI();
}
});
toolkit.realSync();
// press mouse -> ItemEvent
Point point = getClickPoint();
robot.mouseMove(point.x, point.y);
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.mouseRelease(InputEvent.BUTTON1_MASK);
toolkit.realSync();
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
list.requestFocusInWindow();
}
});
toolkit.realSync();
if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != list) {
throw new RuntimeException("Test failed - list isn't focus owner.");
}
// press key ENTER -> ActionEvent
robot.keyPress(KeyEvent.VK_ENTER);
robot.keyRelease(KeyEvent.VK_ENTER);
toolkit.realSync();
// press key SPACE -> ItemEvent
robot.keyPress(KeyEvent.VK_SPACE);
robot.keyRelease(KeyEvent.VK_SPACE);
toolkit.realSync();
// mouse double click -> ActionEvent
robot.setAutoDelay(10);
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.mouseRelease(InputEvent.BUTTON1_MASK);
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.mouseRelease(InputEvent.BUTTON1_MASK);
toolkit.realSync();
}
private static Point getClickPoint() throws Exception {
final Point[] result = new Point[1];
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
Point point = list.getLocationOnScreen();
point.translate(list.getWidth() / 2, list.getHeight() / 2);
result[0] = point;
}
});
return result[0];
}
private static void createAndShowGUI() {
JFrame frame = new JFrame();
frame.setSize(200, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel(new BorderLayout());
frame.getToolkit().addAWTEventListener(new AWTEventListener() {
public void eventDispatched(AWTEvent e) {
System.out.println(e);
}
}, AWTEvent.FOCUS_EVENT_MASK | AWTEvent.WINDOW_FOCUS_EVENT_MASK);
MyListener listener = new MyListener();
list = new List(4, true);
list.addActionListener(listener);
list.addItemListener(listener);
panel.add(list);
frame.getContentPane().add(panel);
frame.setVisible(true);
}
static class MyListener implements ActionListener, ItemListener {
public void actionPerformed(ActionEvent ae) {
System.err.println(ae);
throw new RuntimeException("Test failed - list is empty so event is redundant");
}
public void itemStateChanged(ItemEvent ie) {
System.err.println(ie);
throw new RuntimeException("Test failed - list is empty so event is redundant");
}
}
}

View File

@ -0,0 +1,65 @@
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.ScrollPane;
import java.awt.Toolkit;
import sun.awt.SunToolkit;
/**
* @test
* @bug 7124213
* @author Sergey Bylokhov
*/
public final class ScrollPanePreferredSize {
public static void main(final String[] args) {
final Dimension expected = new Dimension(300, 300);
final Frame frame = new Frame();
final ScrollPane sp = new ScrollPane();
sp.setSize(expected);
frame.add(sp);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
sleep();
final Dimension size = frame.getSize();
if (size.width < expected.width || size.height < expected.height) {
throw new RuntimeException(
"Expected size: >= " + expected + ", actual size: " + size);
}
frame.dispose();
}
private static void sleep() {
((SunToolkit) Toolkit.getDefaultToolkit()).realSync();
try {
Thread.sleep(500L);
} catch (InterruptedException ignored) {
}
}
}

View File

@ -0,0 +1,66 @@
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.TextArea;
import java.awt.Toolkit;
import sun.awt.SunToolkit;
/**
* @test
* @bug 7160627
* @summary We shouldn't get different frame size when we call Frame.pack()
* twice.
* @author Sergey Bylokhov
*/
public final class TextAreaTwicePack {
public static void main(final String[] args) {
final Frame frame = new Frame();
final TextArea ta = new TextArea();
frame.add(ta);
frame.pack();
frame.setVisible(true);
sleep();
final Dimension before = frame.getSize();
frame.pack();
final Dimension after = frame.getSize();
if (!after.equals(before)) {
throw new RuntimeException(
"Expected size: " + before + ", actual size: " + after);
}
frame.dispose();
}
private static void sleep() {
((SunToolkit) Toolkit.getDefaultToolkit()).realSync();
try {
Thread.sleep(500L);
} catch (InterruptedException ignored) {
}
}
}

View File

@ -0,0 +1,131 @@
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 7199180
* @summary [macosx] Dead keys handling for input methods
* @author alexandr.scherbatiy area=awt.event
* @run main DeadKeyMacOSXInputText
*/
import java.awt.*;
import java.awt.event.*;
import java.awt.event.KeyEvent;
import javax.swing.JTextField;
import sun.awt.OSInfo;
import sun.awt.SunToolkit;
public class DeadKeyMacOSXInputText {
private static SunToolkit toolkit;
private static volatile int state = 0;
public static void main(String[] args) throws Exception {
if (OSInfo.getOSType() != OSInfo.OSType.MACOSX) {
return;
}
toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
Robot robot = new Robot();
robot.setAutoDelay(50);
createAndShowGUI();
// Pressed keys: Alt + E + A
// Results: ALT + VK_DEAD_ACUTE + a with accute accent
robot.keyPress(KeyEvent.VK_ALT);
robot.keyPress(KeyEvent.VK_E);
robot.keyRelease(KeyEvent.VK_E);
robot.keyRelease(KeyEvent.VK_ALT);
robot.keyPress(KeyEvent.VK_A);
robot.keyRelease(KeyEvent.VK_A);
toolkit.realSync();
if (state != 3) {
throw new RuntimeException("Wrong number of key events.");
}
}
static void createAndShowGUI() {
Frame frame = new Frame();
frame.setSize(300, 300);
Panel panel = new Panel(new BorderLayout());
JTextField textField = new JTextField();
textField.addKeyListener(new DeadKeyListener());
panel.add(textField, BorderLayout.CENTER);
frame.add(panel);
frame.setVisible(true);
toolkit.realSync();
textField.requestFocusInWindow();
toolkit.realSync();
}
static class DeadKeyListener extends KeyAdapter {
@Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
char keyChar = e.getKeyChar();
switch (state) {
case 0:
if (keyCode != KeyEvent.VK_ALT) {
throw new RuntimeException("Alt is not pressed.");
}
state++;
break;
case 1:
if (keyCode != KeyEvent.VK_DEAD_ACUTE) {
throw new RuntimeException("Dead ACUTE is not pressed.");
}
if (keyChar != 0xB4) {
throw new RuntimeException("Pressed char is not dead acute.");
}
state++;
break;
}
}
@Override
public void keyTyped(KeyEvent e) {
int keyCode = e.getKeyCode();
char keyChar = e.getKeyChar();
if (state == 2) {
if (keyCode != 0) {
throw new RuntimeException("Key code should be undefined.");
}
if (keyChar != 0xE1) {
throw new RuntimeException("A char does not have ACCUTE accent");
}
state++;
} else {
throw new RuntimeException("Wron number of keyTyped events.");
}
}
}
}

View File

@ -0,0 +1,113 @@
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* Portions Copyright (c) 2012 IBM Corporation
*/
/*
* @test
* @bug 7194184
* @summary Tests JColorChooser Swatch keyboard accessibility.
* @author Sean Chou
* @library ../regtesthelpers
* @build Util
* @run main Test7194184
*/
import java.awt.Component;
import java.awt.AWTException;
import java.awt.Color;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import javax.swing.JColorChooser;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import java.util.concurrent.Callable;
import sun.awt.SunToolkit;
public class Test7194184 implements Runnable {
private static JFrame frame;
private static JColorChooser colorChooser;
private static Color selectedColor;
public static void main(String[] args) throws Exception {
testKeyBoardAccess();
}
private static void testKeyBoardAccess() throws Exception {
Robot robot = new Robot();
SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
SwingUtilities.invokeLater(new Test7194184());
toolkit.realSync();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
selectedColor = colorChooser.getColor();
Component recentSwatchPanel = Util.findSubComponent(colorChooser, "RecentSwatchPanel");
if (recentSwatchPanel == null) {
throw new RuntimeException("RecentSwatchPanel not found");
}
recentSwatchPanel.requestFocusInWindow();
}
});
toolkit.realSync();
// Tab to move the focus to MainSwatch
Util.hitKeys(robot, KeyEvent.VK_SHIFT, KeyEvent.VK_TAB);
// Select the color on right
Util.hitKeys(robot, KeyEvent.VK_RIGHT);
Util.hitKeys(robot, KeyEvent.VK_RIGHT);
Util.hitKeys(robot, KeyEvent.VK_SPACE);
toolkit.realSync();
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
frame.dispose();
if (selectedColor == colorChooser.getColor()) {
throw new RuntimeException("JColorChooser misses keyboard accessibility");
}
}
});
}
public void run() {
String title = getClass().getName();
frame = new JFrame(title);
colorChooser = new JColorChooser();
frame.add(colorChooser);
frame.pack();
frame.setVisible(true);
}
}

View File

@ -0,0 +1,220 @@
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
@bug 7123767
@summary Wrong tooltip location in Multi-Monitor configurations
@author Vladislav Karnaukhov
@run main bug7123767
*/
import sun.awt.SunToolkit;
import javax.swing.*;
import javax.swing.plaf.metal.MetalLookAndFeel;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.lang.reflect.InvocationTargetException;
public class bug7123767 extends JFrame {
private static class TestFactory extends PopupFactory {
private static TestFactory newFactory = new TestFactory();
private static PopupFactory oldFactory;
private TestFactory() {
super();
}
public static void install() {
if (oldFactory == null) {
oldFactory = getSharedInstance();
setSharedInstance(newFactory);
}
}
public static void uninstall() {
if (oldFactory != null) {
setSharedInstance(oldFactory);
}
}
// Actual test happens here
public Popup getPopup(Component owner, Component contents, int x, int y) {
GraphicsConfiguration mouseGC = testGC(MouseInfo.getPointerInfo().getLocation());
if (mouseGC == null) {
throw new RuntimeException("Can't find GraphicsConfiguration that mouse pointer belongs to");
}
GraphicsConfiguration tipGC = testGC(new Point(x, y));
if (tipGC == null) {
throw new RuntimeException("Can't find GraphicsConfiguration that tip belongs to");
}
if (!mouseGC.equals(tipGC)) {
throw new RuntimeException("Mouse and tip GCs are not equal");
}
return super.getPopup(owner, contents, x, y);
}
private static GraphicsConfiguration testGC(Point pt) {
GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] devices = environment.getScreenDevices();
for (GraphicsDevice device : devices) {
GraphicsConfiguration[] configs = device.getConfigurations();
for (GraphicsConfiguration config : configs) {
Rectangle rect = config.getBounds();
Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(config);
adjustInsets(rect, insets);
if (rect.contains(pt))
return config;
}
}
return null;
}
}
private static final int MARGIN = 10;
private static bug7123767 frame;
private static Robot robot;
public static void main(String[] args) throws Exception {
UIManager.setLookAndFeel(new MetalLookAndFeel());
setUp();
testToolTip();
TestFactory.uninstall();
}
// Creates a window that is stretched across all available monitors
// and adds itself as ContainerListener to track tooltips drawing
private bug7123767() {
super();
ToolTipManager.sharedInstance().setInitialDelay(0);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
TestFactory.install();
JLabel label1 = new JLabel("no preferred location");
label1.setToolTipText("tip");
add(label1, BorderLayout.WEST);
JLabel label2 = new JLabel("preferred location (20000, 20000)") {
public Point getToolTipLocation(MouseEvent event) {
return new Point(20000, 20000);
}
};
label2.setToolTipText("tip");
add(label2, BorderLayout.EAST);
setUndecorated(true);
pack();
Rectangle rect = new Rectangle();
GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] devices = environment.getScreenDevices();
for (GraphicsDevice device : devices) {
GraphicsConfiguration[] configs = device.getConfigurations();
for (GraphicsConfiguration config : configs) {
Insets localInsets = Toolkit.getDefaultToolkit().getScreenInsets(config);
Rectangle localRect = config.getBounds();
adjustInsets(localRect, localInsets);
rect.add(localRect);
}
}
setBounds(rect);
}
private static void setUp() throws InterruptedException, InvocationTargetException {
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
frame = new bug7123767();
frame.setVisible(true);
}
});
}
// Moves mouse pointer to the corners of every GraphicsConfiguration
private static void testToolTip() throws AWTException {
SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
toolkit.realSync();
GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] devices = environment.getScreenDevices();
for (GraphicsDevice device : devices) {
GraphicsConfiguration[] configs = device.getConfigurations();
for (GraphicsConfiguration config : configs) {
Rectangle rect = config.getBounds();
Insets insets = toolkit.getScreenInsets(config);
adjustInsets(rect, insets);
// Upper left
glide(rect.x + rect.width / 2, rect.y + rect.height / 2,
rect.x + MARGIN, rect.y + MARGIN);
toolkit.realSync();
// Lower left
glide(rect.x + rect.width / 2, rect.y + rect.height / 2,
rect.x + MARGIN, rect.y + rect.height - MARGIN);
toolkit.realSync();
// Upper right
glide(rect.x + rect.width / 2, rect.y + rect.height / 2,
rect.x + rect.width - MARGIN, rect.y + MARGIN);
toolkit.realSync();
// Lower right
glide(rect.x + rect.width / 2, rect.y + rect.height / 2,
rect.x + rect.width - MARGIN, rect.y + rect.height - MARGIN);
toolkit.realSync();
}
}
}
private static void glide(int x0, int y0, int x1, int y1) throws AWTException {
if (robot == null) {
robot = new Robot();
robot.setAutoDelay(20);
}
float dmax = (float) Math.max(Math.abs(x1 - x0), Math.abs(y1 - y0));
float dx = (x1 - x0) / dmax;
float dy = (y1 - y0) / dmax;
robot.mouseMove(x0, y0);
for (int i = 1; i <= dmax; i += 10) {
robot.mouseMove((int) (x0 + dx * i), (int) (y0 + dy * i));
}
}
private static void adjustInsets(Rectangle rect, final Insets insets) {
rect.x += insets.left;
rect.y += insets.top;
rect.width -= (insets.left + insets.right);
rect.height -= (insets.top + insets.bottom);
}
}