From: <ls...@us...> - 2006-12-09 18:47:59
|
Revision: 2883 http://jnode.svn.sourceforge.net/jnode/?rev=2883&view=rev Author: lsantha Date: 2006-12-09 10:47:57 -0800 (Sat, 09 Dec 2006) Log Message: ----------- Classpath patches. Modified Paths: -------------- trunk/core/src/classpath/javax/javax/swing/JEditorPane.java trunk/core/src/classpath/javax/javax/swing/JTextField.java trunk/core/src/classpath/javax/javax/swing/plaf/basic/BasicHTML.java trunk/core/src/classpath/javax/javax/swing/plaf/basic/BasicTextUI.java Modified: trunk/core/src/classpath/javax/javax/swing/JEditorPane.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/JEditorPane.java 2006-12-09 18:47:15 UTC (rev 2882) +++ trunk/core/src/classpath/javax/javax/swing/JEditorPane.java 2006-12-09 18:47:57 UTC (rev 2883) @@ -40,6 +40,8 @@ import java.awt.Container; import java.awt.Dimension; +import java.io.BufferedInputStream; +import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -47,6 +49,7 @@ import java.io.StringReader; import java.net.MalformedURLException; import java.net.URL; +import java.net.URLConnection; import java.util.HashMap; import javax.accessibility.AccessibleContext; @@ -56,6 +59,8 @@ import javax.accessibility.AccessibleText; import javax.swing.event.HyperlinkEvent; import javax.swing.event.HyperlinkListener; +import javax.swing.plaf.TextUI; +import javax.swing.text.AbstractDocument; import javax.swing.text.BadLocationException; import javax.swing.text.DefaultEditorKit; import javax.swing.text.Document; @@ -482,6 +487,34 @@ } /** + * Used to store a mapping for content-type to editor kit class. + */ + private static class EditorKitMapping + { + /** + * The classname of the editor kit. + */ + String className; + + /** + * The classloader with which the kit is to be loaded. + */ + ClassLoader classLoader; + + /** + * Creates a new EditorKitMapping object. + * + * @param cn the classname + * @param cl the classloader + */ + EditorKitMapping(String cn, ClassLoader cl) + { + className = cn; + classLoader = cl; + } + } + + /** * An EditorKit used for plain text. This is the default editor kit for * JEditorPanes. * @@ -505,19 +538,159 @@ } } + /** + * A special stream that can be cancelled. + */ + private class PageStream + extends FilterInputStream + { + /** + * True when the stream has been cancelled, false otherwise. + */ + private boolean cancelled; + + protected PageStream(InputStream in) + { + super(in); + cancelled = false; + } + + private void checkCancelled() + throws IOException + { + if (cancelled) + throw new IOException("Stream has been cancelled"); + } + + void cancel() + { + cancelled = true; + } + + public int read() + throws IOException + { + checkCancelled(); + return super.read(); + } + + public int read(byte[] b, int off, int len) + throws IOException + { + checkCancelled(); + return super.read(b, off, len); + } + + public long skip(long n) + throws IOException + { + checkCancelled(); + return super.skip(n); + } + + public int available() + throws IOException + { + checkCancelled(); + return super.available(); + } + + public void reset() + throws IOException + { + checkCancelled(); + super.reset(); + } + } + + /** + * The thread that loads documents asynchronously. + */ + private class PageLoader + implements Runnable + { + private Document doc; + private PageStream in; + private URL old; + URL page; + PageLoader(Document doc, InputStream in, URL old, URL page) + { + this.doc = doc; + this.in = new PageStream(in); + this.old = old; + this.page = page; + } + + public void run() + { + try + { + read(in, doc); + } + catch (IOException ex) + { + UIManager.getLookAndFeel().provideErrorFeedback(JEditorPane.this); + } + finally + { + if (SwingUtilities.isEventDispatchThread()) + firePropertyChange("page", old, page); + else + { + SwingUtilities.invokeLater(new Runnable() + { + public void run() + { + firePropertyChange("page", old, page); + } + }); + } + } + } + + void cancel() + { + in.cancel(); + } + } + private static final long serialVersionUID = 3140472492599046285L; - private URL page; private EditorKit editorKit; boolean focus_root; + /** + * Maps content-types to editor kit instances. + */ + static HashMap editorKits; + // A mapping between content types and registered EditorKit types static HashMap registerMap; + static + { + registerMap = new HashMap(); + editorKits = new HashMap(); + registerEditorKitForContentType("application/rtf", + "javax.swing.text.rtf.RTFEditorKit"); + registerEditorKitForContentType("text/plain", + "javax.swing.JEditorPane$PlainEditorKit"); + registerEditorKitForContentType("text/html", + "javax.swing.text.html.HTMLEditorKit"); + registerEditorKitForContentType("text/rtf", + "javax.swing.text.rtf.RTFEditorKit"); + + } + // A mapping between content types and used EditorKits HashMap editorMap; + /** + * The currently loading stream, if any. + */ + private PageLoader loader; + public JEditorPane() { init(); @@ -550,15 +723,6 @@ void init() { editorMap = new HashMap(); - registerMap = new HashMap(); - registerEditorKitForContentType("application/rtf", - "javax.swing.text.rtf.RTFEditorKit"); - registerEditorKitForContentType("text/plain", - "javax.swing.JEditorPane$PlainEditorKit"); - registerEditorKitForContentType("text/html", - "javax.swing.text.html.HTMLEditorKit"); - registerEditorKitForContentType("text/rtf", - "javax.swing.text.rtf.RTFEditorKit"); } protected EditorKit createDefaultEditorKit() @@ -578,21 +742,29 @@ */ public static EditorKit createEditorKitForContentType(String type) { - // TODO: Have to handle the case where a ClassLoader was specified - // when the EditorKit was registered - EditorKit e = null; - String className = (String) registerMap.get(type); - if (className != null) + // Try cached instance. + EditorKit e = (EditorKit) editorKits.get(type); + if (e == null) { + EditorKitMapping m = (EditorKitMapping) registerMap.get(type); + if (m != null) + { + String className = m.className; + ClassLoader loader = m.classLoader; try { - e = (EditorKit) Class.forName(className).newInstance(); + e = (EditorKit) loader.loadClass(className).newInstance(); } catch (Exception e2) { - // TODO: Not sure what to do here. + // The reference implementation returns null when class is not + // loadable or instantiatable. } } + // Cache this for later retrieval. + if (e != null) + editorKits.put(type, e); + } return e; } @@ -652,7 +824,9 @@ */ public static String getEditorKitClassNameForContentType(String type) { - return (String) registerMap.get(type); + EditorKitMapping m = (EditorKitMapping) registerMap.get(type); + String kitName = m != null ? m.className : null; + return kitName; } /** @@ -675,10 +849,14 @@ EditorKit e = (EditorKit) editorMap.get(type); // Then check to see if we can create one. if (e == null) + { e = createEditorKitForContentType(type); + if (e != null) + setEditorKitForContentType(type, e); + } // Otherwise default to PlainEditorKit. if (e == null) - e = new PlainEditorKit(); + e = createDefaultEditorKit(); return e; } @@ -695,10 +873,28 @@ public Dimension getPreferredSize() { Dimension pref = super.getPreferredSize(); - if (getScrollableTracksViewportWidth()) - pref.width = getUI().getMinimumSize(this).width; - if (getScrollableTracksViewportHeight()) - pref.height = getUI().getMinimumSize(this).height; + Container parent = getParent(); + if (parent instanceof JViewport) + { + JViewport vp = (JViewport) getParent(); + TextUI ui = getUI(); + Dimension min = null; + if (! getScrollableTracksViewportWidth()) + { + min = ui.getMinimumSize(this); + int vpWidth = vp.getWidth(); + if (vpWidth != 0 && vpWidth < min.width) + pref.width = min.width; + } + if (! getScrollableTracksViewportHeight()) + { + if (min == null) + min = ui.getMinimumSize(this); + int vpHeight = vp.getHeight(); + if (vpHeight != 0 && vpHeight < min.height) + pref.height = min.height; + } + } return pref; } @@ -716,9 +912,11 @@ // Tests show that this returns true when the parent is a JViewport // and has a height > minimum UI height. Container parent = getParent(); + int height = parent.getHeight(); + TextUI ui = getUI(); return parent instanceof JViewport - && parent.getHeight() >= getUI().getMinimumSize(this).height - && parent.getHeight() <= getUI().getMaximumSize(this).height; + && height >= ui.getMinimumSize(this).height + && height <= ui.getMaximumSize(this).height; } /** @@ -741,13 +939,19 @@ public URL getPage() { - return page; + return loader != null ? loader.page : null; } protected InputStream getStream(URL page) throws IOException { - return page.openStream(); + URLConnection conn = page.openConnection(); + // Try to detect the content type of the stream data. + String type = conn.getContentType(); + if (type != null) + setContentType(type); + InputStream stream = conn.getInputStream(); + return new BufferedInputStream(stream); } public String getText() @@ -778,10 +982,12 @@ EditorKit kit = getEditorKit(); if (kit instanceof HTMLEditorKit && desc instanceof HTMLDocument) { - Document doc = (Document) desc; + HTMLDocument doc = (HTMLDocument) desc; + setDocument(doc); try { - kit.read(in, doc, 0); + InputStreamReader reader = new InputStreamReader(in); + kit.read(reader, doc, 0); } catch (BadLocationException ex) { @@ -806,7 +1012,8 @@ public static void registerEditorKitForContentType(String type, String classname) { - registerMap.put(type, classname); + registerEditorKitForContentType(type, classname, + Thread.currentThread().getContextClassLoader()); } /** @@ -816,7 +1023,7 @@ String classname, ClassLoader loader) { - // TODO: Implement this properly. + registerMap.put(type, new EditorKitMapping(classname, loader)); } /** @@ -840,6 +1047,13 @@ public final void setContentType(String type) { + // Strip off content type parameters. + int paramIndex = type.indexOf(';'); + if (paramIndex > -1) + { + // TODO: Handle character encoding. + type = type.substring(0, paramIndex).trim(); + } if (editorKit != null && editorKit.getContentType().equals(type)) return; @@ -900,14 +1114,45 @@ if (page == null) throw new IOException("invalid url"); - try + URL old = getPage(); + // Only reload if the URL doesn't point to the same file. + // This is not the same as equals because there might be different + // URLs on the same file with different anchors. + if (old == null || ! old.sameFile(page)) { - this.page = page; - getEditorKit().read(page.openStream(), getDocument(), 0); + InputStream in = getStream(page); + if (editorKit != null) + { + Document doc = editorKit.createDefaultDocument(); + doc.putProperty(Document.StreamDescriptionProperty, page); + + if (loader != null) + loader.cancel(); + loader = new PageLoader(doc, in, old, page); + + int prio = -1; + if (doc instanceof AbstractDocument) + { + AbstractDocument aDoc = (AbstractDocument) doc; + prio = aDoc.getAsynchronousLoadPriority(); + } + if (prio >= 0) + { + // Load asynchronously. + setDocument(doc); + Thread loadThread = new Thread(loader, + "JEditorPane.PageLoader"); + loadThread.setDaemon(true); + loadThread.setPriority(prio); + loadThread.start(); } - catch (BadLocationException e) + else { - // Ignored. '0' is always a valid offset. + // Load synchronously. + loader.run(); + setDocument(doc); + } + } } } Modified: trunk/core/src/classpath/javax/javax/swing/JTextField.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/JTextField.java 2006-12-09 18:47:15 UTC (rev 2882) +++ trunk/core/src/classpath/javax/javax/swing/JTextField.java 2006-12-09 18:47:57 UTC (rev 2883) @@ -270,7 +270,8 @@ */ protected void fireActionPerformed() { - ActionEvent event = new ActionEvent(this, 0, getText()); + ActionEvent event = new ActionEvent(this, 0, + actionCommand == null ? getText() : actionCommand); ActionListener[] listeners = getActionListeners(); for (int index = 0; index < listeners.length; ++index) Modified: trunk/core/src/classpath/javax/javax/swing/plaf/basic/BasicHTML.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/plaf/basic/BasicHTML.java 2006-12-09 18:47:15 UTC (rev 2882) +++ trunk/core/src/classpath/javax/javax/swing/plaf/basic/BasicHTML.java 2006-12-09 18:47:57 UTC (rev 2883) @@ -48,6 +48,7 @@ import javax.swing.JComponent; import javax.swing.SwingConstants; import javax.swing.event.DocumentEvent; +import javax.swing.text.AttributeSet; import javax.swing.text.BadLocationException; import javax.swing.text.Document; import javax.swing.text.EditorKit; @@ -355,6 +356,22 @@ { return document; } + + /** + * Overridden to return null, as a RootView has no attributes on its own. + */ + public AttributeSet getAttributes() + { + return null; + } + + /** + * Overridden to provide an element for the view. + */ + public Element getElement() + { + return view.getElement(); + } } /** Modified: trunk/core/src/classpath/javax/javax/swing/plaf/basic/BasicTextUI.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/plaf/basic/BasicTextUI.java 2006-12-09 18:47:15 UTC (rev 2882) +++ trunk/core/src/classpath/javax/javax/swing/plaf/basic/BasicTextUI.java 2006-12-09 18:47:57 UTC (rev 2883) @@ -38,6 +38,8 @@ package javax.swing.plaf.basic; +import gnu.classpath.SystemProperties; + import java.awt.Color; import java.awt.Container; import java.awt.Dimension; @@ -121,7 +123,141 @@ } } + private static class FocusHandler + implements FocusListener + { + public void focusGained(FocusEvent e) + { + // Nothing to do here. + } + public void focusLost(FocusEvent e) + { + JTextComponent textComponent = (JTextComponent) e.getComponent(); + // Integrates Swing text components with the system clipboard: + // The idea is that if one wants to copy text around X11-style + // (select text and middle-click in the target component) the focus + // will move to the new component which gives the old focus owner the + // possibility to paste its selection into the clipboard. + if (!e.isTemporary() + && textComponent.getSelectionStart() + != textComponent.getSelectionEnd()) + { + SecurityManager sm = System.getSecurityManager(); + try + { + if (sm != null) + sm.checkSystemClipboardAccess(); + + Clipboard cb = Toolkit.getDefaultToolkit().getSystemSelection(); + if (cb != null) + { + StringSelection selection = new StringSelection( + textComponent.getSelectedText()); + cb.setContents(selection, selection); + } + } + catch (SecurityException se) + { + // Not allowed to access the clipboard: Ignore and + // do not access it. + } + catch (HeadlessException he) + { + // There is no AWT: Ignore and do not access the + // clipboard. + } + catch (IllegalStateException ise) + { + // Clipboard is currently unavaible. + } + } + } + } + /** + * This FocusListener triggers repaints on focus shift. + */ + private static FocusListener focusListener; + + /** + * Receives notifications when properties of the text component change. + */ + private class Handler + implements PropertyChangeListener, DocumentListener + { + /** + * Notifies when a property of the text component changes. + * + * @param event the PropertyChangeEvent describing the change + */ + public void propertyChange(PropertyChangeEvent event) + { + if (event.getPropertyName().equals("document")) + { + // Document changed. + Object oldValue = event.getOldValue(); + if (oldValue != null) + { + Document oldDoc = (Document) oldValue; + oldDoc.removeDocumentListener(handler); + } + Object newValue = event.getNewValue(); + if (newValue != null) + { + Document newDoc = (Document) newValue; + newDoc.addDocumentListener(handler); + } + modelChanged(); + } + + BasicTextUI.this.propertyChange(event); + } + + /** + * Notification about a document change event. + * + * @param ev the DocumentEvent describing the change + */ + public void changedUpdate(DocumentEvent ev) + { + // Updates are forwarded to the View even if 'getVisibleEditorRect' + // method returns null. This means the View classes have to be + // aware of that possibility. + rootView.changedUpdate(ev, getVisibleEditorRect(), + rootView.getViewFactory()); + } + + /** + * Notification about a document insert event. + * + * @param ev the DocumentEvent describing the insertion + */ + public void insertUpdate(DocumentEvent ev) + { + // Updates are forwarded to the View even if 'getVisibleEditorRect' + // method returns null. This means the View classes have to be + // aware of that possibility. + rootView.insertUpdate(ev, getVisibleEditorRect(), + rootView.getViewFactory()); + } + + /** + * Notification about a document removal event. + * + * @param ev the DocumentEvent describing the removal + */ + public void removeUpdate(DocumentEvent ev) + { + // Updates are forwarded to the View even if 'getVisibleEditorRect' + // method returns null. This means the View classes have to be + // aware of that possibility. + rootView.removeUpdate(ev, getVisibleEditorRect(), + rootView.getViewFactory()); + } + + } + + /** * This view forms the root of the View hierarchy. However, it delegates * most calls to another View which is the real root of the hierarchy. * The purpose is to make sure that all Views in the hierarchy, including @@ -227,24 +363,13 @@ } /** - * Returns the preferred span along the specified <code>axis</code>. - * This is delegated to the real root view. - * - * @param axis the axis for which the preferred span is queried - * - * @return the preferred span along the axis + * Sets the size of the renderer. This is synchronized because that + * potentially triggers layout and we don't want more than one thread + * playing with the layout information. */ - public float getPreferredSpan(int axis) + public synchronized void setSize(float w, float h) { if (view != null) - return view.getPreferredSpan(axis); - - return Integer.MAX_VALUE; - } - - public void setSize(float w, float h) - { - if (view != null) view.setSize(w, h); } @@ -258,8 +383,8 @@ { if (view != null) { - Rectangle b = s.getBounds(); - view.setSize(b.width, b.height); + Rectangle b = s instanceof Rectangle ? (Rectangle) s : s.getBounds(); + setSize(b.width, b.height); view.paint(g, s); } } @@ -319,6 +444,7 @@ */ public void insertUpdate(DocumentEvent ev, Shape shape, ViewFactory vf) { + if (view != null) view.insertUpdate(ev, shape, vf); } @@ -332,6 +458,7 @@ */ public void removeUpdate(DocumentEvent ev, Shape shape, ViewFactory vf) { + if (view != null) view.removeUpdate(ev, shape, vf); } @@ -345,6 +472,7 @@ */ public void changedUpdate(DocumentEvent ev, Shape shape, ViewFactory vf) { + if (view != null) view.changedUpdate(ev, shape, vf); } @@ -415,103 +543,60 @@ { return null; } - } /** - * Receives notifications when properties of the text component change. - */ - private class PropertyChangeHandler implements PropertyChangeListener - { - /** - * Notifies when a property of the text component changes. - * - * @param event the PropertyChangeEvent describing the change + * Overridden to forward to the view. */ - public void propertyChange(PropertyChangeEvent event) - { - if (event.getPropertyName().equals("document")) - { - // Document changed. - Object oldValue = event.getOldValue(); - if (oldValue != null) + public float getPreferredSpan(int axis) { - Document oldDoc = (Document) oldValue; - oldDoc.removeDocumentListener(documentHandler); - } - Object newValue = event.getNewValue(); - if (newValue != null) - { - Document newDoc = (Document) newValue; - newDoc.addDocumentListener(documentHandler); - } - modelChanged(); - } - - BasicTextUI.this.propertyChange(event); - } + // The RI returns 10 in the degenerate case. + float span = 10; + if (view != null) + span = view.getPreferredSpan(axis); + return span; } /** - * Listens for changes on the underlying model and forwards notifications - * to the View. This also updates the caret position of the text component. - * - * TODO: Maybe this should somehow be handled through EditorKits + * Overridden to forward to the real view. */ - class DocumentHandler implements DocumentListener - { - /** - * Notification about a document change event. - * - * @param ev the DocumentEvent describing the change - */ - public void changedUpdate(DocumentEvent ev) + public float getMinimumSpan(int axis) { - // Updates are forwarded to the View even if 'getVisibleEditorRect' - // method returns null. This means the View classes have to be - // aware of that possibility. - rootView.changedUpdate(ev, getVisibleEditorRect(), - rootView.getViewFactory()); + // The RI returns 10 in the degenerate case. + float span = 10; + if (view != null) + span = view.getMinimumSpan(axis); + return span; } /** - * Notification about a document insert event. - * - * @param ev the DocumentEvent describing the insertion + * Overridden to return Integer.MAX_VALUE. */ - public void insertUpdate(DocumentEvent ev) + public float getMaximumSpan(int axis) { - // Updates are forwarded to the View even if 'getVisibleEditorRect' - // method returns null. This means the View classes have to be - // aware of that possibility. - rootView.insertUpdate(ev, getVisibleEditorRect(), - rootView.getViewFactory()); + // The RI returns Integer.MAX_VALUE here, regardless of the real view's + // maximum size. + return Integer.MAX_VALUE; } + } /** - * Notification about a document removal event. - * - * @param ev the DocumentEvent describing the removal + * The EditorKit used by this TextUI. */ - public void removeUpdate(DocumentEvent ev) - { - // Updates are forwarded to the View even if 'getVisibleEditorRect' - // method returns null. This means the View classes have to be - // aware of that possibility. - rootView.removeUpdate(ev, getVisibleEditorRect(), - rootView.getViewFactory()); - } - } + private static EditorKit kit; /** - * The EditorKit used by this TextUI. + * The combined event handler for text components. + * + * This is package private to avoid accessor methods. */ - // FIXME: should probably be non-static. - static EditorKit kit = new DefaultEditorKit(); + Handler handler; /** * The root view. + * + * This is package private to avoid accessor methods. */ - RootView rootView = new RootView(); + RootView rootView; /** * The text component that we handle. @@ -519,14 +604,6 @@ JTextComponent textComponent; /** - * Receives notification when the model changes. - */ - private PropertyChangeHandler updateHandler = new PropertyChangeHandler(); - - /** The DocumentEvent handler. */ - DocumentHandler documentHandler = new DocumentHandler(); - - /** * Creates a new <code>BasicTextUI</code> instance. */ public BasicTextUI() @@ -573,17 +650,31 @@ public void installUI(final JComponent c) { textComponent = (JTextComponent) c; + + if (rootView == null) + rootView = new RootView(); + installDefaults(); - textComponent.addPropertyChangeListener(updateHandler); + installFixedDefaults(); + + // These listeners must be installed outside of installListeners(), + // because overriding installListeners() doesn't prevent installing + // these in the RI, but overriding isntallUI() does. + if (handler == null) + handler = new Handler(); + textComponent.addPropertyChangeListener(handler); Document doc = textComponent.getDocument(); if (doc == null) { + // The Handler takes care of installing the necessary listeners + // on the document here. doc = getEditorKit(textComponent).createDefaultDocument(); textComponent.setDocument(doc); } else { - doc.addDocumentListener(documentHandler); + // Must install the document listener. + doc.addDocumentListener(handler); modelChanged(); } @@ -601,7 +692,6 @@ LookAndFeel.installColorsAndFont(textComponent, prefix + ".background", prefix + ".foreground", prefix + ".font"); LookAndFeel.installBorder(textComponent, prefix + ".border"); - textComponent.setMargin(UIManager.getInsets(prefix + ".margin")); // Some additional text component only properties. Color color = textComponent.getCaretColor(); @@ -615,7 +705,7 @@ color = textComponent.getDisabledTextColor(); if (color == null || color instanceof UIResource) { - color = UIManager.getColor(prefix + ".inactiveBackground"); + color = UIManager.getColor(prefix + ".inactiveForeground"); textComponent.setDisabledTextColor(color); } color = textComponent.getSelectedTextColor(); @@ -638,6 +728,15 @@ textComponent.setMargin(margin); } + } + + /** + * Installs defaults that can't be overridden by overriding + * installDefaults(). + */ + private void installFixedDefaults() + { + String prefix = getPropertyPrefix(); Caret caret = textComponent.getCaret(); if (caret == null || caret instanceof UIResource) { @@ -653,64 +752,18 @@ } /** - * This FocusListener triggers repaints on focus shift. - */ - private FocusListener focuslistener = new FocusListener() { - public void focusGained(FocusEvent e) - { - textComponent.repaint(); - } - public void focusLost(FocusEvent e) - { - textComponent.repaint(); - - // Integrates Swing text components with the system clipboard: - // The idea is that if one wants to copy text around X11-style - // (select text and middle-click in the target component) the focus - // will move to the new component which gives the old focus owner the - // possibility to paste its selection into the clipboard. - if (!e.isTemporary() - && textComponent.getSelectionStart() - != textComponent.getSelectionEnd()) - { - SecurityManager sm = System.getSecurityManager(); - try - { - if (sm != null) - sm.checkSystemClipboardAccess(); - - Clipboard cb = Toolkit.getDefaultToolkit().getSystemSelection(); - if (cb != null) - { - StringSelection selection = new StringSelection( - textComponent.getSelectedText()); - cb.setContents(selection, selection); - } - } - catch (SecurityException se) - { - // Not allowed to access the clipboard: Ignore and - // do not access it. - } - catch (HeadlessException he) - { - // There is no AWT: Ignore and do not access the - // clipboard. - } - catch (IllegalStateException ise) - { - // Clipboard is currently unavaible. - } - } - } - }; - - /** * Install all listeners on the text component. */ protected void installListeners() { - textComponent.addFocusListener(focuslistener); + // + if (SystemProperties.getProperty("gnu.swing.text.no-xlike-clipboard") + == null) + { + if (focusListener == null) + focusListener = new FocusHandler(); + textComponent.addFocusListener(focusListener); + } } /** @@ -849,10 +902,12 @@ */ public void uninstallUI(final JComponent component) { - super.uninstallUI(component); + textComponent.removePropertyChangeListener(handler); + textComponent.getDocument().removeDocumentListener(handler); rootView.setView(null); uninstallDefaults(); + uninstallFixedDefaults(); uninstallListeners(); uninstallKeyboardActions(); @@ -865,17 +920,41 @@ */ protected void uninstallDefaults() { - // Do nothing here. + if (textComponent.getCaretColor() instanceof UIResource) + textComponent.setCaretColor(null); + if (textComponent.getSelectionColor() instanceof UIResource) + textComponent.setSelectionColor(null); + if (textComponent.getDisabledTextColor() instanceof UIResource) + textComponent.setDisabledTextColor(null); + if (textComponent.getSelectedTextColor() instanceof UIResource) + textComponent.setSelectedTextColor(null); + LookAndFeel.uninstallBorder(textComponent); + if (textComponent.getMargin() instanceof UIResource) + textComponent.setMargin(null); } /** + * Uninstalls additional fixed defaults that were installed + * by installFixedDefaults(). + */ + private void uninstallFixedDefaults() + { + if (textComponent.getCaret() instanceof UIResource) + textComponent.setCaret(null); + if (textComponent.getHighlighter() instanceof UIResource) + textComponent.setHighlighter(null); + } + + /** * Uninstalls all listeners that have previously been installed by * this UI. */ protected void uninstallListeners() { - textComponent.removeFocusListener(focuslistener); - textComponent.getDocument().removeDocumentListener(documentHandler); + // Don't nullify the focusListener field, as it is static and shared + // between components. + if (focusListener != null) + textComponent.removeFocusListener(focusListener); } /** @@ -909,14 +988,33 @@ { Dimension d = c.getSize(); Insets i = c.getInsets(); + // We need to lock here, since we require the view hierarchy to _not_ + // change in between. + float w; + float h; + Document doc = textComponent.getDocument(); + if (doc instanceof AbstractDocument) + ((AbstractDocument) doc).readLock(); + try + { if (d.width > (i.left + i.right) && d.height > (i.top + i.bottom)) { rootView.setSize(d.width - i.left - i.right, d.height - i.top - i.bottom); } - float w = rootView.getPreferredSpan(View.X_AXIS); - float h = rootView.getPreferredSpan(View.Y_AXIS); - + else + { + // Not laid out yet. Force some pseudo size. + rootView.setSize(Integer.MAX_VALUE, Integer.MAX_VALUE); + } + w = rootView.getPreferredSpan(View.X_AXIS); + h = rootView.getPreferredSpan(View.Y_AXIS); + } + finally + { + if (doc instanceof AbstractDocument) + ((AbstractDocument) doc).readUnlock(); + } Dimension size = new Dimension((int) w + i.left + i.right, (int) h + i.top + i.bottom); return size; @@ -933,8 +1031,27 @@ */ public Dimension getMaximumSize(JComponent c) { - // Sun's implementation returns Integer.MAX_VALUE here, so do we. - return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); + Dimension d = new Dimension(); + Insets i = c.getInsets(); + Document doc = textComponent.getDocument(); + // We need to lock here, since we require the view hierarchy to _not_ + // change in between. + if (doc instanceof AbstractDocument) + ((AbstractDocument) doc).readLock(); + try + { + // Check for overflow here. + d.width = (int) Math.min((long) rootView.getMaximumSpan(View.X_AXIS) + + i.left + i.right, Integer.MAX_VALUE); + d.height = (int) Math.min((long) rootView.getMaximumSpan(View.Y_AXIS) + + i.top + i.bottom, Integer.MAX_VALUE); + } + finally + { + if (doc instanceof AbstractDocument) + ((AbstractDocument) doc).readUnlock(); + } + return d; } /** @@ -945,8 +1062,26 @@ */ public Dimension getMinimumSize(JComponent c) { + Dimension d = new Dimension(); + Document doc = textComponent.getDocument(); + // We need to lock here, since we require the view hierarchy to _not_ + // change in between. + if (doc instanceof AbstractDocument) + ((AbstractDocument) doc).readLock(); + try + { + d.width = (int) rootView.getMinimumSpan(View.X_AXIS); + d.height = (int) rootView.getMinimumSpan(View.Y_AXIS); + } + finally + { + if (doc instanceof AbstractDocument) + ((AbstractDocument) doc).readUnlock(); + } Insets i = c.getInsets(); - return new Dimension(i.left + i.right, i.top + i.bottom); + d.width += i.left + i.right; + d.height += i.top + i.bottom; + return d; } /** @@ -967,7 +1102,6 @@ AbstractDocument aDoc = (AbstractDocument) doc; aDoc.readLock(); } - paintSafely(g); } finally @@ -1017,7 +1151,6 @@ g.setColor(oldColor); } - rootView.paint(g, getVisibleEditorRect()); if (caret != null && textComponent.hasFocus()) @@ -1125,6 +1258,8 @@ */ public EditorKit getEditorKit(JTextComponent t) { + if (kit == null) + kit = new DefaultEditorKit(); return kit; } @@ -1147,13 +1282,27 @@ Position.Bias[] biasRet) throws BadLocationException { - // A comment in the spec of NavigationFilter.getNextVisualPositionFrom() - // suggests that this method should be implemented by forwarding the call - // the root view. - return rootView.getNextVisualPositionFrom(pos, b, - getVisibleEditorRect(), + int offset = -1; + Document doc = textComponent.getDocument(); + if (doc instanceof AbstractDocument) + ((AbstractDocument) doc).readLock(); + try + { + Rectangle alloc = getVisibleEditorRect(); + if (alloc != null) + { + rootView.setSize(alloc.width, alloc.height); + offset = rootView.getNextVisualPositionFrom(pos, b, alloc, direction, biasRet); } + } + finally + { + if (doc instanceof AbstractDocument) + ((AbstractDocument) doc).readUnlock(); + } + return offset; + } /** * Returns the root {@link View} of a text component. @@ -1262,7 +1411,25 @@ */ public int viewToModel(JTextComponent t, Point pt, Position.Bias[] biasReturn) { - return rootView.viewToModel(pt.x, pt.y, getVisibleEditorRect(), biasReturn); + int offset = -1; + Document doc = textComponent.getDocument(); + if (doc instanceof AbstractDocument) + ((AbstractDocument) doc).readLock(); + try + { + Rectangle alloc = getVisibleEditorRect(); + if (alloc != null) + { + rootView.setSize(alloc.width, alloc.height); + offset = rootView.viewToModel(pt.x, pt.y, alloc, biasReturn); + } + } + finally + { + if (doc instanceof AbstractDocument) + ((AbstractDocument) doc).readUnlock(); + } + return offset; } /** @@ -1294,6 +1461,11 @@ } /** + * A cached Insets instance to be reused below. + */ + private Insets cachedInsets; + + /** * Returns the allocation to give the root view. * * @return the allocation to give the root view @@ -1311,7 +1483,7 @@ if (width <= 0 || height <= 0) return null; - Insets insets = textComponent.getInsets(); + Insets insets = textComponent.getInsets(cachedInsets); return new Rectangle(insets.left, insets.top, width - insets.left - insets.right, height - insets.top - insets.bottom); @@ -1362,4 +1534,5 @@ { // The default implementation does nothing. } + } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ls...@us...> - 2007-01-07 21:54:38
|
Revision: 3047 http://jnode.svn.sourceforge.net/jnode/?rev=3047&view=rev Author: lsantha Date: 2007-01-07 13:54:36 -0800 (Sun, 07 Jan 2007) Log Message: ----------- Classpath patches. Modified Paths: -------------- trunk/core/src/classpath/javax/javax/swing/colorchooser/DefaultHSBChooserPanel.java trunk/core/src/classpath/javax/javax/swing/event/EventListenerList.java trunk/core/src/classpath/javax/javax/swing/filechooser/FileSystemView.java trunk/core/src/classpath/javax/javax/swing/text/AbstractDocument.java trunk/core/src/classpath/javax/javax/swing/text/AsyncBoxView.java trunk/core/src/classpath/javax/javax/swing/text/AttributeSet.java trunk/core/src/classpath/javax/javax/swing/text/DefaultCaret.java trunk/core/src/classpath/javax/javax/swing/text/DefaultFormatter.java trunk/core/src/classpath/javax/javax/swing/text/DefaultStyledDocument.java trunk/core/src/classpath/javax/javax/swing/text/FieldView.java trunk/core/src/classpath/javax/javax/swing/text/InternationalFormatter.java trunk/core/src/classpath/javax/javax/swing/text/JTextComponent.java trunk/core/src/classpath/javax/javax/swing/text/MutableAttributeSet.java trunk/core/src/classpath/javax/javax/swing/text/SimpleAttributeSet.java trunk/core/src/classpath/javax/javax/swing/text/StyleContext.java trunk/core/src/classpath/javax/javax/swing/text/TextAction.java trunk/core/src/classpath/javax/javax/swing/text/html/HTML.java trunk/core/src/classpath/javax/javax/swing/text/html/HTMLDocument.java trunk/core/src/classpath/javax/javax/swing/text/html/StyleSheet.java trunk/core/src/classpath/javax/javax/swing/text/html/parser/AttributeList.java trunk/core/src/classpath/javax/javax/swing/text/html/parser/ContentModel.java trunk/core/src/classpath/javax/javax/swing/text/html/parser/DTD.java Modified: trunk/core/src/classpath/javax/javax/swing/colorchooser/DefaultHSBChooserPanel.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/colorchooser/DefaultHSBChooserPanel.java 2007-01-07 21:49:14 UTC (rev 3046) +++ trunk/core/src/classpath/javax/javax/swing/colorchooser/DefaultHSBChooserPanel.java 2007-01-07 21:54:36 UTC (rev 3047) @@ -778,7 +778,6 @@ if (locked == HLOCKED) { slider.setMaximum(359); - ; slider.setValue(((Number) hSpinner.getValue()).intValue()); slider.setInverted(true); } Modified: trunk/core/src/classpath/javax/javax/swing/event/EventListenerList.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/event/EventListenerList.java 2007-01-07 21:49:14 UTC (rev 3046) +++ trunk/core/src/classpath/javax/javax/swing/event/EventListenerList.java 2007-01-07 21:54:36 UTC (rev 3047) @@ -37,6 +37,9 @@ package javax.swing.event; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; import java.io.Serializable; import java.lang.reflect.Array; import java.util.EventListener; @@ -136,7 +139,7 @@ * * @throws NullPointerException if <code>t</code> is <code>null</code>. */ - public void add(Class t, EventListener listener) + public <T extends EventListener> void add(Class<T> t, T listener) { int oldLength; Object[] newList; @@ -175,7 +178,7 @@ * <code>t</code>. Thus, subclasses of <code>t</code> will not be * counted. */ - public int getListenerCount(Class t) + public int getListenerCount(Class<?> t) { int result = 0; for (int i = 0; i < listenerList.length; i += 2) @@ -224,7 +227,7 @@ * * @since 1.3 */ - public EventListener[] getListeners(Class c) + public <T extends EventListener> T[] getListeners(Class<T> c) { int count, f; EventListener[] result; @@ -236,7 +239,7 @@ if (listenerList[i] == c) result[f++] = (EventListener) listenerList[i + 1]; - return result; + return (T[]) result; } @@ -253,7 +256,7 @@ * * @throws NullPointerException if <code>t</code> is <code>null</code>. */ - public void remove(Class t, EventListener listener) + public <T extends EventListener> void remove(Class<T> t, T listener) { Object[] oldList, newList; int oldLength; @@ -304,4 +307,51 @@ } return buf.toString(); } + + /** + * Serializes an instance to an ObjectOutputStream. + * + * @param out the stream to serialize to + * + * @throws IOException if something goes wrong + */ + private void writeObject(ObjectOutputStream out) + throws IOException + { + out.defaultWriteObject(); + for (int i = 0; i < listenerList.length; i += 2) + { + Class cl = (Class) listenerList[i]; + EventListener l = (EventListener) listenerList[i + 1]; + if (l != null && l instanceof Serializable) + { + out.writeObject(cl.getName()); + out.writeObject(l); + } + } + // Write end marker. + out.writeObject(null); + } + + /** + * Deserializes an instance from an ObjectInputStream. + * + * @param in the input stream + * + * @throws ClassNotFoundException if a serialized class can't be found + * @throws IOException if something goes wrong + */ + private <T extends EventListener> void readObject(ObjectInputStream in) + throws ClassNotFoundException, IOException + { + listenerList = NO_LISTENERS; + in.defaultReadObject(); + Object type; + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + while ((type = in.readObject()) != null) + { + EventListener l = (EventListener) in.readObject(); + add(((Class<T>) Class.forName((String) type, true, cl)), (T) l); + } + } } Modified: trunk/core/src/classpath/javax/javax/swing/filechooser/FileSystemView.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/filechooser/FileSystemView.java 2007-01-07 21:49:14 UTC (rev 3046) +++ trunk/core/src/classpath/javax/javax/swing/filechooser/FileSystemView.java 2007-01-07 21:54:36 UTC (rev 3047) @@ -37,8 +37,6 @@ package javax.swing.filechooser; -import gnu.classpath.NotImplementedException; - import java.io.File; import java.io.IOException; import java.util.ArrayList; @@ -171,7 +169,6 @@ * @return A default {@link FileSystemView} appropriate for the platform. */ public static FileSystemView getFileSystemView() - throws NotImplementedException { if (defaultFileSystemView == null) { Modified: trunk/core/src/classpath/javax/javax/swing/text/AbstractDocument.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/text/AbstractDocument.java 2007-01-07 21:49:14 UTC (rev 3046) +++ trunk/core/src/classpath/javax/javax/swing/text/AbstractDocument.java 2007-01-07 21:54:36 UTC (rev 3047) @@ -1,5 +1,5 @@ /* AbstractDocument.java -- - Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -467,7 +467,7 @@ * * @return the properties of this <code>Document</code> */ - public Dictionary getDocumentProperties() + public Dictionary<Object, Object> getDocumentProperties() { // FIXME: make me thread-safe if (properties == null) @@ -518,7 +518,7 @@ * * @return all registered listeners of the specified type */ - public EventListener[] getListeners(Class listenerType) + public <T extends EventListener> T[] getListeners(Class<T> listenerType) { return listenerList.getListeners(listenerType); } @@ -1347,7 +1347,7 @@ * * @param p the document properties to set */ - public void setDocumentProperties(Dictionary p) + public void setDocumentProperties(Dictionary<Object, Object> p) { // FIXME: make me thread-safe properties = p; @@ -1521,7 +1521,7 @@ * @return the attributes of <code>old</code> minus the attributes in * <code>attributes</code> */ - AttributeSet removeAttributes(AttributeSet old, Enumeration names); + AttributeSet removeAttributes(AttributeSet old, Enumeration<?> names); } /** @@ -1777,7 +1777,7 @@ * * @param names the names of the attributes to be removed */ - public void removeAttributes(Enumeration names) + public void removeAttributes(Enumeration<?> names) { attributes = getAttributeContext().removeAttributes(attributes, names); } @@ -1872,7 +1872,7 @@ * * @return the names of the attributes of this element */ - public Enumeration getAttributeNames() + public Enumeration<?> getAttributeNames() { return attributes.getAttributeNames(); } @@ -2093,7 +2093,7 @@ /** * The child elements of this BranchElement. */ - private Element[] children;; + private Element[] children; /** * The number of children in the branch element. @@ -2450,8 +2450,6 @@ */ public boolean addEdit(UndoableEdit edit) { - // XXX - Fully qualify ElementChange to work around gcj bug #2499. - // Start using Hashtable when we pass a certain threshold. This // gives a good memory/performance compromise. if (changes == null && edits.size() > THRESHOLD) @@ -2461,19 +2459,17 @@ for (int i = 0; i < count; i++) { Object o = edits.elementAt(i); - if (o instanceof DocumentEvent.ElementChange) + if (o instanceof ElementChange) { - DocumentEvent.ElementChange ec = - (DocumentEvent.ElementChange) o; + ElementChange ec = (ElementChange) o; changes.put(ec.getElement(), ec); } } } - if (changes != null && edit instanceof DocumentEvent.ElementChange) + if (changes != null && edit instanceof ElementChange) { - DocumentEvent.ElementChange elEdit = - (DocumentEvent.ElementChange) edit; + ElementChange elEdit = (ElementChange) edit; changes.put(elEdit.getElement(), elEdit); } return super.addEdit(edit); @@ -2527,13 +2523,12 @@ * @return the changes for <code>elem</code> or <code>null</code> if * <code>elem</code> has not been changed */ - public DocumentEvent.ElementChange getChange(Element elem) + public ElementChange getChange(Element elem) { - // XXX - Fully qualify ElementChange to work around gcj bug #2499. - DocumentEvent.ElementChange change = null; + ElementChange change = null; if (changes != null) { - change = (DocumentEvent.ElementChange) changes.get(elem); + change = (ElementChange) changes.get(elem); } else { @@ -2541,10 +2536,9 @@ for (int i = 0; i < count && change == null; i++) { Object o = edits.get(i); - if (o instanceof DocumentEvent.ElementChange) + if (o instanceof ElementChange) { - DocumentEvent.ElementChange ec = - (DocumentEvent.ElementChange) o; + ElementChange ec = (ElementChange) o; if (elem.equals(ec.getElement())) change = ec; } Modified: trunk/core/src/classpath/javax/javax/swing/text/AsyncBoxView.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/text/AsyncBoxView.java 2007-01-07 21:49:14 UTC (rev 3046) +++ trunk/core/src/classpath/javax/javax/swing/text/AsyncBoxView.java 2007-01-07 21:54:36 UTC (rev 3047) @@ -307,7 +307,7 @@ private int updateChildOffsets(float targetOffset) { int n = getViewCount(); - int targetIndex = n - 1;; + int targetIndex = n - 1; int pos = lastValidOffset.getChildView().getStartOffset(); int startIndex = getViewIndexAtPosition(pos, Position.Bias.Forward); float start = lastValidOffset.getMajorOffset(); Modified: trunk/core/src/classpath/javax/javax/swing/text/AttributeSet.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/text/AttributeSet.java 2007-01-07 21:49:14 UTC (rev 3046) +++ trunk/core/src/classpath/javax/javax/swing/text/AttributeSet.java 2007-01-07 21:54:36 UTC (rev 3047) @@ -158,7 +158,7 @@ * @return the names of the attributes that are stored in this * <code>AttributeSet</code> */ - Enumeration getAttributeNames(); + Enumeration<?> getAttributeNames(); /** * Returns the resolving parent of this <code>AttributeSet</code>. Modified: trunk/core/src/classpath/javax/javax/swing/text/DefaultCaret.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/text/DefaultCaret.java 2007-01-07 21:49:14 UTC (rev 3046) +++ trunk/core/src/classpath/javax/javax/swing/text/DefaultCaret.java 2007-01-07 21:54:36 UTC (rev 3047) @@ -946,7 +946,7 @@ * * @return all registered event listeners of the specified type */ - public EventListener[] getListeners(Class listenerType) + public <T extends EventListener> T[] getListeners(Class<T> listenerType) { return listenerList.getListeners(listenerType); } Modified: trunk/core/src/classpath/javax/javax/swing/text/DefaultFormatter.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/text/DefaultFormatter.java 2007-01-07 21:49:14 UTC (rev 3046) +++ trunk/core/src/classpath/javax/javax/swing/text/DefaultFormatter.java 2007-01-07 21:54:36 UTC (rev 3047) @@ -330,7 +330,7 @@ * * @return the class that is used for values */ - public Class getValueClass() + public Class<?> getValueClass() { return valueClass; } @@ -342,7 +342,7 @@ * * @see #getValueClass() */ - public void setValueClass(Class valueClass) + public void setValueClass(Class<?> valueClass) { this.valueClass = valueClass; } Modified: trunk/core/src/classpath/javax/javax/swing/text/DefaultStyledDocument.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/text/DefaultStyledDocument.java 2007-01-07 21:49:14 UTC (rev 3046) +++ trunk/core/src/classpath/javax/javax/swing/text/DefaultStyledDocument.java 2007-01-07 21:54:36 UTC (rev 3047) @@ -1126,7 +1126,9 @@ int p; for (p = 0; p < data.length && data[p].getType() == ElementSpec.EndTagType; - p++); + p++) + ; + Edit edit = insertPath[insertPath.length - p - 1]; edit.index--; edit.removed.add(0, edit.e.getElement(edit.index)); @@ -2377,7 +2379,7 @@ * * @return an enumeration of all style names */ - public Enumeration getStyleNames() + public Enumeration<?> getStyleNames() { StyleContext context = (StyleContext) getAttributeContext(); return context.getStyleNames(); Modified: trunk/core/src/classpath/javax/javax/swing/text/FieldView.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/text/FieldView.java 2007-01-07 21:49:14 UTC (rev 3046) +++ trunk/core/src/classpath/javax/javax/swing/text/FieldView.java 2007-01-07 21:54:36 UTC (rev 3047) @@ -91,7 +91,7 @@ horizontalVisibility.addChangeListener(new ChangeListener(){ public void stateChanged(ChangeEvent event) { getContainer().repaint(); - }; + } }); // It turned out that the span calculated at this point is wrong Modified: trunk/core/src/classpath/javax/javax/swing/text/InternationalFormatter.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/text/InternationalFormatter.java 2007-01-07 21:49:14 UTC (rev 3046) +++ trunk/core/src/classpath/javax/javax/swing/text/InternationalFormatter.java 2007-01-07 21:54:36 UTC (rev 3047) @@ -1,5 +1,5 @@ /* InternationalFormatter.java -- -Copyright (C) 2005 Free Software Foundation, Inc. +Copyright (C) 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -329,7 +329,7 @@ * * @throws CloneNotSupportedException not thrown here, since cloning is * supported - * XXX - FIXME - Whole method disabled as workaround for gcj bug #22060. + */ public Object clone() throws CloneNotSupportedException { @@ -338,7 +338,6 @@ Object clone = super.clone(); return clone; } - */ /** * Returns the Actions that are supported by this Formatter. Modified: trunk/core/src/classpath/javax/javax/swing/text/JTextComponent.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/text/JTextComponent.java 2007-01-07 21:49:14 UTC (rev 3046) +++ trunk/core/src/classpath/javax/javax/swing/text/JTextComponent.java 2007-01-07 21:54:36 UTC (rev 3047) @@ -1821,7 +1821,7 @@ public boolean getScrollableTracksViewportWidth() { - boolean res = false;; + boolean res = false; Container c = getParent(); if (c instanceof JViewport) res = ((JViewport) c).getExtentSize().width > getPreferredSize().width; Modified: trunk/core/src/classpath/javax/javax/swing/text/MutableAttributeSet.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/text/MutableAttributeSet.java 2007-01-07 21:49:14 UTC (rev 3046) +++ trunk/core/src/classpath/javax/javax/swing/text/MutableAttributeSet.java 2007-01-07 21:54:36 UTC (rev 3047) @@ -90,7 +90,7 @@ * @throws NullPointerException if <code>names</code> is <code>null</code> * or contains any <code>null</code> values. */ - void removeAttributes(Enumeration names); + void removeAttributes(Enumeration<?> names); /** * Removes attributes from this set if they are found in the Modified: trunk/core/src/classpath/javax/javax/swing/text/SimpleAttributeSet.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/text/SimpleAttributeSet.java 2007-01-07 21:49:14 UTC (rev 3046) +++ trunk/core/src/classpath/javax/javax/swing/text/SimpleAttributeSet.java 2007-01-07 21:54:36 UTC (rev 3047) @@ -261,7 +261,7 @@ * * @return An enumeration of the attribute names. */ - public Enumeration getAttributeNames() + public Enumeration<?> getAttributeNames() { return tab.keys(); } @@ -375,7 +375,7 @@ * @throws NullPointerException if <code>names</code> is <code>null</code> * or contains any <code>null</code> values. */ - public void removeAttributes(Enumeration names) + public void removeAttributes(Enumeration<?> names) { while (names.hasMoreElements()) { Modified: trunk/core/src/classpath/javax/javax/swing/text/StyleContext.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/text/StyleContext.java 2007-01-07 21:49:14 UTC (rev 3046) +++ trunk/core/src/classpath/javax/javax/swing/text/StyleContext.java 2007-01-07 21:54:36 UTC (rev 3047) @@ -121,7 +121,7 @@ listenerList.remove(ChangeListener.class, l); } - public EventListener[] getListeners(Class listenerType) + public <T extends EventListener> T[] getListeners(Class<T> listenerType) { return listenerList.getListeners(listenerType); } @@ -183,7 +183,7 @@ return attributes.getAttributeCount(); } - public Enumeration getAttributeNames() + public Enumeration<?> getAttributeNames() { return attributes.getAttributeNames(); } @@ -210,7 +210,7 @@ fireStateChanged(); } - public void removeAttributes(Enumeration names) + public void removeAttributes(Enumeration<?> names) { attributes = StyleContext.this.removeAttributes(attributes, names); fireStateChanged(); @@ -351,7 +351,7 @@ return attrs.length / 2; } - public Enumeration getAttributeNames() + public Enumeration<?> getAttributeNames() { return new Enumeration() { @@ -539,7 +539,7 @@ * Get the names of the style. The returned enumeration always * contains at least one member, the default style. */ - public Enumeration getStyleNames() + public Enumeration<?> getStyleNames() { return styles.getAttributeNames(); } @@ -749,7 +749,7 @@ } public synchronized AttributeSet removeAttributes(AttributeSet old, - Enumeration names) + Enumeration<?> names) { AttributeSet ret; if (old.getAttributeCount() <= getCompressionThreshold()) Modified: trunk/core/src/classpath/javax/javax/swing/text/TextAction.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/text/TextAction.java 2007-01-07 21:49:14 UTC (rev 3046) +++ trunk/core/src/classpath/javax/javax/swing/text/TextAction.java 2007-01-07 21:54:36 UTC (rev 3047) @@ -96,7 +96,7 @@ */ public static final Action[] augmentList(Action[] list1, Action[] list2) { - HashMap actions = new HashMap(); + HashMap<Object,Action> actions = new HashMap<Object,Action>(); for (int i = 0; i < list1.length; ++i) { @@ -104,6 +104,7 @@ Object name = a.getValue(Action.NAME); actions.put(name != null ? name : "", a); } + for (int i = 0; i < list2.length; ++i) { Action a = list2[i]; @@ -113,9 +114,10 @@ Action[] augmented = new Action[actions.size()]; int i = 0; - for (Iterator it = actions.values().iterator(); it.hasNext(); i++) - augmented[i] = (Action) it.next(); + for (Iterator<Action> it = actions.values().iterator(); it.hasNext(); i++) + augmented[i] = it.next(); return augmented; + } /** Modified: trunk/core/src/classpath/javax/javax/swing/text/html/HTML.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/text/html/HTML.java 2007-01-07 21:49:14 UTC (rev 3046) +++ trunk/core/src/classpath/javax/javax/swing/text/html/HTML.java 2007-01-07 21:54:36 UTC (rev 3047) @@ -1129,8 +1129,8 @@ static final int BLOCK = 2; static final int PREFORMATTED = 4; static final int SYNTHETIC = 8; - private static Map tagMap; - private static Map attrMap; + private static Map<String,Tag> tagMap; + private static Map<String,Attribute> attrMap; /** * The public constructor (does nothing). It it seldom required to have @@ -1169,7 +1169,7 @@ if (attrMap == null) { // Create the map on demand. - attrMap = new TreeMap(); + attrMap = new TreeMap<String,Attribute>(); Attribute[] attrs = getAllAttributeKeys(); @@ -1179,7 +1179,7 @@ } } - return (Attribute) attrMap.get(attName.toLowerCase()); + return attrMap.get(attName.toLowerCase()); } /** @@ -1238,7 +1238,7 @@ if (tagMap == null) { // Create the mao on demand. - tagMap = new TreeMap(); + tagMap = new TreeMap<String,Tag>(); Tag[] tags = getAllTags(); @@ -1248,6 +1248,6 @@ } } - return (Tag) tagMap.get(tagName.toLowerCase()); + return tagMap.get(tagName.toLowerCase()); } } Modified: trunk/core/src/classpath/javax/javax/swing/text/html/HTMLDocument.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/text/html/HTMLDocument.java 2007-01-07 21:49:14 UTC (rev 3046) +++ trunk/core/src/classpath/javax/javax/swing/text/html/HTMLDocument.java 2007-01-07 21:54:36 UTC (rev 3047) @@ -649,12 +649,12 @@ */ protected MutableAttributeSet charAttr = new SimpleAttributeSet(); - protected Vector parseBuffer = new Vector(); + protected Vector<ElementSpec> parseBuffer = new Vector<ElementSpec>(); /** * The parse stack. It holds the current element tree path. */ - private Stack parseStack = new Stack(); + private Stack<HTML.Tag> parseStack = new Stack<HTML.Tag>(); /** * A stack for character attribute sets * @@ -1791,7 +1791,7 @@ boolean inParagraph = false; if (! parseStack.isEmpty()) { - HTML.Tag top = (HTML.Tag) parseStack.peek(); + HTML.Tag top = parseStack.peek(); inParagraph = top == HTML.Tag.P || top == HTML.Tag.IMPLIED; } return inParagraph; @@ -1802,7 +1802,7 @@ boolean inParagraph = false; if (! parseStack.isEmpty()) { - HTML.Tag top = (HTML.Tag) parseStack.peek(); + HTML.Tag top = parseStack.peek(); inParagraph = top == HTML.Tag.IMPLIED; } return inParagraph; Modified: trunk/core/src/classpath/javax/javax/swing/text/html/StyleSheet.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/text/html/StyleSheet.java 2007-01-07 21:49:14 UTC (rev 3046) +++ trunk/core/src/classpath/javax/javax/swing/text/html/StyleSheet.java 2007-01-07 21:54:36 UTC (rev 3047) @@ -870,7 +870,7 @@ * @param names - the attribute names * @return the update attribute set */ - public AttributeSet removeAttributes(AttributeSet old, Enumeration names) + public AttributeSet removeAttributes(AttributeSet old, Enumeration<?> names) { // FIXME: Not implemented. return super.removeAttributes(old, names); Modified: trunk/core/src/classpath/javax/javax/swing/text/html/parser/AttributeList.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/text/html/parser/AttributeList.java 2007-01-07 21:49:14 UTC (rev 3046) +++ trunk/core/src/classpath/javax/javax/swing/text/html/parser/AttributeList.java 2007-01-07 21:54:36 UTC (rev 3047) @@ -122,7 +122,7 @@ * null, if this parameter was not specified. * Values, defined in DTD, are case insensitive. */ - public Vector values; + public Vector<?> values; /** * The modifier of this attribute. This field contains one of the @@ -176,7 +176,7 @@ * Equals to null for the last attribute definition. */ public AttributeList(String a_name, int a_type, int a_modifier, - String a_default, Vector allowed_values, + String a_default, Vector<?> allowed_values, AttributeList a_next ) { @@ -251,7 +251,7 @@ /** * Get the allowed values of this attribute. */ - public Enumeration getValues() + public Enumeration<?> getValues() { return values.elements(); } Modified: trunk/core/src/classpath/javax/javax/swing/text/html/parser/ContentModel.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/text/html/parser/ContentModel.java 2007-01-07 21:49:14 UTC (rev 3046) +++ trunk/core/src/classpath/javax/javax/swing/text/html/parser/ContentModel.java 2007-01-07 21:54:36 UTC (rev 3047) @@ -151,13 +151,15 @@ * discarded. * @param elements - a vector to add the values to. */ - public void getElements(Vector elements) + public void getElements(Vector<Element> elements) { ContentModel c = this; while (c != null) { - elements.add(c.content); + // FIXME: correct? + if (c.content instanceof Element) + elements.add((Element) c.content); c = c.next; } } Modified: trunk/core/src/classpath/javax/javax/swing/text/html/parser/DTD.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/text/html/parser/DTD.java 2007-01-07 21:49:14 UTC (rev 3046) +++ trunk/core/src/classpath/javax/javax/swing/text/html/parser/DTD.java 2007-01-07 21:54:36 UTC (rev 3047) @@ -88,7 +88,7 @@ /** * The table of existing available DTDs. */ - static Hashtable dtdHash = new Hashtable(); + static Hashtable<String,DTD> dtdHash = new Hashtable<String,DTD>(); /** * The applet element for this DTD. @@ -148,12 +148,13 @@ /** * The element for accessing all DTD elements by name. */ - public Hashtable elementHash = new Hashtable(); + public Hashtable<String,Element> elementHash = + new Hashtable<String,Element>(); /** * The entity table for accessing all DTD entities by name. */ - public Hashtable entityHash = new Hashtable(); + public Hashtable<Object, Entity> entityHash = new Hashtable<Object, Entity>(); /** * The name of this DTD. @@ -165,7 +166,7 @@ * javax.swing.text.html.parser.Element#index field of all elements * in this vector is set to the element position in this vector. */ - public Vector elements = new Vector(); + public Vector<Element> elements = new Vector<Element>(); /** Create a new DTD with the specified name. */ protected DTD(String a_name) @@ -224,7 +225,7 @@ String name = Entity.mapper.get(id); if (name != null) - return (Entity) entityHash.get(name); + return entityHash.get(name); else return null; } @@ -269,7 +270,7 @@ */ public void defineAttributes(String forElement, AttributeList attributes) { - Element e = (Element) elementHash.get(forElement.toLowerCase()); + Element e = elementHash.get(forElement.toLowerCase()); if (e == null) e = newElement(forElement); @@ -420,7 +421,7 @@ if (allowed_values != null) { StringTokenizer st = new StringTokenizer(allowed_values, " \t|"); - Vector v = new Vector(st.countTokens()); + Vector<String> v = new Vector<String>(st.countTokens()); while (st.hasMoreTokens()) v.add(st.nextToken()); @@ -571,7 +572,7 @@ */ private Element newElement(String name) { - Element e = (Element) elementHash.get(name.toLowerCase()); + Element e = elementHash.get(name.toLowerCase()); if (e == null) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ls...@us...> - 2007-01-09 20:25:51
|
Revision: 3062 http://jnode.svn.sourceforge.net/jnode/?rev=3062&view=rev Author: lsantha Date: 2007-01-09 12:25:48 -0800 (Tue, 09 Jan 2007) Log Message: ----------- Classpath patches. Modified Paths: -------------- trunk/core/src/classpath/javax/javax/swing/AbstractButton.java trunk/core/src/classpath/javax/javax/swing/AbstractListModel.java trunk/core/src/classpath/javax/javax/swing/AbstractSpinnerModel.java trunk/core/src/classpath/javax/javax/swing/ButtonGroup.java trunk/core/src/classpath/javax/javax/swing/DefaultBoundedRangeModel.java trunk/core/src/classpath/javax/javax/swing/DefaultButtonModel.java trunk/core/src/classpath/javax/javax/swing/DefaultComboBoxModel.java trunk/core/src/classpath/javax/javax/swing/DefaultListModel.java trunk/core/src/classpath/javax/javax/swing/DefaultListSelectionModel.java trunk/core/src/classpath/javax/javax/swing/DefaultSingleSelectionModel.java trunk/core/src/classpath/javax/javax/swing/JButton.java trunk/core/src/classpath/javax/javax/swing/JComboBox.java trunk/core/src/classpath/javax/javax/swing/JEditorPane.java trunk/core/src/classpath/javax/javax/swing/JFileChooser.java trunk/core/src/classpath/javax/javax/swing/JFormattedTextField.java trunk/core/src/classpath/javax/javax/swing/JList.java trunk/core/src/classpath/javax/javax/swing/JMenuBar.java trunk/core/src/classpath/javax/javax/swing/JRootPane.java trunk/core/src/classpath/javax/javax/swing/JScrollPane.java trunk/core/src/classpath/javax/javax/swing/JTabbedPane.java trunk/core/src/classpath/javax/javax/swing/JToggleButton.java trunk/core/src/classpath/javax/javax/swing/JToolTip.java trunk/core/src/classpath/javax/javax/swing/JWindow.java trunk/core/src/classpath/javax/javax/swing/LookAndFeel.java trunk/core/src/classpath/javax/javax/swing/Popup.java trunk/core/src/classpath/javax/javax/swing/SizeSequence.java trunk/core/src/classpath/javax/javax/swing/SortingFocusTraversalPolicy.java trunk/core/src/classpath/javax/javax/swing/SpinnerListModel.java trunk/core/src/classpath/javax/javax/swing/Timer.java trunk/core/src/classpath/javax/javax/swing/UIDefaults.java Modified: trunk/core/src/classpath/javax/javax/swing/AbstractButton.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/AbstractButton.java 2007-01-09 20:25:00 UTC (rev 3061) +++ trunk/core/src/classpath/javax/javax/swing/AbstractButton.java 2007-01-09 20:25:48 UTC (rev 3062) @@ -37,8 +37,6 @@ package javax.swing; -import gnu.classpath.NotImplementedException; - import java.awt.Component; import java.awt.Graphics; import java.awt.Image; @@ -74,7 +72,10 @@ import javax.swing.plaf.basic.BasicHTML; import javax.swing.text.AttributeSet; import javax.swing.text.BadLocationException; +import javax.swing.text.Document; +import javax.swing.text.Element; import javax.swing.text.Position; +import javax.swing.text.StyledDocument; import javax.swing.text.View; @@ -804,22 +805,127 @@ return -1; } - public String getAtIndex(int value0, int value1) - throws NotImplementedException + /** + * Returns the character, word or sentence at the specified index. The + * <code>part</code> parameter determines what is returned, the character, + * word or sentence after the index. + * + * @param part one of {@link AccessibleText#CHARACTER}, + * {@link AccessibleText#WORD} or + * {@link AccessibleText#SENTENCE}, specifying what is returned + * @param index the index + * + * @return the character, word or sentence after <code>index</code> + */ + public String getAtIndex(int part, int index) { - return null; // TODO + String result = ""; + int startIndex = -1; + int endIndex = -1; + switch(part) + { + case AccessibleText.CHARACTER: + result = String.valueOf(text.charAt(index)); + break; + case AccessibleText.WORD: + startIndex = text.lastIndexOf(' ', index); + endIndex = text.indexOf(' ', startIndex + 1); + if (endIndex == -1) + endIndex = startIndex + 1; + result = text.substring(startIndex + 1, endIndex); + break; + case AccessibleText.SENTENCE: + default: + startIndex = text.lastIndexOf('.', index); + endIndex = text.indexOf('.', startIndex + 1); + if (endIndex == -1) + endIndex = startIndex + 1; + result = text.substring(startIndex + 1, endIndex); + break; + } + return result; } - public String getAfterIndex(int value0, int value1) - throws NotImplementedException + /** + * Returns the character, word or sentence after the specified index. The + * <code>part</code> parameter determines what is returned, the character, + * word or sentence after the index. + * + * @param part one of {@link AccessibleText#CHARACTER}, + * {@link AccessibleText#WORD} or + * {@link AccessibleText#SENTENCE}, specifying what is returned + * @param index the index + * + * @return the character, word or sentence after <code>index</code> + */ + public String getAfterIndex(int part, int index) { - return null; // TODO + String result = ""; + int startIndex = -1; + int endIndex = -1; + switch(part) + { + case AccessibleText.CHARACTER: + result = String.valueOf(text.charAt(index + 1)); + break; + case AccessibleText.WORD: + startIndex = text.indexOf(' ', index); + endIndex = text.indexOf(' ', startIndex + 1); + if (endIndex == -1) + endIndex = startIndex + 1; + result = text.substring(startIndex + 1, endIndex); + break; + case AccessibleText.SENTENCE: + default: + startIndex = text.indexOf('.', index); + endIndex = text.indexOf('.', startIndex + 1); + if (endIndex == -1) + endIndex = startIndex + 1; + result = text.substring(startIndex + 1, endIndex); + break; + } + return result; } - public String getBeforeIndex(int value0, int value1) - throws NotImplementedException + /** + * Returns the character, word or sentence before the specified index. The + * <code>part</code> parameter determines what is returned, the character, + * word or sentence before the index. + * + * @param part one of {@link AccessibleText#CHARACTER}, + * {@link AccessibleText#WORD} or + * {@link AccessibleText#SENTENCE}, specifying what is returned + * @param index the index + * + * @return the character, word or sentence before <code>index</code> + */ + public String getBeforeIndex(int part, int index) { - return null; // TODO + String result = ""; + int startIndex = -1; + int endIndex = -1; + switch(part) + { + case AccessibleText.CHARACTER: + result = String.valueOf(text.charAt(index - 1)); + break; + case AccessibleText.WORD: + endIndex = text.lastIndexOf(' ', index); + if (endIndex == -1) + endIndex = 0; + startIndex = text.lastIndexOf(' ', endIndex - 1); + result = text.substring(startIndex + 1, endIndex); + break; + case AccessibleText.SENTENCE: + default: + endIndex = text.lastIndexOf('.', index); + if (endIndex == -1) + endIndex = 0; + startIndex = text.lastIndexOf('.', endIndex - 1); + result = text.substring(startIndex + 1, endIndex); + break; + } + return result; } /** @@ -837,7 +943,14 @@ View view = (View) getClientProperty(BasicHTML.propertyKey); if (view != null) { - + Document doc = view.getDocument(); + if (doc instanceof StyledDocument) + { + StyledDocument sDoc = (StyledDocument) doc; + Element charEl = sDoc.getCharacterElement(i); + if (charEl != null) + atts = charEl.getAttributes(); + } } return atts; } @@ -904,7 +1017,10 @@ setDisplayedMnemonicIndex(-1); setOpaque(true); text = ""; - updateUI(); + // testing on JRE1.5 shows that the iconTextGap default value is + // hard-coded here and the 'Button.iconTextGap' setting in the + // UI defaults is ignored, at least by the MetalLookAndFeel + iconTextGap = 4; } /** @@ -965,6 +1081,8 @@ if (icon != null) default_icon = icon; + + updateUI(); } /** Modified: trunk/core/src/classpath/javax/javax/swing/AbstractListModel.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/AbstractListModel.java 2007-01-09 20:25:00 UTC (rev 3061) +++ trunk/core/src/classpath/javax/javax/swing/AbstractListModel.java 2007-01-09 20:25:48 UTC (rev 3062) @@ -164,7 +164,7 @@ * * @return The set of listeners of the specified type */ - public EventListener[] getListeners(Class listenerType) + public <T extends EventListener> T[] getListeners(Class<T> listenerType) { return listenerList.getListeners(listenerType); } Modified: trunk/core/src/classpath/javax/javax/swing/AbstractSpinnerModel.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/AbstractSpinnerModel.java 2007-01-09 20:25:00 UTC (rev 3061) +++ trunk/core/src/classpath/javax/javax/swing/AbstractSpinnerModel.java 2007-01-09 20:25:48 UTC (rev 3062) @@ -1,5 +1,5 @@ /* AbstractSpinnerModel.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -48,12 +48,15 @@ * Provides standard implementations for some of the methods in * {@link SpinnerModel}. * + * @since 1.4 + * * @author Ka-Hing Cheung */ public abstract class AbstractSpinnerModel implements SpinnerModel { private ChangeEvent changeEvent = new ChangeEvent(this); + /** Stores the listeners registered with the model. */ protected EventListenerList listenerList = new EventListenerList(); /** @@ -65,9 +68,10 @@ } /** - * Adds a <code>ChangeListener</code>. + * Registers a <code>ChangeListener</code> with the model so that it will + * receive {@link ChangeEvent} notifications when the model changes. * - * @param listener the listener to add + * @param listener the listener to add (<code>null</code> is ignored). */ public void addChangeListener(ChangeListener listener) { @@ -80,7 +84,7 @@ * @param c the type of listener * @return the listeners that are of the specific type */ - public EventListener[] getListeners(Class c) + public <T extends EventListener> T[] getListeners(Class<T> c) { return listenerList.getListeners(c); } Modified: trunk/core/src/classpath/javax/javax/swing/ButtonGroup.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/ButtonGroup.java 2007-01-09 20:25:00 UTC (rev 3061) +++ trunk/core/src/classpath/javax/javax/swing/ButtonGroup.java 2007-01-09 20:25:48 UTC (rev 3062) @@ -68,7 +68,7 @@ private static final long serialVersionUID = 4259076101881721375L; /** Stores references to the buttons added to this button group. */ - protected Vector buttons = new Vector(); + protected Vector<AbstractButton> buttons = new Vector<AbstractButton>(); /** The currently selected button model. */ ButtonModel sel; @@ -129,7 +129,7 @@ * * @return <code>Enumeration</code> over all added buttons */ - public Enumeration getElements() + public Enumeration<AbstractButton> getElements() { return buttons.elements(); } @@ -183,6 +183,10 @@ if (old != null) old.setSelected(false); + + if (m != null) + sel.setSelected(true); + AbstractButton button = findButton(old); if (button != null) button.repaint(); Modified: trunk/core/src/classpath/javax/javax/swing/DefaultBoundedRangeModel.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/DefaultBoundedRangeModel.java 2007-01-09 20:25:00 UTC (rev 3061) +++ trunk/core/src/classpath/javax/javax/swing/DefaultBoundedRangeModel.java 2007-01-09 20:25:48 UTC (rev 3062) @@ -424,7 +424,7 @@ * * @since 1.3 */ - public EventListener[] getListeners(Class listenerType) + public <T extends EventListener> T[] getListeners(Class<T> listenerType) { return listenerList.getListeners(listenerType); } Modified: trunk/core/src/classpath/javax/javax/swing/DefaultButtonModel.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/DefaultButtonModel.java 2007-01-09 20:25:00 UTC (rev 3061) +++ trunk/core/src/classpath/javax/javax/swing/DefaultButtonModel.java 2007-01-09 20:25:48 UTC (rev 3062) @@ -166,7 +166,7 @@ * * @return array of listeners */ - public EventListener[] getListeners(Class listenerType) + public <T extends EventListener> T[] getListeners(Class<T> listenerType) { return listenerList.getListeners(listenerType); } Modified: trunk/core/src/classpath/javax/javax/swing/DefaultComboBoxModel.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/DefaultComboBoxModel.java 2007-01-09 20:25:00 UTC (rev 3061) +++ trunk/core/src/classpath/javax/javax/swing/DefaultComboBoxModel.java 2007-01-09 20:25:48 UTC (rev 3062) @@ -104,7 +104,7 @@ * * @throws NullPointerException if <code>vector</code> is <code>null</code>. */ - public DefaultComboBoxModel(Vector vector) + public DefaultComboBoxModel(Vector<?> vector) { this.list = vector; if (getSize() > 0) @@ -224,16 +224,24 @@ */ public void setSelectedItem(Object object) { - if (selectedItem == null) - { - if (object == null) + // No item is selected and object is null, so no change required. + if (selectedItem == null && object == null) return; - } - else - { - if (selectedItem.equals(object)) + + // object is already selected so no change required. + if (selectedItem != null && selectedItem.equals(object)) return; - } + + // Simply return if object is not in the list. + if (object != null && getIndexOf(object) == -1) + return; + + // Here we know that object is either an item in the list or null. + + // Handle the three change cases: selectedItem is null, object is + // non-null; selectedItem is non-null, object is null; + // selectedItem is non-null, object is non-null and they're not + // equal. selectedItem = object; fireContentsChanged(this, -1, -1); } Modified: trunk/core/src/classpath/javax/javax/swing/DefaultListModel.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/DefaultListModel.java 2007-01-09 20:25:00 UTC (rev 3061) +++ trunk/core/src/classpath/javax/javax/swing/DefaultListModel.java 2007-01-09 20:25:48 UTC (rev 3062) @@ -309,7 +309,7 @@ * * @return A new enumeration which iterates over the list */ - public Enumeration elements() + public Enumeration<?> elements() { return elements.elements(); } Modified: trunk/core/src/classpath/javax/javax/swing/DefaultListSelectionModel.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/DefaultListSelectionModel.java 2007-01-09 20:25:00 UTC (rev 3061) +++ trunk/core/src/classpath/javax/javax/swing/DefaultListSelectionModel.java 2007-01-09 20:25:48 UTC (rev 3062) @@ -815,7 +815,7 @@ * @see #getListSelectionListeners * @since 1.3 */ - public EventListener[] getListeners(Class listenerType) + public <T extends EventListener> T[] getListeners(Class<T> listenerType) { return listenerList.getListeners(listenerType); } Modified: trunk/core/src/classpath/javax/javax/swing/DefaultSingleSelectionModel.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/DefaultSingleSelectionModel.java 2007-01-09 20:25:00 UTC (rev 3061) +++ trunk/core/src/classpath/javax/javax/swing/DefaultSingleSelectionModel.java 2007-01-09 20:25:48 UTC (rev 3062) @@ -174,7 +174,7 @@ * * @since 1.3 */ - public EventListener[] getListeners(Class listenerClass) + public <T extends EventListener> T[] getListeners(Class<T> listenerClass) { return listenerList.getListeners(listenerClass); } Modified: trunk/core/src/classpath/javax/javax/swing/JButton.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/JButton.java 2007-01-09 20:25:00 UTC (rev 3061) +++ trunk/core/src/classpath/javax/javax/swing/JButton.java 2007-01-09 20:25:48 UTC (rev 3062) @@ -132,8 +132,8 @@ public JButton(String text, Icon icon) { super(); + setModel(new DefaultButtonModel()); init(text, icon); - setModel(new DefaultButtonModel()); defaultCapable = true; } Modified: trunk/core/src/classpath/javax/javax/swing/JComboBox.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/JComboBox.java 2007-01-09 20:25:00 UTC (rev 3061) +++ trunk/core/src/classpath/javax/javax/swing/JComboBox.java 2007-01-09 20:25:48 UTC (rev 3062) @@ -196,7 +196,7 @@ * * @param itemVector vector containing list of items for this JComboBox. */ - public JComboBox(Vector itemVector) + public JComboBox(Vector<?> itemVector) { this(new DefaultComboBoxModel(itemVector)); Modified: trunk/core/src/classpath/javax/javax/swing/JEditorPane.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/JEditorPane.java 2007-01-09 20:25:00 UTC (rev 3061) +++ trunk/core/src/classpath/javax/javax/swing/JEditorPane.java 2007-01-09 20:25:48 UTC (rev 3062) @@ -712,7 +712,7 @@ public JEditorPane(URL url) throws IOException { init(); - setEditorKit(createEditorKitForContentType("text/html"));; + setEditorKit(createEditorKitForContentType("text/html")); setPage(url); } Modified: trunk/core/src/classpath/javax/javax/swing/JFileChooser.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/JFileChooser.java 2007-01-09 20:25:00 UTC (rev 3061) +++ trunk/core/src/classpath/javax/javax/swing/JFileChooser.java 2007-01-09 20:25:48 UTC (rev 3062) @@ -43,6 +43,8 @@ import java.awt.HeadlessException; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.WindowEvent; +import java.awt.event.WindowAdapter; import java.beans.PropertyChangeEvent; import java.io.File; import java.util.ArrayList; @@ -351,7 +353,7 @@ * The file selection mode. * @see #setFileSelectionMode(int) */ - private int fileSelectionMode = FILES_AND_DIRECTORIES; + private int fileSelectionMode = FILES_ONLY; /** * The file view. @@ -744,10 +746,16 @@ JDialog dialog = new JDialog(toUse); setSelectedFile(null); dialog.getContentPane().add(this); + dialog.addWindowListener( new WindowAdapter() + { + public void windowClosing(WindowEvent e) + { + cancelSelection(); + } + }); dialog.setModal(true); dialog.invalidate(); dialog.repaint(); - return dialog; } Modified: trunk/core/src/classpath/javax/javax/swing/JFormattedTextField.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/JFormattedTextField.java 2007-01-09 20:25:00 UTC (rev 3061) +++ trunk/core/src/classpath/javax/javax/swing/JFormattedTextField.java 2007-01-09 20:25:48 UTC (rev 3062) @@ -415,7 +415,7 @@ // to create a new formatter. Object oldValue = this.value; - this.value = formatter.stringToValue(getText());; + this.value = formatter.stringToValue(getText()); editValid = true; firePropertyChange("value", oldValue, this.value); Modified: trunk/core/src/classpath/javax/javax/swing/JList.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/JList.java 2007-01-09 20:25:00 UTC (rev 3061) +++ trunk/core/src/classpath/javax/javax/swing/JList.java 2007-01-09 20:25:48 UTC (rev 3062) @@ -1041,7 +1041,7 @@ * * @param items the initial list items. */ - public JList(Vector items) + public JList(Vector<?> items) { init(createListModel(items)); } @@ -1643,9 +1643,20 @@ * @param listData The object array to build a new list model on * @see #setModel */ - public void setListData(Vector listData) + public void setListData(final Vector<?> listData) { - setModel(createListModel(listData)); + setModel(new AbstractListModel() + { + public int getSize() + { + return listData.size(); + } + + public Object getElementAt(int i) + { + return listData.elementAt(i); + } + }); } /** Modified: trunk/core/src/classpath/javax/javax/swing/JMenuBar.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/JMenuBar.java 2007-01-09 20:25:00 UTC (rev 3061) +++ trunk/core/src/classpath/javax/javax/swing/JMenuBar.java 2007-01-09 20:25:48 UTC (rev 3062) @@ -298,19 +298,25 @@ } /** - * DOCUMENT ME! + * This method is not implemented and will throw an {@link Error} if called. * - * @return DOCUMENT ME! + * @return This method never returns anything, it throws an exception. */ public JMenu getHelpMenu() { - return null; + // the following error matches the behaviour of the reference + // implementation... + throw new Error("getHelpMenu() is not implemented"); } /** - * Returns margin betweeen menu bar's border and its menues + * Returns the margin between the menu bar's border and its menus. If the + * margin is <code>null</code>, this method returns + * <code>new Insets(0, 0, 0, 0)</code>. * - * @return margin between menu bar's border and its menues + * @return The margin (never <code>null</code>). + * + * @see #setMargin(Insets) */ public Insets getMargin() { @@ -617,13 +623,12 @@ } /** - * Sets the menu bar's "margin" bound property, which represents - * distance between the menubar's border and its menus. - * icon. When marging property is modified, PropertyChangeEvent will - * be fired to menuBar's PropertyChangeListener's. + * Sets the margin between the menu bar's border and its menus (this is a + * bound property with the name 'margin'). * - * @param m distance between the menubar's border and its menus. + * @param m the margin (<code>null</code> permitted). * + * @see #getMargin() */ public void setMargin(Insets m) { Modified: trunk/core/src/classpath/javax/javax/swing/JRootPane.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/JRootPane.java 2007-01-09 20:25:00 UTC (rev 3061) +++ trunk/core/src/classpath/javax/javax/swing/JRootPane.java 2007-01-09 20:25:48 UTC (rev 3062) @@ -505,12 +505,18 @@ } /** - * DOCUMENT ME! + * Set the layered pane for the root pane. * - * @param f DOCUMENT ME! + * @param f The JLayeredPane to be used. + * + * @throws IllegalComponentStateException if JLayeredPane + * parameter is null. */ public void setLayeredPane(JLayeredPane f) { + if (f == null) + throw new IllegalComponentStateException(); + if (layeredPane != null) remove(layeredPane); Modified: trunk/core/src/classpath/javax/javax/swing/JScrollPane.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/JScrollPane.java 2007-01-09 20:25:00 UTC (rev 3061) +++ trunk/core/src/classpath/javax/javax/swing/JScrollPane.java 2007-01-09 20:25:48 UTC (rev 3062) @@ -162,9 +162,10 @@ protected JViewport viewport; - Border viewportBorder; - boolean wheelScrollingEnabled; + private Border viewportBorder; + private boolean wheelScrollingEnabled; + public JViewport getColumnHeader() { return columnHeader; @@ -595,6 +596,7 @@ */ public JScrollPane(Component view, int vsbPolicy, int hsbPolicy) { + wheelScrollingEnabled = true; setVerticalScrollBarPolicy(vsbPolicy); setVerticalScrollBar(createVerticalScrollBar()); setHorizontalScrollBarPolicy(hsbPolicy); Modified: trunk/core/src/classpath/javax/javax/swing/JTabbedPane.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/JTabbedPane.java 2007-01-09 20:25:00 UTC (rev 3061) +++ trunk/core/src/classpath/javax/javax/swing/JTabbedPane.java 2007-01-09 20:25:48 UTC (rev 3062) @@ -887,7 +887,7 @@ if (model != null) { - if (changeListener != null) + if (changeListener == null) changeListener = createChangeListener(); model.addChangeListener(changeListener); } @@ -1054,7 +1054,10 @@ } if (getSelectedIndex() == -1) + { setSelectedIndex(0); + fireStateChanged(); + } revalidate(); repaint(); Modified: trunk/core/src/classpath/javax/javax/swing/JToggleButton.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/JToggleButton.java 2007-01-09 20:25:00 UTC (rev 3061) +++ trunk/core/src/classpath/javax/javax/swing/JToggleButton.java 2007-01-09 20:25:48 UTC (rev 3062) @@ -1,5 +1,5 @@ /* JToggleButton.java -- - Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -291,9 +291,8 @@ public JToggleButton (String text, Icon icon, boolean selected) { super(); - init(text, icon); - setModel(new ToggleButtonModel()); + init(text, icon); model.setSelected(selected); setAlignmentX(LEFT_ALIGNMENT); } Modified: trunk/core/src/classpath/javax/javax/swing/JToolTip.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/JToolTip.java 2007-01-09 20:25:00 UTC (rev 3061) +++ trunk/core/src/classpath/javax/javax/swing/JToolTip.java 2007-01-09 20:25:48 UTC (rev 3062) @@ -181,7 +181,7 @@ { StringBuffer sb = new StringBuffer(super.paramString()); sb.append(",tiptext="); - if (text != null); + if (text != null) sb.append(text); return sb.toString(); } Modified: trunk/core/src/classpath/javax/javax/swing/JWindow.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/JWindow.java 2007-01-09 20:25:00 UTC (rev 3061) +++ trunk/core/src/classpath/javax/javax/swing/JWindow.java 2007-01-09 20:25:48 UTC (rev 3062) @@ -38,6 +38,7 @@ package javax.swing; +import java.awt.AWTEvent; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Container; @@ -158,6 +159,10 @@ protected void windowInit() { + // We need to explicitly enable events here so that our processKeyEvent() + // and processWindowEvent() gets called. + enableEvents(AWTEvent.KEY_EVENT_MASK); + super.setLayout(new BorderLayout(1, 1)); getRootPane(); // will do set/create // Now we're done init stage, adds and layouts go to content pane. Modified: trunk/core/src/classpath/javax/javax/swing/LookAndFeel.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/LookAndFeel.java 2007-01-09 20:25:00 UTC (rev 3061) +++ trunk/core/src/classpath/javax/javax/swing/LookAndFeel.java 2007-01-09 20:25:48 UTC (rev 3062) @@ -284,7 +284,7 @@ * @return A {@link UIDefaults.LazyValue} that serves up an * {@link IconUIResource}. */ - public static Object makeIcon(Class baseClass, String gifFile) + public static Object makeIcon(Class<?> baseClass, String gifFile) { final URL file = baseClass.getResource(gifFile); return new UIDefaults.LazyValue() Modified: trunk/core/src/classpath/javax/javax/swing/Popup.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/Popup.java 2007-01-09 20:25:00 UTC (rev 3061) +++ trunk/core/src/classpath/javax/javax/swing/Popup.java 2007-01-09 20:25:48 UTC (rev 3062) @@ -284,7 +284,7 @@ panel.setSize(contents.getSize()); Point layeredPaneLoc = layeredPane.getLocationOnScreen(); panel.setLocation(x - layeredPaneLoc.x, y - layeredPaneLoc.y); - layeredPane.add(panel, JLayeredPane.POPUP_LAYER); + layeredPane.add(panel, JLayeredPane.POPUP_LAYER, 0); panel.repaint(); } Modified: trunk/core/src/classpath/javax/javax/swing/SizeSequence.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/SizeSequence.java 2007-01-09 20:25:00 UTC (rev 3061) +++ trunk/core/src/classpath/javax/javax/swing/SizeSequence.java 2007-01-09 20:25:48 UTC (rev 3062) @@ -129,14 +129,18 @@ } /** - * Returns the size of the specified element. + * Returns the size of the specified element, or 0 if the element index is + * outside the defined range. * * @param index the element index. * - * @return The size of the specified element. + * @return The size of the specified element, or 0 if the element index is + * outside the defined range. */ public int getSize(int index) { + if (index < 0 || index >= sizes.length) + return 0; return sizes[index]; } Modified: trunk/core/src/classpath/javax/javax/swing/SortingFocusTraversalPolicy.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/SortingFocusTraversalPolicy.java 2007-01-09 20:25:00 UTC (rev 3061) +++ trunk/core/src/classpath/javax/javax/swing/SortingFocusTraversalPolicy.java 2007-01-09 20:25:48 UTC (rev 3062) @@ -91,7 +91,7 @@ * * @param comparator the comparator to set */ - public SortingFocusTraversalPolicy(Comparator comparator) + public SortingFocusTraversalPolicy(Comparator<? super Component> comparator) { this.comparator = comparator; } @@ -119,7 +119,7 @@ * * @see #setComparator */ - protected Comparator getComparator() + protected Comparator<? super Component> getComparator() { return comparator; } @@ -131,7 +131,7 @@ * * @see #getComparator */ - protected void setComparator(Comparator comparator) + protected void setComparator(Comparator<? super Component> comparator) { this.comparator = comparator; } Modified: trunk/core/src/classpath/javax/javax/swing/SpinnerListModel.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/SpinnerListModel.java 2007-01-09 20:25:00 UTC (rev 3061) +++ trunk/core/src/classpath/javax/javax/swing/SpinnerListModel.java 2007-01-09 20:25:48 UTC (rev 3062) @@ -118,7 +118,7 @@ * @see SpinnerListModel#getNextValue() * @see SpinnerListModel#getValue() */ - public SpinnerListModel(List list) + public SpinnerListModel(List<?> list) { // Retain a reference to the valid list. setList(list); @@ -163,7 +163,7 @@ * * @return The backing list. */ - public List getList() + public List<?> getList() { return list; } @@ -239,7 +239,7 @@ * * @see ChangeEvent */ - public void setList(List list) + public void setList(List<?> list) { // Check for null or zero size list. if (list == null || list.size() == 0) Modified: trunk/core/src/classpath/javax/javax/swing/Timer.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/Timer.java 2007-01-09 20:25:00 UTC (rev 3061) +++ trunk/core/src/classpath/javax/javax/swing/Timer.java 2007-01-09 20:25:48 UTC (rev 3062) @@ -228,7 +228,7 @@ * fired by this timer * @since 1.3 */ - public EventListener[] getListeners(Class listenerType) + public <T extends EventListener> T[] getListeners(Class<T> listenerType) { return listenerList.getListeners(listenerType); } Modified: trunk/core/src/classpath/javax/javax/swing/UIDefaults.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/UIDefaults.java 2007-01-09 20:25:00 UTC (rev 3061) +++ trunk/core/src/classpath/javax/javax/swing/UIDefaults.java 2007-01-09 20:25:48 UTC (rev 3062) @@ -63,7 +63,7 @@ * * @author Ronald Veldema (rve...@cs...) */ -public class UIDefaults extends Hashtable +public class UIDefaults extends Hashtable<Object, Object> { /** Our ResourceBundles. */ @@ -672,7 +672,7 @@ * * @return the UI class for <code>id</code> */ - public Class getUIClass(String id, ClassLoader loader) + public Class<? extends ComponentUI> getUIClass(String id, ClassLoader loader) { String className = (String) get(id); if (className == null) @@ -681,7 +681,7 @@ { if (loader == null) loader = ClassLoader.getSystemClassLoader(); - return loader.loadClass (className); + return (Class<? extends ComponentUI>) loader.loadClass (className); } catch (Exception e) { @@ -698,7 +698,7 @@ * * @return the UI class for <code>id</code> */ - public Class getUIClass(String id) + public Class<? extends ComponentUI> getUIClass(String id) { return getUIClass (id, null); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ls...@us...> - 2007-02-04 09:46:30
|
Revision: 3106 http://jnode.svn.sourceforge.net/jnode/?rev=3106&view=rev Author: lsantha Date: 2007-02-04 01:46:03 -0800 (Sun, 04 Feb 2007) Log Message: ----------- Classpath patches. Modified Paths: -------------- trunk/core/src/classpath/javax/javax/swing/JComponent.java trunk/core/src/classpath/javax/javax/swing/JDialog.java trunk/core/src/classpath/javax/javax/swing/JFrame.java trunk/core/src/classpath/javax/javax/swing/JInternalFrame.java trunk/core/src/classpath/javax/javax/swing/JLabel.java trunk/core/src/classpath/javax/javax/swing/JLayeredPane.java trunk/core/src/classpath/javax/javax/swing/JMenuItem.java trunk/core/src/classpath/javax/javax/swing/JScrollBar.java trunk/core/src/classpath/javax/javax/swing/JSlider.java trunk/core/src/classpath/javax/javax/swing/JSplitPane.java trunk/core/src/classpath/javax/javax/swing/JTable.java trunk/core/src/classpath/javax/javax/swing/JTree.java trunk/core/src/classpath/javax/javax/swing/JViewport.java trunk/core/src/classpath/javax/javax/swing/RepaintManager.java trunk/core/src/classpath/javax/javax/swing/UIManager.java Modified: trunk/core/src/classpath/javax/javax/swing/JComponent.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/JComponent.java 2007-02-03 20:57:41 UTC (rev 3105) +++ trunk/core/src/classpath/javax/javax/swing/JComponent.java 2007-02-04 09:46:03 UTC (rev 3106) @@ -48,12 +48,10 @@ import java.awt.FocusTraversalPolicy; import java.awt.Font; import java.awt.Graphics; -import java.awt.Graphics2D; import java.awt.Image; import java.awt.Insets; import java.awt.Point; import java.awt.Rectangle; -import java.awt.Shape; import java.awt.Window; import java.awt.dnd.DropTarget; import java.awt.event.ActionEvent; @@ -69,6 +67,7 @@ import java.beans.PropertyChangeListener; import java.beans.PropertyVetoException; import java.beans.VetoableChangeListener; +import java.beans.VetoableChangeSupport; import java.io.Serializable; import java.util.ArrayList; import java.util.EventListener; @@ -506,27 +505,6 @@ } /** - * An explicit value for the component's preferred size; if not set by a - * user, this is calculated on the fly by delegating to the {@link - * ComponentUI#getPreferredSize} method on the {@link #ui} property. - */ - Dimension preferredSize; - - /** - * An explicit value for the component's minimum size; if not set by a - * user, this is calculated on the fly by delegating to the {@link - * ComponentUI#getMinimumSize} method on the {@link #ui} property. - */ - Dimension minimumSize; - - /** - * An explicit value for the component's maximum size; if not set by a - * user, this is calculated on the fly by delegating to the {@link - * ComponentUI#getMaximumSize} method on the {@link #ui} property. - */ - Dimension maximumSize; - - /** * A value between 0.0 and 1.0 indicating the preferred horizontal * alignment of the component, relative to its siblings. The values * {@link #LEFT_ALIGNMENT}, {@link #CENTER_ALIGNMENT}, and {@link @@ -564,12 +542,19 @@ Border border; /** - * The text to show in the tooltip associated with this component. + * The popup menu for the component. * - * @see #setToolTipText - * @see #getToolTipText() + * @see #getComponentPopupMenu() + * @see #setComponentPopupMenu(JPopupMenu) */ - String toolTipText; + JPopupMenu componentPopupMenu; + + /** + * A flag that controls whether the {@link #getComponentPopupMenu()} method + * looks to the component's parent when the <code>componentPopupMenu</code> + * field is <code>null</code>. + */ + boolean inheritsPopupMenu; /** * <p>Whether to double buffer this component when painting. This flag @@ -668,9 +653,15 @@ * Indicates whether the current paint call is already double buffered or * not. */ - static boolean isPaintingDoubleBuffered = false; + static boolean paintingDoubleBuffered = false; /** + * Indicates whether we are calling paintDoubleBuffered() from + * paintImmadiately (RepaintManager) or from paint() (AWT refresh). + */ + static boolean isRepainting = false; + + /** * Listeners for events other than {@link PropertyChangeEvent} are * handled by this listener list. PropertyChangeEvents are handled in * {@link #changeSupport}. @@ -678,6 +669,11 @@ protected EventListenerList listenerList = new EventListenerList(); /** + * Handles VetoableChangeEvents. + */ + private VetoableChangeSupport vetoableChangeSupport; + + /** * Storage for "client properties", which are key/value pairs associated * with this component by a "client", such as a user application or a * layout manager. This is lazily constructed when the component gets its @@ -690,7 +686,7 @@ private ComponentInputMap inputMap_whenInFocusedWindow; private ActionMap actionMap; /** @since 1.3 */ - private boolean verifyInputWhenFocusTarget; + private boolean verifyInputWhenFocusTarget = true; private InputVerifier inputVerifier; private TransferHandler transferHandler; @@ -759,7 +755,14 @@ */ public static final int WHEN_IN_FOCUSED_WINDOW = 2; + /** + * Used to optimize painting. This is set in paintImmediately2() to specify + * the exact component path to be painted by paintChildren. + */ + Component paintChild; + + /** * Indicates if the opaque property has been set by a client program or by * the UI. * @@ -784,7 +787,7 @@ { super(); setDropTarget(new DropTarget()); - defaultLocale = Locale.getDefault(); + setLocale(getDefaultLocale()); debugGraphicsOptions = DebugGraphics.NONE_OPTION; setRequestFocusEnabled(true); } @@ -844,6 +847,11 @@ t.put(key, value); else t.remove(key); + + // When both old and new value are null, no event is fired. This is + // different from what firePropertyChange() normally does, so we add this + // check here. + if (old != null || value != null) firePropertyChange(key.toString(), old, value); } @@ -868,7 +876,8 @@ */ public void removeVetoableChangeListener(VetoableChangeListener listener) { - listenerList.remove(VetoableChangeListener.class, listener); + if (vetoableChangeSupport != null) + vetoableChangeSupport.removeVetoableChangeListener(listener); } /** @@ -884,23 +893,6 @@ } /** - * Register a <code>PropertyChangeListener</code> for a specific, named - * property. To listen to all property changes, regardless of name, use - * {@link #addPropertyChangeListener(PropertyChangeListener)} instead. - * - * @param propertyName The property name to listen to - * @param listener The listener to register - * - * @see #removePropertyChangeListener(String, PropertyChangeListener) - * @see #changeSupport - */ - public void addPropertyChangeListener(String propertyName, - PropertyChangeListener listener) - { - listenerList.add(PropertyChangeListener.class, listener); - } - - /** * Register a <code>VetoableChangeListener</code>. * * @param listener The listener to register @@ -910,7 +902,10 @@ */ public void addVetoableChangeListener(VetoableChangeListener listener) { - listenerList.add(VetoableChangeListener.class, listener); + // Lazily instantiate this, it's rarely needed. + if (vetoableChangeSupport == null) + vetoableChangeSupport = new VetoableChangeSupport(this); + vetoableChangeSupport.addVetoableChangeListener(listener); } /** @@ -932,10 +927,12 @@ * * @since 1.3 */ - public EventListener[] getListeners(Class listenerType) + public <T extends EventListener> T[] getListeners(Class<T> listenerType) { if (listenerType == PropertyChangeListener.class) - return getPropertyChangeListeners(); + return (T[]) getPropertyChangeListeners(); + else if (listenerType == VetoableChangeListener.class) + return (T[]) getVetoableChangeListeners(); else return listenerList.getListeners(listenerType); } @@ -954,60 +951,19 @@ /** * Return all registered <code>VetoableChangeListener</code> objects. * - * @return The set of <code>VetoableChangeListener</code> objects in {@link - * #listenerList} + * @return An array of the <code>VetoableChangeListener</code> objects + * registered with this component (possibly empty but never + * <code>null</code>). + * + * @since 1.4 */ public VetoableChangeListener[] getVetoableChangeListeners() { - return (VetoableChangeListener[]) getListeners(VetoableChangeListener.class); + return vetoableChangeSupport == null ? new VetoableChangeListener[0] + : vetoableChangeSupport.getVetoableChangeListeners(); } /** - * A variant of {@link #firePropertyChange(String,Object,Object)} - * for properties with <code>boolean</code> values. - * - * @specnote It seems that in JDK1.5 all property related methods have been - * moved to java.awt.Component, except this and 2 others. We call - * super here. I guess this will also be removed in one of the next - * releases. - */ - public void firePropertyChange(String propertyName, boolean oldValue, - boolean newValue) - { - super.firePropertyChange(propertyName, oldValue, newValue); - } - - /** - * A variant of {@link #firePropertyChange(String,Object,Object)} - * for properties with <code>char</code> values. - * - * @specnote It seems that in JDK1.5 all property related methods have been - * moved to java.awt.Component, except this and 2 others. We call - * super here. I guess this will also be removed in one of the next - * releases. - */ - public void firePropertyChange(String propertyName, char oldValue, - char newValue) - { - super.firePropertyChange(propertyName, oldValue, newValue); - } - - /** - * A variant of {@link #firePropertyChange(String,Object,Object)} - * for properties with <code>int</code> values. - * - * @specnote It seems that in JDK1.5 all property related methods have been - * moved to java.awt.Component, except this and 2 others. We call - * super here. I guess this will also be removed in one of the next - * releases. - */ - public void firePropertyChange(String propertyName, int oldValue, - int newValue) - { - super.firePropertyChange(propertyName, oldValue, newValue); - } - - /** * Call {@link VetoableChangeListener#vetoableChange} on all listeners * registered to listen to a given property. Any method which changes * the specified property of this component should call this method. @@ -1025,14 +981,45 @@ Object newValue) throws PropertyVetoException { - VetoableChangeListener[] listeners = getVetoableChangeListeners(); + if (vetoableChangeSupport != null) + vetoableChangeSupport.fireVetoableChange(propertyName, oldValue, newValue); + } - PropertyChangeEvent evt = - new PropertyChangeEvent(this, propertyName, oldValue, newValue); - for (int i = 0; i < listeners.length; i++) - listeners[i].vetoableChange(evt); + /** + * Fires a property change for a primitive integer property. + * + * @param property the name of the property + * @param oldValue the old value of the property + * @param newValue the new value of the property + * + * @specnote This method is implemented in + * {@link Component#firePropertyChange(String, int, int)}. It is + * only here because it is specified to be public, whereas the + * Component method is protected. + */ + public void firePropertyChange(String property, int oldValue, int newValue) + { + super.firePropertyChange(property, oldValue, newValue); } + + /** + * Fires a property change for a primitive boolean property. + * + * @param property the name of the property + * @param oldValue the old value of the property + * @param newValue the new value of the property + * + * @specnote This method is implemented in + * {@link Component#firePropertyChange(String, boolean, boolean)}. + * It is only here because it is specified to be public, whereas + * the Component method is protected. + */ + public void firePropertyChange(String property, boolean oldValue, + boolean newValue) + { + super.firePropertyChange(property, oldValue, newValue); + } /** * Get the value of the accessibleContext property for this component. @@ -1252,37 +1239,38 @@ } /** - * Get the component's maximum size. If the {@link #maximumSize} property - * has been explicitly set, it is returned. If the {@link #maximumSize} + * Get the component's maximum size. If the <code>maximumSize</code> property + * has been explicitly set, it is returned. If the <code>maximumSize</code> * property has not been set but the {@link #ui} property has been, the * result of {@link ComponentUI#getMaximumSize} is returned. If neither * property has been set, the result of {@link Container#getMaximumSize} * is returned. * - * @return The maximum size of the component + * @return the maximum size of the component * - * @see #maximumSize - * @see #setMaximumSize + * @see Component#setMaximumSize + * @see Component#getMaximumSize() + * @see Component#isMaximumSizeSet() + * @see ComponentUI#getMaximumSize(JComponent) */ public Dimension getMaximumSize() { - if (maximumSize != null) - return maximumSize; - - if (ui != null) + Dimension size = null; + if (isMaximumSizeSet()) + size = super.getMaximumSize(); + else { - Dimension s = ui.getMaximumSize(this); - if (s != null) - return s; + if (ui != null) + size = ui.getMaximumSize(this); + if (size == null) + size = super.getMaximumSize(); } - - Dimension p = super.getMaximumSize(); - return p; + return size; } /** - * Get the component's minimum size. If the {@link #minimumSize} property - * has been explicitly set, it is returned. If the {@link #minimumSize} + * Get the component's minimum size. If the <code>minimumSize</code> property + * has been explicitly set, it is returned. If the <code>minimumSize</code> * property has not been set but the {@link #ui} property has been, the * result of {@link ComponentUI#getMinimumSize} is returned. If neither * property has been set, the result of {@link Container#getMinimumSize} @@ -1290,95 +1278,55 @@ * * @return The minimum size of the component * - * @see #minimumSize - * @see #setMinimumSize + * @see Component#setMinimumSize + * @see Component#getMinimumSize() + * @see Component#isMinimumSizeSet() + * @see ComponentUI#getMinimumSize(JComponent) */ public Dimension getMinimumSize() { - if (minimumSize != null) - return minimumSize; - - if (ui != null) + Dimension size = null; + if (isMinimumSizeSet()) + size = super.getMinimumSize(); + else { - Dimension s = ui.getMinimumSize(this); - if (s != null) - return s; + if (ui != null) + size = ui.getMinimumSize(this); + if (size == null) + size = super.getMinimumSize(); } - - Dimension p = super.getMinimumSize(); - return p; + return size; } /** - * Get the component's preferred size. If the {@link #preferredSize} - * property has been explicitly set, it is returned. If the {@link - * #preferredSize} property has not been set but the {@link #ui} property - * has been, the result of {@link ComponentUI#getPreferredSize} is + * Get the component's preferred size. If the <code>preferredSize</code> + * property has been explicitly set, it is returned. If the + * <code>preferredSize</code> property has not been set but the {@link #ui} + * property has been, the result of {@link ComponentUI#getPreferredSize} is * returned. If neither property has been set, the result of {@link * Container#getPreferredSize} is returned. * * @return The preferred size of the component * - * @see #preferredSize - * @see #setPreferredSize + * @see Component#setPreferredSize + * @see Component#getPreferredSize() + * @see Component#isPreferredSizeSet() + * @see ComponentUI#getPreferredSize(JComponent) */ public Dimension getPreferredSize() { - Dimension prefSize = null; - if (preferredSize != null) - prefSize = new Dimension(preferredSize); - - else if (ui != null) - { - Dimension s = ui.getPreferredSize(this); - if (s != null) - prefSize = s; - } - - if (prefSize == null) - prefSize = super.getPreferredSize(); - - return prefSize; - } - - /** - * Checks if a maximum size was explicitely set on the component. - * - * @return <code>true</code> if a maximum size was set, - * <code>false</code> otherwise - * - * @since 1.3 - */ - public boolean isMaximumSizeSet() + Dimension size = null; + if (isPreferredSizeSet()) + size = super.getPreferredSize(); + else { - return maximumSize != null; + if (ui != null) + size = ui.getPreferredSize(this); + if (size == null) + size = super.getPreferredSize(); } - - /** - * Checks if a minimum size was explicitely set on the component. - * - * @return <code>true</code> if a minimum size was set, - * <code>false</code> otherwise - * - * @since 1.3 - */ - public boolean isMinimumSizeSet() - { - return minimumSize != null; + return size; } - - /** - * Checks if a preferred size was explicitely set on the component. - * - * @return <code>true</code> if a preferred size was set, - * <code>false</code> otherwise - * - * @since 1.3 - */ - public boolean isPreferredSizeSet() - { - return preferredSize != null; - } /** * Return the value of the <code>nextFocusableComponent</code> property. @@ -1402,11 +1350,32 @@ * Return the set of {@link KeyStroke} objects which are registered * to initiate actions on this component. * - * @return An array of the registered keystrokes + * @return An array of the registered keystrokes (possibly empty but never + * <code>null</code>). */ public KeyStroke[] getRegisteredKeyStrokes() { - return null; + KeyStroke[] ks0; + KeyStroke[] ks1; + KeyStroke[] ks2; + if (inputMap_whenFocused != null) + ks0 = inputMap_whenFocused.keys(); + else + ks0 = new KeyStroke[0]; + if (inputMap_whenAncestorOfFocused != null) + ks1 = inputMap_whenAncestorOfFocused.keys(); + else + ks1 = new KeyStroke[0]; + if (inputMap_whenInFocusedWindow != null) + ks2 = inputMap_whenInFocusedWindow.keys(); + else + ks2 = new KeyStroke[0]; + int count = ks0.length + ks1.length + ks2.length; + KeyStroke[] result = new KeyStroke[count]; + System.arraycopy(ks0, 0, result, 0, ks0.length); + System.arraycopy(ks1, 0, result, ks0.length, ks1.length); + System.arraycopy(ks2, 0, result, ks0.length + ks1.length, ks2.length); + return result; } /** @@ -1452,14 +1421,12 @@ { JToolTip toolTip = new JToolTip(); toolTip.setComponent(this); - toolTip.setTipText(toolTipText); - return toolTip; } /** - * Return the location at which the {@link #toolTipText} property should be - * displayed, when triggered by a particular mouse event. + * Return the location at which the <code>toolTipText</code> property should + * be displayed, when triggered by a particular mouse event. * * @param event The event the tooltip is being presented in response to * @@ -1472,53 +1439,56 @@ } /** - * Set the value of the {@link #toolTipText} property. + * Set the tooltip text for this component. If a non-<code>null</code> + * value is set, this component is registered in the + * <code>ToolTipManager</code> in order to turn on tooltips for this + * component. If a <code>null</code> value is set, tooltips are turne off + * for this component. * - * @param text The new property value + * @param text the tooltip text for this component * * @see #getToolTipText() + * @see #getToolTipText(MouseEvent) */ public void setToolTipText(String text) { + String old = getToolTipText(); + putClientProperty(TOOL_TIP_TEXT_KEY, text); + ToolTipManager ttm = ToolTipManager.sharedInstance(); if (text == null) - { - ToolTipManager.sharedInstance().unregisterComponent(this); - toolTipText = null; - return; - } - - // XXX: The tip text doesn't get updated unless you set it to null - // and then to something not-null. This is consistent with the behaviour - // of Sun's ToolTipManager. - - String oldText = toolTipText; - toolTipText = text; - - if (oldText == null) - ToolTipManager.sharedInstance().registerComponent(this); + ttm.unregisterComponent(this); + else if (old == null) + ttm.registerComponent(this); } /** - * Get the value of the {@link #toolTipText} property. + * Returns the current tooltip text for this component, or <code>null</code> + * if none has been set. * - * @return The current property value + * @return the current tooltip text for this component, or <code>null</code> + * if none has been set * * @see #setToolTipText + * @see #getToolTipText(MouseEvent) */ public String getToolTipText() { - return toolTipText; + return (String) getClientProperty(TOOL_TIP_TEXT_KEY); } /** - * Get the value of the {@link #toolTipText} property, in response to a - * particular mouse event. + * Returns the tooltip text for this component for a particular mouse + * event. This can be used to support context sensitive tooltips that can + * change with the mouse location. By default this returns the static + * tooltip text returned by {@link #getToolTipText()}. * - * @param event The mouse event which triggered the tooltip + * @param event the mouse event which triggered the tooltip * - * @return The current property value + * @return the tooltip text for this component for a particular mouse + * event * * @see #setToolTipText + * @see #getToolTipText() */ public String getToolTipText(MouseEvent event) { @@ -1526,6 +1496,88 @@ } /** + * Returns the flag that controls whether or not the component inherits its + * parent's popup menu when no popup menu is specified for this component. + * + * @return A boolean. + * + * @since 1.5 + * + * @see #setInheritsPopupMenu(boolean) + */ + public boolean getInheritsPopupMenu() + { + return inheritsPopupMenu; + } + + /** + * Sets the flag that controls whether or not the component inherits its + * parent's popup menu when no popup menu is specified for this component. + * This is a bound property with the property name 'inheritsPopupMenu'. + * + * @param inherit the new flag value. + * + * @since 1.5 + * + * @see #getInheritsPopupMenu() + */ + public void setInheritsPopupMenu(boolean inherit) + { + if (inheritsPopupMenu != inherit) + { + inheritsPopupMenu = inherit; + this.firePropertyChange("inheritsPopupMenu", ! inherit, inherit); + } + } + + /** + * Returns the popup menu for this component. If the popup menu is + * <code>null</code> AND the {@link #getInheritsPopupMenu()} method returns + * <code>true</code>, this method will return the parent's popup menu (if it + * has one). + * + * @return The popup menu (possibly <code>null</code>. + * + * @since 1.5 + * + * @see #setComponentPopupMenu(JPopupMenu) + * @see #getInheritsPopupMenu() + */ + public JPopupMenu getComponentPopupMenu() + { + if (componentPopupMenu == null && getInheritsPopupMenu()) + { + Container parent = getParent(); + if (parent instanceof JComponent) + return ((JComponent) parent).getComponentPopupMenu(); + else + return null; + } + else + return componentPopupMenu; + } + + /** + * Sets the popup menu for this component (this is a bound property with + * the property name 'componentPopupMenu'). + * + * @param popup the popup menu (<code>null</code> permitted). + * + * @since 1.5 + * + * @see #getComponentPopupMenu() + */ + public void setComponentPopupMenu(JPopupMenu popup) + { + if (componentPopupMenu != popup) + { + JPopupMenu old = componentPopupMenu; + componentPopupMenu = popup; + firePropertyChange("componentPopupMenu", old, popup); + } + } + + /** * Return the top level ancestral container (usually a {@link * java.awt.Window} or {@link java.applet.Applet}) which this component is * contained within, or <code>null</code> if no ancestors exist. @@ -1725,11 +1777,11 @@ // buffer. When this method completes, the call stack unwinds back to // paintDoubleBuffered, where the buffer contents is finally drawn to the // screen. - if (!isPaintingDoubleBuffered && isDoubleBuffered() + if (!paintingDoubleBuffered && isDoubleBuffered() && rm.isDoubleBufferingEnabled()) { Rectangle clip = g.getClipBounds(); - paintDoubleBuffered(clip); + paintDoubleBuffered(clip.x, clip.y, clip.width, clip.height); } else { @@ -1744,8 +1796,22 @@ dragBuffer = null; } - if (g.getClip() == null) - g.setClip(0, 0, getWidth(), getHeight()); + Rectangle clip = g.getClipBounds(); + int clipX, clipY, clipW, clipH; + if (clip == null) + { + clipX = 0; + clipY = 0; + clipW = getWidth(); + clipH = getHeight(); + } + else + { + clipX = clip.x; + clipY = clip.y; + clipW = clip.width; + clipH = clip.height; + } if (dragBuffer != null && dragBufferInitialized) { g.drawImage(dragBuffer, 0, 0, this); @@ -1753,14 +1819,51 @@ else { Graphics g2 = getComponentGraphics(g); + if (! isOccupiedByChild(clipX, clipY, clipW, clipH)) + { paintComponent(g2); paintBorder(g2); + } paintChildren(g2); } } } /** + * Determines if a region of this component is completely occupied by + * an opaque child component, in which case we don't need to bother + * painting this component at all. + * + * @param x the area, x coordinate + * @param y the area, y coordinate + * @param w the area, width + * @param h the area, height + * + * @return <code>true</code> if the specified area is completely covered + * by a child component, <code>false</code> otherwise + */ + private boolean isOccupiedByChild(int x, int y, int w, int h) + { + boolean occupied = false; + int count = getComponentCount(); + for (int i = 0; i < count; i++) + { + Component child = getComponent(i); + int cx = child.getX(); + int cy = child.getY(); + int cw = child.getWidth(); + int ch = child.getHeight(); + if (child.isVisible() && x >= cx && x + w <= cx + cw && y >= cy + && y + h <= cy + ch) + { + occupied = child.isOpaque(); + break; + } + } + return occupied; + } + + /** * Initializes the drag buffer by creating a new image and painting this * component into it. */ @@ -1816,235 +1919,122 @@ { if (getComponentCount() > 0) { - if (isOptimizedDrawingEnabled()) - paintChildrenOptimized(g); - else - paintChildrenWithOverlap(g); - } - } - - /** - * Paints the children of this JComponent in the case when the component - * is not marked as optimizedDrawingEnabled, that means the container cannot - * guarantee that it's children are tiled. For this case we must - * perform a more complex optimization to determine the minimal rectangle - * to be painted for each child component. - * - * @param g the graphics context to use - */ - private void paintChildrenWithOverlap(Graphics g) - { - Shape originalClip = g.getClip(); - Rectangle inner = SwingUtilities.calculateInnerArea(this, rectCache); - g.clipRect(inner.x, inner.y, inner.width, inner.height); - Component[] children = getComponents(); - - // Find the rectangles that need to be painted for each child component. - // We push on this list arrays that have the Rectangles to be painted as - // the first elements and the component to be painted as the last one. - // Later we go through that list in reverse order and paint the rectangles. - ArrayList paintRegions = new ArrayList(children.length); - ArrayList paintRectangles = new ArrayList(); - ArrayList newPaintRects = new ArrayList(); - paintRectangles.add(g.getClipBounds()); - ArrayList componentRectangles = new ArrayList(); - - // Go through children from top to bottom and find out their paint - // rectangles. - for (int index = 0; paintRectangles.size() > 0 && - index < children.length; index++) - { - Component comp = children[index]; - if (! comp.isVisible()) - continue; - - Rectangle compBounds = comp.getBounds(); - boolean isOpaque = comp instanceof JComponent - && ((JComponent) comp).isOpaque(); - - // Add all the current paint rectangles that intersect with the - // component to the component's paint rectangle array. - for (int i = paintRectangles.size() - 1; i >= 0; i--) - { - Rectangle r = (Rectangle) paintRectangles.get(i); - if (r.intersects(compBounds)) + // Need to lock the tree to avoid problems with AWT and concurrency. + synchronized (getTreeLock()) + { + // Fast forward to the child to paint, if set by + // paintImmediately2() + int i = getComponentCount() - 1; + if (paintChild != null && paintChild.isOpaque()) { - Rectangle compRect = r.intersection(compBounds); - componentRectangles.add(compRect); - // If the component is opaque, split up each paint rect and - // add paintRect - compBounds to the newPaintRects array. - if (isOpaque) + for (; i >= 0 && getComponent(i) != paintChild; i--) + ; + } + for (; i >= 0; i--) + { + Component child = getComponent(i); + if (child != null && child.isLightweight() + && child.isVisible()) { - int x, y, w, h; - Rectangle rect = new Rectangle(); - - // The north retangle. - x = Math.max(compBounds.x, r.x); - y = r.y; - w = Math.min(compBounds.width, r.width + r.x - x); - h = compBounds.y - r.y; - rect.setBounds(x, y, w, h); - if (! rect.isEmpty()) + int cx = child.getX(); + int cy = child.getY(); + int cw = child.getWidth(); + int ch = child.getHeight(); + if (g.hitClip(cx, cy, cw, ch)) { - newPaintRects.add(rect); - rect = new Rectangle(); - } - - // The south rectangle. - x = Math.max(compBounds.x, r.x); - y = compBounds.y + compBounds.height; - w = Math.min(compBounds.width, r.width + r.x - x); - h = r.height - (compBounds.y - r.y) - compBounds.height; - rect.setBounds(x, y, w, h); - if (! rect.isEmpty()) + if ((! isOptimizedDrawingEnabled()) && i > 0) + { + // Check if the child is completely obscured. + Rectangle clip = g.getClipBounds(); // A copy. + SwingUtilities.computeIntersection(cx, cy, cw, ch, + clip); + if (isCompletelyObscured(i, clip.x, clip.y, + clip.width, clip.height)) + continue; // Continues the for-loop. + } + Graphics cg = g.create(cx, cy, cw, ch); + cg.setColor(child.getForeground()); + cg.setFont(child.getFont()); + try { - newPaintRects.add(rect); - rect = new Rectangle(); + child.paint(cg); } - - // The west rectangle. - x = r.x; - y = r.y; - w = compBounds.x - r.x; - h = r.height; - rect.setBounds(x, y, w, h); - if (! rect.isEmpty()) + finally { - newPaintRects.add(rect); - rect = new Rectangle(); + cg.dispose(); } - - // The east rectangle. - x = compBounds.x + compBounds.width; - y = r.y; - w = r.width - (compBounds.x - r.x) - compBounds.width; - h = r.height; - rect.setBounds(x, y, w, h); - if (! rect.isEmpty()) - { - newPaintRects.add(rect); - } } - else - { - // Not opaque, need to reuse the current paint rectangles - // for the next component. - newPaintRects.add(r); } - } - else - { - newPaintRects.add(r); - } } - - // Replace the paintRectangles with the new split up - // paintRectangles. - paintRectangles.clear(); - paintRectangles.addAll(newPaintRects); - newPaintRects.clear(); - - // Store paint rectangles if there are any for the current component. - int compRectsSize = componentRectangles.size(); - if (compRectsSize > 0) - { - componentRectangles.add(comp); - paintRegions.add(componentRectangles); - componentRectangles = new ArrayList(); } } - // paintingTile becomes true just before we start painting the component's - // children. - paintingTile = true; - - // We must go through the painting regions backwards, because the - // topmost components have been added first, followed by the components - // below. - int prEndIndex = paintRegions.size() - 1; - for (int i = prEndIndex; i >= 0; i--) + /** + * Determines if a region of a child component is completely obscured by one + * of its siblings. + * + * @param index the index of the child component + * @param x the region to check, x coordinate + * @param y the region to check, y coordinate + * @param w the region to check, width + * @param h the region to check, height + * + * @return <code>true</code> if the region is completely obscured by a + * sibling, <code>false</code> otherwise + */ + private boolean isCompletelyObscured(int index, int x, int y, int w, int h) { - // paintingTile must be set to false before we begin to start painting - // the last tile. - if (i == 0) - paintingTile = false; - - ArrayList paintingRects = (ArrayList) paintRegions.get(i); - // The last element is always the component. - Component c = (Component) paintingRects.get(paintingRects.size() - 1); - int endIndex = paintingRects.size() - 2; - for (int j = 0; j <= endIndex; j++) + boolean obscured = false; + for (int i = index - 1; i >= 0 && obscured == false; i--) { - Rectangle cBounds = c.getBounds(); - Rectangle bounds = (Rectangle) paintingRects.get(j); - Rectangle oldClip = g.getClipBounds(); - if (oldClip == null) - oldClip = bounds; - - boolean translated = false; - try + Component sib = getComponent(i); + if (sib.isVisible()) { - g.setClip(bounds); - g.translate(cBounds.x, cBounds.y); - translated = true; - c.paint(g); - } - finally + Rectangle sibRect = sib.getBounds(rectCache); + if (sib.isOpaque() && x >= sibRect.x + && (x + w) <= (sibRect.x + sibRect.width) + && y >= sibRect.y + && (y + h) <= (sibRect.y + sibRect.height)) { - if (translated) - g.translate(-cBounds.x, -cBounds.y); - g.setClip(oldClip); + obscured = true; } } } - g.setClip(originalClip); + return obscured; } /** - * Paints the children of this container when it is marked as - * optimizedDrawingEnabled. In this case the container can guarantee that - * it's children are tiled, which allows for a much more efficient - * algorithm to determine the minimum rectangles to be painted for - * each child. + * Checks if a component/rectangle is partially obscured by one of its + * siblings. + * Note that this doesn't check for completely obscured, this is + * done by isCompletelyObscured() and should probably also be checked. * - * @param g the graphics context to use + * @param i the component index from which to start searching + * @param x the x coordinate of the rectangle to check + * @param y the y coordinate of the rectangle to check + * @param w the width of the rectangle to check + * @param h the height of the rectangle to check + * + * @return <code>true</code> if the rectangle is partially obscured */ - private void paintChildrenOptimized(Graphics g) + private boolean isPartiallyObscured(int i, int x, int y, int w, int h) { - Shape originalClip = g.getClip(); - Rectangle inner = SwingUtilities.calculateInnerArea(this, rectCache); - g.clipRect(inner.x, inner.y, inner.width, inner.height); - Component[] children = getComponents(); - - // paintingTile becomes true just before we start painting the component's - // children. - paintingTile = true; - for (int i = children.length - 1; i >= 0; i--) //children.length; i++) + boolean obscured = false; + for (int j = i - 1; j >= 0 && ! obscured; j--) { - // paintingTile must be set to false before we begin to start painting - // the last tile. - if (i == children.length - 1) - paintingTile = false; - - if (!children[i].isVisible()) - continue; - - Rectangle bounds = children[i].getBounds(rectCache); - Rectangle oldClip = g.getClipBounds(); - if (oldClip == null) - oldClip = bounds; - - if (!g.hitClip(bounds.x, bounds.y, bounds.width, bounds.height)) - continue; - - boolean translated = false; - Graphics g2 = g.create(bounds.x, bounds.y, bounds.width, - bounds.height); - children[i].paint(g2); - g2.dispose(); + Component sibl = getComponent(j); + if (sibl.isVisible()) + { + Rectangle rect = sibl.getBounds(rectCache); + if (!(x + w <= rect.x) + || (y + h <= rect.y) + || (x >= rect.x + rect.width) + || (y >= rect.y + rect.height)) + obscured = true; + } } - g.setClip(originalClip); + return obscured; } /** @@ -2064,14 +2054,17 @@ { if (ui != null) { - Graphics g2 = g; - if (!(g instanceof Graphics2D)) - g2 = g.create(); + Graphics g2 = g.create(); + try + { ui.update(g2, this); - if (!(g instanceof Graphics2D)) + } + finally + { g2.dispose(); } } + } /** * A variant of {@link #paintImmediately(Rectangle)} which takes @@ -2084,7 +2077,26 @@ */ public void paintImmediately(int x, int y, int w, int h) { - paintImmediately(new Rectangle(x, y, w, h)); + // Find opaque parent and call paintImmediately2() on it. + if (isShowing()) + { + Component c = this; + Component p; + while (c != null && ! c.isOpaque()) + { + p = c.getParent(); + if (p != null) + { + x += c.getX(); + y += c.getY(); + c = p; + } + } + if (c instanceof JComponent) + ((JComponent) c).paintImmediately2(x, y, w, h); + else + c.repaint(x, y, w, h); + } } /** @@ -2107,102 +2119,267 @@ */ public void paintImmediately(Rectangle r) { - // Try to find a root pane for this component. - //Component root = findPaintRoot(r); - Component root = findPaintRoot(r); - // If no paint root is found, then this component is completely overlapped - // by another component and we don't need repainting. - if (root == null) - return; - if (root == null || !root.isShowing()) - return; - - Rectangle rootClip = SwingUtilities.convertRectangle(this, r, root); - if (root instanceof JComponent) - ((JComponent) root).paintImmediately2(rootClip); - else - root.repaint(rootClip.x, rootClip.y, rootClip.width, rootClip.height); + paintImmediately(r.x, r.y, r.width, r.height); } /** * Performs the actual work of paintImmediatly on the repaint root. * - * @param r the area to be repainted + * @param x the area to be repainted, X coordinate + * @param y the area to be repainted, Y coordinate */ - void paintImmediately2(Rectangle r) + void paintImmediately2(int x, int y, int w, int h) { + // Optimization for components that are always painted on top. + boolean onTop = onTop() && isOpaque(); + + // Fetch the RepaintManager. RepaintManager rm = RepaintManager.currentManager(this); - if (rm.isDoubleBufferingEnabled() && isDoubleBuffered()) - paintDoubleBuffered(r); + + // The painting clip; + int paintX = x; + int paintY = y; + int paintW = w; + int paintH = h; + + // If we should paint buffered or not. + boolean haveBuffer = false; + + // The component that is finally triggered for painting. + JComponent paintRoot = this; + + // Stores the component and all its parents. This will be used to limit + // the actually painted components in paintChildren by setting + // the field paintChild. + int pIndex = -1; + int pCount = 0; + ArrayList components = new ArrayList(); + + // Offset to subtract from the paintRoot rectangle when painting. + int offsX = 0; + int offsY = 0; + + // The current component and its child. + Component child; + Container c; + + // Find appropriate paint root. + for (c = this, child = null; + c != null && ! (c instanceof Window) && ! (c instanceof Applet); + child = c, c = c.getParent()) + { + JComponent jc = c instanceof JComponent ? (JComponent) c : null; + components.add(c); + if (! onTop && jc != null && ! jc.isOptimizedDrawingEnabled()) + { + // Indicates whether we reset the paint root to be the current + // component. + boolean updatePaintRoot = false; + + // Check obscured state of the child. + // Generally, we have 3 cases here: + // 1. Not obscured. No need to paint from the parent. + // 2. Partially obscured. Paint from the parent. + // 3. Completely obscured. No need to paint anything. + if (c != this) + { + if (jc.isPaintRoot()) + updatePaintRoot = true; else - paintSimple(r); + { + int count = c.getComponentCount(); + int i = 0; + for (; i < count && c.getComponent(i) != child; i++) + ; + + if (jc.isCompletelyObscured(i, paintX, paintY, paintW, + paintH)) + return; // No need to paint anything. + else if (jc.isPartiallyObscured(i, paintX, paintY, paintW, + paintH)) + updatePaintRoot = true; + + } + } + if (updatePaintRoot) + { + // Paint from parent. + paintRoot = jc; + pIndex = pCount; + offsX = 0; + offsY = 0; + haveBuffer = false; + } + } + pCount++; + // Check if component is double buffered. + if (rm.isDoubleBufferingEnabled() && jc != null + && jc.isDoubleBuffered()) + { + haveBuffer = true; + } + + // Clip the paint region with the parent. + if (! onTop) + { + paintX = Math.max(0, paintX); + paintY = Math.max(0, paintY); + paintW = Math.min(c.getWidth(), paintW + paintX) - paintX; + paintH = Math.min(c.getHeight(), paintH + paintY) - paintY; + int dx = c.getX(); + int dy = c.getY(); + paintX += dx; + paintY += dy; + offsX += dx; + offsY += dy; + } + } + if (c != null && c.getPeer() != null && paintW > 0 && paintH > 0) + { + isRepainting = true; + paintX -= offsX; + paintY -= offsY; + + // Set the painting path so that paintChildren paints only what we + // want. + if (paintRoot != this) + { + for (int i = pIndex; i > 0; i--) + { + Component paintParent = (Component) components.get(i); + if (paintParent instanceof JComponent) + ((JComponent) paintParent).paintChild = + (Component) components.get(i - 1); + } + } + + // Actually trigger painting. + if (haveBuffer) + paintRoot.paintDoubleBuffered(paintX, paintY, paintW, paintH); + else + { + Graphics g = paintRoot.getGraphics(); + try + { + g.setClip(paintX, paintY, paintW, paintH); + paintRoot.paint(g); + } + finally + { + g.dispose(); + } + } + + // Reset the painting path. + if (paintRoot != this) + { + for (int i = pIndex; i > 0; i--) + { + Component paintParent = (Component) components.get(i); + if (paintParent instanceof JComponent) + ((JComponent) paintParent).paintChild = null; + } + } + + isRepainting = false; + } } /** - * Gets the root of the component given. If a parent of the - * component is an instance of Applet, then the applet is - * returned. The applet is considered the root for painting - * and adding/removing components. Otherwise, the root Window - * is returned if it exists. + * Returns <code>true</code> if the component is guaranteed to be painted + * on top of others. This returns false by default and is overridden by + * components like JMenuItem, JPopupMenu and JToolTip to return true for + * added efficiency. * - * @param comp - The component to get the root for. - * @return the parent root. An applet if it is a parent, - * or the root window. If neither exist, null is returned. + * @return <code>true</code> if the component is guaranteed to be painted + * on top of others */ - private Component getRoot(Component comp) + boolean onTop() { - Applet app = null; - - while (comp != null) - { - if (app == null && comp instanceof Window) - return comp; - else if (comp instanceof Applet) - app = (Applet) comp; - comp = comp.getParent(); + return false; } - return app; + /** + * This returns true when a component needs to force itself as a paint + * origin. This is used for example in JViewport to make sure that it + * gets to update its backbuffer. + * + * @return true when a component needs to force itself as a paint + * origin + */ + boolean isPaintRoot() + { + return false; } /** * Performs double buffered repainting. */ - private void paintDoubleBuffered(Rectangle r) + private void paintDoubleBuffered(int x, int y, int w, int h) { RepaintManager rm = RepaintManager.currentManager(this); // Paint on the offscreen buffer. - Component root = getRoot(this); + Component root = SwingUtilities.getRoot(this); Image buffer = rm.getVolatileOffscreenBuffer(this, root.getWidth(), root.getHeight()); + // The volatile offscreen buffer may be null when that's not supported // by the AWT backend. Fall back to normal backbuffer in this case. if (buffer == null) buffer = rm.getOffscreenBuffer(this, root.getWidth(), root.getHeight()); //Rectangle targetClip = SwingUtilities.convertRectangle(this, r, root); - Point translation = SwingUtilities.convertPoint(this, 0, 0, root); Graphics g2 = buffer.getGraphics(); - g2.translate(translation.x, translation.y); - g2.setClip(r.x, r.y, r.width, r.height); + clipAndTranslateGraphics(root, this, g2); + g2.clipRect(x, y, w, h); g2 = getComponentGraphics(g2); - isPaintingDoubleBuffered = true; + paintingDoubleBuffered = true; try { + if (isRepainting) // Called from paintImmediately, go through paint(). paint(g2); + else // Called from paint() (AWT refresh), don't call it again. + { + paintComponent(g2); + paintBorder(g2); + paintChildren(g2); + } } finally { - isPaintingDoubleBuffered = false; + paintingDoubleBuffered = false; g2.dispose(); } // Paint the buffer contents on screen. - rm.commitBuffer(root, new Rectangle(translation.x + r.x, - translation.y + r.y, r.width, - r.height)); + rm.commitBuffer(this, x, y, w, h); + } + + /** + * Clips and translates the Graphics instance for painting on the double + * buffer. This has to be done, so that it reflects the component clip of the + * target component. + * + * @param root the root component (top-level container usually) + * @param target the component to be painted + * @param g the Graphics instance + */ + private void clipAndTranslateGraphics(Component root, Component target, + Graphics g) + { + Component parent = target; + int deltaX = 0; + int deltaY = 0; + while (parent != root) + { + deltaX += parent.getX(); + deltaY += parent.getY(); + parent = parent.getParent(); } + g.translate(deltaX, deltaY); + g.clipRect(0, 0, target.getWidth(), target.getHeight()); + } /** * Performs normal painting without double buffering. @@ -2251,6 +2428,12 @@ * A variant of {@link * #registerKeyboardAction(ActionListener,String,KeyStroke,int)} which * provides <code>null</code> for the command name. + * + * @param act the action listener to notify when the keystroke occurs. + * @param stroke the key stroke. + * @param cond the condition (one of {@link #WHEN_FOCUSED}, + * {@link #WHEN_IN_FOCUSED_WINDOW} and + * {@link #WHEN_ANCESTOR_OF_FOCUSED_COMPONENT}). */ public void registerKeyboardAction(ActionListener act, KeyStroke stroke, @@ -2327,9 +2510,22 @@ KeyStroke stroke, int cond) { - getInputMap(cond).put(stroke, new ActionListenerProxy(act, cmd)); + ActionListenerProxy proxy = new ActionListenerProxy(act, cmd); + getInputMap(cond).put(stroke, proxy); + getActionMap().put(proxy, proxy); } + /** + * Sets the input map for the given condition. + * + * @param condition the condition (one of {@link #WHEN_FOCUSED}, + * {@link #WHEN_IN_FOCUSED_WINDOW} and + * {@link #WHEN_ANCESTOR_OF_FOCUSED_COMPONENT}). + * @param map the map. + * + * @throws IllegalArgumentException if <code>condition</code> is not one of + * the specified values. + */ public final void setInputMap(int condition, InputMap map) { enableEvents(AWTEvent.KEY_EVENT_MASK); @@ -2465,13 +2661,17 @@ */ public ActionListener getActionForKeyStroke(KeyStroke ks) { - Object cmd = getInputMap().get(ks); - if (cmd != null) + Object key = getInputMap(JComponent.WHEN_FOCUSED).get(ks); + if (key == null) + key = getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).get(ks); + if (key == null) + key = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).get(ks); + if (key != null) { - if (cmd instanceof ActionListenerProxy) - return (ActionListenerProxy) cmd; - else if (cmd instanceof String) - return getActionMap().get(cmd); + if (key instanceof ActionListenerProxy) + return ((ActionListenerProxy) key).target; + else + return getActionMap().get(key); } return null; } @@ -2570,20 +2770,37 @@ if (isEnabled()) { Action act = null; + Object cmd = null; InputMap map = getInputMap(condition); if (map != null) { - Object cmd = map.get(ks); + cmd = map.get(ks); if (cmd != null) { if (cmd instanceof ActionListenerProxy) act = (Action) cmd; else - act = (Action) getActionMap().get(cmd); + act = getActionMap().get(cmd); } } if (act != null && act.isEnabled()) - return SwingUtilities.notifyAction(act, ks, e, this, e.getModifiers()); + { + // Need to synchronize here so we don't get in trouble with + // our __command__ hack. + synchronized (act) + { + // We add the command as value to the action, so that + // the action can later determine the command with which it + // was called. This is undocumented, but shouldn't affect + // compatibility. It allows us to use only one Action instance + // to do the work for all components of one type, instead of + // having loads of small Actions. This effectivly saves startup + // time of Swing. + act.putValue("__command__", cmd); + return SwingUtilities.notifyAction(act, ks, e, this, + e.getModifiers()); + } + } } return false; } @@ -2685,6 +2902,11 @@ */ public void revalidate() { + // As long as we don't have a parent we don't need to do any layout, since + // this is done anyway as soon as we get connected to a parent. + if (getParent() == null) + return; + if (! EventQueue.isDispatchThread()) SwingUtilities.invokeLater(new Runnable() { @@ -2708,9 +2930,25 @@ */ public void scrollRectToVisible(Rectangle r) { - Component p = getParent(); - if (p instanceof JComponent) - ((JComponent) p).scrollRectToVisible(r); + // Search nearest JComponent. + int xOffs = getX(); + int yOffs = getY(); + Component p; + for (p = getParent(); p != null && ! (p instanceof JComponent); + p = p.getParent()) + { + xOffs += p.getX(); + yOffs += p.getY(); + } + if (p != null) + { + r.x += xOffs; + r.y += yOffs; + JComponent jParent = (JComponent) p; + jParent.scrollRectToVisible(r); + r.x -= xOffs; + r.y -= yOffs; + } } /** @@ -2829,57 +3067,6 @@ } /** - * Set the value of the {@link #maximumSize} property. The passed value is - * copied, the later direct changes on the argument have no effect on the - * property value. - * - * @param max The new value of the property - */ - public void setMaximumSize(Dimension max) - { - Dimension oldMaximumSize = maximumSize; - if (max != null) - maximumSize = new Dimension(max); - else - maximumSize = null; - firePropertyChange("maximumSize", oldMaximumSize, maximumSize); - } - - /** - * Set the value of the {@link #minimumSize} property. The passed value is - * copied, the later direct changes on the argument have no effect on the - * property value. - * - * @param min The new value of the property - */ - public void setMinimumSize(Dimension min) - { - Dimension oldMinimumSize = minimumSize; - if (min != null) - minimumSize = new Dimension(min); - else - minimumSize = null; - firePropertyChange("minimumSize", oldMinimumSize, minimumSize); - } - - /** - * Set the value of the {@link #preferredSize} property. The passed value is - * copied, the later direct changes on the argument have no effect on the - * property value. - * - * @param pref The new value of the property - */ - public void setPreferredSize(Dimension pref) - { - Dimension oldPreferredSize = preferredSize; - if (pref != null) - preferredSize = new Dimension(pref); - else - preferredSize = null; - firePropertyChange("preferredSize", oldPreferredSize, preferredSize); - } - - /** * Set the specified component to be the next component in the * focus cycle, overriding the {@link FocusTraversalPolicy} for * this component. @@ -3068,11 +3255,29 @@ // Nothing to do here. } + /** + * Returns the locale used as the default for all new components. The + * default value is {@link Locale#getDefault()} (that is, the platform + * default locale). + * + * @return The locale (never <code>null</code>). + * + * @see #setDefaultLocale(Locale) + */ public static Locale getDefaultLocale() { + if (defaultLocale == null) + defaultLocale = Locale.getDefault(); return defaultLocale; } + /** + * Sets the locale to be used as the default for all new components. If this + * is set to <code>null</code>, the {@link #getDefaultLocale()} method will + * return the platform default locale. + * + * @param l the locale (<code>null</code> permitted). + */ public static void setDefaultLocale(Locale l) { defaultLocale = l; @@ -3510,141 +3715,18 @@ } } // Dispatch event to all children. - Component[] children = getComponents(); - for (int i = 0; i < children.leng... [truncated message content] |
From: <ls...@us...> - 2007-07-07 12:37:31
|
Revision: 3353 http://jnode.svn.sourceforge.net/jnode/?rev=3353&view=rev Author: lsantha Date: 2007-07-07 05:37:26 -0700 (Sat, 07 Jul 2007) Log Message: ----------- Openjdk integration. Modified Paths: -------------- trunk/core/src/classpath/javax/javax/swing/JComponent.java trunk/core/src/classpath/javax/javax/swing/JDesktopPane.java trunk/core/src/classpath/javax/javax/swing/JEditorPane.java trunk/core/src/classpath/javax/javax/swing/JInternalFrame.java trunk/core/src/classpath/javax/javax/swing/JList.java trunk/core/src/classpath/javax/javax/swing/JTabbedPane.java trunk/core/src/classpath/javax/javax/swing/JTable.java trunk/core/src/classpath/javax/javax/swing/JTree.java trunk/core/src/classpath/javax/javax/swing/LookAndFeel.java trunk/core/src/classpath/javax/javax/swing/TransferHandler.java trunk/core/src/classpath/javax/javax/swing/UIDefaults.java trunk/core/src/classpath/javax/javax/swing/border/AbstractBorder.java trunk/core/src/classpath/javax/javax/swing/plaf/ComponentUI.java trunk/core/src/classpath/javax/javax/swing/plaf/basic/BasicComboBoxUI.java trunk/core/src/classpath/javax/javax/swing/plaf/basic/BasicComboPopup.java trunk/core/src/classpath/javax/javax/swing/plaf/basic/BasicDirectoryModel.java trunk/core/src/classpath/javax/javax/swing/plaf/basic/BasicGraphicsUtils.java trunk/core/src/classpath/javax/javax/swing/plaf/basic/BasicInternalFrameTitlePane.java trunk/core/src/classpath/javax/javax/swing/plaf/basic/BasicListUI.java trunk/core/src/classpath/javax/javax/swing/plaf/basic/BasicLookAndFeel.java trunk/core/src/classpath/javax/javax/swing/plaf/basic/BasicMenuItemUI.java trunk/core/src/classpath/javax/javax/swing/plaf/basic/BasicScrollBarUI.java trunk/core/src/classpath/javax/javax/swing/plaf/basic/BasicScrollPaneUI.java trunk/core/src/classpath/javax/javax/swing/plaf/basic/BasicSliderUI.java trunk/core/src/classpath/javax/javax/swing/plaf/basic/BasicSplitPaneUI.java trunk/core/src/classpath/javax/javax/swing/text/DefaultCaret.java trunk/core/src/classpath/javax/javax/swing/text/DefaultEditorKit.java trunk/core/src/classpath/javax/javax/swing/text/JTextComponent.java Modified: trunk/core/src/classpath/javax/javax/swing/JComponent.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/JComponent.java 2007-07-06 11:09:17 UTC (rev 3352) +++ trunk/core/src/classpath/javax/javax/swing/JComponent.java 2007-07-07 12:37:26 UTC (rev 3353) @@ -3796,4 +3796,169 @@ + propertyName); } } + + //jnode openjdk + /** + * Calculates a custom drop location for this type of component, + * representing where a drop at the given point should insert data. + * <code>null</code> is returned if this component doesn't calculate + * custom drop locations. In this case, <code>TransferHandler</code> + * will provide a default <code>DropLocation</code> containing just + * the point. + * + * @param p the point to calculate a drop location for + * @return the drop location, or <code>null</code> + */ + TransferHandler.DropLocation dropLocationForPoint(Point p) { + return null; + } + + /** + * Returns <code>true</code> if the current painting operation on this + * component is part of a <code>print</code> operation. This method is + * useful when you want to customize what you print versus what you show + * on the screen. + * <p> + * You can detect changes in the value of this property by listening for + * property change events on this component with name + * <code>"paintingForPrint"</code>. + * <p> + * Note: This method provides complimentary functionality to that provided + * by other high level Swing printing APIs. However, it deals strictly with + * painting and should not be confused as providing information on higher + * level print processes. For example, a {@link javax.swing.JTable#print()} + * operation doesn't necessarily result in a continuous rendering of the + * full component, and the return value of this method can change multiple + * times during that operation. It is even possible for the component to be + * painted to the screen while the printing process is ongoing. In such a + * case, the return value of this method is <code>true</code> when, and only + * when, the table is being painted as part of the printing process. + * + * @return true if the current painting operation on this component + * is part of a print operation + * @see #print + * @since 1.6 + */ + public final boolean isPaintingForPrint() { + return getFlag(IS_PRINTING); + } + private void setFlag(int aFlag, boolean aValue) { + if(aValue) { + flags |= (1 << aFlag); + } else { + flags &= ~(1 << aFlag); + } + } + private boolean getFlag(int aFlag) { + int mask = (1 << aFlag); + return ((flags & mask) == mask); + } + private int flags; + + /** Private flags **/ + private static final int IS_DOUBLE_BUFFERED = 0; + private static final int ANCESTOR_USING_BUFFER = 1; + private static final int IS_PAINTING_TILE = 2; + private static final int IS_OPAQUE = 3; + private static final int KEY_EVENTS_ENABLED = 4; + private static final int FOCUS_INPUTMAP_CREATED = 5; + private static final int ANCESTOR_INPUTMAP_CREATED = 6; + private static final int WIF_INPUTMAP_CREATED = 7; + private static final int ACTIONMAP_CREATED = 8; + private static final int CREATED_DOUBLE_BUFFER = 9; + // bit 10 is free + private static final int IS_PRINTING = 11; + private static final int IS_PRINTING_ALL = 12; + private static final int IS_REPAINTING = 13; + /** Bits 14-21 are used to handle nested writeObject calls. **/ + private static final int WRITE_OBJ_COUNTER_FIRST = 14; + private static final int RESERVED_1 = 15; + private static final int RESERVED_2 = 16; + private static final int RESERVED_3 = 17; + private static final int RESERVED_4 = 18; + private static final int RESERVED_5 = 19; + private static final int RESERVED_6 = 20; + private static final int WRITE_OBJ_COUNTER_LAST = 21; + + private static final int REQUEST_FOCUS_DISABLED = 22; + private static final int INHERITS_POPUP_MENU = 23; + private static final int OPAQUE_SET = 24; + private static final int AUTOSCROLLS_SET = 25; + private static final int FOCUS_TRAVERSAL_KEYS_FORWARD_SET = 26; + private static final int FOCUS_TRAVERSAL_KEYS_BACKWARD_SET = 27; + private static final int REVALIDATE_RUNNABLE_SCHEDULED = 28; + + /** + * Returns the baseline. The baseline is measured from the top of + * the component. This method is primarily meant for + * <code>LayoutManager</code>s to align components along their + * baseline. A return value less than 0 indicates this component + * does not have a reasonable baseline and that + * <code>LayoutManager</code>s should not align this component on + * its baseline. + * <p> + * This method calls into the <code>ComponentUI</code> method of the + * same name. If this component does not have a <code>ComponentUI</code> + * -1 will be returned. If a value >= 0 is + * returned, then the component has a valid baseline for any + * size >= the minimum size and <code>getBaselineResizeBehavior</code> + * can be used to determine how the baseline changes with size. + * + * @throws IllegalArgumentException {@inheritDoc} + * @see #getBaselineResizeBehavior + * @see java.awt.FontMetrics + * @since 1.6 + */ + public int getBaseline(int width, int height) { + // check size. + super.getBaseline(width, height); + if (ui != null) { + return ui.getBaseline(this, width, height); + } + return -1; + } + + /** + * Returns the preferred location to display the popup menu in this + * component's coordinate system. It is up to the look and feel to + * honor this property, some may choose to ignore it. + * If {@code null}, the look and feel will choose a suitable location. + * + * @param event the {@code MouseEvent} that triggered the popup to be + * shown, or {@code null} if the popup is not being shown as the + * result of a mouse event + * @return location to display the {@code JPopupMenu}, or {@code null} + * @since 1.5 + */ + public Point getPopupLocation(MouseEvent event) { + return null; + } + + /** + * Returns an enum indicating how the baseline of the component + * changes as the size changes. This method is primarily meant for + * layout managers and GUI builders. + * <p> + * This method calls into the <code>ComponentUI</code> method of + * the same name. If this component does not have a + * <code>ComponentUI</code> + * <code>BaselineResizeBehavior.OTHER</code> will be + * returned. Subclasses should + * never return <code>null</code>; if the baseline can not be + * calculated return <code>BaselineResizeBehavior.OTHER</code>. Callers + * should first ask for the baseline using + * <code>getBaseline</code> and if a value >= 0 is returned use + * this method. It is acceptable for this method to return a + * value other than <code>BaselineResizeBehavior.OTHER</code> even if + * <code>getBaseline</code> returns a value less than 0. + * + * @see #getBaseline(int, int) + * @since 1.6 + */ + public BaselineResizeBehavior getBaselineResizeBehavior() { + if (ui != null) { + return ui.getBaselineResizeBehavior(this); + } + return BaselineResizeBehavior.OTHER; + } } Modified: trunk/core/src/classpath/javax/javax/swing/JDesktopPane.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/JDesktopPane.java 2007-07-06 11:09:17 UTC (rev 3352) +++ trunk/core/src/classpath/javax/javax/swing/JDesktopPane.java 2007-07-07 12:37:26 UTC (rev 3353) @@ -381,4 +381,50 @@ super.setUIProperty(propertyName, value); } } + + //jnode openjdk + /** + * Selects the next <code>JInternalFrame</code> in this desktop pane. + * + * @param forward a boolean indicating which direction to select in; + * <code>true</code> for forward, <code>false</code> for + * backward + * @return the JInternalFrame that was selected or <code>null</code> + * if nothing was selected + * @since 1.6 + */ + public JInternalFrame selectFrame(boolean forward) { + JInternalFrame selectedFrame = getSelectedFrame(); + JInternalFrame frameToSelect = getNextFrame(selectedFrame, forward); + if (frameToSelect == null) { + return null; + } + // Maintain navigation traversal order until an + // external stack change, such as a click on a frame. + setComponentOrderCheckingEnabled(false); + if (forward && selectedFrame != null) { + selectedFrame.moveToBack(); // For Windows MDI fidelity. + } + try { frameToSelect.setSelected(true); + } catch (PropertyVetoException pve) {} + setComponentOrderCheckingEnabled(true); + return frameToSelect; + } + + /* + * Sets whether component order checking is enabled. + * @param enable a boolean value, where <code>true</code> means + * a change in component order will cause a change in the keyboard + * navigation order. + * @since 1.6 + */ + void setComponentOrderCheckingEnabled(boolean enable) { + componentOrderCheckingEnabled = enable; + } + private boolean componentOrderCheckingEnabled = true; + + private JInternalFrame getNextFrame(JInternalFrame f, boolean forward) { + return null; + } + } Modified: trunk/core/src/classpath/javax/javax/swing/JEditorPane.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/JEditorPane.java 2007-07-06 11:09:17 UTC (rev 3352) +++ trunk/core/src/classpath/javax/javax/swing/JEditorPane.java 2007-07-07 12:37:26 UTC (rev 3353) @@ -1219,4 +1219,32 @@ { return (HyperlinkListener[]) getListeners(HyperlinkListener.class); } + + //jnode openjdk + /** + * Key for a client property used to indicate whether + * the default font and foreground color from the component are + * used if a font or foreground color is not specified in the styled + * text. + * <p> + * The default varies based on the look and feel; + * to enable it set the client {@link #putClientProperty property} with + * this name to <code>Boolean.TRUE</code>. + * + * @since 1.5 + */ + public static final String HONOR_DISPLAY_PROPERTIES = "JEditorPane.honorDisplayProperties"; + + /** + * Key for a client property used to indicate whether + * <a href="http://www.w3.org/TR/CSS21/syndata.html#length-units"> + * w3c compliant</a> length units are used for html rendering. + * <p> + * By default this is not enabled; to enable + * it set the client {@link #putClientProperty property} with this name + * to <code>Boolean.TRUE</code>. + * + * @since 1.5 + */ + public static final String W3C_LENGTH_UNITS = "JEditorPane.w3cLengthUnits"; } Modified: trunk/core/src/classpath/javax/javax/swing/JInternalFrame.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/JInternalFrame.java 2007-07-06 11:09:17 UTC (rev 3352) +++ trunk/core/src/classpath/javax/javax/swing/JInternalFrame.java 2007-07-07 12:37:26 UTC (rev 3353) @@ -38,14 +38,7 @@ package javax.swing; -import java.awt.BorderLayout; -import java.awt.Component; -import java.awt.Container; -import java.awt.Graphics; -import java.awt.IllegalComponentStateException; -import java.awt.KeyboardFocusManager; -import java.awt.LayoutManager; -import java.awt.Rectangle; +import java.awt.*; import java.beans.PropertyChangeEvent; import java.beans.PropertyVetoException; @@ -1817,4 +1810,18 @@ { super.fireVetoableChange(name, Boolean.valueOf(oldValue), Boolean.valueOf(newValue)); } + + /** + * Returns the last <code>Cursor</code> that was set by the + * <code>setCursor</code> method that is not a resizable + * <code>Cursor</code>. + * + * @return the last non-resizable <code>Cursor</code> + * @since 1.6 + */ + public Cursor getLastCursor() { + return lastCursor; + } + + private Cursor lastCursor; } Modified: trunk/core/src/classpath/javax/javax/swing/JList.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/JList.java 2007-07-06 11:09:17 UTC (rev 3352) +++ trunk/core/src/classpath/javax/javax/swing/JList.java 2007-07-07 12:37:26 UTC (rev 3353) @@ -120,7 +120,106 @@ public class JList extends JComponent implements Accessible, Scrollable { + //jnode openjdk + /** + * A subclass of <code>TransferHandler.DropLocation</code> representing + * a drop location for a <code>JList</code>. + * + * @see #getDropLocation + * @since 1.6 + */ + public static final class DropLocation extends TransferHandler.DropLocation { + private final int index; + private final boolean isInsert; + private DropLocation(Point p, int index, boolean isInsert) { + super(p); + this.index = index; + this.isInsert = isInsert; + } + + /** + * Returns the index where dropped data should be placed in the + * list. Interpretation of the value depends on the drop mode set on + * the associated component. If the drop mode is either + * <code>DropMode.USE_SELECTION</code> or <code>DropMode.ON</code>, + * the return value is an index of a row in the list. If the drop mode is + * <code>DropMode.INSERT</code>, the return value refers to the index + * where the data should be inserted. If the drop mode is + * <code>DropMode.ON_OR_INSERT</code>, the value of + * <code>isInsert()</code> indicates whether the index is an index + * of a row, or an insert index. + * <p> + * <code>-1</code> indicates that the drop occurred over empty space, + * and no index could be calculated. + * + * @return the drop index + */ + public int getIndex() { + return index; + } + + /** + * Returns whether or not this location represents an insert + * location. + * + * @return whether or not this is an insert location + */ + public boolean isInsert() { + return isInsert; + } + + /** + * Returns a string representation of this drop location. + * This method is intended to be used for debugging purposes, + * and the content and format of the returned string may vary + * between implementations. + * + * @return a string representation of this drop location + */ + public String toString() { + return getClass().getName() + + "[dropPoint=" + getDropPoint() + "," + + "index=" + index + "," + + "insert=" + isInsert + "]"; + } + } + + /** + * Returns the location that this component should visually indicate + * as the drop location during a DnD operation over the component, + * or {@code null} if no location is to currently be shown. + * <p> + * This method is not meant for querying the drop location + * from a {@code TransferHandler}, as the drop location is only + * set after the {@code TransferHandler}'s <code>canImport</code> + * has returned and has allowed for the location to be shown. + * <p> + * When this property changes, a property change event with + * name "dropLocation" is fired by the component. + * <p> + * By default, responsibility for listening for changes to this property + * and indicating the drop location visually lies with the list's + * {@code ListUI}, which may paint it directly and/or install a cell + * renderer to do so. Developers wishing to implement custom drop location + * painting and/or replace the default cell renderer, may need to honor + * this property. + * + * @return the drop location + * @see #setDropMode + * @see TransferHandler#canImport(TransferHandler.TransferSupport) + * @since 1.6 + */ + public final DropLocation getDropLocation() { + return dropLocation; + } + + /** + * The drop location. + */ + private transient DropLocation dropLocation; + + /** * Provides accessibility support for <code>JList</code>. */ Modified: trunk/core/src/classpath/javax/javax/swing/JTabbedPane.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/JTabbedPane.java 2007-07-06 11:09:17 UTC (rev 3352) +++ trunk/core/src/classpath/javax/javax/swing/JTabbedPane.java 2007-07-07 12:37:26 UTC (rev 3353) @@ -1723,4 +1723,87 @@ return accessibleContext; } + + //jnode openjdk + /** + * Returns the tab component at <code>index</code>. + * + * @param index the index of the item being queried + * @return the tab component at <code>index</code> + * @exception IndexOutOfBoundsException if index is out of range + * (index < 0 || index >= tab count) + * + * @see #setTabComponentAt + * @since 1.6 + */ + public Component getTabComponentAt(int index) { + //return pages.get(index).tabComponent; + return null; + } + + /** + * Returns the index of the tab for the specified tab component. + * Returns -1 if there is no tab for this tab component. + * + * @param tabComponent the tab component for the tab + * @return the first tab which matches this tab component, or -1 + * if there is no tab for this tab component + * @see #setTabComponentAt + * @see #getTabComponentAt + * @since 1.6 + */ + public int indexOfTabComponent(Component tabComponent) { + for(int i = 0; i < getTabCount(); i++) { + Component c = getTabComponentAt(i); + if (c == tabComponent) { + return i; + } + } + return -1; + } + + /** + * Sets the component that is responsible for rendering the + * title for the specified tab. A null value means + * <code>JTabbedPane</code> will render the title and/or icon for + * the specified tab. A non-null value means the component will + * render the title and <code>JTabbedPane</code> will not render + * the title and/or icon. + * <p> + * Note: The component must not be one that the developer has + * already added to the tabbed pane. + * + * @param index the tab index where the component should be set + * @param component the component to render the title for the + * specified tab + * @exception IndexOutOfBoundsException if index is out of range + * (index < 0 || index >= tab count) + * @exception IllegalArgumentException if component has already been + * added to this <code>JTabbedPane</code> + * + * @see #getTabComponentAt + * @beaninfo + * preferred: true + * attribute: visualUpdate true + * description: The tab component at the specified tab index. + * @since 1.6 + */ + public void setTabComponentAt(int index, Component component) { + /* + if (component != null && indexOfComponent(component) != -1) { + throw new IllegalArgumentException("Component is already added to this JTabbedPane"); + } + Component oldValue = getTabComponentAt(index); + if (component != oldValue) { + int tabComponentIndex = indexOfTabComponent(component); + if (tabComponentIndex != -1) { + setTabComponentAt(tabComponentIndex, null); + } + pages.get(index).tabComponent = component; + firePropertyChange("indexForTabComponent", -1, index); + } + */ + } + + } Modified: trunk/core/src/classpath/javax/javax/swing/JTable.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/JTable.java 2007-07-06 11:09:17 UTC (rev 3352) +++ trunk/core/src/classpath/javax/javax/swing/JTable.java 2007-07-07 12:37:26 UTC (rev 3353) @@ -75,6 +75,7 @@ import javax.swing.event.TableColumnModelListener; import javax.swing.event.TableModelEvent; import javax.swing.event.TableModelListener; +import javax.swing.event.RowSorterEvent; import javax.swing.plaf.TableUI; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.DefaultTableColumnModel; @@ -85,6 +86,7 @@ import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; import javax.swing.table.TableModel; +import sun.swing.SwingUtilities2; /** * The table component, displaying information, organized in rows and columns. @@ -100,6 +102,104 @@ implements TableModelListener, Scrollable, TableColumnModelListener, ListSelectionListener, CellEditorListener, Accessible { + //jnode openjdk + /** + * A subclass of <code>TransferHandler.DropLocation</code> representing + * a drop location for a <code>JTable</code>. + * + * @see #getDropLocation + * @since 1.6 + */ + public static final class DropLocation extends TransferHandler.DropLocation { + private final int row; + private final int col; + private final boolean isInsertRow; + private final boolean isInsertCol; + + private DropLocation(Point p, int row, int col, + boolean isInsertRow, boolean isInsertCol) { + + super(p); + this.row = row; + this.col = col; + this.isInsertRow = isInsertRow; + this.isInsertCol = isInsertCol; + } + + /** + * Returns the row index where a dropped item should be placed in the + * table. Interpretation of the value depends on the return of + * <code>isInsertRow()</code>. If that method returns + * <code>true</code> this value indicates the index where a new + * row should be inserted. Otherwise, it represents the value + * of an existing row on which the data was dropped. This index is + * in terms of the view. + * <p> + * <code>-1</code> indicates that the drop occurred over empty space, + * and no row could be calculated. + * + * @return the drop row + */ + public int getRow() { + return row; + } + + /** + * Returns the column index where a dropped item should be placed in the + * table. Interpretation of the value depends on the return of + * <code>isInsertColumn()</code>. If that method returns + * <code>true</code> this value indicates the index where a new + * column should be inserted. Otherwise, it represents the value + * of an existing column on which the data was dropped. This index is + * in terms of the view. + * <p> + * <code>-1</code> indicates that the drop occurred over empty space, + * and no column could be calculated. + * + * @return the drop row + */ + public int getColumn() { + return col; + } + + /** + * Returns whether or not this location represents an insert + * of a row. + * + * @return whether or not this is an insert row + */ + public boolean isInsertRow() { + return isInsertRow; + } + + /** + * Returns whether or not this location represents an insert + * of a column. + * + * @return whether or not this is an insert column + */ + public boolean isInsertColumn() { + return isInsertCol; + } + + /** + * Returns a string representation of this drop location. + * This method is intended to be used for debugging purposes, + * and the content and format of the returned string may vary + * between implementations. + * + * @return a string representation of this drop location + */ + public String toString() { + return getClass().getName() + + "[dropPoint=" + getDropPoint() + "," + + "row=" + row + "," + + "column=" + col + "," + + "insertRow=" + isInsertRow + "," + + "insertColumn=" + isInsertCol + "]"; + } + } + /** * Provides accessibility support for <code>JTable</code>. * @@ -5154,4 +5254,79 @@ super.setUIProperty(propertyName, value); } } -} + + //jnode openjdk + /** + * Returns the object responsible for sorting. + * + * @return the object responsible for sorting + * @since 1.6 + */ + public RowSorter<? extends TableModel> getRowSorter() { + //return (sortManager != null) ? sortManager.sorter : null; + return null; + } + /** + * Information used in sorting. + */ + //private transient SortManager sortManager; + + /** + * Sets the <code>RowSorter</code>. <code>RowSorter</code> is used + * to provide sorting and filtering to a <code>JTable</code>. + * <p> + * This method clears the selection and resets any variable row heights. + * <p> + * If the underlying model of the <code>RowSorter</code> differs from + * that of this <code>JTable</code> undefined behavior will result. + * + * @param sorter the <code>RowSorter</code>; <code>null</code> turns + * sorting off + * @see javax.swing.table.TableRowSorter + * @since 1.6 + */ + public void setRowSorter(RowSorter<? extends TableModel> sorter) { + /* + RowSorter<? extends TableModel> oldRowSorter = null; + if (sortManager != null) { + oldRowSorter = sortManager.sorter; + sortManager.dispose(); + sortManager = null; + } + rowModel = null; + clearSelectionAndLeadAnchor(); + if (sorter != null) { + sortManager = new SortManager(sorter); + } + resizeAndRepaint(); + firePropertyChange("sorter", oldRowSorter, sorter); + */ + } + + /** + * Returns the location that this component should visually indicate + * as the drop location during a DnD operation over the component, + * or {@code null} if no location is to currently be shown. + * <p> + * This method is not meant for querying the drop location + * from a {@code TransferHandler}, as the drop location is only + * set after the {@code TransferHandler}'s <code>canImport</code> + * has returned and has allowed for the location to be shown. + * <p> + * When this property changes, a property change event with + * name "dropLocation" is fired by the component. + * + * @return the drop location + * @see #setDropMode + * @see TransferHandler#canImport(TransferHandler.TransferSupport) + * @since 1.6 + */ + public final DropLocation getDropLocation() { + return dropLocation; + } + /** + * The drop location. + */ + private transient DropLocation dropLocation; + +} \ No newline at end of file Modified: trunk/core/src/classpath/javax/javax/swing/JTree.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/JTree.java 2007-07-06 11:09:17 UTC (rev 3352) +++ trunk/core/src/classpath/javax/javax/swing/JTree.java 2007-07-07 12:37:26 UTC (rev 3353) @@ -86,6 +86,106 @@ public class JTree extends JComponent implements Scrollable, Accessible { + //jnode openjdk + /** + * A subclass of <code>TransferHandler.DropLocation</code> representing + * a drop location for a <code>JTree</code>. + * + * @see #getDropLocation + * @since 1.6 + */ + public static final class DropLocation extends TransferHandler.DropLocation { + private final TreePath path; + private final int index; + + private DropLocation(Point p, TreePath path, int index) { + super(p); + this.path = path; + this.index = index; + } + + /** + * Returns the index where the dropped data should be inserted + * with respect to the path returned by <code>getPath()</code>. + * <p> + * For drop modes <code>DropMode.USE_SELECTION</code> and + * <code>DropMode.ON</code>, this index is unimportant (and it will + * always be <code>-1</code>) as the only interesting data is the + * path over which the drop operation occurred. + * <p> + * For drop mode <code>DropMode.INSERT</code>, this index + * indicates the index at which the data should be inserted into + * the parent path represented by <code>getPath()</code>. + * <code>-1</code> indicates that the drop occurred over the + * parent itself, and in most cases should be treated as inserting + * into either the beginning or the end of the parent's list of + * children. + * <p> + * For <code>DropMode.ON_OR_INSERT</code>, this value will be + * an insert index, as described above, or <code>-1</code> if + * the drop occurred over the path itself. + * + * @return the child index + * @see #getPath + */ + public int getChildIndex() { + return index; + } + + /** + * Returns the path where dropped data should be placed in the + * tree. + * <p> + * Interpretation of this value depends on the drop mode set on the + * component. If the drop mode is <code>DropMode.USE_SELECTION</code> + * or <code>DropMode.ON</code>, the return value is the path in the + * tree over which the data has been (or will be) dropped. + * <code>null</code> indicates that the drop is over empty space, + * not associated with a particular path. + * <p> + * If the drop mode is <code>DropMode.INSERT</code>, the return value + * refers to the path that should become the parent of the new data, + * in which case <code>getChildIndex()</code> indicates where the + * new item should be inserted into this parent path. A + * <code>null</code> path indicates that no parent path has been + * determined, which can happen for multiple reasons: + * <ul> + * <li>The tree has no model + * <li>There is no root in the tree + * <li>The root is collapsed + * <li>The root is a leaf node + * </ul> + * It is up to the developer to decide if and how they wish to handle + * the <code>null</code> case. + * <p> + * If the drop mode is <code>DropMode.ON_OR_INSERT</code>, + * <code>getChildIndex</code> can be used to determine whether the + * drop is on top of the path itself (<code>-1</code>) or the index + * at which it should be inserted into the path (values other than + * <code>-1</code>). + * + * @return the drop path + * @see #getChildIndex + */ + public TreePath getPath() { + return path; + } + + /** + * Returns a string representation of this drop location. + * This method is intended to be used for debugging purposes, + * and the content and format of the returned string may vary + * between implementations. + * + * @return a string representation of this drop location + */ + public String toString() { + return getClass().getName() + + "[dropPoint=" + getDropPoint() + "," + + "path=" + path + "," + + "childIndex=" + index + "]"; + } + } /** * This class implements accessibility support for the JTree class. It * provides an implementation of the Java Accessibility API appropriate @@ -3183,4 +3283,31 @@ super.setUIProperty(propertyName, value); } } + //jnode openjdk + /** + * Returns the location that this component should visually indicate + * as the drop location during a DnD operation over the component, + * or {@code null} if no location is to currently be shown. + * <p> + * This method is not meant for querying the drop location + * from a {@code TransferHandler}, as the drop location is only + * set after the {@code TransferHandler}'s <code>canImport</code> + * has returned and has allowed for the location to be shown. + * <p> + * When this property changes, a property change event with + * name "dropLocation" is fired by the component. + * + * @return the drop location + * @see #setDropMode + * @see TransferHandler#canImport(TransferHandler.TransferSupport) + * @since 1.6 + */ + public final DropLocation getDropLocation() { + return dropLocation; + } + /** + * The drop location. + */ + private transient DropLocation dropLocation; + } Modified: trunk/core/src/classpath/javax/javax/swing/LookAndFeel.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/LookAndFeel.java 2007-07-06 11:09:17 UTC (rev 3352) +++ trunk/core/src/classpath/javax/javax/swing/LookAndFeel.java 2007-07-07 12:37:26 UTC (rev 3353) @@ -51,6 +51,8 @@ import javax.swing.plaf.UIResource; import javax.swing.plaf.metal.MetalLookAndFeel; import javax.swing.text.JTextComponent; +import sun.swing.DefaultLayoutStyle; +import sun.swing.ImageIconUIResource; /** * A <i>look-and-feel</i> controls most aspects of the appearance and @@ -430,4 +432,73 @@ { c.setUIProperty(propertyName, value); } + + //jnode openjdk + /** + * Returns the <code>LayoutStyle</code> for this look + * and feel. This never returns {@code null}. + * <p> + * You generally don't use the <code>LayoutStyle</code> from + * the look and feel, instead use the <code>LayoutStyle</code> + * method <code>getInstance</code>. + * + * @see LayoutStyle#getInstance + * @return the <code>LayoutStyle</code> for this look and feel + * @since 1.6 + */ + public LayoutStyle getLayoutStyle() { + return DefaultLayoutStyle.getInstance(); + } + /** + * Returns an <code>Icon</code> with a disabled appearance. + * This method is used to generate a disabled <code>Icon</code> when + * one has not been specified. For example, if you create a + * <code>JButton</code> and only specify an <code>Icon</code> via + * <code>setIcon</code> this method will be called to generate the + * disabled <code>Icon</code>. If {@code null} is passed as + * <code>icon</code> this method returns {@code null}. + * <p> + * Some look and feels might not render the disabled {@code Icon}, in which + * case they will ignore this. + * + * @param component {@code JComponent} that will display the {@code Icon}, + * may be {@code null} + * @param icon {@code Icon} to generate the disabled icon from + * @return disabled {@code Icon}, or {@code null} if a suitable + * {@code Icon} can not be generated + * @since 1.5 + */ + public Icon getDisabledIcon(JComponent component, Icon icon) { + if (icon instanceof ImageIcon) { + return new ImageIconUIResource(GrayFilter. + createDisabledImage(((ImageIcon)icon).getImage())); + } + return null; + } + + /** + * Returns an <code>Icon</code> for use by disabled + * components that are also selected. This method is used to generate an + * <code>Icon</code> for components that are in both the disabled and + * selected states but do not have a specific <code>Icon</code> for this + * state. For example, if you create a <code>JButton</code> and only + * specify an <code>Icon</code> via <code>setIcon</code> this method + * will be called to generate the disabled and selected + * <code>Icon</code>. If {@code null} is passed as <code>icon</code> this + * methods returns {@code null}. + * <p> + * Some look and feels might not render the disabled and selected + * {@code Icon}, in which case they will ignore this. + * + * @param component {@code JComponent} that will display the {@code Icon}, + * may be {@code null} + * @param icon {@code Icon} to generate disabled and selected icon from + * @return disabled and selected icon, or {@code null} if a suitable + * {@code Icon} can not be generated. + * @since 1.5 + */ + public Icon getDisabledSelectedIcon(JComponent component, Icon icon) { + return getDisabledIcon(component, icon); + } + } Modified: trunk/core/src/classpath/javax/javax/swing/TransferHandler.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/TransferHandler.java 2007-07-06 11:09:17 UTC (rev 3352) +++ trunk/core/src/classpath/javax/javax/swing/TransferHandler.java 2007-07-07 12:37:26 UTC (rev 3353) @@ -40,7 +40,11 @@ import gnu.classpath.NotImplementedException; -import java.awt.Toolkit; +import java.awt.*; +import java.awt.dnd.DropTargetEvent; +import java.awt.dnd.DropTargetDragEvent; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.dnd.DnDConstants; import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; @@ -54,10 +58,511 @@ import java.io.IOException; import java.io.Serializable; import java.lang.reflect.Method; +import javax.swing.text.JTextComponent; +import sun.reflect.misc.MethodUtil; +import sun.swing.SwingUtilities2; +import sun.awt.AppContext; +import sun.swing.*; + public class TransferHandler implements Serializable { + //jnode openjdk + /** + * Represents a location where dropped data should be inserted. + * This is a base class that only encapsulates a point. + * Components supporting drop may provide subclasses of this + * containing more information. + * <p> + * Developers typically shouldn't create instances of, or extend, this + * class. Instead, these are something provided by the DnD + * implementation by <code>TransferSupport</code> instances and by + * components with a <code>getDropLocation()</code> method. + * + * @see javax.swing.TransferHandler.TransferSupport#getDropLocation + * @since 1.6 + */ + public static class DropLocation { + private final Point dropPoint; + /** + * Constructs a drop location for the given point. + * + * @param dropPoint the drop point, representing the mouse's + * current location within the component. + * @throws IllegalArgumentException if the point + * is <code>null</code> + */ + protected DropLocation(Point dropPoint) { + if (dropPoint == null) { + throw new IllegalArgumentException("Point cannot be null"); + } + + this.dropPoint = new Point(dropPoint); + } + + /** + * Returns the drop point, representing the mouse's + * current location within the component. + * + * @return the drop point. + */ + public final Point getDropPoint() { + return new Point(dropPoint); + } + + /** + * Returns a string representation of this drop location. + * This method is intended to be used for debugging purposes, + * and the content and format of the returned string may vary + * between implementations. + * + * @return a string representation of this drop location + */ + public String toString() { + return getClass().getName() + "[dropPoint=" + dropPoint + "]"; + } + }; + /** + * This class encapsulates all relevant details of a clipboard + * or drag and drop transfer, and also allows for customizing + * aspects of the drag and drop experience. + * <p> + * The main purpose of this class is to provide the information + * needed by a developer to determine the suitability of a + * transfer or to import the data contained within. But it also + * doubles as a controller for customizing properties during drag + * and drop, such as whether or not to show the drop location, + * and which drop action to use. + * <p> + * Developers typically need not create instances of this + * class. Instead, they are something provided by the DnD + * implementation to certain methods in <code>TransferHandler</code>. + * + * @see #canImport(TransferHandler.TransferSupport) + * @see #importData(TransferHandler.TransferSupport) + * @since 1.6 + */ + public final static class TransferSupport { + private boolean isDrop; + private Component component; + + private boolean showDropLocationIsSet; + private boolean showDropLocation; + + private int dropAction = -1; + + /** + * The source is a {@code DropTargetDragEvent} or + * {@code DropTargetDropEvent} for drops, + * and a {@code Transferable} otherwise + */ + private Object source; + + private DropLocation dropLocation; + + /** + * Create a <code>TransferSupport</code> with <code>isDrop()</code> + * <code>true</code> for the given component, event, and index. + * + * @param component the target component + * @param event a <code>DropTargetEvent</code> + */ + private TransferSupport(Component component, + DropTargetEvent event) { + + isDrop = true; + setDNDVariables(component, event); + } + + /** + * Create a <code>TransferSupport</code> with <code>isDrop()</code> + * <code>false</code> for the given component and + * <code>Transferable</code>. + * + * @param component the target component + * @param transferable the transferable + * @throws NullPointerException if either parameter + * is <code>null</code> + */ + public TransferSupport(Component component, Transferable transferable) { + if (component == null) { + throw new NullPointerException("component is null"); + } + + if (transferable == null) { + throw new NullPointerException("transferable is null"); + } + + isDrop = false; + this.component = component; + this.source = transferable; + } + + /** + * Allows for a single instance to be reused during DnD. + * + * @param component the target component + * @param event a <code>DropTargetEvent</code> + */ + private void setDNDVariables(Component component, + DropTargetEvent event) { + + assert isDrop; + + this.component = component; + this.source = event; + dropLocation = null; + dropAction = -1; + showDropLocationIsSet = false; + + if (source == null) { + return; + } + + assert source instanceof DropTargetDragEvent || + source instanceof DropTargetDropEvent; + + Point p = source instanceof DropTargetDragEvent + ? ((DropTargetDragEvent)source).getLocation() + : ((DropTargetDropEvent)source).getLocation(); + + if (component instanceof JTextComponent) { + try { + AccessibleMethod method + = new AccessibleMethod(JTextComponent.class, + "dropLocationForPoint", + Point.class); + + dropLocation = + (DropLocation)method.invokeNoChecked(component, p); + } catch (NoSuchMethodException e) { + throw new AssertionError( + "Couldn't locate method JTextComponent.dropLocationForPoint"); + } + } else if (component instanceof JComponent) { + dropLocation = ((JComponent)component).dropLocationForPoint(p); + } + + /* + * The drop location may be null at this point if the component + * doesn't return custom drop locations. In this case, a point-only + * drop location will be created lazily when requested. + */ + } + + /** + * Returns whether or not this <code>TransferSupport</code> + * represents a drop operation. + * + * @return <code>true</code> if this is a drop operation, + * <code>false</code> otherwise. + */ + public boolean isDrop() { + return isDrop; + } + + /** + * Returns the target component of this transfer. + * + * @return the target component + */ + public Component getComponent() { + return component; + } + + /** + * Checks that this is a drop and throws an + * {@code IllegalStateException} if it isn't. + * + * @throws IllegalStateException if {@code isDrop} is false. + */ + private void assureIsDrop() { + if (!isDrop) { + throw new IllegalStateException("Not a drop"); + } + } + + /** + * Returns the current (non-{@code null}) drop location for the component, + * when this {@code TransferSupport} represents a drop. + * <p> + * Note: For components with built-in drop support, this location + * will be a subclass of {@code DropLocation} of the same type + * returned by that component's {@code getDropLocation} method. + * <p> + * This method is only for use with drag and drop transfers. + * Calling it when {@code isDrop()} is {@code false} results + * in an {@code IllegalStateException}. + * + * @return the drop location + * @throws IllegalStateException if this is not a drop + * @see #isDrop + */ + public DropLocation getDropLocation() { + assureIsDrop(); + + if (dropLocation == null) { + /* + * component didn't give us a custom drop location, + * so lazily create a point-only location + */ + Point p = source instanceof DropTargetDragEvent + ? ((DropTargetDragEvent)source).getLocation() + : ((DropTargetDropEvent)source).getLocation(); + + dropLocation = new DropLocation(p); + } + + return dropLocation; + } + + /** + * Sets whether or not the drop location should be visually indicated + * for the transfer - which must represent a drop. This is applicable to + * those components that automatically + * show the drop location when appropriate during a drag and drop + * operation). By default, the drop location is shown only when the + * {@code TransferHandler} has said it can accept the import represented + * by this {@code TransferSupport}. With this method you can force the + * drop location to always be shown, or always not be shown. + * <p> + * This method is only for use with drag and drop transfers. + * Calling it when {@code isDrop()} is {@code false} results + * in an {@code IllegalStateException}. + * + * @param showDropLocation whether or not to indicate the drop location + * @throws IllegalStateException if this is not a drop + * @see #isDrop + */ + public void setShowDropLocation(boolean showDropLocation) { + assureIsDrop(); + + this.showDropLocation = showDropLocation; + this.showDropLocationIsSet = true; + } + + /** + * Sets the drop action for the transfer - which must represent a drop + * - to the given action, + * instead of the default user drop action. The action must be + * supported by the source's drop actions, and must be one + * of {@code COPY}, {@code MOVE} or {@code LINK}. + * <p> + * This method is only for use with drag and drop transfers. + * Calling it when {@code isDrop()} is {@code false} results + * in an {@code IllegalStateException}. + * + * @param dropAction the drop action + * @throws IllegalStateException if this is not a drop + * @throws IllegalArgumentException if an invalid action is specified + * @see #getDropAction + * @see #getUserDropAction + * @see #getSourceDropActions + * @see #isDrop + */ + public void setDropAction(int dropAction) { + assureIsDrop(); + + int action = dropAction & getSourceDropActions(); + + if (!(action == COPY || action == MOVE || action == LINK)) { + throw new IllegalArgumentException("unsupported drop action: " + dropAction); + } + + this.dropAction = dropAction; + } + + /** + * Returns the action chosen for the drop, when this + * {@code TransferSupport} represents a drop. + * <p> + * Unless explicitly chosen by way of {@code setDropAction}, + * this returns the user drop action provided by + * {@code getUserDropAction}. + * <p> + * You may wish to query this in {@code TransferHandler}'s + * {@code importData} method to customize processing based + * on the action. + * <p> + * This method is only for use with drag and drop transfers. + * Calling it when {@code isDrop()} is {@code false} results + * in an {@code IllegalStateException}. + * + * @return the action chosen for the drop + * @throws IllegalStateException if this is not a drop + * @see #setDropAction + * @see #getUserDropAction + * @see #isDrop + */ + public int getDropAction() { + return dropAction == -1 ? getUserDropAction() : dropAction; + } + + /** + * Returns the user drop action for the drop, when this + * {@code TransferSupport} represents a drop. + * <p> + * The user drop action is chosen for a drop as described in the + * documentation for {@link java.awt.dnd.DropTargetDragEvent} and + * {@link java.awt.dnd.DropTargetDropEvent}. A different action + * may be chosen as the drop action by way of the {@code setDropAction} + * method. + * <p> + * You may wish to query this in {@code TransferHandler}'s + * {@code canImport} method when determining the suitability of a + * drop or when deciding on a drop action to explicitly choose. + * <p> + * This method is only for use with drag and drop transfers. + * Calling it when {@code isDrop()} is {@code false} results + * in an {@code IllegalStateException}. + * + * @return the user drop action + * @throws IllegalStateException if this is not a drop + * @see #setDropAction + * @see #getDropAction + * @see #isDrop + */ + public int getUserDropAction() { + assureIsDrop(); + + return (source instanceof DropTargetDragEvent) + ? ((DropTargetDragEvent)source).getDropAction() + : ((DropTargetDropEvent)source).getDropAction(); + } + + /** + * Returns the drag source's supported drop actions, when this + * {@code TransferSupport} represents a drop. + * <p> + * The source actions represent the set of actions supported by the + * source of this transfer, and are represented as some bitwise-OR + * combination of {@code COPY}, {@code MOVE} and {@code LINK}. + * You may wish to query this in {@code TransferHandler}'s + * {@code canImport} method when determining the suitability of a drop + * or when deciding on a drop action to explicitly choose. To determine + * if a particular action is supported by the source, bitwise-AND + * the action with the source drop actions, and then compare the result + * against the original action. For example: + * <pre> + * boolean copySupported = (COPY & getSourceDropActions()) == COPY; + * </pre> + * <p> + * This method is only for use with drag and drop transfers. + * Calling it when {@code isDrop()} is {@code false} results + * in an {@code IllegalStateException}. + * + * @return the drag source's supported drop actions + * @throws IllegalStateException if this is not a drop + * @see #isDrop + */ + public int getSourceDropActions() { + assureIsDrop(); + + return (source instanceof DropTargetDragEvent) + ? ((DropTargetDragEvent)source).getSourceActions() + : ((DropTargetDropEvent)source).getSourceActions(); + } + + /** + * Returns the data flavors for this transfer. + * + * @return the data flavors for this transfer + */ + public DataFlavor[] getDataFlavors() { + if (isDrop) { + if (source instanceof DropTargetDragEvent) { + return ((DropTargetDragEvent)source).getCurrentDataFlavors(); + } else { + return ((DropTargetDropEvent)source).getCurrentDataFlavors(); + } + } + + return ((Transferable)source).getTransferDataFlavors(); + } + + /** + * Returns whether or not the given data flavor is supported. + * + * @param df the <code>DataFlavor</code> to test + * @return whether or not the given flavor is supported. + */ + public boolean isDataFlavorSupported(DataFlavor df) { + if (isDrop) { + if (source instanceof DropTargetDragEvent) { + return ((DropTargetDragEvent)source).isDataFlavorSupported(df); + } else { + return ((DropTargetDropEvent)source).isDataFlavorSupported(df); + } + } + + return ((Transferable)source).isDataFlavorSupported(df); + } + + /** + * Returns the <code>Transferable</code> associated with this transfer. + * <p> + * Note: Unless it is necessary to fetch the <code>Transferable</code> + * directly, use one of the other methods on this class to inquire about + * the transfer. This may perform better than fetching the + * <code>Transferable</code> and asking it directly. + * + * @return the <code>Transferable</code> associated with this transfer + */ + public Transferable getTransferable() { + if (isDrop) { + if (source instanceof DropTargetDragEvent) { + return ((DropTargetDragEvent)source).getTransferable(); + } else { + return ((DropTargetDropEvent)source).getTransferable(); + } + } + + return (Transferable)source; + } + } + + /** + * An <code>int</code> representing a "link" transfer action. + * This value is used to specify that data should be linked in a drag + * and drop operation. + * + * @see java.awt.dnd.DnDConstants#ACTION_LINK + * @since 1.6 + */ + public static final int LINK = DnDConstants.ACTION_LINK; + + /** + * Causes a transfer to occur from a clipboard or a drag and + * drop operation. The <code>Transferable</code> to be + * imported and the component to transfer to are contained + * within the <code>TransferSupport</code>. + * <p> + * While the drag and drop implementation calls {@code canImport} + * to determine the suitability of a transfer before calling this + * method, the implementation of paste does not. As such, it cannot + * be assumed that the transfer is acceptable upon a call to + * this method for paste. It is recommended that {@code canImport} be + * explicitly called to cover this case. + * <p> + * Note: The <code>TransferSupport</code> object passed to this method... [truncated message content] |
From: <ls...@us...> - 2008-03-16 20:07:02
|
Revision: 3848 http://jnode.svn.sourceforge.net/jnode/?rev=3848&view=rev Author: lsantha Date: 2008-03-16 13:07:00 -0700 (Sun, 16 Mar 2008) Log Message: ----------- OpenJDK AWT & Swing integration. Removed Paths: ------------- trunk/core/src/classpath/javax/javax/swing/AbstractButton.java trunk/core/src/classpath/javax/javax/swing/Box.java trunk/core/src/classpath/javax/javax/swing/CellRendererPane.java trunk/core/src/classpath/javax/javax/swing/CompatibilityFocusTraversalPolicy.java trunk/core/src/classpath/javax/javax/swing/ComponentInputMap.java trunk/core/src/classpath/javax/javax/swing/DefaultDesktopManager.java trunk/core/src/classpath/javax/javax/swing/DefaultListCellRenderer.java trunk/core/src/classpath/javax/javax/swing/JApplet.java trunk/core/src/classpath/javax/javax/swing/JButton.java trunk/core/src/classpath/javax/javax/swing/JCheckBox.java trunk/core/src/classpath/javax/javax/swing/JCheckBoxMenuItem.java trunk/core/src/classpath/javax/javax/swing/JColorChooser.java trunk/core/src/classpath/javax/javax/swing/JComboBox.java trunk/core/src/classpath/javax/javax/swing/JDesktopPane.java trunk/core/src/classpath/javax/javax/swing/JDialog.java trunk/core/src/classpath/javax/javax/swing/JEditorPane.java trunk/core/src/classpath/javax/javax/swing/JFileChooser.java trunk/core/src/classpath/javax/javax/swing/JFormattedTextField.java trunk/core/src/classpath/javax/javax/swing/JFrame.java trunk/core/src/classpath/javax/javax/swing/JInternalFrame.java trunk/core/src/classpath/javax/javax/swing/JLabel.java trunk/core/src/classpath/javax/javax/swing/JLayeredPane.java trunk/core/src/classpath/javax/javax/swing/JList.java trunk/core/src/classpath/javax/javax/swing/JMenu.java trunk/core/src/classpath/javax/javax/swing/JMenuBar.java trunk/core/src/classpath/javax/javax/swing/JMenuItem.java trunk/core/src/classpath/javax/javax/swing/JOptionPane.java trunk/core/src/classpath/javax/javax/swing/JPanel.java trunk/core/src/classpath/javax/javax/swing/JPasswordField.java trunk/core/src/classpath/javax/javax/swing/JPopupMenu.java trunk/core/src/classpath/javax/javax/swing/JProgressBar.java trunk/core/src/classpath/javax/javax/swing/JRadioButton.java trunk/core/src/classpath/javax/javax/swing/JRadioButtonMenuItem.java trunk/core/src/classpath/javax/javax/swing/JRootPane.java trunk/core/src/classpath/javax/javax/swing/JScrollBar.java trunk/core/src/classpath/javax/javax/swing/JScrollPane.java trunk/core/src/classpath/javax/javax/swing/JSeparator.java trunk/core/src/classpath/javax/javax/swing/JSlider.java trunk/core/src/classpath/javax/javax/swing/JSpinner.java trunk/core/src/classpath/javax/javax/swing/JSplitPane.java trunk/core/src/classpath/javax/javax/swing/JTabbedPane.java trunk/core/src/classpath/javax/javax/swing/JTable.java trunk/core/src/classpath/javax/javax/swing/JTextArea.java trunk/core/src/classpath/javax/javax/swing/JTextField.java trunk/core/src/classpath/javax/javax/swing/JTextPane.java trunk/core/src/classpath/javax/javax/swing/JToggleButton.java trunk/core/src/classpath/javax/javax/swing/JToolBar.java trunk/core/src/classpath/javax/javax/swing/JToolTip.java trunk/core/src/classpath/javax/javax/swing/JViewport.java trunk/core/src/classpath/javax/javax/swing/JWindow.java trunk/core/src/classpath/javax/javax/swing/Popup.java trunk/core/src/classpath/javax/javax/swing/PopupFactory.java trunk/core/src/classpath/javax/javax/swing/ToolTipManager.java trunk/core/src/classpath/javax/javax/swing/UIManager.java trunk/core/src/classpath/javax/javax/swing/colorchooser/ trunk/core/src/classpath/javax/javax/swing/plaf/ trunk/core/src/classpath/javax/javax/swing/text/ trunk/core/src/classpath/javax/javax/swing/tree/ Deleted: trunk/core/src/classpath/javax/javax/swing/AbstractButton.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/AbstractButton.java 2008-03-16 20:05:09 UTC (rev 3847) +++ trunk/core/src/classpath/javax/javax/swing/AbstractButton.java 2008-03-16 20:07:00 UTC (rev 3848) @@ -1,2650 +0,0 @@ -/* AbstractButton.java -- Provides basic button functionality. - Copyright (C) 2002, 2004, 2006, Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath 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 for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package javax.swing; - -import java.awt.Component; -import java.awt.Graphics; -import java.awt.Image; -import java.awt.Insets; -import java.awt.ItemSelectable; -import java.awt.LayoutManager; -import java.awt.Point; -import java.awt.Rectangle; -import java.awt.Shape; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; -import java.awt.image.ImageObserver; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.io.Serializable; -import java.util.Enumeration; - -import javax.accessibility.Accessible; -import javax.accessibility.AccessibleAction; -import javax.accessibility.AccessibleContext; -import javax.accessibility.AccessibleIcon; -import javax.accessibility.AccessibleRelation; -import javax.accessibility.AccessibleRelationSet; -import javax.accessibility.AccessibleState; -import javax.accessibility.AccessibleStateSet; -import javax.accessibility.AccessibleText; -import javax.accessibility.AccessibleValue; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; -import javax.swing.plaf.ButtonUI; -import javax.swing.plaf.basic.BasicHTML; -import javax.swing.text.AttributeSet; -import javax.swing.text.BadLocationException; -import javax.swing.text.Document; -import javax.swing.text.Element; -import javax.swing.text.Position; -import javax.swing.text.StyledDocument; -import javax.swing.text.View; - - -/** - * Provides an abstract implementation of common button behaviour, - * data model and look & feel. - * - * <p>This class is supposed to serve as a base class for - * several kinds of buttons with similar but non-identical semantics: - * toggle buttons (radio buttons and checkboxes), simple push buttons, - * menu items, etc.</p> - * - * <p>Buttons have many properties, some of which are stored in this class - * while others are delegated to the button's model. The following properties - * are available:</p> - * - * <table> - * <tr><th>Property </th><th>Stored in</th><th>Bound?</th></tr> - * - * <tr><td>action </td><td>button</td> <td>no</td></tr> - * <tr><td>actionCommand </td><td>model</td> <td>no</td></tr> - * <tr><td>borderPainted </td><td>button</td> <td>yes</td></tr> - * <tr><td>contentAreaFilled </td><td>button</td> <td>yes</td></tr> - * <tr><td>disabledIcon </td><td>button</td> <td>yes</td></tr> - * <tr><td>disabledSelectedIcon </td><td>button</td> <td>yes</td></tr> - * <tr><td>displayedMnemonicIndex </td><td>button</td> <td>no</td></tr> - * <tr><td>enabled </td><td>model</td> <td>no</td></tr> - * <tr><td>focusPainted </td><td>button</td> <td>yes</td></tr> - * <tr><td>horizontalAlignment </td><td>button</td> <td>yes</td></tr> - * <tr><td>horizontalTextPosition </td><td>button</td> <td>yes</td></tr> - * <tr><td>icon </td><td>button</td> <td>yes</td></tr> - * <tr><td>iconTextGap </td><td>button</td> <td>no</td></tr> - * <tr><td>label (same as text) </td><td>model</td> <td>yes</td></tr> - * <tr><td>margin </td><td>button</td> <td>yes</td></tr> - * <tr><td>multiClickThreshold </td><td>button</td> <td>no</td></tr> - * <tr><td>pressedIcon </td><td>button</td> <td>yes</td></tr> - * <tr><td>rolloverEnabled </td><td>button</td> <td>yes</td></tr> - * <tr><td>rolloverIcon </td><td>button</td> <td>yes</td></tr> - * <tr><td>rolloverSelectedIcon </td><td>button</td> <td>yes</td></tr> - * <tr><td>selected </td><td>model</td> <td>no</td></tr> - * <tr><td>selectedIcon </td><td>button</td> <td>yes</td></tr> - * <tr><td>selectedObjects </td><td>button</td> <td>no</td></tr> - * <tr><td>text </td><td>model</td> <td>yes</td></tr> - * <tr><td>UI </td><td>button</td> <td>yes</td></tr> - * <tr><td>verticalAlignment </td><td>button</td> <td>yes</td></tr> - * <tr><td>verticalTextPosition </td><td>button</td> <td>yes</td></tr> - * - * </table> - * - * <p>The various behavioral aspects of these properties follows:</p> - * - * <ul> - * - * <li>When non-bound properties stored in the button change, the button - * fires ChangeEvents to its ChangeListeners.</li> - * - * <li>When bound properties stored in the button change, the button fires - * PropertyChangeEvents to its PropertyChangeListeners</li> - * - * <li>If any of the model's properties change, it fires a ChangeEvent to - * its ChangeListeners, which include the button.</li> - * - * <li>If the button receives a ChangeEvent from its model, it will - * propagate the ChangeEvent to its ChangeListeners, with the ChangeEvent's - * "source" property set to refer to the button, rather than the model. The - * the button will request a repaint, to paint its updated state.</li> - * - * <li>If the model's "selected" property changes, the model will fire an - * ItemEvent to its ItemListeners, which include the button, in addition to - * the ChangeEvent which models the property change. The button propagates - * ItemEvents directly to its ItemListeners.</li> - * - * <li>If the model's armed and pressed properties are simultaneously - * <code>true</code>, the model will fire an ActionEvent to its - * ActionListeners, which include the button. The button will propagate - * this ActionEvent to its ActionListeners, with the ActionEvent's "source" - * property set to refer to the button, rather than the model.</li> - * - * </ul> - * - * @author Ronald Veldema (rve...@cs...) - * @author Graydon Hoare (gr...@re...) - */ - -public abstract class AbstractButton extends JComponent - implements ItemSelectable, SwingConstants -{ - private static final long serialVersionUID = -937921345538462020L; - - /** - * An extension of ChangeListener to be serializable. - */ - protected class ButtonChangeListener - implements ChangeListener, Serializable - { - private static final long serialVersionUID = 1471056094226600578L; - - /** - * The spec has no public/protected constructor for this class, so do we. - */ - ButtonChangeListener() - { - // Nothing to do here. - } - - /** - * Notified when the target of the listener changes its state. - * - * @param ev the ChangeEvent describing the change - */ - public void stateChanged(ChangeEvent ev) - { - getEventHandler().stateChanged(ev); - } - } - - /** - * The combined event handler for ActionEvent, ChangeEvent and - * ItemEvent. This combines ButtonChangeListener, ActionListener - */ - private class EventHandler - implements ActionListener, ChangeListener, ItemListener - { - public void actionPerformed(ActionEvent ev) - { - fireActionPerformed(ev); - } - - public void stateChanged(ChangeEvent ev) - { - fireStateChanged(); - repaint(); - } - - public void itemStateChanged(ItemEvent ev) - { - fireItemStateChanged(ev); - } - } - - /** The icon displayed by default. */ - Icon default_icon; - - /** The icon displayed when the button is pressed. */ - Icon pressed_icon; - - /** The icon displayed when the button is disabled. */ - Icon disabledIcon; - - /** The icon displayed when the button is selected. */ - Icon selectedIcon; - - /** The icon displayed when the button is selected but disabled. */ - Icon disabledSelectedIcon; - - /** The icon displayed when the button is rolled over. */ - Icon rolloverIcon; - - /** The icon displayed when the button is selected and rolled over. */ - Icon rolloverSelectedIcon; - - /** The icon currently displayed. */ - Icon current_icon; - - /** The text displayed in the button. */ - String text; - - /** - * The gap between icon and text, if both icon and text are - * non-<code>null</code>. - */ - int iconTextGap; - - /** The vertical alignment of the button's text and icon. */ - int verticalAlignment; - - /** The horizontal alignment of the button's text and icon. */ - int horizontalAlignment; - - /** The horizontal position of the button's text relative to its icon. */ - int horizontalTextPosition; - - /** The vertical position of the button's text relative to its icon. */ - int verticalTextPosition; - - /** Whether or not the button paints its border. */ - boolean borderPainted; - - /** Whether or not the button paints its focus state. */ - boolean focusPainted; - - /** Whether or not the button fills its content area. */ - boolean contentAreaFilled; - - /** Whether rollover is enabled. */ - boolean rollOverEnabled; - - /** The action taken when the button is clicked. */ - Action action; - - /** The button's current state. */ - protected ButtonModel model; - - /** The margin between the button's border and its label. */ - Insets margin; - - /** - * A hint to the look and feel class, suggesting which character in the - * button's label should be underlined when drawing the label. - */ - int mnemonicIndex; - - /** - * Listener the button uses to receive ActionEvents from its model. - */ - protected ActionListener actionListener; - - /** - * Listener the button uses to receive ItemEvents from its model. - */ - protected ItemListener itemListener; - - /** - * Listener the button uses to receive ChangeEvents from its model. - */ - protected ChangeListener changeListener; - - /** - * The event handler for ActionEvent, ItemEvent and ChangeEvent. - * This replaces the above three handlers and combines them - * into one for efficiency. - */ - private EventHandler eventHandler; - - /** - * The time in milliseconds in which clicks get coalesced into a single - * <code>ActionEvent</code>. - */ - long multiClickThreshhold; - - /** - * Listener the button uses to receive PropertyChangeEvents from its - * Action. - */ - PropertyChangeListener actionPropertyChangeListener; - - /** ChangeEvent that is fired to button's ChangeEventListeners */ - protected ChangeEvent changeEvent = new ChangeEvent(this); - - /** - * Indicates if the borderPainted property has been set by a client - * program or by the UI. - * - * @see #setUIProperty(String, Object) - * @see LookAndFeel#installProperty(JComponent, String, Object) - */ - private boolean clientBorderPaintedSet = false; - - /** - * Indicates if the rolloverEnabled property has been set by a client - * program or by the UI. - * - * @see #setUIProperty(String, Object) - * @see LookAndFeel#installProperty(JComponent, String, Object) - */ - private boolean clientRolloverEnabledSet = false; - - /** - * Indicates if the iconTextGap property has been set by a client - * program or by the UI. - * - * @see #setUIProperty(String, Object) - * @see LookAndFeel#installProperty(JComponent, String, Object) - */ - private boolean clientIconTextGapSet = false; - - /** - * Indicates if the contentAreaFilled property has been set by a client - * program or by the UI. - * - * @see #setUIProperty(String, Object) - * @see LookAndFeel#installProperty(JComponent, String, Object) - */ - private boolean clientContentAreaFilledSet = false; - - /** - * Fired in a PropertyChangeEvent when the "borderPainted" property changes. - */ - public static final String BORDER_PAINTED_CHANGED_PROPERTY = "borderPainted"; - - /** - * Fired in a PropertyChangeEvent when the "contentAreaFilled" property - * changes. - */ - public static final String CONTENT_AREA_FILLED_CHANGED_PROPERTY = - "contentAreaFilled"; - - /** - * Fired in a PropertyChangeEvent when the "disabledIcon" property changes. - */ - public static final String DISABLED_ICON_CHANGED_PROPERTY = "disabledIcon"; - - /** - * Fired in a PropertyChangeEvent when the "disabledSelectedIcon" property - * changes. - */ - public static final String DISABLED_SELECTED_ICON_CHANGED_PROPERTY = - "disabledSelectedIcon"; - - /** - * Fired in a PropertyChangeEvent when the "focusPainted" property changes. - */ - public static final String FOCUS_PAINTED_CHANGED_PROPERTY = "focusPainted"; - - /** - * Fired in a PropertyChangeEvent when the "horizontalAlignment" property - * changes. - */ - public static final String HORIZONTAL_ALIGNMENT_CHANGED_PROPERTY = - "horizontalAlignment"; - - /** - * Fired in a PropertyChangeEvent when the "horizontalTextPosition" property - * changes. - */ - public static final String HORIZONTAL_TEXT_POSITION_CHANGED_PROPERTY = - "horizontalTextPosition"; - - /** - * Fired in a PropertyChangeEvent when the "icon" property changes. */ - public static final String ICON_CHANGED_PROPERTY = "icon"; - - /** Fired in a PropertyChangeEvent when the "margin" property changes. */ - public static final String MARGIN_CHANGED_PROPERTY = "margin"; - - /** Fired in a PropertyChangeEvent when the "mnemonic" property changes. */ - public static final String MNEMONIC_CHANGED_PROPERTY = "mnemonic"; - - /** Fired in a PropertyChangeEvent when the "model" property changes. */ - public static final String MODEL_CHANGED_PROPERTY = "model"; - - /** Fired in a PropertyChangeEvent when the "pressedIcon" property changes. */ - public static final String PRESSED_ICON_CHANGED_PROPERTY = "pressedIcon"; - - /** - * Fired in a PropertyChangeEvent when the "rolloverEnabled" property - * changes. - */ - public static final String ROLLOVER_ENABLED_CHANGED_PROPERTY = - "rolloverEnabled"; - - /** - * Fired in a PropertyChangeEvent when the "rolloverIcon" property changes. - */ - public static final String ROLLOVER_ICON_CHANGED_PROPERTY = "rolloverIcon"; - - /** - * Fired in a PropertyChangeEvent when the "rolloverSelectedIcon" property - * changes. - */ - public static final String ROLLOVER_SELECTED_ICON_CHANGED_PROPERTY = - "rolloverSelectedIcon"; - - /** - * Fired in a PropertyChangeEvent when the "selectedIcon" property changes. - */ - public static final String SELECTED_ICON_CHANGED_PROPERTY = "selectedIcon"; - - /** Fired in a PropertyChangeEvent when the "text" property changes. */ - public static final String TEXT_CHANGED_PROPERTY = "text"; - - /** - * Fired in a PropertyChangeEvent when the "verticalAlignment" property - * changes. - */ - public static final String VERTICAL_ALIGNMENT_CHANGED_PROPERTY = - "verticalAlignment"; - - /** - * Fired in a PropertyChangeEvent when the "verticalTextPosition" property - * changes. - */ - public static final String VERTICAL_TEXT_POSITION_CHANGED_PROPERTY = - "verticalTextPosition"; - - /** - * A Java Accessibility extension of the AbstractButton. - */ - protected abstract class AccessibleAbstractButton - extends AccessibleJComponent implements AccessibleAction, AccessibleValue, - AccessibleText - { - private static final long serialVersionUID = -5673062525319836790L; - - protected AccessibleAbstractButton() - { - // Nothing to do here yet. - } - - /** - * Returns the accessible state set of this object. In addition to the - * superclass's states, the <code>AccessibleAbstractButton</code> - * supports the following states: {@link AccessibleState#ARMED}, - * {@link AccessibleState#FOCUSED}, {@link AccessibleState#PRESSED} and - * {@link AccessibleState#CHECKED}. - * - * @return the current state of this accessible object - */ - public AccessibleStateSet getAccessibleStateSet() - { - AccessibleStateSet state = super.getAccessibleStateSet(); - - if (getModel().isArmed()) - state.add(AccessibleState.ARMED); - if (getModel().isPressed()) - state.add(AccessibleState.PRESSED); - if (isSelected()) - state.add(AccessibleState.CHECKED); - - return state; - } - - /** - * Returns the accessible name for the button. - */ - public String getAccessibleName() - { - String result = super.getAccessibleName(); - if (result == null) - result = text; - return result; - } - - /** - * Returns the accessible icons of this object. If the AbstractButton's - * icon is an Accessible, and it's AccessibleContext is an AccessibleIcon, - * then this AccessibleIcon is returned, otherwise <code>null</code>. - * - * @return the accessible icons of this object, or <code>null</code> if - * there is no accessible icon - */ - public AccessibleIcon[] getAccessibleIcon() - { - AccessibleIcon[] ret = null; - Icon icon = getIcon(); - if (icon instanceof Accessible) - { - AccessibleContext ctx = ((Accessible) icon).getAccessibleContext(); - if (ctx instanceof AccessibleIcon) - { - ret = new AccessibleIcon[]{ (AccessibleIcon) ctx }; - } - } - return ret; - } - - /** - * Returns the accessible relations of this AccessibleAbstractButton. - * If the AbstractButton is part of a ButtonGroup, then all the buttons - * in this button group are added as targets in a MEMBER_OF relation, - * otherwise an empty relation set is returned (from super). - * - * @return the accessible relations of this AccessibleAbstractButton - */ - public AccessibleRelationSet getAccessibleRelationSet() - { - AccessibleRelationSet relations = super.getAccessibleRelationSet(); - ButtonModel model = getModel(); - if (model instanceof DefaultButtonModel) - { - ButtonGroup group = ((DefaultButtonModel) model).getGroup(); - if (group != null) - { - Object[] target = new Object[group.getButtonCount()]; - Enumeration els = group.getElements(); - - for (int index = 0; els.hasMoreElements(); ++index) - { - target[index] = els.nextElement(); - } - - AccessibleRelation rel = - new AccessibleRelation(AccessibleRelation.MEMBER_OF); - rel.setTarget(target); - relations.add(rel); - } - } - return relations; - } - - /** - * Returns the accessible action associated with this object. For buttons, - * this will be <code>this</code>. - * - * @return <code>this</code> - */ - public AccessibleAction getAccessibleAction() - { - return this; - } - - /** - * Returns the accessible value of this AccessibleAbstractButton, which - * is always <code>this</code>. - * - * @return the accessible value of this AccessibleAbstractButton, which - * is always <code>this</code> - */ - public AccessibleValue getAccessibleValue() - { - return this; - } - - /** - * Returns the number of accessible actions that are supported by this - * object. Buttons support one action by default ('press button'), so this - * method always returns <code>1</code>. - * - * @return <code>1</code>, the number of supported accessible actions - */ - public int getAccessibleActionCount() - { - return 1; - } - - /** - * Returns a description for the action with the specified index or - * <code>null</code> if such action does not exist. - * - * @param actionIndex the zero based index to the actions - * - * @return a description for the action with the specified index or - * <code>null</code> if such action does not exist - */ - public String getAccessibleActionDescription(int actionIndex) - { - String descr = null; - if (actionIndex == 0) - { - // FIXME: Supply localized descriptions in the UIDefaults. - descr = UIManager.getString("AbstractButton.clickText"); - } - return descr; - } - - /** - * Performs the acccessible action with the specified index on this object. - * Since buttons have only one action by default (which is to press the - * button), this method performs a 'press button' when the specified index - * is <code>0</code> and nothing otherwise. - * - * @param actionIndex a zero based index into the actions of this button - * - * @return <code>true</code> if the specified action has been performed - * successfully, <code>false</code> otherwise - */ - public boolean doAccessibleAction(int actionIndex) - { - boolean retVal = false; - if (actionIndex == 0) - { - doClick(); - retVal = true; - } - return retVal; - } - - /** - * Returns the current value of this object as a number. This - * implementation returns an <code>Integer(1)</code> if the button is - * selected, <code>Integer(0)</code> if the button is not selected. - * - * @return the current value of this object as a number - */ - public Number getCurrentAccessibleValue() - { - Integer retVal; - if (isSelected()) - retVal = new Integer(1); - else - retVal = new Integer(0); - return retVal; - } - - /** - * Sets the current accessible value as object. If the specified number - * is 0 the button will be deselected, otherwise the button will - * be selected. - * - * @param value 0 for deselected button, other for selected button - * - * @return <code>true</code> if the value has been set, <code>false</code> - * otherwise - */ - public boolean setCurrentAccessibleValue(Number value) - { - boolean retVal = false; - if (value != null) - { - if (value.intValue() == 0) - setSelected(false); - else - setSelected(true); - retVal = true; - } - return retVal; - } - - /** - * Returns the minimum accessible value for the AccessibleAbstractButton, - * which is <code>0</code>. - * - * @return the minimimum accessible value for the AccessibleAbstractButton, - * which is <code>0</code> - */ - public Number getMinimumAccessibleValue() - { - return new Integer(0); - } - - /** - * Returns the maximum accessible value for the AccessibleAbstractButton, - * which is <code>1</code>. - * - * @return the maximum accessible value for the AccessibleAbstractButton, - * which is <code>1</code> - */ - public Number getMaximumAccessibleValue() - { - return new Integer(1); - } - - /** - * Returns the accessible text for this AccessibleAbstractButton. This - * will be <code>null</code> if the button has a non-HTML label, otherwise - * <code>this</code>. - * - * @return the accessible text for this AccessibleAbstractButton - */ - public AccessibleText getAccessibleText() - { - AccessibleText accessibleText = null; - if (getClientProperty(BasicHTML.propertyKey) != null) - accessibleText = this; - - return accessibleText; - } - - /** - * Returns the index of the label's character at the specified point, - * relative to the local bounds of the button. This only works for - * HTML labels. - * - * @param p the point, relative to the buttons local bounds - * - * @return the index of the label's character at the specified point - */ - public int getIndexAtPoint(Point p) - { - int index = -1; - View view = (View) getClientProperty(BasicHTML.propertyKey); - if (view != null) - { - Rectangle shape = new Rectangle(0, 0, getWidth(), getHeight()); - index = view.viewToModel(p.x, p.y, shape, new Position.Bias[1]); - } - return index; - } - - /** - * Returns the bounds of the character at the specified index of the - * button's label. This will only work for HTML labels. - * - * @param i the index of the character of the label - * - * @return the bounds of the character at the specified index of the - * button's label - */ - public Rectangle getCharacterBounds(int i) - { - Rectangle rect = null; - View view = (View) getClientProperty(BasicHTML.propertyKey); - if (view != null) - { - Rectangle shape = new Rectangle(0, 0, getWidth(), getHeight()); - try - { - Shape s = view.modelToView(i, shape, Position.Bias.Forward); - rect = s.getBounds(); - } - catch (BadLocationException ex) - { - rect = null; - } - } - return rect; - } - - /** - * Returns the number of characters in the button's label. - * - * @return the bounds of the character at the specified index of the - * button's label - */ - public int getCharCount() - { - int charCount; - View view = (View) getClientProperty(BasicHTML.propertyKey); - if (view != null) - { - charCount = view.getDocument().getLength(); - } - else - { - charCount = getAccessibleName().length(); - } - return charCount; - } - - /** - * This always returns <code>-1</code> since there is no caret in a button. - * - * @return <code>-1</code> since there is no caret in a button - */ - public int getCaretPosition() - { - return -1; - } - - /** - * Returns the character, word or sentence at the specified index. The - * <code>part</code> parameter determines what is returned, the character, - * word or sentence after the index. - * - * @param part one of {@link AccessibleText#CHARACTER}, - * {@link AccessibleText#WORD} or - * {@link AccessibleText#SENTENCE}, specifying what is returned - * @param index the index - * - * @return the character, word or sentence after <code>index</code> - */ - public String getAtIndex(int part, int index) - { - String result = ""; - int startIndex = -1; - int endIndex = -1; - switch(part) - { - case AccessibleText.CHARACTER: - result = String.valueOf(text.charAt(index)); - break; - case AccessibleText.WORD: - startIndex = text.lastIndexOf(' ', index); - endIndex = text.indexOf(' ', startIndex + 1); - if (endIndex == -1) - endIndex = startIndex + 1; - result = text.substring(startIndex + 1, endIndex); - break; - case AccessibleText.SENTENCE: - default: - startIndex = text.lastIndexOf('.', index); - endIndex = text.indexOf('.', startIndex + 1); - if (endIndex == -1) - endIndex = startIndex + 1; - result = text.substring(startIndex + 1, endIndex); - break; - } - return result; - } - - /** - * Returns the character, word or sentence after the specified index. The - * <code>part</code> parameter determines what is returned, the character, - * word or sentence after the index. - * - * @param part one of {@link AccessibleText#CHARACTER}, - * {@link AccessibleText#WORD} or - * {@link AccessibleText#SENTENCE}, specifying what is returned - * @param index the index - * - * @return the character, word or sentence after <code>index</code> - */ - public String getAfterIndex(int part, int index) - { - String result = ""; - int startIndex = -1; - int endIndex = -1; - switch(part) - { - case AccessibleText.CHARACTER: - result = String.valueOf(text.charAt(index + 1)); - break; - case AccessibleText.WORD: - startIndex = text.indexOf(' ', index); - endIndex = text.indexOf(' ', startIndex + 1); - if (endIndex == -1) - endIndex = startIndex + 1; - result = text.substring(startIndex + 1, endIndex); - break; - case AccessibleText.SENTENCE: - default: - startIndex = text.indexOf('.', index); - endIndex = text.indexOf('.', startIndex + 1); - if (endIndex == -1) - endIndex = startIndex + 1; - result = text.substring(startIndex + 1, endIndex); - break; - } - return result; - } - - /** - * Returns the character, word or sentence before the specified index. The - * <code>part</code> parameter determines what is returned, the character, - * word or sentence before the index. - * - * @param part one of {@link AccessibleText#CHARACTER}, - * {@link AccessibleText#WORD} or - * {@link AccessibleText#SENTENCE}, specifying what is returned - * @param index the index - * - * @return the character, word or sentence before <code>index</code> - */ - public String getBeforeIndex(int part, int index) - { - String result = ""; - int startIndex = -1; - int endIndex = -1; - switch(part) - { - case AccessibleText.CHARACTER: - result = String.valueOf(text.charAt(index - 1)); - break; - case AccessibleText.WORD: - endIndex = text.lastIndexOf(' ', index); - if (endIndex == -1) - endIndex = 0; - startIndex = text.lastIndexOf(' ', endIndex - 1); - result = text.substring(startIndex + 1, endIndex); - break; - case AccessibleText.SENTENCE: - default: - endIndex = text.lastIndexOf('.', index); - if (endIndex == -1) - endIndex = 0; - startIndex = text.lastIndexOf('.', endIndex - 1); - result = text.substring(startIndex + 1, endIndex); - break; - } - return result; - } - - /** - * Returns the text attribute for the character at the specified character - * index. - * - * @param i the character index - * - * @return the character attributes for the specified character or - * <code>null</code> if the character has no attributes - */ - public AttributeSet getCharacterAttribute(int i) - { - AttributeSet atts = null; - View view = (View) getClientProperty(BasicHTML.propertyKey); - if (view != null) - { - Document doc = view.getDocument(); - if (doc instanceof StyledDocument) - { - StyledDocument sDoc = (StyledDocument) doc; - Element charEl = sDoc.getCharacterElement(i); - if (charEl != null) - atts = charEl.getAttributes(); - } - } - return atts; - } - - /** - * This always returns <code>-1</code> since - * button labels can't be selected. - * - * @return <code>-1</code>, button labels can't be selected - */ - public int getSelectionStart() - { - return -1; - } - - /** - * This always returns <code>-1</code> since - * button labels can't be selected. - * - * @return <code>-1</code>, button labels can't be selected - */ - public int getSelectionEnd() - { - return -1; - } - - /** - * Returns the selected text. This always returns <code>null</code> since - * button labels can't be selected. - * - * @return <code>null</code>, button labels can't be selected - */ - public String getSelectedText() - { - return null; - } - } - - /** - * Creates a new AbstractButton object. Subclasses should call the following - * sequence in their constructor in order to initialize the button correctly: - * <pre> - * super(); - * init(text, icon); - * </pre> - * - * The {@link #init(String, Icon)} method is not called automatically by this - * constructor. - * - * @see #init(String, Icon) - */ - public AbstractButton() - { - horizontalAlignment = CENTER; - horizontalTextPosition = TRAILING; - verticalAlignment = CENTER; - verticalTextPosition = CENTER; - borderPainted = true; - contentAreaFilled = true; - focusPainted = true; - setFocusable(true); - setAlignmentX(CENTER_ALIGNMENT); - setAlignmentY(CENTER_ALIGNMENT); - setDisplayedMnemonicIndex(-1); - setOpaque(true); - text = ""; - // testing on JRE1.5 shows that the iconTextGap default value is - // hard-coded here and the 'Button.iconTextGap' setting in the - // UI defaults is ignored, at least by the MetalLookAndFeel - iconTextGap = 4; - } - - /** - * Get the model the button is currently using. - * - * @return The current model - */ - public ButtonModel getModel() - { - return model; - } - - /** - * Set the model the button is currently using. This un-registers all - * listeners associated with the current model, and re-registers them - * with the new model. - * - * @param newModel The new model - */ - public void setModel(ButtonModel newModel) - { - if (newModel == model) - return; - - if (model != null) - { - model.removeActionListener(actionListener); - actionListener = null; - model.removeChangeListener(changeListener); - changeListener = null; - model.removeItemListener(itemListener); - itemListener = null; - } - ButtonModel old = model; - model = newModel; - if (model != null) - { - actionListener = createActionListener(); - model.addActionListener(actionListener); - changeListener = createChangeListener(); - model.addChangeListener(changeListener); - itemListener = createItemListener(); - model.addItemListener(itemListener); - } - firePropertyChange(MODEL_CHANGED_PROPERTY, old, model); - revalidate(); - repaint(); - } - - protected void init(String text, Icon icon) - { - // If text is null, we fall back to the empty - // string (which is set using AbstractButton's - // constructor). - // This way the behavior of the JDK is matched. - if(text != null) - setText(text); - - if (icon != null) - default_icon = icon; - - updateUI(); - } - - /** - * <p>Returns the action command string for this button's model.</p> - * - * <p>If the action command was set to <code>null</code>, the button's - * text (label) is returned instead.</p> - * - * @return The current action command string from the button's model - */ - public String getActionCommand() - { - String ac = model.getActionCommand(); - if (ac != null) - return ac; - else - return text; - } - - /** - * Sets the action command string for this button's model. - * - * @param actionCommand The new action command string to set in the button's - * model. - */ - public void setActionCommand(String actionCommand) - { - if (model != null) - model.setActionCommand(actionCommand); - } - - /** - * Adds an ActionListener to the button's listener list. When the - * button's model is clicked it fires an ActionEvent, and these - * listeners will be called. - * - * @param l The new listener to add - */ - public void addActionListener(ActionListener l) - { - listenerList.add(ActionListener.class, l); - } - - /** - * Removes an ActionListener from the button's listener list. - * - * @param l The listener to remove - */ - public void removeActionListener(ActionListener l) - { - listenerList.remove(ActionListener.class, l); - } - - /** - * Returns all added <code>ActionListener</code> objects. - * - * @return an array of listeners - * - * @since 1.4 - */ - public ActionListener[] getActionListeners() - { - return (ActionListener[]) listenerList.getListeners(ActionListener.class); - } - - /** - * Adds an ItemListener to the button's listener list. When the button's - * model changes state (between any of ARMED, ENABLED, PRESSED, ROLLOVER - * or SELECTED) it fires an ItemEvent, and these listeners will be - * called. - * - * @param l The new listener to add - */ - public void addItemListener(ItemListener l) - { - listenerList.add(ItemListener.class, l); - } - - /** - * Removes an ItemListener from the button's listener list. - * - * @param l The listener to remove - */ - public void removeItemListener(ItemListener l) - { - listenerList.remove(ItemListener.class, l); - } - - /** - * Returns all added <code>ItemListener</code> objects. - * - * @return an array of listeners - * - * @since 1.4 - */ - public ItemListener[] getItemListeners() - { - return (ItemListener[]) listenerList.getListeners(ItemListener.class); - } - - /** - * Adds a ChangeListener to the button's listener list. When the button's - * model changes any of its (non-bound) properties, these listeners will be - * called. - * - * @param l The new listener to add - */ - public void addChangeListener(ChangeListener l) - { - listenerList.add(ChangeListener.class, l); - } - - /** - * Removes a ChangeListener from the button's listener list. - * - * @param l The listener to remove - */ - public void removeChangeListener(ChangeListener l) - { - listenerList.remove(ChangeListener.class, l); - } - - /** - * Returns all added <code>ChangeListener</code> objects. - * - * @return an array of listeners - * - * @since 1.4 - */ - public ChangeListener[] getChangeListeners() - { - return (ChangeListener[]) listenerList.getListeners(ChangeListener.class); - } - - /** - * Calls {@link ItemListener#itemStateChanged} on each ItemListener in - * the button's listener list. - * - * @param e The event signifying that the button's model changed state - */ - protected void fireItemStateChanged(ItemEvent e) - { - e.setSource(this); - ItemListener[] listeners = getItemListeners(); - - for (int i = 0; i < listeners.length; i++) - listeners[i].itemStateChanged(e); - } - - /** - * Calls {@link ActionListener#actionPerformed} on each {@link - * ActionListener} in the button's listener list. - * - * @param e The event signifying that the button's model was clicked - */ - protected void fireActionPerformed(ActionEvent e) - { - // Dispatch a copy of the given ActionEvent in order to - // set the source and action command correctly. - ActionEvent ae = new ActionEvent( - this, - e.getID(), - getActionCommand(), - e.getWhen(), - e.getModifiers()); - - ActionListener[] listeners = getActionListeners(); - - for (int i = 0; i < listeners.length; i++) - listeners[i].actionPerformed(ae); - } - - /** - * Calls {@link ChangeListener#stateChanged} on each {@link ChangeListener} - * in the button's listener list. - */ - protected void fireStateChanged() - { - ChangeListener[] listeners = getChangeListeners(); - - for (int i = 0; i < listeners.length; i++) - listeners[i].stateChanged(changeEvent); - } - - /** - * Get the current keyboard mnemonic value. This value corresponds to a - * single key code (one of the {@link java.awt.event.KeyEvent} VK_* - * codes) and is used to activate the button when pressed in conjunction - * with the "mouseless modifier" of the button's look and feel class, and - * when focus is in one of the button's ancestors. - * - * @return The button's current keyboard mnemonic - */ - public int getMnemonic() - { - ButtonModel mod = getModel(); - if (mod != null) - return mod.getMnemonic(); - return -1; - } - - /** - * Set the current keyboard mnemonic value. This value corresponds to a - * single key code (one of the {@link java.awt.event.KeyEvent} VK_* - * codes) and is used to activate the button when pressed in conjunction - * with the "mouseless modifier" of the button's look and feel class, and - * when focus is in one of the button's ancestors. - * - * @param mne A new mnemonic to use for the button - */ - public void setMnemonic(char mne) - { - setMnemonic((int) mne); - } - - /** - * Set the current keyboard mnemonic value. This value corresponds to a - * single key code (one of the {@link java.awt.event.KeyEvent} VK_* - * codes) and is used to activate the button when pressed in conjunction - * with the "mouseless modifier" of the button's look and feel class, and - * when focus is in one of the button's ancestors. - * - * @param mne A new mnemonic to use for the button - */ - public void setMnemonic(int mne) - { - ButtonModel mod = getModel(); - int old = -1; - if (mod != null) - old = mod.getMnemonic(); - - if (old != mne) - { - if (mod != null) - mod.setMnemonic(mne); - - if (text != null && !text.equals("")) - { - // Since lower case char = upper case char for - // mnemonic, we will convert both text and mnemonic - // to upper case before checking if mnemonic character occurs - // in the menu item text. - int upperCaseMne = Character.toUpperCase((char) mne); - String upperCaseText = text.toUpperCase(); - setDisplayedMnemonicIndex(upperCaseText.indexOf(upperCaseMne)); - } - - firePropertyChange(MNEMONIC_CHANGED_PROPERTY, old, mne); - revalidate(); - repaint(); - } - } - - /** - * Sets the button's mnemonic index. The mnemonic index is a hint to the - * look and feel class, suggesting which character in the button's label - * should be underlined when drawing the label. If the mnemonic index is - * -1, no mnemonic will be displayed. - * - * If no mnemonic index is set, the button will choose a mnemonic index - * by default, which will be the first occurrence of the mnemonic - * character in the button's text. - * - * @param index An offset into the "text" property of the button - * @throws IllegalArgumentException If <code>index</code> is not within the - * range of legal offsets for the "text" property of the button. - * @since 1.4 - */ - - public void setDisplayedMnemonicIndex(int index) - { - if (index < -1 || (text != null && index >= text.length())) - throw new IllegalArgumentException(); - - mnemonicIndex = index; - } - - /** - * Get the button's mnemonic index, which is an offset into the button's - * "text" property. The character specified by this offset should be - * underlined when the look and feel class draws this button. - * - * @return An index into the button's "text" property - */ - public int getDisplayedMnemonicIndex() - { - return mnemonicIndex; - } - - - /** - * Set the "rolloverEnabled" property. When rollover is enabled, and the - * look and feel supports it, the button will change its icon to - * rolloverIcon, when the mouse passes over it. - * - * @param r Whether or not to enable rollover icon changes - */ - public void setRolloverEnabled(boolean r) - { - clientRolloverEnabledSet = true; - if (rollOverEnabled != r) - { - rollOverEnabled = r; - firePropertyChange(ROLLOVER_ENABLED_CHANGED_PROPERTY, !r, r); - revalidate(); - repaint(); - } - } - - /** - * Returns whether or not rollover icon changes are enabled on the - * button. - * - * @return The state of the "rolloverEnabled" property - */ - public boolean isRolloverEnabled() - { - return rollOverEnabled; - } - - /** - * Set the value of the button's "selected" property. Selection is only - * meaningful for toggle-type buttons (check boxes, radio buttons). - * - * @param s New value for the property - */ - public void setSelected(boolean s) - { - ButtonModel mod = getModel(); - if (mod != null) - mod.setSelected(s); - } - - /** - * Get the value of the button's "selected" property. Selection is only - * meaningful for toggle-type buttons (check boxes, radio buttons). - * - * @return The value of the property - */ - public boolean isSelected() - { - ButtonModel mod = getModel(); - if (mod != null) - return mod.isSelected(); - return false; - } - - /** - * Enables or disables the button. A button will neither be selectable - * nor preform any actions unless it is enabled. - * - * @param b Whether or not to enable the button - */ - public void setEnabled(boolean b) - { - // Do nothing if state does not change. - if (b == isEnabled()) - return; - super.setEnabled(b); - setFocusable(b); - ButtonModel mod = getModel(); - if (mod != null) - mod.setEnabled(b); - } - - /** - * Set the horizontal alignment of the button's text and icon. The - * alignment is a numeric constant from {@link SwingConstants}. It must - * be one of: <code>RIGHT</code>, <code>LEFT</code>, <code>CENTER</code>, - * <code>LEADING</code> or <code>TRAILING</code>. The default is - * <code>CENTER</code>. - * - * @return The current horizontal alignment - * - * @see #setHorizontalAlignment(int) - */ - public int getHorizontalAlignment() - { - return horizontalAlignment; - } - - /** - * Set the horizontal alignment of the button's text and icon. The - * alignment is a numeric constant from {@link SwingConstants}. It must - * be one of: <code>RIGHT</code>, <code>LEFT</code>, <code>CENTER</code>, - * <code>LEADING</code> or <code>TRAILING</code>. The default is - * <code>CENTER</code>. - * - * @param a The new horizontal alignment - * @throws IllegalArgumentException If alignment is not one of the legal - * constants. - * - * @see #getHorizontalAlignment() - */ - public void setHorizontalAlignment(int a) - { - if (horizontalAlignment == a) - return; - if (a != LEFT && a != CENTER && a != RIGHT && a != LEADING - && a != TRAILING) - throw new IllegalArgumentException("Invalid alignment."); - int old = horizontalAlignment; - horizontalAlignment = a; - firePropertyChange(HORIZONTAL_ALIGNMENT_CHANGED_PROPERTY, old, a); - revalidate(); - repaint(); - } - - /** - * Get the horizontal position of the button's text relative to its - * icon. The position is a numeric constant from {@link - * SwingConstants}. It must be one of: <code>RIGHT</code>, - * <code>LEFT</code>, <code>CENTER</code>, <code>LEADING</code> or - * <code>TRAILING</code>. The default is <code>TRAILING</code>. - * - * @return The current horizontal text position - */ - public int getHorizontalTextPosition() - { - return horizontalTextPosition; - } - - /** - * Set the horizontal position of the button's text relative to its - * icon. The position is a numeric constant from {@link - * SwingConstants}. It must be one of: <code>RIGHT</code>, - * <code>LEFT</code>, <code>CENTER</code>, <code>LEADING</code> or - * <code>TRAILING</code>. The default is <code>TRAILING</code>. - * - * @param t The new horizontal text position - * @throws IllegalArgumentException If position is not one of the legal - * constants. - */ - public void setHorizontalTextPosition(int t) - { - if (horizontalTextPosition == t) - return; - if (t != LEFT && t != CENTER && t != RIGHT && t != LEADING - && t != TRAILING) - throw new IllegalArgumentException("Invalid alignment."); - - int old = horizontalTextPosition; - horizontalTextPosition = t; - firePropertyChange(HORIZONTAL_TEXT_POSITION_CHANGED_PROPERTY, old, t); - revalidate(); - repaint(); - } - - /** - * Get the vertical alignment of the button's text and icon. The - * alignment is a numeric constant from {@link SwingConstants}. It must - * be one of: <code>CENTER</code>, <code>TOP</code>, or - * <code>BOTTOM</code>. The default is <code>CENTER</code>. - * - * @return The current vertical alignment - * - * @see #setVerticalAlignment(int) - */ - public int getVerticalAlignment() - { - return verticalAlignment; - } - - /** - * Set the vertical alignment of the button's text and icon. The - * alignment is a numeric constant from {@link SwingConstants}. It must - * be one of: <code>CENTER</code>, <code>TOP</code>, or - * <code>BOTTOM</code>. The default is <code>CENTER</code>. - * - * @param a The new vertical alignment - * @throws IllegalArgumentException If alignment is not one of the legal - * constants. - * - * @see #getVerticalAlignment() - */ - public void setVerticalAlignment(int a) - { - if (verticalAlignment == a) - return; - if (a != TOP && a != CENTER && a != BOTTOM) - throw new IllegalArgumentException("Invalid alignment."); - - int old = verticalAlignment; - verticalAlignment = a; - firePropertyChange(VERTICAL_ALIGNMENT_CHANGED_PROPERTY, old, a); - revalidate(); - repaint(); - } - - /** - * Get the vertical position of the button's text relative to its - * icon. The alignment is a numeric constant from {@link - * SwingConstants}. It must be one of: <code>CENTER</code>, - * <code>TOP</code>, or <code>BOTTOM</code>. The default is - * <code>CENTER</code>. - * - * @return The current vertical position - */ - public int getVerticalTextPosition() - { - return verticalTextPosition; - } - - /** - * Set the vertical position of the button's text relative to its - * icon. The alignment is a numeric constant from {@link - * SwingConstants}. It must be one of: <code>CENTER</code>, - * <code>TOP</code>, or <code>BOTTOM</code>. The default is - * <code>CENTER</code>. - * - * @param t The new vertical position - * @throws IllegalArgumentException If position is not one of the legal - * constants. - */ - public void setVerticalTextPosition(int t) - { - if (verticalTextPosition == t) - return; - if (t != TOP && t != CENTER && t != BOTTOM) - throw new IllegalArgumentException("Invalid alignment."); - - int old = verticalTextPosition; - verticalTextPosition = t; - firePropertyChange(VERTICAL_TEXT_POSITION_CHANGED_PROPERTY, old, t); - revalidate(); - repaint(); - } - - /** - * Set the value of the "borderPainted" property. If set to - * <code>false</code>, the button's look and feel class should not paint - * a border for the button. The default is <code>true</code>. - * - * @return The current value of the property. - */ - public boolean isBorderPainted() - { - return borderPainted; - } - - /** - * Set the value of the "borderPainted" property. If set to - * <code>false</code>, the button's look and feel class should not paint - * a border for the button. The default is <code>true</code>. - * - * @param b The new value of the property. - */ - public void setBorderPainted(boolean b) - { - clientBorderPaintedSet = true; - if (borderPainted == b) - return; - boolean old = borderPainted; - borderPainted = b; - firePropertyChange(BORDER_PAINTED_CHANGED_PROPERTY, old, b); - revalidate(); - repaint(); - } - - /** - * Get the value of the "action" property. - * - * @return The current value of the "action" property - */ - public Action getAction() - { - return action; - } - - /** - * <p>Set the button's "action" property, subscribing the new action to the - * button, as an ActionListener, if it is not already subscribed. The old - * Action, if it exists, is unsubscribed, and the button is unsubscribed - * from the old Action if it was previously subscribed as a - * PropertyChangeListener.</p> - * - * <p>This method also configures several of the button's properties from - * the Action, by calling {@link #configurePropertiesFromAction}, and - * subscribes the button to the Action as a PropertyChangeListener. - * Subsequent changes to the Action will thus reconfigure the button - * automatically.</p> - * - * @param a The new value of the "action" property - */ - public void setAction(Action a) - { - if (action != null) - { - action.removePropertyChangeListener(actionPropertyChangeListener); - removeActionListener(action); - if (actionPropertyChangeListener != null) - { - action.removePropertyChangeListener(actionPropertyChangeListener); - actionPropertyChangeListener = null; - } - } - - Action old = action; - action = a; - configurePropertiesFromAction(action); - if (action != null) - { - actionPropertyChangeListener = createActionPropertyChangeListener(a); - action.addPropertyChangeListener(actionPropertyChangeListener); - addActionListener(action); - } - } - - /** - * Return the button's default "icon" property. - * - * @return The current default icon - */ - public Icon getIcon() - { - return default_icon; - } - - /** - * Set the button's default "icon" property. This icon is used as a basis - * for the pressed and disabled icons, if none are explicitly set. - * - * @param i The new default icon - */ - public void setIcon(Icon i) - { - if (default_icon == i) - return; - - Icon old = default_icon; - default_icon = i; - firePropertyChange(ICON_CHANGED_PROPERTY, old, i); - revalidate(); - repaint(); - } - - /** - * Return the button's "text" property. This property is synonymous with - * the "label" property. - * - * @return The current "text" property - */ - public String getText() - { - return text; - } - - /** - * Set the button's "label" property. This property is synonymous with the - * "text" property. - * - * @param label The new "label" property - * - * @deprecated use <code>setText(text)</code> - */ - public void setLabel(String label) - { - setText(label); - } - - /** - * Return the button's "label" property. This property is synonymous with - * the "text" property. - * - * @return The current "label" property - * - * @deprecated use <code>getText()</code> - */ - public String getLabel() - { - return getText(); - } - - /** - * Set the button's "text" property. This property is synonymous with the - * "label" property. - * - * @param t The new "text" property - */ - public void setText(String t) - { - if (text == t) - return; - - String old = text; - text = t; - firePropertyChange(TEXT_CHANGED_PROPERTY, old, t); - revalidate(); - ... [truncated message content] |
From: <ls...@us...> - 2008-03-16 20:26:17
|
Revision: 3857 http://jnode.svn.sourceforge.net/jnode/?rev=3857&view=rev Author: lsantha Date: 2008-03-16 13:26:16 -0700 (Sun, 16 Mar 2008) Log Message: ----------- OpenJDK AWT & Swing integration. Removed Paths: ------------- trunk/core/src/classpath/javax/javax/swing/DebugGraphics.java trunk/core/src/classpath/javax/javax/swing/JComponent.java trunk/core/src/classpath/javax/javax/swing/KeyboardManager.java trunk/core/src/classpath/javax/javax/swing/RepaintManager.java trunk/core/src/classpath/javax/javax/swing/SwingUtilities.java Deleted: trunk/core/src/classpath/javax/javax/swing/DebugGraphics.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/DebugGraphics.java 2008-03-16 20:25:30 UTC (rev 3856) +++ trunk/core/src/classpath/javax/javax/swing/DebugGraphics.java 2008-03-16 20:26:16 UTC (rev 3857) @@ -1,1125 +0,0 @@ -/* DebugGraphics.java -- - Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath 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 for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package javax.swing; - -import java.awt.Color; -import java.awt.Font; -import java.awt.FontMetrics; -import java.awt.Graphics; -import java.awt.Image; -import java.awt.Point; -import java.awt.Rectangle; -import java.awt.Shape; -import java.awt.image.ImageObserver; -import java.io.PrintStream; -import java.text.AttributedCharacterIterator; - - -/** - * An extension of {@link Graphics} that can be used for debugging - * custom Swing widgets. <code>DebugGraphics</code> has the ability to - * draw slowly and can log drawing actions. - * - * @author Andrew Selkirk - */ -public class DebugGraphics extends Graphics -{ - /** - * LOG_OPTION - */ - public static final int LOG_OPTION = 1; - - /** - * FLASH_OPTION - */ - public static final int FLASH_OPTION = 2; - - /** - * BUFFERED_OPTION - */ - public static final int BUFFERED_OPTION = 4; - - /** - * NONE_OPTION - */ - public static final int NONE_OPTION = -1; - - static Color debugFlashColor = Color.RED; - static int debugFlashCount = 10; - static int debugFlashTime = 1000; - static PrintStream debugLogStream = System.out; - - /** - * Counts the created DebugGraphics objects. This is used by the - * logging facility. - */ - static int counter = 0; - - /** - * graphics - */ - Graphics graphics; - - /** - * buffer - */ - Image buffer; - - /** - * debugOptions - */ - int debugOptions; - - /** - * graphicsID - */ - int graphicsID; - - /** - * xOffset - */ - int xOffset; - - /** - * yOffset - */ - int yOffset; - - /** - * Creates a <code>DebugGraphics</code> object. - */ - public DebugGraphics() - { - counter++; - } - - /** - * Creates a <code>DebugGraphics</code> object. - * - * @param graphics The <code>Graphics</code> object to wrap - * @param component TODO - */ - public DebugGraphics(Graphics graphics, JComponent component) - { - this(graphics); - // FIXME: What shall we do with component ? - } - - /** - * Creates a <code>DebugGraphics</code> object. - * - * @param graphics The <code>Graphics</code> object to wrap - */ - public DebugGraphics(Graphics graphics) - { - this(); - this.graphics = graphics; - } - - /** - * Sets the color to draw stuff with. - * - * @param color The color - */ - public void setColor(Color color) - { - if ((debugOptions & LOG_OPTION) != 0) - logStream().println(prefix() + " Setting color: " + color); - - graphics.setColor(color); - } - - /** - * Creates a overrides <code>Graphics.create</code> to create a - * <code>DebugGraphics</code> object. - * - * @return a new <code>DebugGraphics</code> object. - */ - public Graphics create() - { - DebugGraphics copy = new DebugGraphics(graphics.create()); - copy.debugOptions = debugOptions; - return copy; - } - - /** - * Creates a overrides <code>Graphics.create</code> to create a - * <code>DebugGraphics</code> object. - * - * @param x the x coordinate - * @param y the y coordinate - * @param width the width - * @param height the height - * - * @return a new <code>DebugGraphics</code> object. - */ - public Graphics create(int x, int y, int width, int height) - { - DebugGraphics copy = new DebugGraphics(graphics.create(x, y, width, - height)); - copy.debugOptions = debugOptions; - return copy; - } - - /** - * flashColor - * - * @return Color - */ - public static Color flashColor() - { - return debugFlashColor; - } - - /** - * setFlashColor - * - * @param color the color to use for flashing - */ - public static void setFlashColor(Color color) - { - debugFlashColor = color; - } - - /** - * flashTime - * - * @return The time in milliseconds - */ - public static int flashTime() - { - return debugFlashTime; - } - - /** - * setFlashTime - * - * @param time The time in milliseconds - */ - public static void setFlashTime(int time) - { - debugFlashTime = time; - } - - /** - * flashCount - * - * @return The number of flashes - */ - public static int flashCount() - { - return debugFlashCount; - } - - /** - * setFlashCount - * - * @param count The number of flashes - */ - public static void setFlashCount(int count) - { - debugFlashCount = count; - } - - /** - * logStream - * - * @return The <code>PrintStream</code> to write logging messages to - */ - public static PrintStream logStream() - { - return debugLogStream; - } - - /** - * setLogStream - * - * @param stream The currently set <code>PrintStream</code>. - */ - public static void setLogStream(PrintStream stream) - { - debugLogStream = stream; - } - - /** - * getFont - * - * @return The font - */ - public Font getFont() - { - return graphics.getFont(); - } - - /** - * setFont - * - * @param font The font to use for drawing text - */ - public void setFont(Font font) - { - if ((debugOptions & LOG_OPTION) != 0) - logStream().println(prefix() + " Setting font: " + font); - - graphics.setFont(font); - } - - /** - * Returns the color used for drawing. - * - * @return The color. - */ - public Color getColor() - { - return graphics.getColor(); - } - - /** - * Returns the font metrics of the current font. - * - * @return a <code>FontMetrics</code> object - */ - public FontMetrics getFontMetrics() - { - return graphics.getFontMetrics(); - } - - /** - * Returns the font metrics for a given font. - * - * @param font the font to get the metrics for - * - * @return a <code>FontMetrics</code> object - */ - public FontMetrics getFontMetrics(Font font) - { - return graphics.getFontMetrics(font); - } - - /** - * translate - * - * @param x the x coordinate - * @param y the y coordinate - */ - public void translate(int x, int y) - { - if ((debugOptions & LOG_OPTION) != 0) - logStream().println(prefix() + " Translating by: " + new Point(x, y)); - - graphics.translate(x, y); - } - - /** - * setPaintMode - */ - public void setPaintMode() - { - if ((debugOptions & LOG_OPTION) != 0) - logStream().println(prefix() + " Setting paint mode"); - - graphics.setPaintMode(); - } - - /** - * setXORMode - * - * @param color the color - */ - public void setXORMode(Color color) - { - if ((debugOptions & LOG_OPTION) != 0) - logStream().println(prefix() + " Setting XOR mode: " + color); - - graphics.setXORMode(color); - } - - /** - * getClipBounds - * - * @return Rectangle - */ - public Rectangle getClipBounds() - { - return graphics.getClipBounds(); - } - - /** - * Intersects the current clip region with the given region. - * - * @param x The x-position of the region - * @param y The y-position of the region - * @param width The width of the region - * @param height The height of the region - */ - public void clipRect(int x, int y, int width, int height) - { - if ((debugOptions & LOG_OPTION) != 0) - { - logStream().print(prefix() + " Setting clipRect: " - + new Rectangle(x, y, width, height)); - } - - graphics.clipRect(x, y, width, height); - - if ((debugOptions & LOG_OPTION) != 0) - logStream().println(" Netting clipRect: " + graphics.getClipBounds()); - } - - /** - * Sets the clipping region. - * - * @param x The x-position of the region - * @param y The y-position of the region - * @param width The width of the region - * @param height The height of the region - */ - public void setClip(int x, int y, int width, int height) - { - if ((debugOptions & LOG_OPTION) != 0) - { - logStream().println(prefix() + " Setting new clipRect: " - + new Rectangle(x, y, width, height)); - } - - graphics.setClip(x, y, width, height); - } - - /** - * Returns the current clipping region. - * - * @return Shape - */ - public Shape getClip() - { - return graphics.getClip(); - } - - /** - * Sets the current clipping region - * - * @param shape The clippin region - */ - public void setClip(Shape shape) - { - if ((debugOptions & LOG_OPTION) != 0) - logStream().println(prefix() + " Setting new clipRect: " + shape); - - graphics.setClip(shape); - } - - private void sleep(int milliseconds) - { - try - { - Thread.sleep(milliseconds); - } - catch (InterruptedException e) - { - // Ignore this. - } - } - - /** - * Draws a rectangle. - * - * @param x The x-position of the rectangle - * @param y The y-position of the rectangle - * @param width The width of the rectangle - * @param height The height of the rectangle - */ - public void drawRect(int x, int y, int width, int height) - { - if ((debugOptions & LOG_OPTION) != 0) - { - logStream().println(prefix() + " Drawing rect: " - + new Rectangle(x, y, width, height)); - } - - if ((debugOptions & FLASH_OPTION) != 0) - { - Color color = graphics.getColor(); - for (int index = 0; index < (debugFlashCount - 1); ++index) - { - graphics.setColor(color); - graphics.drawRect(x, y, width, height); - sleep(debugFlashTime); - graphics.setColor(debugFlashColor); - graphics.drawRect(x, y, width, height); - sleep(debugFlashTime); - } - graphics.setColor(color); - } - - graphics.drawRect(x, y, width, height); - } - - /** - * Draws a filled rectangle. - * - * @param x The x-position of the rectangle - * @param y The y-position of the rectangle - * @param width The width of the rectangle - * @param height The height of the rectangle - */ - public void fillRect(int x, int y, int width, int height) - { - if ((debugOptions & LOG_OPTION) != 0) - { - logStream().println(prefix() + " Filling rect: " - + new Rectangle(x, y, width, height)); - } - - if ((debugOptions & FLASH_OPTION) != 0) - { - Color color = graphics.getColor(); - for (int index = 0; index < (debugFlashCount - 1); ++index) - { - graphics.setColor(color); - graphics.fillRect(x, y, width, height); - sleep(debugFlashTime); - graphics.setColor(debugFlashColor); - graphics.fillRect(x, y, width, height); - sleep(debugFlashTime); - } - graphics.setColor(color); - } - - graphics.fillRect(x, y, width, height); - } - - /** - * clearRect - * - * @param x The x-position of the rectangle - * @param y The y-position of the rectangle - * @param width The width of the rectangle - * @param height The height of the rectangle - */ - public void clearRect(int x, int y, int width, int height) - { - if ((debugOptions & LOG_OPTION) != 0) - { - logStream().println(prefix() + " Clearing rect: " - + new Rectangle(x, y, width, height)); - } - - graphics.clearRect(x, y, width, height); - } - - /** - * drawRoundRect - * - * @param x The x-position of the rectangle - * @param y The y-position of the rectangle - * @param width The width of the rectangle - * @param height The height of the rectangle - * @param arcWidth TODO - * @param arcHeight TODO - */ - public void drawRoundRect(int x, int y, int width, int height, - int arcWidth, int arcHeight) - { - if ((debugOptions & LOG_OPTION) != 0) - { - logStream().println(prefix() + " Drawing round rect: " - + new Rectangle(x, y, width, height) - + " arcWidth: " + arcWidth - + " arcHeight: " + arcHeight); - } - - graphics.drawRoundRect(x, y, width, height, arcWidth, arcHeight); - } - - /** - * fillRoundRect - * - * @param x The x-position of the rectangle - * @param y The y-position of the rectangle - * @param width The width of the rectangle - * @param height The height of the rectangle - * @param arcWidth TODO - * @param arcHeight TODO - */ - public void fillRoundRect(int x, int y, int width, int height, - int arcWidth, int arcHeight) - { - if ((debugOptions & LOG_OPTION) != 0) - { - logStream().println(prefix() + " Filling round rect: " - + new Rectangle(x, y, width, height) - + " arcWidth: " + arcWidth - + " arcHeight: " + arcHeight); - } - - graphics.fillRoundRect(x, y, width, height, arcWidth, arcHeight); - } - - /** - * drawLine - * - * @param x1 The x-position of the start - * @param y1 The y-position of the start - * @param x2 The x-position of the end - * @param y2 The y-position of the end - */ - public void drawLine(int x1, int y1, int x2, int y2) - { - if ((debugOptions & LOG_OPTION) != 0) - { - logStream().println(prefix() + " Drawing line: from (" + x1 + ", " - + y1 + ") to (" + x2 + ", " + y2 + ")"); - } - - graphics.drawLine(x1, y1, x2, y2); - } - - /** - * draw3DRect - * - * @param x The x-position of the rectangle - * @param y The y-position of the rectangle - * @param width The width of the rectangle - * @param height The height of the rectangle - * @param raised TODO - */ - public void draw3DRect(int x, int y, int width, int height, boolean raised) - { - if ((debugOptions & LOG_OPTION) != 0) - { - logStream().println(prefix() + " Drawing 3D rect: " - + new Rectangle(x, y, width, height) - + "Raised bezel: " + raised); - } - - graphics.draw3DRect(x, y, width, height, raised); - } - - /** - * fill3DRect - * - * @param x The x-position of the rectangle - * @param y The y-position of the rectangle - * @param width The width of the rectangle - * @param height The height of the rectangle - * @param raised TODO - */ - public void fill3DRect(int x, int y, int width, int height, boolean raised) - { - if ((debugOptions & LOG_OPTION) != 0) - { - logStream().println(prefix() + " Filling 3D rect: " - + new Rectangle(x, y, width, height) - + "Raised bezel: " + raised); - } - - graphics.fill3DRect(x, y, width, height, raised); - } - - /** - * drawOval - * - * @param x the x coordinate - * @param y the y coordiante - * @param width the width - * @param height the height - */ - public void drawOval(int x, int y, int width, int height) - { - if ((debugOptions & LOG_OPTION) != 0) - { - logStream().println(prefix() + " Drawing oval: " - + new Rectangle(x, y, width, height)); - } - - graphics.drawOval(x, y, width, height); - } - - /** - * fillOval - * - * @param x the x coordinate - * @param y the y coordinate - * @param width the width - * @param height the height - */ - public void fillOval(int x, int y, int width, int height) - { - if ((debugOptions & LOG_OPTION) != 0) - { - logStream().println(prefix() + " Filling oval: " - + new Rectangle(x, y, width, height)); - } - - graphics.fillOval(x, y, width, height); - } - - /** - * drawArc - * - * @param x the x coordinate - * @param y the y coordinate - * @param width the width - * @param height the height - * @param startAngle TODO - * @param arcAngle TODO - */ - public void drawArc(int x, int y, int width, int height, - int startAngle, int arcAngle) - { - if ((debugOptions & LOG_OPTION) != 0) - { - logStream().println(prefix() + " Drawing arc: " - + new Rectangle(x, y, width, height) - + " startAngle: " + startAngle - + " arcAngle: " + arcAngle); - } - - graphics.drawArc(x, y, width, height, startAngle, arcAngle); - } - - /** - * fillArc - * - * @param x the coordinate - * @param y the y coordinate - * @param width the width - * @param height the height - * @param startAngle TODO - * @param arcAngle TODO - */ - public void fillArc(int x, int y, int width, int height, - int startAngle, int arcAngle) - { - if ((debugOptions & LOG_OPTION) != 0) - { - logStream().println(prefix() + " Filling arc: " - + new Rectangle(x, y, width, height) - + " startAngle: " + startAngle - + " arcAngle: " + arcAngle); - } - - graphics.fillArc(x, y, width, height, startAngle, arcAngle); - } - - /** - * drawPolyline - * - * @param xpoints TODO - * @param ypoints TODO - * @param npoints TODO - */ - public void drawPolyline(int[] xpoints, int[] ypoints, int npoints) - { - if ((debugOptions & LOG_OPTION) != 0) - { - logStream().println(prefix() + " Drawing polyline: nPoints: " + npoints - + " X's: " + xpoints + " Y's: " + ypoints); - } - - graphics.drawPolyline(xpoints, ypoints, npoints); - } - - /** - * drawPolygon - * - * @param xpoints TODO - * @param ypoints TODO - * @param npoints TODO - */ - public void drawPolygon(int[] xpoints, int[] ypoints, int npoints) - { - if ((debugOptions & LOG_OPTION) != 0) - { - logStream().println(prefix() + " Drawing polygon: nPoints: " + npoints - + " X's: " + xpoints + " Y's: " + ypoints); - } - - graphics.drawPolygon(xpoints, ypoints, npoints); - } - - /** - * fillPolygon - * - * @param xpoints TODO - * @param ypoints TODO - * @param npoints TODO - */ - public void fillPolygon(int[] xpoints, int[] ypoints, int npoints) - { - if ((debugOptions & LOG_OPTION) != 0) - { - logStream().println(prefix() + " Drawing polygon: nPoints: " + npoints - + " X's: " + xpoints + " Y's: " + ypoints); - } - - graphics.fillPolygon(xpoints, ypoints, npoints); - } - - /** - * drawString - * - * @param string the string - * @param x the x coordinate - * @param y the y coordinate - */ - public void drawString(String string, int x, int y) - { - if ((debugOptions & LOG_OPTION) != 0) - { - logStream().println(prefix() + " Drawing string: \"" + string - + "\" at: " + new Point(x, y)); - } - - graphics.drawString(string, x, y); - } - - /** - * drawString - * - * @param iterator TODO - * @param x the x coordinate - * @param y the y coordinate - */ - public void drawString(AttributedCharacterIterator iterator, - int x, int y) - { - if ((debugOptions & LOG_OPTION) != 0) - { - logStream().println(prefix() + " Drawing string: \"" + iterator - + "\" at: " + new Point(x, y)); - } - - graphics.drawString(iterator, x, y); - } - - /** - * drawBytes - * - * @param data TODO - * @param offset TODO - * @param length TODO - * @param x the x coordinate - * @param y the y coordinate - */ - public void drawBytes(byte[] data, int offset, int length, - int x, int y) - { - if ((debugOptions & LOG_OPTION) != 0) - logStream().println(prefix() + " Drawing bytes at: " + new Point(x, y)); - - graphics.drawBytes(data, offset, length, x, y); - } - - /** - * drawChars - * - * @param data array of characters to draw - * @param offset offset in array - * @param length number of characters in array to draw - * @param x x-position - * @param y y-position - */ - public void drawChars(char[] data, int offset, int length, - int x, int y) - { - if ((debugOptions & LOG_OPTION) != 0) - logStream().println(prefix() + " Drawing chars at: " + new Point(x, y)); - - if ((debugOptions & FLASH_OPTION) != 0) - { - Color color = graphics.getColor(); - for (int index = 0; index < (debugFlashCount - 1); ++index) - { - graphics.setColor(color); - graphics.drawChars(data, offset, length, x, y); - sleep(debugFlashTime); - graphics.setColor(debugFlashColor); - graphics.drawChars(data, offset, length, x, y); - sleep(debugFlashTime); - } - graphics.setColor(color); - } - - graphics.drawChars(data, offset, length, x, y); - } - - /** - * drawImage - * - * @param image The image to draw - * @param x The x position - * @param y The y position - * @param observer The image observer - * @return boolean - */ - public boolean drawImage(Image image, int x, int y, - ImageObserver observer) - { - if ((debugOptions & LOG_OPTION) != 0) - { - logStream().println(prefix() + " Drawing image: " + image + " at: " - + new Point(x, y)); - } - - return graphics.drawImage(image, x, y, observer); - } - - /** - * drawImage - * - * @param image The image to draw - * @param x The x position - * @param y The y position - * @param width The width of the area to draw the image - * @param height The height of the area to draw the image - * @param observer The image observer - * - * @return boolean - */ - public boolean drawImage(Image image, int x, int y, int width, - int height, ImageObserver observer) - { - if ((debugOptions & LOG_OPTION) != 0) - { - logStream().println(prefix() + " Drawing image: " + image - + " at: " + new Rectangle(x, y, width, height)); - } - - return graphics.drawImage(image, x, y, width, height, observer); - } - - /** - * drawImage - * - * @param image The image to draw - * @param x The x position - * @param y The y position - * @param background The color for the background in the opaque regions - * of the image - * @param observer The image observer - * - * @return boolean - */ - public boolean drawImage(Image image, int x, int y, - Color background, ImageObserver observer) - { - if ((debugOptions & LOG_OPTION) != 0) - { - logStream().println(prefix() + " Drawing image: " + image - + " at: " + new Point(x, y) - + ", bgcolor: " + background); - } - - return graphics.drawImage(image, x, y, background, observer); - } - - /** - * drawImage - * - * @param image The image to draw - * @param x The x position - * @param y The y position - * @param width The width of the area to draw the image - * @param height The height of the area to draw the image - * @param background The color for the background in the opaque regions - * of the image - * @param observer The image observer - * - * @return boolean - */ - public boolean drawImage(Image image, int x, int y, int width, int height, - Color background, ImageObserver observer) - { - if ((debugOptions & LOG_OPTION) != 0) - { - logStream().println(prefix() + " Drawing image: " + image - + " at: " + new Rectangle(x, y, width, height) - + ", bgcolor: " + background); - } - - return graphics.drawImage(image, x, y, width, height, background, observer); - } - - /** - * drawImage - * - * @param image The image to draw - * @param dx1 TODO - * @param dy1 TODO - * @param dx2 TODO - * @param dy2 TODO - * @param sx1 TODO - * @param sy1 TODO - * @param sx2 TODO - * @param sy2 TODO - * @param observer The image observer - * - * @return boolean - */ - public boolean drawImage(Image image, int dx1, int dy1, - int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, - ImageObserver observer) - { - if ((debugOptions & LOG_OPTION) != 0) - { - logStream().println(prefix() + " Drawing image: " + image - + " destination: " + new Rectangle(dx1, dy1, dx2, dy2) - + " source: " + new Rectangle(sx1, sy1, sx2, sy2)); - } - - return graphics.drawImage(image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, observer); - } - - /** - * drawImage - * - * @param image The image to draw - * @param dx1 TODO - * @param dy1 TODO - * @param dx2 TODO - * @param dy2 TODO - * @param sx1 TODO - * @param sy1 TODO - * @param sx2 TODO - * @param sy2 TODO - * @param background The color for the background in the opaque regions - * of the image - * @param observer The image observer - * - * @return boolean - */ - public boolean drawImage(Image image, int dx1, int dy1, - int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, - Color background, ImageObserver observer) - { - if ((debugOptions & LOG_OPTION) != 0) - { - logStream().println(prefix() + " Drawing image: " + image - + " destination: " + new Rectangle(dx1, dy1, dx2, dy2) - + " source: " + new Rectangle(sx1, sy1, sx2, sy2) - + ", bgcolor: " + background); - } - - return graphics.drawImage(image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, background, observer); - } - - /** - * copyArea - * - * @param x The x position of the source area - * @param y The y position of the source area - * @param width The width of the area - * @param height The height of the area - * @param destx The x position of the destination area - * @param desty The y posiiton of the destination area - */ - public void copyArea(int x, int y, int width, int height, - int destx, int desty) - { - if ((debugOptions & LOG_OPTION) != 0) - { - logStream().println(prefix() + " Copying area from: " - + new Rectangle(x, y, width, height) - + " to: " + new Point(destx, desty)); - } - - graphics.copyArea(x, y, width, height, destx, desty); - } - - /** - * Releases all system resources that this <code>Graphics</code> is using. - */ - public void dispose() - { - graphics.dispose(); - graphics = null; - } - - /** - * isDrawingBuffer - * - * @return boolean - */ - public boolean isDrawingBuffer() - { - return false; // TODO - } - - /** - * setDebugOptions - * - * @param options the debug options - */ - public void setDebugOptions(int options) - { - debugOptions = options; - if ((debugOptions & LOG_OPTION) != 0) - if (options == NONE_OPTION) - logStream().println(prefix() + "Disabling debug"); - else - logStream().println(prefix() + "Enabling debug"); - } - - /** - * getDebugOptions - * - * @return the debug options - */ - public int getDebugOptions() - { - return debugOptions; - } - - /** - * Creates and returns the prefix that should be prepended to all logging - * messages. The prefix is made up like this: - * - * <code>Graphics(<counter>-1)</code> where counter is an integer number - * saying how many DebugGraphics objects have been created so far. The second - * number always seem to be 1 on Sun's JDK, this has to be investigated a - * little more. - * - * @return the prefix that should be prepended to all logging - * messages - */ - private String prefix() - { - return "Graphics(" + counter + "-1)"; - } -} Deleted: trunk/core/src/classpath/javax/javax/swing/JComponent.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/JComponent.java 2008-03-16 20:25:30 UTC (rev 3856) +++ trunk/core/src/classpath/javax/javax/swing/JComponent.java 2008-03-16 20:26:16 UTC (rev 3857) @@ -1,4085 +0,0 @@ -/* JComponent.java -- Every component in swing inherits from this class. - Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath 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 for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package javax.swing; - -import java.applet.Applet; -import java.awt.AWTEvent; -import java.awt.Color; -import java.awt.Component; -import java.awt.Container; -import java.awt.Dimension; -import java.awt.EventQueue; -import java.awt.FocusTraversalPolicy; -import java.awt.Font; -import java.awt.Graphics; -import java.awt.Image; -import java.awt.Insets; -import java.awt.Point; -import java.awt.Rectangle; -import java.awt.Window; -import java.awt.dnd.DropTarget; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.ContainerEvent; -import java.awt.event.ContainerListener; -import java.awt.event.FocusEvent; -import java.awt.event.FocusListener; -import java.awt.event.KeyEvent; -import java.awt.event.MouseEvent; -import java.awt.peer.LightweightPeer; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.beans.PropertyVetoException; -import java.beans.VetoableChangeListener; -import java.beans.VetoableChangeSupport; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.EventListener; -import java.util.Hashtable; -import java.util.Locale; -import java.util.Set; - -import javax.accessibility.Accessible; -import javax.accessibility.AccessibleContext; -import javax.accessibility.AccessibleExtendedComponent; -import javax.accessibility.AccessibleKeyBinding; -import javax.accessibility.AccessibleRole; -import javax.accessibility.AccessibleState; -import javax.accessibility.AccessibleStateSet; -import javax.swing.border.Border; -import javax.swing.border.CompoundBorder; -import javax.swing.border.TitledBorder; -import javax.swing.event.AncestorEvent; -import javax.swing.event.AncestorListener; -import javax.swing.event.EventListenerList; -import javax.swing.plaf.ComponentUI; - -/** - * The base class of all Swing components. - * It contains generic methods to manage events, properties and sizes. Actual - * drawing of the component is channeled to a look-and-feel class that is - * implemented elsewhere. - * - * @author Ronald Veldema (rveldema&064;cs.vu.nl) - * @author Graydon Hoare (graydon&064;redhat.com) - */ -public abstract class JComponent extends Container implements Serializable -{ - private static final long serialVersionUID = -7908749299918704233L; - - /** - * The accessible context of this <code>JComponent</code>. - */ - protected AccessibleContext accessibleContext; - - /** - * Basic accessibility support for <code>JComponent</code> derived - * widgets. - */ - public abstract class AccessibleJComponent - extends AccessibleAWTContainer - implements AccessibleExtendedComponent - { - /** - * Receives notification if the focus on the JComponent changes and - * fires appropriate PropertyChangeEvents to listeners registered with - * the AccessibleJComponent. - */ - protected class AccessibleFocusHandler - implements FocusListener - { - /** - * Creates a new AccessibleFocusHandler. - */ - protected AccessibleFocusHandler() - { - // Nothing to do here. - } - - /** - * Receives notification when the JComponent gained focus and fires - * a PropertyChangeEvent to listeners registered on the - * AccessibleJComponent with a property name of - * {@link AccessibleContext#ACCESSIBLE_STATE_PROPERTY} and a new value - * of {@link AccessibleState#FOCUSED}. - */ - public void focusGained(FocusEvent event) - { - AccessibleJComponent.this.firePropertyChange - (AccessibleContext.ACCESSIBLE_STATE_PROPERTY, null, - AccessibleState.FOCUSED); - } - - /** - * Receives notification when the JComponent lost focus and fires - * a PropertyChangeEvent to listeners registered on the - * AccessibleJComponent with a property name of - * {@link AccessibleContext#ACCESSIBLE_STATE_PROPERTY} and an old value - * of {@link AccessibleState#FOCUSED}. - */ - public void focusLost(FocusEvent valevent) - { - AccessibleJComponent.this.firePropertyChange - (AccessibleContext.ACCESSIBLE_STATE_PROPERTY, - AccessibleState.FOCUSED, null); - } - } - - /** - * Receives notification if there are child components are added or removed - * from the JComponent and fires appropriate PropertyChangeEvents to - * interested listeners on the AccessibleJComponent. - */ - protected class AccessibleContainerHandler - implements ContainerListener - { - /** - * Creates a new AccessibleContainerHandler. - */ - protected AccessibleContainerHandler() - { - // Nothing to do here. - } - - /** - * Receives notification when a child component is added to the - * JComponent and fires a PropertyChangeEvent on listeners registered - * with the AccessibleJComponent with a property name of - * {@link AccessibleContext#ACCESSIBLE_CHILD_PROPERTY}. - * - * @param event the container event - */ - public void componentAdded(ContainerEvent event) - { - Component c = event.getChild(); - if (c != null && c instanceof Accessible) - { - AccessibleContext childCtx = c.getAccessibleContext(); - AccessibleJComponent.this.firePropertyChange - (AccessibleContext.ACCESSIBLE_CHILD_PROPERTY, null, childCtx); - } - } - - /** - * Receives notification when a child component is removed from the - * JComponent and fires a PropertyChangeEvent on listeners registered - * with the AccessibleJComponent with a property name of - * {@link AccessibleContext#ACCESSIBLE_CHILD_PROPERTY}. - * - * @param event the container event - */ - public void componentRemoved(ContainerEvent event) - { - Component c = event.getChild(); - if (c != null && c instanceof Accessible) - { - AccessibleContext childCtx = c.getAccessibleContext(); - AccessibleJComponent.this.firePropertyChange - (AccessibleContext.ACCESSIBLE_CHILD_PROPERTY, childCtx, null); - } - } - } - - private static final long serialVersionUID = -7047089700479897799L; - - /** - * Receives notification when a child component is added to the - * JComponent and fires a PropertyChangeEvent on listeners registered - * with the AccessibleJComponent. - * - * @specnote AccessibleAWTContainer has a protected field with the same - * name. Looks like a bug or nasty misdesign to me. - */ - protected ContainerListener accessibleContainerHandler; - - /** - * Receives notification if the focus on the JComponent changes and - * fires appropriate PropertyChangeEvents to listeners registered with - * the AccessibleJComponent. - * - * @specnote AccessibleAWTComponent has a protected field - * accessibleAWTFocusHandler. Looks like a bug or nasty misdesign - * to me. - */ - protected FocusListener accessibleFocusHandler; - - /** - * Creates a new AccessibleJComponent. - */ - protected AccessibleJComponent() - { - // Nothing to do here. - } - - /** - * Adds a property change listener to the list of registered listeners. - * - * This sets up the {@link #accessibleContainerHandler} and - * {@link #accessibleFocusHandler} fields and calls - * <code>super.addPropertyChangeListener(listener)</code>. - * - * @param listener the listener to add - */ - public void addPropertyChangeListener(PropertyChangeListener listener) - { - // Tests seem to indicate that this method also sets up the other two - // handlers. - if (accessibleContainerHandler == null) - { - accessibleContainerHandler = new AccessibleContainerHandler(); - addContainerListener(accessibleContainerHandler); - } - if (accessibleFocusHandler == null) - { - accessibleFocusHandler = new AccessibleFocusHandler(); - addFocusListener(accessibleFocusHandler); - } - super.addPropertyChangeListener(listener); - } - - /** - * Removes a property change listener from the list of registered listeners. - * - * This uninstalls the {@link #accessibleContainerHandler} and - * {@link #accessibleFocusHandler} fields and calls - * <code>super.removePropertyChangeListener(listener)</code>. - * - * @param listener the listener to remove - */ - public void removePropertyChangeListener(PropertyChangeListener listener) - { - // Tests seem to indicate that this method also resets the other two - // handlers. - if (accessibleContainerHandler != null) - { - removeContainerListener(accessibleContainerHandler); - accessibleContainerHandler = null; - } - if (accessibleFocusHandler != null) - { - removeFocusListener(accessibleFocusHandler); - accessibleFocusHandler = null; - } - super.removePropertyChangeListener(listener); - } - - /** - * Returns the number of accessible children of this object. - * - * @return the number of accessible children of this object - */ - public int getAccessibleChildrenCount() - { - // TODO: The functionality should be performed in the superclass. - // Find out why this is overridden. However, it is very well possible - // that this is left over from times when there was no such superclass - // method. - return super.getAccessibleChildrenCount(); - } - - /** - * Returns the accessible child component at index <code>i</code>. - * - * @param i the index of the accessible child to return - * - * @return the accessible child component at index <code>i</code> - */ - public Accessible getAccessibleChild(int i) - { - // TODO: The functionality should be performed in the superclass. - // Find out why this is overridden. However, it is very well possible - // that this is left over from times when there was no such superclass - // method. - return super.getAccessibleChild(i); - } - - /** - * Returns the accessible state set of this component. - * - * @return the accessible state set of this component - */ - public AccessibleStateSet getAccessibleStateSet() - { - // Note: While the java.awt.Component has an 'opaque' property, it - // seems that it is not added to the accessible state set there, even - // if this property is true. However, it is handled for JComponent, so - // we add it here. - AccessibleStateSet state = super.getAccessibleStateSet(); - if (isOpaque()) - state.add(AccessibleState.OPAQUE); - return state; - } - - /** - * Returns the localized name for this object. Generally this should - * almost never return {@link Component#getName()} since that is not - * a localized name. If the object is some kind of text component (like - * a menu item), then the value of the object may be returned. Also, if - * the object has a tooltip, the value of the tooltip may also be - * appropriate. - * - * @return the localized name for this object or <code>null</code> if this - * object has no name - */ - public String getAccessibleName() - { - String name = super.getAccessibleName(); - - // There are two fallbacks provided by the JComponent in the case the - // superclass returns null: - // - If the component is inside a titled border, then it inherits the - // name from the border title. - // - If the component is not inside a titled border but has a label - // (via JLabel.setLabelFor()), then it gets the name from the label's - // accessible context. - - if (name == null) - { - name = getTitledBorderText(); - } - - if (name == null) - { - Object l = getClientProperty(JLabel.LABEL_PROPERTY); - if (l instanceof Accessible) - { - AccessibleContext labelCtx = - ((Accessible) l).getAccessibleContext(); - name = labelCtx.getAccessibleName(); - } - } - - return name; - } - - /** - * Returns the localized description of this object. - * - * @return the localized description of this object or <code>null</code> - * if this object has no description - */ - public String getAccessibleDescription() - { - // There are two fallbacks provided by the JComponent in the case the - // superclass returns null: - // - If the component has a tooltip, then inherit the description from - // the tooltip. - // - If the component is not inside a titled border but has a label - // (via JLabel.setLabelFor()), then it gets the name from the label's - // accessible context. - String descr = super.getAccessibleDescription(); - - if (descr == null) - { - descr = getToolTipText(); - } - - if (descr == null) - { - Object l = getClientProperty(JLabel.LABEL_PROPERTY); - if (l instanceof Accessible) - { - AccessibleContext labelCtx = - ((Accessible) l).getAccessibleContext(); - descr = labelCtx.getAccessibleName(); - } - } - - return descr; - } - - /** - * Returns the accessible role of this component. - * - * @return the accessible role of this component - * - * @see AccessibleRole - */ - public AccessibleRole getAccessibleRole() - { - return AccessibleRole.SWING_COMPONENT; - } - - /** - * Recursivly searches a border hierarchy (starting at <code>border) for - * a titled border and returns the title if one is found, <code>null</code> - * otherwise. - * - * @param border the border to start search from - * - * @return the border title of a possibly found titled border - */ - protected String getBorderTitle(Border border) - { - String title = null; - if (border instanceof CompoundBorder) - { - CompoundBorder compound = (CompoundBorder) border; - Border inner = compound.getInsideBorder(); - title = getBorderTitle(inner); - if (title == null) - { - Border outer = compound.getOutsideBorder(); - title = getBorderTitle(outer); - } - } - else if (border instanceof TitledBorder) - { - TitledBorder titled = (TitledBorder) border; - title = titled.getTitle(); - } - return title; - } - - /** - * Returns the tooltip text for this accessible component. - * - * @return the tooltip text for this accessible component - */ - public String getToolTipText() - { - return JComponent.this.getToolTipText(); - } - - /** - * Returns the title of the border of this accessible component if - * this component has a titled border, otherwise returns <code>null</code>. - * - * @return the title of the border of this accessible component if - * this component has a titled border, otherwise returns - * <code>null</code> - */ - public String getTitledBorderText() - { - return getBorderTitle(getBorder()); - } - - /** - * Returns the keybindings associated with this accessible component or - * <code>null</code> if the component does not support key bindings. - * - * @return the keybindings associated with this accessible component - */ - public AccessibleKeyBinding getAccessibleKeyBinding() - { - // The reference implementation seems to always return null here, - // independent of the key bindings of the JComponent. So do we. - return null; - } - } - - /** - * A value between 0.0 and 1.0 indicating the preferred horizontal - * alignment of the component, relative to its siblings. The values - * {@link #LEFT_ALIGNMENT}, {@link #CENTER_ALIGNMENT}, and {@link - * #RIGHT_ALIGNMENT} can also be used, as synonyms for <code>0.0</code>, - * <code>0.5</code>, and <code>1.0</code>, respectively. Not all layout - * managers use this property. - * - * @see #getAlignmentX - * @see #setAlignmentX - * @see javax.swing.OverlayLayout - * @see javax.swing.BoxLayout - */ - float alignmentX = -1.0F; - - /** - * A value between 0.0 and 1.0 indicating the preferred vertical - * alignment of the component, relative to its siblings. The values - * {@link #TOP_ALIGNMENT}, {@link #CENTER_ALIGNMENT}, and {@link - * #BOTTOM_ALIGNMENT} can also be used, as synonyms for <code>0.0</code>, - * <code>0.5</code>, and <code>1.0</code>, respectively. Not all layout - * managers use this property. - * - * @see #getAlignmentY - * @see #setAlignmentY - * @see javax.swing.OverlayLayout - * @see javax.swing.BoxLayout - */ - float alignmentY = -1.0F; - - /** - * The border painted around this component. - * - * @see #paintBorder - */ - Border border; - - /** - * The popup menu for the component. - * - * @see #getComponentPopupMenu() - * @see #setComponentPopupMenu(JPopupMenu) - */ - JPopupMenu componentPopupMenu; - - /** - * A flag that controls whether the {@link #getComponentPopupMenu()} method - * looks to the component's parent when the <code>componentPopupMenu</code> - * field is <code>null</code>. - */ - boolean inheritsPopupMenu; - - /** - * <p>Whether to double buffer this component when painting. This flag - * should generally be <code>true</code>, to ensure good painting - * performance.</p> - * - * <p>All children of a double buffered component are painted into the - * double buffer automatically, so only the top widget in a window needs - * to be double buffered.</p> - * - * @see #setDoubleBuffered - * @see #isDoubleBuffered - * @see #paint - */ - boolean doubleBuffered = true; - - /** - * A set of flags indicating which debugging graphics facilities should - * be enabled on this component. The values should be a combination of - * {@link DebugGraphics#NONE_OPTION}, {@link DebugGraphics#LOG_OPTION}, - * {@link DebugGraphics#FLASH_OPTION}, or {@link - * DebugGraphics#BUFFERED_OPTION}. - * - * @see #setDebugGraphicsOptions - * @see #getDebugGraphicsOptions - * @see DebugGraphics - * @see #getComponentGraphics - */ - int debugGraphicsOptions; - - /** - * <p>This property controls two independent behaviors simultaneously.</p> - * - * <p>First, it controls whether to fill the background of this widget - * when painting its body. This affects calls to {@link - * JComponent#paintComponent}, which in turn calls {@link - * ComponentUI#update} on the component's {@link #ui} property. If the - * component is opaque during this call, the background will be filled - * before calling {@link ComponentUI#paint}. This happens merely as a - * convenience; you may fill the component's background yourself too, - * but there is no need to do so if you will be filling with the same - * color.</p> - * - * <p>Second, it the opaque property informs swing's repaint system - * whether it will be necessary to paint the components "underneath" this - * component, in Z-order. If the component is opaque, it is considered to - * completely occlude components "underneath" it, so they will not be - * repainted along with the opaque component.</p> - * - * <p>The default value for this property is <code>false</code>, but most - * components will want to set it to <code>true</code> when installing UI - * defaults in {@link ComponentUI#installUI}.</p> - * - * @see #setOpaque - * @see #isOpaque - * @see #paintComponent - */ - boolean opaque = false; - - /** - * The user interface delegate for this component. Event delivery and - * repainting of the component are usually delegated to this object. - * - * @see #setUI - * @see #getUIClassID - * @see #updateUI - */ - protected ComponentUI ui; - - /** - * A hint to the focus system that this component should or should not - * get focus. If this is <code>false</code>, swing will not try to - * request focus on this component; if <code>true</code>, swing might - * try to request focus, but the request might fail. Thus it is only - * a hint guiding swing's behavior. - * - * @see #requestFocus() - * @see #isRequestFocusEnabled - * @see #setRequestFocusEnabled - */ - boolean requestFocusEnabled; - - /** - * Flag indicating behavior of this component when the mouse is dragged - * outside the component and the mouse <em>stops moving</em>. If - * <code>true</code>, synthetic mouse events will be delivered on regular - * timed intervals, continuing off in the direction the mouse exited the - * component, until the mouse is released or re-enters the component. - * - * @see #setAutoscrolls - * @see #getAutoscrolls - */ - boolean autoscrolls = false; - - /** - * Indicates whether the current paint call is already double buffered or - * not. - */ - static boolean paintingDoubleBuffered = false; - - /** - * Indicates whether we are calling paintDoubleBuffered() from - * paintImmadiately (RepaintManager) or from paint() (AWT refresh). - */ - static boolean isRepainting = false; - - /** - * Listeners for events other than {@link PropertyChangeEvent} are - * handled by this listener list. PropertyChangeEvents are handled in - * {@link #changeSupport}. - */ - protected EventListenerList listenerList = new EventListenerList(); - - /** - * Handles VetoableChangeEvents. - */ - private VetoableChangeSupport vetoableChangeSupport; - - /** - * Storage for "client properties", which are key/value pairs associated - * with this component by a "client", such as a user application or a - * layout manager. This is lazily constructed when the component gets its - * first client property. - */ - private Hashtable clientProperties; - - private InputMap focusInputMap; - private InputMap ancestorInputMap; - private ComponentInputMap windowInputMap; - private ActionMap actionMap; - /** @since 1.3 */ - private boolean verifyInputWhenFocusTarget = true; - private InputVerifier inputVerifier; - - private TransferHandler transferHandler; - - /** - * Indicates if this component is currently painting a tile or not. - */ - private boolean paintingTile; - - /** - * A temporary buffer used for fast dragging of components. - */ - private Image dragBuffer; - - /** - * Indicates if the dragBuffer is already initialized. - */ - private boolean dragBufferInitialized; - - /** - * A cached Rectangle object to be reused. Be careful when you use that, - * so that it doesn't get modified in another context within the same - * method call chain. - */ - private static transient Rectangle rectCache; - - /** - * The default locale of the component. - * - * @see #getDefaultLocale - * @see #setDefaultLocale - */ - private static Locale defaultLocale; - - public static final String TOOL_TIP_TEXT_KEY = "ToolTipText"; - - /** - * Constant used to indicate that no condition has been assigned to a - * particular action. - * - * @see #registerKeyboardAction(ActionListener, KeyStroke, int) - */ - public static final int UNDEFINED_CONDITION = -1; - - /** - * Constant used to indicate that an action should be performed only when - * the component has focus. - * - * @see #registerKeyboardAction(ActionListener, KeyStroke, int) - */ - public static final int WHEN_FOCUSED = 0; - - /** - * Constant used to indicate that an action should be performed only when - * the component is an ancestor of the component which has focus. - * - * @see #registerKeyboardAction(ActionListener, KeyStroke, int) - */ - public static final int WHEN_ANCESTOR_OF_FOCUSED_COMPONENT = 1; - - /** - * Constant used to indicate that an action should be performed only when - * the component is in the window which has focus. - * - * @see #registerKeyboardAction(ActionListener, KeyStroke, int) - */ - public static final int WHEN_IN_FOCUSED_WINDOW = 2; - - - /** - * Used to optimize painting. This is set in paintImmediately2() to specify - * the exact component path to be painted by paintChildren. - */ - Component paintChild; - - /** - * Indicates if the opaque property has been set by a client program or by - * the UI. - * - * @see #setUIProperty(String, Object) - * @see LookAndFeel#installProperty(JComponent, String, Object) - */ - private boolean clientOpaqueSet = false; - - /** - * Indicates if the autoscrolls property has been set by a client program or - * by the UI. - * - * @see #setUIProperty(String, Object) - * @see LookAndFeel#installProperty(JComponent, String, Object) - */ - private boolean clientAutoscrollsSet = false; - - /** - * Creates a new <code>JComponent</code> instance. - */ - public JComponent() - { - super(); - setDropTarget(new DropTarget()); - setLocale(getDefaultLocale()); - debugGraphicsOptions = DebugGraphics.NONE_OPTION; - setRequestFocusEnabled(true); - } - - /** - * Helper to lazily construct and return the client properties table. - * - * @return The current client properties table - * - * @see #clientProperties - * @see #getClientProperty - * @see #putClientProperty - */ - private Hashtable getClientProperties() - { - if (clientProperties == null) - clientProperties = new Hashtable(); - return clientProperties; - } - - /** - * Get a client property associated with this component and a particular - * key. - * - * @param key The key with which to look up the client property - * - * @return A client property associated with this object and key - * - * @see #clientProperties - * @see #getClientProperties - * @see #putClientProperty - */ - public final Object getClientProperty(Object key) - { - return getClientProperties().get(key); - } - - /** - * Add a client property <code>value</code> to this component, associated - * with <code>key</code>. If there is an existing client property - * associated with <code>key</code>, it will be replaced. A - * {@link PropertyChangeEvent} is sent to registered listeners (with the - * name of the property being <code>key.toString()</code>). - * - * @param key The key of the client property association to add - * @param value The value of the client property association to add - * - * @see #clientProperties - * @see #getClientProperties - * @see #getClientProperty - */ - public final void putClientProperty(Object key, Object value) - { - Hashtable t = getClientProperties(); - Object old = t.get(key); - if (value != null) - t.put(key, value); - else - t.remove(key); - - // When both old and new value are null, no event is fired. This is - // different from what firePropertyChange() normally does, so we add this - // check here. - if (old != null || value != null) - firePropertyChange(key.toString(), old, value); - } - - /** - * Unregister an <code>AncestorListener</code>. - * - * @param listener The listener to unregister - * - * @see #addAncestorListener - */ - public void removeAncestorListener(AncestorListener listener) - { - listenerList.remove(AncestorListener.class, listener); - } - - /** - * Unregister a <code>VetoableChangeChangeListener</code>. - * - * @param listener The listener to unregister - * - * @see #addVetoableChangeListener - */ - public void removeVetoableChangeListener(VetoableChangeListener listener) - { - if (vetoableChangeSupport != null) - vetoableChangeSupport.removeVetoableChangeListener(listener); - } - - /** - * Register an <code>AncestorListener</code>. - * - * @param listener The listener to register - * - * @see #removeVetoableChangeListener - */ - public void addAncestorListener(AncestorListener listener) - { - listenerList.add(AncestorListener.class, listener); - } - - /** - * Register a <code>VetoableChangeListener</code>.... [truncated message content] |