# HG changeset patch # User zhouyx # Date 1348148387 -14400 # Node ID 218c91f4bb7b44d51d8778a2869141b3e10af576 # Parent 1ca9ff9c025497822817b359f28a1ef0db49e45e 7194184: JColorChooser swatch cannot accessed from keyboard Reviewed-by: rupashka, alexsch diff -r 1ca9ff9c0254 -r 218c91f4bb7b jdk/src/share/classes/javax/swing/colorchooser/DefaultSwatchChooserPanel.java --- a/jdk/src/share/classes/javax/swing/colorchooser/DefaultSwatchChooserPanel.java Tue Sep 18 17:38:40 2012 +0400 +++ b/jdk/src/share/classes/javax/swing/colorchooser/DefaultSwatchChooserPanel.java Thu Sep 20 17:39:47 2012 +0400 @@ -57,6 +57,8 @@ RecentSwatchPanel recentSwatchPanel; MouseListener mainSwatchListener; MouseListener recentSwatchListener; + private KeyListener mainSwatchKeyListener; + private KeyListener recentSwatchKeyListener; public DefaultSwatchChooserPanel() { super(); @@ -151,10 +153,14 @@ 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 @@ 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 @@ } + 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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); diff -r 1ca9ff9c0254 -r 218c91f4bb7b jdk/test/javax/swing/JColorChooser/Test7194184.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/swing/JColorChooser/Test7194184.java Thu Sep 20 17:39:47 2012 +0400 @@ -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); + } + +}