This commit is contained in:
Yuri Nesterenko 2009-10-06 23:44:44 -07:00
commit 682543d219
25 changed files with 798 additions and 258 deletions

View File

@ -715,7 +715,7 @@ public class JFileChooser extends JComponent implements Accessible {
* <ul> * <ul>
* <li>JFileChooser.CANCEL_OPTION * <li>JFileChooser.CANCEL_OPTION
* <li>JFileChooser.APPROVE_OPTION * <li>JFileChooser.APPROVE_OPTION
* <li>JFileCHooser.ERROR_OPTION if an error occurs or the * <li>JFileChooser.ERROR_OPTION if an error occurs or the
* dialog is dismissed * dialog is dismissed
* </ul> * </ul>
* @exception HeadlessException if GraphicsEnvironment.isHeadless() * @exception HeadlessException if GraphicsEnvironment.isHeadless()
@ -724,6 +724,11 @@ public class JFileChooser extends JComponent implements Accessible {
*/ */
public int showDialog(Component parent, String approveButtonText) public int showDialog(Component parent, String approveButtonText)
throws HeadlessException { throws HeadlessException {
if (dialog != null) {
// Prevent to show second instance of dialog if the previous one still exists
return JFileChooser.ERROR_OPTION;
}
if(approveButtonText != null) { if(approveButtonText != null) {
setApproveButtonText(approveButtonText); setApproveButtonText(approveButtonText);
setDialogType(CUSTOM_DIALOG); setDialogType(CUSTOM_DIALOG);

View File

@ -56,28 +56,70 @@ import java.security.PrivilegedAction;
* {@code JLayer} is a good solution if you only need to do custom painting * {@code JLayer} is a good solution if you only need to do custom painting
* over compound component or catch input events from its subcomponents. * over compound component or catch input events from its subcomponents.
* <pre> * <pre>
* import javax.swing.*;
* import javax.swing.plaf.LayerUI;
* import java.awt.*;
*
* public class JLayerSample {
*
* private static JLayer&lt;JComponent&gt; createLayer() {
* // This custom layerUI will fill the layer with translucent green
* // and print out all mouseMotion events generated within its borders
* LayerUI&lt;JComponent&gt; layerUI = new LayerUI&lt;JComponent&gt;() {
*
* public void paint(Graphics g, JComponent c) {
* // paint the layer as is
* super.paint(g, c);
* // fill it with the translucent green
* g.setColor(new Color(0, 128, 0, 128));
* g.fillRect(0, 0, c.getWidth(), c.getHeight());
* }
*
* public void installUI(JComponent c) {
* super.installUI(c);
* // enable mouse motion events for the layer's subcomponents
* ((JLayer) c).setLayerEventMask(AWTEvent.MOUSE_MOTION_EVENT_MASK);
* }
*
* public void uninstallUI(JComponent c) {
* super.uninstallUI(c);
* // reset the layer event mask
* ((JLayer) c).setLayerEventMask(0);
* }
*
* // overridden method which catches MouseMotion events
* public void eventDispatched(AWTEvent e, JLayer&lt;? extends JComponent&gt; l) {
* System.out.println("AWTEvent detected: " + e);
* }
* };
* // create a component to be decorated with the layer * // create a component to be decorated with the layer
* JPanel panel = new JPanel(); * JPanel panel = new JPanel();
* panel.add(new JButton("JButton")); * panel.add(new JButton("JButton"));
* // This custom layerUI will fill the layer with translucent green *
* // and print out all mouseMotion events generated within its borders * // create the layer for the panel using our custom layerUI
* LayerUI&lt;JPanel&gt; layerUI = new LayerUI&lt;JPanel&gt;() { * return new JLayer&lt;JComponent&gt;(panel, layerUI);
* public void paint(Graphics g, JCompo nent c) { * }
* // paint the layer as is *
* super.paint(g, c); * private static void createAndShowGUI() {
* // fill it with the translucent green * final JFrame frame = new JFrame();
* g.setColor(new Color(0, 128, 0, 128)); * frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
* g.fillRect(0, 0, c.getWidth(), c.getHeight()); *
* } * // work with the layer as with any other Swing component
* // overridden method which catches MouseMotion events * frame.add(createLayer());
* public void eventDispatched(AWTEvent e, JLayer&lt;JPanel&gt; l) { *
* System.out.println("AWTEvent detected: " + e); * frame.setSize(200, 200);
* } * frame.setLocationRelativeTo(null);
* }; * frame.setVisible(true);
* // create the layer for the panel using our custom layerUI * }
* JLayer&lt;JPanel&gt; layer = new JLayer&lt;JPanel&gt;(panel, layerUI); *
* // work with the layer as with any other Swing component * public static void main(String[] args) throws Exception {
* frame.add(layer); * SwingUtilities.invokeAndWait(new Runnable() {
* public void run() {
* createAndShowGUI();
* }
* });
* }
* }
* </pre> * </pre>
* *
* <b>Note:</b> {@code JLayer} doesn't support the following methods: * <b>Note:</b> {@code JLayer} doesn't support the following methods:
@ -291,7 +333,9 @@ public final class JLayer<V extends Component>
* {@inheritDoc} * {@inheritDoc}
*/ */
public void remove(Component comp) { public void remove(Component comp) {
if (comp == getView()) { if (comp == null) {
super.remove(comp);
} else if (comp == getView()) {
setView(null); setView(null);
} else if (comp == getGlassPane()) { } else if (comp == getGlassPane()) {
setGlassPane(null); setGlassPane(null);

View File

@ -1766,7 +1766,7 @@ public class BasicComboBoxUI extends ComboBoxUI {
} }
private boolean isTypeAheadKey( KeyEvent e ) { private boolean isTypeAheadKey( KeyEvent e ) {
return !e.isAltDown() && !e.isControlDown() && !e.isMetaDown(); return !e.isAltDown() && !BasicGraphicsUtils.isMenuShortcutKeyDown(e);
} }
// //

View File

@ -483,11 +483,12 @@ public class BasicComboPopup extends JPopupMenu implements ComboPopup {
protected JList createList() { protected JList createList() {
return new JList( comboBox.getModel() ) { return new JList( comboBox.getModel() ) {
public void processMouseEvent(MouseEvent e) { public void processMouseEvent(MouseEvent e) {
if (e.isControlDown()) { if (BasicGraphicsUtils.isMenuShortcutKeyDown(e)) {
// Fix for 4234053. Filter out the Control Key from the list. // Fix for 4234053. Filter out the Control Key from the list.
// ie., don't allow CTRL key deselection. // ie., don't allow CTRL key deselection.
Toolkit toolkit = Toolkit.getDefaultToolkit();
e = new MouseEvent((Component)e.getSource(), e.getID(), e.getWhen(), e = new MouseEvent((Component)e.getSource(), e.getID(), e.getWhen(),
e.getModifiers() ^ InputEvent.CTRL_MASK, e.getModifiers() ^ toolkit.getMenuShortcutKeyMask(),
e.getX(), e.getY(), e.getX(), e.getY(),
e.getXOnScreen(), e.getYOnScreen(), e.getXOnScreen(), e.getYOnScreen(),
e.getClickCount(), e.getClickCount(),

View File

@ -924,7 +924,8 @@ public class BasicFileChooserUI extends FileChooserUI {
boolean isTrav = (selectedFile != null && chooser.isTraversable(selectedFile)); boolean isTrav = (selectedFile != null && chooser.isTraversable(selectedFile));
boolean isDirSelEnabled = chooser.isDirectorySelectionEnabled(); boolean isDirSelEnabled = chooser.isDirectorySelectionEnabled();
boolean isFileSelEnabled = chooser.isFileSelectionEnabled(); boolean isFileSelEnabled = chooser.isFileSelectionEnabled();
boolean isCtrl = (e != null && (e.getModifiers() & ActionEvent.CTRL_MASK) != 0); boolean isCtrl = (e != null && (e.getModifiers() &
Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) != 0);
if (isDir && isTrav && (isCtrl || !isDirSelEnabled)) { if (isDir && isTrav && (isCtrl || !isDirSelEnabled)) {
changeDirectory(selectedFile); changeDirectory(selectedFile);

View File

@ -33,7 +33,10 @@ import java.awt.FontMetrics;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Insets; import java.awt.Insets;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.awt.event.InputEvent;
import sun.swing.SwingUtilities2; import sun.swing.SwingUtilities2;
@ -303,4 +306,9 @@ public class BasicGraphicsUtils
static boolean isLeftToRight( Component c ) { static boolean isLeftToRight( Component c ) {
return c.getComponentOrientation().isLeftToRight(); return c.getComponentOrientation().isLeftToRight();
} }
static boolean isMenuShortcutKeyDown(InputEvent event) {
return (event.getModifiers() &
Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) != 0;
}
} }

View File

@ -2371,8 +2371,9 @@ public class BasicListUI extends ListUI
JList src = (JList)e.getSource(); JList src = (JList)e.getSource();
ListModel model = src.getModel(); ListModel model = src.getModel();
if (model.getSize() == 0 || e.isAltDown() || e.isControlDown() || e.isMetaDown() || if (model.getSize() == 0 || e.isAltDown() ||
isNavigationKey(e)) { BasicGraphicsUtils.isMenuShortcutKeyDown(e) ||
isNavigationKey(e)) {
// Nothing to select // Nothing to select
return; return;
} }
@ -2665,7 +2666,7 @@ public class BasicListUI extends ListUI
if (row != -1 && DragRecognitionSupport.mousePressed(e)) { if (row != -1 && DragRecognitionSupport.mousePressed(e)) {
dragPressDidSelection = false; dragPressDidSelection = false;
if (e.isControlDown()) { if (BasicGraphicsUtils.isMenuShortcutKeyDown(e)) {
// do nothing for control - will be handled on release // do nothing for control - will be handled on release
// or when drag starts // or when drag starts
return; return;
@ -2717,7 +2718,7 @@ public class BasicListUI extends ListUI
anchorSelected = list.isSelectedIndex(anchorIndex); anchorSelected = list.isSelectedIndex(anchorIndex);
} }
if (e.isControlDown()) { if (BasicGraphicsUtils.isMenuShortcutKeyDown(e)) {
if (e.isShiftDown()) { if (e.isShiftDown()) {
if (anchorSelected) { if (anchorSelected) {
list.addSelectionInterval(anchorIndex, row); list.addSelectionInterval(anchorIndex, row);
@ -2742,7 +2743,7 @@ public class BasicListUI extends ListUI
} }
public void dragStarting(MouseEvent me) { public void dragStarting(MouseEvent me) {
if (me.isControlDown()) { if (BasicGraphicsUtils.isMenuShortcutKeyDown(me)) {
int row = SwingUtilities2.loc2IndexFileList(list, me.getPoint()); int row = SwingUtilities2.loc2IndexFileList(list, me.getPoint());
list.addSelectionInterval(row, row); list.addSelectionInterval(row, row);
} }
@ -2758,7 +2759,7 @@ public class BasicListUI extends ListUI
return; return;
} }
if (e.isShiftDown() || e.isControlDown()) { if (e.isShiftDown() || BasicGraphicsUtils.isMenuShortcutKeyDown(e)) {
return; return;
} }

View File

@ -196,10 +196,6 @@ public class BasicMenuUI extends BasicMenuItemUI
return getHandler(); return getHandler();
} }
protected MenuKeyListener createMenuKeyListener(JComponent c) {
return (MenuKeyListener)getHandler();
}
public Dimension getMaximumSize(JComponent c) { public Dimension getMaximumSize(JComponent c) {
if (((JMenu)menuItem).isTopLevelMenu() == true) { if (((JMenu)menuItem).isTopLevelMenu() == true) {
Dimension d = c.getPreferredSize(); Dimension d = c.getPreferredSize();
@ -401,8 +397,7 @@ public class BasicMenuUI extends BasicMenuItemUI
public void stateChanged(ChangeEvent e) { } public void stateChanged(ChangeEvent e) { }
} }
private class Handler extends BasicMenuItemUI.Handler implements private class Handler extends BasicMenuItemUI.Handler {
MenuKeyListener {
// //
// PropertyChangeListener // PropertyChangeListener
// //
@ -585,45 +580,5 @@ public class BasicMenuUI extends BasicMenuItemUI
} }
public void menuDragMouseExited(MenuDragMouseEvent e) {} public void menuDragMouseExited(MenuDragMouseEvent e) {}
public void menuDragMouseReleased(MenuDragMouseEvent e) {} public void menuDragMouseReleased(MenuDragMouseEvent e) {}
//
// MenuKeyListener
//
/**
* Open the Menu
*/
public void menuKeyTyped(MenuKeyEvent e) {
if (!crossMenuMnemonic && BasicPopupMenuUI.getLastPopup() != null) {
// when crossMenuMnemonic is not set, we don't open a toplevel
// menu if another toplevel menu is already open
return;
}
char key = Character.toLowerCase((char)menuItem.getMnemonic());
MenuElement path[] = e.getPath();
MenuSelectionManager manager = e.getMenuSelectionManager();
if (key == Character.toLowerCase(e.getKeyChar())) {
JPopupMenu popupMenu = ((JMenu)menuItem).getPopupMenu();
ArrayList<MenuElement> newList = new ArrayList<MenuElement>(Arrays.asList(path));
newList.add(popupMenu);
MenuElement subs[] = popupMenu.getSubElements();
MenuElement sub =
BasicPopupMenuUI.findEnabledChild(subs, -1, true);
if(sub != null) {
newList.add(sub);
}
MenuElement newPath[] = new MenuElement[0];
newPath = newList.toArray(newPath);
manager.setSelectedPath(newPath);
e.consume();
} else if (((JMenu)menuItem).isTopLevelMenu()
&& BasicPopupMenuUI.getLastPopup() == null) {
manager.clearSelectedPath();
}
}
public void menuKeyPressed(MenuKeyEvent e) {}
public void menuKeyReleased(MenuKeyEvent e) {}
} }
} }

View File

@ -339,7 +339,7 @@ public class BasicPopupMenuUI extends PopupMenuUI {
indexes[matches++] = j; indexes[matches++] = j;
} }
} }
if (item.isArmed()) { if (item.isArmed() || item.isSelected()) {
currentIndex = matches - 1; currentIndex = matches - 1;
} }
} }

View File

@ -1027,7 +1027,7 @@ public class BasicTableUI extends TableUI
shouldStartTimer = shouldStartTimer =
table.isCellSelected(pressedRow, pressedCol) && table.isCellSelected(pressedRow, pressedCol) &&
!e.isShiftDown() && !e.isShiftDown() &&
!e.isControlDown() && !BasicGraphicsUtils.isMenuShortcutKeyDown(e) &&
!outsidePrefSize; !outsidePrefSize;
} }
@ -1051,7 +1051,7 @@ public class BasicTableUI extends TableUI
dragPressDidSelection = false; dragPressDidSelection = false;
if (e.isControlDown() && isFileList) { if (BasicGraphicsUtils.isMenuShortcutKeyDown(e) && isFileList) {
// do nothing for control - will be handled on release // do nothing for control - will be handled on release
// or when drag starts // or when drag starts
return; return;
@ -1115,7 +1115,9 @@ public class BasicTableUI extends TableUI
CellEditor editor = table.getCellEditor(); CellEditor editor = table.getCellEditor();
if (dragEnabled || editor == null || editor.shouldSelectCell(e)) { if (dragEnabled || editor == null || editor.shouldSelectCell(e)) {
table.changeSelection(pressedRow, pressedCol, e.isControlDown(), e.isShiftDown()); table.changeSelection(pressedRow, pressedCol,
BasicGraphicsUtils.isMenuShortcutKeyDown(e),
e.isShiftDown());
} }
} }
@ -1212,7 +1214,7 @@ public class BasicTableUI extends TableUI
public void dragStarting(MouseEvent me) { public void dragStarting(MouseEvent me) {
dragStarted = true; dragStarted = true;
if (me.isControlDown() && isFileList) { if (BasicGraphicsUtils.isMenuShortcutKeyDown(me) && isFileList) {
table.getSelectionModel().addSelectionInterval(pressedRow, table.getSelectionModel().addSelectionInterval(pressedRow,
pressedRow); pressedRow);
table.getColumnModel().getSelectionModel(). table.getColumnModel().getSelectionModel().
@ -1251,7 +1253,8 @@ public class BasicTableUI extends TableUI
return; return;
} }
table.changeSelection(row, column, e.isControlDown(), true); table.changeSelection(row, column,
BasicGraphicsUtils.isMenuShortcutKeyDown(e), true);
} }

View File

@ -2265,7 +2265,7 @@ public class BasicTreeUI extends TreeUI
*/ */
protected boolean isToggleSelectionEvent(MouseEvent event) { protected boolean isToggleSelectionEvent(MouseEvent event) {
return (SwingUtilities.isLeftMouseButton(event) && return (SwingUtilities.isLeftMouseButton(event) &&
event.isControlDown()); BasicGraphicsUtils.isMenuShortcutKeyDown(event));
} }
/** /**
@ -3255,7 +3255,7 @@ public class BasicTreeUI extends TreeUI
// handle first letter navigation // handle first letter navigation
if(tree != null && tree.getRowCount()>0 && tree.hasFocus() && if(tree != null && tree.getRowCount()>0 && tree.hasFocus() &&
tree.isEnabled()) { tree.isEnabled()) {
if (e.isAltDown() || e.isControlDown() || e.isMetaDown() || if (e.isAltDown() || BasicGraphicsUtils.isMenuShortcutKeyDown(e) ||
isNavigationKey(e)) { isNavigationKey(e)) {
return; return;
} }
@ -3511,7 +3511,7 @@ public class BasicTreeUI extends TreeUI
dragPressDidSelection = false; dragPressDidSelection = false;
if (e.isControlDown()) { if (BasicGraphicsUtils.isMenuShortcutKeyDown(e)) {
// do nothing for control - will be handled on release // do nothing for control - will be handled on release
// or when drag starts // or when drag starts
return; return;
@ -3565,7 +3565,7 @@ public class BasicTreeUI extends TreeUI
public void dragStarting(MouseEvent me) { public void dragStarting(MouseEvent me) {
dragStarted = true; dragStarted = true;
if (me.isControlDown()) { if (BasicGraphicsUtils.isMenuShortcutKeyDown(me)) {
tree.addSelectionPath(pressedPath); tree.addSelectionPath(pressedPath);
setAnchorSelectionPath(pressedPath); setAnchorSelectionPath(pressedPath);
setLeadSelectionPath(pressedPath, true); setLeadSelectionPath(pressedPath, true);

View File

@ -14824,7 +14824,9 @@
<background/> <background/>
<cacheSettingsInherited>false</cacheSettingsInherited> <cacheSettingsInherited>false</cacheSettingsInherited>
<cacheMode>NO_CACHING</cacheMode> <cacheMode>NO_CACHING</cacheMode>
<uiproperties/> <uiproperties>
<uiProperty name="textIconGap" type="INT" value="5"/>
</uiproperties>
</style> </style>
<backgroundStates> <backgroundStates>
<state stateKeys="Disabled"> <state stateKeys="Disabled">

View File

@ -475,11 +475,11 @@ public class SynthGraphicsUtils {
return result; return result;
} }
static void applyInsets(Rectangle rect, Insets insets) { static void applyInsets(Rectangle rect, Insets insets, boolean leftToRight) {
if (insets != null) { if (insets != null) {
rect.x += insets.left; rect.x += (leftToRight ? insets.left : insets.right);
rect.y += insets.top; rect.y += insets.top;
rect.width -= (insets.right + rect.x); rect.width -= (leftToRight ? insets.right : insets.left) + rect.x;
rect.height -= (insets.bottom + rect.y); rect.height -= (insets.bottom + rect.y);
} }
} }
@ -492,12 +492,12 @@ public class SynthGraphicsUtils {
g.setFont(style.getFont(context)); g.setFont(style.getFont(context));
Rectangle viewRect = new Rectangle(0, 0, mi.getWidth(), mi.getHeight()); Rectangle viewRect = new Rectangle(0, 0, mi.getWidth(), mi.getHeight());
applyInsets(viewRect, mi.getInsets()); boolean leftToRight = SynthLookAndFeel.isLeftToRight(mi);
applyInsets(viewRect, mi.getInsets(), leftToRight);
SynthMenuItemLayoutHelper lh = new SynthMenuItemLayoutHelper( SynthMenuItemLayoutHelper lh = new SynthMenuItemLayoutHelper(
context, accContext, mi, checkIcon, context, accContext, mi, checkIcon, arrowIcon, viewRect,
arrowIcon, viewRect, defaultTextIconGap, acceleratorDelimiter, defaultTextIconGap, acceleratorDelimiter, leftToRight,
SynthLookAndFeel.isLeftToRight(mi),
MenuItemLayoutHelper.useCheckAndArrow(mi), propertyPrefix); MenuItemLayoutHelper.useCheckAndArrow(mi), propertyPrefix);
MenuItemLayoutHelper.LayoutResult lr = lh.layoutMenuItem(); MenuItemLayoutHelper.LayoutResult lr = lh.layoutMenuItem();

View File

@ -510,7 +510,7 @@ public class DefaultCaret extends Rectangle implements Caret, FocusListener, Mou
if ((e.getModifiers() & ActionEvent.SHIFT_MASK) != 0 && if ((e.getModifiers() & ActionEvent.SHIFT_MASK) != 0 &&
getDot() != -1) { getDot() != -1) {
moveCaret(e); moveCaret(e);
} else { } else if (!e.isPopupTrigger()) {
positionCaret(e); positionCaret(e);
} }
} }

View File

@ -30,6 +30,7 @@ import java.text.AttributedCharacterIterator;
import java.text.BreakIterator; import java.text.BreakIterator;
import java.awt.font.*; import java.awt.font.*;
import java.awt.geom.AffineTransform; import java.awt.geom.AffineTransform;
import javax.swing.JComponent;
import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentEvent;
import sun.font.BidiUtils; import sun.font.BidiUtils;
@ -301,6 +302,13 @@ class TextLayoutStrategy extends FlowView.FlowStrategy {
iter = BreakIterator.getLineInstance(); iter = BreakIterator.getLineInstance();
} }
Object shaper = null;
if (c instanceof JComponent) {
shaper = ((JComponent) c).getClientProperty(
TextAttribute.NUMERIC_SHAPING);
}
text.setShaper(shaper);
measurer = new LineBreakMeasurer(text, iter, frc); measurer = new LineBreakMeasurer(text, iter, frc);
// If the children of the FlowView's logical view are GlyphViews, they // If the children of the FlowView's logical view are GlyphViews, they
@ -399,6 +407,10 @@ class TextLayoutStrategy extends FlowView.FlowStrategy {
return pos - v.getStartOffset() + getBeginIndex(); return pos - v.getStartOffset() + getBeginIndex();
} }
private void setShaper(Object shaper) {
this.shaper = shaper;
}
// --- AttributedCharacterIterator methods ------------------------- // --- AttributedCharacterIterator methods -------------------------
/** /**
@ -511,6 +523,8 @@ class TextLayoutStrategy extends FlowView.FlowStrategy {
} else if( attribute == TextAttribute.RUN_DIRECTION ) { } else if( attribute == TextAttribute.RUN_DIRECTION ) {
return return
v.getDocument().getProperty(TextAttribute.RUN_DIRECTION); v.getDocument().getProperty(TextAttribute.RUN_DIRECTION);
} else if (attribute == TextAttribute.NUMERIC_SHAPING) {
return shaper;
} }
return null; return null;
} }
@ -532,8 +546,10 @@ class TextLayoutStrategy extends FlowView.FlowStrategy {
keys = new HashSet<Attribute>(); keys = new HashSet<Attribute>();
keys.add(TextAttribute.FONT); keys.add(TextAttribute.FONT);
keys.add(TextAttribute.RUN_DIRECTION); keys.add(TextAttribute.RUN_DIRECTION);
keys.add(TextAttribute.NUMERIC_SHAPING);
} }
private Object shaper = null;
} }
} }

View File

@ -57,8 +57,9 @@ class ShellFolderManager {
* folders, such as Desktop, Documents, History, Network, Home, etc. * folders, such as Desktop, Documents, History, Network, Home, etc.
* This is used in the shortcut panel of the filechooser on Windows 2000 * This is used in the shortcut panel of the filechooser on Windows 2000
* and Windows Me. * and Windows Me.
* "fileChooserIcon nn": * "fileChooserIcon <icon>":
* Returns an <code>Image</code> - icon nn from resource 124 in comctl32.dll (Windows only). * Returns an <code>Image</code> - icon can be ListView, DetailsView, UpFolder, NewFolder or
* ViewMenu (Windows only).
* *
* @return An Object matching the key string. * @return An Object matching the key string.
*/ */

View File

@ -192,6 +192,19 @@ public class SwingUtilities2 {
fontCache = new LSBCacheEntry[CACHE_SIZE]; fontCache = new LSBCacheEntry[CACHE_SIZE];
} }
/**
* Fill the character buffer cache. Return the buffer length.
*/
private static int syncCharsBuffer(String s) {
int length = s.length();
if ((charsBuffer == null) || (charsBuffer.length < length)) {
charsBuffer = s.toCharArray();
} else {
s.getChars(0, length, charsBuffer, 0);
}
return length;
}
/** /**
* checks whether TextLayout is required to handle characters. * checks whether TextLayout is required to handle characters.
* *
@ -237,15 +250,23 @@ public class SwingUtilities2 {
* Returns the left side bearing of the first character of string. The * Returns the left side bearing of the first character of string. The
* left side bearing is calculated from the passed in * left side bearing is calculated from the passed in
* FontMetrics. If the passed in String is less than one * FontMetrics. If the passed in String is less than one
* character, this will throw a StringIndexOutOfBoundsException exception. * character {@code 0} is returned.
* *
* @param c JComponent that will display the string * @param c JComponent that will display the string
* @param fm FontMetrics used to measure the String width * @param fm FontMetrics used to measure the String width
* @param string String to get the left side bearing for. * @param string String to get the left side bearing for.
* @throws NullPointerException if {@code string} is {@code null}
*
* @return the left side bearing of the first character of string
* or {@code 0} if the string is empty
*/ */
public static int getLeftSideBearing(JComponent c, FontMetrics fm, public static int getLeftSideBearing(JComponent c, FontMetrics fm,
String string) { String string) {
return getLeftSideBearing(c, fm, string.charAt(0)); int res = 0;
if (!string.isEmpty()) {
res = getLeftSideBearing(c, fm, string.charAt(0));
}
return res;
} }
/** /**
@ -353,7 +374,21 @@ public class SwingUtilities2 {
if (string == null || string.equals("")) { if (string == null || string.equals("")) {
return 0; return 0;
} }
return fm.stringWidth(string); boolean needsTextLayout = ((c != null) &&
(c.getClientProperty(TextAttribute.NUMERIC_SHAPING) != null));
if (needsTextLayout) {
synchronized(charsBufferLock) {
int length = syncCharsBuffer(string);
needsTextLayout = isComplexLayout(charsBuffer, 0, length);
}
}
if (needsTextLayout) {
TextLayout layout = createTextLayout(c, string,
fm.getFont(), fm.getFontRenderContext());
return (int) layout.getAdvance();
} else {
return fm.stringWidth(string);
}
} }
@ -394,21 +429,11 @@ public class SwingUtilities2 {
String string, int availTextWidth) { String string, int availTextWidth) {
// c may be null here. // c may be null here.
String clipString = "..."; String clipString = "...";
int stringLength = string.length();
availTextWidth -= SwingUtilities2.stringWidth(c, fm, clipString); availTextWidth -= SwingUtilities2.stringWidth(c, fm, clipString);
if (availTextWidth <= 0) {
//can not fit any characters
return clipString;
}
boolean needsTextLayout; boolean needsTextLayout;
synchronized (charsBufferLock) { synchronized (charsBufferLock) {
if (charsBuffer == null || charsBuffer.length < stringLength) { int stringLength = syncCharsBuffer(string);
charsBuffer = string.toCharArray();
} else {
string.getChars(0, stringLength, charsBuffer, 0);
}
needsTextLayout = needsTextLayout =
isComplexLayout(charsBuffer, 0, stringLength); isComplexLayout(charsBuffer, 0, stringLength);
if (!needsTextLayout) { if (!needsTextLayout) {
@ -425,6 +450,10 @@ public class SwingUtilities2 {
if (needsTextLayout) { if (needsTextLayout) {
FontRenderContext frc = getFontRenderContext(c, fm); FontRenderContext frc = getFontRenderContext(c, fm);
AttributedString aString = new AttributedString(string); AttributedString aString = new AttributedString(string);
if (c != null) {
aString.addAttribute(TextAttribute.NUMERIC_SHAPING,
c.getClientProperty(TextAttribute.NUMERIC_SHAPING));
}
LineBreakMeasurer measurer = LineBreakMeasurer measurer =
new LineBreakMeasurer(aString.getIterator(), frc); new LineBreakMeasurer(aString.getIterator(), frc);
int nChars = measurer.nextOffset(availTextWidth); int nChars = measurer.nextOffset(availTextWidth);
@ -465,7 +494,7 @@ public class SwingUtilities2 {
*/ */
float screenWidth = (float) float screenWidth = (float)
g2d.getFont().getStringBounds(text, DEFAULT_FRC).getWidth(); g2d.getFont().getStringBounds(text, DEFAULT_FRC).getWidth();
TextLayout layout = new TextLayout(text, g2d.getFont(), TextLayout layout = createTextLayout(c, text, g2d.getFont(),
g2d.getFontRenderContext()); g2d.getFontRenderContext());
layout = layout.getJustifiedLayout(screenWidth); layout = layout.getJustifiedLayout(screenWidth);
@ -505,7 +534,21 @@ public class SwingUtilities2 {
} }
} }
g.drawString(text, x, y); boolean needsTextLayout = ((c != null) &&
(c.getClientProperty(TextAttribute.NUMERIC_SHAPING) != null));
if (needsTextLayout) {
synchronized(charsBufferLock) {
int length = syncCharsBuffer(text);
needsTextLayout = isComplexLayout(charsBuffer, 0, length);
}
}
if (needsTextLayout) {
TextLayout layout = createTextLayout(c, text, g2.getFont(),
g2.getFontRenderContext());
layout.draw(g2, x, y);
} else {
g.drawString(text, x, y);
}
if (oldAAValue != null) { if (oldAAValue != null) {
g2.setRenderingHint(KEY_TEXT_ANTIALIASING, oldAAValue); g2.setRenderingHint(KEY_TEXT_ANTIALIASING, oldAAValue);
@ -547,11 +590,7 @@ public class SwingUtilities2 {
boolean needsTextLayout = isPrinting; boolean needsTextLayout = isPrinting;
if (!needsTextLayout) { if (!needsTextLayout) {
synchronized (charsBufferLock) { synchronized (charsBufferLock) {
if (charsBuffer == null || charsBuffer.length < textLength) { syncCharsBuffer(text);
charsBuffer = text.toCharArray();
} else {
text.getChars(0, textLength, charsBuffer, 0);
}
needsTextLayout = needsTextLayout =
isComplexLayout(charsBuffer, 0, textLength); isComplexLayout(charsBuffer, 0, textLength);
} }
@ -567,7 +606,7 @@ public class SwingUtilities2 {
Graphics2D g2d = getGraphics2D(g); Graphics2D g2d = getGraphics2D(g);
if (g2d != null) { if (g2d != null) {
TextLayout layout = TextLayout layout =
new TextLayout(text, g2d.getFont(), createTextLayout(c, text, g2d.getFont(),
g2d.getFontRenderContext()); g2d.getFontRenderContext());
if (isPrinting) { if (isPrinting) {
float screenWidth = (float)g2d.getFont(). float screenWidth = (float)g2d.getFont().
@ -728,7 +767,7 @@ public class SwingUtilities2 {
!isFontRenderContextPrintCompatible !isFontRenderContextPrintCompatible
(deviceFontRenderContext, frc)) { (deviceFontRenderContext, frc)) {
TextLayout layout = TextLayout layout =
new TextLayout(new String(data,offset,length), createTextLayout(c, new String(data, offset, length),
g2d.getFont(), g2d.getFont(),
deviceFontRenderContext); deviceFontRenderContext);
float screenWidth = (float)g2d.getFont(). float screenWidth = (float)g2d.getFont().
@ -846,6 +885,20 @@ public class SwingUtilities2 {
return retVal; return retVal;
} }
private static TextLayout createTextLayout(JComponent c, String s,
Font f, FontRenderContext frc) {
Object shaper = (c == null ?
null : c.getClientProperty(TextAttribute.NUMERIC_SHAPING));
if (shaper == null) {
return new TextLayout(s, f, frc);
} else {
Map<TextAttribute, Object> a = new HashMap<TextAttribute, Object>();
a.put(TextAttribute.FONT, f);
a.put(TextAttribute.NUMERIC_SHAPING, shaper);
return new TextLayout(s, a, frc);
}
}
/* /*
* Checks if two given FontRenderContexts are compatible for printing. * Checks if two given FontRenderContexts are compatible for printing.
* We can't just use equals as we want to exclude from the comparison : * We can't just use equals as we want to exclude from the comparison :

View File

@ -922,7 +922,7 @@ final class Win32ShellFolder2 extends ShellFolder {
// Dispose the HICON // Dispose the HICON
private static native void disposeIcon(long hIcon); private static native void disposeIcon(long hIcon);
public static native int[] getFileChooserBitmapBits(); static native int[] getStandardViewButton0(int iconIndex);
// Should be called from the COM thread // Should be called from the COM thread
private long getIShellIcon() { private long getIShellIcon() {
@ -933,34 +933,6 @@ final class Win32ShellFolder2 extends ShellFolder {
return pIShellIcon; return pIShellIcon;
} }
static int[] fileChooserBitmapBits = null;
static Image[] fileChooserIcons = new Image[47];
static Image getFileChooserIcon(int i) {
if (fileChooserIcons[i] != null) {
return fileChooserIcons[i];
} else {
if (fileChooserBitmapBits == null) {
fileChooserBitmapBits = getFileChooserBitmapBits();
}
if (fileChooserBitmapBits != null) {
int nImages = fileChooserBitmapBits.length / (16*16);
int[] bitmapBits = new int[16 * 16];
for (int y = 0; y < 16; y++) {
for (int x = 0; x < 16; x++) {
bitmapBits[y * 16 + x] = fileChooserBitmapBits[y * (nImages * 16) + (i * 16) + x];
}
}
BufferedImage img = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
img.setRGB(0, 0, 16, 16, bitmapBits, 0, 16);
fileChooserIcons[i] = img;
}
}
return fileChooserIcons[i];
}
private static Image makeIcon(long hIcon, boolean getLargeIcon) { private static Image makeIcon(long hIcon, boolean getLargeIcon) {
if (hIcon != 0L && hIcon != -1L) { if (hIcon != 0L && hIcon != -1L) {
// Get the bits. This has the side effect of setting the imageHash value for this object. // Get the bits. This has the side effect of setting the imageHash value for this object.

View File

@ -25,7 +25,8 @@
package sun.awt.shell; package sun.awt.shell;
import java.awt.Toolkit; import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
@ -33,6 +34,7 @@ import java.io.IOException;
import java.security.AccessController; import java.security.AccessController;
import java.security.PrivilegedAction; import java.security.PrivilegedAction;
import java.util.*; import java.util.*;
import java.util.List;
import java.util.concurrent.*; import java.util.concurrent.*;
import sun.security.action.LoadLibraryAction; import sun.security.action.LoadLibraryAction;
@ -98,6 +100,29 @@ public class Win32ShellFolderManager2 extends ShellFolderManager {
return parent; return parent;
} }
private static final int VIEW_LIST = 2;
private static final int VIEW_DETAILS = 3;
private static final int VIEW_PARENTFOLDER = 8;
private static final int VIEW_NEWFOLDER = 11;
private static final Image[] STANDARD_VIEW_BUTTONS = new Image[12];
private static Image getStandardViewButton(int iconIndex) {
Image result = STANDARD_VIEW_BUTTONS[iconIndex];
if (result != null) {
return result;
}
BufferedImage img = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
img.setRGB(0, 0, 16, 16, Win32ShellFolder2.getStandardViewButton0(iconIndex), 0, 16);
STANDARD_VIEW_BUTTONS[iconIndex] = img;
return img;
}
// Special folders // Special folders
private static Win32ShellFolder2 desktop; private static Win32ShellFolder2 desktop;
private static Win32ShellFolder2 drives; private static Win32ShellFolder2 drives;
@ -105,12 +130,6 @@ public class Win32ShellFolderManager2 extends ShellFolderManager {
private static Win32ShellFolder2 network; private static Win32ShellFolder2 network;
private static Win32ShellFolder2 personal; private static Win32ShellFolder2 personal;
private static final boolean USE_SHELL32_ICONS = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
public Boolean run() {
return OSInfo.getWindowsVersion().compareTo(OSInfo.WINDOWS_XP) >= 0;
}
});
static Win32ShellFolder2 getDesktop() { static Win32ShellFolder2 getDesktop() {
if (desktop == null) { if (desktop == null) {
try { try {
@ -206,9 +225,9 @@ public class Win32ShellFolderManager2 extends ShellFolderManager {
* folders, such as Desktop, Documents, History, Network, Home, etc. * folders, such as Desktop, Documents, History, Network, Home, etc.
* This is used in the shortcut panel of the filechooser on Windows 2000 * This is used in the shortcut panel of the filechooser on Windows 2000
* and Windows Me. * and Windows Me.
* "fileChooserIcon nn": * "fileChooserIcon <icon>":
* Returns an <code>Image</code> - icon nn from resource 216 in shell32.dll, * Returns an <code>Image</code> - icon can be ListView, DetailsView, UpFolder, NewFolder or
* or if not found there from resource 124 in comctl32.dll (Windows only). * ViewMenu (Windows only).
* "optionPaneIcon iconName": * "optionPaneIcon iconName":
* Returns an <code>Image</code> - icon from the system icon list * Returns an <code>Image</code> - icon from the system icon list
* *
@ -303,26 +322,23 @@ public class Win32ShellFolderManager2 extends ShellFolderManager {
} }
return folders.toArray(new File[folders.size()]); return folders.toArray(new File[folders.size()]);
} else if (key.startsWith("fileChooserIcon ")) { } else if (key.startsWith("fileChooserIcon ")) {
int i = -1; String name = key.substring(key.indexOf(" ") + 1);
String name = key.substring(key.indexOf(" ")+1);
try { int iconIndex;
i = Integer.parseInt(name);
} catch (NumberFormatException ex) { if (name.equals("ListView") || name.equals("ViewMenu")) {
if (name.equals("ListView")) { iconIndex = VIEW_LIST;
i = (USE_SHELL32_ICONS) ? 21 : 2; } else if (name.equals("DetailsView")) {
} else if (name.equals("DetailsView")) { iconIndex = VIEW_DETAILS;
i = (USE_SHELL32_ICONS) ? 23 : 3; } else if (name.equals("UpFolder")) {
} else if (name.equals("UpFolder")) { iconIndex = VIEW_PARENTFOLDER;
i = (USE_SHELL32_ICONS) ? 28 : 8; } else if (name.equals("NewFolder")) {
} else if (name.equals("NewFolder")) { iconIndex = VIEW_NEWFOLDER;
i = (USE_SHELL32_ICONS) ? 31 : 11; } else {
} else if (name.equals("ViewMenu")) { return null;
i = (USE_SHELL32_ICONS) ? 21 : 2;
}
}
if (i >= 0) {
return Win32ShellFolder2.getFileChooserIcon(i);
} }
return getStandardViewButton(iconIndex);
} else if (key.startsWith("optionPaneIcon ")) { } else if (key.startsWith("optionPaneIcon ")) {
Win32ShellFolder2.SystemIcon iconType; Win32ShellFolder2.SystemIcon iconType;
if (key == "optionPaneIcon Error") { if (key == "optionPaneIcon Error") {

View File

@ -256,7 +256,6 @@ JNIEXPORT void JNICALL Java_sun_awt_shell_Win32ShellFolderManager2_uninitializeC
static IShellIcon* getIShellIcon(IShellFolder* pIShellFolder) { static IShellIcon* getIShellIcon(IShellFolder* pIShellFolder) {
// http://msdn.microsoft.com/library/en-us/shellcc/platform/Shell/programmersguide/shell_int/shell_int_programming/std_ifaces.asp // http://msdn.microsoft.com/library/en-us/shellcc/platform/Shell/programmersguide/shell_int/shell_int_programming/std_ifaces.asp
HRESULT hres; HRESULT hres;
HICON hIcon = NULL;
IShellIcon* pIShellIcon; IShellIcon* pIShellIcon;
if (pIShellFolder != NULL) { if (pIShellFolder != NULL) {
hres = pIShellFolder->QueryInterface(IID_IShellIcon, (void**)&pIShellIcon); hres = pIShellFolder->QueryInterface(IID_IShellIcon, (void**)&pIShellIcon);
@ -965,89 +964,40 @@ JNIEXPORT jintArray JNICALL Java_sun_awt_shell_Win32ShellFolder2_getIconBits
/* /*
* Class: sun_awt_shell_Win32ShellFolder2 * Class: sun_awt_shell_Win32ShellFolder2
* Method: getFileChooserBitmapBits * Method: getStandardViewButton0
* Signature: ()[I * Signature: (I)[I
*/ */
JNIEXPORT jintArray JNICALL Java_sun_awt_shell_Win32ShellFolder2_getFileChooserBitmapBits JNIEXPORT jintArray JNICALL Java_sun_awt_shell_Win32ShellFolder2_getStandardViewButton0
(JNIEnv* env, jclass cls) (JNIEnv* env, jclass cls, jint iconIndex)
{ {
HBITMAP hBitmap = NULL; jintArray result = NULL;
BITMAP bm;
HINSTANCE libComCtl32;
HINSTANCE libShell32;
libShell32 = LoadLibrary(TEXT("shell32.dll")); // Create a toolbar
if (libShell32 != NULL) { HWND hWndToolbar = ::CreateWindowEx(0, TOOLBARCLASSNAME, NULL,
hBitmap = (HBITMAP)LoadImage(libShell32, 0, 0, 0, 0, 0,
IS_WINVISTA ? TEXT("IDB_TB_SH_DEF_16") : MAKEINTRESOURCE(216), NULL, NULL, NULL, NULL);
IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
if (hBitmap == NULL) { if (hWndToolbar != NULL) {
// version of shell32.dll doesn't match OS version. SendMessage(hWndToolbar, TB_LOADIMAGES, (WPARAM)IDB_VIEW_SMALL_COLOR, (LPARAM)HINST_COMMCTRL);
// So we either are in a Vista Compatibility Mode
// or shell32.dll was copied from OS of another version HIMAGELIST hImageList = (HIMAGELIST) SendMessage(hWndToolbar, TB_GETIMAGELIST, 0, 0);
hBitmap = (HBITMAP)LoadImage(libShell32,
IS_WINVISTA ? MAKEINTRESOURCE(216) : TEXT("IDB_TB_SH_DEF_16"), if (hImageList != NULL) {
IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION); HICON hIcon = ImageList_GetIcon(hImageList, iconIndex, ILD_TRANSPARENT);
if (hIcon != NULL) {
result = Java_sun_awt_shell_Win32ShellFolder2_getIconBits(env, cls, ptr_to_jlong(hIcon), 16);
DestroyIcon(hIcon);
}
ImageList_Destroy(hImageList);
} }
}
if (hBitmap == NULL) { DestroyWindow(hWndToolbar);
libComCtl32 = LoadLibrary(TEXT("comctl32.dll"));
if (libComCtl32 != NULL) {
hBitmap = (HBITMAP)LoadImage(libComCtl32, MAKEINTRESOURCE(124),
IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
}
}
if (hBitmap == NULL) {
return NULL;
} }
GetObject(hBitmap, sizeof(bm), (LPSTR)&bm); return result;
// Get the screen DC
HDC dc = GetDC(NULL);
if (dc == NULL) {
return NULL;
}
// Set up BITMAPINFO
BITMAPINFO bmi;
memset(&bmi, 0, sizeof(BITMAPINFO));
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = bm.bmWidth;
bmi.bmiHeader.biHeight = -bm.bmHeight;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biCompression = BI_RGB;
// Extract the color bitmap
int numPixels = bm.bmWidth * bm.bmHeight;
//long colorBits[192 * 16];
long *colorBits = (long*)safe_Malloc(numPixels * sizeof(long));
if (GetDIBits(dc, hBitmap, 0, bm.bmHeight, colorBits, &bmi, DIB_RGB_COLORS) == 0) {
return NULL;
}
// Release DC
ReleaseDC(NULL, dc);
// The color of the first pixel defines the transparency, according
// to the documentation for LR_LOADTRANSPARENT at
// http://msdn.microsoft.com/library/psdk/winui/resource_9fhi.htm
long transparent = colorBits[0];
for (int i=0; i < numPixels; i++) {
if (colorBits[i] != transparent) {
colorBits[i] |= 0xff000000;
}
}
// Create java array
jintArray bits = env->NewIntArray(numPixels);
// Copy values to java array
env->SetIntArrayRegion(bits, 0, numPixels, colorBits);
// Fix 4745575 GDI Resource Leak
::DeleteObject(hBitmap);
::FreeLibrary(libComCtl32);
return bits;
} }
/* /*

View File

@ -0,0 +1,254 @@
/*
* @test
* @bug 4337267
* @summary test that numeric shaping works in Swing components
* @author Sergey Groznyh
* @run main bug4337267
*/
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.font.NumericShaper;
import java.awt.font.TextAttribute;
import java.awt.image.BufferedImage;
import javax.swing.BoxLayout;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
public class bug4337267 {
TestJPanel p1, p2;
TestBufferedImage i1, i2;
JComponent[] printq;
JFrame window;
static boolean testFailed = false;
static boolean done = false;
String shaped =
"000 (E) 111 (A) \u0641\u0642\u0643 \u0662\u0662\u0662 (E) 333";
String text = "000 (E) 111 (A) \u0641\u0642\u0643 222 (E) 333";
void run() {
initUI();
testTextComponent();
testNonTextComponentHTML();
testNonTextComponentPlain();
doneTask();
}
void initUI() {
window = new JFrame("bug4337267");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setSize(800, 600);
Component content = createContentPane();
window.add(content);
window.setVisible(true);
}
Runnable printComponents = new Runnable() {
public void run() {
printComponent(printq[0], i1);
printComponent(printq[1], i2);
}
};
Runnable compareRasters = new Runnable() {
public void run() {
assertEquals(p1.image, p2.image);
assertEquals(i1, i2);
}
};
void doneTask() {
final Object monitor = this;
SwingUtilities.invokeLater(new Runnable() {
public void run() {
done = true;
synchronized(monitor) {
monitor.notify();
}
}
});
}
void fail(String message) {
testFailed = true;
throw new RuntimeException(message);
}
void assertEquals(Object o1, Object o2) {
if ((o1 == null) && (o2 != null)) {
fail("Expected null, got " + o2);
} else if ((o1 != null) && (o2 == null)) {
fail("Expected " + o1 + ", got null");
} else if (!o1.equals(o2)) {
fail("Expected " + o1 + ", got " + o2);
}
}
void testTextComponent() {
System.out.println("testTextComponent:");
JTextArea area1 = new JTextArea();
injectComponent(p1, area1, false);
area1.setText(shaped);
JTextArea area2 = new JTextArea();
injectComponent(p2, area2, true);
area2.setText(text);
window.repaint();
printq = new JComponent[] { area1, area2 };
SwingUtilities.invokeLater(printComponents);
SwingUtilities.invokeLater(compareRasters);
}
void testNonTextComponentHTML() {
System.out.println("testNonTextComponentHTML:");
JLabel label1 = new JLabel();
injectComponent(p1, label1, false);
label1.setText("<html>" + shaped);
JLabel label2 = new JLabel();
injectComponent(p2, label2, true);
label2.setText("<html>" + text);
window.repaint();
printq = new JComponent[] { label1, label2 };
SwingUtilities.invokeLater(printComponents);
SwingUtilities.invokeLater(compareRasters);
}
void testNonTextComponentPlain() {
System.out.println("testNonTextComponentHTML:");
JLabel label1 = new JLabel();
injectComponent(p1, label1, false);
label1.setText(shaped);
JLabel label2 = new JLabel();
injectComponent(p2, label2, true);
label2.setText(text);
window.repaint();
printq = new JComponent[] { label1, label2 };
SwingUtilities.invokeLater(printComponents);
SwingUtilities.invokeLater(compareRasters);
}
void setShaping(JComponent c) {
c.putClientProperty(TextAttribute.NUMERIC_SHAPING,
NumericShaper.getContextualShaper(NumericShaper.ARABIC));
}
void injectComponent(JComponent p, JComponent c, boolean shape) {
if (shape) {
setShaping(c);
}
p.removeAll();
p.add(c);
}
void printComponent(JComponent c, TestBufferedImage i) {
Graphics g = i.getGraphics();
g.setColor(c.getBackground());
g.fillRect(0, 0, i.getWidth(), i.getHeight());
c.print(g);
}
Component createContentPane() {
Dimension size = new Dimension(500, 100);
i1 = new TestBufferedImage(size.width, size.height,
BufferedImage.TYPE_INT_ARGB);
i2 = new TestBufferedImage(size.width, size.height,
BufferedImage.TYPE_INT_ARGB);
p1 = new TestJPanel();
p1.setPreferredSize(size);
p2 = new TestJPanel();
p2.setPreferredSize(size);
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.add(p1);
panel.add(p2);
return panel;
}
static class TestBufferedImage extends BufferedImage {
int MAX_GLITCHES = 0;
TestBufferedImage(int width, int height, int imageType) {
super(width, height, imageType);
}
@Override
public boolean equals(Object other) {
if (! (other instanceof TestBufferedImage)) {
return false;
}
TestBufferedImage image2 = (TestBufferedImage) other;
int width = getWidth();
int height = getHeight();
if ((image2.getWidth() != width) || (image2.getHeight() != height)) {
return false;
}
int glitches = 0;
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
int rgb1 = getRGB(x, y);
int rgb2 = image2.getRGB(x, y);
if (rgb1 != rgb2) {
//System.out.println(x+" "+y+" "+rgb1+" "+rgb2);
glitches++;
}
}
}
return glitches <= MAX_GLITCHES;
}
}
static class TestJPanel extends JPanel {
TestBufferedImage image = createImage(new Dimension(1, 1));
TestBufferedImage createImage(Dimension d) {
return new TestBufferedImage(d.width, d.height,
BufferedImage.TYPE_INT_ARGB);
}
public void setPreferredSize(Dimension size) {
super.setPreferredSize(size);
image = createImage(size);
}
public void paint(Graphics g) {
Graphics g0 = image.getGraphics();
super.paint(g0);
g.drawImage(image, 0, 0, this);
}
}
public static void main(String[] args) throws Throwable {
final bug4337267 test = new bug4337267();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
test.run();
}
});
synchronized(test) {
while (!done) {
try {
test.wait();
} catch (InterruptedException ex) {
// do nothing
}
}
}
if (testFailed) {
throw new RuntimeException("FAIL");
}
System.out.println("OK");
}
}

View File

@ -0,0 +1,96 @@
/*
* Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/* @test
* @bug 6489130
* @summary FileChooserDemo hung by keeping pressing Enter key
* @author Pavel Porvatov
@run main bug6489130
*/
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
public class bug6489130 {
private final JFileChooser chooser = new JFileChooser();
private static final CountDownLatch MUX = new CountDownLatch(1);
private final Timer timer = new Timer(1000, new ActionListener() {
public void actionPerformed(ActionEvent e) {
switch (state) {
case 0:
case 1: {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
chooser.showOpenDialog(null);
}
});
break;
}
case 2:
case 3: {
Window[] windows = Frame.getWindows();
if (windows.length > 0) {
windows[0].dispose();
}
break;
}
case 4: {
MUX.countDown();
break;
}
}
state++;
}
});
private int state = 0;
public static void main(String[] args) throws InterruptedException {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new bug6489130().run();
}
});
if (!MUX.await(10, TimeUnit.SECONDS)) {
throw new RuntimeException("Timeout");
}
}
private void run() {
timer.start();
}
}

View File

@ -0,0 +1,66 @@
/*
* Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/* @test
@bug 6840086
@summary JFileChooser lacks icons on top right when running on Windows 7
@author Pavel Porvatov
@run main bug6840086
*/
import sun.awt.OSInfo;
import sun.awt.shell.ShellFolder;
import java.awt.*;
public class bug6840086 {
private static final String[] KEYS = {
"fileChooserIcon ListView",
"fileChooserIcon ViewMenu",
"fileChooserIcon DetailsView",
"fileChooserIcon UpFolder",
"fileChooserIcon NewFolder",
};
public static void main(String[] args) {
if (OSInfo.getOSType() != OSInfo.OSType.WINDOWS) {
System.out.println("The test was skipped because it is sensible only for Windows.");
return;
}
for (String key : KEYS) {
Image image = (Image) ShellFolder.get(key);
if (image == null) {
throw new RuntimeException("The image '" + key + "' not found.");
}
if (image != ShellFolder.get(key)) {
throw new RuntimeException("The image '" + key + "' is not cached.");
}
}
System.out.println("The test passed.");
}
}

View File

@ -0,0 +1,46 @@
/*
* Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/* @test
* @bug 6875716
* @summary JLayer.remove((Component)null) should behave consistently in (not) throwing NPE
* @author Alexander Potochkin
*/
import javax.swing.*;
import java.awt.*;
public class bug6875716 {
public static void main(String[] args) throws Exception {
JLayer<Component> layer = new JLayer<Component>(new Component(){});
layer.setGlassPane(null);
try {
layer.remove((Component)null);
} catch (NullPointerException e) {
//this is what we expect
return;
}
throw new RuntimeException("Test failed");
}
}

View File

@ -0,0 +1,50 @@
/*
* Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
* @test
* @bug 6883341
* @summary Checks that menu items with no text don't throw an exception
* @author Alexander Potochkin
* @run main bug6883341
*/
import javax.swing.*;
public class bug6883341 {
private static void createGui() {
JPopupMenu menu = new JPopupMenu();
menu.add(new JMenuItem());
menu.setVisible(true);
menu.setVisible(false);
}
public static void main(String[] args) throws Exception {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
bug6883341.createGui();
}
});
}
}