J2SE 5.0 における Swing API の変更点について、次のセクションで詳しく説明します。
5.0 の Swing でもっとも大きな変更点です。Java Look & Feel を使用した場合、使用しているアプリケーションは、5.0 で自動的に Ocean と呼ばれる新しい見た目になります。Ocean はウィジェットの優先サイズを変更しないように、互換性を考慮して設計されました。見た目とわずかな使い心地だけが変更されています。システムプロパティー swing.metalTheme=steel
を設定すると、従来の見た目に戻すことができます。
Ocean は、現在 private であるカスタム MetalTheme として実装されています。この手法の利点は、ユーザーがカスタム MetalTheme
を作成した場合に、Ocean による影響をまったく受けないという点です。つまり、作成したアプリケーションは 1.4 の場合と同様になります。
AbstractButton サブクラスの無効なアイコンが UI から生成されるようになりました。これにより、getDisabledIcon の仕様が次のように改訂されました。
/** * Returns the icon used by the button when it's disabled. * If no disabled icon has been set this will forward the call to * the ui to construct an appropriate disabled Icon. * <p> * Some types of look and feel might not render the disabled Icon, in which * case they will ignore this. * * @return the <code>disabledIcon</code> property * @see #getPressedIcon * @see #setDisabledIcon * @see javax.swing.plaf.ButtonUI#getDisabledIcon */ public Icon getDisabledIcon();
また、メソッド getDisabledIcon
が ButtonUI に追加されました。
/** * Returns the icon to display when the developer has not specified * a disabled icon. * <p> * Some look and feels might not render the disabled Icon, in which * case they will ignore this. * * @param button AbstractButton requesting the Icon * @return Disabled icon, or null. * @see javax.swing.AbstractButton#setIcon * @see javax.swing.AbstractButton#setDisabledIcon * @throws NullPointerException if <code>button</code> is null * @since 1.5 */ public Icon getDisabledIcon(AbstractButton button);
JButton の無効なアイコンの見た目をカスタマイズするために、MetalButtonUI は getDisabledIcon
をオーバーライドします。
/** * Returns the icon to display when the button is disabled. * * @param button AbstractButton requesting the Icon * @return Disabled icon, or null. * @see javax.swing.AbstractButton#setIcon * @see javax.swing.AbstractButton#setDisabledIcon * @throws NullPointerException if <code>button</code> is null * @since 1.5 */ public Icon getDisabledIcon(AbstractButton button);
JComboBox の見た目をカスタマイズするために、MetalCombBoxUI は次のメソッドをオーバーライドします。
/** * If necessary paints the currently selected item. * * @param g Graphics to paint to * @param bounds Region to paint current value to * @param hasFocus whether or not the JComboBox has focus * @throws NullPointerException if any of the arguments are null. * @since 1.5 */ public void paintCurrentValue(Graphics g, Rectangle bounds, boolean hasFocus); /** * If necessary paints the background of the currently selected item. * * @param g Graphics to paint to * @param bounds Region to paint background to * @param hasFocus whether or not the JComboBox has focus * @throws NullPointerException if any of the arguments are null. * @since 1.5 */ public void paintCurrentValueBackground(Graphics g, Rectangle bounds, boolean hasFocus);
JButton の見た目をカスタマイズするために、MetalButtonUI は次のメソッドをオーバーライドします。
/** * If necessary paints the background of the component, then * invokes <code>paint</code>. * * @param g Graphics to paint to * @param c JComponent painting on * @throws NullPointerException if <code>g</code> or <code>c</code> is * null * @see javax.swing.plaf.ComponentUI#update * @see javax.swing.plaf.ComponentUI#paint * @since 1.5 */ public void update(Graphics g, JComponent c);
JMenuBar の見た目をカスタマイズするために、メタルに MetalMenuBarUI が用意されます。
JToolBar の見た目をカスタマイズするために、MetalToolBarUI は update
をオーバーライドします。
/** * If necessary paints the background of the component, then invokes * <code>paint</code>. * * @param g Graphics to paint to * @param c JComponent painting on * @throws NullPointerException if <code>g</code> or <code>c</code> is * null * @see javax.swing.plaf.ComponentUI#update * @see javax.swing.plaf.ComponentUI#paint * @since 1.5 */ public void update(Graphics g, JComponent c);
JToggleButton の見た目をカスタマイズするために、MetalToggleButtonUI は次のメソッドをオーバーライドします。
/** * If necessary paints the background of the component, then invokes * <code>paint</code>. * * @param g Graphics to paint to * @param c JComponent painting on * @throws NullPointerException if <code>g</code> or <code>c</code> is * null * @see javax.swing.plaf.ComponentUI#update * @see javax.swing.plaf.ComponentUI#paint * @since 1.5 */ public void update(Graphics g, JComponent c); /** * Paints the appropriate icon of the button <code>b</code> in the * space <code>iconRect</code>. * * @param g Graphics to paint to * @param b Button to render for * @param iconRect space to render in * @throws NullPointerException if any of the arguments are null. * @since 1.5 */ protected void paintIcon(Graphics g, AbstractButton b, Rectangle iconRect); /** * Returns the icon to display when the button is disabled. * * @param button AbstractButton requesting the Icon * @return Disabled icon, or null. * @see javax.swing.AbstractButton#setIcon * @see javax.swing.AbstractButton#setDisabledIcon * @throws NullPointerException if <code>button</code> is null * @since 1.5 */ public Icon getDisabledIcon(AbstractButton button);
Swing における初期の設計目標には、コードを変更せずに、アプリケーションで複数の Look & Feel をサポートできるようにすることがありました。この機能により、開発者はアプリケーションをさまざまな Look & Feel でシームレスに実行できます。Alloy Look and Feel を始めとするカスタム Look & Feel がいくつも用意されていますが、新しい Look & Feel を作成するにはプログラムの作成と Swing のプラグイン可能な Look & Feel に対する広範な知識が必要となります。そのためほとんどの場合、この機能の対象は経験豊富な開発者にかぎられていました。5.0 では、Synth と呼ばれるスキン設定可能な Look & Feel が Swing に追加されました。Synth はコードを書き換えることなく完全なカスタマイズが可能で、プログラマでなくても新しい Look & Feel を作成できます。
Synth は javax.swing.plaf.synth パッケージに含まれています。パッケージレベルの javadoc には、Synth の概要が記述されています。Synth はファイルの形式でカスタマイズできます。Synth で javax.swing.plaf.basic を拡張できるようにするために、次の変更が加えられました。
次のメソッドは不必要であるため (実装がスーパークラスと同一である)、削除されました。BasicOptionPaneUI の getMinimumSize、BasicOptionPaneUI の getMaximumSize、BasicTabbedPaneUI の getPreferredSize、BasicMenuBarUI の getPreferredSize、BasicPopupMenuUI の getMinimumSize、BasicPopupMenuUI の getPreferredSize、BasicPopupMenuUI の getMaximumSize、BasicScrollPaneUI の getPreferredSize、BasicScrollPaneUI の getMinimumSize、BasicListUI の getMinimumSize、BasicListUI の getMaximumSize、BasicScrollBarUI の getMinimumSize、BasicToolBarSeparatorUI の getMinimumSize、BasicToolBarSeparatorUI の getMaximumSize、BasicToolBarUI の getMinimumSize、BasicToolBarUI の getPreferredSize、BasicToolBarUI の getMaximumSize。
JComponent サブクラスの多くには、プリミティブプロパティーがあります。UI はこれらのプロパティーの値を設定する必要がありますが、そのプロパティーを開発者が設定したかどうかを判別する方法がないために、開発者が指定した値をリセットしてしまうこともあります。開発者が値を指定しなかった場合にだけ UI で値を設定できるようにするために、すべてのプリミティブ設定メソッドを LookAndFeel 内のメソッド経由にします。
/** * Convenience method for installing a property with the specified name * and value on a component if that property has not already been set * by the client program. This method is intended to be used by * UI delegate instances that need to specify a default value for a * property of primitive type (boolean, int, ..), but do not wish * to override a value set by the client. Since primitive property * values cannot be wrapped with the UIResource marker, this method * uses private state to determine whether the property has been set * by the client. * @throws IllegalArgumentException if the specified property is not * one which can be set using this method * @throws ClassCastException May be thrown if the propertyValue is not * of the expected type. * @throws NullPointerException May be thrown if the JComponent is null, * or the propertyValue is null. * @param c the target component for installing the property * @param propertyName String containing the name of the property to be set * @param propertyValue Object containing the value of the property * @since 1.5 */ public static void installProperty(JComponent c, String propertyName, Object propertyValue)
BasicTabbedPaneUI のサブクラスで独自のボタンを作成できるようにするために、次のメソッドが追加されました。
/** * Creates and returns a JButton that will provide the user * with a way to scroll the tabs in a particular direction. The * returned JButton must be instance of UIResource. * * @param direction One of the SwingConstants constants: * SOUTH, NORTH, EAST or WEST * @return Widget for user to * @see javax.swing.JTabbedPane#setTabPlacement * @see javax.swing.SwingConstants * @throws IllegalArgumentException if direction is not one of * NORTH, SOUTH, EAST or WEST * @since 1.5 */ protected JButton createScrollButton(int direction);
BasicTabbedPaneUI のサブクラスでフォーカスのあるタブを判別できるようにするために、次が追加されました。
/** * Returns the index of the tab that has focus. * * @return index of tab that has focus * @since 1.5 */ protected int getFocusIndex();
BasicTabbedPaneUI のサブクラスでロールオーバー効果を提供できるようにするために、次が追加されました。
/** * Sets the tab the mouse is currently over toindex
. *index
will be -1 if the mouse is no longer over any * tab. No checking is done to ensure the passed in index identifies a * valid tab. * * @param index Index of the tab the mouse is over. * @since 1.5 */ protected void setRolloverTab(int index); /** * Returns the tab the mouse is currently over, or -1 if the mouse is no * longer over any tab. * * @param index Index of the tab the mouse is over. * @since 1.5 */ protected int getRolloverTab();
次のフィールドが BasicColorChooserUI に追加されました。
/** * JColorChooser this BasicColorChooserUI is installed on. * * @since 1.5 */ protected JColorChooser chooser;
BasicSpinnerUI のサブクラスで独自のキーボードアクションを導入できるようにするために、次のメソッドが追加されました。
/** * Installs the keyboard Actions onto the JSpinner. * * @since 1.5 */ protected void installKeyboardActions();
BasicSpinnerUI のサブクラスで独自のスピンボタンを提供できるようにするために、次のメソッドが追加されました。
/** * Installs the necessary listeners on the next button,c
, * to update theJSpinner
in response to a user gesture. * * @param c Component to install the listeners on * @throws NullPointerException ifc
is null. * @see #createNextButton * @since 1.5 */ protected void installNextButtonListeners(Component c); /** * Installs the necessary listeners on the previous button,c
, * to update theJSpinner
in response to a user gesture. * * @param c Component to install the listeners on. * @throws NullPointerException ifc
is null. * @see #createPreviousButton * @since 1.5 */ protected void installPreviousButtonListeners(Component c);
BasicScrollBarUI のサブクラスでロールオーバーフィードバックを提供できるようにするために、次のメソッドが追加されました。
/** * Sets whether or not the mouse is currently over the thumb. * * @param active True indicates the thumb is currently active. * @since 1.5 */ protected void setThumbRollover(boolean active); /** * Returns true if the mouse is currently over the thumb. * * @return true if the thumb is currently active * @since 1.5 */ public boolean isThumbRollover(); /** * Indicates whether the user can absolutely position the thumb with * a mouse gesture (usually the middle mouse button). * * @return true if a mouse gesture can absolutely position the thumb * @since 1.5 */ public boolean getSupportsAbsolutePositioning();
クラスのロードを短縮するために、次が BasicComboPopup に追加されました。
/** * Gets the AccessibleContext associated with this BasicComboPopup. * The AccessibleContext will have its parent set to the ComboBox. * * @return an AccessibleContext for the BasicComboPopup * @since 1.5 */ public AccessibleContext getAccessibleContext();
BasicSplitPaneDivider のサブクラスでマウスオーバーフィードバックを提供できるようにするために、次が追加されました。
/** * Sets whether or not the mouse is currently over the divider. * * @param mouseOver whether or not the mouse is currently over the divider * @since 1.5 */ protected void setMouseOver(boolean mouseOver); /** * Returns whether or not the mouse is currently over the divider * * @param Returns whether or not the mouse is currently over the divider */ public boolean isMouseOver();
BasicTreeUI のサブクラスで特定の行の位置を変更できるようにするために、次が追加されました。
/** * Returns the location, along the x-axis, to render a particular row * at. The return value does not include any Insets specified on the JTree. * This does not check for the validity of the row or depth, it is assumed * to be correct and will not throw an Exception if the row or depth * doesn't match that of the tree. * * @param row Row to return x location for * @param depth Depth of the row * @return amount to indent the given row. * @since 1.5 */ protected int getRowX(int row, int depth);
BasicProgressBarUI のサブクラスで進捗バーのサイズを変更できるようにするために、次が追加されました。
/** * Used to hold the location and size of the bouncing box (returned * by getBox) to be painted. * * @since 1.5 */ protected Rectangle boxRect; /** * Returns the length * of the "bouncing box" to be painted. * This method is invoked by the * default implementation of <code>paintIndeterminate</code> * to get the width (if the progress bar is horizontal) * or height (if vertical) of the box. * For example: * <blockquote> * <pre> *boxRect.width = getBoxLength(componentInnards.width, * componentInnards.height); * </pre> * </blockquote> * * @param availableLength the amount of space available * for the bouncing box to move in; * for a horizontal progress bar, * for example, * this should be * the inside width of the progress bar * (the component width minus borders) * @param otherDimension for a horizontal progress bar, this should be * the inside height of the progress bar; this * value might be used to constrain or determine * the return value * * @return the size of the box dimension being determined; * must be no larger than <code>availableLength</code> * * @see javax.swing.SwingUtilities#calculateInnerArea * @since 1.5 */ protected int getBoxLength(int availableLength, int otherDimension);
BasicSliderUI のサブクラスでスライダーの状態に応じてペイントを特殊化できるようにするために、次が追加されました。
/** * Returns true if the user is dragging the slider. * * @return true if the user is dragging the slider * @since 1.5 */ protected boolean isDragging();
BasicToolBarUI のサブクラスでドラッグに使用されるウィンドウがペイントされる方法を特殊化できるようにするために、次が追加されました。
/**
* Paints the contents of the window used for dragging.
*
* @param g Graphics to paint to.
* @throws NullPointerException is g
is null
* @since 1.5
*/
protected void paintDragWindow(Graphics g);
BasicDesktopIconUI のサブクラスで iconPane へのハンドルを取得できるようにするために、次が追加されました。
/** * The title pane component used in the desktop icon. * * @since 1.5 */ protected JComponent iconPane;
JPopupMenu でポップアップメニューを作成できます。5.0 より前では、JPopupMenu
を使用する開発者は、JPopupMenu
を表示するために、必要なリスナーをインストールし、適切なキーの割り当てを登録する必要がありました。5.0 では、適切なリスナーの登録とキーの割り当ての登録を引き受けるメカニズムが追加されました。この結果、次のメソッドが JComponent に追加されました。
/** * Sets whether or not <code>getComponentPopupMenu</code> should delegate * to the parent if this component does not have a <code>JPopupMenu</code> * assigned to it. * <p> * The default value for this is false, but some <code>JComponent</code> * subclasses that are implemented as a number of <code>JComponent</code>s * may set this to true. * <p> * This is a bound property. * * @param value whether or not the JPopupMenu is inherited * @see #setComponentPopupMenu * @beaninfo * bound: true * description: Whether or not the JPopupMenu is inherited * @since 1.5 */ public void setInheritsPopupMenu(boolean value); /** * Returns true if the JPopupMenu should be inherited from the parent. * * @see #setComponentPopupMenu * @since 1.5 */ public boolean getInheritsPopupMenu(); /** * Sets the <code>JPopupMenu</code> for this <code>JComponent</code>. * The UI is responsible for registering bindings and adding the necessary * listeners such that the <code>JPopupMenu</code> will be shown at * the appropriate time. When the <code>JPopupMenu</code> is shown * depends upon the look and feel: some may show it on a mouse event, * some may enable a key binding. * <p> * If <code>popup</code> is null, and <code>getInheritsPopupMenu</code> * returns true, then <code>getComponentPopupMenu</code> will be delegated * to the parent. This provides for a way to make all child components * inherit the popupmenu of the parent. * <p> * This is a bound property. * * @param popup - the popup that will be assigned to this component * may be null * @see #getComponentPopupMenu * @beaninfo * bound: true * preferred: true * description: Popup to show * @since 1.5 */ public void setComponentPopupMenu(JPopupMenu popup); /** * Returns <code>JPopupMenu</code> that assigned for this component. * If this component does not have a <code>JPopupMenu</code> assigned * to it and <code>getInheritsPopupMenu</code> is true, this * will return <code>getParent().getComponentPopupMenu()</code> (assuming * the parent is valid.) * * @return <code>JPopupMenu</code> assigned for this component * or <code>null</code> if no popup assigned * @see #setComponentPopupMenu * @since 1.5 */ public JPopupMenu getComponentPopupMenu();
次が BasicLookAndFeel に追加されました。
/** * UIManager.setLookAndFeel calls this method before the first call * (and typically the only call) to getDefaults(). * * @since 1.5 */ public void initialize() { /** * UIManager.setLookAndFeel calls this method just * before we're replaced by a new default look and feel. * * @since 1.5 */ public void uninitialize() {
上記概要のとおりです。次が JTable
に追加されました。
/** * Printing modes, used in printing <code>JTable</code>s. * * @see #print(JTable.PrintMode, MessageFormat, MessageFormat, * boolean, PrintRequestAttributeSet, boolean) * @see #getPrintable * @since 1.5 */ public enum PrintMode { /** * Printing mode that prints the table at its current size, * spreading both columns and rows across multiple pages if necessary. */ NORMAL, /** * Printing mode that scales the output smaller, if necessary, * to fit the table's entire width (and thereby all columns) on each page; * Rows are spread across multiple pages as necessary. */ FIT_WIDTH } /** * A convenience method that displays a printing dialog, and then prints * this <code>JTable</code> in mode <code>PrintMode.FIT_WIDTH</code>, * with no header or footer text. A modal progress dialog, with an abort * option, will be shown for the duration of printing. * <p> * Note: In headless mode, no dialogs will be shown. * * @return true, unless printing is cancelled by the user * @throws PrinterException if an error in the print system causes the job * to be aborted * @see #print(JTable.PrintMode, MessageFormat, MessageFormat, * boolean, PrintRequestAttributeSet, boolean) * @see #getPrintable * * @since 1.5 */ public boolean print() throws PrinterException; /** * A convenience method that displays a printing dialog, and then prints * this <code>JTable</code> in the given printing mode, * with no header or footer text. A modal progress dialog, with an abort * option, will be shown for the duration of printing. * <p> * Note: In headless mode, no dialogs will be shown. * * @param printMode the printing mode that the printable should use * @return true, unless printing is cancelled by the user * @throws PrinterException if an error in the print system causes the job * to be aborted * @see #print(JTable.PrintMode, MessageFormat, MessageFormat, * boolean, PrintRequestAttributeSet, boolean) * @see #getPrintable * * @since 1.5 */ public boolean print(PrintMode printMode) throws PrinterException; /** * A convenience method that displays a printing dialog, and then prints * this <code>JTable</code> in the given printing mode, * with the specified header and footer text. A modal progress dialog, * with an abort option, will be shown for the duration of printing. * <p> * Note: In headless mode, no dialogs will be shown. * * @param printMode the printing mode that the printable should use * @param headerFormat a <code>MessageFormat</code> specifying the text * to be used in printing a header, * or null for none * @param footerFormat a <code>MessageFormat</code> specifying the text * to be used in printing a footer, * or null for none * @return true, unless printing is cancelled by the user * @throws PrinterException if an error in the print system causes the job * to be aborted * @see #print(JTable.PrintMode, MessageFormat, MessageFormat, * boolean, PrintRequestAttributeSet, boolean) * @see #getPrintable * * @since 1.5 */ public boolean print(PrintMode printMode, MessageFormat headerFormat, MessageFormat footerFormat) throws PrinterException; /** * Print this <code>JTable</code>. Takes steps that the majority of * developers would take in order to print a <code>JTable</code>. * In short, it prepares the table, calls <code>getPrintable</code> to * fetch an appropriate <code>Printable</code>, and then sends it to the * printer. * <p> * A <code>boolean</code> parameter allows you to specify whether or not * a printing dialog is displayed to the user. When it is, the user may * use the dialog to change printing attributes or even cancel the print. * Another parameter allows for printing attributes to be specified * directly. This can be used either to provide the initial values for the * print dialog, or to supply any needed attributes when the dialog is not * shown. * <p> * A second <code>boolean</code> parameter allows you to specify whether * or not to perform printing in an interactive mode. If <code>true</code>, * a modal progress dialog, with an abort option, is displayed for the * duration of printing . This dialog also prevents any user action which * may affect the table. However, it can not prevent the table from being * modified by code (for example, another thread that posts updates using * <code>SwingUtilities.invokeLater</code>). It is therefore the * responsibility of the developer to ensure that no other code modifies * the table in any way during printing (invalid modifications include * changes in: size, renderers, or underlying data). Printing behavior is * undefined when the table is changed during printing. * <p> * If <code>false</code> is specified for this parameter, no dialog will * be displayed and printing will begin immediately on the event-dispatch * thread. This blocks any other events, including repaints, from being * processed until printing is complete. Although this effectively prevents * the table from being changed, it doesn't provide a good user experience. * For this reason, specifying <code>false</code> is only recommended when * printing from an application with no visible GUI. * <p> * Note: Attempting to show the printing dialog or run interactively, while * in headless mode, will result in a <code>HeadlessException</code>. * <p> * Before fetching the printable, this method prepares the table in order * to get the most desirable printed result. If the table is currently * in an editing mode, it terminates the editing as gracefully as * possible. It also ensures that the table's current selection and * focused cell are not indicated in the printed output. This is handled on * the view level, and only for the duration of the printing, thus no * notification needs to be sent to the selection models. * <p> * See {@link #getPrintable} for further description on how the * table is printed. * * @param printMode the printing mode that the printable should use * @param headerFormat a <code>MessageFormat</code> specifying the text * to be used in printing a header, * or null for none * @param footerFormat a <code>MessageFormat</code> specifying the text * to be used in printing a footer, * or null for none * @param showPrintDialog whether or not to display a print dialog * @param attr a <code>PrintRequestAttributeSet</code> * specifying any printing attributes, * or null for none * @param interactive whether or not to print in an interactive mode * @return true, unless printing is cancelled by the user * @throws PrinterException if an error in the print system causes the job * to be aborted * @throws HeadlessException if the method is asked to show a printing * dialog or run interactively, and * <code>GraphicsEnvironment.isHeadless</code> * returns true * @see #getPrintable * @see java.awt.GraphicsEnvironment#isHeadless * * @since 1.5 */ public boolean print(PrintMode printMode, MessageFormat headerFormat, MessageFormat footerFormat, boolean showPrintDialog, PrintRequestAttributeSet attr, boolean interactive) throws PrinterException, HeadlessException; /** * Return a <code>Printable</code> for use in printing this JTable. * <p> * The <code>Printable</code> can be requested in one of two printing modes. * In both modes, it spreads table rows naturally in sequence across * multiple pages, fitting as many rows as possible per page. * <code>PrintMode.NORMAL</code> specifies that the table be * printed at its current size. In this mode, there may be a need to spread * columns across pages in a similar manner to that of the rows. When the * need arises, columns are distributed in an order consistent with the * table's <code>ComponentOrientation</code>. * <code>PrintMode.FIT_WIDTH</code> specifies that the output be * scaled smaller, if necessary, to fit the table's entire width * (and thereby all columns) on each page. Width and height are scaled * equally, maintaining the aspect ratio of the output. * <p> * The <code>Printable</code> heads the portion of table on each page * with the appropriate section from the table's <code>JTableHeader</code>, * if it has one. * <p> * Header and footer text can be added to the output by providing * <code>MessageFormat</code> arguments. The printing code requests * Strings from the formats, providing a single item which may be included * in the formatted string: an <code>Integer</code> representing the current * page number. * <p> * You are encouraged to read the documentation for * <code>MessageFormat</code> as some characters, such as single-quote, * are special and need to be escaped. * <p> * Here's an example of creating a <code>MessageFormat</code> that can be * used to print "Duke's Table: Page - " and the current page number: * <p> * <pre> * // notice the escaping of the single quote * // notice how the page number is included with "{0}" * MessageFormat format = new MessageFormat("Duke''s Table: Page - {0}"); * </pre> * <p> * The <code>Printable</code> constrains what it draws to the printable * area of each page that it prints. Under certain circumstances, it may * find it impossible to fit all of a page's content into that area. In * these cases the output may be clipped, but the implementation * makes an effort to do something reasonable. Here are a few situations * where this is known to occur, and how they may be handled by this * particular implementation: * <ul> * <li>In any mode, when the header or footer text is too wide to fit * completely in the printable area -- print as much of the text as * possible starting from the beginning, as determined by the table's * <code>ComponentOrientation</code>. * <li>In any mode, when a row is too tall to fit in the * printable area -- print the upper-most portion of the row * and paint no lower border on the table. * <li>In <code>PrintMode.NORMAL</code> when a column * is too wide to fit in the printable area -- print the center * portion of the column and leave the left and right borders * off the table. * </ul> * <p> * It is entirely valid for this <code>Printable</code> to be wrapped * inside another in order to create complex reports and documents. You may * even request that different pages be rendered into different sized * printable areas. The implementation must be prepared to handle this * (possibly by doing its layout calculations on the fly). However, * providing different heights to each page will likely not work well * with <code>PrintMode.NORMAL</code> when it has to spread columns * across pages. * <p> * It is important to note that this <code>Printable</code> prints the * table at its current visual state, using the table's existing renderers. * <i>Before</i> calling this method, you may wish to <i>first</i> modify * the state of the table (such as to change the renderers, cancel editing, * or hide the selection). * <p> * You must not, however, modify the table in any way <i>after</i> * this <code>Printable</code> is fetched (invalid modifications include * changes in: size, renderers, or underlying data). The behavior of the * returned <code>Printable</code> is undefined once the table has been * changed. * <p> * Here's a simple example that calls this method to fetch a * <code>Printable</code>, shows a cross-platform print dialog, and then * prints the <code>Printable</code> unless the user cancels the dialog: * <p> * <pre> * // prepare the table for printing here first (for example, hide selection) * * // wrap in a try/finally so table can be restored even if something fails * try { * // fetch the printable * Printable printable = table.getPrintable(JTable.PrintMode.FIT_WIDTH, * new MessageFormat("My Table"), * new MessageFormat("Page - {0}")); * * // fetch a PrinterJob * PrinterJob job = PrinterJob.getPrinterJob(); * * // set the Printable on the PrinterJob * job.setPrintable(printable); * * // create an attribute set to store attributes from the print dialog * PrintRequestAttributeSet attr = new HashPrintRequestAttributeSet(); * * // display a print dialog and record whether or not the user cancels it * boolean printAccepted = job.printDialog(attr); * * // if the user didn't cancel the dialog * if (printAccepted) { * // do the printing (may need to handle PrinterException) * job.print(attr); * } * } finally { * // restore the original table state here (for example, restore selection) * } * </pre> * * @param printMode the printing mode that the printable should use * @param headerFormat a <code>MessageFormat</code> specifying the text to * be used in printing a header, or null for none * @param footerFormat a <code>MessageFormat</code> specifying the text to * be used in printing a footer, or null for none * @return a <code>Printable</code> for printing this JTable * @see Printable * @see PrinterJob * * @since 1.5 */ public Printable getPrintable(PrintMode printMode, MessageFormat headerFormat, MessageFormat footerFormat);
Swing のテキストコンポーネントメソッドの一部、特にテキストコンポーネントの内容を変更するメソッドは、スレッドに対して安全です。5.0 より前では、イベントのディスパッチスレッドで変更が起きた場合にだけキャレットの位置が更新されました。状況によっては、変更の起きたスレッドに関係なく、位置の更新が必要です。そのため、updatePolicy
プロパティーが DefaultCaret に追加されました。このプロパティーを使用すると、開発者は内容が変更された場合に位置がいつ変更されるようにするかを指定できます。下位互換性のために、ポリシーは、イベントディスパッチスレッドで変更が起きた場合にだけ位置を変更する、というままです。
結果、次のフィールドとメソッドが DefaultCaret に追加されました。
/** * Indicates that the caret position is to be updated only when * document changes are performed on the Event Dispatching Thread. * @see #setUpdatePolicy * @see #getUpdatePolicy * @since 1.5 */ public static final int UPDATE_WHEN_ON_EDT = 0; /** * Indicates that the caret should remain at the same * absolute position in the document regardless of any document * updates, except when the document length becomes less than * the current caret position due to removal. In that case the caret * position is adjusted to the end of the document. * * @see #setUpdatePolicy * @see #getUpdatePolicy * @since 1.5 */ public static final int NEVER_UPDATE = 1; /** * Indicates that the caret position is to be <b>always</b> * updated accordingly to the document changes regardless whether * the document updates are performed on the Event Dispatching Thread * or not. * * @see #setUpdatePolicy * @see #getUpdatePolicy * @since 1.5 */ public static final int ALWAYS_UPDATE = 2; /** * Sets the caret movement policy on the document updates. Normally * the caret updates its absolute position within the document on * insertions occurred before or at the caret position and * on removals before the caret position. 'Absolute position' * means here the position relative to the start of the document. * For example if * a character is typed within editable text component it is inserted * at the caret position and the caret moves to the next absolute * position within the document due to insertion and if * <code>BACKSPACE</code> is typed then caret decreases its absolute * position due to removal of a character before it. Sometimes * it may be useful to turn off the caret position updates so that * the caret stays at the same absolute position within the * document position regardless of any document updates. * <p> * The following update policies are allowed: * <ul> * <li><code>NEVER_UPDATE</code>: the caret stays at the same * absolute position in the document regardless of any document * updates, except when document length becomes less than * the current caret position due to removal. In that case caret * position is adjusted to the end of the document. * The caret doesn't try to keep itself visible by scrolling * the associated view when using this policy. </li> * <li><code>ALWAYS_UPDATE</code>: the caret always tracks document * changes. For regular changes it increases its position * if an insertion occurs before or at its current position, * and decreases position if a removal occurs before * its current position. For undo/redo updates it is always * moved to the position where update occurred. The caret * also tries to keep itself visible by calling * <code>adjustVisibility</code> method.</li> * <li><code>UPDATE_WHEN_ON_EDT</code>: acts like <code>ALWAYS_UPDATE</code> * if the document updates are performed on the Event Dispatching Thread * and like <code>NEVER_UPDATE</code> if updates are performed on * other thread. </li> * </ul> <p> * The default property value is <code>UPDATE_WHEN_ON_EDT</code>. * * @param policy one of the following values : <code>UPDATE_WHEN_ON_EDT</code>, * <code>NEVER_UPDATE</code>, <code>ALWAYS_UPDATE</code> * @throws IllegalArgumentException if invalid value is passed * * @see #getUpdatePolicy * @see #adjustVisibility * @see #UPDATE_WHEN_ON_EDT * @see #NEVER_UPDATE * @see #ALWAYS_UPDATE * * @since 1.5 */ public void setUpdatePolicy(int policy) /** * Gets the caret movement policy on document updates. * * @return one of the following values : <code>UPDATE_WHEN_ON_EDT</code>, * <code>NEVER_UPDATE</code>, <code>ALWAYS_UPDATE</code> * * @see #getUpdatePolicy * @see #UPDATE_WHEN_ON_EDT * @see #NEVER_UPDATE * @see #ALWAYS_UPDATE * * @since 1.5 */ public int getUpdatePolicy()
JEditorPane
は、HTML テキストの表示に使用できます。ユーザーがリンクをクリックすると、何が起こるかを開発者がカスタマイズできるイベントが生成されます。現時点では、HTML ページにフォームが含まれていてユーザーが送信をトリガーするとポストが発生します。この場合、開発者は動作を変更できません。開発者がこの動作をカスタマイズできるようにするために、次のメソッドが HTMLEditorKit に追加されました。
/** * Indicates whether an html form submission is processed automatically * or only <code>FormSubmitEvent</code> is fired. * * @return true if html form submission is processed automatically, * false otherwise. * * @see #setAutoFormSubmission * @since 1.5 */ public boolean isAutoFormSubmission(); /** * Specifies if an html form submission is processed * automatically or only <code>FormSubmitEvent</code> is fired. * By default it the property is set to true. * * @see #isAutoFormSubmission * @see FormSubmitEvent * @since 1.5 */ public void setAutoFormSubmission(boolean isAuto);
ここで重要な部分は、クラス FormSubmitEvent
を public にしたことです。これについての詳細は、4954126 を参照してください。
現在のところ、キャレットがアクティブで点滅していることを判別する方法はありません。isVisible
メソッドはこの目的のためにありますが、実装では、このメソッドが呼び出された時点でキャレットがペイントされているかどうかを返します。つまり、キャレットが点滅していると、キャレットの点滅に合わせて isVisible
は true と false の間で変化します。下位互換性を維持するために isVisible
メソッドの解釈は変更しないまま、isActive
プロパティーを追加しました。このメソッドではキャレットがアクティブであるかどうかを調べますが、呼び出されたときに可視状態であるかどうかは関係ありません。
次のメソッドが DefaultCaret に追加されました。
/** * Determines if the caret is currently active. * <p> * This method returns whether or not the <code>Caret</code> * is currently in a blinking state. It does not provide * information as to whether it is currently blinked on or off. * To determine if the caret is currently painted use the * <code>isVisible</code> method. * * @return <code>true</code> if active else <code>false</code> * @see #isVisible * * @since 1.5 */ public boolean isActive() * Sets the caret visibility, and repaints the caret. * It is important to understand the relationship between this method, * <code>isVisible</code> and <code>isActive</code>. * Calling this method with a value of <code>true</code> activates the * caret blinking. Setting it to <code>false</code> turns it completely off. * To determine whether the blinking is active, you should call * <code>isActive</code>. In effect, <code>isActive</code> is an * appropriate corresponding "getter" method for this one. * <code>isVisible</code> can be used to fetch the current * visibility status of the caret, meaning whether or not it is currently * painted. This status will change as the caret blinks on and off. * <p> * Here's a list showing the potential return values of both * <code>isActive</code> and <code>isVisible</code> * after calling this method: * <p> * <b><code>setVisible(true)</code></b>: * <ul> * <li>isActive(): true</li> * <li>isVisible(): true or false depending on whether * or not the caret is blinked on or off</li> * </ul> * <p> * <b><code>setVisible(false)</code></b>: * <ul> * <li>isActive(): false</li> * <li>isVisible(): false</li> * </ul> * * @param e the visibility specifier * @see #isActive * @see Caret#setVisible */ public void setVisible(boolean e)
DefaultCaret の isVisible メソッドのドキュメントは、この 2 つのプロパティーの違いを示すように更新されました。
/** * Indicates whether or not the caret is currently visible. As the * caret flashes on and off the return value of this will change * between true, when the caret is painted, and false, when the * caret is not painted. <code>isActive</code> indicates whether * or not the caret is in a blinking state, such that it <b>can</b> * be visible, and <code>isVisible</code> indicates whether or not * the caret <b>is</b> actually visible. * <p> * Subclasses that wish to render a different flashing caret * should override paint and only paint the caret if this method * returns true. * * @return true if visible else false * @see Caret#isVisible * @see #isActive */ public boolean isVisible()
css スタイルシートの background 属性は、HTML テキストの描画時に無視されます。この属性を機能させるために、次のメソッドが LabelView に追加されました。
/** * Sets the background color for the view. This method is typically * invoked as part of configuring this <code>View</code>. If you need * to customize the background color you should override * <code>setPropertiesFromAttributes</code> and invoke this method. A * value of null indicates no background should be rendered, so that the * background of the parent <code>View</code> will show through. * * @param bg background color, or null * @see #setPropertiesFromAttributes * @since 1.5 */ protected void setBackground(Color bg);
TabSet で equals
メソッドがオーバーライドされないため、TabStop
配列に同一の TabStop
が含まれている場合でも、比較に失敗します。異なるのは TabSet
が別のオブジェクトインスタンスであるという点だけにもかかわらず、オーバーライドしないために AttributeSet
が等しくなりません。
TabSet
で equals
および hashCode
がオーバーライドされるようになりました。
/** * Indicates whether this <code>TabSet</code> is equal to another one. * @param o the <code>TabSet</code> instance which this instance * should be compared to. * @return <code>true</code> if <code>o</code> is the instance of * <code>TabSet</code>, has the same number of <code>TabStop</code>s * and they are all equal, <code>false</code> otherwise. * * @since 1.5 */ public boolean equals(Object o) /** * Returns a hashcode for this set of TabStops. * @return a hashcode value for this set of TabStops. * * @since 1.5 */ public int hashCode()
JTextArea.setEditable を呼び出すと、フォーカストラバーサルキーがリセットされます。これは、フォーカストラバーサルキーのカスタムセットを提供して、その編集可能な属性を条件に応じて変更する開発者にとって問題です。
これを修正するために、JComponent
で次がオーバーライドされるようになりました。
/** * Sets the focus traversal keys for a given traversal operation for this * Component. * Refer to * {@link java.awt.Component#setFocusTraversalKeys} * for a complete description of this method. * * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS * @param keystrokes the Set of AWTKeyStroke for the specified operation * @see java.awt.KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS * @see java.awt.KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS * @see java.awt.KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS * @throws IllegalArgumentException if id is not one of * KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or if keystrokes * contains null, or if any Object in keystrokes is not an * AWTKeyStroke, or if any keystroke represents a KEY_TYPED event, * or if any keystroke already maps to another focus traversal * operation for this Component * @since 1.5 * @beaninfo * bound: true */ public void setFocusTraversalKeys(int id, Set keystrokes);
要望にあったように、FormSubmitEvent は public ではありませんでした。
ListDataEvent のコンストラクタは、getIndex0() の戻り値が常に getIndex1 の戻り値以下になるように、コンストラクタに渡される 2 つのインデックスを入れ替えるように変更されました。
/** * Constructs a ListDataEvent object. If index0 is > * index1, index0 and index1 will be swapped such that * index0 will always be <= index1. * * @param source the source Object (typically <code>this</code>) * @param type an int specifying {@link #CONTENTS_CHANGED}, * {@link #INTERVAL_ADDED}, or {@link #INTERVAL_REMOVED} * @param index0 one end of the new interval * @param index1 the other end of the new interval */ public ListDataEvent(Object source, int type, int index0, int index1) {
JTable および JList では、キーボードを使用して不連続選択を行う方法が現在のところありません。不連続選択を行えるようにするために、次が DefaultListSelectionModel に追加されました。
/** * Set the lead selection index, leaving all selection values unchanged. * If leadAnchorNotificationEnabled is true, send a notification covering * the old and new lead cells. * * @param leadIndex the new lead selection index * * @see #setAnchorSelectionIndex * @see #setLeadSelectionIndex * @see #getLeadSelectionIndex * * @since 1.5 */ public void moveLeadSelectionIndex(int leadIndex)
さらに、DefaultListSelectionModel の isLeadAnchorNotificationEnabled メソッドおよび changeSelection
メソッドが改訂されました。
JDesktopPane.LIVE_DRAG_MODE、JDesktopPane.OUTLINE_DRAG_MODE、および DTD.FILE_VERSION の static フィールドは、static final になりました。
斜影ボーダーでは、それが浮き彫りか彫り込みかに応じて shadowInner
および shadowOuter
の色が入れ替えられます。しかし、BorderFactory および BevelBorder ではこのことを説明せずに、浮き彫り斜影ボーダーについてのみ説明しています。これにより、次が BevelBorder のコンストラクタおよび BorderFactory の createBevelBorder メソッドに追加されました。
* Note: The shadow inner and outer colors are * switched for a lowered bevel border.
/** * Overridden to return true so that any calls to <code>revalidate</code> * on any descendants of this <code>JScrollPane</code> will cause the * entire tree beginning with this <code>JScrollPane</code> to be * validated. * * @return true * @see java.awt.Container#validate * @see JComponent#revalidate * @see JComponent#isValidateRoot * * @beaninfo * hidden: true */
PropertyChangeSupport クラスは、JavaBean プロパティーが変更されたことを通知する PropertyChangeEvent の登録とトリガーを簡単に行うためのユーティリティーです。SwingPropertyChangeSupport は、PropertyChangeSupport
のサブクラスであり、冗長なメソッドが多数含まれています。さらに、1.2 の時期に、プロパティー変更のサポートが Component に追加されました。Component
は、SwingPropertyChangeSupport
に依存するようにせずに、PropertyChangeSupport
を使用します。JComponent では SwingPropertyChangeSupport
のインスタンスを維持し、Component
では PropertyChangeSupport
のインスタンスを維持します。その結果、どの JComponent
にも PropertyChangeSupport
のインスタンスが 2 つ存在し、そのうちの 1 つは使用されていません。Component
と JComponent
の重複部分、また PropertyChangeSupport
と SwingPropertyChangeSupport
の重複部分を減らすために、次の変更が加えられました。
次のメソッドが JComponent
から Component
にプロモートされました。
/** * Reports a bound property change. * * @param propertyName the programmatic name of the property * that was changed * @param oldValue the old value of the property (as a byte) * @param newValue the new value of the property (as a byte) * @see #firePropertyChange(java.lang.String, java.lang.Object, * java.lang.Object) * @since 1.5 */ public void firePropertyChange(String propertyName, byte oldValue, byte newValue); /** * Reports a bound property change. * * @param propertyName the programmatic name of the property * that was changed * @param oldValue the old value of the property (as a char) * @param newValue the new value of the property (as a char) * @see #firePropertyChange(java.lang.String, java.lang.Object, * java.lang.Object) * @since 1.5 */ public void firePropertyChange(String propertyName, char oldValue, char newValue); /** * Reports a bound property change. * * @param propertyName the programmatic name of the property * that was changed * @param oldValue the old value of the property (as a short) * @param newValue the old value of the property (as a short) * @see #firePropertyChange(java.lang.String, java.lang.Object, * java.lang.Object) * @since 1.5 */ public void firePropertyChange(String propertyName, short oldValue, short newValue); /** * Reports a bound property change. * * @param propertyName the programmatic name of the property * that was changed * @param oldValue the old value of the property (as a long) * @param newValue the new value of the property (as a long) * @see #firePropertyChange(java.lang.String, java.lang.Object, * java.lang.Object) * @since 1.5 */ public void firePropertyChange(String propertyName, long oldValue, long newValue); /** * Reports a bound property change. * * @param propertyName the programmatic name of the property * that was changed * @param oldValue the old value of the property (as a float) * @param newValue the new value of the property (as a float) * @see #firePropertyChange(java.lang.String, java.lang.Object, * java.lang.Object) * @since 1.5 */ public void firePropertyChange(String propertyName, float oldValue, float newValue); /** * Reports a bound property change. * * @param propertyName the programmatic name of the property * that was changed * @param oldValue the old value of the property (as a double) * @param newValue the new value of the property (as a double) * @see #firePropertyChange(java.lang.String, java.lang.Object, * java.lang.Object) * @since 1.5 */ public void firePropertyChange(String propertyName, double oldValue, double newValue);
JComponent
の対応するメソッドは削除されました。
SwingPropertyChangeSupport
のメソッドは、コンストラクタを除いてすべて削除されました。
Swing のセルレンダラでは、セルレンダラに必要のないいくつかのメソッドを、何もしないようにオーバーライドします。現在呼び出されても何もしていないメソッドは、セルレンダラによってオーバーライドされるべきです。
次のメソッドが DefaultTableCellRenderer、DefaultListCellRenderer、および DefaultTreeCellRenderer に追加されました
/** * Overridden for performance reasons. * See the <a href="#override">Implementation Note</a> * for more information. * * @since 1.5 */ public void invalidate(); /** * Overridden for performance reasons. * See the <a href="#override">Implementation Note</a> * for more information. * * @since 1.5 */ public void repaint();
JLayeredPane は、それに含まれる Components
の HashTable
を維持します。現在、removeAll
をオーバーライドしないために HashTable
が更新されず、リークが発生する可能性があります。JLayeredPane
は removeAll
をオーバーライドして必要なクリーンアップを行うようになりました。
/** * Removes all the components from this container. * * @since 1.5 */ public void removeAll();
Swing クラスでは、多くのプロパティーのデフォルト値をドキュメント化しています。カスタム Look & Feel によって値が変更され、デフォルト値が有効でないように見えることがあるので、このことを明確にしておく必要があります。これをドキュメント化するために、次が JComponent のクラスレベルの javadoc に追加されました。
* <code>JComponent</code> and its subclasses document default values * for certain properties. For example, <code>JTable</code> documents the * default row height as 16. Each <code>JComponent</code> subclass * that has a <code>ComponentUI</code> will create the * <code>ComponentUI</code> as part of its constructor. In order * to provide a particular look and feel each * <code>ComponentUI</code> may set properties back on the * <code>JComponent</code> that created it. For example, a custom * look and feel may require <code>JTable</code>s to have a row * height of 24. The documented defaults are the value of a property * BEFORE the <code>ComponentUI</code> has been installed. If you * need a specific value for a particular property you should * explicitly set it.
1.4 以降、JFileChooser コードはネイティブレイヤーに依存しすぎています。カスタマイズされた「仮想の」ファイルシステムを使用するプログラムでこのクラスをバイパスするようにされましたが、アルゴリズムに 100% の信頼性がありません。この動作を切り替えるには、クライアントプロパティー FileChooser.useShellFolder
を使用します。たとえば、ネイティブの使用をやめるには、このプロパティーを false
に設定します。
jFileChooser.putClientProperty("FileChooser.useShellFolder", Boolean.FALSE);
現在のところ、SpringLayout を使用して、一般的なレイアウトを構築するのはやや困難です。一般的なレイアウトを SpringLayout を使用して簡単に作成するメソッド、および SpringLayout を簡単に永続するメソッドが、開発者から要求されてきました。
次が Spring に追加されました。
/** * Returns a spring whose <em>minimum</em>, <em>preferred</em>, <em>maximum</em> * and <em>value</em> properties are each multiples of the properties of the * argument spring, <code>s</code>. Minimum and maximum properties are * swapped when <code>factor</code> is negative (in accordance with the * rules of interval arithmetic). * <p> * When factor is, for example, 0.5f the result represents 'the mid-point' * of its input - an operation that is useful for centering components in * a container. * * @param s the spring to scale * @param factor amount to scale by. * @return a spring whose properties are those of the input spring <code>s</code> * multiplied by <code>factor</code> * @throws NullPointerException if <code>s</code> is null * @since 1.5 */ public static Spring scale(Spring s, float factor); /** * Returns a spring whose <em>minimum</em>, <em>preferred</em>, <em>maximum</em> * and <em>value</em> properties are defined by the widths of the <em>minimumSize</em>, * <em>preferredSize</em>, <em>maximumSize</em> and <em>size</em> properties * of the supplied component. The returned spring is a 'wrapper' implementation * whose methods call the appropriate size methods of the supplied component. * The minimum, preferred, maximum and value properties of the returned spring * therefore report the current state of the appropriate properties in the * component and track them as they change. * * @param c Component used for calculating size * @return a spring whose properties are defined by the horizontal component * of the component's size methods. * @throws NullPointerException if <code>c</code> is null * @since 1.5 */ public static Spring width(Component c); /** * Returns a spring whose <em>minimum</em>, <em>preferred</em>, <em>maximum</em> * and <em>value</em> properties are defined by the heights of the <em>minimumSize</em>, * <em>preferredSize</em>, <em>maximumSize</em> and <em>size</em> properties * of the supplied component. The returned spring is a 'wrapper' implementation * whose methods call the appropriate size methods of the supplied component. * The minimum, preferred, maximum and value properties of the returned spring * therefore report the current state of the appropriate properties in the * component and track them as they change. * * @param c Component used for calculating size * @return a spring whose properties are defined by the vertical component * of the component's size methods. * @throws NullPointerException if <code>c</code> is null * @since 1.5 */ public static Spring height(Component c);
また、次が SpringLayout.Constraints に追加されました。
/** * Creates a <code>Constraints</code> object with * suitable <code>x</code>, <code>y</code>, <code>width</code> and * <code>height</code> springs for component, <code>c</code>. * The <code>x</code> and <code>y</code> springs are constant * springs initialised with the component's location at * the time this method is called. The <code>width</code> and * <code>height</code> springs are special springs, created by * the <code>Spring.width()</code> and <code>Spring.height()</code> * methods, which track the size characteristics of the component * when they change. * * @param c the component whose characteristics will be reflected by this Constraints object * @throws NullPointerException if <code>c</code> is null. * @since 1.5 */ public Constraints(Component c);
AWT プログラミングとは異なり、JFrame/JDialg/JWindow/JApplet/JInternalFrame では Component
を追加できません。その代わり、JRootPane
について理解して、そこに子 Component を追加する必要があります。このため、新しい開発者に不必要な混乱を招きます。
5.0 より前は、Component
をトップレベルに対して追加または削除しようとすると、Component
が例外をスローしていました。5.0 では、例外がスローされるのではなく、Component
がコンテンツペインに対して追加または削除されます。この結果、JFrame
、JDialog
、JWindow
、JApplet
、および JInternalFrame
の javadoc が一部改訂されました。これについては、RootPaneContainer の javadoc にまとめられています。
* For conveniance * <code>JFrame</code>, <code>JDialog</code>, <code>JWindow</code>, * <code>JApplet</code> and <code>JInternalFrame</code>, by default, * forward all calls to <code>add</code> and its variants, * <code>remove</code> and <code>setLayout</code> to the * <code>contentPane</code>. This means rather than writing: * <pre> * rootPaneContainer.getContentPane().add(component); * </pre> * you can do: * <pre> * rootPaneContainer.add(component); * </pre> * <p> * The behavior of <code>add</code> and its variants and * <code>setLayout</code> for * <code>JFrame</code>, <code>JDialog</code>, <code>JWindow</code>, * <code>JApplet</code> and <code>JInternalFrame</code> is controlled by * the <code>rootPaneCheckingEnabled</code> property. If this property is * true, the default, then <code>add</code> and its variants and * <code>setLayout</code> are * forwarded to the <code>contentPane</code>, if it is false, then these * methods operate directly on the <code>RootPaneContainer</code>. This * property is only intended for subclasses, and is therefor protected.
JFileChooser のドキュメントでは、ファイルまたはディレクトリ、あるいはその両方が選択されるようにするための設定を、ファイルチューザのどこに指定するかが不明確です。このため、次のメソッドのドキュメントが改訂されました。
/** * Adds a filter to the list of user choosable file filters. * For information on setting the file selection mode, see * {@link #setFileSelectionMode setFileSelectionMode}. * * @param filter the <code>FileFilter</code> to add to the choosable file * filter list * * @beaninfo * preferred: true * bound: true * description: Adds a filter to the list of user choosable file filters. * * @see #getChoosableFileFilters * @see #removeChoosableFileFilter * @see #resetChoosableFileFilters * @see #setFileSelectionMode */ public void addChoosableFileFilter(FileFilter filter); /** * Sets the <code>JFileChooser</code> to allow the user to just * select files, just select * directories, or select both files and directories. The default is * <code>JFilesChooser.FILES_ONLY</code>. * * @param mode the type of files to be displayed: * <ul> * <li>JFileChooser.FILES_ONLY * <li>JFileChooser.DIRECTORIES_ONLY * <li>JFileChooser.FILES_AND_DIRECTORIES * </ul> * * @exception IllegalArgumentException if <code>mode</code> is an * illegal file selection mode * @beaninfo * preferred: true * bound: true * description: Sets the types of files that the JFileChooser can choose. * enum: FILES_ONLY JFileChooser.FILES_ONLY * DIRECTORIES_ONLY JFileChooser.DIRECTORIES_ONLY * FILES_AND_DIRECTORIES JFileChooser.FILES_AND_DIRECTORIES * * * @see #getFileSelectionMode */ public void setFileSelectionMode(int mode);
JDesktopPane.setDesktopManager を呼び出しても、UI を再ロードするまで有効になりません。
これを修正するために、BasicDesktopPaneUI は次のメソッドをオーバーライドしません。
/** * Installs the <code>PropertyChangeListener</code> returned from * <code>createPropertyChangeListener</code> on the <code>JDesktopPane</code>. * * @since 1.5 * @see #createPropertyChangeListener */ protected void installListeners() /** * Uninstalls the <code>PropertyChangeListener</code> returned from * <code>createPropertyChangeListener</code> from the <code>JDesktopPane</code>. * * @since 1.5 * @see #createPropertyChangeListener */ protected void uninstallListeners() /* * Returns the <code>PropertyChangeListener</code> to install on * the <code>JDesktopPane</code>. * * @since 1.5 * @return The PropertyChangeListener that will be added to track * changes in the desktop pane. */ protected PropertyChangeListener createPropertyChangeListener()
さまざまな JComponent サブクラスのインスタンスごとのサイズを減らすために、次の変更が加えられました。
JComponent
の優先、最小、および最大サイズのストレージが重複しないように、次のメソッドが Component
にプロモートされました。
/** * Sets the preferred size of this component to a constant * value. Subsequent calls to <code>getPreferredSize</code> will always * return this value. Setting the preferred size to <code>null</code> * restores the default behavior. * * @param preferredSize The new preferred size, or null * @see #getPreferredSize * @see #isPreferredSizeSet * @since 1.5 */ public void setPreferredSize(Dimension preferredSize); /** * Returns true if the preferred size has been set to a * non-<code>null</code> value otherwise returns false. * * @return true if <code>setPreferredSize</code> has been invoked * with a non-null value. * @since 1.5 */ public boolean isPreferredSizeSet(); /** * Sets the minimum size of this component to a constant * value. Subsequent calls to <code>getMinimumSize</code> will always * return this value. Setting the minimum size to <code>null</code> * restores the default behavior. * * @param minimumSize the new minimum size of this component * @see #getMinimumSize * @see #isMinimumSizeSet * @since 1.5 */ public void setMinimumSize(Dimension minimumSize); /** * Returns whether or not <code>setMinimumSize</code> has been * invoked with a non-null value. * * @return true if <code>setMinimumSize</code> has been invoked with a * non-null value. * @since 1.5 */ public boolean isMinimumSizeSet(); /** * Sets the maximum size of this component to a constant * value. Subsequent calls to <code>getMaximumSize</code> will always * return this value. Setting the maximum size to <code>null</code> * restores the default behavior. * * @param maximumSize a <code>Dimension</code> containing the * desired maximum allowable size * @see #getMaximumSize * @see #isMaximumSizeSet * @since 1.5 */ public void setMaximumSize(Dimension maximumSize); /** * Returns true if the maximum size has been set to a non-<code>null</code> * value otherwise returns false. * * @return true if <code>maximumSize</code> is non-<code>null</code>, * false otherwise * @since 1.5 */ public boolean isMaximumSizeSet();
自動スクロールに必要なメモリーを改善するために、JComponent
では次のメソッドがオーバーライドされます。
/** * Processes mouse events occurring on this component by * dispatching them to any registered * <code>MouseListener</code> objects, refer to * {@link java.awt.Component#processMouseEvent(MouseEvent)} * for a complete description of this method. * * @param e the mouse event * @see java.awt.Component#processMouseEvent * @since 1.5 */ protected void processMouseEvent(MouseEvent e);
AbstractButton
のサイズを減らすために、次のメソッドがオーバーライドされます。
/** * Adds the specified component to this container at the specified * index, refer to * {@link java.awt.Container#addImpl(Component, Object, int)} * for a complete description of this method. * * @param comp the component to be added * @param constraints an object expressing layout constraints * for this component * @param index the position in the container's list at which to * insert the component, where <code>-1</code> * means append to the end * @exception IllegalArgumentException if <code>index</code> is invalid * @exception IllegalArgumentException if adding the container's parent * to itself * @exception IllegalArgumentException if adding a window to a container * @since 1.5 */ protected void addImpl(Component comp, Object constraints, int index); /** * Sets the layout manager for this container, refer to * {@link java.awt.Container#setLayout(LayoutManager)} * for a complete description of this method. * * @param mgr the specified layout manager * @since 1.5 */ public void setLayout(LayoutManager mgr);
Swing では、Key-Index.html、Key-Metal.html、Key-Motif.html、および Key-Windows.html ファイル内のさまざまなコンポーネントのキーの割り当てがドキュメント化されています。これらのファイルはディレクトリ src/share/classes/javax/swing/doc-files にあり、いくつかの Swing ウィジェットから参照されています。これらのファイルは非常に古いものであり、実際には Swing のキーの割り当てをすべてドキュメント化しているわけではありません。そのため、これらのファイルと、ファイルに対するすべての参照が削除されました。
Swing の UIManager クラスは、現在のシステムに Look & Feel を提供するために使用できるクラスの名前を調べるために特に使用されます。Gnome を搭載する Solaris では、getSystemLookAndFeelClassName
の呼び出しによって GTK Look & Feel のパッケージ名が返されるべきです。
このため、次の変更が UIManager
に加えられました。
/** * Returns the name of the <code>LookAndFeel</code> class that implements * the native systems look and feel if there is one, otherwise * the name of the default cross platform <code>LookAndFeel</code> * class. If the system property <code>swing.systemlaf</code> has been * defined, it's value will be returned. * * @return the <code>String</code> of the <code>LookAndFeel</code> * class * * @see #setLookAndFeel * @see #getCrossPlatformLookAndFeelClassName */ public static String getSystemLookAndFeelClassName(); /** * Returns the name of the <code>LookAndFeel</code> class that implements * the default cross platform look and feel -- the Java * Look and Feel (JLF). If the system property * <code>swing.crossplatformlaf</code> has been * defined, it's value will be returned. * * @return a string with the JLF implementation-class * @see #setLookAndFeel * @see #getSystemLookAndFeelClassName */ public static String getCrossPlatformLookAndFeelClassName();
この作業の一貫として、WindowsClassicLookAndFeel
も作成しました。ユーザーが Windows XP を実行している場合でも、このクラスによって強制的に旧来の Windows の見た目を使用できます。
Swing でアンチエイリアス処理されたテキストを使用できるようになる前段階として、JComponent では次のメソッドをオーバーライドするようになりました。
/** * Gets the <code>FontMetrics</code> for the specified <code>Font</code>. * * @param font the font for which font metrics is to be * obtained * @return the font metrics for <code>font</code> * @throws NullPointerException if <code>font</code> is null * @since 1.5 */ public FontMetrics getFontMetrics(Font font);
これらいくつかの API の変更により、5.0 とそれ以前のリリースとの間には、潜在的な非互換性が存在するようになりました。しかし、これらの変更の影響を受ける開発者はほとんどいません。考えられる非互換性を次に示します。
Ocean ではボタン上にグラデーションを描画します。グラデーションは、contentAreaFilled
プロパティーが true であるか、background
プロパティーが UIResource
のインスタンスである場合にだけ描画されます。グラデーションが不要な場合は、contentAreaFilled
プロパティーを false に設定するか、background を UIResource 以外
に設定します。ほとんどの場合、次のように簡単です。
button.setBackground(Color.RED);
なんらかの理由で、UIResource
を使用する場合は、UIResource
ではない新しい Color
を作成する必要があります。次に例を示します。
button.setBackground(new Color(oldColor));
JTree
および JList
は、カーソルの動きをリードを基準にして解釈します。たとえば、リードが JTree
の 4 行目にあるときに上矢印キーを押すと、選択範囲が 3 行目に移動します。同様に、JTree
および JList
は、引数をそれぞれのレンダラに渡して、描画中の項目がフォーカスされているかどうかを示します。これは、描画中の項目がリードであるかどうかに基づきます。5.0 より前の JTable
ではこのような場合にアンカーを使用していましたが、5.0 の JTable
ではリードを使用します。このため、アンカーをフォーカスのあるセルと考えていた開発者に影響を及ぼす可能性があり、適切でない状況でフォーカスインジケータが描画される可能性があります。
JComboBox
のポップアップを描画するために、Sun の Look & Feel では JScrollPane
のインスタンスを使用します。JScrollPane
は、水平スクロールバーを持つようには構成されていません。5.0 では、setHorizontalScrollBar(null)
が呼び出されるようになります。