summaryrefslogtreecommitdiff
path: root/javax/swing
diff options
context:
space:
mode:
Diffstat (limited to 'javax/swing')
-rw-r--r--javax/swing/AbstractButton.java122
-rw-r--r--javax/swing/AbstractSpinnerModel.java1
-rw-r--r--javax/swing/ActionMap.java1
-rw-r--r--javax/swing/BorderFactory.java2
-rw-r--r--javax/swing/BoundedRangeModel.java4
-rw-r--r--javax/swing/Box.java4
-rw-r--r--javax/swing/BoxLayout.java683
-rw-r--r--javax/swing/ButtonGroup.java5
-rw-r--r--javax/swing/CellEditor.java2
-rw-r--r--javax/swing/CellRendererPane.java38
-rw-r--r--javax/swing/ComboBoxEditor.java2
-rw-r--r--javax/swing/DebugGraphics.java308
-rw-r--r--javax/swing/DefaultButtonModel.java1
-rw-r--r--javax/swing/DefaultCellEditor.java7
-rw-r--r--javax/swing/DefaultComboBoxModel.java172
-rw-r--r--javax/swing/DefaultDesktopManager.java4
-rw-r--r--javax/swing/DefaultListCellRenderer.java14
-rw-r--r--javax/swing/DefaultListSelectionModel.java60
-rw-r--r--javax/swing/DesktopManager.java2
-rw-r--r--javax/swing/FocusManager.java425
-rw-r--r--javax/swing/ImageIcon.java9
-rw-r--r--javax/swing/InputVerifier.java1
-rw-r--r--javax/swing/JApplet.java10
-rw-r--r--javax/swing/JButton.java7
-rw-r--r--javax/swing/JCheckBox.java22
-rw-r--r--javax/swing/JCheckBoxMenuItem.java13
-rw-r--r--javax/swing/JColorChooser.java2
-rw-r--r--javax/swing/JComboBox.java88
-rw-r--r--javax/swing/JComponent.java594
-rw-r--r--javax/swing/JDesktopPane.java3
-rw-r--r--javax/swing/JEditorPane.java441
-rw-r--r--javax/swing/JFileChooser.java765
-rw-r--r--javax/swing/JFrame.java8
-rw-r--r--javax/swing/JLabel.java18
-rw-r--r--javax/swing/JLayeredPane.java61
-rw-r--r--javax/swing/JList.java109
-rw-r--r--javax/swing/JMenu.java27
-rw-r--r--javax/swing/JMenuBar.java143
-rw-r--r--javax/swing/JMenuItem.java32
-rw-r--r--javax/swing/JOptionPane.java114
-rw-r--r--javax/swing/JPanel.java5
-rw-r--r--javax/swing/JPasswordField.java1
-rw-r--r--javax/swing/JPopupMenu.java326
-rw-r--r--javax/swing/JProgressBar.java3
-rw-r--r--javax/swing/JRadioButton.java4
-rw-r--r--javax/swing/JRadioButtonMenuItem.java8
-rw-r--r--javax/swing/JRootPane.java33
-rw-r--r--javax/swing/JScrollPane.java198
-rw-r--r--javax/swing/JSeparator.java2
-rw-r--r--javax/swing/JSlider.java3
-rw-r--r--javax/swing/JSpinner.java42
-rw-r--r--javax/swing/JSplitPane.java3
-rw-r--r--javax/swing/JTabbedPane.java8
-rw-r--r--javax/swing/JTable.java479
-rw-r--r--javax/swing/JTextArea.java43
-rw-r--r--javax/swing/JTextField.java181
-rw-r--r--javax/swing/JTextPane.java11
-rw-r--r--javax/swing/JToggleButton.java24
-rw-r--r--javax/swing/JToolBar.java3
-rw-r--r--javax/swing/JToolTip.java3
-rw-r--r--javax/swing/JTree.java52
-rw-r--r--javax/swing/JViewport.java525
-rw-r--r--javax/swing/KeyStroke.java1
-rw-r--r--javax/swing/LookAndFeel.java115
-rw-r--r--javax/swing/MutableComboBoxModel.java4
-rw-r--r--javax/swing/OverlayLayout.java326
-rw-r--r--javax/swing/Popup.java105
-rw-r--r--javax/swing/PopupFactory.java33
-rw-r--r--javax/swing/RepaintManager.java212
-rw-r--r--javax/swing/ScrollPaneLayout.java370
-rw-r--r--javax/swing/SizeRequirements.java178
-rw-r--r--javax/swing/SortingFocusTraversalPolicy.java2
-rw-r--r--javax/swing/Spring.java1
-rw-r--r--javax/swing/SwingUtilities.java6
-rw-r--r--javax/swing/ToolTipManager.java218
-rw-r--r--javax/swing/TransferHandler.java5
-rw-r--r--javax/swing/UIDefaults.java10
-rw-r--r--javax/swing/UIManager.java20
-rw-r--r--javax/swing/ViewportLayout.java3
-rw-r--r--javax/swing/border/AbstractBorder.java46
-rw-r--r--javax/swing/border/BevelBorder.java13
-rw-r--r--javax/swing/border/Border.java6
-rw-r--r--javax/swing/border/CompoundBorder.java57
-rw-r--r--javax/swing/border/EmptyBorder.java4
-rw-r--r--javax/swing/border/EtchedBorder.java45
-rw-r--r--javax/swing/border/LineBorder.java44
-rw-r--r--javax/swing/border/MatteBorder.java4
-rw-r--r--javax/swing/border/SoftBevelBorder.java12
-rw-r--r--javax/swing/border/TitledBorder.java113
-rw-r--r--javax/swing/colorchooser/AbstractColorChooserPanel.java35
-rw-r--r--javax/swing/colorchooser/ColorChooserComponentFactory.java3
-rw-r--r--javax/swing/colorchooser/DefaultSwatchChooserPanel.java3
-rw-r--r--javax/swing/event/EventListenerList.java1
-rw-r--r--javax/swing/event/InternalFrameAdapter.java147
-rw-r--r--javax/swing/event/ListDataListener.java55
-rw-r--r--javax/swing/event/MouseInputListener.java13
-rw-r--r--javax/swing/event/SwingPropertyChangeSupport.java7
-rw-r--r--javax/swing/filechooser/FileFilter.java77
-rw-r--r--javax/swing/filechooser/FileSystemView.java25
-rw-r--r--javax/swing/filechooser/FileView.java1
-rw-r--r--javax/swing/plaf/ActionMapUIResource.java4
-rw-r--r--javax/swing/plaf/BorderUIResource.java4
-rw-r--r--javax/swing/plaf/ButtonUI.java4
-rw-r--r--javax/swing/plaf/ColorChooserUI.java3
-rw-r--r--javax/swing/plaf/ColorUIResource.java4
-rw-r--r--javax/swing/plaf/ComboBoxUI.java4
-rw-r--r--javax/swing/plaf/ComponentInputMapUIResource.java3
-rw-r--r--javax/swing/plaf/ComponentUI.java8
-rw-r--r--javax/swing/plaf/DesktopIconUI.java4
-rw-r--r--javax/swing/plaf/DesktopPaneUI.java5
-rw-r--r--javax/swing/plaf/DimensionUIResource.java4
-rw-r--r--javax/swing/plaf/FileChooserUI.java4
-rw-r--r--javax/swing/plaf/FontUIResource.java4
-rw-r--r--javax/swing/plaf/IconUIResource.java3
-rw-r--r--javax/swing/plaf/InputMapUIResource.java6
-rw-r--r--javax/swing/plaf/InsetsUIResource.java3
-rw-r--r--javax/swing/plaf/InternalFrameUI.java4
-rw-r--r--javax/swing/plaf/LabelUI.java4
-rw-r--r--javax/swing/plaf/ListUI.java4
-rw-r--r--javax/swing/plaf/MenuBarUI.java4
-rw-r--r--javax/swing/plaf/MenuItemUI.java4
-rw-r--r--javax/swing/plaf/PanelUI.java4
-rw-r--r--javax/swing/plaf/PopupMenuUI.java4
-rw-r--r--javax/swing/plaf/ProgressBarUI.java4
-rw-r--r--javax/swing/plaf/RootPaneUI.java4
-rw-r--r--javax/swing/plaf/ScrollBarUI.java4
-rw-r--r--javax/swing/plaf/ScrollPaneUI.java4
-rw-r--r--javax/swing/plaf/SeparatorUI.java1
-rw-r--r--javax/swing/plaf/SliderUI.java4
-rw-r--r--javax/swing/plaf/SpinnerUI.java4
-rw-r--r--javax/swing/plaf/SplitPaneUI.java4
-rw-r--r--javax/swing/plaf/TabbedPaneUI.java4
-rw-r--r--javax/swing/plaf/TableHeaderUI.java4
-rw-r--r--javax/swing/plaf/TableUI.java4
-rw-r--r--javax/swing/plaf/TextUI.java4
-rw-r--r--javax/swing/plaf/ToolBarUI.java4
-rw-r--r--javax/swing/plaf/ToolTipUI.java4
-rw-r--r--javax/swing/plaf/TreeUI.java4
-rw-r--r--javax/swing/plaf/UIResource.java6
-rw-r--r--javax/swing/plaf/ViewportUI.java4
-rw-r--r--javax/swing/plaf/basic/BasicArrowButton.java393
-rw-r--r--javax/swing/plaf/basic/BasicBorders.java13
-rw-r--r--javax/swing/plaf/basic/BasicButtonListener.java11
-rw-r--r--javax/swing/plaf/basic/BasicButtonUI.java128
-rw-r--r--javax/swing/plaf/basic/BasicCheckBoxMenuItemUI.java23
-rw-r--r--javax/swing/plaf/basic/BasicColorChooserUI.java20
-rw-r--r--javax/swing/plaf/basic/BasicComboBoxEditor.java1
-rw-r--r--javax/swing/plaf/basic/BasicComboBoxRenderer.java1
-rw-r--r--javax/swing/plaf/basic/BasicComboBoxUI.java218
-rw-r--r--javax/swing/plaf/basic/BasicComboPopup.java58
-rw-r--r--javax/swing/plaf/basic/BasicDesktopIconUI.java2
-rw-r--r--javax/swing/plaf/basic/BasicDesktopPaneUI.java80
-rw-r--r--javax/swing/plaf/basic/BasicFileChooserUI.java510
-rw-r--r--javax/swing/plaf/basic/BasicFormattedTextFieldUI.java1
-rw-r--r--javax/swing/plaf/basic/BasicGraphicsUtils.java1
-rw-r--r--javax/swing/plaf/basic/BasicIconFactory.java26
-rw-r--r--javax/swing/plaf/basic/BasicInternalFrameTitlePane.java55
-rw-r--r--javax/swing/plaf/basic/BasicInternalFrameUI.java26
-rw-r--r--javax/swing/plaf/basic/BasicLabelUI.java18
-rw-r--r--javax/swing/plaf/basic/BasicListUI.java525
-rw-r--r--javax/swing/plaf/basic/BasicLookAndFeel.java133
-rw-r--r--javax/swing/plaf/basic/BasicMenuBarUI.java29
-rw-r--r--javax/swing/plaf/basic/BasicMenuItemUI.java102
-rw-r--r--javax/swing/plaf/basic/BasicMenuUI.java88
-rw-r--r--javax/swing/plaf/basic/BasicOptionPaneUI.java75
-rw-r--r--javax/swing/plaf/basic/BasicPanelUI.java28
-rw-r--r--javax/swing/plaf/basic/BasicPasswordFieldUI.java1
-rw-r--r--javax/swing/plaf/basic/BasicPopupMenuUI.java12
-rw-r--r--javax/swing/plaf/basic/BasicProgressBarUI.java24
-rw-r--r--javax/swing/plaf/basic/BasicRadioButtonMenuItemUI.java4
-rw-r--r--javax/swing/plaf/basic/BasicRadioButtonUI.java35
-rw-r--r--javax/swing/plaf/basic/BasicRootPaneUI.java119
-rw-r--r--javax/swing/plaf/basic/BasicScrollBarUI.java315
-rw-r--r--javax/swing/plaf/basic/BasicScrollPaneUI.java403
-rw-r--r--javax/swing/plaf/basic/BasicSeparatorUI.java73
-rw-r--r--javax/swing/plaf/basic/BasicSliderUI.java51
-rw-r--r--javax/swing/plaf/basic/BasicSpinnerUI.java16
-rw-r--r--javax/swing/plaf/basic/BasicSplitPaneDivider.java1
-rw-r--r--javax/swing/plaf/basic/BasicSplitPaneUI.java64
-rw-r--r--javax/swing/plaf/basic/BasicTabbedPaneUI.java44
-rw-r--r--javax/swing/plaf/basic/BasicTableHeaderUI.java63
-rw-r--r--javax/swing/plaf/basic/BasicTableUI.java575
-rw-r--r--javax/swing/plaf/basic/BasicTextAreaUI.java41
-rw-r--r--javax/swing/plaf/basic/BasicTextFieldUI.java15
-rw-r--r--javax/swing/plaf/basic/BasicTextUI.java94
-rw-r--r--javax/swing/plaf/basic/BasicToggleButtonUI.java65
-rw-r--r--javax/swing/plaf/basic/BasicToolBarSeparatorUI.java5
-rw-r--r--javax/swing/plaf/basic/BasicToolBarUI.java47
-rw-r--r--javax/swing/plaf/basic/BasicToolTipUI.java99
-rw-r--r--javax/swing/plaf/basic/BasicTreeUI.java838
-rw-r--r--javax/swing/plaf/basic/BasicViewportUI.java177
-rw-r--r--javax/swing/plaf/metal/MetalBorders.java374
-rw-r--r--javax/swing/plaf/metal/MetalButtonListener.java86
-rw-r--r--javax/swing/plaf/metal/MetalButtonUI.java158
-rw-r--r--javax/swing/plaf/metal/MetalCheckBoxIcon.java3
-rw-r--r--javax/swing/plaf/metal/MetalCheckBoxUI.java7
-rw-r--r--javax/swing/plaf/metal/MetalComboBoxButton.java29
-rw-r--r--javax/swing/plaf/metal/MetalComboBoxEditor.java8
-rw-r--r--javax/swing/plaf/metal/MetalComboBoxUI.java32
-rw-r--r--javax/swing/plaf/metal/MetalDesktopIconUI.java10
-rw-r--r--javax/swing/plaf/metal/MetalFileChooserUI.java430
-rw-r--r--javax/swing/plaf/metal/MetalIconFactory.java473
-rw-r--r--javax/swing/plaf/metal/MetalInternalFrameTitlePane.java24
-rw-r--r--javax/swing/plaf/metal/MetalInternalFrameUI.java8
-rw-r--r--javax/swing/plaf/metal/MetalLabelUI.java10
-rw-r--r--javax/swing/plaf/metal/MetalLookAndFeel.java35
-rw-r--r--javax/swing/plaf/metal/MetalPopupMenuSeparatorUI.java10
-rw-r--r--javax/swing/plaf/metal/MetalProgressBarUI.java33
-rw-r--r--javax/swing/plaf/metal/MetalRadioButtonUI.java15
-rw-r--r--javax/swing/plaf/metal/MetalRootPaneUI.java13
-rw-r--r--javax/swing/plaf/metal/MetalScrollBarUI.java218
-rw-r--r--javax/swing/plaf/metal/MetalScrollButton.java7
-rw-r--r--javax/swing/plaf/metal/MetalScrollPaneUI.java10
-rw-r--r--javax/swing/plaf/metal/MetalSeparatorUI.java63
-rw-r--r--javax/swing/plaf/metal/MetalSliderUI.java10
-rw-r--r--javax/swing/plaf/metal/MetalSplitPaneDivider.java2
-rw-r--r--javax/swing/plaf/metal/MetalSplitPaneUI.java35
-rw-r--r--javax/swing/plaf/metal/MetalTabbedPaneUI.java28
-rw-r--r--javax/swing/plaf/metal/MetalTextFieldUI.java32
-rw-r--r--javax/swing/plaf/metal/MetalToggleButtonUI.java38
-rw-r--r--javax/swing/plaf/metal/MetalToolBarUI.java112
-rw-r--r--javax/swing/plaf/metal/MetalToolTipUI.java272
-rw-r--r--javax/swing/plaf/metal/MetalTreeUI.java54
-rw-r--r--javax/swing/plaf/metal/MetalUtils.java99
-rw-r--r--javax/swing/plaf/metal/OceanTheme.java11
-rw-r--r--javax/swing/plaf/metal/package.html13
-rw-r--r--javax/swing/plaf/multi/MultiLookAndFeel.java1
-rw-r--r--javax/swing/table/DefaultTableCellRenderer.java11
-rw-r--r--javax/swing/table/JTableHeader.java109
-rw-r--r--javax/swing/table/TableColumnModel.java4
-rw-r--r--javax/swing/text/AbstractDocument.java197
-rw-r--r--javax/swing/text/AttributeSet.java6
-rw-r--r--javax/swing/text/BoxView.java248
-rw-r--r--javax/swing/text/ComponentView.java68
-rw-r--r--javax/swing/text/CompositeView.java20
-rw-r--r--javax/swing/text/DefaultCaret.java199
-rw-r--r--javax/swing/text/DefaultEditorKit.java24
-rw-r--r--javax/swing/text/DefaultFormatter.java5
-rw-r--r--javax/swing/text/DefaultHighlighter.java2
-rw-r--r--javax/swing/text/DefaultStyledDocument.java18
-rw-r--r--javax/swing/text/EditorKit.java10
-rw-r--r--javax/swing/text/FieldView.java7
-rw-r--r--javax/swing/text/FlowView.java38
-rw-r--r--javax/swing/text/GapContent.java256
-rw-r--r--javax/swing/text/GlyphView.java20
-rw-r--r--javax/swing/text/JTextComponent.java159
-rw-r--r--javax/swing/text/LabelView.java242
-rw-r--r--javax/swing/text/LayoutQueue.java1
-rw-r--r--javax/swing/text/ParagraphView.java30
-rw-r--r--javax/swing/text/PlainDocument.java28
-rw-r--r--javax/swing/text/PlainView.java324
-rw-r--r--javax/swing/text/Segment.java4
-rw-r--r--javax/swing/text/SimpleAttributeSet.java46
-rw-r--r--javax/swing/text/StyleContext.java11
-rw-r--r--javax/swing/text/StyledDocument.java191
-rw-r--r--javax/swing/text/Utilities.java250
-rw-r--r--javax/swing/text/View.java49
-rw-r--r--javax/swing/text/WrappedPlainView.java547
-rw-r--r--javax/swing/text/html/CSS.java35
-rw-r--r--javax/swing/text/html/HTML.java13
-rw-r--r--javax/swing/text/html/HTMLDocument.java215
-rw-r--r--javax/swing/text/html/HTMLEditorKit.java40
-rw-r--r--javax/swing/text/html/HTMLFrameHyperlinkEvent.java4
-rw-r--r--javax/swing/text/html/parser/ContentModel.java5
-rw-r--r--javax/swing/text/html/parser/DTD.java3
-rw-r--r--javax/swing/text/html/parser/DocumentParser.java7
-rw-r--r--javax/swing/text/html/parser/Element.java2
-rw-r--r--javax/swing/text/html/parser/Parser.java10
-rw-r--r--javax/swing/tree/DefaultMutableTreeNode.java1
-rw-r--r--javax/swing/tree/DefaultTreeCellEditor.java13
-rw-r--r--javax/swing/tree/DefaultTreeModel.java1
-rw-r--r--javax/swing/tree/TreeCellRenderer.java34
-rw-r--r--javax/swing/tree/TreeModel.java122
-rw-r--r--javax/swing/undo/CannotRedoException.java4
-rw-r--r--javax/swing/undo/CannotUndoException.java1
275 files changed, 14906 insertions, 6000 deletions
diff --git a/javax/swing/AbstractButton.java b/javax/swing/AbstractButton.java
index 21c4fc0a2..9d9597639 100644
--- a/javax/swing/AbstractButton.java
+++ b/javax/swing/AbstractButton.java
@@ -165,6 +165,8 @@ public abstract class AbstractButton extends JComponent
*/
public void stateChanged(ChangeEvent ev)
{
+ AbstractButton.this.fireStateChanged();
+ repaint();
}
}
@@ -375,6 +377,7 @@ public abstract class AbstractButton extends JComponent
protected AccessibleAbstractButton()
{
+ // Nothing to do here yet.
}
public AccessibleStateSet getAccessibleStateSet()
@@ -509,11 +512,37 @@ public abstract class AbstractButton extends JComponent
}
/**
- * Creates a new AbstractButton object.
+ * 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()
{
- init("", null);
+ actionListener = createActionListener();
+ changeListener = createChangeListener();
+ itemListener = createItemListener();
+
+ 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 = "";
updateUI();
}
@@ -524,7 +553,7 @@ public abstract class AbstractButton extends JComponent
*/
public ButtonModel getModel()
{
- return model;
+ return model;
}
/**
@@ -569,25 +598,6 @@ public abstract class AbstractButton extends JComponent
if (icon != null)
default_icon = icon;
-
- actionListener = createActionListener();
- changeListener = createChangeListener();
- itemListener = createItemListener();
-
- horizontalAlignment = CENTER;
- horizontalTextPosition = TRAILING;
- verticalAlignment = CENTER;
- verticalTextPosition = CENTER;
- borderPainted = true;
- contentAreaFilled = true;
-
- focusPainted = true;
- setFocusable(true);
-
- setAlignmentX(LEFT_ALIGNMENT);
- setAlignmentY(CENTER_ALIGNMENT);
-
- setDisplayedMnemonicIndex(-1);
}
/**
@@ -615,7 +625,8 @@ public abstract class AbstractButton extends JComponent
*/
public void setActionCommand(String actionCommand)
{
- model.setActionCommand(actionCommand);
+ if (model != null)
+ model.setActionCommand(actionCommand);
}
/**
@@ -782,7 +793,10 @@ public abstract class AbstractButton extends JComponent
*/
public int getMnemonic()
{
- return getModel().getMnemonic();
+ ButtonModel mod = getModel();
+ if (mod != null)
+ return mod.getMnemonic();
+ return -1;
}
/**
@@ -810,11 +824,15 @@ public abstract class AbstractButton extends JComponent
*/
public void setMnemonic(int mne)
{
- int old = getModel().getMnemonic();
+ ButtonModel mod = getModel();
+ int old = -1;
+ if (mod != null)
+ old = mod.getMnemonic();
if (old != mne)
{
- getModel().setMnemonic(mne);
+ if (mod != null)
+ mod.setMnemonic(mne);
if (text != null && !text.equals(""))
{
@@ -907,7 +925,9 @@ public abstract class AbstractButton extends JComponent
*/
public void setSelected(boolean s)
{
- getModel().setSelected(s);
+ ButtonModel mod = getModel();
+ if (mod != null)
+ mod.setSelected(s);
}
/**
@@ -918,7 +938,10 @@ public abstract class AbstractButton extends JComponent
*/
public boolean isSelected()
{
- return getModel().isSelected();
+ ButtonModel mod = getModel();
+ if (mod != null)
+ return mod.isSelected();
+ return false;
}
/**
@@ -929,8 +952,13 @@ public abstract class AbstractButton extends JComponent
*/
public void setEnabled(boolean b)
{
+ // Do nothing if state does not change.
+ if (b == isEnabled())
+ return;
super.setEnabled(b);
- getModel().setEnabled(b);
+ ButtonModel mod = getModel();
+ if (mod != null)
+ mod.setEnabled(b);
}
/**
@@ -1608,16 +1636,9 @@ public abstract class AbstractButton extends JComponent
*
* @return The new ChangeListener
*/
- protected ChangeListener createChangeListener()
+ protected ChangeListener createChangeListener()
{
- return new ChangeListener()
- {
- public void stateChanged(ChangeEvent e)
- {
- AbstractButton.this.fireStateChanged();
- AbstractButton.this.repaint();
- }
- };
+ return new ButtonChangeListener();
}
/**
@@ -1669,18 +1690,22 @@ public abstract class AbstractButton extends JComponent
*/
public void doClick(int pressTime)
{
- getModel().setArmed(true);
- getModel().setPressed(true);
- try
+ ButtonModel mod = getModel();
+ if (mod != null)
{
- java.lang.Thread.sleep(pressTime);
- }
- catch (java.lang.InterruptedException e)
- {
- // probably harmless
+ mod.setArmed(true);
+ mod.setPressed(true);
+ try
+ {
+ java.lang.Thread.sleep(pressTime);
+ }
+ catch (java.lang.InterruptedException e)
+ {
+ // probably harmless
+ }
+ mod.setPressed(false);
+ mod.setArmed(false);
}
- getModel().setPressed(false);
- getModel().setArmed(false);
}
/**
@@ -1979,6 +2004,7 @@ public abstract class AbstractButton extends JComponent
*/
public void updateUI()
{
+ // TODO: What to do here?
}
/**
diff --git a/javax/swing/AbstractSpinnerModel.java b/javax/swing/AbstractSpinnerModel.java
index 2590fe195..9402c1565 100644
--- a/javax/swing/AbstractSpinnerModel.java
+++ b/javax/swing/AbstractSpinnerModel.java
@@ -61,6 +61,7 @@ public abstract class AbstractSpinnerModel implements SpinnerModel
*/
public AbstractSpinnerModel()
{
+ // Nothing to do here.
}
/**
diff --git a/javax/swing/ActionMap.java b/javax/swing/ActionMap.java
index c14bafdb4..56bc41de6 100644
--- a/javax/swing/ActionMap.java
+++ b/javax/swing/ActionMap.java
@@ -80,6 +80,7 @@ public class ActionMap
*/
public ActionMap()
{
+ // Nothing to do here.
}
/**
diff --git a/javax/swing/BorderFactory.java b/javax/swing/BorderFactory.java
index 45cf3bbe0..ca78deb12 100644
--- a/javax/swing/BorderFactory.java
+++ b/javax/swing/BorderFactory.java
@@ -71,7 +71,7 @@ public class BorderFactory
*/
public static Border createLineBorder(Color color)
{
- return null;
+ return createLineBorder(color, 1);
}
/**
diff --git a/javax/swing/BoundedRangeModel.java b/javax/swing/BoundedRangeModel.java
index 5ca5a7e04..54446acd5 100644
--- a/javax/swing/BoundedRangeModel.java
+++ b/javax/swing/BoundedRangeModel.java
@@ -165,13 +165,13 @@ public interface BoundedRangeModel
*
* @param value the value
* @param extent the extent
- * @param minnimum the minimum value
+ * @param minimum the minimum value
* @param maximum the maximum value
* @param adjusting a flag that indicates the model is being adjusted
* continuously.
*/
void setRangeProperties(int value, int extent, int minimum, int maximum,
- boolean adjusting);
+ boolean adjusting);
/**
* Adds a <code>ChangeListener</code> to this object.
diff --git a/javax/swing/Box.java b/javax/swing/Box.java
index 9cd4421a2..57519f6fc 100644
--- a/javax/swing/Box.java
+++ b/javax/swing/Box.java
@@ -70,6 +70,7 @@ public class Box extends JComponent implements Accessible
protected AccessibleBox()
{
+ // Nothing to do here.
}
public AccessibleRole getAccessibleRole()
@@ -95,6 +96,7 @@ public class Box extends JComponent implements Accessible
protected AccessibleBoxFiller()
{
+ // Nothing to do here.
}
public AccessibleRole getAccessibleRole()
@@ -103,8 +105,6 @@ public class Box extends JComponent implements Accessible
}
}
- protected AccessibleContext accessibleContext;
-
private transient Dimension min, pref, max;
/**
diff --git a/javax/swing/BoxLayout.java b/javax/swing/BoxLayout.java
index 28bb53928..fb540e478 100644
--- a/javax/swing/BoxLayout.java
+++ b/javax/swing/BoxLayout.java
@@ -45,12 +45,6 @@ import java.awt.Dimension;
import java.awt.Insets;
import java.awt.LayoutManager2;
import java.io.Serializable;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Vector;
-
-import gnu.java.awt.AWTUtilities;
/**
* A layout that stacks the children of a container in a Box, either
@@ -63,248 +57,6 @@ public class BoxLayout implements LayoutManager2, Serializable
{
/**
- * This is an abstraction that allows the BoxLayout algorithm to
- * be applied to both direction (X and Y) without duplicating the
- * algorithm. It defines several methods that access properties of
- * a component for a specific direction.
- */
- static interface Direction
- {
- /**
- * Returns the correct part of <code>d</code> for this direction. This will
- * be <code>d.width</code> for horizontal and <code>d.height</code> for
- * vertical direction.
- *
- * @param d the size as Dimension object
- *
- * @return the correct part of <code>d</code> for this direction
- */
- int size(Dimension d);
-
- /**
- * Returns the lower bounds of the {@link Insets} object according to this
- * direction. This will be <code>insets.top</code> for vertical direction
- * and <code>insets.left</code> for horizontal direction.
- *
- * @param the {@link Insets} object from which to return the lower bounds
- *
- * @return the lower bounds of the {@link Insets} object according to this
- * direction
- */
- int lower(Insets insets);
-
- /**
- * Returns the alignment property according to this direction.
- *
- * @param comp the Component for which to return the alignment property
- *
- * @return the alignment property according to this direction
- */
- float alignment(Component comp);
-
- /**
- * Sets the location for Component <code>c</code>. <code>coord1</code>
- * specifies the coordinate of the location in this direction,
- * <code>coord2</code> the coordinate of the location in the opposite
- * direction.
- *
- * @param c the Component for which to set the location
- * @param coord1 the coordinate in this direction
- * @param coord2 the coordinate in the opposite direction
- */
- void setLocation(Component c, int coord1, int coord2);
-
- /**
- * Sets the size for Component <code>c</code>. <code>coord1</code>
- * specifies the size in this direction,
- * <code>coord2</code> the size in the opposite
- * direction.
- *
- * @param c the Component for which to set the size
- * @param size1 the size in this direction
- * @param size2 the size in the opposite direction
- */
- void setSize(Component c, int size1, int size2);
- }
-
- /**
- * The horizontal direction.
- */
- static class Horizontal implements Direction
- {
- /**
- * Returns the correct part of <code>d</code> for this direction. This will
- * be <code>d.width</code> for horizontal and <code>d.height</code> for
- * vertical direction.
- *
- * @param d the size as Dimension object
- *
- * @return the correct part of <code>d</code> for this direction
- */
- public int size(Dimension d)
- {
- return d.width;
- }
-
- /**
- * Returns the lower bounds of the {@link Insets} object according to this
- * direction. This will be <code>insets.top</code> for vertical direction
- * and <code>insets.left</code> for horizontal direction.
- *
- * @param insets the {@link Insets} object from which to return the lower
- * bounds
- *
- * @return the lower bounds of the {@link Insets} object according to this
- * direction
- */
- public int lower(Insets insets)
- {
- return insets.left;
- }
-
- /**
- * Returns the alignment property according to this direction.
- *
- * @param comp the Component for which to return the alignment property
- *
- * @return the alignment property according to this direction
- */
- public float alignment(Component comp)
- {
- return comp.getAlignmentX();
- }
-
- /**
- * Sets the location for Component <code>c</code>. <code>coord1</code>
- * specifies the coordinate of the location in this direction,
- * <code>coord2</code> the coordinate of the location in the opposite
- * direction.
- *
- * @param c the Component for which to set the location
- * @param coord1 the coordinate in this direction
- * @param coord2 the coordinate in the opposite direction
- */
- public void setLocation(Component c, int coord1, int coord2)
- {
- c.setLocation(coord1, coord2);
- }
-
- /**
- * Sets the size for Component <code>c</code>. <code>coord1</code>
- * specifies the size in this direction,
- * <code>coord2</code> the size in the opposite
- * direction.
- *
- * @param c the Component for which to set the size
- * @param size1 the size in this direction
- * @param size2 the size in the opposite direction
- */
- public void setSize(Component c, int size1, int size2)
- {
- c.setSize(size1, size2);
- }
- }
- /**
- * The vertical direction.
- */
- static class Vertical implements Direction
- {
- /**
- * Returns the correct part of <code>d</code> for this direction. This will
- * be <code>d.width</code> for horizontal and <code>d.height</code> for
- * vertical direction.
- *
- * @param d the size as Dimension object
- *
- * @return the correct part of <code>d</code> for this direction
- */
- public int size(Dimension d)
- {
- return d.height;
- }
-
- /**
- * Returns the lower bounds of the {@link Insets} object according to this
- * direction. This will be <code>insets.top</code> for vertical direction
- * and <code>insets.left</code> for horizontal direction.
- *
- * @param insets the {@link Insets} object from which to return the lower
- * bounds
- *
- * @return the lower bounds of the {@link Insets} object according to this
- * direction
- */
- public int lower(Insets insets)
- {
- return insets.top;
- }
-
- /**
- * Returns the alignment property according to this direction.
- *
- * @param comp the Component for which to return the alignment property
- *
- * @return the alignment property according to this direction
- */
- public float alignment(Component comp)
- {
- return comp.getAlignmentY();
- }
-
- /**
- * Sets the location for Component <code>c</code>. <code>coord1</code>
- * specifies the coordinate of the location in this direction,
- * <code>coord2</code> the coordinate of the location in the opposite
- * direction.
- *
- * @param c the Component for which to set the location
- * @param coord1 the coordinate in this direction
- * @param coord2 the coordinate in the opposite direction
- */
- public void setLocation(Component c, int coord1, int coord2)
- {
- c.setLocation(coord2, coord1);
- }
-
- /**
- * Sets the size for Component <code>c</code>. <code>coord1</code>
- * specifies the size in this direction,
- * <code>coord2</code> the size in the opposite
- * direction.
- *
- * @param c the Component for which to set the size
- * @param size1 the size in this direction
- * @param size2 the size in the opposite direction
- */
- public void setSize(Component c, int size1, int size2)
- {
- c.setSize(size2, size1);
- }
- }
-
- /**
- * A helper class that temporarily stores the size specs of a component.
- */
- static class SizeReq
- {
- int size;
- int min;
- int pref;
- int max;
- float align;
- Component comp;
- SizeReq(Component comp, Direction dir)
- {
- this.min = dir.size(comp.getMinimumSize());
- this.pref = dir.size(comp.getPreferredSize());
- this.max = dir.size(comp.getMaximumSize());
- this.size = dir.size(comp.getSize());
- this.align = dir.alignment(comp);
- this.comp = comp;
- }
- }
-
- /**
* Specifies that components are laid out left to right.
*/
public static final int X_AXIS = 0;
@@ -334,16 +86,50 @@ public class BoxLayout implements LayoutManager2, Serializable
*/
private Container container;
- /*
+ /**
* Current type of component layouting. Defaults to X_AXIS.
*/
private int way = X_AXIS;
- /** Constant for the horizontal direction. */
- private static final Direction HORIZONTAL = new Horizontal();
+ /**
+ * The size requirements of the containers children for the X direction.
+ */
+ private SizeRequirements[] xChildren;
- /** Constant for the vertical direction. */
- private static final Direction VERTICAL = new Vertical();
+ /**
+ * The size requirements of the containers children for the Y direction.
+ */
+ private SizeRequirements[] yChildren;
+
+ /**
+ * The size requirements of the container to be laid out for the X direction.
+ */
+ private SizeRequirements xTotal;
+
+ /**
+ * The size requirements of the container to be laid out for the Y direction.
+ */
+ private SizeRequirements yTotal;
+
+ /**
+ * The offsets of the child components in the X direction.
+ */
+ private int[] offsetsX;
+
+ /**
+ * The offsets of the child components in the Y direction.
+ */
+ private int[] offsetsY;
+
+ /**
+ * The spans of the child components in the X direction.
+ */
+ private int[] spansX;
+
+ /**
+ * The spans of the child components in the Y direction.
+ */
+ private int[] spansY;
/**
* Constructs a <code>BoxLayout</code> object.
@@ -369,6 +155,7 @@ public class BoxLayout implements LayoutManager2, Serializable
*/
public void addLayoutComponent(String name, Component component)
{
+ // Nothing to do here.
}
/**
@@ -378,6 +165,7 @@ public class BoxLayout implements LayoutManager2, Serializable
*/
public void removeLayoutComponent(Component component)
{
+ // Nothing to do here.
}
private boolean isHorizontalIn(Container parent)
@@ -401,45 +189,16 @@ public class BoxLayout implements LayoutManager2, Serializable
*/
public Dimension preferredLayoutSize(Container parent)
{
- if (parent != container)
- throw new AWTError("invalid parent");
-
- Insets insets = parent.getInsets();
- int x = 0;
- int y = 0;
-
- List children = AWTUtilities.getVisibleChildren(parent);
+ synchronized (container.getTreeLock())
+ {
+ if (container != parent)
+ throw new AWTError("BoxLayout can't be shared");
- if (isHorizontalIn(parent))
- {
- x = insets.left + insets.right;
- // sum up preferred widths of components, find maximum of preferred
- // heights
- for (Iterator i = children.iterator(); i.hasNext();)
- {
- Component comp = (Component) i.next();
- Dimension sz = comp.getPreferredSize();
- x += sz.width;
- y = Math.max(y, sz.height);
- }
- y += insets.bottom + insets.top;
- }
- else
- {
- y = insets.top + insets.bottom;
- // sum up preferred heights of components, find maximum of
- // preferred widths
- for (Iterator i = children.iterator(); i.hasNext();)
- {
- Component comp = (Component) i.next();
- Dimension sz = comp.getPreferredSize();
- y += sz.height;
- x = Math.max(x, sz.width);
- }
- x += insets.left + insets.right;
+ checkTotalRequirements();
+ Insets i = container.getInsets();
+ return new Dimension(xTotal.preferred + i.left + i.right,
+ yTotal.preferred + i.top + i.bottom);
}
-
- return new Dimension(x, y);
}
/**
@@ -451,41 +210,14 @@ public class BoxLayout implements LayoutManager2, Serializable
*/
public Dimension minimumLayoutSize(Container parent)
{
- if (parent != container)
- throw new AWTError("invalid parent");
-
- Insets insets = parent.getInsets();
- int x = insets.left + insets.right;
- int y = insets.bottom + insets.top;
-
- List children = AWTUtilities.getVisibleChildren(parent);
-
- if (isHorizontalIn(parent))
+ synchronized (container.getTreeLock())
{
- // sum up preferred widths of components, find maximum of preferred
- // heights
- for (Iterator i = children.iterator(); i.hasNext();)
- {
- Component comp = (Component) i.next();
- Dimension sz = comp.getMinimumSize();
- x += sz.width;
- y = Math.max(y, sz.height);
- }
- }
- else
- {
- // sum up preferred heights of components, find maximum of
- // preferred widths
- for (Iterator i = children.iterator(); i.hasNext();)
- {
- Component comp = (Component) i.next();
- Dimension sz = comp.getMinimumSize();
- y += sz.height;
- x = Math.max(x, sz.width);
- }
+ if (container != parent)
+ throw new AWTError("BoxLayout can't be shared");
+
+ checkTotalRequirements();
+ return new Dimension(xTotal.minimum, yTotal.minimum);
}
-
- return new Dimension(x, y);
}
/**
@@ -495,12 +227,20 @@ public class BoxLayout implements LayoutManager2, Serializable
*/
public void layoutContainer(Container parent)
{
- if (isHorizontalIn(parent))
- layoutAlgorithm(parent, HORIZONTAL, VERTICAL);
- else
- layoutAlgorithm(parent, VERTICAL, HORIZONTAL);
+ synchronized (container.getTreeLock())
+ {
+ if (container != parent)
+ throw new AWTError("BoxLayout can't be shared");
+
+ checkLayout();
+ Component[] children = container.getComponents();
+ Insets in = container.getInsets();
+ for (int i = 0; i < children.length; i++)
+ children[i].setBounds(offsetsX[i] + in.left, offsetsY[i] + in.top,
+ spansX[i], spansY[i]);
+ }
}
-
+
/**
* Adds a component to the layout. Not used in BoxLayout
*
@@ -509,6 +249,7 @@ public class BoxLayout implements LayoutManager2, Serializable
*/
public void addLayoutComponent(Component child, Object constraints)
{
+ // Nothing to do here.
}
/**
@@ -520,10 +261,14 @@ public class BoxLayout implements LayoutManager2, Serializable
*/
public float getLayoutAlignmentX(Container parent)
{
- if (parent != container)
- throw new AWTError("invalid parent");
-
- return 0;
+ synchronized (container.getTreeLock())
+ {
+ if (container != parent)
+ throw new AWTError("BoxLayout can't be shared");
+
+ checkTotalRequirements();
+ return xTotal.alignment;
+ }
}
/**
@@ -535,10 +280,14 @@ public class BoxLayout implements LayoutManager2, Serializable
*/
public float getLayoutAlignmentY(Container parent)
{
- if (parent != container)
- throw new AWTError("invalid parent");
-
- return 0;
+ synchronized (container.getTreeLock())
+ {
+ if (container != parent)
+ throw new AWTError("BoxLayout can't be shared");
+
+ checkTotalRequirements();
+ return yTotal.alignment;
+ }
}
/**
@@ -548,8 +297,17 @@ public class BoxLayout implements LayoutManager2, Serializable
*/
public void invalidateLayout(Container parent)
{
- if (parent != container)
- throw new AWTError("invalid parent");
+ synchronized (container.getTreeLock())
+ {
+ xChildren = null;
+ yChildren = null;
+ xTotal = null;
+ yTotal = null;
+ offsetsX = null;
+ offsetsY = null;
+ spansX = null;
+ spansY = null;
+ }
}
/**
@@ -562,188 +320,115 @@ public class BoxLayout implements LayoutManager2, Serializable
*/
public Dimension maximumLayoutSize(Container parent)
{
- if (parent != container)
- throw new AWTError("invalid parent");
-
- Insets insets = parent.getInsets();
- int x = insets.left + insets.right;
- int y = insets.top + insets.bottom;
+ synchronized (container.getTreeLock())
+ {
+ if (container != parent)
+ throw new AWTError("BoxLayout can't be shared");
- List children = AWTUtilities.getVisibleChildren(parent);
+ checkTotalRequirements();
+ return new Dimension(xTotal.maximum, yTotal.maximum);
+ }
+ }
- if (isHorizontalIn(parent))
+ /**
+ * Makes sure that the xTotal and yTotal fields are set up correctly. A call
+ * to {@link #invalidateLayout} sets these fields to null and they have to be
+ * recomputed.
+ */
+ private void checkTotalRequirements()
+ {
+ if (xTotal == null || yTotal == null)
{
-
- // sum up preferred widths of components, find maximum of preferred
- // heights
- for (Iterator i = children.iterator(); i.hasNext();)
+ checkRequirements();
+ if (isHorizontalIn(container))
{
- Component comp = (Component) i.next();
- Dimension sz = comp.getMaximumSize();
- x += sz.width;
- // Check for overflow.
- if (x < 0)
- x = Integer.MAX_VALUE;
- y = Math.max(y, sz.height);
+ xTotal = SizeRequirements.getTiledSizeRequirements(xChildren);
+ yTotal = SizeRequirements.getAlignedSizeRequirements(yChildren);
}
- }
- else
- {
- // sum up preferred heights of components, find maximum of
- // preferred widths
- for (Iterator i = children.iterator(); i.hasNext();)
+ else
{
- Component comp = (Component) i.next();
- Dimension sz = comp.getMaximumSize();
- y += sz.height;
- // Check for overflow
- if (y < 0)
- y = Integer.MAX_VALUE;
- x = Math.max(x, sz.width);
+ xTotal = SizeRequirements.getAlignedSizeRequirements(xChildren);
+ yTotal = SizeRequirements.getTiledSizeRequirements(yChildren);
}
- }
- return new Dimension(x, y);
+ }
}
/**
- * Lays out the Container <code>c</code> in the layout direction
- * <code>layoutDir</code>. The direction that is crossing the layout
- * direction is specified in <code>crossDir</code>.
- *
- * @param parent
- * @param layoutDir
- * @param crossDir
+ * Makes sure that the xChildren and yChildren fields are correctly set up.
+ * A call to {@link #invalidateLayout(Container)} sets these fields to null,
+ * so they have to be set up again.
*/
- void layoutAlgorithm(Container parent, Direction layoutDir, Direction crossDir)
+ private void checkRequirements()
{
- if (parent != container)
- throw new AWTError("invalid parent");
-
- Dimension parentSize = parent.getSize();
- Insets insets = parent.getInsets();
- Dimension innerSize = new Dimension(parentSize.width - insets.left
- - insets.right, parentSize.height
- - insets.bottom - insets.top);
-
- // Set all components to their preferredSizes and sum up the allocated
- // space. Create SizeReqs for each component and store them in
- // sizeReqs. Find the maximum size in the crossing direction.
- List children = AWTUtilities.getVisibleChildren(parent);
- Vector sizeReqs = new Vector();
- int allocated = 0;
- for (Iterator i = children.iterator(); i.hasNext();)
- {
- Component c = (Component) i.next();
- SizeReq sizeReq = new SizeReq(c, layoutDir);
- int preferred = layoutDir.size(c.getPreferredSize());
- sizeReq.size = preferred;
- allocated += preferred;
- sizeReqs.add(sizeReq);
- }
-
- // Distribute remaining space (may be positive or negative) over components
- int remainder = layoutDir.size(innerSize) - allocated;
- distributeSpace(sizeReqs, remainder, layoutDir);
-
- // Resize and relocate components. If the component can be sized to
- // take the full space in the crossing direction, then do so, otherwise
- // align according to its alingnmentX or alignmentY property.
- int loc = 0;
- int offset1 = layoutDir.lower(insets);
- int offset2 = crossDir.lower(insets);
- for (Iterator i = sizeReqs.iterator(); i.hasNext();)
+ if (xChildren == null || yChildren == null)
{
- SizeReq sizeReq = (SizeReq) i.next();
- Component c = sizeReq.comp;
- int availCrossSize = crossDir.size(innerSize);
- int maxCross = crossDir.size(c.getMaximumSize());
- int crossSize = Math.min(availCrossSize, maxCross);
- int crossRemainder = availCrossSize - crossSize;
- int crossLoc = (int) (crossDir.alignment(c) * crossRemainder);
- layoutDir.setSize(c, sizeReq.size, crossSize);
- layoutDir.setLocation(c, offset1 + loc, offset2 + crossLoc);
- loc += sizeReq.size;
+ Component[] children = container.getComponents();
+ xChildren = new SizeRequirements[children.length];
+ yChildren = new SizeRequirements[children.length];
+ for (int i = 0; i < children.length; i++)
+ {
+ if (! children[i].isVisible())
+ {
+ xChildren[i] = new SizeRequirements();
+ yChildren[i] = new SizeRequirements();
+ }
+ else
+ {
+ xChildren[i] =
+ new SizeRequirements(children[i].getMinimumSize().width,
+ children[i].getPreferredSize().width,
+ children[i].getMaximumSize().width,
+ children[i].getAlignmentX());
+ yChildren[i] =
+ new SizeRequirements(children[i].getMinimumSize().height,
+ children[i].getPreferredSize().height,
+ children[i].getMaximumSize().height,
+ children[i].getAlignmentY());
+ }
+ }
}
}
/**
- * Distributes some space over a set of components. This implementation
- * tries to set the components as close as possible to their
- * <code>preferredSize</code>s, and respects the components
- * <code>minimumSize</code> and <code>maximumSize</code>.
- *
- * The algorithm is implemented as follows:
- *
- * <ul>
- * <li>The <code>remainder</code> is divided by the number of components
- * in <code>freeComponents</code>.</li>
- * <li>The result is added to (or substracted from) the size of each
- * component.</li>
- * <li>If the <code>minimumSize</code> or <code>maximumSize</code> of a
- * component is exceeded, then this component is set to its
- * <code>minimumSize</code> or <code>maximumSize</code>, it is removed from
- * <code>freeComponents</code> and the difference is added to a new
- * remainder.</li>
- * <li>Finally, if there is a new remainer != 0 and the
- * <code>freeComponents.size() != 0</code>, then this method is called
- * recursivly to distribute the newly allocated remaining space.</li>
- * </ul>
- *
- * @param freeComponents a SizeReq collection for components that have space
- * left so that they can be moved freely
- * @param remainder the space that should be distributed between the
- * components
- * @param dir the direction in which we operate
+ * Makes sure that the offsetsX, offsetsY, spansX and spansY fields are set
+ * up correctly. A call to {@link #invalidateLayout} sets these fields
+ * to null and they have to be recomputed.
*/
- void distributeSpace(Collection freeComponents, int remainder, Direction dir)
+ private void checkLayout()
{
- // Sum up total available space in components. If the remainder is negative
- // then we sum up the difference between minSize and size. If remainder
- // is positive we sum up the difference between maxSize and size.
- double totalAvailable = 0;
- for (Iterator i = freeComponents.iterator(); i.hasNext();)
- {
- SizeReq sizeReq = (SizeReq) i.next();
- if (remainder >= 0)
- totalAvailable += sizeReq.max - sizeReq.size;
- else
- totalAvailable += sizeReq.min - sizeReq.size;
- }
- if (totalAvailable == 0)
- if (remainder >= 0)
- totalAvailable = 1;
- else
- totalAvailable = -1;
-
- int newRemainder = 0;
- Vector stillFree = new Vector();
- for (Iterator i = freeComponents.iterator(); i.hasNext();)
+ if (offsetsX == null || offsetsY == null || spansX == null
+ || spansY == null)
{
- // Add/substract share to component.
- SizeReq sizeReq = (SizeReq) i.next();
- double available = 0;
- if (remainder >= 0)
- available = sizeReq.max - sizeReq.size;
+ checkRequirements();
+ checkTotalRequirements();
+ int len = container.getComponents().length;
+ offsetsX = new int[len];
+ offsetsY = new int[len];
+ spansX = new int[len];
+ spansY = new int[len];
+
+ Insets in = container.getInsets();
+ int width = container.getWidth() - in.left - in.right;
+ int height = container.getHeight() - in.top -in.bottom;
+
+ if (isHorizontalIn(container))
+ {
+ SizeRequirements.calculateTiledPositions(width,
+ xTotal, xChildren,
+ offsetsX, spansX);
+ SizeRequirements.calculateAlignedPositions(height,
+ yTotal, yChildren,
+ offsetsY, spansY);
+ }
else
- available = sizeReq.min - sizeReq.size;
- int share = (int) ((available / totalAvailable) * remainder);
- sizeReq.size += share;
- // check for min/maximumSize
- if (sizeReq.size < sizeReq.min)
- {
- newRemainder += sizeReq.size - sizeReq.min;
- sizeReq.size = sizeReq.min;
- }
- else if (sizeReq.size > sizeReq.max)
- {
- newRemainder += sizeReq.size - sizeReq.max;
- sizeReq.size = sizeReq.max;
- }
- else
- stillFree.add(sizeReq);
+ {
+ SizeRequirements.calculateAlignedPositions(width,
+ xTotal, xChildren,
+ offsetsX, spansX);
+ SizeRequirements.calculateTiledPositions(height,
+ yTotal, yChildren,
+ offsetsY, spansY);
+ }
}
- // recursivly call this method if necessary
- if (newRemainder != 0 && stillFree.size() > 0)
- distributeSpace(stillFree, newRemainder, dir);
}
}
diff --git a/javax/swing/ButtonGroup.java b/javax/swing/ButtonGroup.java
index 3de1d4b9f..94f0109e6 100644
--- a/javax/swing/ButtonGroup.java
+++ b/javax/swing/ButtonGroup.java
@@ -79,6 +79,7 @@ public class ButtonGroup implements Serializable
*/
public ButtonGroup()
{
+ // Nothing to do here.
}
/**
@@ -89,6 +90,8 @@ public class ButtonGroup implements Serializable
public void add(AbstractButton b)
{
b.getModel().setGroup(this);
+ if (b.isSelected())
+ sel = b.getModel();
buttons.addElement(b);
}
@@ -158,7 +161,7 @@ public class ButtonGroup implements Serializable
{
ButtonModel old = sel;
sel = m;
-
+
if (old != null)
old.setSelected(false);
AbstractButton button = FindButton(old);
diff --git a/javax/swing/CellEditor.java b/javax/swing/CellEditor.java
index bdb166575..3d229b266 100644
--- a/javax/swing/CellEditor.java
+++ b/javax/swing/CellEditor.java
@@ -83,7 +83,7 @@ public interface CellEditor
/**
* addCellEditorListener
- * @param value0 TODO
+ * @param listener TODO
*/
void addCellEditorListener(CellEditorListener listener);
diff --git a/javax/swing/CellRendererPane.java b/javax/swing/CellRendererPane.java
index 886d5c5f2..c59afd318 100644
--- a/javax/swing/CellRendererPane.java
+++ b/javax/swing/CellRendererPane.java
@@ -54,9 +54,7 @@ import javax.accessibility.AccessibleRole;
*
* @author Andrew Selkirk
*/
-public class CellRendererPane
- extends Container
- implements Accessible
+public class CellRendererPane extends Container implements Accessible
{
private static final long serialVersionUID = -7642183829532984273L;
@@ -72,6 +70,7 @@ public class CellRendererPane
*/
protected AccessibleCellRendererPane()
{
+ // Nothing to do here.
}
/**
@@ -89,22 +88,13 @@ public class CellRendererPane
*/
protected AccessibleContext accessibleContext = null;
-
- //-------------------------------------------------------------
- // Initialization ---------------------------------------------
- //-------------------------------------------------------------
-
/**
* Constructs a new CellRendererPane.
*/
public CellRendererPane()
{
- } // CellRendererPane()
-
-
- //-------------------------------------------------------------
- // Methods ----------------------------------------------------
- //-------------------------------------------------------------
+ // Nothing to do here.
+ }
/**
* Should not be called.
@@ -113,7 +103,8 @@ public class CellRendererPane
*/
public void update(Graphics graphics)
{
- } // update()
+ //Nothing to do here.
+ }
/**
* Despite normal behaviour this does <em>not</em> cause the container
@@ -121,7 +112,8 @@ public class CellRendererPane
*/
public void invalidate()
{
- } // invalidate()
+ // Overridden to do nothing.
+ }
/**
* Should not be called.
@@ -130,6 +122,7 @@ public class CellRendererPane
*/
public void paint(Graphics graphics)
{
+ // Overridden to do nothing.
}
/**
@@ -147,7 +140,7 @@ public class CellRendererPane
{
super.addImpl(c, constraints, index);
}
- } // addImpl()
+ }
/**
* Paints the specified component <code>c</code> on the {@link Graphics}
@@ -175,9 +168,10 @@ public class CellRendererPane
// reparent c
addImpl(c, null, 0);
+ Rectangle oldClip = graphics.getClipBounds();
// translate to (x,y)
graphics.translate(x, y);
-
+ graphics.clipRect(0, 0, w, h);
// set bounds of c
c.setBounds(0, 0, w, h);
@@ -192,8 +186,8 @@ public class CellRendererPane
// untranslate g
graphics.translate(-x, -y);
-
- } // paintComponent()
+ graphics.setClip(oldClip);
+ }
/**
* Paints the specified component <code>c</code> on the {@link Graphics}
@@ -215,7 +209,7 @@ public class CellRendererPane
Container p, int x, int y, int w, int h)
{
paintComponent(graphics, c, p, x, y, w, h, false);
- } // paintComponent()
+ }
/**
* Paints the specified component <code>c</code> on the {@link Graphics}
@@ -233,7 +227,7 @@ public class CellRendererPane
Container p, Rectangle r)
{
paintComponent(graphics, c, p, r.x, r.y, r.width, r.height);
- } // paintComponent()
+ }
/**
* getAccessibleContext <em>TODO</em>
diff --git a/javax/swing/ComboBoxEditor.java b/javax/swing/ComboBoxEditor.java
index 4eb5fc562..8e914e4b9 100644
--- a/javax/swing/ComboBoxEditor.java
+++ b/javax/swing/ComboBoxEditor.java
@@ -64,7 +64,7 @@ public interface ComboBoxEditor
* combo box list then this method should be called to change editting item
* to the new selected item.
*
- * @param selectedItem item that is currently selected in the combo box
+ * @param item item that is currently selected in the combo box
*/
void setItem(Object item);
diff --git a/javax/swing/DebugGraphics.java b/javax/swing/DebugGraphics.java
index 137b82337..126309a58 100644
--- a/javax/swing/DebugGraphics.java
+++ b/javax/swing/DebugGraphics.java
@@ -42,6 +42,7 @@ 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;
@@ -84,15 +85,16 @@ public class DebugGraphics extends Graphics
static PrintStream debugLogStream = System.out;
/**
- * graphics
+ * Counts the created DebugGraphics objects. This is used by the
+ * logging facility.
*/
- Graphics graphics;
+ static int counter = 0;
/**
- * color
+ * graphics
*/
- Color color = Color.BLACK;
-
+ Graphics graphics;
+
/**
* buffer
*/
@@ -123,7 +125,7 @@ public class DebugGraphics extends Graphics
*/
public DebugGraphics()
{
- // TODO
+ counter++;
}
/**
@@ -134,7 +136,7 @@ public class DebugGraphics extends Graphics
*/
public DebugGraphics(Graphics graphics, JComponent component)
{
- this.graphics = graphics;
+ this(graphics);
// FIXME: What shall we do with component ?
}
@@ -145,6 +147,7 @@ public class DebugGraphics extends Graphics
*/
public DebugGraphics(Graphics graphics)
{
+ this();
this.graphics = graphics;
}
@@ -155,7 +158,10 @@ public class DebugGraphics extends Graphics
*/
public void setColor(Color color)
{
- this.color = color;
+ if ((debugOptions & LOG_OPTION) != 0)
+ logStream().println(prefix() + " Setting color: " + color);
+
+ graphics.setColor(color);
}
/**
@@ -166,7 +172,9 @@ public class DebugGraphics extends Graphics
*/
public Graphics create()
{
- return new DebugGraphics(graphics.create());
+ DebugGraphics copy = new DebugGraphics(graphics.create());
+ copy.debugOptions = debugOptions;
+ return copy;
}
/**
@@ -182,7 +190,10 @@ public class DebugGraphics extends Graphics
*/
public Graphics create(int x, int y, int width, int height)
{
- return new DebugGraphics(graphics.create(x, y, width, height));
+ DebugGraphics copy = new DebugGraphics(graphics.create(x, y, width,
+ height));
+ copy.debugOptions = debugOptions;
+ return copy;
}
/**
@@ -282,6 +293,9 @@ public class DebugGraphics extends Graphics
*/
public void setFont(Font font)
{
+ if ((debugOptions & LOG_OPTION) != 0)
+ logStream().println(prefix() + " Setting font: " + font);
+
graphics.setFont(font);
}
@@ -292,7 +306,7 @@ public class DebugGraphics extends Graphics
*/
public Color getColor()
{
- return color;
+ return graphics.getColor();
}
/**
@@ -325,6 +339,9 @@ public class DebugGraphics extends Graphics
*/
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);
}
@@ -333,6 +350,9 @@ public class DebugGraphics extends Graphics
*/
public void setPaintMode()
{
+ if ((debugOptions & LOG_OPTION) != 0)
+ logStream().println(prefix() + " Setting paint mode");
+
graphics.setPaintMode();
}
@@ -343,6 +363,9 @@ public class DebugGraphics extends Graphics
*/
public void setXORMode(Color color)
{
+ if ((debugOptions & LOG_OPTION) != 0)
+ logStream().println(prefix() + " Setting XOR mode: " + color);
+
graphics.setXORMode(color);
}
@@ -366,7 +389,16 @@ public class DebugGraphics extends Graphics
*/
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());
}
/**
@@ -379,6 +411,12 @@ public class DebugGraphics extends Graphics
*/
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);
}
@@ -399,6 +437,9 @@ public class DebugGraphics extends Graphics
*/
public void setClip(Shape shape)
{
+ if ((debugOptions & LOG_OPTION) != 0)
+ logStream().println(prefix() + " Setting new clipRect: " + shape);
+
graphics.setClip(shape);
}
@@ -424,18 +465,27 @@ public class DebugGraphics extends Graphics
*/
public void drawRect(int x, int y, int width, int height)
{
- for (int index = 0; index < (debugFlashCount - 1); ++index)
+ if ((debugOptions & LOG_OPTION) != 0)
{
- graphics.setColor(color);
- graphics.drawRect(x, y, width, height);
- sleep(debugFlashTime);
+ logStream().println(prefix() + " Drawing rect: "
+ + new Rectangle(x, y, width, height));
+ }
- graphics.setColor(debugFlashColor);
- graphics.drawRect(x, y, width, height);
- sleep(debugFlashTime);
+ 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.setColor(color);
graphics.drawRect(x, y, width, height);
}
@@ -449,18 +499,27 @@ public class DebugGraphics extends Graphics
*/
public void fillRect(int x, int y, int width, int height)
{
- for (int index = 0; index < (debugFlashCount - 1); ++index)
+ if ((debugOptions & LOG_OPTION) != 0)
{
- graphics.setColor(color);
- graphics.fillRect(x, y, width, height);
- sleep(debugFlashTime);
+ logStream().println(prefix() + " Filling rect: "
+ + new Rectangle(x, y, width, height));
+ }
- graphics.setColor(debugFlashColor);
- graphics.fillRect(x, y, width, height);
- sleep(debugFlashTime);
+ 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.setColor(color);
graphics.fillRect(x, y, width, height);
}
@@ -474,6 +533,12 @@ public class DebugGraphics extends Graphics
*/
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);
}
@@ -490,6 +555,14 @@ public class DebugGraphics extends Graphics
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);
}
@@ -506,6 +579,14 @@ public class DebugGraphics extends Graphics
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);
}
@@ -519,6 +600,12 @@ public class DebugGraphics extends Graphics
*/
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);
}
@@ -533,6 +620,13 @@ public class DebugGraphics extends Graphics
*/
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);
}
@@ -547,6 +641,13 @@ public class DebugGraphics extends Graphics
*/
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);
}
@@ -560,6 +661,12 @@ public class DebugGraphics extends Graphics
*/
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);
}
@@ -573,6 +680,12 @@ public class DebugGraphics extends Graphics
*/
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);
}
@@ -589,6 +702,14 @@ public class DebugGraphics extends Graphics
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);
}
@@ -605,6 +726,14 @@ public class DebugGraphics extends Graphics
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);
}
@@ -617,6 +746,12 @@ public class DebugGraphics extends Graphics
*/
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);
}
@@ -629,6 +764,12 @@ public class DebugGraphics extends Graphics
*/
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);
}
@@ -641,6 +782,12 @@ public class DebugGraphics extends Graphics
*/
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);
}
@@ -653,6 +800,12 @@ public class DebugGraphics extends Graphics
*/
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);
}
@@ -666,6 +819,12 @@ public class DebugGraphics extends Graphics
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);
}
@@ -681,6 +840,9 @@ public class DebugGraphics extends Graphics
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);
}
@@ -696,18 +858,24 @@ public class DebugGraphics extends Graphics
public void drawChars(char[] data, int offset, int length,
int x, int y)
{
- for (int index = 0; index < (debugFlashCount - 1); ++index)
+ 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);
- sleep(debugFlashTime);
-
- graphics.setColor(debugFlashColor);
- graphics.drawChars(data, offset, length, x, y);
- sleep(debugFlashTime);
}
- graphics.setColor(color);
graphics.drawChars(data, offset, length, x, y);
}
@@ -723,6 +891,12 @@ public class DebugGraphics extends Graphics
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);
}
@@ -741,6 +915,12 @@ public class DebugGraphics extends Graphics
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);
}
@@ -759,6 +939,13 @@ public class DebugGraphics extends Graphics
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);
}
@@ -779,6 +966,13 @@ public class DebugGraphics extends Graphics
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);
}
@@ -802,6 +996,13 @@ public class DebugGraphics extends Graphics
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);
}
@@ -827,6 +1028,14 @@ public class DebugGraphics extends Graphics
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);
}
@@ -843,6 +1052,13 @@ public class DebugGraphics extends Graphics
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);
}
@@ -873,6 +1089,11 @@ public class DebugGraphics extends Graphics
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");
}
/**
@@ -884,4 +1105,21 @@ public class DebugGraphics extends Graphics
{
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)";
+ }
}
diff --git a/javax/swing/DefaultButtonModel.java b/javax/swing/DefaultButtonModel.java
index 13a126461..201ee2a8c 100644
--- a/javax/swing/DefaultButtonModel.java
+++ b/javax/swing/DefaultButtonModel.java
@@ -145,6 +145,7 @@ public class DefaultButtonModel implements ButtonModel, Serializable
*/
public DefaultButtonModel()
{
+ // Nothing to do here.
}
/**
diff --git a/javax/swing/DefaultCellEditor.java b/javax/swing/DefaultCellEditor.java
index 00e008644..39e48551e 100644
--- a/javax/swing/DefaultCellEditor.java
+++ b/javax/swing/DefaultCellEditor.java
@@ -69,7 +69,7 @@ public class DefaultCellEditor
private static final long serialVersionUID = 3564035141373880027L;
/**
- * Delegates a couple of method calls (such as {@link #isCellEditable)
+ * Delegates a couple of method calls (such as {@link #isCellEditable}
* to the component it contains and listens for events that indicate
* that editing has stopped.
*/
@@ -88,12 +88,13 @@ public class DefaultCellEditor
*/
protected EditorDelegate()
{
+ // Nothing to do here.
}
/**
* setValue
*
- * @param event TODO
+ * @param value TODO
*/
public void setValue(Object value)
{
@@ -387,7 +388,7 @@ public class DefaultCellEditor
/**
* getTableCellEditorComponent
*
- * @param tree TODO
+ * @param table TODO
* @param value TODO
* @param isSelected TODO
* @param row TODO
diff --git a/javax/swing/DefaultComboBoxModel.java b/javax/swing/DefaultComboBoxModel.java
index b48b968d6..ea261a33b 100644
--- a/javax/swing/DefaultComboBoxModel.java
+++ b/javax/swing/DefaultComboBoxModel.java
@@ -1,5 +1,5 @@
/* DefaultComboBoxModel.java --
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -41,13 +41,14 @@ import java.io.Serializable;
import java.util.Arrays;
import java.util.Vector;
+import javax.swing.event.ListDataEvent;
+
/**
- * The default implementation of {@link MutableComboBoxModel}.
- * This model keeps track
- * of elements contained in the JComboBox as well as the current combo box
- * selection. Whenever selection in the JComboBox changes, the ComboBoxModel
- * will fire ListDataEvents to ComboBox's ListDataListeners.
+ * A model that stores a list of elements and a selected item (which may be
+ * <code>null</code>). Changes to the model are signalled to listeners using
+ * {@link ListDataEvent}. This model is designed for use by the
+ * {@link JComboBox} component.
*
* @author Andrew Selkirk
* @author Olga Rodimina
@@ -59,17 +60,17 @@ public class DefaultComboBoxModel extends AbstractListModel
private static final long serialVersionUID = 6698657703676921904L;
/**
- * List containing items in the combo box
+ * Storage for the elements in the model's list.
*/
private Vector list;
/**
- * Currently selected item in the combo box list
+ * The selected item (<code>null</code> indicates no selection).
*/
private Object selectedItem = null;
/**
- * Constructor DefaultComboBoxModel. Create empty JComboBox.
+ * Creates a new model, initially empty.
*/
public DefaultComboBoxModel()
{
@@ -77,64 +78,92 @@ public class DefaultComboBoxModel extends AbstractListModel
}
/**
- * Constructs new DefaultComboBoxModel object and initializes its item list
- * to values in the given array.
+ * Creates a new model and initializes its item list to the values in the
+ * given array. The selected item is set to the first item in the array, or
+ * <code>null</code> if the array length is zero.
*
- * @param items array containing items of the combo box.
+ * @param items an array containing items for the model (<code>null</code>
+ * not permitted).
+ *
+ * @throws NullPointerException if <code>items</code> is <code>null</code>.
*/
public DefaultComboBoxModel(Object[] items)
{
list = new Vector(Arrays.asList(items));
+ if (list.size() > 0)
+ selectedItem = list.get(0);
}
/**
- * Consturcts new DefaultComboBoxModel object and initializes its item list
- * to values in the given vector.
+ * Creates a new model and initializes its item list to the values in the
+ * given vector. The selected item is set to the first item in the vector,
+ * or <code>null</code> if the vector length is zero.
*
- * @param vector Vector containing items for this combo box.
+ * @param vector a vector containing items for the model (<code>null</code>
+ * not permitted).
+ *
+ * @throws NullPointerException if <code>vector</code> is <code>null</code>.
*/
public DefaultComboBoxModel(Vector vector)
{
this.list = vector;
+ if (vector.size() > 0)
+ selectedItem = vector.get(0);
}
/**
- * This method adds element to the combo box list. It fires ListDataEvent
- * indicating that component was added to the combo box to all of the
- * JComboBox's registered ListDataListeners.
+ * Adds an element to the model's item list and sends a {@link ListDataEvent}
+ * to all registered listeners. If the new element is the first item added
+ * to the list, it is set as the selected item.
*
- * @param object item to add to the combo box list
+ * @param object item to add to the model's item list.
*/
public void addElement(Object object)
{
list.add(object);
- fireIntervalAdded(this, list.size() - 1, list.size());
+ fireIntervalAdded(this, list.size() - 1, list.size() - 1);
+ if (list.size() == 1)
+ setSelectedItem(object);
}
/**
- * This method removes element at the specified index from the combo box
- * list. It fires ListDataEvent indicating that component was removed from
- * the combo box list to all of the JComboBox's registered
- * ListDataListeners.
+ * Removes the element at the specified index from the model's item list
+ * and sends a {@link ListDataEvent} to all registered listeners. If the
+ * element removed was the selected item, then the preceding element becomes
+ * the new selected item (or the next element, if there is no preceding
+ * element).
*
- * @param index index specifying location of the element to remove in the
- * combo box list.
+ * @param index the index of the item to remove.
+ *
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds.
*/
public void removeElementAt(int index)
{
+ int selected = getIndexOf(selectedItem);
list.remove(index);
+ if (selected == index) // choose a new selected item
+ {
+ if (selected > 0)
+ selectedItem = getElementAt(selected - 1);
+ else
+ selectedItem = getElementAt(selected);
+ }
fireIntervalRemoved(this, index, index);
}
/**
- * This method inserts given object to the combo box list at the specified
- * index. It fires ListDataEvent indicating that component was inserted to
- * the combo box list to all of the JComboBox's registered
- * ListDataListeners.
+ * Adds an element at the specified index in the model's item list
+ * and sends a {@link ListDataEvent} to all registered listeners.
*
* @param object element to insert
* @param index index specifing position in the list where given element
* should be inserted.
+ *
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds.
+ *
+ * @see #addElement(Object)
*/
public void insertElementAt(Object object, int index)
{
@@ -143,11 +172,13 @@ public class DefaultComboBoxModel extends AbstractListModel
}
/**
- * Removes given object from the combo box list. It fires ListDataEvent
- * indicating that component was removed from the combo box list to all of
- * the JComboBox's registered ListDataListeners.
+ * Removes an element from the model's item list and sends a
+ * {@link ListDataEvent} to all registered listeners. If the item to be
+ * removed is the current selected item, a new selected item will be set.
+ * If the element is not found in the model's item list, this method does
+ * nothing.
*
- * @param object Element that will be removed from the combo box list
+ * @param object the element to remove.
*/
public void removeElement(Object object)
{
@@ -157,21 +188,25 @@ public class DefaultComboBoxModel extends AbstractListModel
}
/**
- * Removes all the items from the JComboBox's item list. It fires
- * ListDataEvent indicating that all the elements were removed from the
- * combo box list to all of the JComboBox's registered ListDataListeners.
+ * Removes all the items from the model's item list, resets and selected item
+ * to <code>null</code>, and sends a {@link ListDataEvent} to all registered
+ * listeners.
*/
public void removeAllElements()
{
- list.clear();
- int listSize = getSize();
- fireIntervalAdded(this, 0, listSize);
+ selectedItem = null;
+ int size = getSize();
+ if (size > 0)
+ {
+ list.clear();
+ fireIntervalRemoved(this, 0, size - 1);
+ }
}
/**
- * Returns number of items in the combo box list
+ * Returns the number of items in the model's item list.
*
- * @return number of items in the combo box list
+ * @return The number of items in the model's item list.
*/
public int getSize()
{
@@ -179,32 +214,32 @@ public class DefaultComboBoxModel extends AbstractListModel
}
/**
- * Selects given object in the combo box list. This method fires
- * ListDataEvent to all registered ListDataListeners of the JComboBox. The
- * start and end index of the event is set to -1 to indicate combo box's
- * selection has changed, and not its contents.
- *
- * <p>If the given object is not contained in the combo box list then nothing
- * happens.</p>
+ * Sets the selected item for the model and sends a {@link ListDataEvent} to
+ * all registered listeners. The start and end index of the event is set to
+ * -1 to indicate the model's selection has changed, and not its contents.
*
- * @param object item to select in the JComboBox
+ * @param object the new selected item (<code>null</code> permitted).
*/
public void setSelectedItem(Object object)
{
-
- // Updates the selected item only if the given object
- // is null or in the list (this is how the JDK behaves).
- if(object == null || list.contains(object)) {
- selectedItem = object;
- fireContentsChanged(this, -1, -1);
- }
-
+ if (selectedItem == null)
+ {
+ if (object == null)
+ return;
+ }
+ else
+ {
+ if (selectedItem.equals(object))
+ return;
+ }
+ selectedItem = object;
+ fireContentsChanged(this, -1, -1);
}
/**
- * Returns currently selected item in the combo box list
+ * Returns the selected item.
*
- * @return currently selected item in the combo box list
+ * @return The selected item (possibly <code>null</code>).
*/
public Object getSelectedItem()
{
@@ -212,24 +247,27 @@ public class DefaultComboBoxModel extends AbstractListModel
}
/**
- * Returns element in the combo box list located at the given index
+ * Returns the element at the specified index in the model's item list.
*
- * @param index specifying location of the element in the list
+ * @param index the element index.
*
- * @return return element in the combo box list located at the given index
+ * @return The element at the specified index in the model's item list, or
+ * <code>null</code> if the <code>index</code> is outside the bounds
+ * of the list.
*/
public Object getElementAt(int index)
{
+ if (index < 0 || index >= list.size())
+ return null;
return list.elementAt(index);
}
/**
- * Returns index of the specified object in the combo box list.
+ * Returns the index of the specified element in the model's item list.
*
- * @param object element to look for in the combo box list .
+ * @param object the element.
*
- * @return Index specifying position of the specified element in combo box
- * list.
+ * @return The index of the specified element in the model's item list.
*/
public int getIndexOf(Object object)
{
diff --git a/javax/swing/DefaultDesktopManager.java b/javax/swing/DefaultDesktopManager.java
index 2b8977e9d..7f62c9486 100644
--- a/javax/swing/DefaultDesktopManager.java
+++ b/javax/swing/DefaultDesktopManager.java
@@ -91,6 +91,7 @@ public class DefaultDesktopManager implements DesktopManager, Serializable
*/
public DefaultDesktopManager()
{
+ // Nothing to do here.
}
/**
@@ -223,6 +224,7 @@ public class DefaultDesktopManager implements DesktopManager, Serializable
}
catch (PropertyVetoException e)
{
+ // Do nothing if attempt is vetoed.
}
}
@@ -302,6 +304,7 @@ public class DefaultDesktopManager implements DesktopManager, Serializable
}
catch (PropertyVetoException e)
{
+ // Do nothing if attempt is vetoed.
}
}
@@ -329,6 +332,7 @@ public class DefaultDesktopManager implements DesktopManager, Serializable
}
catch (PropertyVetoException e)
{
+ // Do nothing if attempt is vetoed.
}
}
}
diff --git a/javax/swing/DefaultListCellRenderer.java b/javax/swing/DefaultListCellRenderer.java
index 5a34ba7aa..9a8e07071 100644
--- a/javax/swing/DefaultListCellRenderer.java
+++ b/javax/swing/DefaultListCellRenderer.java
@@ -68,6 +68,7 @@ public class DefaultListCellRenderer extends JLabel
{
public UIResource()
{
+ super();
}
}
@@ -124,62 +125,75 @@ public class DefaultListCellRenderer extends JLabel
public void validate()
{
+ // Overridden to do nothing.
}
public void revalidate()
{
+ // Overridden to do nothing.
}
public void repaint(long tm, int x, int y, int w, int h)
{
+ // Overridden to do nothing.
}
public void repaint(Rectangle rect)
{
+ // Overridden to do nothing.
}
protected void firePropertyChange(String propertyName, Object oldValue,
Object newValue)
{
+ // Overridden to do nothing.
}
public void firePropertyChange(String propertyName, byte oldValue,
byte newValue)
{
+ // Overridden to do nothing.
}
public void firePropertyChange(String propertyName, char oldValue,
char newValue)
{
+ // Overridden to do nothing.
}
public void firePropertyChange(String propertyName, short oldValue,
short newValue)
{
+ // Overridden to do nothing.
}
public void firePropertyChange(String propertyName, int oldValue,
int newValue)
{
+ // Overridden to do nothing.
}
public void firePropertyChange(String propertyName, long oldValue,
long newValue)
{
+ // Overridden to do nothing.
}
public void firePropertyChange(String propertyName, float oldValue,
float newValue)
{
+ // Overridden to do nothing.
}
public void firePropertyChange(String propertyName, double oldValue,
double newValue)
{
+ // Overridden to do nothing.
}
public void firePropertyChange(String propertyName, boolean oldValue,
boolean newValue)
{
+ // Overridden to do nothing.
}
}
diff --git a/javax/swing/DefaultListSelectionModel.java b/javax/swing/DefaultListSelectionModel.java
index 7344b0dca..5729e1837 100644
--- a/javax/swing/DefaultListSelectionModel.java
+++ b/javax/swing/DefaultListSelectionModel.java
@@ -238,14 +238,32 @@ public class DefaultListSelectionModel implements Cloneable,
*/
public void setLeadSelectionIndex(int leadIndex)
{
+ // Only set the lead selection index to < 0 if anchorSelectionIndex < 0.
+ if (leadIndex < 0)
+ {
+ if (anchorSelectionIndex < 0)
+ leadSelectionIndex = -1;
+ else
+ return;
+ }
+
+ // Only touch the lead selection index if the anchor is >= 0.
+ if (anchorSelectionIndex < 0)
+ return;
+
+ if (selectionMode == SINGLE_SELECTION)
+ setSelectionInterval (leadIndex, leadIndex);
+
int oldLeadIndex = leadSelectionIndex;
+ if (oldLeadIndex == -1)
+ oldLeadIndex = leadIndex;
if (setLeadCalledFromAdd == false)
oldSel = sel.clone();
leadSelectionIndex = leadIndex;
if (anchorSelectionIndex == -1)
- return;
-
+ return;
+
int R1 = Math.min(anchorSelectionIndex, oldLeadIndex);
int R2 = Math.max(anchorSelectionIndex, oldLeadIndex);
int S1 = Math.min(anchorSelectionIndex, leadIndex);
@@ -254,8 +272,6 @@ public class DefaultListSelectionModel implements Cloneable,
int lo = Math.min(R1, S1);
int hi = Math.max(R2, S2);
- BitSet oldRange = sel.get(lo, hi+1);
-
if (isSelectedIndex(anchorSelectionIndex))
{
sel.clear(R1, R2+1);
@@ -265,10 +281,7 @@ public class DefaultListSelectionModel implements Cloneable,
{
sel.set(R1, R2+1);
sel.clear(S1, S2+1);
- }
-
- BitSet newRange = sel.get(lo, hi+1);
- newRange.xor(oldRange);
+ }
int beg = sel.nextSetBit(0), end = -1;
for(int i=beg; i >= 0; i=sel.nextSetBit(i+1))
@@ -278,6 +291,27 @@ public class DefaultListSelectionModel implements Cloneable,
}
/**
+ * Moves the lead selection index to <code>leadIndex</code> without
+ * changing the selection values.
+ *
+ * If leadAnchorNotificationEnabled is true, send a notification covering the
+ * old and new lead cells.
+ *
+ * @param leadIndex the new lead selection index
+ * @since 1.5
+ */
+ public void moveLeadSelectionIndex (int leadIndex)
+ {
+ if (leadSelectionIndex == leadIndex)
+ return;
+
+ leadSelectionIndex = leadIndex;
+ if (isLeadAnchorNotificationEnabled())
+ fireValueChanged(Math.min(leadSelectionIndex, leadIndex),
+ Math.max(leadSelectionIndex, leadIndex));
+ }
+
+ /**
* Gets the value of the {@link #leadAnchorNotificationEnabled} property.
*
* @return The current property value
@@ -388,6 +422,9 @@ public class DefaultListSelectionModel implements Cloneable,
*/
public boolean isSelectedIndex(int a)
{
+ // TODO: Probably throw an exception here?
+ if (a >= sel.length() || a < 0)
+ return false;
return sel.get(a);
}
@@ -415,7 +452,7 @@ public class DefaultListSelectionModel implements Cloneable,
oldSel = sel.clone();
if (selectionMode == SINGLE_SELECTION)
- sel.clear();
+ setSelectionInterval(index0, index1);
// COMPAT: Like Sun (but not like IBM), we allow calls to
// addSelectionInterval when selectionMode is
@@ -426,10 +463,7 @@ public class DefaultListSelectionModel implements Cloneable,
isSelectedIndex(index1) ||
isSelectedIndex(Math.max(lo-1,0)) ||
isSelectedIndex(Math.min(hi+1,sel.size()))))
- sel.clear();
-
- if (selectionMode == SINGLE_SELECTION)
- index0 = index1;
+ sel.clear();
// We have to update the anchorSelectionIndex and leadSelectionIndex
// variables
diff --git a/javax/swing/DesktopManager.java b/javax/swing/DesktopManager.java
index 300d66517..620c7ffb8 100644
--- a/javax/swing/DesktopManager.java
+++ b/javax/swing/DesktopManager.java
@@ -95,7 +95,7 @@ public interface DesktopManager
* This method should give focus to the JInternalFrame and its default focus
* owner.
*
- * @param frame The JInternalFrame to activate.
+ * @param vframe The JInternalFrame to activate.
*/
void activateFrame(JInternalFrame vframe);
diff --git a/javax/swing/FocusManager.java b/javax/swing/FocusManager.java
index 179fa6f82..a2109ee06 100644
--- a/javax/swing/FocusManager.java
+++ b/javax/swing/FocusManager.java
@@ -38,10 +38,19 @@ exception statement from your version. */
package javax.swing;
+import java.awt.AWTEvent;
import java.awt.Component;
+import java.awt.Container;
import java.awt.DefaultKeyboardFocusManager;
+import java.awt.FocusTraversalPolicy;
+import java.awt.KeyEventDispatcher;
+import java.awt.KeyEventPostProcessor;
import java.awt.KeyboardFocusManager;
+import java.awt.Window;
import java.awt.event.KeyEvent;
+import java.beans.PropertyChangeListener;
+import java.beans.VetoableChangeListener;
+import java.util.Set;
/**
* This class has been obsoleted by the new
@@ -54,46 +63,409 @@ public abstract class FocusManager
extends DefaultKeyboardFocusManager
{
/**
- * DisabledFocusManager
+ * A FocusManager that wraps an AWT KeyboardFocusManager and forwards all
+ * method calls to it. This is used for compatibility with the new focus
+ * system.
+ *
+ * @author Roman Kennke (kennke@aicas.com)
*/
- static class DisabledFocusManager
+ private static class WrappingFocusManager
extends FocusManager
{
+ /**
+ * The wrapped KeyboardFocusManager.
+ */
+ private KeyboardFocusManager wrapped;
+
+ /**
+ * Creates a new instance of WrappedFocusManager.
+ *
+ * @param fm the focus manager to wrap
+ */
+ WrappingFocusManager(KeyboardFocusManager fm)
+ {
+ wrapped = fm;
+ }
+
+ /**
+ * Wraps {@link DefaultKeyboardFocusManager#dispatchEvent(AWTEvent)}.
+ *
+ * @param ev the event to dispatch
+ *
+ * @return <code>true</code> if the event has been dispatched,
+ * <code>false</code> otherwise
+ */
+ public boolean dispatchEvent(AWTEvent ev)
+ {
+ return wrapped.dispatchEvent(ev);
+ }
+
+ /**
+ * Wraps {@link DefaultKeyboardFocusManager#dispatchKeyEvent(KeyEvent)}.
+ *
+ * @param ev the event to dispatch
+ *
+ * @return <code>true</code> if the event has been dispatched,
+ * <code>false</code> otherwise
+ */
+ public boolean dispatchKeyEvent(KeyEvent ev)
+ {
+ return wrapped.dispatchKeyEvent(ev);
+ }
+
+ /**
+ * Wraps {@link DefaultKeyboardFocusManager#downFocusCycle(Container)}.
+ *
+ * @param c the container
+ */
+ public void downFocusCycle(Container c)
+ {
+ wrapped.downFocusCycle(c);
+ }
+
+ /**
+ * Wraps {@link DefaultKeyboardFocusManager#upFocusCycle(Container)}.
+ *
+ * @param c the container
+ */
+ public void upFocusCycle(Container c)
+ {
+ wrapped.upFocusCycle(c);
+ }
+
+ /**
+ * Wraps {@link DefaultKeyboardFocusManager#focusNextComponent(Component)}.
+ *
+ * @param c the component
+ */
+ public void focusNextComponent(Component c)
+ {
+ wrapped.focusNextComponent(c);
+ }
+
+ /**
+ * Wraps
+ * {@link DefaultKeyboardFocusManager#focusPreviousComponent(Component)}.
+ *
+ * @param c the component
+ */
+ public void focusPreviousComponent(Component c)
+ {
+ wrapped.focusPreviousComponent(c);
+ }
+
+ /**
+ * Wraps {@link DefaultKeyboardFocusManager#postProcessKeyEvent(KeyEvent)}.
+ *
+ * @param e the key event
+ *
+ * @return a boolead
+ */
+ public boolean postProcessKeyEvent(KeyEvent e)
+ {
+ return wrapped.postProcessKeyEvent(e);
+ }
+
+ /**
+ * Wraps
+ * {@link DefaultKeyboardFocusManager#processKeyEvent(Component, KeyEvent)}.
+ *
+ * @param c the component
+ * @param e the key event
+ */
+ public void processKeyEvent(Component c, KeyEvent e)
+ {
+ wrapped.processKeyEvent(c, e);
+ }
+
+ /**
+ * Wraps
+ * {@link KeyboardFocusManager#addKeyEventDispatcher(KeyEventDispatcher)}.
+ *
+ * @param d the dispatcher
+ */
+ public void addKeyEventDispatcher(KeyEventDispatcher d)
+ {
+ wrapped.addKeyEventDispatcher(d);
+ }
+
+ /**
+ * Wraps
+ * {@link KeyboardFocusManager#addKeyEventPostProcessor(KeyEventPostProcessor)}.
+ *
+ * @param p the post processor
+ */
+ public void addKeyEventPostProcessor(KeyEventPostProcessor p)
+ {
+ wrapped.addKeyEventPostProcessor(p);
+ }
+
+ /**
+ * Wraps {@link KeyboardFocusManager#addPropertyChangeListener(PropertyChangeListener)}.
+ *
+ * @param l the property change listener
+ */
+ public void addPropertyChangeListener(PropertyChangeListener l)
+ {
+ wrapped.addPropertyChangeListener(l);
+ }
+
+ /**
+ * Wraps {@link KeyboardFocusManager#addPropertyChangeListener(String, PropertyChangeListener)}.
+ *
+ * @param p the property name
+ * @param l the property change listener
+ */
+ public void addPropertyChangeListener(String p, PropertyChangeListener l)
+ {
+ wrapped.addPropertyChangeListener(p, l);
+ }
+
+ /**
+ * Wraps {@link KeyboardFocusManager#addVetoableChangeListener(String, VetoableChangeListener)}.
+ *
+ * @param p the property name
+ * @param l the vetoable change listener
+ */
+ public void addVetoableChangeListener(String p, VetoableChangeListener l)
+ {
+ wrapped.addVetoableChangeListener(p, l);
+ }
+
+ /**
+ * Wraps {@link KeyboardFocusManager#addVetoableChangeListener(VetoableChangeListener)}.
+ *
+ * @param l the vetoable change listener
+ */
+ public void addVetoableChangeListener(VetoableChangeListener l)
+ {
+ wrapped.addVetoableChangeListener(l);
+ }
+
+ /**
+ * Wraps {@link KeyboardFocusManager#clearGlobalFocusOwner()}.
+ */
+ public void clearGlobalFocusOwner()
+ {
+ wrapped.clearGlobalFocusOwner();
+ }
+
+ /**
+ * Wraps {@link KeyboardFocusManager#getActiveWindow()}.
+ *
+ * @return the active window
+ */
+ public Window getActiveWindow()
+ {
+ return wrapped.getActiveWindow();
+ }
+
+ /**
+ * Wraps {@link KeyboardFocusManager#getCurrentFocusCycleRoot()}.
+ *
+ * @return the focus cycle root
+ */
+ public Container getCurrentFocusCycleRoot()
+ {
+ return wrapped.getCurrentFocusCycleRoot();
+ }
+
+ /**
+ * Wraps {@link KeyboardFocusManager#getDefaultFocusTraversalKeys(int)}.
+ *
+ * @param i the ID
+ *
+ * @return the focus traversal keys
+ */
+ public Set getDefaultFocusTraversalKeys(int i)
+ {
+ return wrapped.getDefaultFocusTraversalKeys(i);
+ }
+
+ /**
+ * Wraps {@link KeyboardFocusManager#getDefaultFocusTraversalPolicy()}.
+ *
+ * @return the focus traversal policy
+ */
+ public FocusTraversalPolicy getDefaultFocusTraversalPolicy()
+ {
+ return wrapped.getDefaultFocusTraversalPolicy();
+ }
+
+ /**
+ * Wraps {@link KeyboardFocusManager#getFocusedWindow()}.
+ *
+ * @return the focused window
+ */
+ public Window getFocusedWindow()
+ {
+ return wrapped.getFocusedWindow();
+ }
+
+ /**
+ * Wraps {@link KeyboardFocusManager#getFocusOwner()}.
+ *
+ * @return the focus owner
+ */
+ public Component getFocusOwner()
+ {
+ return wrapped.getFocusOwner();
+ }
+
+ /**
+ * Wraps {@link KeyboardFocusManager#getPermanentFocusOwner()}.
+ *
+ * @return the focus owner
+ */
+ public Component getPermanentFocusOwner()
+ {
+ return wrapped.getPermanentFocusOwner();
+ }
+
+ /**
+ * Wraps {@link KeyboardFocusManager#getPropertyChangeListeners()}.
+ *
+ * @return the property change listeners
+ */
+ public PropertyChangeListener[] getPropertyChangeListeners()
+ {
+ return wrapped.getPropertyChangeListeners();
+ }
+
+ /**
+ * Wraps {@link KeyboardFocusManager#getPropertyChangeListeners(String)}.
+ *
+ * @param n the property name
+ *
+ * @return the property change listeners
+ */
+ public PropertyChangeListener[] getPropertyChangeListeners(String n)
+ {
+ return wrapped.getPropertyChangeListeners(n);
+ }
+
+ /**
+ * Wraps {@link KeyboardFocusManager#getVetoableChangeListeners()}.
+ *
+ * @return the vetoable change listeners
+ */
+ public VetoableChangeListener[] getVetoableChangeListeners()
+ {
+ return wrapped.getVetoableChangeListeners();
+ }
+
+ /**
+ * Wraps {@link KeyboardFocusManager#getVetoableChangeListeners(String)}.
+ *
+ * @param n the property name
+ *
+ * @return the vetoable change listeners
+ */
+ public VetoableChangeListener[] getVetoableChangeListeners(String n)
+ {
+ return wrapped.getVetoableChangeListeners(n);
+ }
+
+
+ /**
+ * Wraps
+ * {@link KeyboardFocusManager#removeKeyEventDispatcher(KeyEventDispatcher)}.
+ *
+ * @param d the key event dispatcher to remove
+ */
+ public void removeKeyEventDispatcher(KeyEventDispatcher d)
+ {
+ wrapped.removeKeyEventDispatcher(d);
+ }
+
+ /**
+ * Wraps
+ * {@link KeyboardFocusManager#removeKeyEventPostProcessor(KeyEventPostProcessor)}.
+ *
+ * @param p the post processor
+ */
+ public void removeKeyEventPostProcessor(KeyEventPostProcessor p)
+ {
+ wrapped.removeKeyEventPostProcessor(p);
+ }
+
+ /**
+ * Wraps
+ * {@link KeyboardFocusManager#removePropertyChangeListener(PropertyChangeListener)}.
+ *
+ * @param l the listener
+ */
+ public void removePropertyChangeListener(PropertyChangeListener l)
+ {
+ wrapped.removePropertyChangeListener(l);
+ }
+
+ /**
+ * Wraps
+ * {@link KeyboardFocusManager#removePropertyChangeListener(String, PropertyChangeListener)}.
+ *
+ * @param n the property name
+ * @param l the listener
+ */
+ public void removePropertyChangeListener(String n, PropertyChangeListener l)
+ {
+ wrapped.removePropertyChangeListener(n, l);
+ }
+
+ /**
+ * Wraps
+ * {@link KeyboardFocusManager#removeVetoableChangeListener(VetoableChangeListener)}.
+ *
+ * @param l the listener
+ */
+ public void removeVetoableChangeListener(VetoableChangeListener l)
+ {
+ wrapped.removeVetoableChangeListener(l);
+ }
/**
- * Constructor DisabledFocusManager
+ * Wraps
+ * {@link KeyboardFocusManager#removeVetoableChangeListener(String, VetoableChangeListener)}.
+ *
+ * @param n the property name
+ * @param l the listener
*/
- DisabledFocusManager()
+ public void removeVetoableChangeListener(String n, VetoableChangeListener l)
{
- // TODO
+ wrapped.removeVetoableChangeListener(n, l);
}
/**
- * processKeyEvent
- * @param component TODO
- * @param event TODO
+ * Wraps
+ * {@link KeyboardFocusManager#setDefaultFocusTraversalKeys(int, Set)}.
+ *
+ * @param id the ID
+ * @param k the keystrokes
*/
- public void processKeyEvent(Component component, KeyEvent event)
+ public void setDefaultFocusTraversalKeys(int id, Set k)
{
- // TODO
+ wrapped.setDefaultFocusTraversalKeys(id, k);
}
/**
- * focusNextComponent
- * @param component TODO
+ * Wraps {@link KeyboardFocusManager#setDefaultFocusTraversalPolicy(FocusTraversalPolicy)}.
+ *
+ * @param p the focus traversal policy
*/
- public void focusNextComponent(Component component)
+ public void setDefaultFocusTraversalPolicy(FocusTraversalPolicy p)
{
- // TODO
+ wrapped.setDefaultFocusTraversalPolicy(p);
}
/**
- * focusPreviousComponent
- * @param value0 TODO
+ * Wraps
+ * {@link KeyboardFocusManager#setGlobalCurrentFocusCycleRoot(Container)}.
+ *
+ * @param r the focus cycle root
*/
- public void focusPreviousComponent(Component value0)
+ public void setGlobalCurrentFocusCycleRoot(Container r)
{
- // TODO
+ wrapped.setGlobalCurrentFocusCycleRoot(r);
}
}
@@ -117,20 +489,9 @@ public abstract class FocusManager
*/
public static FocusManager getCurrentManager()
{
- KeyboardFocusManager fm =
- KeyboardFocusManager.getCurrentKeyboardFocusManager();
- if (fm instanceof FocusManager)
- return (FocusManager) fm;
- else
- {
- System.err.println("The Swing FocusManager API has been obsoleted by");
- System.err.println("the new KeyboardFocusManager system.");
- System.err.println("You should either not use the Swing FocusManager");
- System.err.println("API or set the system property");
- System.err.println
- ("gnu.java.awt.FocusManager=javax.swing.FocusManager");
- }
- return null;
+ KeyboardFocusManager m =
+ KeyboardFocusManager.getCurrentKeyboardFocusManager();
+ return new WrappingFocusManager(m);
}
/**
diff --git a/javax/swing/ImageIcon.java b/javax/swing/ImageIcon.java
index b650cd81f..b6ed949d8 100644
--- a/javax/swing/ImageIcon.java
+++ b/javax/swing/ImageIcon.java
@@ -73,6 +73,7 @@ public class ImageIcon
*/
protected AccessibleImageIcon()
{
+ // Nothing to do here.
}
/**
@@ -204,7 +205,10 @@ public class ImageIcon
private static final long serialVersionUID = 532615968316031794L;
/** A dummy Component that is used in the MediaTracker. */
- protected static Component component = new Component(){};
+ protected static Component component = new Component()
+ {
+ // No need to implement this.
+ };
/** The MediaTracker used to monitor the loading of images. */
protected static MediaTracker tracker = new MediaTracker(component);
@@ -227,6 +231,7 @@ public class ImageIcon
*/
public ImageIcon()
{
+ // Nothing to do here.
}
/**
@@ -417,7 +422,7 @@ public class ImageIcon
}
catch (InterruptedException ex)
{
- ; // ignore this for now
+ // Ignore this for now.
}
finally
{
diff --git a/javax/swing/InputVerifier.java b/javax/swing/InputVerifier.java
index 8e02ab813..eeb81b5d5 100644
--- a/javax/swing/InputVerifier.java
+++ b/javax/swing/InputVerifier.java
@@ -53,6 +53,7 @@ public abstract class InputVerifier
*/
public InputVerifier()
{
+ // Nothing to do here.
}
/**
diff --git a/javax/swing/JApplet.java b/javax/swing/JApplet.java
index aa3fcf4e2..22bbe92bf 100644
--- a/javax/swing/JApplet.java
+++ b/javax/swing/JApplet.java
@@ -73,6 +73,11 @@ public class JApplet extends Applet
}
}
+ /**
+ * The accessible context for this <code>JApplet</code>.
+ */
+ protected AccessibleContext accessibleContext;
+
private static final long serialVersionUID = 7269359214497372587L;
protected JRootPane rootPane;
@@ -89,11 +94,6 @@ public class JApplet extends Applet
*/
private boolean initStageDone = false;
- /**
- * The accessible context for this <code>JApplet</code>.
- */
- AccessibleContext accessibleContext;
-
public JApplet()
{
super.setLayout(new BorderLayout(1, 1));
diff --git a/javax/swing/JButton.java b/javax/swing/JButton.java
index 5653fbf42..ff0ecfccf 100644
--- a/javax/swing/JButton.java
+++ b/javax/swing/JButton.java
@@ -75,9 +75,6 @@ public class JButton extends AbstractButton
boolean def;
boolean is_def;
- /** The AccessibleContext for this JButton. */
- AccessibleJButton accessibleContext;
-
public JButton()
{
this(null, null);
@@ -166,6 +163,10 @@ public class JButton extends AbstractButton
*/
public void removeNotify()
{
+ JRootPane root = SwingUtilities.getRootPane(this);
+ if (root != null && root.getDefaultButton() == this)
+ root.setDefaultButton(null);
+ super.removeNotify();
}
public void setDefaultCapable(boolean defaultCapable)
diff --git a/javax/swing/JCheckBox.java b/javax/swing/JCheckBox.java
index f493782b2..74fda8f6d 100644
--- a/javax/swing/JCheckBox.java
+++ b/javax/swing/JCheckBox.java
@@ -97,50 +97,44 @@ public class JCheckBox extends JToggleButton implements Accessible
public JCheckBox()
{
- super();
- init();
+ this(null, null, false);
}
public JCheckBox(Action action)
{
super(action);
- init();
}
public JCheckBox(Icon icon)
{
- super(icon);
- init();
+ this(null, icon, false);
}
public JCheckBox(Icon icon, boolean selected)
{
- super(icon, selected);
- init();
+ this(null, icon, selected);
}
public JCheckBox(String text)
{
- super(text);
- init();
+ this(text, null, false);
}
public JCheckBox(String text, boolean selected)
{
- super(text, selected);
- init();
+ this(text, null, selected);
}
public JCheckBox(String text, Icon icon)
{
- super(text, icon);
- init();
+ this(text, icon, false);
}
public JCheckBox(String text, Icon icon, boolean selected)
{
super(text, icon, selected);
- init();
+ setHorizontalAlignment(LEADING);
+ setBorderPainted(false);
}
/**
diff --git a/javax/swing/JCheckBoxMenuItem.java b/javax/swing/JCheckBoxMenuItem.java
index f9dd56500..815244259 100644
--- a/javax/swing/JCheckBoxMenuItem.java
+++ b/javax/swing/JCheckBoxMenuItem.java
@@ -38,9 +38,6 @@ exception statement from your version. */
package javax.swing;
-import java.io.IOException;
-import java.io.ObjectOutputStream;
-
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
@@ -48,8 +45,9 @@ import javax.accessibility.AccessibleRole;
/**
* A menu item that displays a checkbox. Its behaviour is very similar
* to {@link JCheckBox}. Just like the <code>JCheckBox</code>, user can check
- * and uncheck this menu item by clicking on it. Also {@link #setSelected()}
- * and {@link #setState()} can be use used for the same purpose.
+ * and uncheck this menu item by clicking on it. Also
+ * {@link AbstractButton#setSelected} and {@link #setState} can be use used
+ * for the same purpose.
* <code>JCheckBoxMenuItem</code> uses
* <code>ToggleButtonModel</code> to keep track of its selection.
*
@@ -152,10 +150,6 @@ public class JCheckBoxMenuItem extends JMenuItem implements SwingConstants,
this.setVisible(true);
}
- private void writeObject(ObjectOutputStream stream) throws IOException
- {
- }
-
/**
* This method returns a name to identify which look and feel class will be
* the UI delegate for the menuItem.
@@ -248,6 +242,7 @@ public class JCheckBoxMenuItem extends JMenuItem implements SwingConstants,
*/
protected AccessibleJCheckBoxMenuItem()
{
+ // Nothing to do here.
}
public AccessibleRole getAccessibleRole()
diff --git a/javax/swing/JColorChooser.java b/javax/swing/JColorChooser.java
index 4016b82f3..a9650ffb7 100644
--- a/javax/swing/JColorChooser.java
+++ b/javax/swing/JColorChooser.java
@@ -87,6 +87,7 @@ public class JColorChooser extends JComponent implements Accessible
*/
protected AccessibleJColorChooser()
{
+ // Nothing to do here.
}
/**
@@ -247,6 +248,7 @@ public class JColorChooser extends JComponent implements Accessible
}
catch (InterruptedException e)
{
+ // TODO: Should this be handled?
}
}
diff --git a/javax/swing/JComboBox.java b/javax/swing/JComboBox.java
index 07e149e7e..cd30840a6 100644
--- a/javax/swing/JComboBox.java
+++ b/javax/swing/JComboBox.java
@@ -46,8 +46,6 @@ import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
-import java.io.IOException;
-import java.io.ObjectOutputStream;
import java.util.Vector;
import javax.accessibility.Accessible;
@@ -58,6 +56,7 @@ import javax.accessibility.AccessibleSelection;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.event.PopupMenuListener;
+import javax.swing.event.PopupMenuEvent;
import javax.swing.plaf.ComboBoxUI;
/**
@@ -212,10 +211,6 @@ public class JComboBox extends JComponent implements ItemSelectable,
this(new DefaultComboBoxModel());
}
- private void writeObject(ObjectOutputStream stream) throws IOException
- {
- }
-
/**
* This method returns true JComboBox is editable and false otherwise
*
@@ -310,7 +305,8 @@ public class JComboBox extends JComponent implements ItemSelectable,
// Stores old data model for event notification.
ComboBoxModel oldDataModel = dataModel;
dataModel = newDataModel;
-
+ selectedItemReminder = newDataModel.getSelectedItem();
+
// Notifies the listeners of the model change.
firePropertyChange("model", oldDataModel, dataModel);
}
@@ -843,6 +839,47 @@ public class JComboBox extends JComponent implements ItemSelectable,
}
/**
+ * Fires a popupMenuCanceled() event to all <code>PopupMenuListeners</code>.
+ *
+ * Note: This method is intended for use by plaf classes only.
+ */
+ public void firePopupMenuCanceled()
+ {
+ PopupMenuListener[] listeners = getPopupMenuListeners();
+ PopupMenuEvent e = new PopupMenuEvent(this);
+ for(int i = 0; i < listeners.length; i++)
+ listeners[i].popupMenuCanceled(e);
+ }
+
+ /**
+ * Fires a popupMenuWillBecomeInvisible() event to all
+ * <code>PopupMenuListeners</code>.
+ *
+ * Note: This method is intended for use by plaf classes only.
+ */
+ public void firePopupMenuWillBecomeInvisible()
+ {
+ PopupMenuListener[] listeners = getPopupMenuListeners();
+ PopupMenuEvent e = new PopupMenuEvent(this);
+ for(int i = 0; i < listeners.length; i++)
+ listeners[i].popupMenuWillBecomeInvisible(e);
+ }
+
+ /**
+ * Fires a popupMenuWillBecomeVisible() event to all
+ * <code>PopupMenuListeners</code>.
+ *
+ * Note: This method is intended for use by plaf classes only.
+ */
+ public void firePopupMenuWillBecomeVisible()
+ {
+ PopupMenuListener[] listeners = getPopupMenuListeners();
+ PopupMenuEvent e = new PopupMenuEvent(this);
+ for(int i = 0; i < listeners.length; i++)
+ listeners[i].popupMenuWillBecomeVisible(e);
+ }
+
+ /**
* This method is invoked whenever selected item changes in the combo box's
* data model. It fires ItemEvent and ActionEvent to all registered
* ComboBox's ItemListeners and ActionListeners respectively, indicating
@@ -859,8 +896,9 @@ public class JComboBox extends JComponent implements ItemSelectable,
// Fire ItemEvent to indicate that new item is selected
Object newSelection = getSelectedItem();
- fireItemStateChanged(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED,
- newSelection, ItemEvent.SELECTED));
+ if (newSelection != null)
+ fireItemStateChanged(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED,
+ newSelection, ItemEvent.SELECTED));
// Fire Action Event to JComboBox's registered listeners
fireActionEvent();
@@ -984,19 +1022,19 @@ public class JComboBox extends JComponent implements ItemSelectable,
*/
public void processKeyEvent(KeyEvent e)
{
- }
-
- /**
- * This method always returns false to indicate that JComboBox itself is
- * not focus traversable.
- *
- * @return false to indicate that JComboBox itself is not focus traversable.
- *
- * @deprecated
- */
- public boolean isFocusTraversable()
- {
- return false;
+ if (e.getKeyCode() == KeyEvent.VK_TAB)
+ setPopupVisible(false);
+ else if (keySelectionManager != null)
+ {
+ int i = keySelectionManager.selectionForKey(e.getKeyChar(),
+ getModel());
+ if (i >= 0)
+ setSelectedIndex(i);
+ else
+ super.processKeyEvent(e);
+ }
+ else
+ super.processKeyEvent(e);
}
/**
@@ -1006,6 +1044,7 @@ public class JComboBox extends JComponent implements ItemSelectable,
*/
public void setKeySelectionManager(KeySelectionManager aManager)
{
+ keySelectionManager = aManager;
}
/**
@@ -1170,6 +1209,7 @@ public class JComboBox extends JComponent implements ItemSelectable,
protected AccessibleJComboBox()
{
+ // Nothing to do here.
}
public int getAccessibleChildrenCount()
@@ -1229,18 +1269,22 @@ public class JComboBox extends JComponent implements ItemSelectable,
public void addAccessibleSelection(int value0)
{
+ // TODO: Implement this properly.
}
public void removeAccessibleSelection(int value0)
{
+ // TODO: Implement this properly.
}
public void clearAccessibleSelection()
{
+ // TODO: Implement this properly.
}
public void selectAllAccessibleSelection()
{
+ // TODO: Implement this properly.
}
}
}
diff --git a/javax/swing/JComponent.java b/javax/swing/JComponent.java
index b13f2d14c..80cfc5b32 100644
--- a/javax/swing/JComponent.java
+++ b/javax/swing/JComponent.java
@@ -44,6 +44,7 @@ import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
+import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.FocusTraversalPolicy;
import java.awt.Font;
@@ -53,6 +54,7 @@ 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;
@@ -64,7 +66,6 @@ import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.geom.Rectangle2D;
-import java.awt.image.ImageObserver;
import java.awt.peer.LightweightPeer;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
@@ -121,9 +122,18 @@ public abstract class JComponent extends Container implements Serializable
protected class AccessibleFocusHandler
implements FocusListener
{
- protected AccessibleFocusHandler(){}
- public void focusGained(FocusEvent event){}
- public void focusLost(FocusEvent valevent){}
+ protected AccessibleFocusHandler()
+ {
+ // TODO: Implement this properly.
+ }
+ public void focusGained(FocusEvent event)
+ {
+ // TODO: Implement this properly.
+ }
+ public void focusLost(FocusEvent valevent)
+ {
+ // TODO: Implement this properly.
+ }
}
/**
@@ -132,9 +142,18 @@ public abstract class JComponent extends Container implements Serializable
protected class AccessibleContainerHandler
implements ContainerListener
{
- protected AccessibleContainerHandler() {}
- public void componentAdded(ContainerEvent event) {}
- public void componentRemoved(ContainerEvent valevent) {}
+ protected AccessibleContainerHandler()
+ {
+ // TODO: Implement this properly.
+ }
+ public void componentAdded(ContainerEvent event)
+ {
+ // TODO: Implement this properly.
+ }
+ public void componentRemoved(ContainerEvent valevent)
+ {
+ // TODO: Implement this properly.
+ }
}
private static final long serialVersionUID = -7047089700479897799L;
@@ -142,12 +161,41 @@ public abstract class JComponent extends Container implements Serializable
protected ContainerListener accessibleContainerHandler;
protected FocusListener accessibleFocusHandler;
- protected AccessibleJComponent() {}
- public void addPropertyChangeListener(PropertyChangeListener listener) {}
- public void removePropertyChangeListener(PropertyChangeListener listener) {}
+ protected AccessibleJComponent()
+ {
+ // TODO: Implement this properly.
+ }
+
+ /**
+ * Adds a property change listener to the list of registered listeners.
+ *
+ * @param listener the listener to add
+ */
+ public void addPropertyChangeListener(PropertyChangeListener listener)
+ {
+ // TODO: Why is this overridden?
+ super.addPropertyChangeListener(listener);
+ }
+
+ public void removePropertyChangeListener(PropertyChangeListener listener)
+ {
+ // TODO: Implement this properly.
+ }
public int getAccessibleChildrenCount() { return 0; }
public Accessible getAccessibleChild(int value0) { return null; }
- public AccessibleStateSet getAccessibleStateSet() { return null; }
+
+ /**
+ * Returns the accessible state set of this component.
+ *
+ * @return the accessible state set of this component
+ */
+ public AccessibleStateSet getAccessibleStateSet()
+ {
+ // FIXME: Figure out which states should be set here, and which are
+ // inherited from the super class.
+ return super.getAccessibleStateSet();
+ }
+
public String getAccessibleName() { return null; }
public String getAccessibleDescription() { return null; }
public AccessibleRole getAccessibleRole() { return null; }
@@ -160,21 +208,21 @@ public abstract class JComponent extends Container implements Serializable
/**
* 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.
+ * 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.
+ * 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.
+ * ComponentUI#getMaximumSize} method on the {@link #ui} property.
*/
Dimension maximumSize;
@@ -219,14 +267,14 @@ public abstract class JComponent extends Container implements Serializable
* The text to show in the tooltip associated with this component.
*
* @see #setToolTipText
- * @see #getToolTipText
+ * @see #getToolTipText()
*/
String toolTipText;
/**
* <p>Whether to double buffer this component when painting. This flag
- * should generally be <code>false</code>, except for top level
- * components such as {@link JFrame} or {@link JApplet}.</p>
+ * 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
@@ -234,22 +282,21 @@ public abstract class JComponent extends Container implements Serializable
*
* @see #setDoubleBuffered
* @see #isDoubleBuffered
- * @see #paintLock
* @see #paint
*/
- boolean doubleBuffered = false;
+ 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}.
+ * {@link DebugGraphics#NONE_OPTION}, {@link DebugGraphics#LOG_OPTION},
+ * {@link DebugGraphics#FLASH_OPTION}, or {@link
+ * DebugGraphics#BUFFERED_OPTION}.
*
- * @see setDebugGraphicsOptions
- * @see getDebugGraphicsOptions
+ * @see #setDebugGraphicsOptions
+ * @see #getDebugGraphicsOptions
* @see DebugGraphics
- * @see getComponentGraphics
+ * @see #getComponentGraphics
*/
int debugGraphicsOptions;
@@ -299,7 +346,7 @@ public abstract class JComponent extends Container implements Serializable
* try to request focus, but the request might fail. Thus it is only
* a hint guiding swing's behavior.
*
- * @see #requestFocus
+ * @see #requestFocus()
* @see #isRequestFocusEnabled
* @see #setRequestFocusEnabled
*/
@@ -312,12 +359,18 @@ public abstract class JComponent extends Container implements Serializable
* 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
+ * @see #setAutoscrolls
+ * @see #getAutoscrolls
*/
boolean autoscrolls = false;
/**
+ * Indicates whether the current paint call is already double buffered or
+ * not.
+ */
+ static boolean isPaintingDoubleBuffered = false;
+
+ /**
* Listeners for events other than {@link PropertyChangeEvent} are
* handled by this listener list. PropertyChangeEvents are handled in
* {@link #changeSupport}.
@@ -350,16 +403,12 @@ public abstract class JComponent extends Container implements Serializable
private TransferHandler transferHandler;
- /**
- * A lock held during recursive painting; this is used to serialize
- * access to the double buffer, and also to select the "top level"
- * object which should acquire the double buffer in a given widget
- * tree (which may have multiple double buffered children).
- *
- * @see #doubleBuffered
- * @see #paint
+ /**
+ * 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 final Object paintLock = new Object();
+ private static transient Rectangle rectCache;
/**
* The default locale of the component.
@@ -404,6 +453,13 @@ public abstract class JComponent extends Container implements Serializable
public static final int WHEN_IN_FOCUSED_WINDOW = 2;
/**
+ * Indicates if this component is completely dirty or not. This is used
+ * by the RepaintManager's
+ * {@link RepaintManager#isCompletelyDirty(JComponent)} method.
+ */
+ boolean isCompletelyDirty = false;
+
+ /**
* Creates a new <code>JComponent</code> instance.
*/
public JComponent()
@@ -837,9 +893,13 @@ public abstract class JComponent extends Container implements Serializable
*/
public void setBorder(Border newBorder)
{
- Border oldBorder = border;
+ Border oldBorder = getBorder();
+ if (oldBorder == newBorder)
+ return;
+
border = newBorder;
firePropertyChange("border", oldBorder, newBorder);
+ repaint();
}
/**
@@ -890,10 +950,19 @@ public abstract class JComponent extends Container implements Serializable
* @see #paint
*/
protected Graphics getComponentGraphics(Graphics g)
- {
- g.setFont (this.getFont());
- g.setColor (this.getForeground());
- return g;
+ {
+ Graphics g2 = g;
+ int options = getDebugGraphicsOptions();
+ if (options != DebugGraphics.NONE_OPTION)
+ {
+ if (!(g2 instanceof DebugGraphics))
+ g2 = new DebugGraphics(g);
+ DebugGraphics dg = (DebugGraphics) g2;
+ dg.setDebugOptions(dg.getDebugOptions() | options);
+ }
+ g2.setFont(this.getFont());
+ g2.setColor(this.getForeground());
+ return g2;
}
/**
@@ -906,7 +975,19 @@ public abstract class JComponent extends Container implements Serializable
*/
public int getDebugGraphicsOptions()
{
- return 0;
+ String option = System.getProperty("gnu.javax.swing.DebugGraphics");
+ int options = debugGraphicsOptions;
+ if (option != null && option.length() != 0)
+ {
+ if (options < 0)
+ options = 0;
+
+ if (option.equals("LOG"))
+ options |= DebugGraphics.LOG_OPTION;
+ else if (option.equals("FLASH"))
+ options |= DebugGraphics.FLASH_OPTION;
+ }
+ return options;
}
/**
@@ -1303,6 +1384,7 @@ public abstract class JComponent extends Container implements Serializable
*/
public void grabFocus()
{
+ // TODO: Implement this properly.
}
/**
@@ -1411,16 +1493,6 @@ public abstract class JComponent extends Container implements Serializable
* RepaintManager}. Client code should usually call {@link #repaint()} to
* trigger painting.</p>
*
- * <p>This method will acquire a double buffer from the {@link
- * RepaintManager} if the component's {@link #doubleBuffered} property is
- * <code>true</code> and the <code>paint</code> call is the
- * <em>first</em> recursive <code>paint</code> call inside swing.</p>
- *
- * <p>The method will also modify the provided {@link Graphics} context
- * via the {@link #getComponentGraphics} method. If you want to customize
- * the graphics object used for painting, you should override that method
- * rather than <code>paint</code>.</p>
- *
* <p>The body of the <code>paint</code> call involves calling {@link
* #paintComponent}, {@link #paintBorder}, and {@link #paintChildren} in
* order. If you want to customize painting behavior, you should override
@@ -1436,32 +1508,29 @@ public abstract class JComponent extends Container implements Serializable
*/
public void paint(Graphics g)
{
- Graphics g2 = g;
- Image doubleBuffer = null;
RepaintManager rm = RepaintManager.currentManager(this);
-
- if (isDoubleBuffered()
- && (rm.isDoubleBufferingEnabled())
- && (! Thread.holdsLock(paintLock)))
- {
- doubleBuffer = rm.getOffscreenBuffer(this, getWidth(), getHeight());
- }
-
- synchronized (paintLock)
+ // We do a little stunt act here to switch on double buffering if it's
+ // not already on. If we are not already doublebuffered, then we jump
+ // into the method paintDoubleBuffered, which turns on the double buffer
+ // and then calls paint(g) again. In the second call we go into the else
+ // branch of this if statement and actually paint things to the double
+ // 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()
+ && rm.isDoubleBufferingEnabled())
+ paintDoubleBuffered(g);
+ else
{
- if (doubleBuffer != null)
- {
- g2 = doubleBuffer.getGraphics();
- g2.setClip(g.getClipBounds());
- }
-
- g2 = getComponentGraphics(g2);
- paintComponent(g2);
- paintBorder(g2);
- paintChildren(g2);
-
- if (doubleBuffer != null)
- g.drawImage(doubleBuffer, 0, 0, (ImageObserver) null);
+ if (g.getClip() == null)
+ g.setClip(0, 0, getWidth(), getHeight());
+ paintComponent(g);
+ paintBorder(g);
+ paintChildren(g);
+ Rectangle clip = g.getClipBounds();
+ if (clip.x == 0 && clip.y == 0 && clip.width == getWidth()
+ && clip.height == getHeight())
+ RepaintManager.currentManager(this).markCompletelyClean(this);
}
}
@@ -1500,7 +1569,39 @@ public abstract class JComponent extends Container implements Serializable
*/
protected void paintChildren(Graphics g)
{
- super.paint(g);
+ Shape originalClip = g.getClip();
+ Rectangle inner = SwingUtilities.calculateInnerArea(this, rectCache);
+ g.clipRect(inner.x, inner.y, inner.width, inner.height);
+ Component[] children = getComponents();
+ for (int i = children.length - 1; i >= 0; --i)
+ {
+ 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;
+ try
+ {
+ g.clipRect(bounds.x, bounds.y, bounds.width, bounds.height);
+ g.translate(bounds.x, bounds.y);
+ translated = true;
+ children[i].paint(g);
+ }
+ finally
+ {
+ if (translated)
+ g.translate(-bounds.x, -bounds.y);
+ g.setClip(oldClip);
+ }
+ }
+ g.setClip(originalClip);
}
/**
@@ -1549,24 +1650,93 @@ public abstract class JComponent extends Container implements Serializable
* that root pane. This method is called from the {@link RepaintManager}
* and should always be called within the painting thread.
*
+ * <p>This method will acquire a double buffer from the {@link
+ * RepaintManager} if the component's {@link #doubleBuffered} property is
+ * <code>true</code> and the <code>paint</code> call is the
+ * <em>first</em> recursive <code>paint</code> call inside swing.</p>
+ *
+ * <p>The method will also modify the provided {@link Graphics} context
+ * via the {@link #getComponentGraphics} method. If you want to customize
+ * the graphics object used for painting, you should override that method
+ * rather than <code>paint</code>.</p>
+ *
* @param r The dirty rectangle to paint
*/
public void paintImmediately(Rectangle r)
{
- Component root = SwingUtilities.getRoot(this);
- if (root == null || ! root.isShowing())
+ // 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;
- Graphics g = root.getGraphics();
- if (g == null)
+ if (root == null || !root.isShowing())
return;
- Rectangle clip = SwingUtilities.convertRectangle(this, r, root);
- g.setClip(clip);
- root.paint(g);
+ 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);
+ }
+
+ /**
+ * Performs the actual work of paintImmediatly on the repaint root.
+ *
+ * @param r the area to be repainted
+ */
+ void paintImmediately2(Rectangle r)
+ {
+ RepaintManager rm = RepaintManager.currentManager(this);
+ Graphics g = getGraphics();
+ g.setClip(r.x, r.y, r.width, r.height);
+ if (rm.isDoubleBufferingEnabled() && isDoubleBuffered())
+ paintDoubleBuffered(g);
+ else
+ paintSimple(g);
g.dispose();
}
/**
+ * Performs double buffered repainting.
+ *
+ * @param g the graphics context to paint to
+ */
+ void paintDoubleBuffered(Graphics g)
+ {
+
+ Rectangle r = g.getClipBounds();
+ if (r == null)
+ r = new Rectangle(0, 0, getWidth(), getHeight());
+ RepaintManager rm = RepaintManager.currentManager(this);
+
+ // Paint on the offscreen buffer.
+ Image buffer = rm.getOffscreenBuffer(this, getWidth(), getHeight());
+ Graphics g2 = buffer.getGraphics();
+ g2 = getComponentGraphics(g2);
+ g2.setClip(r.x, r.y, r.width, r.height);
+ isPaintingDoubleBuffered = true;
+ paint(g2);
+ isPaintingDoubleBuffered = false;
+ g2.dispose();
+
+ // Paint the buffer contents on screen.
+ g.drawImage(buffer, 0, 0, this);
+ }
+
+ /**
+ * Performs normal painting without double buffering.
+ *
+ * @param g the graphics context to use
+ */
+ void paintSimple(Graphics g)
+ {
+ Graphics g2 = getComponentGraphics(g);
+ paint(g2);
+ }
+
+ /**
* Return a string representation for this component, for use in
* debugging.
*
@@ -1802,6 +1972,7 @@ public abstract class JComponent extends Container implements Serializable
*/
protected void processComponentKeyEvent(KeyEvent e)
{
+ // This method does nothing, it is meant to be overridden by subclasses.
}
/**
@@ -1980,8 +2151,19 @@ public abstract class JComponent extends Container implements Serializable
*/
public void revalidate()
{
- invalidate();
- RepaintManager.currentManager(this).addInvalidComponent(this);
+ if (! EventQueue.isDispatchThread())
+ SwingUtilities.invokeLater(new Runnable()
+ {
+ public void run()
+ {
+ revalidate();
+ }
+ });
+ else
+ {
+ invalidate();
+ RepaintManager.currentManager(this).addInvalidComponent(this);
+ }
}
/**
@@ -2054,9 +2236,11 @@ public abstract class JComponent extends Container implements Serializable
*/
public void setEnabled(boolean enable)
{
- boolean oldEnabled = isEnabled();
+ if (enable == isEnabled())
+ return;
super.setEnabled(enable);
- firePropertyChange("enabled", oldEnabled, enable);
+ firePropertyChange("enabled", !enable, enable);
+ repaint();
}
/**
@@ -2066,7 +2250,11 @@ public abstract class JComponent extends Container implements Serializable
*/
public void setFont(Font f)
{
+ if (f == getFont())
+ return;
super.setFont(f);
+ revalidate();
+ repaint();
}
/**
@@ -2076,7 +2264,10 @@ public abstract class JComponent extends Container implements Serializable
*/
public void setBackground(Color bg)
{
+ if (bg == getBackground())
+ return;
super.setBackground(bg);
+ repaint();
}
/**
@@ -2086,7 +2277,10 @@ public abstract class JComponent extends Container implements Serializable
*/
public void setForeground(Color fg)
{
+ if (fg == getForeground())
+ return;
super.setForeground(fg);
+ repaint();
}
/**
@@ -2136,6 +2330,7 @@ public abstract class JComponent extends Container implements Serializable
*/
public void setNextFocusableComponent(Component aComponent)
{
+ // TODO: Implement this properly.
}
/**
@@ -2196,11 +2391,29 @@ public abstract class JComponent extends Container implements Serializable
/**
* Set the value of the visible property.
*
+ * If the value is changed, then the AncestorListeners of this component
+ * and all its children (recursivly) are notified.
+ *
* @param v The new value of the property
*/
public void setVisible(boolean v)
{
+ // No need to do anything if the actual value doesn't change.
+ if (isVisible() == v)
+ return;
+
super.setVisible(v);
+
+ // Notify AncestorListeners.
+ if (v == true)
+ fireAncestorEvent(this, AncestorEvent.ANCESTOR_ADDED);
+ else
+ fireAncestorEvent(this, AncestorEvent.ANCESTOR_REMOVED);
+
+ Container parent = getParent();
+ if (parent != null)
+ parent.repaint(getX(), getY(), getWidth(), getHeight());
+ revalidate();
}
/**
@@ -2253,7 +2466,8 @@ public abstract class JComponent extends Container implements Serializable
ui.installUI(this);
firePropertyChange("UI", oldUI, newUI);
-
+ revalidate();
+ repaint();
}
/**
@@ -2461,15 +2675,9 @@ public abstract class JComponent extends Container implements Serializable
parent = jParent.getParent();
}
-
- // notify ancestor listeners
- AncestorListener[] ls = getAncestorListeners();
- AncestorEvent ev = new AncestorEvent(this, AncestorEvent.ANCESTOR_ADDED,
- this, parent);
- for (int i = 0; i < ls.length; i++)
- {
- ls[i].ancestorAdded(ev);
- }
+
+ // Notify AncestorListeners.
+ fireAncestorEvent(this, AncestorEvent.ANCESTOR_ADDED);
// fire property change event for 'ancestor'
firePropertyChange("ancestor", null, parent);
@@ -2521,14 +2729,8 @@ public abstract class JComponent extends Container implements Serializable
parent = jParent.getParent();
}
- // notify ancestor listeners
- AncestorListener[] ls = getAncestorListeners();
- AncestorEvent ev = new AncestorEvent(this, AncestorEvent.ANCESTOR_ADDED,
- this, parent);
- for (int i = 0; i < ls.length; i++)
- {
- ls[i].ancestorAdded(ev);
- }
+ // Notify ancestor listeners.
+ fireAncestorEvent(this, AncestorEvent.ANCESTOR_REMOVED);
// fire property change event for 'ancestor'
firePropertyChange("ancestor", parent, null);
@@ -2738,6 +2940,184 @@ public abstract class JComponent extends Container implements Serializable
*/
public void reshape(int x, int y, int w, int h)
{
+ int oldX = getX();
+ int oldY = getY();
super.reshape(x, y, w, h);
+ // Notify AncestorListeners.
+ if (oldX != getX() || oldY != getY())
+ fireAncestorEvent(this, AncestorEvent.ANCESTOR_MOVED);
+ }
+
+ /**
+ * Fires an AncestorEvent to this component's and all of its child
+ * component's AncestorListeners.
+ *
+ * @param ancestor the component that triggered the event
+ * @param id the kind of ancestor event that should be fired
+ */
+ void fireAncestorEvent(JComponent ancestor, int id)
+ {
+ // Fire event for registered ancestor listeners of this component.
+ AncestorListener[] listeners = getAncestorListeners();
+ if (listeners.length > 0)
+ {
+ AncestorEvent ev = new AncestorEvent(this, id,
+ ancestor, ancestor.getParent());
+ for (int i = 0; i < listeners.length; i++)
+ {
+ switch (id)
+ {
+ case AncestorEvent.ANCESTOR_MOVED:
+ listeners[i].ancestorMoved(ev);
+ break;
+ case AncestorEvent.ANCESTOR_ADDED:
+ listeners[i].ancestorAdded(ev);
+ break;
+ case AncestorEvent.ANCESTOR_REMOVED:
+ listeners[i].ancestorRemoved(ev);
+ break;
+ }
+ }
+ }
+ // Dispatch event to all children.
+ Component[] children = getComponents();
+ for (int i = 0; i < children.length; i++)
+ {
+ if (!(children[i] instanceof JComponent))
+ continue;
+ JComponent jc = (JComponent) children[i];
+ jc.fireAncestorEvent(ancestor, id);
+ }
+ }
+
+ /**
+ * Finds a suitable paint root for painting this component. This method first
+ * checks if this component is overlapped using
+ * {@link #findOverlapFreeParent(Rectangle)}. The returned paint root is then
+ * feeded to {@link #findOpaqueParent(Component)} to find the nearest opaque
+ * component for this paint root. If no paint is necessary, then we return
+ * <code>null</code>.
+ *
+ * @param c the clip of this component
+ *
+ * @return the paint root or <code>null</code> if no painting is necessary
+ */
+ private Component findPaintRoot(Rectangle c)
+ {
+ Component p = findOverlapFreeParent(c);
+ if (p == null)
+ return null;
+ Component root = findOpaqueParent(p);
+ return root;
+ }
+
+ /**
+ * Scans the containment hierarchy upwards for components that overlap the
+ * this component in the specified clip. This method returns
+ * <code>this</code>, if no component overlaps this component. It returns
+ * <code>null</code> if another component completely covers this component
+ * in the specified clip (no repaint necessary). If another component partly
+ * overlaps this component in the specified clip, then the parent of this
+ * component is returned (this is the component that must be used as repaint
+ * root). For efficient lookup, the method
+ * {@link #isOptimizedDrawingEnabled()} is used.
+ *
+ * @param clip the clip of this component
+ *
+ * @return the paint root, or <code>null</code> if no paint is necessary
+ */
+ private Component findOverlapFreeParent(Rectangle clip)
+ {
+ Rectangle currentClip = clip;
+ Component found = this;
+ Container parent = this;
+ while (parent != null)
+ {
+ Container newParent = parent.getParent();
+ if (newParent == null)
+ break;
+ // If the parent is optimizedDrawingEnabled, then its children are
+ // tiled and cannot have an overlapping child. Go directly to next
+ // parent.
+ if (newParent instanceof JComponent
+ && ((JComponent) newParent).isOptimizedDrawingEnabled())
+ {
+ parent = newParent;
+ continue;
+ }
+
+ // First we must check if the new parent itself somehow clips the
+ // target rectangle. This can happen in JViewports.
+ Rectangle parRect = new Rectangle(0, 0, newParent.getWidth(),
+ newParent.getHeight());
+ Rectangle target = SwingUtilities.convertRectangle(found,
+ currentClip,
+ newParent);
+ if (target.contains(parRect) || target.intersects(parRect))
+ {
+ found = newParent;
+ currentClip = target;
+ parent = newParent;
+ continue;
+ }
+
+ // Otherwise we must check if one of the children of this parent
+ // overlaps with the current component.
+ Component[] children = newParent.getComponents();
+ // This flag is used to skip components that are 'below' the component
+ // in question.
+ boolean skip = true;
+ for (int i = children.length - 1; i >= 0; i--)
+ {
+ if (children[i] == parent)
+ skip = false;
+ if (skip)
+ continue;
+ Component c = children[i];
+ Rectangle compBounds = c.getBounds();
+ // If the component completely overlaps the clip in question, we
+ // don't need to repaint. Return null.
+ if (compBounds.contains(target))
+ return null;
+ if (compBounds.intersects(target))
+ {
+ // We found a parent whose children overlap with our current
+ // component. Make this the current component.
+ found = newParent;
+ currentClip = target;
+ break;
+ }
+ }
+ parent = newParent;
+ }
+ return found;
+ }
+
+ /**
+ * Finds the nearest component to <code>c</code> (upwards in the containment
+ * hierarchy), that is opaque. If <code>c</code> itself is opaque,
+ * this returns <code>c</code> itself.
+ *
+ * @param c the start component for the search
+ * @return the nearest component to <code>c</code> (upwards in the containment
+ * hierarchy), that is opaque; If <code>c</code> itself is opaque,
+ * this returns <code>c</code> itself
+ */
+ private Component findOpaqueParent(Component c)
+ {
+ Component found = c;
+ while (true)
+ {
+ if ((found instanceof JComponent) && ((JComponent) found).isOpaque())
+ break;
+ else if (!(found instanceof JComponent))
+ break;
+ Container p = found.getParent();
+ if (p == null)
+ break;
+ else
+ found = p;
+ }
+ return found;
}
}
diff --git a/javax/swing/JDesktopPane.java b/javax/swing/JDesktopPane.java
index f4c80eca7..43ab71e7e 100644
--- a/javax/swing/JDesktopPane.java
+++ b/javax/swing/JDesktopPane.java
@@ -97,6 +97,7 @@ public class JDesktopPane extends JLayeredPane implements Accessible
*/
protected AccessibleJDesktopPane()
{
+ // Nothing to do here.
}
/**
@@ -246,6 +247,7 @@ public class JDesktopPane extends JLayeredPane implements Accessible
}
catch (PropertyVetoException e)
{
+ // We do nothing when the attempt is vetoed.
}
}
selectedFrame = null;
@@ -259,6 +261,7 @@ public class JDesktopPane extends JLayeredPane implements Accessible
}
catch (PropertyVetoException e)
{
+ // We do nothing when the attempt is vetoed.
}
}
diff --git a/javax/swing/JEditorPane.java b/javax/swing/JEditorPane.java
index e2f1319a2..9ddf970de 100644
--- a/javax/swing/JEditorPane.java
+++ b/javax/swing/JEditorPane.java
@@ -41,15 +41,27 @@ package javax.swing;
import java.awt.Dimension;
import java.io.IOException;
import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.MalformedURLException;
import java.net.URL;
import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleHyperlink;
+import javax.accessibility.AccessibleHypertext;
+import javax.accessibility.AccessibleStateSet;
+import javax.accessibility.AccessibleText;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultEditorKit;
+import javax.swing.text.Document;
import javax.swing.text.EditorKit;
+import javax.swing.text.Element;
import javax.swing.text.JTextComponent;
+import javax.swing.text.html.HTML;
+import javax.swing.text.html.HTMLDocument;
+import javax.swing.text.html.HTMLEditorKit;
/**
* A powerful text editor component that can handle different types of
@@ -76,6 +88,384 @@ import javax.swing.text.JTextComponent;
*/
public class JEditorPane extends JTextComponent
{
+ /**
+ * Provides accessibility support for <code>JEditorPane</code>.
+ *
+ * @author Roman Kennke (kennke@aicas.com)
+ */
+ protected class AccessibleJEditorPane extends AccessibleJTextComponent
+ {
+
+ /**
+ * Creates a new <code>AccessibleJEditorPane</code> object.
+ */
+ protected AccessibleJEditorPane()
+ {
+ super();
+ }
+
+ /**
+ * Returns a description of this <code>AccessibleJEditorPane</code>. If
+ * this property is not set, then this returns the content-type of the
+ * editor pane.
+ *
+ * @return a description of this AccessibleJEditorPane
+ */
+ public String getAccessibleDescription()
+ {
+ String descr = super.getAccessibleDescription();
+ if (descr == null)
+ return getContentType();
+ else
+ return descr;
+ }
+
+ /**
+ * Returns the accessible state of this <code>AccessibleJEditorPane</code>.
+ *
+ * @return the accessible state of this <code>AccessibleJEditorPane</code>
+ */
+ public AccessibleStateSet getAccessibleStateSet()
+ {
+ AccessibleStateSet state = super.getAccessibleStateSet();
+ // TODO: Figure out what state must be added here to the super's state.
+ return state;
+ }
+ }
+
+ /**
+ * Provides accessibility support for <code>JEditorPane</code>s, when the
+ * editor kit is an instance of {@link HTMLEditorKit}.
+ *
+ * @author Roman Kennke (kennke@aicas.com)
+ */
+ protected class AccessibleJEditorPaneHTML extends AccessibleJEditorPane
+ {
+ /**
+ * Returns the accessible text of the <code>JEditorPane</code>. This will
+ * be an instance of
+ * {@link JEditorPaneAccessibleHypertextSupport}.
+ *
+ * @return the accessible text of the <code>JEditorPane</code>
+ */
+ public AccessibleText getAccessibleText()
+ {
+ return new JEditorPaneAccessibleHypertextSupport();
+ }
+ }
+
+ /**
+ * This is the accessible text that is returned by
+ * {@link AccessibleJEditorPaneHTML#getAccessibleText()}.
+ *
+ * @author Roman Kennke (kennke@aicas.com)
+ */
+ protected class JEditorPaneAccessibleHypertextSupport
+ extends AccessibleJEditorPane implements AccessibleHypertext
+ {
+
+ /**
+ * The accessible representation of a HTML link.
+ *
+ * @author Roman Kennke (kennke@aicas.com)
+ */
+ public class HTMLLink extends AccessibleHyperlink
+ {
+
+ /**
+ * The element in the document that represents the link.
+ */
+ Element element;
+
+ /**
+ * Creates a new <code>HTMLLink</code>.
+ *
+ * @param el the link element
+ */
+ public HTMLLink(Element el)
+ {
+ this.element = el;
+ }
+
+ /**
+ * Returns <code>true</code> if this <code>HTMLLink</code> is still
+ * valid. A <code>HTMLLink</code> can become invalid when the document
+ * changes.
+ *
+ * @return <code>true</code> if this <code>HTMLLink</code> is still
+ * valid
+ */
+ public boolean isValid()
+ {
+ // I test here if the element at our element's start offset is the
+ // same as the element in the document at this offset. If this is true,
+ // I consider the link valid, if not, then this link no longer
+ // represented by this HTMLLink and therefor invalid.
+ HTMLDocument doc = (HTMLDocument) getDocument();
+ return doc.getCharacterElement(element.getStartOffset()) == element;
+ }
+
+ /**
+ * Returns the number of AccessibleActions in this link object. In
+ * general, link have 1 AccessibleAction associated with them. There are
+ * special cases where links can have multiple actions associated, like
+ * in image maps.
+ *
+ * @return the number of AccessibleActions in this link object
+ */
+ public int getAccessibleActionCount()
+ {
+ // TODO: Implement the special cases.
+ return 1;
+ }
+
+ /**
+ * Performs the specified action on the link object. This ususally means
+ * activating the link.
+ *
+ * @return <code>true</code> if the action has been performed
+ * successfully, <code>false</code> otherwise
+ */
+ public boolean doAccessibleAction(int i)
+ {
+ String href = (String) element.getAttributes().getAttribute("href");
+ HTMLDocument doc = (HTMLDocument) getDocument();
+ try
+ {
+ URL url = new URL(doc.getBase(), href);
+ setPage(url);
+ String desc = doc.getText(element.getStartOffset(),
+ element.getEndOffset() - element.getStartOffset());
+ HyperlinkEvent ev =
+ new HyperlinkEvent(JEditorPane.this,
+ HyperlinkEvent.EventType.ACTIVATED, url, desc,
+ element);
+ fireHyperlinkUpdate(ev);
+ return true;
+ }
+ catch (Exception ex)
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Returns the description of the action at action index <code>i</code>.
+ * This method returns the text within the element associated with this
+ * link.
+ *
+ * @param i the action index
+ *
+ * @return the description of the action at action index <code>i</code>
+ */
+ public String getAccessibleActionDescription(int i)
+ {
+ HTMLDocument doc = (HTMLDocument) getDocument();
+ try
+ {
+ return doc.getText(element.getStartOffset(),
+ element.getEndOffset() - element.getStartOffset());
+ }
+ catch (BadLocationException ex)
+ {
+ throw (AssertionError)
+ new AssertionError("BadLocationException must not be thrown "
+ + "here.")
+ .initCause(ex);
+ }
+ }
+
+ /**
+ * Returns an {@link URL} object, that represents the action at action
+ * index <code>i</code>.
+ *
+ * @param i the action index
+ *
+ * @return an {@link URL} object, that represents the action at action
+ * index <code>i</code>
+ */
+ public Object getAccessibleActionObject(int i)
+ {
+ String href = (String) element.getAttributes().getAttribute("href");
+ HTMLDocument doc = (HTMLDocument) getDocument();
+ try
+ {
+ URL url = new URL(doc.getBase(), href);
+ return url;
+ }
+ catch (MalformedURLException ex)
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Returns an object that represents the link anchor. For examples, if
+ * the link encloses a string, then a <code>String</code> object is
+ * returned, if the link encloses an &lt;img&gt; tag, then an
+ * <code>ImageIcon</code> object is returned.
+ *
+ * @return an object that represents the link anchor
+ */
+ public Object getAccessibleActionAnchor(int i)
+ {
+ // TODO: This is only the String case. Implement all cases.
+ return getAccessibleActionDescription(i);
+ }
+
+ /**
+ * Returns the start index of the hyperlink element.
+ *
+ * @return the start index of the hyperlink element
+ */
+ public int getStartIndex()
+ {
+ return element.getStartOffset();
+ }
+
+ /**
+ * Returns the end index of the hyperlink element.
+ *
+ * @return the end index of the hyperlink element
+ */
+ public int getEndIndex()
+ {
+ return element.getEndOffset();
+ }
+
+ }
+
+ /**
+ * Returns the number of hyperlinks in the document.
+ *
+ * @return the number of hyperlinks in the document
+ */
+ public int getLinkCount()
+ {
+ HTMLDocument doc = (HTMLDocument) getDocument();
+ HTMLDocument.Iterator linkIter = doc.getIterator(HTML.Tag.A);
+ int count = 0;
+ while (linkIter.isValid())
+ {
+ count++;
+ linkIter.next();
+ }
+ return count;
+ }
+
+ /**
+ * Returns the <code>i</code>-th hyperlink in the document or
+ * <code>null</code> if there is no hyperlink with the specified index.
+ *
+ * @param i the index of the hyperlink to return
+ *
+ * @return the <code>i</code>-th hyperlink in the document or
+ * <code>null</code> if there is no hyperlink with the specified
+ * index
+ */
+ public AccessibleHyperlink getLink(int i)
+ {
+ HTMLDocument doc = (HTMLDocument) getDocument();
+ HTMLDocument.Iterator linkIter = doc.getIterator(HTML.Tag.A);
+ int count = 0;
+ while (linkIter.isValid())
+ {
+ count++;
+ if (count == i)
+ break;
+ linkIter.next();
+ }
+ if (linkIter.isValid())
+ {
+ int offset = linkIter.getStartOffset();
+ // TODO: I fetch the element for the link via getCharacterElement().
+ // I am not sure that this is correct, maybe we must use
+ // getParagraphElement()?
+ Element el = doc.getCharacterElement(offset);
+ HTMLLink link = new HTMLLink(el);
+ return link;
+ }
+ else
+ return null;
+ }
+
+ /**
+ * Returns the index of the link element at the character position
+ * <code>c</code> within the document, or <code>-1</code> if there is no
+ * link at the specified position.
+ *
+ * @param c the character index from which to fetch the link index
+ *
+ * @return the index of the link element at the character position
+ * <code>c</code> within the document, or <code>-1</code> if there
+ * is no link at the specified position
+ */
+ public int getLinkIndex(int c)
+ {
+ HTMLDocument doc = (HTMLDocument) getDocument();
+ HTMLDocument.Iterator linkIter = doc.getIterator(HTML.Tag.A);
+ int count = 0;
+ while (linkIter.isValid())
+ {
+ if (linkIter.getStartOffset() <= c && linkIter.getEndOffset() > c)
+ break;
+ count++;
+ linkIter.next();
+ }
+ if (linkIter.isValid())
+ return count;
+ else
+ return -1;
+ }
+
+ /**
+ * Returns the link text of the link at index <code>i</code>, or
+ * <code>null</code>, if there is no link at the specified position.
+ *
+ * @param i the index of the link
+ *
+ * @return the link text of the link at index <code>i</code>, or
+ * <code>null</code>, if there is no link at the specified
+ * position
+ */
+ public String getLinkText(int i)
+ {
+ HTMLDocument doc = (HTMLDocument) getDocument();
+ HTMLDocument.Iterator linkIter = doc.getIterator(HTML.Tag.A);
+ int count = 0;
+ while (linkIter.isValid())
+ {
+ count++;
+ if (count == i)
+ break;
+ linkIter.next();
+ }
+ if (linkIter.isValid())
+ {
+ int offset = linkIter.getStartOffset();
+ // TODO: I fetch the element for the link via getCharacterElement().
+ // I am not sure that this is correct, maybe we must use
+ // getParagraphElement()?
+ Element el = doc.getCharacterElement(offset);
+ try
+ {
+ String text = doc.getText(el.getStartOffset(),
+ el.getEndOffset() - el.getStartOffset());
+ return text;
+ }
+ catch (BadLocationException ex)
+ {
+ throw (AssertionError)
+ new AssertionError("BadLocationException must not be thrown "
+ + "here.")
+ .initCause(ex);
+ }
+ }
+ else
+ return null;
+ }
+ }
+
private static final long serialVersionUID = 3140472492599046285L;
private URL page;
@@ -128,9 +518,21 @@ public class JEditorPane extends JTextComponent
listeners[index].hyperlinkUpdate(event);
}
+ /**
+ * Returns the accessible context associated with this editor pane.
+ *
+ * @return the accessible context associated with this editor pane
+ */
public AccessibleContext getAccessibleContext()
{
- return null;
+ if (accessibleContext == null)
+ {
+ if (getEditorKit() instanceof HTMLEditorKit)
+ accessibleContext = new AccessibleJEditorPaneHTML();
+ else
+ accessibleContext = new AccessibleJEditorPane();
+ }
+ return accessibleContext;
}
public final String getContentType()
@@ -169,12 +571,18 @@ public class JEditorPane extends JTextComponent
public boolean getScrollableTracksViewportHeight()
{
- return false;
+ /* Container parent = getParent();
+ return (parent instanceof JViewport &&
+ parent.isValid());*/
+ return isValid();
}
public boolean getScrollableTracksViewportWidth()
{
- return false;
+ /*Container parent = getParent();
+ return (parent instanceof JViewport &&
+ parent.isValid());*/
+ return isValid();
}
public URL getPage()
@@ -211,9 +619,26 @@ public class JEditorPane extends JTextComponent
/**
* This method initializes from a stream.
*/
- public void read(InputStream in, Object desc)
- throws IOException
+ public void read(InputStream in, Object desc) throws IOException
{
+ EditorKit kit = getEditorKit();
+ if (kit instanceof HTMLEditorKit && desc instanceof HTMLDocument)
+ {
+ Document doc = (Document) desc;
+ try
+ {
+ kit.read(in, doc, 0);
+ }
+ catch (BadLocationException ex)
+ {
+ assert false : "BadLocationException must not be thrown here.";
+ }
+ }
+ else
+ {
+ Reader inRead = new InputStreamReader(in);
+ super.read(inRead, desc);
+ }
}
/**
@@ -222,6 +647,7 @@ public class JEditorPane extends JTextComponent
public static void registerEditorKitForContentType(String type,
String classname)
{
+ // TODO: Implement this properly.
}
/**
@@ -231,6 +657,7 @@ public class JEditorPane extends JTextComponent
String classname,
ClassLoader loader)
{
+ // TODO: Implement this properly.
}
/**
@@ -239,6 +666,7 @@ public class JEditorPane extends JTextComponent
*/
public void replaceSelection(String content)
{
+ // TODO: Implement this properly.
}
/**
@@ -247,6 +675,7 @@ public class JEditorPane extends JTextComponent
*/
public void scrollToReference(String reference)
{
+ // TODO: Implement this properly.
}
public final void setContentType(String type)
@@ -281,6 +710,8 @@ public class JEditorPane extends JTextComponent
firePropertyChange("editorKit", oldValue, newValue);
invalidate();
repaint();
+ // Reset the accessibleContext since this depends on the editorKit.
+ accessibleContext = null;
}
public void setEditorKitForContentType(String type, EditorKit k)
diff --git a/javax/swing/JFileChooser.java b/javax/swing/JFileChooser.java
index 0eb832848..1598641f1 100644
--- a/javax/swing/JFileChooser.java
+++ b/javax/swing/JFileChooser.java
@@ -42,10 +42,13 @@ import java.awt.Frame;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
+import java.beans.PropertyChangeEvent;
import java.io.File;
import java.util.ArrayList;
+
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
import javax.swing.JDialog;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileSystemView;
@@ -70,171 +73,324 @@ public class JFileChooser extends JComponent implements Accessible
{
private static final long serialVersionUID = 3162921138695327837L;
- /** DOCUMENT ME! */
+ /**
+ * A dialog type for selecting a file to open.
+ * @see #setDialogType(int)
+ */
public static final int OPEN_DIALOG = 0;
- /** DOCUMENT ME! */
+ /**
+ * A dialog type for selecting a file to save.
+ * @see #setDialogType(int)
+ */
public static final int SAVE_DIALOG = 1;
- /** DOCUMENT ME! */
+ /**
+ * A dialog type for some custom purpose.
+ * @see #setDialogType(int)
+ */
public static final int CUSTOM_DIALOG = 2;
- /** DOCUMENT ME! */
+ /**
+ * A return value indicating the file chooser has been closed by cancelling.
+ *
+ * @see #showOpenDialog(Component)
+ * @see #showSaveDialog(Component)
+ */
public static final int CANCEL_OPTION = 1;
- /** DOCUMENT ME! */
+ /**
+ * A return value indicating the file chooser has been closed by approving
+ * the selection.
+ * @see #showOpenDialog(Component)
+ * @see #showSaveDialog(Component)
+ */
public static final int APPROVE_OPTION = 0;
- /** DOCUMENT ME! */
+ /**
+ * A return value indicating the file chooser has been closed by some error.
+ * @see #showOpenDialog(Component)
+ * @see #showSaveDialog(Component)
+ */
public static final int ERROR_OPTION = -1;
- /** DOCUMENT ME! */
+ /**
+ * A selection mode constant indicating acceptance of files only.
+ * @see #setFileSelectionMode(int)
+ */
public static final int FILES_ONLY = 0;
- /** DOCUMENT ME! */
+ /**
+ * A selection mode constant indicating acceptance of directories only.
+ * @see #setFileSelectionMode(int)
+ */
public static final int DIRECTORIES_ONLY = 1;
- /** DOCUMENT ME! */
+ /**
+ * A selection mode constant indicating acceptance of files and directories.
+ * @see #setFileSelectionMode(int)
+ */
public static final int FILES_AND_DIRECTORIES = 2;
- /** DOCUMENT ME! */
+ /**
+ * Action command string for cancelling the current selection.
+ * @see #cancelSelection()
+ */
public static final String CANCEL_SELECTION = "CancelSelection";
- /** DOCUMENT ME! */
+ /**
+ * Action command string for approving the current selection.
+ * @see #cancelSelection()
+ */
public static final String APPROVE_SELECTION = "ApproveSelection";
- /** DOCUMENT ME! */
+ /**
+ * The name of the property for the approve button text.
+ * @see #setApproveButtonText(String)
+ */
public static final String APPROVE_BUTTON_TEXT_CHANGED_PROPERTY =
"ApproveButtonTextChangedProperty";
- /** DOCUMENT ME! */
+ /**
+ * The name of the property for the approve button tool tip text.
+ * @see #setApproveButtonToolTipText(String)
+ */
public static final String APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY =
"ApproveButtonToolTipTextChangedProperty";
- /** DOCUMENT ME! */
+ /**
+ * The name of the property for the approve button mnemonic.
+ * @see #setApproveButtonMnemonic(int)
+ */
public static final String APPROVE_BUTTON_MNEMONIC_CHANGED_PROPERTY =
"ApproveButtonMnemonicChangedProperty";
- /** DOCUMENT ME! */
+ /**
+ * The name of the property for control button visibility.
+ * @see #setControlButtonsAreShown(boolean)
+ */
public static final String CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY =
"ControlButtonsAreShownChangedProperty";
- /** DOCUMENT ME! */
+ /**
+ * The name of the property for the current directory.
+ * @see #setCurrentDirectory(File)
+ */
public static final String DIRECTORY_CHANGED_PROPERTY = "directoryChanged";
- /** DOCUMENT ME! */
+ /**
+ * The name of the property for the selected file.
+ * @see #setSelectedFile(File)
+ */
public static final String SELECTED_FILE_CHANGED_PROPERTY =
"SelectedFileChangedProperty";
- /** DOCUMENT ME! */
+ /**
+ * The name of the property for the selected files.
+ * @see #setSelectedFiles(File[])
+ */
public static final String SELECTED_FILES_CHANGED_PROPERTY =
"SelectedFilesChangedProperty";
- /** DOCUMENT ME! */
+ /**
+ * The name of the property for multi-selection.
+ * @see #setMultiSelectionEnabled(boolean)
+ */
public static final String MULTI_SELECTION_ENABLED_CHANGED_PROPERTY =
"MultiSelectionEnabledChangedProperty";
- /** DOCUMENT ME! */
+ /**
+ * The name of the 'file system view' property.
+ * @see #setFileSystemView(FileSystemView)
+ */
public static final String FILE_SYSTEM_VIEW_CHANGED_PROPERTY =
"FileSystemViewChanged";
- /** DOCUMENT ME! */
+ /**
+ * The name of the 'file view' property.
+ * @see #setFileView(FileView)
+ */
public static final String FILE_VIEW_CHANGED_PROPERTY = "fileViewChanged";
- /** DOCUMENT ME! */
+ /**
+ * The name of the 'file hiding enabled' property.
+ * @see #setFileHidingEnabled(boolean)
+ */
public static final String FILE_HIDING_CHANGED_PROPERTY =
"FileHidingChanged";
- /** DOCUMENT ME! */
+ /**
+ * The name of the 'file filter' property.
+ * @see #setFileFilter(FileFilter)
+ */
public static final String FILE_FILTER_CHANGED_PROPERTY =
"fileFilterChanged";
- /** DOCUMENT ME! */
+ /**
+ * The name of the 'file selection mode' property.
+ * @see #setFileSelectionMode(int)
+ */
public static final String FILE_SELECTION_MODE_CHANGED_PROPERTY =
"fileSelectionChanged";
- /** DOCUMENT ME! */
+ /**
+ * The name of the 'accessory' property.
+ * @see #setAccessory(JComponent)
+ */
public static final String ACCESSORY_CHANGED_PROPERTY =
"AccessoryChangedProperty";
- /** DOCUMENT ME! */
+ /**
+ * The name of the 'accept all file filter used' property.
+ * @see #setAcceptAllFileFilterUsed(boolean)
+ */
public static final String ACCEPT_ALL_FILE_FILTER_USED_CHANGED_PROPERTY =
"acceptAllFileFilterUsedChanged";
- /** DOCUMENT ME! */
+ /**
+ * The name of the 'dialog title' property.
+ * @see #setDialogTitle(String)
+ */
public static final String DIALOG_TITLE_CHANGED_PROPERTY =
"DialogTitleChangedProperty";
- /** DOCUMENT ME! */
+ /**
+ * The name of the 'dialog type' property.
+ * @see #setDialogType(int)
+ */
public static final String DIALOG_TYPE_CHANGED_PROPERTY =
"DialogTypeChangedProperty";
- /** DOCUMENT ME! */
+ /**
+ * The name of the 'choosable file filters' property.
+ * @see #addChoosableFileFilter(FileFilter)
+ */
public static final String CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY =
"ChoosableFileFilterChangedProperty";
- /** DOCUMENT ME! */
+ /**
+ * The accessible context.
+ * @see #getAccessibleContext()
+ */
protected AccessibleContext accessibleContext;
- /** DOCUMENT ME! */
+ /**
+ * The file system view.
+ * @see #setFileSystemView(FileSystemView)
+ */
private FileSystemView fsv;
- /** DOCUMENT ME! */
+ /**
+ * The accessory component.
+ * @see #setAccessory(JComponent)
+ */
private JComponent accessory;
- /** DOCUMENT ME! */
+ /**
+ * The approve button mnemonic.
+ * @see #setApproveButtonMnemonic(int)
+ */
private int approveButtonMnemonic = 0;
- /** DOCUMENT ME! */
+ /**
+ * The approve button text.
+ * @see #setApproveButtonText(String)
+ */
private String approveButtonText;
- /** DOCUMENT ME! */
+ /**
+ * The approve button tool tip text.
+ * @see #setApproveButtonToolTipText(String)
+ */
private String approveButtonToolTipText;
- /** DOCUMENT ME! */
+ /**
+ * The choosable file filters.
+ * @see #addChoosableFileFilter(FileFilter)
+ */
private ArrayList choosableFilters = new ArrayList();
- /** DOCUMENT ME! */
+ /**
+ * A flag controlling whether the accept all file filter is used.
+ * @see #setAcceptAllFileFilterUsed(boolean)
+ */
private boolean isAcceptAll = true;
- /** DOCUMENT ME! */
+ /**
+ * The dialog title.
+ * @see #setDialogTitle(String)
+ */
private String dialogTitle;
- /** DOCUMENT ME! */
+ /**
+ * The dialog type.
+ * @see #setDialogType(int)
+ */
private int dialogType = OPEN_DIALOG;
- /** DOCUMENT ME! */
+ /**
+ * The return value for the dialog.
+ * @see #showOpenDialog(Component)
+ * @see #showSaveDialog(Component)
+ */
private int retval = ERROR_OPTION;
- /** DOCUMENT ME! */
+ /**
+ * A flag indicating whether the file chooser allows multiple selection.
+ * @see #isMultiSelectionEnabled()
+ */
private boolean multiSelection = false;
- /** DOCUMENT ME! */
+ /**
+ * A flag indicating whether file hiding is enabled.
+ * @see #isFileHidingEnabled()
+ */
private boolean fileHiding = true;
- /** DOCUMENT ME! */
+ /**
+ * The file selection mode.
+ * @see #setFileSelectionMode(int)
+ */
private int fileSelectionMode = FILES_AND_DIRECTORIES;
- /** DOCUMENT ME! */
+ /**
+ * The file view.
+ * @see #setFileView(FileView)
+ */
private FileView fv = null;
- /** DOCUMENT ME! */
+ /**
+ * A flag controlling whether or not the control buttons are visible.
+ * @see #setControlButtonsAreShown(boolean)
+ */
private boolean controlButtonsShown = true;
- /** DOCUMENT ME! */
+ /**
+ * The current directory.
+ * @see #setCurrentDirectory(File)
+ */
private File currentDir = null;
- /** DOCUMENT ME! */
+ /**
+ * The current file filter.
+ * @see #setFileFilter(FileFilter)
+ */
private FileFilter currentFilter = null;
- /** DOCUMENT ME! */
+ /**
+ * An array of selected files.
+ * @see #setSelectedFiles(File[])
+ */
private File[] selectedFiles;
- /** DOCUMENT ME! */
+ /**
+ * The selected file.
+ * @see #setSelectedFile(File)
+ */
private File selectedFile;
/**
- * Creates a new JFileChooser object.
+ * Creates a new <code>JFileChooser</code> object.
*/
public JFileChooser()
{
@@ -243,9 +399,11 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * Creates a new JFileChooser object.
+ * Creates a new <code>JFileChooser</code> object.
*
- * @param currentDirectoryPath DOCUMENT ME!
+ * @param currentDirectoryPath the directory that should initially be
+ * shown in the filechooser (if <code>null</code>, the user's home
+ * directory is used).
*/
public JFileChooser(String currentDirectoryPath)
{
@@ -254,12 +412,14 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * Creates a new JFileChooser object with the specified directory and
- * FileSystemView.
+ * Creates a new <code>JFileChooser</code> object with the specified
+ * directory and {@link FileSystemView}.
*
- * @param currentDirectoryPath the directory that should initially be
- * shown the filechooser
- * @param fsv the FileSystemView object to use
+ * @param currentDirectoryPath the directory that should initially be
+ * shown in the filechooser (if <code>null</code>, the user's home
+ * directory is used).
+ * @param fsv the file system view (if <code>null</code>, the default file
+ * system view is used).
*/
public JFileChooser(String currentDirectoryPath, FileSystemView fsv)
{
@@ -268,9 +428,11 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * Creates a new JFileChooser object.
+ * Creates a new <code>JFileChooser</code> object.
*
- * @param currentDirectory DOCUMENT ME!
+ * @param currentDirectory the directory that should initially be
+ * shown in the filechooser (if <code>null</code>, the user's home
+ * directory is used).
*/
public JFileChooser(File currentDirectory)
{
@@ -279,9 +441,10 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * Creates a new JFileChooser object.
+ * Creates a new <code>JFileChooser</code> object.
*
- * @param fsv DOCUMENT ME!
+ * @param fsv the file system view (if <code>null</code>, the default file
+ * system view is used).
*/
public JFileChooser(FileSystemView fsv)
{
@@ -290,10 +453,13 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * Creates a new JFileChooser object.
+ * Creates a new <code>JFileChooser</code> object.
*
- * @param currentDirectory DOCUMENT ME!
- * @param fsv DOCUMENT ME!
+ * @param currentDirectory the directory that should initially be
+ * shown in the filechooser (if <code>null</code>, the user's home
+ * directory is used).
+ * @param fsv the file system view (if <code>null</code>, the default file
+ * system view is used).
*/
public JFileChooser(File currentDirectory, FileSystemView fsv)
{
@@ -302,9 +468,12 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Sets up the file chooser. This method is called by all the constructors.
*
- * @param view DOCUMENT ME!
+ * @param view the file system view (if <code>null</code>, the default file
+ * system view is used).
+ *
+ * @see FileSystemView#getFileSystemView()
*/
protected void setup(FileSystemView view)
{
@@ -336,9 +505,11 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Returns the selected file, if there is one.
*
- * @return DOCUMENT ME!
+ * @return The selected file (possibly <code>null</code>).
+ *
+ * @see #setSelectedFile(File)
*/
public File getSelectedFile()
{
@@ -346,9 +517,11 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Sets the selected file and sends a {@link PropertyChangeEvent} to all
+ * registered listeners. The property name is
+ * {@link #SELECTED_FILE_CHANGED_PROPERTY}.
*
- * @param file DOCUMENT ME!
+ * @param file the file (<code>null</code> permitted).
*/
public void setSelectedFile(File file)
{
@@ -361,9 +534,10 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Returns the selected file or files.
*
- * @return DOCUMENT ME!
+ * @return An array of the selected files, or <code>null</code> if there are
+ * no selected files.
*/
public File[] getSelectedFiles()
{
@@ -375,9 +549,11 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Sets the selected files and sends a {@link PropertyChangeEvent} (with the
+ * name {@link #SELECTED_FILES_CHANGED_PROPERTY}) to all registered
+ * listeners.
*
- * @param selectedFiles DOCUMENT ME!
+ * @param selectedFiles the selected files (<code>null</code> permitted).
*/
public void setSelectedFiles(File[] selectedFiles)
{
@@ -393,9 +569,9 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Returns the current directory.
*
- * @return DOCUMENT ME!
+ * @return The current directory.
*/
public File getCurrentDirectory()
{
@@ -403,9 +579,15 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Sets the current directory and fires a {@link PropertyChangeEvent} (with
+ * the property name {@link #DIRECTORY_CHANGED_PROPERTY}) to all registered
+ * listeners. If <code>dir</code> is <code>null</code>, the current
+ * directory is set to the default directory returned by the file system
+ * view.
*
- * @param dir DOCUMENT ME!
+ * @param dir the new directory (<code>null</code> permitted).
+ *
+ * @see FileSystemView#getDefaultDirectory()
*/
public void setCurrentDirectory(File dir)
{
@@ -421,7 +603,7 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Called by the UI delegate when the parent directory is changed.
*/
public void changeToParentDirectory()
{
@@ -430,7 +612,7 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Rescans the current directory (this is handled by the UI delegate).
*/
public void rescanCurrentDirectory()
{
@@ -438,9 +620,10 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Ensures the the specified file is visible (this is handled by the
+ * UI delegate).
*
- * @param f DOCUMENT ME!
+ * @param f the file.
*/
public void ensureFileIsVisible(File f)
{
@@ -448,11 +631,14 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Displays the file chooser in a modal dialog using the
+ * {@link #OPEN_DIALOG} type.
*
- * @param parent DOCUMENT ME!
+ * @param parent the parent component.
*
- * @return DOCUMENT ME!
+ * @return A return value indicating how the dialog was closed (one of
+ * {@link #APPROVE_OPTION}, {@link #CANCEL_OPTION} and
+ * {@link #ERROR_OPTION}).
*
* @throws HeadlessException DOCUMENT ME!
*/
@@ -472,11 +658,14 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Displays the file chooser in a modal dialog using the
+ * {@link #SAVE_DIALOG} type.
*
- * @param parent DOCUMENT ME!
+ * @param parent the parent component.
*
- * @return DOCUMENT ME!
+ * @return A return value indicating how the dialog was closed (one of
+ * {@link #APPROVE_OPTION}, {@link #CANCEL_OPTION} and
+ * {@link #ERROR_OPTION}).
*
* @throws HeadlessException DOCUMENT ME!
*/
@@ -493,12 +682,14 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Displays the file chooser in a modal dialog using the
+ * {@link #CUSTOM_DIALOG} type.
*
- * @param parent DOCUMENT ME!
- * @param approveButtonText DOCUMENT ME!
+ * @param parent the parent component.
*
- * @return DOCUMENT ME!
+ * @return A return value indicating how the dialog was closed (one of
+ * {@link #APPROVE_OPTION}, {@link #CANCEL_OPTION} and
+ * {@link #ERROR_OPTION}).
*
* @throws HeadlessException DOCUMENT ME!
*/
@@ -517,11 +708,11 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Creates a modal dialog in which to display the file chooser.
*
- * @param parent DOCUMENT ME!
+ * @param parent the parent component.
*
- * @return DOCUMENT ME!
+ * @return The dialog.
*
* @throws HeadlessException DOCUMENT ME!
*/
@@ -542,9 +733,12 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Returns the flag that controls whether or not the control buttons are
+ * shown on the file chooser.
*
- * @return DOCUMENT ME!
+ * @return A boolean.
+ *
+ * @see #setControlButtonsAreShown(boolean)
*/
public boolean getControlButtonsAreShown()
{
@@ -552,9 +746,12 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Sets the flag that controls whether or not the control buttons are
+ * shown and, if it changes, sends a {@link PropertyChangeEvent} (with the
+ * property name {@link #CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY}) to
+ * all registered listeners.
*
- * @param b DOCUMENT ME!
+ * @param b the new value for the flag.
*/
public void setControlButtonsAreShown(boolean b)
{
@@ -567,9 +764,12 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Returns the type of file chooser.
*
- * @return DOCUMENT ME!
+ * @return {@link #OPEN_DIALOG}, {@link #SAVE_DIALOG} or
+ * {@link #CUSTOM_DIALOG}.
+ *
+ * @see #setDialogType(int)
*/
public int getDialogType()
{
@@ -577,9 +777,14 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Sets the dialog type and fires a {@link PropertyChangeEvent} (with the
+ * property name {@link #DIALOG_TYPE_CHANGED_PROPERTY}) to all
+ * registered listeners.
*
- * @param dialogType DOCUMENT ME!
+ * @param dialogType the dialog type (one of: {@link #OPEN_DIALOG},
+ * {@link #SAVE_DIALOG}, {@link #CUSTOM_DIALOG}).
+ *
+ * @throws IllegalArgumentException if <code>dialogType</code> is not valid.
*/
public void setDialogType(int dialogType)
{
@@ -596,9 +801,13 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Sets the dialog title and sends a {@link PropertyChangeEvent} (with the
+ * property name {@link #DIALOG_TITLE_CHANGED_PROPERTY}) to all
+ * registered listeners.
*
- * @param dialogTitle DOCUMENT ME!
+ * @param dialogTitle the dialog title (<code>null</code> permitted).
+ *
+ * @see #getDialogTitle()
*/
public void setDialogTitle(String dialogTitle)
{
@@ -611,9 +820,11 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Returns the dialog title.
*
- * @return DOCUMENT ME!
+ * @return The dialog title (possibly <code>null</code>).
+ *
+ * @see #setDialogTitle(String)
*/
public String getDialogTitle()
{
@@ -621,9 +832,12 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Sets the tool tip text for the approve button and sends a
+ * {@link PropertyChangeEvent} (with the property name
+ * {@link #APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY}) to all
+ * registered listeners.
*
- * @param toolTipText DOCUMENT ME!
+ * @param toolTipText the text.
*/
public void setApproveButtonToolTipText(String toolTipText)
{
@@ -637,9 +851,11 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Returns the tool tip text for the approve button.
*
- * @return DOCUMENT ME!
+ * @return The tool tip text for the approve button.
+ *
+ * @see #setApproveButtonToolTipText(String)
*/
public String getApproveButtonToolTipText()
{
@@ -647,9 +863,11 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Returns the approve button mnemonic, or zero if no mnemonic has been set.
*
- * @return DOCUMENT ME!
+ * @return The approve button mnemonic.
+ *
+ * @see #setApproveButtonMnemonic(int)
*/
public int getApproveButtonMnemonic()
{
@@ -657,9 +875,14 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Sets the mnemonic for the approve button and sends a
+ * {@link PropertyChangeEvent} (with the property name
+ * {@link #APPROVE_BUTTON_MNEMONIC_CHANGED_PROPERTY}) to all registered
+ * listeners.
*
- * @param mnemonic DOCUMENT ME!
+ * @param mnemonic the mnemonic.
+ *
+ * @see #setApproveButtonMnemonic(char)
*/
public void setApproveButtonMnemonic(int mnemonic)
{
@@ -673,9 +896,14 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Sets the mnemonic for the approve button and sends a
+ * {@link PropertyChangeEvent} (with the property name
+ * {@link #APPROVE_BUTTON_MNEMONIC_CHANGED_PROPERTY}) to all registered
+ * listeners.
*
- * @param mnemonic DOCUMENT ME!
+ * @param mnemonic the mnemonic.
+ *
+ * @see #setApproveButtonMnemonic(int)
*/
public void setApproveButtonMnemonic(char mnemonic)
{
@@ -683,9 +911,13 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Sets the approve button text and fires a {@link PropertyChangeEvent}
+ * (with the property name {@link #APPROVE_BUTTON_TEXT_CHANGED_PROPERTY}) to
+ * all registered listeners.
*
- * @param approveButtonText DOCUMENT ME!
+ * @param approveButtonText the text (<code>null</code> permitted).
+ *
+ * @see #getApproveButtonText()
*/
public void setApproveButtonText(String approveButtonText)
{
@@ -699,9 +931,11 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Returns the approve button text.
*
- * @return DOCUMENT ME!
+ * @return The approve button text (possibly <code>null</code>).
+ *
+ * @see #setApproveButtonText(String)
*/
public String getApproveButtonText()
{
@@ -709,9 +943,9 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Returns the available file filters for this file chooser.
*
- * @return DOCUMENT ME!
+ * @return The available file filters.
*/
public FileFilter[] getChoosableFileFilters()
{
@@ -719,9 +953,12 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Adds a file filter to the list of available filters and sends a
+ * {@link PropertyChangeEvent} (with the property name
+ * {@link #CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY}) to all registered
+ * listeners.
*
- * @param filter DOCUMENT ME!
+ * @param filter the filter.
*/
public void addChoosableFileFilter(FileFilter filter)
{
@@ -732,11 +969,15 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Removes a file filter from the list of available filters and sends a
+ * {@link PropertyChangeEvent} (with the property name
+ * {@link #CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY}) to all registered
+ * listeners.
*
- * @param f DOCUMENT ME!
+ * @param f the file filter.
*
- * @return DOCUMENT ME!
+ * @return <code>true</code> if the filter was removed and
+ * <code>false</code> otherwise.
*/
public boolean removeChoosableFileFilter(FileFilter f)
{
@@ -749,7 +990,8 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Clears the list of choosable file filters and installs the 'accept all'
+ * filter from the UI delegate.
*/
public void resetChoosableFileFilters()
{
@@ -759,9 +1001,9 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Returns the 'accept all' file filter from the UI delegate.
*
- * @return DOCUMENT ME!
+ * @return The 'accept all' file filter.
*/
public FileFilter getAcceptAllFileFilter()
{
@@ -769,9 +1011,12 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Returns the flag that controls whether or not the 'accept all' file
+ * filter is included in the list of filters.
*
- * @return DOCUMENT ME!
+ * @return A boolean.
+ *
+ * @see #setAcceptAllFileFilterUsed(boolean)
*/
public boolean isAcceptAllFileFilterUsed()
{
@@ -779,9 +1024,13 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Sets the flag that controls whether or not the 'accept all' file filter
+ * is included in the list of filters, and sends a
+ * {@link PropertyChangeEvent} (with the property name
+ * {@link #ACCEPT_ALL_FILE_FILTER_USED_CHANGED_PROPERTY}) to all registered
+ * listeners.
*
- * @param b DOCUMENT ME!
+ * @param b the new value of the flag.
*/
public void setAcceptAllFileFilterUsed(boolean b)
{
@@ -794,9 +1043,12 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Returns the accessory component for the file chooser. The default
+ * value is <code>null</code>.
*
- * @return DOCUMENT ME!
+ * @return The accessory component (possibly <code>null</code>).
+ *
+ * @see #setAccessory(JComponent)
*/
public JComponent getAccessory()
{
@@ -804,9 +1056,11 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Sets the accessory component for the file chooser and sends a
+ * {@link PropertyChangeEvent} to all registered listeners. The property
+ * name is {@link #ACCESSORY_CHANGED_PROPERTY}.
*
- * @param newAccessory DOCUMENT ME!
+ * @param newAccessory the accessory component.
*/
public void setAccessory(JComponent newAccessory)
{
@@ -819,9 +1073,14 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Sets the file selection mode and sends a {@link PropertyChangeEvent}
+ * to all registered listeners. The property name is
+ * {@link #FILE_SELECTION_MODE_CHANGED_PROPERTY}.
*
- * @param mode DOCUMENT ME!
+ * @param mode the mode ({@link #FILES_ONLY}, {@link #DIRECTORIES_ONLY} or
+ * {@link #FILES_AND_DIRECTORIES}).
+ *
+ * @throws IllegalArgumentException if the mode is invalid.
*/
public void setFileSelectionMode(int mode)
{
@@ -838,9 +1097,13 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Returns the file selection mode, one of: {@link #FILES_ONLY},
+ * {@link #DIRECTORIES_ONLY} or {@link #FILES_AND_DIRECTORIES}. The
+ * default is {@link #FILES_ONLY}.
*
- * @return DOCUMENT ME!
+ * @return The file selection mode.
+ *
+ * @see #setFileSelectionMode(int)
*/
public int getFileSelectionMode()
{
@@ -848,9 +1111,14 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Returns <code>true</code> if file selection is enabled, and
+ * <code>false</code> otherwise. File selection is enabled when the
+ * file selection mode is {@link #FILES_ONLY} or
+ * {@link #FILES_AND_DIRECTORIES}.
*
- * @return DOCUMENT ME!
+ * @return <code>true</code> if file selection is enabled.
+ *
+ * @see #getFileSelectionMode()
*/
public boolean isFileSelectionEnabled()
{
@@ -859,9 +1127,14 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Returns <code>true</code> if directory selection is enabled, and
+ * <code>false</code> otherwise. Directory selection is enabled when the
+ * file selection mode is {@link #DIRECTORIES_ONLY} or
+ * {@link #FILES_AND_DIRECTORIES}.
*
- * @return DOCUMENT ME!
+ * @return <code>true</code> if file selection is enabled.
+ *
+ * @see #getFileSelectionMode()
*/
public boolean isDirectorySelectionEnabled()
{
@@ -870,9 +1143,12 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Sets the flag that controls whether multiple selections are allowed in
+ * this filechooser and sends a {@link PropertyChangeEvent} (with the
+ * property name {@link #MULTI_SELECTION_ENABLED_CHANGED_PROPERTY}) to all
+ * registered listeners.
*
- * @param b DOCUMENT ME!
+ * @param b the new value of the flag.
*/
public void setMultiSelectionEnabled(boolean b)
{
@@ -885,9 +1161,12 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Returns <code>true</code> if multiple selections are allowed within this
+ * file chooser, and <code>false</code> otherwise.
*
- * @return DOCUMENT ME!
+ * @return A boolean.
+ *
+ * @see #setMultiSelectionEnabled(boolean)
*/
public boolean isMultiSelectionEnabled()
{
@@ -895,9 +1174,12 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Returns <code>true</code> if hidden files are to be hidden, and
+ * <code>false</code> otherwise.
*
- * @return DOCUMENT ME!
+ * @return A boolean.
+ *
+ * @see #setFileHidingEnabled(boolean)
*/
public boolean isFileHidingEnabled()
{
@@ -905,9 +1187,11 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Sets the flag that controls whether or not hidden files are displayed,
+ * and sends a {@link PropertyChangeEvent} (with the property name
+ * {@link #FILE_HIDING_CHANGED_PROPERTY}) to all registered listeners.
*
- * @param b DOCUMENT ME!
+ * @param b the new value of the flag.
*/
public void setFileHidingEnabled(boolean b)
{
@@ -920,9 +1204,11 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Sets the file filter and sends a {@link PropertyChangeEvent} (with the
+ * property name {@link #FILE_FILTER_CHANGED_PROPERTY}) to all registered
+ * listeners.
*
- * @param filter DOCUMENT ME!
+ * @param filter the filter.
*/
public void setFileFilter(FileFilter filter)
{
@@ -935,9 +1221,11 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Returns the file filter.
*
- * @return DOCUMENT ME!
+ * @return The file filter.
+ *
+ * @see #setFileFilter(FileFilter)
*/
public FileFilter getFileFilter()
{
@@ -945,9 +1233,13 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Sets a custom {@link FileView} for the file chooser and sends a
+ * {@link PropertyChangeEvent} to all registered listeners. The property
+ * name is {@link #FILE_VIEW_CHANGED_PROPERTY}.
+ *
+ * @param fileView the file view (<code>null</code> permitted).
*
- * @param fileView DOCUMENT ME!
+ * @see #getFileView()
*/
public void setFileView(FileView fileView)
{
@@ -960,9 +1252,9 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Returns the custom {@link FileView} for the file chooser.
*
- * @return DOCUMENT ME!
+ * @return The file view (possibly <code>null</code>).
*/
public FileView getFileView()
{
@@ -970,71 +1262,83 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Returns the name of the file, generated by the current (or default)
+ * {@link FileView}.
*
- * @return DOCUMENT ME!
- */
- private FileView getInternalFileView()
- {
- if (fv == null)
- return getUI().getFileView(this);
- return fv;
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param f DOCUMENT ME!
+ * @param f the file.
*
- * @return DOCUMENT ME!
+ * @return The file name.
*/
public String getName(File f)
{
- return getInternalFileView().getName(f);
+ String name = null;
+ if (fv != null)
+ name = fv.getName(f);
+ if (name == null)
+ name = getUI().getFileView(this).getName(f);
+ return name;
}
/**
- * DOCUMENT ME!
+ * Returns the description of the file, generated by the current (or default)
+ * {@link FileView}.
*
- * @param f DOCUMENT ME!
+ * @param f the file.
*
- * @return DOCUMENT ME!
+ * @return The file description.
*/
public String getDescription(File f)
{
- return getInternalFileView().getDescription(f);
+ String result = null;
+ if (fv != null)
+ result = fv.getDescription(f);
+ if (result == null)
+ result = getUI().getFileView(this).getDescription(f);
+ return result;
}
/**
- * DOCUMENT ME!
+ * Returns the type description for the file, generated by the current (or
+ * default) {@link FileView}.
*
- * @param f DOCUMENT ME!
+ * @param f the file.
*
- * @return DOCUMENT ME!
+ * @return The file type description.
*/
public String getTypeDescription(File f)
{
- return getInternalFileView().getTypeDescription(f);
+ String result = null;
+ if (fv != null)
+ result = getFileView().getTypeDescription(f);
+ if (result == null)
+ result = getUI().getFileView(this).getTypeDescription(f);
+ return result;
}
/**
- * DOCUMENT ME!
+ * Returns the icon provided by the current (or default) {@link FileView}.
*
- * @param f DOCUMENT ME!
+ * @param f the file.
*
- * @return DOCUMENT ME!
+ * @return An icon representing the file.
*/
public Icon getIcon(File f)
{
- return getInternalFileView().getIcon(f);
+ Icon result = null;
+ if (fv != null)
+ result = fv.getIcon(f);
+ if (result == null)
+ result = getUI().getFileView(this).getIcon(f);
+ return result;
}
/**
- * DOCUMENT ME!
+ * Returns <code>true</code> if the file is traversable, and
+ * <code>false</code> otherwise.
*
- * @param f DOCUMENT ME!
+ * @param f the file or directory.
*
- * @return DOCUMENT ME!
+ * @return A boolean.
*/
public boolean isTraversable(File f)
{
@@ -1042,11 +1346,12 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Returns <code>true</code> if the file is accepted by the current
+ * file filter.
*
- * @param f DOCUMENT ME!
+ * @param f the file.
*
- * @return DOCUMENT ME!
+ * @return A boolean.
*/
public boolean accept(File f)
{
@@ -1056,9 +1361,10 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Sets the file system view for the file chooser and sends a
+ * {@link PropertyChangeEvent} to all registered listeners.
*
- * @param fsv DOCUMENT ME!
+ * @param fsv the file system view.
*/
public void setFileSystemView(FileSystemView fsv)
{
@@ -1071,9 +1377,11 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Returns the file system view being used by this file chooser.
*
- * @return DOCUMENT ME!
+ * @return The file system view.
+ *
+ * @see #setFileSystemView(FileSystemView)
*/
public FileSystemView getFileSystemView()
{
@@ -1081,7 +1389,8 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Approves the selection. An {@link ActionEvent} is sent to all registered
+ * listeners.
*/
public void approveSelection()
{
@@ -1090,7 +1399,8 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Cancels the selection. An {@link ActionEvent} is sent to all registered
+ * listeners.
*/
public void cancelSelection()
{
@@ -1099,9 +1409,9 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Adds an {@link ActionListener} to the file chooser.
*
- * @param l DOCUMENT ME!
+ * @param l the listener.
*/
public void addActionListener(ActionListener l)
{
@@ -1109,9 +1419,9 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Removes an {@link ActionListener} from this file chooser.
*
- * @param l DOCUMENT ME!
+ * @param l the listener.
*/
public void removeActionListener(ActionListener l)
{
@@ -1126,9 +1436,9 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Returns the action listeners registered with this file chooser.
*
- * @return DOCUMENT ME!
+ * @return An array of listeners.
*/
public ActionListener[] getActionListeners()
{
@@ -1136,9 +1446,9 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Sends an @link {ActionEvent} to all registered listeners.
*
- * @param command DOCUMENT ME!
+ * @param command the action command.
*/
protected void fireActionPerformed(String command)
{
@@ -1151,7 +1461,7 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Installs the UI delegate for the current look and feel.
*/
public void updateUI()
{
@@ -1160,9 +1470,9 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Returns the UI delegate class identifier.
*
- * @return DOCUMENT ME!
+ * @return <code>FileChooserUI</code>.
*/
public String getUIClassID()
{
@@ -1170,9 +1480,9 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Returns the UI delegate for the component.
*
- * @return DOCUMENT ME!
+ * @return The UI delegate.
*/
public FileChooserUI getUI()
{
@@ -1190,12 +1500,29 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Returns the accessible context.
*
- * @return DOCUMENT ME!
+ * @return The accessible context.
*/
public AccessibleContext getAccessibleContext()
{
- return null;
+ return new AccessibleJFileChooser();
+ }
+
+ /**
+ * Accessibility support for JFileChooser
+ */
+ protected class AccessibleJFileChooser
+ extends JComponent.AccessibleJComponent
+ {
+ protected AccessibleJFileChooser()
+ {
+ // Nothing to do here.
+ }
+
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.FILE_CHOOSER;
+ }
}
}
diff --git a/javax/swing/JFrame.java b/javax/swing/JFrame.java
index ce422ef3f..d8c3d9654 100644
--- a/javax/swing/JFrame.java
+++ b/javax/swing/JFrame.java
@@ -83,6 +83,14 @@ public class JFrame extends Frame
}
}
+ /**
+ * A flag for {@link #setDefaultCloseOperation(int)}, indicating that the
+ * application should be exited, when this <code>JFrame</code> is closed.
+ *
+ * @since 1.3
+ */
+ public static final int EXIT_ON_CLOSE = 3;
+
private static final long serialVersionUID = -3362141868504252139L;
private static boolean defaultLookAndFeelDecorated;
private int close_action = HIDE_ON_CLOSE;
diff --git a/javax/swing/JLabel.java b/javax/swing/JLabel.java
index 2e7ad98dd..a9adc96b2 100644
--- a/javax/swing/JLabel.java
+++ b/javax/swing/JLabel.java
@@ -331,9 +331,6 @@ public class JLabel extends JComponent implements Accessible, SwingConstants
/** The gap between the icon and the text. */
private transient int iconTextGap = 4;
- /** The accessible context for this JLabel. */
- private AccessibleJLabel accessibleContext;
-
/**
* Creates a new vertically centered, horizontally on the leading edge
* JLabel object with text and no icon.
@@ -403,6 +400,7 @@ public class JLabel extends JComponent implements Accessible, SwingConstants
this.text = text;
this.icon = icon;
this.horizontalAlignment = horizontalAlignment;
+ setAlignmentX(0.0F);
updateUI();
}
@@ -477,12 +475,14 @@ public class JLabel extends JComponent implements Accessible, SwingConstants
{
if (text != newText)
{
- String oldText = text;
- text = newText;
- firePropertyChange("text", oldText, newText);
-
- if (text != null && text.length() <= displayedMnemonicIndex)
- setDisplayedMnemonicIndex(text.length() - 1);
+ String oldText = text;
+ text = newText;
+ firePropertyChange("text", oldText, newText);
+
+ if (text != null && text.length() <= displayedMnemonicIndex)
+ setDisplayedMnemonicIndex(text.length() - 1);
+ revalidate();
+ repaint();
}
}
diff --git a/javax/swing/JLayeredPane.java b/javax/swing/JLayeredPane.java
index e86910395..2617bc408 100644
--- a/javax/swing/JLayeredPane.java
+++ b/javax/swing/JLayeredPane.java
@@ -40,6 +40,7 @@ package javax.swing;
import java.awt.Component;
import java.awt.Container;
+import java.awt.Graphics;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
@@ -164,7 +165,6 @@ public class JLayeredPane extends JComponent implements Accessible
setLayout(null);
}
-
/**
* Looks up the layer a child component is currently assigned to.
*
@@ -272,7 +272,7 @@ public class JLayeredPane extends JComponent implements Accessible
* Increments the recorded size of a given layer.
*
* @param layer the layer number to increment.
- * @see #incrLayer()
+ * @see #incrLayer
*/
private void incrLayer(Integer layer)
{
@@ -286,7 +286,7 @@ public class JLayeredPane extends JComponent implements Accessible
* Decrements the recorded size of a given layer.
*
* @param layer the layer number to decrement.
- * @see #decrLayer()
+ * @see #incrLayer
*/
private void decrLayer(Integer layer)
{
@@ -573,26 +573,15 @@ public class JLayeredPane extends JComponent implements Accessible
*
* @param index the index of the child component to remove.
*/
- public void remove (int index)
+ public void remove(int index)
{
- Component c = getComponent (index);
- int layer = getLayer (c);
- decrLayer (new Integer(layer));
- componentToLayer.remove (c);
- super.remove (index);
+ Component c = getComponent(index);
+ int layer = getLayer(c);
+ decrLayer(new Integer(layer));
+ componentToLayer.remove(c);
+ super.remove(index);
+ // FIXME: Figure out if this call is correct.
revalidate();
- repaint();
- }
-
- /**
- * Removes a child from this container. The child is specified directly.
- * After removal, the child no longer occupies a layer.
- *
- * @param comp the child to remove.
- */
- public void remove (Component comp)
- {
- remove (getIndexOf (comp));
}
/**
@@ -655,8 +644,6 @@ public class JLayeredPane extends JComponent implements Accessible
incrLayer (layer);
super.addImpl(comp, null, newIdx);
- revalidate();
- repaint();
}
/**
@@ -681,4 +668,32 @@ public class JLayeredPane extends JComponent implements Accessible
accessibleContext = new AccessibleJLayeredPane();
return accessibleContext;
}
+
+ /**
+ * This method is overridden order to provide a reasonable painting
+ * mechanism for <code>JLayeredPane</code>. This is necessary since
+ * <code>JLayeredPane</code>'s do not have an own UI delegate.
+ *
+ * Basically this method clears the background for the
+ * <code>JLayeredPane</code> and then calls <code>super.paint(g)</code>.
+ *
+ * @param g the graphics context to use
+ */
+ public void paint(Graphics g)
+ {
+ g.setColor(getBackground());
+ g.fillRect(0, 0, getWidth(), getHeight());
+ super.paint(g);
+ }
+
+ /**
+ * Overridden to return <code>false</code>, since <code>JLayeredPane</code>
+ * cannot guarantee that its children don't overlap.
+ *
+ * @return <code>false</code>
+ */
+ public boolean isOptimizedDrawingEnabled()
+ {
+ return false;
+ }
}
diff --git a/javax/swing/JList.java b/javax/swing/JList.java
index 0aedee2ab..d77bc41d6 100644
--- a/javax/swing/JList.java
+++ b/javax/swing/JList.java
@@ -614,6 +614,14 @@ public class JList extends JComponent implements Accessible, Scrollable
// TODO: Implement the remaining methods of this class.
}
+
+ /**
+ * Create a new AccessibleJList.
+ */
+ public AccessibleJList()
+ {
+ // Nothing to do here.
+ }
/**
* Returns the number of selected accessible children.
@@ -915,7 +923,7 @@ public class JList extends JComponent implements Accessible, Scrollable
/**
* This property specifies a foreground color for the selected cells in
- * the list. When {@link ListCellRenderer.getListCellRendererComponent}
+ * the list. When {@link ListCellRenderer#getListCellRendererComponent}
* is called with a selected cell object, the component returned will
* have its "foreground" set to this color.
*/
@@ -923,7 +931,7 @@ public class JList extends JComponent implements Accessible, Scrollable
/**
* This property specifies a background color for the selected cells in
- * the list. When {@link ListCellRenderer.getListCellRendererComponent}
+ * the list. When {@link ListCellRenderer#getListCellRendererComponent}
* is called with a selected cell object, the component returned will
* have its "background" property set to this color.
*/
@@ -950,9 +958,9 @@ public class JList extends JComponent implements Accessible, Scrollable
/**
* This property indicates a <em>preference</em> for the number of rows
* displayed in the list, and will scale the
- * {@link #preferredScrollableViewportSize} property accordingly. The actual
+ * {@link #getPreferredScrollableViewportSize} property accordingly. The actual
* number of displayed rows, when the list is placed in a real {@link
- * Viewport} or other component, may be greater or less than this number.
+ * JViewport} or other component, may be greater or less than this number.
*/
int visibleRowCount;
@@ -1004,7 +1012,7 @@ public class JList extends JComponent implements Accessible, Scrollable
event.getValueIsAdjusting());
JList.this.repaint();
}
- };
+ }
/**
* Shared ListListener instance, subscribed to both the current {@link
@@ -1171,7 +1179,7 @@ public class JList extends JComponent implements Accessible, Scrollable
/**
* Sets the value of the {@link #visibleRowCount} property.
*
- * @param visibleRowCount The new property value
+ * @param vc The new property value
*/
public void setVisibleRowCount(int vc)
{
@@ -1297,8 +1305,8 @@ public class JList extends JComponent implements Accessible, Scrollable
/**
* Returns the list index of the upper left or upper right corner of the
- * {@link #visibleRect} property, depending on the {@link
- * #componentOrientation} property.
+ * visible rectangle of this list, depending on the {@link
+ * Component#getComponentOrientation} property.
*
* @return The index of the first visible list cell, or <code>-1</code>
* if none is visible.
@@ -1319,7 +1327,8 @@ public class JList extends JComponent implements Accessible, Scrollable
*
* @return index of the cell to which specified location is closest to.
*/
- public int locationToIndex(Point location) {
+ public int locationToIndex(Point location)
+ {
return getUI().locationToIndex(this, location);
}
@@ -1329,14 +1338,15 @@ public class JList extends JComponent implements Accessible, Scrollable
*
* @return location of the cell located at the specified index in the list.
*/
- public Point indexToLocation(int index){
- return getCellBounds(index, index).getLocation();
+ public Point indexToLocation(int index)
+ {
+ return getUI().indexToLocation(this, index);
}
/**
* Returns the list index of the lower right or lower left corner of the
- * {@link #visibleRect} property, depending on the {@link
- * #componentOrientation} property.
+ * visible rectangle of this list, depending on the {@link
+ * Component#getComponentOrientation} property.
*
* @return The index of the last visible list cell, or <code>-1</code>
* if none is visible.
@@ -1359,7 +1369,7 @@ public class JList extends JComponent implements Accessible, Scrollable
* selected.
*
* @return An array of model indices, each of which is selected according
- * to the {@link #selection} property
+ * to the {@link #getSelectedValues} property
*/
public int[] getSelectedIndices()
{
@@ -1374,7 +1384,7 @@ public class JList extends JComponent implements Accessible, Scrollable
n++;
int [] v = new int[n];
j = 0;
- for (i = lo; i < hi; ++i)
+ for (i = lo; i <= hi; ++i)
if (selectionModel.isSelectedIndex(i))
v[j++] = i;
return v;
@@ -1404,7 +1414,7 @@ public class JList extends JComponent implements Accessible, Scrollable
* @return The first selected element, or <code>null</code> if no element
* is selected.
*
- * @see getSelectedValues
+ * @see #getSelectedValues
*/
public Object getSelectedValue()
{
@@ -1420,7 +1430,7 @@ public class JList extends JComponent implements Accessible, Scrollable
*
* @return An array containing all the selected values
*
- * @see getSelectedValue
+ * @see #setSelectedValue
*/
public Object[] getSelectedValues()
{
@@ -1579,7 +1589,7 @@ public class JList extends JComponent implements Accessible, Scrollable
}
/**
- * Sets the value of the {@link #celLRenderer} property.
+ * Sets the value of the {@link #getCellRenderer} property.
*
* @param renderer The new property value
*/
@@ -1753,14 +1763,14 @@ public class JList extends JComponent implements Accessible, Scrollable
public AccessibleContext getAccessibleContext()
{
- return null;
+ return new AccessibleJList();
}
/**
* Returns a size indicating how much space this list would like to
* consume, when contained in a scrollable viewport. This is part of the
* {@link Scrollable} interface, which interacts with {@link
- * ScrollPaneLayout} and {@link Viewport} to define scrollable objects.
+ * ScrollPaneLayout} and {@link JViewport} to define scrollable objects.
*
* @return The preferred size
*/
@@ -1770,36 +1780,43 @@ public class JList extends JComponent implements Accessible, Scrollable
//return the value from getPreferredSize. The current ListUI is
//expected to override getPreferredSize to return an appropriate value.
if (getLayoutOrientation() != VERTICAL)
- return getPreferredSize();
+ return getPreferredSize();
+
+ int size = getModel().getSize();
+ // Trivial case: if fixedCellWidth and fixedCellHeight were set
+ // just use them
if (fixedCellHeight != -1 && fixedCellWidth != -1)
- return new Dimension(fixedCellWidth, getModel().getSize() *
- fixedCellHeight);
+ return new Dimension(fixedCellWidth, size * fixedCellHeight);
+
+ // If the model is empty we use 16 * the number of visible rows
+ // for the height and either fixedCellWidth (if set) or 256
+ // for the width
+ if (size == 0)
+ {
+ if (fixedCellWidth == -1)
+ return new Dimension(256, 16 * getVisibleRowCount());
+ else
+ return new Dimension(fixedCellWidth, 16 * getVisibleRowCount());
+ }
- int prefWidth, prefHeight;
+ // Calculate the width: if fixedCellWidth was set use that, otherwise
+ // use the preferredWidth
+ int prefWidth;
if (fixedCellWidth != -1)
prefWidth = fixedCellWidth;
else
- {
- prefWidth = 0;
- int size = getModel().getSize();
- for (int i = 0; i < size; i++)
- if (getCellBounds(i, i).width > prefWidth)
- prefWidth = getCellBounds(i, i).width;
- }
-
- if (getModel().getSize() == 0 && fixedCellWidth == -1)
- return new Dimension(256, 16 * getVisibleRowCount());
- else if (getModel().getSize() == 0)
- return new Dimension (fixedCellWidth, 16 * getVisibleRowCount());
-
+ prefWidth = getPreferredSize().width;
+
+ // Calculate the height: if fixedCellHeight was set use that, otherwise
+ // use the height of the first row multiplied by the number of visible
+ // rows
+ int prefHeight;
if (fixedCellHeight != -1)
prefHeight = fixedCellHeight;
else
- {
- prefHeight = getVisibleRowCount() * getCellBounds
- (getFirstVisibleIndex(), getFirstVisibleIndex()).height;
- }
+ prefHeight = getVisibleRowCount() * getCellBounds(0, 0).height;
+
return new Dimension (prefWidth, prefHeight);
}
@@ -1930,7 +1947,7 @@ public class JList extends JComponent implements Accessible, Scrollable
}
/**
- * Gets the value of the {@link #scrollableTracksViewportWidth} property.
+ * Gets the value of the <code>scrollableTracksViewportWidth</code> property.
*
* @return <code>true</code> if the viewport is larger (horizontally)
* than the list and the list should be expanded to fit the viewport;
@@ -1955,7 +1972,7 @@ public class JList extends JComponent implements Accessible, Scrollable
}
/**
- * Gets the value of the {@link #scrollableTracksViewportWidth} property.
+ * Gets the value of the </code>scrollableTracksViewportWidth</code> property.
*
* @return <code>true</code> if the viewport is larger (vertically)
* than the list and the list should be expanded to fit the viewport;
@@ -2107,7 +2124,7 @@ public class JList extends JComponent implements Accessible, Scrollable
*/
public Rectangle getCellBounds(int index0, int index1)
{
- return ((ListUI) ui).getCellBounds(this, index0, index1);
+ return getUI().getCellBounds(this, index0, index1);
}
/**
@@ -2117,8 +2134,8 @@ public class JList extends JComponent implements Accessible, Scrollable
*
* @param prefix the prefix to search for in the cell values
* @param startIndex the index where to start searching from
- * @param bias the search direction, either {@link Position.Bias.Forward}
- * or {@link Position.Bias.Backward}
+ * @param bias the search direction, either {@link Position.Bias#Forward}
+ * or {@link Position.Bias#Backward}
*
* @return the index of the found element or -1 if no such element has
* been found
diff --git a/javax/swing/JMenu.java b/javax/swing/JMenu.java
index 8dcad8b77..9734eb873 100644
--- a/javax/swing/JMenu.java
+++ b/javax/swing/JMenu.java
@@ -45,8 +45,6 @@ import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
-import java.io.IOException;
-import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.EventListener;
@@ -137,10 +135,6 @@ public class JMenu extends JMenuItem implements Accessible, MenuElement
this(text);
}
- private void writeObject(ObjectOutputStream stream) throws IOException
- {
- }
-
/**
* Adds specified menu item to this menu
*
@@ -768,6 +762,7 @@ public class JMenu extends JMenuItem implements Accessible, MenuElement
*/
protected void processKeyEvent(KeyEvent event)
{
+ // TODO: Implement this properly.
}
/**
@@ -812,6 +807,7 @@ public class JMenu extends JMenuItem implements Accessible, MenuElement
return accessibleContext;
}
+ // FIXME: This inner class is a complete stub and needs to be implemented.
protected class AccessibleJMenu extends AccessibleJMenuItem
implements AccessibleSelection
{
@@ -819,6 +815,7 @@ public class JMenu extends JMenuItem implements Accessible, MenuElement
protected AccessibleJMenu()
{
+ // Nothing to do here.
}
public int getAccessibleChildrenCount()
@@ -858,32 +855,48 @@ public class JMenu extends JMenuItem implements Accessible, MenuElement
public void addAccessibleSelection(int value0)
{
+ // TODO: Implement this properly.
}
public void removeAccessibleSelection(int value0)
{
+ // TODO: Implement this properly.
}
public void clearAccessibleSelection()
{
+ // TODO: Implement this properly.
}
public void selectAllAccessibleSelection()
{
+ // TODO: Implement this properly.
}
}
protected class WinListener extends WindowAdapter implements Serializable
{
- JPopupMenu popupMenu;
private static final long serialVersionUID = -6415815570638474823L;
+ /**
+ * Creates a new <code>WinListener</code>.
+ *
+ * @param popup the popup menu which is observed
+ */
public WinListener(JPopupMenu popup)
{
+ // TODO: What should we do with the popup argument?
}
+ /**
+ * Receives notification when the popup menu is closing and deselects
+ * the menu.
+ *
+ * @param event the window event
+ */
public void windowClosing(WindowEvent event)
{
+ setSelected(false);
}
}
diff --git a/javax/swing/JMenuBar.java b/javax/swing/JMenuBar.java
index 25d4b0cfa..829d671ec 100644
--- a/javax/swing/JMenuBar.java
+++ b/javax/swing/JMenuBar.java
@@ -46,6 +46,9 @@ import java.awt.event.MouseEvent;
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleSelection;
+import javax.accessibility.AccessibleStateSet;
import javax.swing.plaf.MenuBarUI;
/**
@@ -59,6 +62,137 @@ import javax.swing.plaf.MenuBarUI;
*/
public class JMenuBar extends JComponent implements Accessible, MenuElement
{
+ /**
+ * Provides accessibility support for <code>JMenuBar</code>.
+ *
+ * @author Roman Kennke (kennke@aicas.com)
+ */
+ protected class AccessibleJMenuBar extends AccessibleJComponent
+ implements AccessibleSelection
+ {
+
+ /**
+ * Returns the number of selected items in the menu bar. Possible values
+ * are <code>0</code> if nothing is selected, or <code>1</code> if one
+ * item is selected.
+ *
+ * @return the number of selected items in the menu bar
+ */
+ public int getAccessibleSelectionCount()
+ {
+ int count = 0;
+ if (getSelectionModel().getSelectedIndex() != -1)
+ count = 1;
+ return count;
+ }
+
+ /**
+ * Returns the selected with index <code>i</code> menu, or
+ * <code>null</code> if the specified menu is not selected.
+ *
+ * @param i the index of the menu to return
+ *
+ * @return the selected with index <code>i</code> menu, or
+ * <code>null</code> if the specified menu is not selected
+ */
+ public Accessible getAccessibleSelection(int i)
+ {
+ if (getSelectionModel().getSelectedIndex() != i)
+ return null;
+ return getMenu(i);
+ }
+
+ /**
+ * Returns <code>true</code> if the specified menu is selected,
+ * <code>false</code> otherwise.
+ *
+ * @param i the index of the menu to check
+ *
+ *@return <code>true</code> if the specified menu is selected,
+ * <code>false</code> otherwise
+ */
+ public boolean isAccessibleChildSelected(int i)
+ {
+ return getSelectionModel().getSelectedIndex() == i;
+ }
+
+ /**
+ * Selects the menu with index <code>i</code>. If another menu is already
+ * selected, this will be deselected.
+ *
+ * @param i the menu to be selected
+ */
+ public void addAccessibleSelection(int i)
+ {
+ getSelectionModel().setSelectedIndex(i);
+ }
+
+ /**
+ * Deselects the menu with index <code>i</code>.
+ *
+ * @param i the menu index to be deselected
+ */
+ public void removeAccessibleSelection(int i)
+ {
+ if (getSelectionModel().getSelectedIndex() == i)
+ getSelectionModel().clearSelection();
+ }
+
+ /**
+ * Deselects all possibly selected menus.
+ */
+ public void clearAccessibleSelection()
+ {
+ getSelectionModel().clearSelection();
+ }
+
+ /**
+ * In menu bars it is not possible to select all items, so this method
+ * does nothing.
+ */
+ public void selectAllAccessibleSelection()
+ {
+ // In menu bars it is not possible to select all items, so this method
+ // does nothing.
+ }
+
+ /**
+ * Returns the accessible role of <code>JMenuBar</code>, which is
+ * {@link AccessibleRole#MENU_BAR}.
+ *
+ * @return the accessible role of <code>JMenuBar</code>, which is
+ * {@link AccessibleRole#MENU_BAR}
+ */
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.MENU_BAR;
+ }
+
+ /**
+ * Returns the <code>AccessibleSelection</code> for this object. This
+ * method returns <code>this</code>, since the
+ * <code>AccessibleJMenuBar</code> manages its selection itself.
+ *
+ * @return the <code>AccessibleSelection</code> for this object
+ */
+ public AccessibleSelection getAccessibleSelection()
+ {
+ return this;
+ }
+
+ /**
+ * Returns the state of this <code>AccessibleJMenuBar</code>.
+ *
+ * @return the state of this <code>AccessibleJMenuBar</code>.
+ */
+ public AccessibleStateSet getAccessibleStateSet()
+ {
+ AccessibleStateSet stateSet = super.getAccessibleStateSet();
+ // TODO: Figure out what state must be added to the super state set.
+ return stateSet;
+ }
+ }
+
private static final long serialVersionUID = -8191026883931977036L;
/** JMenuBar's model. It keeps track of selected menu's index */
@@ -106,7 +240,9 @@ public class JMenuBar extends JComponent implements Accessible, MenuElement
public AccessibleContext getAccessibleContext()
{
- return null;
+ if (accessibleContext == null)
+ accessibleContext = new AccessibleJMenuBar();
+ return accessibleContext;
}
/**
@@ -384,9 +520,14 @@ public class JMenuBar extends JComponent implements Accessible, MenuElement
* Sets help menu for this menu bar
*
* @param menu help menu
+ *
+ * @specnote The specification states that this method is not yet implemented
+ * and should throw an exception.
*/
public void setHelpMenu(JMenu menu)
{
+ // We throw an Error here, just as Sun's JDK does.
+ throw new Error("setHelpMenu() not yet implemented.");
}
/**
diff --git a/javax/swing/JMenuItem.java b/javax/swing/JMenuItem.java
index 069b7bc86..9799017f6 100644
--- a/javax/swing/JMenuItem.java
+++ b/javax/swing/JMenuItem.java
@@ -44,9 +44,6 @@ import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
import java.util.EventListener;
import javax.accessibility.Accessible;
@@ -84,6 +81,7 @@ public class JMenuItem extends AbstractButton implements Accessible,
public JMenuItem()
{
super();
+ init(null, null);
}
/**
@@ -118,6 +116,7 @@ public class JMenuItem extends AbstractButton implements Accessible,
{
super();
super.setAction(action);
+ init(null, null);
}
/**
@@ -147,15 +146,6 @@ public class JMenuItem extends AbstractButton implements Accessible,
setMnemonic(mnemonic);
}
- private void readObject(ObjectInputStream stream)
- throws IOException, ClassNotFoundException
- {
- }
-
- private void writeObject(ObjectOutputStream stream) throws IOException
- {
- }
-
/**
* Initializes this menu item
*
@@ -176,7 +166,7 @@ public class JMenuItem extends AbstractButton implements Accessible,
//borderPainted = false;
focusPainted = false;
horizontalAlignment = JButton.LEFT;
- horizontalTextPosition = JButton.LEFT;
+ horizontalTextPosition = JButton.TRAILING;
}
/**
@@ -189,7 +179,7 @@ public class JMenuItem extends AbstractButton implements Accessible,
{
super.setUI(ui);
}
-
+
/**
* This method sets this menuItem's UI to the UIManager's default for the
* current look and feel.
@@ -255,8 +245,11 @@ public class JMenuItem extends AbstractButton implements Accessible,
}
/**
- * Sets accelerator for this menu item.
- *
+ * Sets the key combination which invokes the menu item's action
+ * listeners without navigating the menu hierarchy. Note that when the
+ * keyboard accelerator is typed, it will work whether or not the
+ * menu is currently displayed.
+ *
* @param keystroke accelerator for this menu item.
*/
public void setAccelerator(KeyStroke keystroke)
@@ -276,7 +269,11 @@ public class JMenuItem extends AbstractButton implements Accessible,
super.configurePropertiesFromAction(action);
if (! (this instanceof JMenu) && action != null)
- setAccelerator((KeyStroke) (action.getValue(Action.ACCELERATOR_KEY)));
+ {
+ setAccelerator((KeyStroke) (action.getValue(Action.ACCELERATOR_KEY)));
+ super.registerKeyboardAction(action, accelerator,
+ JComponent.WHEN_IN_FOCUSED_WINDOW);
+ }
}
/**
@@ -667,6 +664,7 @@ public class JMenuItem extends AbstractButton implements Accessible,
public void stateChanged(ChangeEvent event)
{
+ // TODO: What should be done here, if anything?
}
public AccessibleRole getAccessibleRole()
diff --git a/javax/swing/JOptionPane.java b/javax/swing/JOptionPane.java
index 54e6abc0e..2f28ccc91 100644
--- a/javax/swing/JOptionPane.java
+++ b/javax/swing/JOptionPane.java
@@ -39,7 +39,6 @@ exception statement from your version. */
package javax.swing;
import java.awt.Component;
-import java.awt.Dimension;
import java.awt.Frame;
import javax.accessibility.Accessible;
@@ -60,16 +59,19 @@ public class JOptionPane extends JComponent implements Accessible
/**
* DOCUMENT ME!
*/
+ // FIXME: This inner class is a complete stub and needs to be implemented
+ // properly.
protected class AccessibleJOptionPane extends JComponent.AccessibleJComponent
{
/** DOCUMENT ME! */
private static final long serialVersionUID = 686071432213084821L;
-
+
/**
* Creates a new AccessibleJOptionPane object.
*/
protected AccessibleJOptionPane()
{
+ // Nothing to do here.
}
/**
@@ -343,8 +345,6 @@ public class JOptionPane extends JComponent implements Accessible
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
updateUI();
- invalidate();
- repaint();
}
/**
@@ -377,8 +377,6 @@ public class JOptionPane extends JComponent implements Accessible
dialog.getContentPane().add(this);
dialog.setModal(true);
dialog.setResizable(false);
- dialog.invalidate();
- dialog.repaint();
return dialog;
}
@@ -513,6 +511,8 @@ public class JOptionPane extends JComponent implements Accessible
*/
public Object getInputValue()
{
+ if (getValue().equals(new Integer(CANCEL_OPTION)))
+ setInputValue(null);
return inputValue;
}
@@ -974,7 +974,7 @@ public class JOptionPane extends JComponent implements Accessible
JDialog dialog = pane.createDialog(parentComponent, null);
dialog.pack();
dialog.show();
-
+
return (String) pane.getInputValue();
}
@@ -1001,7 +1001,7 @@ public class JOptionPane extends JComponent implements Accessible
JDialog dialog = pane.createDialog(parentComponent, null);
dialog.pack();
dialog.show();
-
+
return (String) pane.getInputValue();
}
@@ -1027,7 +1027,7 @@ public class JOptionPane extends JComponent implements Accessible
JDialog dialog = pane.createDialog(parentComponent, title);
dialog.pack();
dialog.show();
-
+
return (String) pane.getInputValue();
}
@@ -1060,8 +1060,8 @@ public class JOptionPane extends JComponent implements Accessible
JDialog dialog = pane.createDialog(parentComponent, title);
dialog.pack();
dialog.show();
-
- return (String) pane.getInputValue();
+
+ return pane.getInputValue();
}
/**
@@ -1081,7 +1081,7 @@ public class JOptionPane extends JComponent implements Accessible
JDialog dialog = pane.createDialog(null, null);
dialog.pack();
dialog.show();
-
+
return (String) pane.getInputValue();
}
@@ -1106,7 +1106,7 @@ public class JOptionPane extends JComponent implements Accessible
JDialog dialog = pane.createDialog(null, null);
dialog.pack();
dialog.show();
-
+
return (String) pane.getInputValue();
}
@@ -1128,8 +1128,10 @@ public class JOptionPane extends JComponent implements Accessible
JInternalFrame frame = pane.createInternalFrame(parentComponent, null);
startModal(frame);
-
- return ((Integer) pane.getValue()).intValue();
+
+ if (pane.getValue() instanceof Integer)
+ return ((Integer) pane.getValue()).intValue();
+ return -1;
}
/**
@@ -1154,7 +1156,9 @@ public class JOptionPane extends JComponent implements Accessible
startModal(frame);
- return ((Integer) pane.getValue()).intValue();
+ if (pane.getValue() instanceof Integer)
+ return ((Integer) pane.getValue()).intValue();
+ return -1;
}
/**
@@ -1180,7 +1184,9 @@ public class JOptionPane extends JComponent implements Accessible
startModal(frame);
- return ((Integer) pane.getValue()).intValue();
+ if (pane.getValue() instanceof Integer)
+ return ((Integer) pane.getValue()).intValue();
+ return -1;
}
/**
@@ -1208,7 +1214,9 @@ public class JOptionPane extends JComponent implements Accessible
startModal(frame);
- return ((Integer) pane.getValue()).intValue();
+ if (pane.getValue() instanceof Integer)
+ return ((Integer) pane.getValue()).intValue();
+ return -1;
}
/**
@@ -1230,7 +1238,7 @@ public class JOptionPane extends JComponent implements Accessible
JInternalFrame frame = pane.createInternalFrame(parentComponent, null);
startModal(frame);
-
+
return (String) pane.getInputValue();
}
@@ -1256,7 +1264,7 @@ public class JOptionPane extends JComponent implements Accessible
JInternalFrame frame = pane.createInternalFrame(parentComponent, title);
startModal(frame);
-
+
return (String) pane.getInputValue();
}
@@ -1291,8 +1299,8 @@ public class JOptionPane extends JComponent implements Accessible
JInternalFrame frame = pane.createInternalFrame(parentComponent, title);
startModal(frame);
-
- return (String) pane.getInputValue();
+
+ return pane.getInputValue();
}
/**
@@ -1384,8 +1392,10 @@ public class JOptionPane extends JComponent implements Accessible
JInternalFrame frame = pane.createInternalFrame(parentComponent, title);
startModal(frame);
-
- return ((Integer) pane.getValue()).intValue();
+
+ if (pane.getValue() instanceof Integer)
+ return ((Integer) pane.getValue()).intValue();
+ return -1;
}
/**
@@ -1400,7 +1410,7 @@ public class JOptionPane extends JComponent implements Accessible
JOptionPane pane = new JOptionPane(message, INFORMATION_MESSAGE);
JDialog dialog = pane.createDialog(parentComponent, null);
dialog.pack();
- dialog.show();
+ dialog.show();
}
/**
@@ -1472,7 +1482,9 @@ public class JOptionPane extends JComponent implements Accessible
dialog.pack();
dialog.show();
- return ((Integer) pane.getValue()).intValue();
+ if (pane.getValue() instanceof Integer)
+ return ((Integer) pane.getValue()).intValue();
+ return -1;
}
/**
@@ -1532,34 +1544,34 @@ public class JOptionPane extends JComponent implements Accessible
* JInternalFrame's preferred size.
*
* @param f The JInternalFrame to make modal.
- * @param pane The JOptionPane to add to the JInternalFrame.
*/
private static void startModal(JInternalFrame f)
{
synchronized (f)
- {
- final JInternalFrame tmp = f;
- tmp.toFront();
-
- f.addInternalFrameListener(new InternalFrameAdapter()
- {
- public void internalFrameClosed(InternalFrameEvent e)
- {
- synchronized (tmp)
- {
- tmp.removeInternalFrameListener(this);
- tmp.notifyAll();
- }
- }
- });
- try
- {
- while (! f.isClosed())
- f.wait();
- }
- catch (InterruptedException ignored)
- {
- }
- }
+ {
+ final JInternalFrame tmp = f;
+ tmp.toFront();
+
+ f.addInternalFrameListener(new InternalFrameAdapter()
+ {
+ public void internalFrameClosed(InternalFrameEvent e)
+ {
+ synchronized (tmp)
+ {
+ tmp.removeInternalFrameListener(this);
+ tmp.notifyAll();
+ }
+ }
+ });
+ try
+ {
+ while (! f.isClosed())
+ f.wait();
+ }
+ catch (InterruptedException ignored)
+ {
+ // Ignore this Exception.
+ }
+ }
}
}
diff --git a/javax/swing/JPanel.java b/javax/swing/JPanel.java
index daf3ce61e..7805e92b6 100644
--- a/javax/swing/JPanel.java
+++ b/javax/swing/JPanel.java
@@ -80,11 +80,6 @@ public class JPanel extends JComponent implements Accessible
}
}
- /**
- * The accessible context for this <code>JPanel</code>.
- */
- AccessibleContext accessibleContext;
-
public JPanel()
{
this(new FlowLayout(), true);
diff --git a/javax/swing/JPasswordField.java b/javax/swing/JPasswordField.java
index 151d2484a..11e45e8a5 100644
--- a/javax/swing/JPasswordField.java
+++ b/javax/swing/JPasswordField.java
@@ -67,6 +67,7 @@ public class JPasswordField extends JTextField
*/
protected AccessibleJPasswordField()
{
+ // Nothing to do here.
}
/**
diff --git a/javax/swing/JPopupMenu.java b/javax/swing/JPopupMenu.java
index 18da20afa..1f2282e23 100644
--- a/javax/swing/JPopupMenu.java
+++ b/javax/swing/JPopupMenu.java
@@ -39,19 +39,13 @@ exception statement from your version. */
package javax.swing;
import java.awt.Component;
-import java.awt.Container;
import java.awt.Dimension;
-import java.awt.GridBagConstraints;
import java.awt.Insets;
-import java.awt.Panel;
import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.EventListener;
@@ -102,11 +96,11 @@ public class JPopupMenu extends JComponent implements Accessible, MenuElement
1. if DefaultLightWeightPopupEnabled true
(i) use lightweight container if popup feets inside top-level window
- (ii) only use heavyweight container (JWindow) if popup doesn't fit.
+ (ii) only use heavyweight container (JDialog) if popup doesn't fit.
2. if DefaultLightWeightPopupEnabled false
(i) if popup fits, use awt.Panel (mediumWeight)
- (ii) if popup doesn't fit, use JWindow (heavyWeight)
+ (ii) if popup doesn't fit, use JDialog (heavyWeight)
*/
private static boolean DefaultLightWeightPopupEnabled = true;
@@ -130,8 +124,15 @@ public class JPopupMenu extends JComponent implements Accessible, MenuElement
/* Popup that is used to display JPopupMenu */
private transient Popup popup;
- /* Location of the popup */
- private Point popupLocation;
+ /**
+ * Location of the popup, X coordinate.
+ */
+ private int popupLocationX;
+
+ /**
+ * Location of the popup, Y coordinate.
+ */
+ private int popupLocationY;
/* Field indicating if popup menu is visible or not */
private boolean visible = false;
@@ -158,15 +159,6 @@ public class JPopupMenu extends JComponent implements Accessible, MenuElement
updateUI();
}
- private void readObject(ObjectInputStream stream)
- throws IOException, ClassNotFoundException
- {
- }
-
- private void writeObject(ObjectOutputStream stream) throws IOException
- {
- }
-
/**
* Adds given menu item to the popup menu
*
@@ -220,19 +212,7 @@ public class JPopupMenu extends JComponent implements Accessible, MenuElement
public void remove(int index)
{
super.remove(index);
-
- GridBagConstraints constraints = new GridBagConstraints();
- constraints.fill = GridBagConstraints.BOTH;
- constraints.weightx = 100.0;
- constraints.weighty = 100.0;
-
- Component[] items = getComponents();
- for (int i = index; i < items.length; i++)
- {
- constraints.gridy = i;
- super.add(items[i], constraints, i);
- }
- this.setSize(this.getPreferredSize());
+ revalidate();
}
/**
@@ -257,27 +237,7 @@ public class JPopupMenu extends JComponent implements Accessible, MenuElement
*/
public void insert(Component component, int index)
{
- GridBagConstraints constraints = new GridBagConstraints();
- constraints.fill = GridBagConstraints.BOTH;
- constraints.weightx = 100.0;
- constraints.weighty = 100.0;
-
- constraints.gridy = index;
- super.add(component, constraints, index);
-
- // need to change constraints for the components that were moved by 1
- // due to the insertion
- if (index != -1)
- {
- Component[] items = getComponents();
-
- for (int i = index + 1; i < items.length; i++)
- {
- constraints.gridy = i;
- super.add(items[i], constraints, i);
- }
- }
- this.setSize(this.getPreferredSize());
+ super.add(component, index);
}
/**
@@ -527,7 +487,20 @@ public class JPopupMenu extends JComponent implements Accessible, MenuElement
*/
public void pack()
{
- super.setSize(null);
+ // Hook up this call so that it gets executed on the event thread in order
+ // to avoid synchronization problems when calling the layout manager.
+ if (! SwingUtilities.isEventDispatchThread())
+ {
+ SwingUtilities.invokeLater(new Runnable()
+ {
+ public void run()
+ {
+ show();
+ }
+ });
+ }
+
+ setSize(getPreferredSize());
}
/**
@@ -547,8 +520,21 @@ public class JPopupMenu extends JComponent implements Accessible, MenuElement
*
* @param visible true if popup menu will become visible and false otherwise.
*/
- public void setVisible(boolean visible)
+ public void setVisible(final boolean visible)
{
+ // Hook up this call so that it gets executed on the event thread in order
+ // to avoid synchronization problems when calling the layout manager.
+ if (! SwingUtilities.isEventDispatchThread())
+ {
+ SwingUtilities.invokeLater(new Runnable()
+ {
+ public void run()
+ {
+ setVisible(visible);
+ }
+ });
+ }
+
if (visible == isVisible())
return;
@@ -560,62 +546,11 @@ public class JPopupMenu extends JComponent implements Accessible, MenuElement
if (visible)
{
firePopupMenuWillBecomeVisible();
- Container rootContainer = (Container) SwingUtilities.getRoot(invoker);
- Dimension screenSize = getToolkit().getScreenSize();
-
- boolean fit = true;
- Dimension size;
-
- // Determine the size of the popup menu
- if (this.getSize().width == 0 && this.getSize().width == 0)
- size = this.getPreferredSize();
- else
- size = this.getSize();
-
- if ((size.width > (rootContainer.getWidth() - popupLocation.x))
- || (size.height > (rootContainer.getHeight() - popupLocation.y)))
- fit = false;
- if (lightWeightPopupEnabled && fit)
- popup = new LightWeightPopup(this);
- else
- {
- if (fit)
- popup = new MediumWeightPopup(this);
- else
- popup = new HeavyWeightPopup(this);
- }
- if (popup instanceof LightWeightPopup
- || popup instanceof MediumWeightPopup)
- {
- JLayeredPane layeredPane;
- layeredPane = SwingUtilities.getRootPane(invoker).getLayeredPane();
- Point p = new Point(popupLocation.x, popupLocation.y);
-
- if (layeredPane.isShowing())
- SwingUtilities.convertPointFromScreen(p, layeredPane);
-
- if (size.width + popupLocation.x > screenSize.width)
- popupLocation.x -= size.width;
- if (size.height + popupLocation.y > screenSize.height)
- popupLocation.y -= size.height;
-
- popup.show(p.x, p.y, size.width, size.height);
- }
- else
- {
- // Subtract insets of the top-level container if popup menu's
- // top-left corner is inside it.
- Insets insets = rootContainer.getInsets();
-
- if (size.width + popupLocation.x > screenSize.width)
- popupLocation.x -= size.width;
- if (size.height + popupLocation.y > screenSize.height)
- popupLocation.y -= size.height;
-
- popup.show(popupLocation.x - insets.left,
- popupLocation.y - insets.top,
- size.width, size.height);
- }
+
+ PopupFactory pf = PopupFactory.getSharedInstance();
+ pack();
+ popup = pf.getPopup(invoker, this, popupLocationX, popupLocationY);
+ popup.show();
}
else
{
@@ -633,11 +568,11 @@ public class JPopupMenu extends JComponent implements Accessible, MenuElement
*/
public void setLocation(int x, int y)
{
- if (popupLocation == null)
- popupLocation = new Point();
-
- popupLocation.x = x;
- popupLocation.y = y;
+ popupLocationX = x;
+ popupLocationY = y;
+ // Handle the case when the popup is already showing. In this case we need
+ // to fetch a new popup from PopupFactory and use this. See the general
+ // contract of the PopupFactory.
}
/**
@@ -899,164 +834,13 @@ public class JPopupMenu extends JComponent implements Accessible, MenuElement
}
/**
- * This interface is used to display menu items of the JPopupMenu
- */
- private interface Popup
- {
- /**
- * Displays container on the screen
- *
- * @param x x-coordinate of popup menu's location on the screen
- * @param y y-coordinate of popup menu's location on the screen
- * @param width width of the container that is used to display menu
- * item's for popup menu
- * @param height height of the container that is used to display menu
- * item's for popup menu
- */
- void show(int x, int y, int width, int height);
-
- /**
- * Hides container used to display popup menu item's from the screen
- */
- void hide();
- }
-
- /**
- * This class represents Popup menu that uses light weight container
- * to display its contents.
- */
- private class LightWeightPopup extends Container implements Popup
- {
- private Component c;
-
- /**
- * Creates a new LightWeightPopup menu
- *
- * @param c Container containing menu items
- */
- public LightWeightPopup(Container c)
- {
- this.c = c;
- }
-
- /**
- * Displayes lightweight container with menu items to the screen
- *
- * @param x x-coordinate of lightweight container on the screen
- * @param y y-coordinate of lightweight container on the screen
- * @param width width of the lightweight container
- * @param height height of the lightweight container
- */
- public void show(int x, int y, int width, int height)
- {
- JLayeredPane layeredPane;
- layeredPane = SwingUtilities.getRootPane(invoker).getLayeredPane();
- c.setBounds(x, y, width, height);
- layeredPane.add(c, JLayeredPane.POPUP_LAYER, 0);
- }
-
- /**
- * Hides lightweight container from the screen
- */
- public void hide()
- {
- // FIXME: Right now the lightweight container is removed from JLayered
- // pane. It is probably would be better in order to improve performance
- // to make the container invisible instead of removing it everytime.
- JLayeredPane layeredPane;
- layeredPane = SwingUtilities.getRootPane(invoker).getLayeredPane();
- int index = layeredPane.getIndexOf(c);
- layeredPane.remove(index);
- }
- }
-
- /**
- * MediumWeightPopup is an AWT Panel with JPopupMenu's menu items.
- * It is used to display JPopupMenu's menu items on the screen
- */
- private class MediumWeightPopup extends Panel implements Popup
- {
- /**
- * Creates a new MediumWeightPopup object.
- *
- * @param c Container with JPopupMenu's menu items
- */
- public MediumWeightPopup(Container c)
- {
- this.add(c);
- }
-
- /**
- * Displays AWT Panel with its components on the screen
- *
- * @param x x-coordinate of the upper-left corner of the panel's
- * @param y y-coordinate of the upper-left corner of the panel's
- * @param width width of the panel
- * @param height height of the panel
- */
- public void show(int x, int y, int width, int height)
- {
- JLayeredPane layeredPane;
- layeredPane = SwingUtilities.getRootPane(invoker).getLayeredPane();
- layeredPane.add(this, JLayeredPane.POPUP_LAYER, 0);
- this.setBounds(x, y, width, height);
- }
-
- /**
- * Hides This panel from the screen
- */
- public void hide()
- {
- // FIXME: Right now the lightweight container is removed from JLayered
- // pane. It is probably would be better in order to improve performance
- // to make the container invisible instead of removing it everytime.
- JLayeredPane layeredPane;
- layeredPane = SwingUtilities.getRootPane(invoker).getLayeredPane();
- int index = layeredPane.getIndexOf(this);
- layeredPane.remove(index);
- }
- }
-
- /**
- * HeavyWeightPopup is JWindow that is used to display JPopupMenu menu item's
- * on the screen
- */
- private class HeavyWeightPopup extends JDialog implements Popup
- {
- /**
- * Creates a new HeavyWeightPopup object.
- *
- * @param c Container containing menu items
- */
- public HeavyWeightPopup(Container c)
- {
- this.setContentPane(c);
- this.setUndecorated(true);
- this.getRootPane().setWindowDecorationStyle(JRootPane.PLAIN_DIALOG);
- }
-
- /**
- * Displays JWindow container JPopupMenu's menu items to the screen
- *
- * @param x x-coordinate of JWindow containing menu items
- * @param y y-coordinate of JWindow containing menu items
- * @param width width of the JWindow
- * @param height height of the JWindow
- */
- public void show(int x, int y, int width, int height)
- {
- this.setBounds(x, y, width, height);
- this.show();
- }
- }
-
- /**
* This is the separator that can be used in popup menu.
*/
public static class Separator extends JSeparator
{
public Separator()
{
+ super();
}
public String getUIClassID()
@@ -1071,6 +855,7 @@ public class JPopupMenu extends JComponent implements Accessible, MenuElement
protected AccessibleJPopupMenu()
{
+ // Nothing to do here.
}
public AccessibleRole getAccessibleRole()
@@ -1085,8 +870,9 @@ public class JPopupMenu extends JComponent implements Accessible, MenuElement
{
public void propertyChange(PropertyChangeEvent evt)
{
- JPopupMenu.this.revalidate();
- JPopupMenu.this.repaint();
+ // We used to have a revalidate() and repaint() call here. However I think
+ // this is not needed. Instead, a new Popup has to be fetched from the
+ // PopupFactory and used here.
}
}
}
diff --git a/javax/swing/JProgressBar.java b/javax/swing/JProgressBar.java
index 19815dbfd..0de9115dc 100644
--- a/javax/swing/JProgressBar.java
+++ b/javax/swing/JProgressBar.java
@@ -81,6 +81,8 @@ public class JProgressBar extends JComponent implements SwingConstants,
/**
* AccessibleJProgressBar
*/
+ // FIXME: This inner class is a complete stub and needs to be implemented
+ // properly.
protected class AccessibleJProgressBar extends AccessibleJComponent
implements AccessibleValue
{
@@ -91,6 +93,7 @@ public class JProgressBar extends JComponent implements SwingConstants,
*/
protected AccessibleJProgressBar()
{
+ // Nothing to do here.
}
/**
diff --git a/javax/swing/JRadioButton.java b/javax/swing/JRadioButton.java
index 66f5902e8..e0593f3a5 100644
--- a/javax/swing/JRadioButton.java
+++ b/javax/swing/JRadioButton.java
@@ -192,8 +192,8 @@ public class JRadioButton extends JToggleButton
public JRadioButton(String text, Icon icon, boolean selected)
{
super(text, icon, selected);
- borderPainted = false;
- contentAreaFilled = false;
+ setBorderPainted(false);
+ setHorizontalAlignment(LEADING);
}
/**
diff --git a/javax/swing/JRadioButtonMenuItem.java b/javax/swing/JRadioButtonMenuItem.java
index 76a8fef64..61a8dbab3 100644
--- a/javax/swing/JRadioButtonMenuItem.java
+++ b/javax/swing/JRadioButtonMenuItem.java
@@ -38,9 +38,6 @@ exception statement from your version. */
package javax.swing;
-import java.io.IOException;
-import java.io.ObjectOutputStream;
-
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
@@ -149,10 +146,6 @@ public class JRadioButtonMenuItem extends JMenuItem implements Accessible
model.setSelected(selected);
}
- private void writeObject(ObjectOutputStream stream) throws IOException
- {
- }
-
/**
* This method returns a name to identify which look and feel class will be
* the UI delegate for the menuItem.
@@ -202,6 +195,7 @@ public class JRadioButtonMenuItem extends JMenuItem implements Accessible
*/
protected AccessibleJRadioButtonMenuItem()
{
+ // Nothing to do here.
}
public AccessibleRole getAccessibleRole()
diff --git a/javax/swing/JRootPane.java b/javax/swing/JRootPane.java
index 500083612..b5d436d7e 100644
--- a/javax/swing/JRootPane.java
+++ b/javax/swing/JRootPane.java
@@ -76,6 +76,7 @@ public class JRootPane extends JComponent implements Accessible
*/
protected AccessibleJRootPane()
{
+ // Nothing to do here.
}
/**
@@ -101,6 +102,7 @@ public class JRootPane extends JComponent implements Accessible
*/
protected RootLayout()
{
+ // Nothing to do here.
}
/**
@@ -111,6 +113,7 @@ public class JRootPane extends JComponent implements Accessible
*/
public void addLayoutComponent(Component comp, Object constraints)
{
+ // Nothing to do here.
}
/**
@@ -121,6 +124,7 @@ public class JRootPane extends JComponent implements Accessible
*/
public void addLayoutComponent(String name, Component comp)
{
+ // Nothing to do here.
}
/**
@@ -154,6 +158,7 @@ public class JRootPane extends JComponent implements Accessible
*/
public void invalidateLayout(Container target)
{
+ // Nothing to do here.
}
/**
@@ -309,6 +314,7 @@ public class JRootPane extends JComponent implements Accessible
*/
public void removeLayoutComponent(Component comp)
{
+ // Nothing to do here.
}
}
@@ -340,6 +346,32 @@ public class JRootPane extends JComponent implements Accessible
protected JButton defaultButton;
/**
+ * This field is unused since JDK1.3. To override the default action you
+ * should modify the JRootPane's ActionMap.
+ *
+ * @deprecated since JDK1.3
+ *
+ * @specnote the specs indicate that the type of this field is
+ * a package private inner class
+ * javax.swing.JRootPane.DefaultAction. I assume that the closest
+ * public superclass is javax.swing.Action.
+ */
+ protected Action defaultPressAction;
+
+ /**
+ * This field is unused since JDK1.3. To override the default action you
+ * should modify the JRootPane's ActionMap.
+ *
+ * @deprecated since JDK1.3
+ *
+ * @specnote the specs indicate that the type of this field is
+ * a package private inner class
+ * javax.swing.JRootPane.DefaultAction. I assume that the closest
+ * public superclass is javax.swing.Action.
+ */
+ protected Action defaultReleaseAction;
+
+ /**
* @since 1.4
*/
private int windowDecorationStyle = NONE;
@@ -504,7 +536,6 @@ public class JRootPane extends JComponent implements Accessible
getGlassPane();
getLayeredPane();
getContentPane();
- setDoubleBuffered(true);
updateUI();
}
diff --git a/javax/swing/JScrollPane.java b/javax/swing/JScrollPane.java
index 42d8ea76f..45dfbf506 100644
--- a/javax/swing/JScrollPane.java
+++ b/javax/swing/JScrollPane.java
@@ -40,13 +40,14 @@ package javax.swing;
import java.awt.Component;
import java.awt.ComponentOrientation;
-import java.awt.Dimension;
import java.awt.Insets;
import java.awt.LayoutManager;
-import java.awt.Point;
import java.awt.Rectangle;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
import javax.swing.border.Border;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
@@ -77,10 +78,73 @@ import javax.swing.plaf.UIResource;
* <tr><td>wheelScrollingEnabled </td><td>scrollPane </td><td>yes </td></tr>
* </table>
*/
-public class JScrollPane
- extends JComponent
+public class JScrollPane extends JComponent
implements Accessible, ScrollPaneConstants
{
+ /**
+ * Provides accessibility support for the <code>JScrollPane</code>.
+ *
+ * @author Roman Kennke (kennke@aicas.com)
+ */
+ protected class AccessibleJScrollPane extends AccessibleJComponent
+ implements ChangeListener, PropertyChangeListener
+ {
+
+ /**
+ * The viewport of the underlying scrollpane.
+ */
+ protected JViewport viewPort;
+
+ /**
+ * Creates a new <code>AccessibleJScrollPane</code> object. This
+ * initializes the <code>viewport</code> field with the current viewport
+ * from the scrollpane associated with this
+ * <code>AccessibleJScrollPane</code>.
+ */
+ public AccessibleJScrollPane()
+ {
+ viewPort = getViewport();
+ viewPort.addChangeListener(this);
+ viewPort.addPropertyChangeListener(this);
+ }
+
+ /**
+ * Receives notification when the state of the viewport changes.
+ *
+ * @param event the change event
+ */
+ public void stateChanged(ChangeEvent event)
+ {
+ // TODO: Figure out what should be done here, if anything.
+ }
+
+ /**
+ * Receives notification if any of the viewport's bound properties changes.
+ *
+ * @param e the propery change event
+ */
+ public void propertyChange(PropertyChangeEvent e)
+ {
+ // TODO: Figure out what should be done here, if anything.
+ }
+
+ /**
+ * Resets the <code>viewPort</code> field when the scrollpane's viewport
+ * changes. This method is called by
+ * {@link JScrollPane#setViewport(JViewport)} in order to update the
+ * <code>viewPort</code> field and set up the listeners on this viewport
+ * correctly.
+ */
+ public void resetViewPort()
+ {
+ viewPort.removeChangeListener(this);
+ viewPort.removePropertyChangeListener(this);
+ viewPort = getViewport();
+ viewPort.addChangeListener(this);
+ viewPort.addPropertyChangeListener(this);
+ }
+ }
+
private static final long serialVersionUID = 5203525440012340014L;
protected JViewport columnHeader;
@@ -100,7 +164,6 @@ public class JScrollPane
Border viewportBorder;
boolean wheelScrollingEnabled;
- ChangeListener scrollListener;
public JViewport getColumnHeader()
{
@@ -331,18 +394,6 @@ public class JScrollPane
firePropertyChange("horizontalScrollBar", old, h);
sync();
- if (old != null)
- {
- BoundedRangeModel model = old.getModel();
- if (model != null)
- model.removeChangeListener(scrollListener);
- }
- if (h != null)
- {
- BoundedRangeModel model = h.getModel();
- if (model != null)
- model.addChangeListener(scrollListener);
- }
}
public void setHorizontalScrollBarPolicy(int h)
@@ -359,6 +410,7 @@ public class JScrollPane
horizontalScrollBarPolicy = h;
firePropertyChange("horizontalScrollBarPolicy", old, h);
sync();
+ revalidate();
}
public void setLayout(LayoutManager l)
@@ -403,19 +455,6 @@ public class JScrollPane
addNonNull(v, JScrollPane.VERTICAL_SCROLLBAR);
firePropertyChange("verticalScrollBar", old, v);
sync();
-
- if (old != null)
- {
- BoundedRangeModel model = old.getModel();
- if (model != null)
- model.removeChangeListener(scrollListener);
- }
- if (v != null)
- {
- BoundedRangeModel model = v.getModel();
- if (model != null)
- model.addChangeListener(scrollListener);
- }
}
public void setVerticalScrollBarPolicy(int v)
@@ -432,6 +471,7 @@ public class JScrollPane
verticalScrollBarPolicy = v;
firePropertyChange("verticalScrollBarPolicy", old, v);
sync();
+ revalidate();
}
public void setWheelScrollingEnabled(boolean b)
@@ -452,16 +492,17 @@ public class JScrollPane
JViewport old = viewport;
removeNonNull(old);
- if (old != null)
- old.removeChangeListener(scrollListener);
viewport = v;
- if (v != null)
- v.addChangeListener(scrollListener);
addNonNull(v, JScrollPane.VIEWPORT);
revalidate();
repaint();
firePropertyChange("viewport", old, v);
sync();
+ if (accessibleContext != null)
+ {
+ AccessibleJScrollPane asp = (AccessibleJScrollPane) accessibleContext;
+ asp.resetViewPort();
+ }
}
public void setViewportBorder(Border b)
@@ -494,79 +535,6 @@ public class JScrollPane
return true;
}
- ChangeListener createScrollListener()
- {
- return new ChangeListener()
- {
-
- public void stateChanged(ChangeEvent event)
- {
- JScrollBar vsb = JScrollPane.this.getVerticalScrollBar();
- JScrollBar hsb = JScrollPane.this.getHorizontalScrollBar();
- JViewport vp = JScrollPane.this.getViewport();
-
- if (vp != null && event.getSource() == vp)
- {
- // if the viewport changed, we should update the VSB / HSB
- // models according to the new vertical and horizontal sizes
-
- Rectangle vr = vp.getViewRect();
- Dimension vs = vp.getViewSize();
- if (vsb != null
- && (vsb.getMinimum() != 0
- || vsb.getMaximum() != vs.height
- || vsb.getValue() != vr.y
- || vsb.getVisibleAmount() != vr.height))
- vsb.setValues(vr.y, vr.height, 0, vs.height);
-
- if (hsb != null
- && (hsb.getMinimum() != 0
- || hsb.getMaximum() != vs.width
- || hsb.getValue() != vr.width
- || hsb.getVisibleAmount() != vr.height))
- hsb.setValues(vr.x, vr.width, 0, vs.width);
- }
- else
- {
- // otherwise we got a change update from either the VSB or
- // HSB model, and we need to update the viewport positions of
- // both the main viewport and any row or column headers to
- // match.
-
- int xpos = 0;
- int ypos = 0;
-
- if (vsb != null)
- ypos = vsb.getValue();
-
- if (hsb != null)
- xpos = hsb.getValue();
-
- Point pt = new Point(xpos, ypos);
-
- if (vp != null
- && vp.getViewPosition() != pt)
- vp.setViewPosition(pt);
-
- pt.x = 0;
-
- if (rowHeader != null
- && rowHeader.getViewPosition() != pt)
- rowHeader.setViewPosition(pt);
-
- pt.x = xpos;
- pt.y = 0;
-
- if (columnHeader != null
- && columnHeader.getViewPosition() != pt)
- columnHeader.setViewPosition(pt);
-
- }
- }
- };
- }
-
-
/**
* Creates a new <code>JScrollPane</code> without a view. The scrollbar
* policy is set to {@link #VERTICAL_SCROLLBAR_AS_NEEDED} and
@@ -627,7 +595,6 @@ public class JScrollPane
*/
public JScrollPane(Component view, int vsbPolicy, int hsbPolicy)
{
- scrollListener = createScrollListener();
setVerticalScrollBarPolicy(vsbPolicy);
setVerticalScrollBar(createVerticalScrollBar());
setHorizontalScrollBarPolicy(hsbPolicy);
@@ -635,7 +602,6 @@ public class JScrollPane
viewport = createViewport();
if (view != null)
getViewport().setView(view);
- viewport.addChangeListener(scrollListener);
add(viewport,0);
setLayout(new ScrollPaneLayout());
setOpaque(false);
@@ -728,4 +694,18 @@ public class JScrollPane
}
}
}
+
+ /**
+ * Returns the accessible context associated with this
+ * <code>JScrollPane</code>.
+ *
+ * @return the accessible context associated with this
+ * <code>JScrollPane</code>
+ */
+ public AccessibleContext getAccessibleContext()
+ {
+ if (accessibleContext == null)
+ accessibleContext = new AccessibleJScrollPane();
+ return accessibleContext;
+ }
}
diff --git a/javax/swing/JSeparator.java b/javax/swing/JSeparator.java
index 6a3b97d35..602af6a38 100644
--- a/javax/swing/JSeparator.java
+++ b/javax/swing/JSeparator.java
@@ -62,6 +62,7 @@ public class JSeparator extends JComponent implements SwingConstants,
*/
protected AccessibleJSeparator()
{
+ // Nothing to do here.
}
/**
@@ -131,7 +132,6 @@ public class JSeparator extends JComponent implements SwingConstants,
public void updateUI()
{
setUI((SeparatorUI) UIManager.getUI(this));
- invalidate();
}
/**
diff --git a/javax/swing/JSlider.java b/javax/swing/JSlider.java
index 2caf509a1..b28b06aba 100644
--- a/javax/swing/JSlider.java
+++ b/javax/swing/JSlider.java
@@ -118,6 +118,8 @@ public class JSlider extends JComponent implements SwingConstants, Accessible,
/**
* DOCUMENT ME!
*/
+ // FIXME: This inner class is a complete stub and needs to be implemented
+ // properly.
protected class AccessibleJSlider extends JComponent.AccessibleJComponent
implements AccessibleValue
{
@@ -128,6 +130,7 @@ public class JSlider extends JComponent implements SwingConstants, Accessible,
*/
protected AccessibleJSlider()
{
+ // Nothing to do here.
}
/**
diff --git a/javax/swing/JSpinner.java b/javax/swing/JSpinner.java
index fc2b13e81..af34d9cf6 100644
--- a/javax/swing/JSpinner.java
+++ b/javax/swing/JSpinner.java
@@ -108,10 +108,10 @@ public class JSpinner extends JComponent
/**
* DOCUMENT ME!
*/
- public void commitEdit()
- throws ParseException
+ public void commitEdit() throws ParseException
{
- } /* TODO */
+ // TODO: Implement this properly.
+ }
/**
* DOCUMENT ME!
@@ -184,7 +184,8 @@ public class JSpinner extends JComponent
*/
public void propertyChange(PropertyChangeEvent event)
{
- } /* TODO */
+ // TODO: Implement this properly.
+ }
/**
* DOCUMENT ME!
@@ -193,11 +194,12 @@ public class JSpinner extends JComponent
*/
public void stateChanged(ChangeEvent event)
{
- } /* TODO */
+ // TODO: Implement this properly.
+ }
- /* no-ops */
public void removeLayoutComponent(Component child)
{
+ // Nothing to do here.
}
/**
@@ -208,6 +210,7 @@ public class JSpinner extends JComponent
*/
public void addLayoutComponent(String name, Component child)
{
+ // Nothing to do here.
}
}
@@ -258,6 +261,31 @@ public class JSpinner extends JComponent
}
/**
+ * A <code>JSpinner</code> editor used for the {@link SpinnerListModel}.
+ * This editor uses a <code>JFormattedTextField</code> to edit the values
+ * of the spinner.
+ *
+ * @author Roman Kennke (kennke@aicas.com)
+ */
+ public static class ListEditor extends DefaultEditor
+ {
+ /**
+ * Creates a new instance of <code>ListEditor</code>.
+ *
+ * @param spinner the spinner for which this editor is used
+ */
+ public ListEditor(JSpinner spinner)
+ {
+ super(spinner);
+ }
+
+ public SpinnerListModel getModel()
+ {
+ return (SpinnerListModel) getSpinner().getModel();
+ }
+ }
+
+ /**
* An editor class for a <code>JSpinner</code> that is used
* for displaying and editing dates (e.g. that uses
* <code>SpinnerDateModel</code> as model).
@@ -307,7 +335,7 @@ public class JSpinner extends JComponent
/**
* Initializes the JFormattedTextField for this editor.
*
- * @param the date format to use in the formatted text field
+ * @param format the date format to use in the formatted text field
*/
private void init(SimpleDateFormat format)
{
diff --git a/javax/swing/JSplitPane.java b/javax/swing/JSplitPane.java
index cea5afef2..cdab7bb6c 100644
--- a/javax/swing/JSplitPane.java
+++ b/javax/swing/JSplitPane.java
@@ -59,6 +59,8 @@ public class JSplitPane extends JComponent implements Accessible
/**
* DOCUMENT ME!
*/
+ // FIXME: This inner class is a complete stub and must be implemented
+ // properly.
protected class AccessibleJSplitPane extends JComponent.AccessibleJComponent
implements AccessibleValue
{
@@ -69,6 +71,7 @@ public class JSplitPane extends JComponent implements Accessible
*/
protected AccessibleJSplitPane()
{
+ // Nothing to do here.
}
/**
diff --git a/javax/swing/JTabbedPane.java b/javax/swing/JTabbedPane.java
index 77e49cba5..8ef1d8f11 100644
--- a/javax/swing/JTabbedPane.java
+++ b/javax/swing/JTabbedPane.java
@@ -75,6 +75,8 @@ public class JTabbedPane extends JComponent implements Serializable,
/**
* Accessibility support for <code>JTabbedPane</code>.
*/
+ // FIXME: This inner class is a complete stub and must be implemented
+ // properly.
protected class AccessibleJTabbedPane extends JComponent.AccessibleJComponent
implements AccessibleSelection, ChangeListener
{
@@ -99,6 +101,7 @@ public class JTabbedPane extends JComponent implements Serializable,
*/
public void stateChanged(ChangeEvent e)
{
+ // Implement this properly.
}
/**
@@ -208,6 +211,7 @@ public class JTabbedPane extends JComponent implements Serializable,
*/
public void addAccessibleSelection(int i)
{
+ // TODO: Implement this properly.
}
/**
@@ -217,6 +221,7 @@ public class JTabbedPane extends JComponent implements Serializable,
*/
public void removeAccessibleSelection(int i)
{
+ // TODO: Implement this properly.
}
/**
@@ -224,6 +229,7 @@ public class JTabbedPane extends JComponent implements Serializable,
*/
public void clearAccessibleSelection()
{
+ // TODO: Implement this properly.
}
/**
@@ -231,6 +237,7 @@ public class JTabbedPane extends JComponent implements Serializable,
*/
public void selectAllAccessibleSelection()
{
+ // TODO: Implement this properly.
}
}
@@ -247,6 +254,7 @@ public class JTabbedPane extends JComponent implements Serializable,
*/
protected ModelListener()
{
+ // Nothing to do here.
}
/**
diff --git a/javax/swing/JTable.java b/javax/swing/JTable.java
index 531838ab1..39673b19c 100644
--- a/javax/swing/JTable.java
+++ b/javax/swing/JTable.java
@@ -45,8 +45,6 @@ import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
-import java.awt.event.KeyAdapter;
-import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.text.DateFormat;
@@ -58,6 +56,10 @@ import java.util.Vector;
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleExtendedTable;
+import javax.accessibility.AccessibleSelection;
+import javax.accessibility.AccessibleTable;
+import javax.accessibility.AccessibleTableModelChange;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ListSelectionEvent;
@@ -78,15 +80,414 @@ import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;
import javax.swing.text.Caret;
-public class JTable extends JComponent
+public class JTable
+ extends JComponent
implements TableModelListener, Scrollable, TableColumnModelListener,
ListSelectionListener, CellEditorListener, Accessible
{
/**
+ * Provides accessibility support for <code>JTable</code>.
+ *
+ * @author Roman Kennke (kennke@aicas.com)
+ */
+ protected class AccessibleJTable
+ extends AccessibleJComponent
+ implements AccessibleSelection, ListSelectionListener, TableModelListener,
+ TableColumnModelListener, CellEditorListener, PropertyChangeListener,
+ AccessibleExtendedTable
+ {
+
+ protected class AccessibleJTableModelChange
+ implements AccessibleTableModelChange
+ {
+ protected int type;
+ protected int firstRow;
+ protected int lastRow;
+ protected int firstColumn;
+ protected int lastColumn;
+
+ protected AccessibleJTableModelChange(int type, int firstRow,
+ int lastRow, int firstColumn,
+ int lastColumn)
+ {
+ this.type = type;
+ this.firstRow = firstRow;
+ this.lastRow = lastRow;
+ this.firstColumn = firstColumn;
+ this.lastColumn = lastColumn;
+ }
+
+ public int getType()
+ {
+ return type;
+ }
+
+ public int getFirstRow()
+ {
+ return firstRow;
+ }
+
+ public int getLastRow()
+ {
+ return lastRow;
+ }
+
+ public int getFirstColumn()
+ {
+ return firstColumn;
+ }
+
+ public int getLastColumn()
+ {
+ return lastColumn;
+ }
+ }
+
+ /**
+ * Creates a new <code>AccessibleJTable</code>.
+ *
+ * @since JDK1.5
+ */
+ protected AccessibleJTable()
+ {
+ getModel().addTableModelListener(this);
+ getSelectionModel().addListSelectionListener(this);
+ getColumnModel().addColumnModelListener(this);
+ getCellEditor().addCellEditorListener(this);
+ }
+
+ /**
+ * Returns the number of selected items in this table.
+ */
+ public int getAccessibleSelectionCount()
+ {
+ return getSelectedColumnCount();
+ }
+
+ public Accessible getAccessibleSelection(int i)
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public boolean isAccessibleChildSelected(int i)
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public void addAccessibleSelection(int i)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void removeAccessibleSelection(int i)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void clearAccessibleSelection()
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void selectAllAccessibleSelection()
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void valueChanged(ListSelectionEvent event)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /**
+ * Receives notification when the table model changes. Depending on the
+ * type of change, this method calls {@link #tableRowsInserted} or
+ * {@link #tableRowsDeleted}.
+ *
+ * @param event the table model event
+ */
+ public void tableChanged(TableModelEvent event)
+ {
+ switch (event.getType())
+ {
+ case TableModelEvent.INSERT:
+ tableRowsInserted(event);
+ break;
+ case TableModelEvent.DELETE:
+ tableRowsDeleted(event);
+ break;
+ }
+ }
+
+ /**
+ * Receives notification when one or more rows have been inserted into the
+ * table.
+ *
+ * @param event the table model event
+ */
+ public void tableRowsInserted(TableModelEvent event)
+ {
+ // TODO: What to do here, if anything? This might be a hook method for
+ // subclasses...
+ }
+
+ /**
+ * Receives notification when one or more rows have been deleted from the
+ * table.
+ *
+ * @param event the table model event
+ */
+ public void tableRowsDeleted(TableModelEvent event)
+ {
+ // TODO: What to do here, if anything? This might be a hook method for
+ // subclasses...
+ }
+
+ public void columnAdded(TableColumnModelEvent event)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void columnMarginChanged(ChangeEvent event)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void columnMoved(TableColumnModelEvent event)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void columnRemoved(TableColumnModelEvent event)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void columnSelectionChanged(ListSelectionEvent event)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void editingCanceled(ChangeEvent event)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void editingStopped(ChangeEvent event)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /**
+ * Receives notification when any of the JTable's properties changes. This
+ * is used to replace the listeners on the table's model, selection model,
+ * column model and cell editor.
+ *
+ * @param e the property change event
+ */
+ public void propertyChange(PropertyChangeEvent e)
+ {
+ String propName = e.getPropertyName();
+ if (propName.equals("tableModel"))
+ {
+ TableModel oldModel = (TableModel) e.getOldValue();
+ oldModel.removeTableModelListener(this);
+ TableModel newModel = (TableModel) e.getNewValue();
+ newModel.addTableModelListener(this);
+ }
+ else if (propName.equals("columnModel"))
+ {
+ TableColumnModel oldModel = (TableColumnModel) e.getOldValue();
+ oldModel.removeColumnModelListener(this);
+ TableColumnModel newModel = (TableColumnModel) e.getNewValue();
+ newModel.addColumnModelListener(this);
+ }
+ else if (propName.equals("selectionModel"))
+ {
+ ListSelectionModel oldModel = (ListSelectionModel) e.getOldValue();
+ oldModel.removeListSelectionListener(this);
+ ListSelectionModel newModel = (ListSelectionModel) e.getNewValue();
+ newModel.addListSelectionListener(this);
+ }
+ else if (propName.equals("cellEditor"))
+ {
+ CellEditor oldEd = (CellEditor) e.getOldValue();
+ oldEd.removeCellEditorListener(this);
+ CellEditor newEd = (CellEditor) e.getNewValue();
+ newEd.addCellEditorListener(this);
+ }
+ }
+
+ public int getAccessibleRow(int index)
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public int getAccessibleColumn(int index)
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public int getAccessibleIndex(int r, int c)
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public Accessible getAccessibleCaption()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void setAccessibleCaption(Accessible caption)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public Accessible getAccessibleSummary()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void setAccessibleSummary(Accessible summary)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public int getAccessibleRowCount()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public int getAccessibleColumnCount()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public Accessible getAccessibleAt(int r, int c)
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public int getAccessibleRowExtentAt(int r, int c)
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public int getAccessibleColumnExtentAt(int r, int c)
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public AccessibleTable getAccessibleRowHeader()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void setAccessibleRowHeader(AccessibleTable header)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public AccessibleTable getAccessibleColumnHeader()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void setAccessibleColumnHeader(AccessibleTable header)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public Accessible getAccessibleRowDescription(int r)
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void setAccessibleRowDescription(int r, Accessible description)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public Accessible getAccessibleColumnDescription(int c)
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void setAccessibleColumnDescription(int c, Accessible description)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public boolean isAccessibleSelected(int r, int c)
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public boolean isAccessibleRowSelected(int r)
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public boolean isAccessibleColumnSelected(int c)
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public int[] getSelectedAccessibleRows()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public int[] getSelectedAccessibleColumns()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ }
+ /**
* Handles property changes from the <code>TableColumn</code>s of this
* <code>JTable</code>.
*
- * More specifically, this triggers a {@link #revalidate} call if the
+ * More specifically, this triggers a {@link #revalidate()} call if the
* preferredWidth of one of the observed columns changes.
*/
class TableColumnPropertyChangeHandler implements PropertyChangeListener
@@ -393,7 +794,7 @@ public class JTable extends JComponent
* property when the {@link #dataModel} property is changed.
*
* @see #setModel(TableModel)
- * @see #createColumnsFromModel()
+ * @see #createDefaultColumnsFromModel()
* @see #setColumnModel(TableColumnModel)
* @see #setAutoCreateColumnsFromModel(boolean)
* @see #getAutoCreateColumnsFromModel()
@@ -509,11 +910,6 @@ public class JTable extends JComponent
protected ListSelectionModel selectionModel;
/**
- * The accessibleContext property.
- */
- protected AccessibleContext accessibleContext;
-
- /**
* The current cell editor.
*/
protected TableCellEditor cellEditor;
@@ -521,7 +917,7 @@ public class JTable extends JComponent
/**
* Whether or not drag-and-drop is enabled on this table.
*
- * @see #setDragEnabled()
+ * @see #setDragEnabled(boolean)
* @see #getDragEnabled()
*/
private boolean dragEnabled;
@@ -678,24 +1074,28 @@ public class JTable extends JComponent
*/
public JTable (TableModel dm, TableColumnModel cm, ListSelectionModel sm)
{
- setModel(dm == null ? createDefaultDataModel() : dm);
- setSelectionModel(sm == null ? createDefaultSelectionModel() : sm);
-
+ boolean autoCreate = false;
if (cm != null)
- {
setColumnModel(cm);
- setAutoCreateColumnsFromModel(false);
- }
else
{
setColumnModel(createDefaultColumnModel());
- setAutoCreateColumnsFromModel(true);
- }
+ autoCreate = true;
+ }
+ setSelectionModel(sm == null ? createDefaultSelectionModel() : sm);
+ setModel(dm == null ? createDefaultDataModel() : dm);
+ setAutoCreateColumnsFromModel(autoCreate);
initializeLocalVars();
- // The next two lines are for compliance with the JDK which starts
- // the JLists associated with a JTable with both lead selection
- // indices at 0, rather than -1 as in regular JLists
+ // The following four lines properly set the lead selection indices.
+ // After this, the UI will handle the lead selection indices.
+ // FIXME: this should probably not be necessary, if the UI is installed
+ // before the TableModel is set then the UI will handle things on its
+ // own, but certain variables need to be set before the UI can be installed
+ // so we must get the correct order for all the method calls in this
+ // constructor.
+ selectionModel.setAnchorSelectionIndex(0);
selectionModel.setLeadSelectionIndex(0);
+ columnModel.getSelectionModel().setAnchorSelectionIndex(0);
columnModel.getSelectionModel().setLeadSelectionIndex(0);
updateUI();
}
@@ -919,6 +1319,12 @@ public class JTable extends JComponent
createDefaultColumnsFromModel();
+ // If the structure changes, we need to revalidate, since that might
+ // affect the size parameters of the JTable. Otherwise we only need
+ // to perform a repaint to update the view.
+ if (event.getType() == TableModelEvent.INSERT
+ || event.getType() == TableModelEvent.DELETE)
+ revalidate();
repaint();
}
@@ -971,8 +1377,7 @@ public class JTable extends JComponent
{
int y0 = getLocation().y;
int nrows = getRowCount();
- Dimension gap = getIntercellSpacing();
- int height = getRowHeight() + (gap == null ? 0 : gap.height);
+ int height = getRowHeight();
int y = point.y;
for (int i = 0; i < nrows; ++i)
@@ -1093,13 +1498,14 @@ public class JTable extends JComponent
// scroll direction.
if (orientation == SwingConstants.VERTICAL)
- return rowHeight;
+ return direction * rowHeight;
else
{
int sum = 0;
for (int i = 0; i < getColumnCount(); ++i)
sum += columnModel.getColumn(0).getWidth();
- return getColumnCount() == 0 ? 10 : sum / getColumnCount();
+ int inc = getColumnCount() == 0 ? 10 : sum / getColumnCount();
+ return direction * inc;
}
}
@@ -1680,7 +2086,9 @@ public class JTable extends JComponent
// Don't do anything if setting the current model again.
if (dataModel == m)
return;
-
+
+ TableModel oldModel = dataModel;
+
// Remove table as TableModelListener from old model.
if (dataModel != null)
dataModel.removeTableModelListener(this);
@@ -1697,7 +2105,10 @@ public class JTable extends JComponent
if (autoCreateColumnsFromModel)
createDefaultColumnsFromModel();
}
-
+
+ // This property is bound, so we fire a property change event.
+ firePropertyChange("model", oldModel, dataModel);
+
// Repaint table.
revalidate();
repaint();
@@ -1983,7 +2394,8 @@ public class JTable extends JComponent
int average = spill / cols.length;
for (int i = 0; i < cols.length; i++)
{
- cols[i].setWidth(cols[i].getWidth() + average);
+ if (cols[i] != null)
+ cols[i].setWidth(cols[i].getWidth() + average);
}
}
@@ -2402,4 +2814,13 @@ public class JTable extends JComponent
return editor.getTableCellEditorComponent
(this, getValueAt(row, column), isCellSelected(row, column), row, column);
}
+
+ /**
+ * This revalidates the <code>JTable</code> and queues a repaint.
+ */
+ protected void resizeAndRepaint()
+ {
+ revalidate();
+ repaint();
+ }
}
diff --git a/javax/swing/JTextArea.java b/javax/swing/JTextArea.java
index e2157bcc6..2fa185b62 100644
--- a/javax/swing/JTextArea.java
+++ b/javax/swing/JTextArea.java
@@ -42,6 +42,8 @@ import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Rectangle;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleStateSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.Element;
@@ -92,6 +94,35 @@ import javax.swing.text.View;
public class JTextArea extends JTextComponent
{
/**
+ * Provides accessibility support for <code>JTextArea</code>.
+ *
+ * @author Roman Kennke (kennke@aicas.com)
+ */
+ protected class AccessibleJTextArea extends AccessibleJTextComponent
+ {
+
+ /**
+ * Creates a new <code>AccessibleJTextArea</code> object.
+ */
+ protected AccessibleJTextArea()
+ {
+ super();
+ }
+
+ /**
+ * Returns the accessible state of this <code>AccessibleJTextArea</code>.
+ *
+ * @return the accessible state of this <code>AccessibleJTextArea</code>
+ */
+ public AccessibleStateSet getAccessibleStateSet()
+ {
+ AccessibleStateSet state = super.getAccessibleStateSet();
+ // TODO: Figure out what state must be added here to the super's state.
+ return state;
+ }
+ }
+
+ /**
* Compatible with Sun's JDK
*/
private static final long serialVersionUID = -6141680179310439825L;
@@ -557,4 +588,16 @@ public class JTextArea extends JTextComponent
return new Dimension(Math.max(reqWidth, neededWidth),
Math.max(reqHeight, neededHeight));
}
+
+ /**
+ * Returns the accessible context associated with the <code>JTextArea</code>.
+ *
+ * @return the accessible context associated with the <code>JTextArea</code>
+ */
+ public AccessibleContext getAccessibleContext()
+ {
+ if (accessibleContext == null)
+ accessibleContext = new AccessibleJTextArea();
+ return accessibleContext;
+ }
}
diff --git a/javax/swing/JTextField.java b/javax/swing/JTextField.java
index 5ae9c9f1a..845edc001 100644
--- a/javax/swing/JTextField.java
+++ b/javax/swing/JTextField.java
@@ -46,9 +46,8 @@ import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
+import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleStateSet;
-import javax.swing.text.AttributeSet;
-import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent;
import javax.swing.text.PlainDocument;
@@ -69,15 +68,19 @@ public class JTextField extends JTextComponent
*/
protected AccessibleJTextField()
{
+ super();
}
/**
- * getAccessibleStateSet
- * @return AccessibleStateSet
+ * Returns the accessible state of this <code>AccessibleJTextField</code>.
+ *
+ * @return the accessible state of this <code>AccessibleJTextField</code>
*/
public AccessibleStateSet getAccessibleStateSet()
{
- return null;
+ AccessibleStateSet state = super.getAccessibleStateSet();
+ // TODO: Figure out what state must be added here to the super's state.
+ return state;
}
}
@@ -92,17 +95,17 @@ public class JTextField extends JTextComponent
public static final String notifyAction = "notify-field-accept";
static
- {
- actions = new Action[1];
- actions[0] = new TextAction(notifyAction)
+ {
+ actions = new Action[1];
+ actions[0] = new TextAction(notifyAction)
{
- public void actionPerformed(ActionEvent event)
- {
- JTextField textField = (JTextField) event.getSource();
- textField.fireActionPerformed();
- }
+ public void actionPerformed(ActionEvent event)
+ {
+ JTextField textField = (JTextField) event.getSource();
+ textField.fireActionPerformed();
+ }
};
- }
+ }
private int columns;
private int align;
@@ -117,6 +120,11 @@ public class JTextField extends JTextComponent
private PropertyChangeListener actionPropertyChangeListener;
/**
+ * The horizontal visibility of the textfield.
+ */
+ private BoundedRangeModel horizontalVisibility;
+
+ /**
* Creates a new instance of <code>JTextField</code>.
*/
public JTextField()
@@ -172,9 +180,9 @@ public class JTextField extends JTextComponent
{
if (columns < 0)
throw new IllegalArgumentException();
-
+
this.columns = columns;
-
+
setDocument(doc == null ? createDefaultModel() : doc);
if (text != null)
@@ -182,6 +190,9 @@ public class JTextField extends JTextComponent
// default value for alignment
align = LEADING;
+
+ // Initialize the horizontal visibility model.
+ horizontalVisibility = new DefaultBoundedRangeModel();
}
/**
@@ -192,15 +203,7 @@ public class JTextField extends JTextComponent
*/
protected Document createDefaultModel()
{
- // subclassed to swallow newlines
- return new PlainDocument() {
- public void insertString(int offset, String str, AttributeSet a)
- throws BadLocationException
- {
- if (str != null && str.indexOf('\n') == -1)
- super.insertString(offset, str, a);
- }
- };
+ return new PlainDocument();
}
/**
@@ -268,6 +271,11 @@ public class JTextField extends JTextComponent
return columns;
}
+ /**
+ * Sets the number of columns and then invalidates the layout.
+ * @param columns the number of columns
+ * @throws IllegalArgumentException if columns < 0
+ */
public void setColumns(int columns)
{
if (columns < 0)
@@ -275,16 +283,31 @@ public class JTextField extends JTextComponent
this.columns = columns;
invalidate();
+ //FIXME: do we need this repaint call?
repaint();
}
+ /**
+ * Returns the horizontal alignment, which is one of: JTextField.LEFT,
+ * JTextField.CENTER, JTextField.RIGHT, JTextField.LEADING,
+ * JTextField.TRAILING.
+ * @return the horizontal alignment
+ */
public int getHorizontalAlignment()
{
return align;
}
+ /**
+ * Sets the horizontal alignment of the text. Calls invalidate and repaint
+ * and fires a property change event.
+ * @param newAlign must be one of: JTextField.LEFT, JTextField.CENTER,
+ * JTextField.RIGHT, JTextField.LEADING, JTextField.TRAILING.
+ * @throws IllegalArgumentException if newAlign is not one of the above.
+ */
public void setHorizontalAlignment(int newAlign)
{
+ //FIXME: should throw an IllegalArgumentException if newAlign is invalid
if (align == newAlign)
return;
@@ -295,12 +318,20 @@ public class JTextField extends JTextComponent
repaint();
}
+ /**
+ * Sets the current font and revalidates so the font will take effect.
+ */
public void setFont(Font newFont)
{
super.setFont(newFont);
revalidate();
}
+ /**
+ * Returns the preferred size. If there is a non-zero number of columns,
+ * this is the number of columns multiplied by the column width, otherwise
+ * it returns super.getPreferredSize().
+ */
public Dimension getPreferredSize()
{
Dimension size = super.getPreferredSize();
@@ -318,6 +349,7 @@ public class JTextField extends JTextComponent
*/
public int getScrollOffset()
{
+ //FIXME: this should return horizontalVisibility's value
return scrollOffset;
}
@@ -328,9 +360,15 @@ public class JTextField extends JTextComponent
*/
public void setScrollOffset(int offset)
{
+ //FIXME: this should actualy scroll the field if needed
scrollOffset = offset;
}
+ /**
+ * Returns the set of Actions that are commands for the editor.
+ * This is the actions supported by this editor plus the actions
+ * of the UI (returned by JTextComponent.getActions()).
+ */
public Action[] getActions()
{
return TextAction.augmentList(super.getActions(), actions);
@@ -364,26 +402,27 @@ public class JTextField extends JTextComponent
if (action != null)
{
- removeActionListener(action);
- action.removePropertyChangeListener(actionPropertyChangeListener);
- actionPropertyChangeListener = null;
+ removeActionListener(action);
+ action.removePropertyChangeListener(actionPropertyChangeListener);
+ actionPropertyChangeListener = null;
}
-
+
Action oldAction = action;
action = newAction;
if (action != null)
{
- addActionListener(action);
- actionPropertyChangeListener =
- createActionPropertyChangeListener(action);
- action.addPropertyChangeListener(actionPropertyChangeListener);
+ addActionListener(action);
+ actionPropertyChangeListener = createActionPropertyChangeListener(action);
+ action.addPropertyChangeListener(actionPropertyChangeListener);
}
-
+
+ //FIXME: is this a hack? The horizontal alignment hasn't changed
firePropertyChange("horizontalAlignment", oldAction, newAction);
}
/**
+ * Sets the command string used in action events.
* @since 1.3
*/
public void setActionCommand(String command)
@@ -397,45 +436,79 @@ public class JTextField extends JTextComponent
protected PropertyChangeListener createActionPropertyChangeListener(Action action)
{
return new PropertyChangeListener()
+ {
+ public void propertyChange(PropertyChangeEvent event)
{
- public void propertyChange(PropertyChangeEvent event)
- {
- // Update properties "action" and "horizontalAlignment".
- String name = event.getPropertyName();
-
- if (name.equals("enabled"))
- {
- boolean enabled = ((Boolean) event.getNewValue()).booleanValue();
- JTextField.this.setEnabled(enabled);
- }
- else if (name.equals(Action.SHORT_DESCRIPTION))
- {
- JTextField.this.setToolTipText((String) event.getNewValue());
- }
- }
- };
+ // Update properties "action" and "horizontalAlignment".
+ String name = event.getPropertyName();
+
+ if (name.equals("enabled"))
+ {
+ boolean enabled = ((Boolean) event.getNewValue()).booleanValue();
+ JTextField.this.setEnabled(enabled);
+ }
+ else if (name.equals(Action.SHORT_DESCRIPTION))
+ {
+ JTextField.this.setToolTipText((String) event.getNewValue());
+ }
+ }
+ };
}
/**
+ *
* @since 1.3
*/
protected void configurePropertiesFromAction(Action action)
{
if (action != null)
{
- setEnabled(action.isEnabled());
- setToolTipText((String) action.getValue(Action.SHORT_DESCRIPTION));
+ setEnabled(action.isEnabled());
+ setToolTipText((String) action.getValue(Action.SHORT_DESCRIPTION));
}
else
{
- setEnabled(true);
- setToolTipText(null);
+ setEnabled(true);
+ setToolTipText(null);
}
}
+ /**
+ * Returns the column width, which is the width of the character m
+ * for the font in use.
+ * @return the width of the character m for the font in use.
+ */
protected int getColumnWidth()
{
FontMetrics metrics = getToolkit().getFontMetrics(getFont());
return metrics.charWidth('m');
}
+
+ /**
+ * Returns the accessible context associated with the <code>JTextField</code>.
+ *
+ * @return the accessible context associated with the <code>JTextField</code>
+ */
+ public AccessibleContext getAccessibleContext()
+ {
+ if (accessibleContext == null)
+ accessibleContext = new AccessibleJTextField();
+ return accessibleContext;
+ }
+
+ /**
+ * Returns the bounded range model that describes the horizontal visibility
+ * of the text field in the case when the text does not fit into the
+ * available space. The actual values of this model are managed by the look
+ * and feel implementation.
+ *
+ * @return the bounded range model that describes the horizontal visibility
+ */
+ public BoundedRangeModel getHorizontalVisibility()
+ {
+ // TODO: The real implementation of this property is still missing.
+ // However, this is not done in JTextField but must instead be handled in
+ // javax.swing.text.FieldView.
+ return horizontalVisibility;
+ }
}
diff --git a/javax/swing/JTextPane.java b/javax/swing/JTextPane.java
index 80632fff3..1f5b99e43 100644
--- a/javax/swing/JTextPane.java
+++ b/javax/swing/JTextPane.java
@@ -39,8 +39,6 @@ exception statement from your version. */
package javax.swing;
import java.awt.Component;
-import java.io.IOException;
-import java.io.ObjectOutputStream;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
@@ -49,7 +47,6 @@ import javax.swing.text.Document;
import javax.swing.text.EditorKit;
import javax.swing.text.Element;
import javax.swing.text.MutableAttributeSet;
-import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.Style;
import javax.swing.text.StyledDocument;
import javax.swing.text.StyledEditorKit;
@@ -106,7 +103,7 @@ public class JTextPane
* @throws IllegalArgumentException if <code>document</code> is not an
* instance of <code>StyledDocument</code>
*
- * @see {@link #setStyledDocument}
+ * @see #setStyledDocument
*/
public void setDocument(Document document)
{
@@ -120,7 +117,7 @@ public class JTextPane
/**
* Returns the {@link StyledDocument} that is the content model for
* this <code>JTextPane</code>. This is a typed wrapper for
- * {@link #getDocument}.
+ * {@link #getDocument()}.
*
* @return the content model of this <code>JTextPane</code>
*/
@@ -179,8 +176,6 @@ public class JTextPane
doc.setCharacterAttributes(start, contentLength, getInputAttributes(),
true);
- // Set dot to new position.
- setCaretPosition(start + contentLength);
}
catch (BadLocationException e)
{
@@ -300,7 +295,7 @@ public class JTextPane
* @param replace if <code>true</code>, the attributes of the current
* selection are overridden, otherwise they are merged
*
- * @see {@link #getInputAttributes}
+ * @see #getInputAttributes
*/
public void setCharacterAttributes(AttributeSet attribute,
boolean replace)
diff --git a/javax/swing/JToggleButton.java b/javax/swing/JToggleButton.java
index 25d67f59e..077e5adb8 100644
--- a/javax/swing/JToggleButton.java
+++ b/javax/swing/JToggleButton.java
@@ -129,7 +129,7 @@ public class JToggleButton extends AbstractButton implements Accessible
* Compatible with Sun's JDK.
*/
private static final long serialVersionUID = -1589950750899943974L;
-
+
/**
* Sets the pressed state of the button. The selected state
* of the button also changes follwing the button being pressed.
@@ -174,8 +174,27 @@ public class JToggleButton extends AbstractButton implements Accessible
ActionEvent.ACTION_PERFORMED,
actionCommand));
}
-
}
+
+ /**
+ * Checks if the button is selected.
+ *
+ * @returns true if the button is selected
+ */
+ public boolean isSelected()
+ {
+ return super.isSelected();
+ }
+
+ /**
+ * Sets the selected state of the button.
+ *
+ * @param b true if button is selected
+ */
+ public void setSelected(boolean b)
+ {
+ super.setSelected(b);
+ }
}
/**
@@ -276,6 +295,7 @@ public class JToggleButton extends AbstractButton implements Accessible
setModel(new ToggleButtonModel());
model.setSelected(selected);
+ setAlignmentX(LEFT_ALIGNMENT);
}
/**
diff --git a/javax/swing/JToolBar.java b/javax/swing/JToolBar.java
index 649919e06..dc85e294d 100644
--- a/javax/swing/JToolBar.java
+++ b/javax/swing/JToolBar.java
@@ -68,6 +68,8 @@ public class JToolBar extends JComponent implements SwingConstants, Accessible
/**
* AccessibleJToolBar
*/
+ // FIXME: This inner class is a complete stub and must be implemented
+ // properly.
protected class AccessibleJToolBar extends AccessibleJComponent
{
/** DOCUMENT ME! */
@@ -78,6 +80,7 @@ public class JToolBar extends JComponent implements SwingConstants, Accessible
*/
protected AccessibleJToolBar()
{
+ // Nothing to do here.
}
/**
diff --git a/javax/swing/JToolTip.java b/javax/swing/JToolTip.java
index 8d7747827..6bc3e3fa2 100644
--- a/javax/swing/JToolTip.java
+++ b/javax/swing/JToolTip.java
@@ -58,6 +58,8 @@ public class JToolTip extends JComponent implements Accessible
/**
* DOCUMENT ME!
*/
+ // FIXME: This inner class is a complete stub and must be implemented
+ // properly.
protected class AccessibleJToolTip extends AccessibleJComponent
{
private static final long serialVersionUID = -6222548177795408476L;
@@ -67,6 +69,7 @@ public class JToolTip extends JComponent implements Accessible
*/
protected AccessibleJToolTip()
{
+ // Nothing to do here.
}
/**
diff --git a/javax/swing/JTree.java b/javax/swing/JTree.java
index 15271bba4..660945c27 100644
--- a/javax/swing/JTree.java
+++ b/javax/swing/JTree.java
@@ -73,7 +73,6 @@ import javax.swing.event.TreeWillExpandListener;
import javax.swing.plaf.TreeUI;
import javax.swing.text.Position;
import javax.swing.tree.DefaultMutableTreeNode;
-import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.DefaultTreeSelectionModel;
import javax.swing.tree.ExpandVetoException;
@@ -84,9 +83,7 @@ import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
-public class JTree
- extends JComponent
- implements Scrollable, Accessible
+public class JTree extends JComponent implements Scrollable, Accessible
{
/**
@@ -977,7 +974,7 @@ public class JTree
/**
* Returns the number of items currently selected.
*
- * @param the number of selected accessibles.
+ * @return the number of selected accessibles.
*/
public int getAccessibleSelectionCount()
{
@@ -1194,6 +1191,7 @@ public class JTree
*/
protected TreeModelHandler()
{
+ // Nothing to do here.
}
/**
@@ -1268,6 +1266,7 @@ public class JTree
*/
protected TreeSelectionRedirector()
{
+ // Nothing to do here.
}
/**
@@ -1303,6 +1302,7 @@ public class JTree
*/
protected EmptySelectionModel()
{
+ // Nothing to do here.
}
/**
@@ -1477,10 +1477,10 @@ public class JTree
*/
public JTree(TreeModel model)
{
+ updateUI();
+ setRootVisible(true);
setModel(model);
setSelectionModel(EmptySelectionModel.sharedInstance());
- setCellRenderer(new DefaultTreeCellRenderer());
- updateUI();
}
/**
@@ -1585,8 +1585,6 @@ public class JTree
public void updateUI()
{
setUI((TreeUI) UIManager.getUI(this));
- revalidate();
- repaint();
}
/**
@@ -1601,13 +1599,13 @@ public class JTree
/**
* Gets the AccessibleContext associated with this
- * <code>JToggleButton</code>.
+ * <code>JTree</code>.
*
* @return the associated context
*/
public AccessibleContext getAccessibleContext()
{
- return null;
+ return new AccessibleJTree();
}
/**
@@ -1632,14 +1630,14 @@ public class JTree
return 1;
}
- public boolean getScrollableTracksViewportWidth()
+ public boolean getScrollableTracksViewportHeight()
{
if (getParent() instanceof JViewport)
return ((JViewport) getParent()).getHeight() > getPreferredSize().height;
return false;
}
- public boolean getScrollableTracksViewportHeight()
+ public boolean getScrollableTracksViewportWidth()
{
if (getParent() instanceof JViewport)
return ((JViewport) getParent()).getWidth() > getPreferredSize().width;
@@ -1837,6 +1835,7 @@ public class JTree
treeModel = model;
firePropertyChange(TREE_MODEL_PROPERTY, oldValue, model);
+ updateUI();
}
/**
@@ -2047,13 +2046,26 @@ public class JTree
{
if (path == null)
return;
-
+
+ Object[] oPath = path.getPath();
+ TreePath temp = new TreePath(oPath[0]);
+ boolean stop = false;
+ int i = 1;
+ while (!stop)
+ {
+ while (isVisible(temp))
+ if (i < oPath.length)
+ temp = temp.pathByAddingChild(oPath[i++]);
+ else
+ {
+ stop = true;
+ break;
+ }
+ makeVisible(temp);
+ }
Rectangle rect = getPathBounds(path);
-
- if (rect == null)
- return;
-
scrollRectToVisible(rect);
+ setSelectionPath(temp);
}
public void scrollRowToVisible(int row)
@@ -2332,6 +2344,7 @@ public class JTree
}
catch (ExpandVetoException ev)
{
+ // We do nothing if attempt has been vetoed.
}
setExpandedState(path, false);
fireTreeCollapsed(path);
@@ -2360,6 +2373,7 @@ public class JTree
}
catch (ExpandVetoException ev)
{
+ // We do nothing if attempt has been vetoed.
}
setExpandedState(path, true);
@@ -2884,7 +2898,7 @@ public class JTree
}
}
}
-
+
/**
* Sent when the tree has changed enough that we need to resize the bounds,
* but not enough that we need to remove the expanded node set (e.g nodes
diff --git a/javax/swing/JViewport.java b/javax/swing/JViewport.java
index a02fedd08..ba44461cb 100644
--- a/javax/swing/JViewport.java
+++ b/javax/swing/JViewport.java
@@ -41,6 +41,7 @@ package javax.swing;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
+import java.awt.Image;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.Point;
@@ -129,12 +130,10 @@ public class JViewport extends JComponent implements Accessible
/**
* A {@link java.awt.event.ComponentListener} that listens for
- * changes of the view's size. This class forbids changes of the view
- * component's size that would exceed the viewport's size.
+ * changes of the view's size. This triggers a revalidate() call on the
+ * viewport.
*/
- protected class ViewListener
- extends ComponentAdapter
- implements Serializable
+ protected class ViewListener extends ComponentAdapter implements Serializable
{
private static final long serialVersionUID = -2812489404285958070L;
@@ -143,57 +142,53 @@ public class JViewport extends JComponent implements Accessible
*/
protected ViewListener()
{
+ // Nothing to do here.
}
/**
* Receives notification when a component (in this case: the view
- * component) changes it's size.
+ * component) changes it's size. This simply triggers a revalidate() on the
+ * viewport.
*
* @param ev the ComponentEvent describing the change
*/
public void componentResized(ComponentEvent ev)
{
- // According to some tests that I did with Sun's implementation
- // this class is supposed to make sure that the view component
- // is not resized to a larger size than the viewport.
- // This is not documented anywhere. What I did is: I subclassed JViewport
- // and ViewListener and 'disabled' the componentResized method by
- // overriding it and not calling super.componentResized().
- // When this method is disabled I can set the size on the view component
- // normally, when it is enabled, it gets immediatly resized back,
- // after a resize attempt that would exceed the Viewport's size.
- Component comp = ev.getComponent();
- Dimension newSize = comp.getSize();
- Dimension viewportSize = getSize();
- boolean revert = false;
- if (newSize.width > viewportSize.width)
- {
- newSize.width = viewportSize.width;
- revert = true;
- }
- if (newSize.height > viewportSize.height)
- {
- newSize.height = viewportSize.height;
- revert = true;
- }
- if (revert == true)
- comp.setSize(newSize);
+ revalidate();
}
}
- private static final long serialVersionUID = -6925142919680527970L;
-
public static final int SIMPLE_SCROLL_MODE = 0;
public static final int BLIT_SCROLL_MODE = 1;
public static final int BACKINGSTORE_SCROLL_MODE = 2;
+ private static final long serialVersionUID = -6925142919680527970L;
+
+ protected boolean scrollUnderway;
+ protected boolean isViewSizeSet;
+
+ /**
+ * This flag indicates whether we use a backing store for drawing.
+ *
+ * @deprecated since JDK 1.3
+ */
+ protected boolean backingStore;
+
+ /**
+ * The backingstore image used for the backingstore and blit scroll methods.
+ */
+ protected Image backingStoreImage;
+
+ /**
+ * The position at which the view has been drawn the last time. This is used
+ * to determine the bittable area.
+ */
+ protected Point lastPaintPosition;
+
ChangeEvent changeEvent = new ChangeEvent(this);
int scrollMode;
- protected boolean scrollUnderway;
- protected boolean isViewSizeSet;
-
/**
* The width and height of the Viewport's area in terms of view
* coordinates. Typically this will be the same as the width and height
@@ -201,34 +196,64 @@ public class JViewport extends JComponent implements Accessible
* width and height, which it may do, for example if it magnifies or
* rotates its view.
*
- * @see #toViewCoordinates
+ * @see #toViewCoordinates(Dimension)
*/
Dimension extentSize;
/**
* The width and height of the view in its own coordinate space.
*/
-
Dimension viewSize;
- Point lastPaintPosition;
-
/**
* The ViewListener instance.
*/
ViewListener viewListener;
/**
- * The accessible context of this <code>JViewport</code>.
+ * Stores the location from where to blit. This is a cached Point object used
+ * in blitting calculations.
+ */
+ Point cachedBlitFrom;
+
+ /**
+ * Stores the location where to blit to. This is a cached Point object used
+ * in blitting calculations.
+ */
+ Point cachedBlitTo;
+
+ /**
+ * Stores the width of the blitted area. This is a cached Dimension object
+ * used in blitting calculations.
+ */
+ Dimension cachedBlitSize;
+
+ /**
+ * Stores the bounds of the area that needs to be repainted. This is a cached
+ * Rectangle object used in blitting calculations.
*/
- AccessibleContext accessibleContext;
+ Rectangle cachedBlitPaint;
+
+ boolean damaged = true;
+
+ /**
+ * A flag indicating if the size of the viewport has changed since the
+ * last repaint. This is used in double buffered painting to check if we
+ * need a new double buffer, or can reuse the old one.
+ */
+ boolean sizeChanged = true;
public JViewport()
{
setOpaque(true);
setScrollMode(BLIT_SCROLL_MODE);
- setLayout(createLayoutManager());
updateUI();
+ setLayout(createLayoutManager());
+ lastPaintPosition = new Point();
+ cachedBlitFrom = new Point();
+ cachedBlitTo = new Point();
+ cachedBlitSize = new Dimension();
+ cachedBlitPaint = new Rectangle();
}
public Dimension getExtentSize()
@@ -314,6 +339,8 @@ public class JViewport extends JComponent implements Accessible
public void setViewPosition(Point p)
{
+ if (getViewPosition().equals(p))
+ return;
Component view = getView();
if (view != null)
{
@@ -322,6 +349,7 @@ public class JViewport extends JComponent implements Accessible
isViewSizeSet = false;
fireStateChanged();
}
+ repaint();
}
public Rectangle getViewRect()
@@ -371,12 +399,8 @@ public class JViewport extends JComponent implements Accessible
public void setView(Component v)
{
- while (getComponentCount() > 0)
- {
- if (viewListener != null)
- getView().removeComponentListener(viewListener);
- remove(0);
- }
+ if (viewListener != null)
+ getView().removeComponentListener(viewListener);
if (v != null)
{
@@ -386,37 +410,25 @@ public class JViewport extends JComponent implements Accessible
add(v);
fireStateChanged();
}
- }
-
- public void revalidate()
- {
- fireStateChanged();
- super.revalidate();
+ revalidate();
+ repaint();
}
public void reshape(int x, int y, int w, int h)
{
- boolean changed =
- (x != getX())
- || (y != getY())
- || (w != getWidth())
- || (h != getHeight());
+ if (w != getWidth() || h != getHeight())
+ sizeChanged = true;
super.reshape(x, y, w, h);
- if (changed)
- fireStateChanged();
- }
-
- protected void addImpl(Component comp, Object constraints, int index)
- {
- if (getComponentCount() > 0)
- remove(getComponents()[0]);
-
- super.addImpl(comp, constraints, index);
+ if (sizeChanged)
+ {
+ damaged = true;
+ fireStateChanged();
+ }
}
- public final Insets getInsets()
+ public final Insets getInsets()
{
- return new Insets(0,0,0,0);
+ return new Insets(0, 0, 0, 0);
}
public final Insets getInsets(Insets insets)
@@ -430,6 +442,14 @@ public class JViewport extends JComponent implements Accessible
return insets;
}
+
+ /**
+ * Overridden to return <code>false</code>, so the JViewport's paint method
+ * gets called instead of directly calling the children. This is necessary
+ * in order to get a useful clipping and translation on the children.
+ *
+ * @return <code>false</code>
+ */
public boolean isOptimizedDrawingEnabled()
{
return false;
@@ -437,7 +457,36 @@ public class JViewport extends JComponent implements Accessible
public void paint(Graphics g)
{
- paintComponent(g);
+ Component view = getView();
+
+ if (view == null)
+ return;
+
+ Point pos = getViewPosition();
+ Rectangle viewBounds = view.getBounds();
+ Rectangle portBounds = getBounds();
+
+ if (viewBounds.width == 0
+ || viewBounds.height == 0
+ || portBounds.width == 0
+ || portBounds.height == 0)
+ return;
+
+ switch (getScrollMode())
+ {
+
+ case JViewport.BACKINGSTORE_SCROLL_MODE:
+ paintBackingStore(g);
+ break;
+ case JViewport.BLIT_SCROLL_MODE:
+ paintBlit(g);
+ break;
+ case JViewport.SIMPLE_SCROLL_MODE:
+ default:
+ paintSimple(g);
+ break;
+ }
+ damaged = false;
}
public void addChangeListener(ChangeListener listener)
@@ -455,13 +504,6 @@ public class JViewport extends JComponent implements Accessible
return (ChangeListener[]) getListeners(ChangeListener.class);
}
- protected void fireStateChanged()
- {
- ChangeListener[] listeners = getChangeListeners();
- for (int i = 0; i < listeners.length; ++i)
- listeners[i].stateChanged(changeEvent);
- }
-
/**
* This method returns the String ID of the UI class of Separator.
*
@@ -507,6 +549,90 @@ public class JViewport extends JComponent implements Accessible
}
/**
+ * Scrolls the view so that contentRect becomes visible.
+ *
+ * @param contentRect the rectangle to make visible within the view
+ */
+ public void scrollRectToVisible(Rectangle contentRect)
+ {
+ Component view = getView();
+ if (view == null)
+ return;
+
+ Point pos = getViewPosition();
+ Rectangle viewBounds = getView().getBounds();
+ Rectangle portBounds = getBounds();
+
+ if (isShowing())
+ getView().validate();
+
+ // If the bottom boundary of contentRect is below the port
+ // boundaries, scroll up as necessary.
+ if (contentRect.y + contentRect.height + viewBounds.y > portBounds.height)
+ pos.y = contentRect.y + contentRect.height - portBounds.height;
+ // If contentRect.y is above the port boundaries, scroll down to
+ // contentRect.y.
+ if (contentRect.y + viewBounds.y < 0)
+ pos.y = contentRect.y;
+ // If the right boundary of contentRect is right from the port
+ // boundaries, scroll left as necessary.
+ if (contentRect.x + contentRect.width + viewBounds.x > portBounds.width)
+ pos.x = contentRect.x + contentRect.width - portBounds.width;
+ // If contentRect.x is left from the port boundaries, scroll right to
+ // contentRect.x.
+ if (contentRect.x + viewBounds.x < 0)
+ pos.x = contentRect.x;
+ setViewPosition(pos);
+ }
+
+ /**
+ * Returns the accessible context for this <code>JViewport</code>. This
+ * will be an instance of {@link AccessibleJViewport}.
+ *
+ * @return the accessible context for this <code>JViewport</code>
+ */
+ public AccessibleContext getAccessibleContext()
+ {
+ if (accessibleContext == null)
+ accessibleContext = new AccessibleJViewport();
+ return accessibleContext;
+ }
+
+ /**
+ * Forward repaint to parent to make sure only one paint is performed by the
+ * RepaintManager.
+ *
+ * @param tm number of milliseconds to defer the repaint request
+ * @param x the X coordinate of the upper left corner of the dirty area
+ * @param y the Y coordinate of the upper left corner of the dirty area
+ * @param w the width of the dirty area
+ * @param h the height of the dirty area
+ */
+ public void repaint(long tm, int x, int y, int w, int h)
+ {
+ Component parent = getParent();
+ if (parent != null)
+ {
+ parent.repaint(tm, x + getX(), y + getY(), w, h);
+ }
+ }
+
+ protected void addImpl(Component comp, Object constraints, int index)
+ {
+ if (getComponentCount() > 0)
+ remove(getComponents()[0]);
+
+ super.addImpl(comp, constraints, index);
+ }
+
+ protected void fireStateChanged()
+ {
+ ChangeListener[] listeners = getChangeListeners();
+ for (int i = 0; i < listeners.length; ++i)
+ listeners[i].stateChanged(changeEvent);
+ }
+
+ /**
* Creates a {@link ViewListener} that is supposed to listen for
* size changes on the view component.
*
@@ -529,56 +655,217 @@ public class JViewport extends JComponent implements Accessible
}
/**
- * Scrolls the view so that contentRect becomes visible.
+ * Computes the parameters for the blitting scroll method. <code>dx</code>
+ * and <code>dy</code> specifiy the X and Y offset by which the viewport
+ * is scrolled. All other arguments are output parameters and are filled by
+ * this method.
*
- * @param contentRect the rectangle to make visible within the view
+ * <code>blitFrom</code> holds the position of the blit rectangle in the
+ * viewport rectangle before scrolling, <code>blitTo</code> where the blitArea
+ * is copied to.
+ *
+ * <code>blitSize</code> holds the size of the blit area and
+ * <code>blitPaint</code> is the area of the view that needs to be painted.
+ *
+ * This method returns <code>true</code> if blitting is possible and
+ * <code>false</code> if the viewport has to be repainted completetly without
+ * blitting.
+ *
+ * @param dx the horizontal delta
+ * @param dy the vertical delta
+ * @param blitFrom the position from where to blit; set by this method
+ * @param blitTo the position where to blit area is copied to; set by this
+ * method
+ * @param blitSize the size of the blitted area; set by this method
+ * @param blitPaint the area that needs repainting; set by this method
+ *
+ * @return <code>true</code> if blitting is possible,
+ * <code>false</code> otherwise
*/
- public void scrollRectToVisible(Rectangle contentRect)
+ protected boolean computeBlit(int dx, int dy, Point blitFrom, Point blitTo,
+ Dimension blitSize, Rectangle blitPaint)
+ {
+ if ((dx != 0 && dy != 0) || damaged)
+ // We cannot blit if the viewport is scrolled in both directions at
+ // once.
+ return false;
+
+ Rectangle portBounds = SwingUtilities.calculateInnerArea(this, getBounds());
+
+ // Compute the blitFrom and blitTo parameters.
+ blitFrom.x = portBounds.x;
+ blitFrom.y = portBounds.y;
+ blitTo.x = portBounds.x;
+ blitTo.y = portBounds.y;
+
+ if (dy > 0)
+ {
+ blitFrom.y = portBounds.y + dy;
+ }
+ else if (dy < 0)
+ {
+ blitTo.y = portBounds.y - dy;
+ }
+ else if (dx > 0)
+ {
+ blitFrom.x = portBounds.x + dx;
+ }
+ else if (dx < 0)
+ {
+ blitTo.x = portBounds.x - dx;
+ }
+
+ // Compute size of the blit area.
+ if (dx != 0)
+ {
+ blitSize.width = portBounds.width - Math.abs(dx);
+ blitSize.height = portBounds.height;
+ }
+ else if (dy != 0)
+ {
+ blitSize.width = portBounds.width;
+ blitSize.height = portBounds.height - Math.abs(dy);
+ }
+
+ // Compute the blitPaint parameter.
+ blitPaint.setBounds(portBounds);
+ if (dy > 0)
+ {
+ blitPaint.y = portBounds.y + portBounds.height - dy;
+ blitPaint.height = dy;
+ }
+ else if (dy < 0)
+ {
+ blitPaint.height = -dy;
+ }
+ if (dx > 0)
+ {
+ blitPaint.x = portBounds.x + portBounds.width - dx;
+ blitPaint.width = dx;
+ }
+ else if (dx < 0)
+ {
+ blitPaint.width = -dx;
+ }
+
+ return true;
+ }
+
+ /**
+ * Paints the viewport in case we have a scrollmode of
+ * {@link #SIMPLE_SCROLL_MODE}.
+ *
+ * This simply paints the view directly on the surface of the viewport.
+ *
+ * @param g the graphics context to use
+ */
+ void paintSimple(Graphics g)
{
Point pos = getViewPosition();
- Rectangle viewBounds = getView().getBounds();
- Rectangle portBounds = getBounds();
-
- // FIXME: should validate the view if it is not valid, however
- // this may cause excessive validation when the containment
- // hierarchy is being created.
-
- // if contentRect is larger than the portBounds, center the view
- if (contentRect.height > portBounds.height ||
- contentRect.width > portBounds.width)
+ Component view = getView();
+ boolean translated = false;
+ try
+ {
+ g.translate(-pos.x, -pos.y);
+ translated = true;
+ view.paint(g);
+ }
+ finally
{
- setViewPosition(new Point(contentRect.x, contentRect.y));
- return;
+ if (translated)
+ g.translate (pos.x, pos.y);
}
-
- // Y-DIRECTION
- if (contentRect.y < -viewBounds.y)
- setViewPosition(new Point(pos.x, contentRect.y));
- else if (contentRect.y + contentRect.height >
- -viewBounds.y + portBounds.height)
- setViewPosition (new Point(pos.x, contentRect.y -
- (portBounds.height - contentRect.height)));
-
- // X-DIRECTION
- pos = getViewPosition();
- if (contentRect.x < -viewBounds.x)
- setViewPosition(new Point(contentRect.x, pos.y));
- else if (contentRect.x + contentRect.width >
- -viewBounds.x + portBounds.width)
- setViewPosition (new Point(contentRect.x -
- (portBounds.width - contentRect.width), pos.y));
}
/**
- * Returns the accessible context for this <code>JViewport</code>. This
- * will be an instance of {@link AccessibleJViewport}.
+ * Paints the viewport in case we have a scroll mode of
+ * {@link #BACKINGSTORE_SCROLL_MODE}.
*
- * @return the accessible context for this <code>JViewport</code>
+ * This method uses a backing store image to paint the view to, which is then
+ * subsequently painted on the screen. This should make scrolling more
+ * smooth.
+ *
+ * @param g the graphics context to use
*/
- public AccessibleContext getAccessibleContext()
+ void paintBackingStore(Graphics g)
{
- if (accessibleContext == null)
- accessibleContext = new AccessibleJViewport();
- return accessibleContext;
+ // If we have no backing store image yet or the size of the component has
+ // changed, we need to rebuild the backing store.
+ if (backingStoreImage == null || sizeChanged)
+ {
+ backingStoreImage = createImage(getWidth(), getHeight());
+ sizeChanged = false;
+ Graphics g2 = backingStoreImage.getGraphics();
+ paintSimple(g2);
+ g2.dispose();
+ }
+ // Otherwise we can perform the blitting on the backing store image:
+ // First we move the part that remains visible after scrolling, then
+ // we only need to paint the bit that becomes newly visible.
+ else
+ {
+ Graphics g2 = backingStoreImage.getGraphics();
+ Point viewPosition = getViewPosition();
+ int dx = viewPosition.x - lastPaintPosition.x;
+ int dy = viewPosition.y - lastPaintPosition.y;
+ boolean canBlit = computeBlit(dx, dy, cachedBlitFrom, cachedBlitTo,
+ cachedBlitSize, cachedBlitPaint);
+ if (canBlit)
+ {
+ // Copy the part that remains visible during scrolling.
+ g2.copyArea(cachedBlitFrom.x, cachedBlitFrom.y,
+ cachedBlitSize.width, cachedBlitSize.height,
+ cachedBlitTo.x - cachedBlitFrom.x,
+ cachedBlitTo.y - cachedBlitFrom.y);
+ // Now paint the part that becomes newly visible.
+ g2.setClip(cachedBlitPaint.x, cachedBlitPaint.y,
+ cachedBlitPaint.width, cachedBlitPaint.height);
+ paintSimple(g2);
+ }
+ // If blitting is not possible for some reason, fall back to repainting
+ // everything.
+ else
+ {
+ paintSimple(g2);
+ }
+ g2.dispose();
+ }
+ // Actually draw the backingstore image to the graphics context.
+ g.drawImage(backingStoreImage, 0, 0, this);
+ // Update the lastPaintPosition so that we know what is already drawn when
+ // we paint the next time.
+ lastPaintPosition.setLocation(getViewPosition());
+ }
+
+ /**
+ * Paints the viewport in case we have a scrollmode of
+ * {@link #BLIT_SCROLL_MODE}.
+ *
+ * This paints the viewport using a backingstore and a blitting algorithm.
+ * Only the newly exposed area of the view is painted from the view painting
+ * methods, the remainder is copied from the backing store.
+ *
+ * @param g the graphics context to use
+ */
+ void paintBlit(Graphics g)
+ {
+ // We cannot perform blitted painting as it is described in Sun's API docs.
+ // There it is suggested that this painting method should blit directly
+ // on the parent window's surface. This is not possible because when using
+ // Swing's double buffering (at least our implementation), it would
+ // immediatly be painted when the buffer is painted on the screen. For this
+ // to work we would need a kind of hole in the buffer image. And honestly
+ // I find this method not very elegant.
+ // The alternative, blitting directly on the buffer image, is also not
+ // possible because the buffer image gets cleared everytime when an opaque
+ // parent component is drawn on it.
+
+ // What we do instead is falling back to the backing store approach which
+ // is in fact a mixed blitting/backing store approach where the blitting
+ // is performed on the backing store image and this is then drawn to the
+ // graphics context. This is very robust and works independent of the
+ // painting mechanism that is used by Swing. And it should have comparable
+ // performance characteristics as the blitting method.
+ paintBackingStore(g);
}
}
diff --git a/javax/swing/KeyStroke.java b/javax/swing/KeyStroke.java
index 12a280c21..b57a71192 100644
--- a/javax/swing/KeyStroke.java
+++ b/javax/swing/KeyStroke.java
@@ -51,6 +51,7 @@ public class KeyStroke
// Called by java.awt.AWTKeyStroke.registerSubclass via reflection.
private KeyStroke()
{
+ // Nothing to do here.
}
private KeyStroke(char keyChar, int keyCode, int modifiers,
diff --git a/javax/swing/LookAndFeel.java b/javax/swing/LookAndFeel.java
index 885874271..1a67e8497 100644
--- a/javax/swing/LookAndFeel.java
+++ b/javax/swing/LookAndFeel.java
@@ -38,9 +38,17 @@ exception statement from your version. */
package javax.swing;
+import java.awt.Color;
import java.awt.Component;
+import java.awt.Font;
import java.awt.Toolkit;
+import java.net.URL;
+import javax.swing.border.Border;
+import javax.swing.plaf.ComponentInputMapUIResource;
+import javax.swing.plaf.IconUIResource;
+import javax.swing.plaf.InputMapUIResource;
+import javax.swing.plaf.UIResource;
import javax.swing.text.JTextComponent;
public abstract class LookAndFeel
@@ -104,6 +112,8 @@ public abstract class LookAndFeel
*/
public void initialize()
{
+ // We do nothing here. This method is meant to be overridden by
+ // LookAndFeel implementations.
}
/**
@@ -113,14 +123,27 @@ public abstract class LookAndFeel
*/
public static void installBorder(JComponent c, String defaultBorderName)
{
+ Border b = c.getBorder();
+ if (b == null || b instanceof UIResource)
+ c.setBorder(UIManager.getBorder(defaultBorderName));
}
/**
* Convenience method for initializing a component's foreground and
* background color properties with values from the current defaults table.
*/
- public static void installColors(JComponent c, String defaultBgName, String defaultFgName)
+ public static void installColors(JComponent c, String defaultBgName,
+ String defaultFgName)
{
+ // Install background.
+ Color bg = c.getBackground();
+ if (bg == null || bg instanceof UIResource)
+ c.setBackground(UIManager.getColor(defaultBgName));
+
+ // Install foreground.
+ Color fg = c.getForeground();
+ if (fg == null || fg instanceof UIResource)
+ c.setForeground(UIManager.getColor(defaultFgName));
}
/**
@@ -128,10 +151,16 @@ public abstract class LookAndFeel
* and font properties with values from the current defaults table.
*/
public static void installColorsAndFont(JComponent component,
- String defaultBgName,
- String defaultFgName,
- String defaultFontName)
+ String defaultBgName,
+ String defaultFgName,
+ String defaultFontName)
{
+ // Install colors.
+ installColors(component, defaultBgName, defaultFgName);
+ // Install font.
+ Font f = component.getFont();
+ if (f == null || f instanceof UIResource)
+ component.setFont(UIManager.getFont(defaultFontName));
}
/**
@@ -156,19 +185,47 @@ public abstract class LookAndFeel
public abstract boolean isSupportedLookAndFeel();
/**
- * Loads the bindings in keys into retMap.
+ * Loads the bindings in keys into retMap. Does not remove existing entries
+ * from retMap. <code>keys</code> describes the InputMap, every even indexed
+ * item is either a KeyStroke or a String representing a KeyStroke and every
+ * odd indexed item is the Object associated with that KeyStroke in an
+ * ActionMap.
+ *
+ * @param retMap the InputMap into which we load bindings
+ * @param keys the Object array describing the InputMap as above
*/
public static void loadKeyBindings(InputMap retMap, Object[] keys)
{
+ if (keys == null)
+ return;
+ for (int i = 0; i < keys.length - 1; i+= 2)
+ {
+ Object key = keys[i];
+ KeyStroke keyStroke;
+ if (key instanceof KeyStroke)
+ keyStroke = (KeyStroke)key;
+ else
+ keyStroke = KeyStroke.getKeyStroke((String)key);
+ retMap.put(keyStroke, keys[i+1]);
+ }
}
/**
- * Creates a ComponentInputMap from keys.
+ * Creates a ComponentInputMap from keys.
+ * <code>keys</code> describes the InputMap, every even indexed
+ * item is either a KeyStroke or a String representing a KeyStroke and every
+ * odd indexed item is the Object associated with that KeyStroke in an
+ * ActionMap.
+ *
+ * @param c the JComponent associated with the ComponentInputMap
+ * @param keys the Object array describing the InputMap as above
*/
public static ComponentInputMap makeComponentInputMap(JComponent c,
Object[] keys)
{
- return null;
+ ComponentInputMap retMap = new ComponentInputMapUIResource(c);
+ loadKeyBindings(retMap, keys);
+ return retMap;
}
/**
@@ -177,23 +234,55 @@ public abstract class LookAndFeel
*/
public static Object makeIcon(Class baseClass, String gifFile)
{
- return null;
+ final URL file = baseClass.getResource(gifFile);
+ return new UIDefaults.LazyValue()
+ {
+ public Object createValue(UIDefaults table)
+ {
+ return new IconUIResource(new ImageIcon(file));
+ }
+ };
}
/**
* Creates a InputMap from keys.
+ * <code>keys</code> describes the InputMap, every even indexed
+ * item is either a KeyStroke or a String representing a KeyStroke and every
+ * odd indexed item is the Object associated with that KeyStroke in an
+ * ActionMap.
+ *
+ * @param keys the Object array describing the InputMap as above
*/
public static InputMap makeInputMap(Object[] keys)
{
- return null;
+ InputMap retMap = new InputMapUIResource();
+ loadKeyBindings(retMap, keys);
+ return retMap;
}
/**
- * Convenience method for building lists of KeyBindings.
+ * Convenience method for building lists of KeyBindings.
+ * <code>keyBindingList</code> is an array of KeyStroke-Action pairs where
+ * even indexed elements are KeyStrokes or Strings representing KeyStrokes
+ * and odd indexed elements are the associated Actions.
+ *
+ * @param keyBindingList the array of KeyStroke-Action pairs
+ * @return a JTextComponent.KeyBinding array
*/
public static JTextComponent.KeyBinding[] makeKeyBindings(Object[] keyBindingList)
{
- return null;
+ JTextComponent.KeyBinding[] retBindings =
+ new JTextComponent.KeyBinding[keyBindingList.length / 2];
+ for (int i = 0; i < keyBindingList.length - 1; i+= 2)
+ {
+ KeyStroke stroke;
+ if (keyBindingList[i] instanceof KeyStroke)
+ stroke = (KeyStroke)keyBindingList[i];
+ else
+ stroke = KeyStroke.getKeyStroke((String)keyBindingList[i]);
+ retBindings[i/2] = new JTextComponent.KeyBinding(stroke, (String)keyBindingList[i+1]);
+ }
+ return retBindings;
}
/**
@@ -224,6 +313,8 @@ public abstract class LookAndFeel
*/
public void uninitialize()
{
+ // We do nothing here. This method is meant to be overridden by
+ // LookAndFeel implementations.
}
/**
@@ -232,5 +323,7 @@ public abstract class LookAndFeel
*/
public static void uninstallBorder(JComponent c)
{
+ if (c.getBorder() instanceof UIResource)
+ c.setBorder(null);
}
}
diff --git a/javax/swing/MutableComboBoxModel.java b/javax/swing/MutableComboBoxModel.java
index ee79dac03..93091786e 100644
--- a/javax/swing/MutableComboBoxModel.java
+++ b/javax/swing/MutableComboBoxModel.java
@@ -76,7 +76,7 @@ public interface MutableComboBoxModel extends ComboBoxModel
/**
* This method removes given element from the data model
*
- * @param element to remove.
+ * @param object element to remove.
*/
void removeElement(Object object);
-} // MutableComboBoxModel
+}
diff --git a/javax/swing/OverlayLayout.java b/javax/swing/OverlayLayout.java
index 143fecbef..56b8c8bb6 100644
--- a/javax/swing/OverlayLayout.java
+++ b/javax/swing/OverlayLayout.java
@@ -1,5 +1,5 @@
-/* OverlayLayout.java --
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+/* OverlayLayout.java -- A layout manager
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,150 +37,376 @@ exception statement from your version. */
package javax.swing;
+import java.awt.AWTError;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
+import java.awt.Insets;
import java.awt.LayoutManager2;
import java.io.Serializable;
/**
- * OverlayLayout
- * @author Andrew Selkirk
- * @version 1.0
+ * A layout manager that lays out the components of a container one over
+ * another.
+ *
+ * The components take as much space as is available in the container, but not
+ * more than specified by their maximum size.
+ *
+ * The overall layout is mainly affected by the components
+ * <code>alignmentX</code> and <code>alignmentY</code> properties. All
+ * components are aligned, so that their alignment points (for either
+ * direction) are placed in one line (the baseline for this direction).
+ *
+ * For example: An X alignment of 0.0 means that the component's alignment
+ * point is at it's left edge, an X alignment of 0.5 means that the alignment
+ * point is in the middle, an X alignment of 1.0 means, the aligment point is
+ * at the right edge. So if you have three components, the first with 0.0, the
+ * second with 0.5 and the third with 1.0, then they are laid out like this:
+ *
+ * <pre>
+ * +-------+
+ * | 1 |
+ * +-------+
+ * +-------+
+ * | 2 |
+ * +-------+
+ * +---------+
+ * | 3 +
+ * +---------+
+ * </pre>
+ * The above picture shows the X alignment between the components. An Y
+ * alignment like shown above cannot be achieved with this layout manager. The
+ * components are place on top of each other, with the X alignment shown above.
+ *
+ * @author Roman Kennke (kennke@aicas.com)
+ * @author Andrew Selkirk
*/
public class OverlayLayout implements LayoutManager2, Serializable
{
private static final long serialVersionUID = 18082829169631543L;
/**
- * target
+ * The container to be laid out.
*/
private Container target;
/**
- * xChildren
+ * The size requirements of the containers children for the X direction.
*/
private SizeRequirements[] xChildren;
/**
- * yChildren
+ * The size requirements of the containers children for the Y direction.
*/
private SizeRequirements[] yChildren;
/**
- * xTotal
+ * The size requirements of the container to be laid out for the X direction.
*/
private SizeRequirements xTotal;
/**
- * yTotal
+ * The size requirements of the container to be laid out for the Y direction.
*/
private SizeRequirements yTotal;
/**
- * Constructor OverlayLayout
- * @param target TODO
+ * The offsets of the child components in the X direction.
+ */
+ private int[] offsetsX;
+
+ /**
+ * The offsets of the child components in the Y direction.
+ */
+ private int[] offsetsY;
+
+ /**
+ * The spans of the child components in the X direction.
+ */
+ private int[] spansX;
+
+ /**
+ * The spans of the child components in the Y direction.
+ */
+ private int[] spansY;
+
+ /**
+ * Creates a new OverlayLayout for the specified container.
+ *
+ * @param target the container to be laid out
*/
public OverlayLayout(Container target)
{
- // TODO
+ this.target = target;
}
/**
- * invalidateLayout
- * @param target TODO
+ * Notifies the layout manager that the layout has become invalid. It throws
+ * away cached layout information and recomputes it the next time it is
+ * requested.
+ *
+ * @param target not used here
*/
public void invalidateLayout(Container target)
{
- // TODO
+ xChildren = null;
+ yChildren = null;
+ xTotal = null;
+ yTotal = null;
+ offsetsX = null;
+ offsetsY = null;
+ spansX = null;
+ spansY = null;
}
/**
- * addLayoutComponent
- * @param string TODO
- * @param component TODO
+ * This method is not used in this layout manager.
+ *
+ * @param string not used here
+ * @param component not used here
*/
public void addLayoutComponent(String string, Component component)
{
- // TODO
+ // Nothing to do here.
}
/**
- * addLayoutComponent
- * @param component TODO
- * @param constraints TODO
+ * This method is not used in this layout manager.
+ *
+ * @param component not used here
+ * @param constraints not used here
*/
public void addLayoutComponent(Component component, Object constraints)
{
- // TODO
+ // Nothing to do here.
}
/**
- * removeLayoutComponent
- * @param component TODO
+ * This method is not used in this layout manager.
+ *
+ * @param component not used here
*/
public void removeLayoutComponent(Component component)
{
- // TODO
+ // Nothing to do here.
}
/**
- * preferredLayoutSize
- * @param target TODO
- * @returns Dimension
+ * Returns the preferred size of the container that is laid out. This is
+ * computed by the children's preferred sizes, taking their alignments into
+ * account.
+ *
+ * @param target not used here
+ *
+ * @returns the preferred size of the container that is laid out
*/
public Dimension preferredLayoutSize(Container target)
{
- return null; // TODO
+ if (target != this.target)
+ throw new AWTError("OverlayLayout can't be shared");
+
+ checkTotalRequirements();
+ return new Dimension(xTotal.preferred, yTotal.preferred);
}
/**
- * minimumLayoutSize
- * @param target TODO
- * @returns Dimension
+ * Returns the minimum size of the container that is laid out. This is
+ * computed by the children's minimum sizes, taking their alignments into
+ * account.
+ *
+ * @param target not used here
+ *
+ * @returns the minimum size of the container that is laid out
*/
public Dimension minimumLayoutSize(Container target)
{
- return null; // TODO
+ if (target != this.target)
+ throw new AWTError("OverlayLayout can't be shared");
+
+ checkTotalRequirements();
+ return new Dimension(xTotal.minimum, yTotal.minimum);
}
/**
- * maximumLayoutSize
- * @param target TODO
- * @returns Dimension
+ * Returns the maximum size of the container that is laid out. This is
+ * computed by the children's maximum sizes, taking their alignments into
+ * account.
+ *
+ * @param target not used here
+ *
+ * @returns the maximum size of the container that is laid out
*/
public Dimension maximumLayoutSize(Container target)
{
- return null; // TODO
+ if (target != this.target)
+ throw new AWTError("OverlayLayout can't be shared");
+
+ checkTotalRequirements();
+ return new Dimension(xTotal.maximum, yTotal.maximum);
}
/**
- * getLayoutAlignmentX
- * @param target TODO
- * @returns float
+ * Returns the X alignment of the container that is laid out. This is
+ * computed by the children's preferred sizes, taking their alignments into
+ * account.
+ *
+ * @param target not used here
+ *
+ * @returns the X alignment of the container that is laid out
*/
public float getLayoutAlignmentX(Container target)
{
- return (float) 0.0; // TODO
+ if (target != this.target)
+ throw new AWTError("OverlayLayout can't be shared");
+
+ checkTotalRequirements();
+ return xTotal.alignment;
}
/**
- * getLayoutAlignmentY
- * @param target TODO
- * @returns float
+ * Returns the Y alignment of the container that is laid out. This is
+ * computed by the children's preferred sizes, taking their alignments into
+ * account.
+ *
+ * @param target not used here
+ *
+ * @returns the X alignment of the container that is laid out
*/
public float getLayoutAlignmentY(Container target)
{
- return (float) 0.0; // TODO
+ if (target != this.target)
+ throw new AWTError("OverlayLayout can't be shared");
+
+ checkTotalRequirements();
+ return yTotal.alignment;
}
/**
- * layoutContainer
- * @param target TODO
+ * Lays out the container and it's children.
+ *
+ * The children are laid out one over another.
+ *
+ * The components take as much space as is available in the container, but
+ * not more than specified by their maximum size.
+ *
+ * The overall layout is mainly affected by the components
+ * <code>alignmentX</code> and <code>alignmentY</code> properties. All
+ * components are aligned, so that their alignment points (for either
+ * direction) are placed in one line (the baseline for this direction).
+ *
+ * For example: An X alignment of 0.0 means that the component's alignment
+ * point is at it's left edge, an X alignment of 0.5 means that the alignment
+ * point is in the middle, an X alignment of 1.0 means, the aligment point is
+ * at the right edge. So if you have three components, the first with 0.0,
+ * the second with 0.5 and the third with 1.0, then they are laid out like
+ * this:
+ *
+ * <pre>
+ * +-------+
+ * | 1 |
+ * +-------+
+ * +-------+
+ * | 2 |
+ * +-------+
+ * +---------+
+ * | 3 +
+ * +---------+
+ * </pre>
+ * The above picture shows the X alignment between the components. An Y
+ * alignment like shown above cannot be achieved with this layout manager.
+ * The components are place on top of each other, with the X alignment shown
+ * above.
+ *
+ * @param target not used here
*/
public void layoutContainer(Container target)
{
- // TODO
+ if (target != this.target)
+ throw new AWTError("OverlayLayout can't be shared");
+
+ checkLayout();
+ Component[] children = target.getComponents();
+ for (int i = 0; i < children.length; i++)
+ children[i].setBounds(offsetsX[i], offsetsY[i], spansX[i], spansY[i]);
}
+ /**
+ * Makes sure that the xChildren and yChildren fields are correctly set up.
+ * A call to {@link #invalidateLayout(Container)} sets these fields to null,
+ * so they have to be set up again.
+ */
+ private void checkRequirements()
+ {
+ if (xChildren == null || yChildren == null)
+ {
+ Component[] children = target.getComponents();
+ xChildren = new SizeRequirements[children.length];
+ yChildren = new SizeRequirements[children.length];
+ for (int i = 0; i < children.length; i++)
+ {
+ if (! children[i].isVisible())
+ {
+ xChildren[i] = new SizeRequirements();
+ yChildren[i] = new SizeRequirements();
+ }
+ else
+ {
+ xChildren[i] =
+ new SizeRequirements(children[i].getMinimumSize().width,
+ children[i].getPreferredSize().width,
+ children[i].getMaximumSize().width,
+ children[i].getAlignmentX());
+ yChildren[i] =
+ new SizeRequirements(children[i].getMinimumSize().height,
+ children[i].getPreferredSize().height,
+ children[i].getMaximumSize().height,
+ children[i].getAlignmentY());
+ }
+ }
+ }
+ }
+
+ /**
+ * Makes sure that the xTotal and yTotal fields are set up correctly. A call
+ * to {@link #invalidateLayout} sets these fields to null and they have to be
+ * recomputed.
+ */
+ private void checkTotalRequirements()
+ {
+ if (xTotal == null || yTotal == null)
+ {
+ checkRequirements();
+ xTotal = SizeRequirements.getAlignedSizeRequirements(xChildren);
+ yTotal = SizeRequirements.getAlignedSizeRequirements(yChildren);
+ }
+ }
+
+ /**
+ * Makes sure that the offsetsX, offsetsY, spansX and spansY fields are set
+ * up correctly. A call to {@link #invalidateLayout} sets these fields
+ * to null and they have to be recomputed.
+ */
+ private void checkLayout()
+ {
+ if (offsetsX == null || offsetsY == null || spansX == null
+ || spansY == null)
+ {
+ checkRequirements();
+ checkTotalRequirements();
+ int len = target.getComponents().length;
+ offsetsX = new int[len];
+ offsetsY = new int[len];
+ spansX = new int[len];
+ spansY = new int[len];
+
+ Insets in = target.getInsets();
+ int width = target.getWidth() - in.left - in.right;
+ int height = target.getHeight() - in.top - in.bottom;
+
+ SizeRequirements.calculateAlignedPositions(width, xTotal,
+ xChildren, offsetsX, spansX);
+ SizeRequirements.calculateAlignedPositions(height, yTotal,
+ yChildren, offsetsY, spansY);
+ }
+ }
}
diff --git a/javax/swing/Popup.java b/javax/swing/Popup.java
index 69e1f5168..5b2615d2f 100644
--- a/javax/swing/Popup.java
+++ b/javax/swing/Popup.java
@@ -39,6 +39,7 @@ exception statement from your version. */
package javax.swing;
import java.awt.Component;
+import java.awt.Point;
/**
@@ -89,6 +90,7 @@ public class Popup
*/
protected Popup()
{
+ // Nothing to do here.
}
@@ -129,6 +131,7 @@ public class Popup
*/
JWindow window;
+ private Component contents;
/**
* Constructs a new <code>JWindowPopup</code> given its owner,
@@ -155,10 +158,11 @@ public class Popup
/* Checks whether contents is null. */
super(owner, contents, x, y);
+ this.contents = contents;
window = new JWindow();
- window.getRootPane().add(contents);
+ window.getContentPane().add(contents);
window.setLocation(x, y);
- window.pack();
+ window.setFocusableWindowState(false);
}
@@ -168,6 +172,7 @@ public class Popup
*/
public void show()
{
+ window.setSize(contents.getSize());
window.show();
}
@@ -186,4 +191,100 @@ public class Popup
window.dispose();
}
}
+
+ /**
+ * A popup that displays itself within the JLayeredPane of a JRootPane of
+ * the containment hierarchy of the owner component.
+ *
+ * @author Roman Kennke (kennke@aicas.com)
+ */
+ static class LightweightPopup extends Popup
+ {
+ /**
+ * The owner component for this popup.
+ */
+ Component owner;
+
+ /**
+ * The contents that should be shown.
+ */
+ Component contents;
+
+ /**
+ * The X location in screen coordinates.
+ */
+ int x;
+
+ /**
+ * The Y location in screen coordinates.
+ */
+ int y;
+
+ /**
+ * The panel that holds the content.
+ */
+ private JPanel panel;
+
+ /**
+ * Constructs a new <code>LightweightPopup</code> given its owner,
+ * contents and the screen position where the popup
+ * will appear.
+ *
+ * @param owner the component that should own the popup window; this
+ * provides the JRootPane in which we place the popup window
+ *
+ * @param contents the contents that will be displayed inside
+ * the <code>Popup</code>.
+ *
+ * @param x the horizontal position where the Popup will appear in screen
+ * coordinates
+ *
+ * @param y the vertical position where the Popup will appear in screen
+ * coordinates
+ *
+ * @throws IllegalArgumentException if <code>contents</code>
+ * is <code>null</code>.
+ */
+ public LightweightPopup(Component owner, Component contents, int x, int y)
+ {
+ super(owner, contents, x, y);
+ this.owner = owner;
+ this.contents = contents;
+ this.x = x;
+ this.y = y;
+ }
+
+ /**
+ * Places the popup within the JLayeredPane of the owner component and
+ * makes it visible.
+ */
+ public void show()
+ {
+ JRootPane rootPane = SwingUtilities.getRootPane(owner);
+ JLayeredPane layeredPane = rootPane.getLayeredPane();
+ // We insert a JPanel between the layered pane and the contents so we
+ // can fiddle with the setLocation() method without disturbing a
+ // JPopupMenu (which overrides setLocation in an unusual manner).
+ if (panel == null)
+ {
+ panel = new JPanel();
+ panel.setLayout(null);
+ }
+ panel.add(contents);
+ panel.setSize(contents.getSize());
+ Point layeredPaneLoc = layeredPane.getLocationOnScreen();
+ panel.setLocation(x - layeredPaneLoc.x, y - layeredPaneLoc.y);
+ layeredPane.add(panel, JLayeredPane.POPUP_LAYER);
+ }
+
+ /**
+ * Removes the popup from the JLayeredPane thus making it invisible.
+ */
+ public void hide()
+ {
+ JRootPane rootPane = SwingUtilities.getRootPane(owner);
+ JLayeredPane layeredPane = rootPane.getLayeredPane();
+ layeredPane.remove(panel);
+ }
+ }
}
diff --git a/javax/swing/PopupFactory.java b/javax/swing/PopupFactory.java
index 29cf86d55..7bb2529cd 100644
--- a/javax/swing/PopupFactory.java
+++ b/javax/swing/PopupFactory.java
@@ -39,6 +39,8 @@ exception statement from your version. */
package javax.swing;
import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Point;
/**
@@ -55,8 +57,8 @@ public class PopupFactory
/**
* The shared factory object.
*
- * @see #getSharedFactory
- * @see #setSharedFactory
+ * @see #getSharedInstance
+ * @see #setSharedInstance
*/
private static PopupFactory sharedFactory;
@@ -69,6 +71,7 @@ public class PopupFactory
*/
public PopupFactory()
{
+ // Nothing to do here.
}
@@ -134,6 +137,30 @@ public class PopupFactory
public Popup getPopup(Component owner, Component contents,
int x, int y)
{
- return new Popup.JWindowPopup(owner, contents, x, y);
+ Popup popup = null;
+ // By default we enable lightweight popups since they are more efficient
+ // than heavyweight popups.
+ boolean lightweightEnabled = true;
+ // Special case JPopupMenu here, since it supports a lightweightEnabled
+ // flag that we must respect.
+ if (contents instanceof JPopupMenu)
+ {
+ JPopupMenu menu = (JPopupMenu) contents;
+ lightweightEnabled = menu.isLightWeightPopupEnabled();
+ }
+
+ // If we have a root pane and the contents fits within the root pane and
+ // lightweight popups are enabled, than we can use a lightweight popup.
+ JRootPane root = SwingUtilities.getRootPane(owner);
+ Point rootLoc = root.getLocationOnScreen();
+ Dimension contentsSize = contents.getSize();
+ Dimension rootSize = root.getSize();
+ if (x >= rootLoc.x && y > rootLoc.y
+ && (x - rootLoc.x) + contentsSize.width < rootSize.width
+ && (y - rootLoc.y) + contentsSize.height < rootSize.height)
+ popup = new Popup.LightweightPopup(owner, contents, x, y);
+ else
+ popup = new Popup.JWindowPopup(owner, contents, x, y);
+ return popup;
}
}
diff --git a/javax/swing/RepaintManager.java b/javax/swing/RepaintManager.java
index 54243aea8..37281e03d 100644
--- a/javax/swing/RepaintManager.java
+++ b/javax/swing/RepaintManager.java
@@ -1,5 +1,5 @@
/* RepaintManager.java --
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -43,12 +43,11 @@ import java.awt.Dimension;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.image.VolatileImage;
-import java.util.Enumeration;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.HashMap;
-import java.util.Hashtable;
import java.util.Iterator;
-import java.util.Map;
-import java.util.Vector;
/**
* <p>The repaint manager holds a set of dirty regions, invalid components,
@@ -111,6 +110,62 @@ public class RepaintManager
}
+ /**
+ * Compares two components using their depths in the component hierarchy.
+ * A component with a lesser depth (higher level components) are sorted
+ * before components with a deeper depth (low level components). This is used
+ * to order paint requests, so that the higher level components are painted
+ * before the low level components get painted.
+ *
+ * @author Roman Kennke (kennke@aicas.com)
+ */
+ private class ComponentComparator implements Comparator
+ {
+
+ /**
+ * Compares two components.
+ *
+ * @param o1 the first component
+ * @param o2 the second component
+ *
+ * @return a negative integer, if <code>o1</code> is higher in the
+ * hierarchy than <code>o2</code>, zero, if both are at the same
+ * level and a positive integer, if <code>o1</code> is deeper in
+ * the hierarchy than <code>o2</code>
+ */
+ public int compare(Object o1, Object o2)
+ {
+ if (o1 instanceof JComponent && o2 instanceof JComponent)
+ {
+ JComponent c1 = (JComponent) o1;
+ JComponent c2 = (JComponent) o2;
+ return getDepth(c1) - getDepth(c2);
+ }
+ else
+ throw new ClassCastException("This comparator can only be used with "
+ + "JComponents");
+ }
+
+ /**
+ * Computes the depth for a given JComponent.
+ *
+ * @param c the component to compute the depth for
+ *
+ * @return the depth of the component
+ */
+ private int getDepth(JComponent c)
+ {
+ Component comp = c;
+ int depth = 0;
+ while (comp != null)
+ {
+ comp = comp.getParent();
+ depth++;
+ }
+ return depth;
+ }
+ }
+
/**
* A table storing the dirty regions of components. The keys of this
* table are components, the values are rectangles. Each component maps
@@ -123,7 +178,20 @@ public class RepaintManager
* @see #markCompletelyClean
* @see #markCompletelyDirty
*/
- Hashtable dirtyComponents;
+ HashMap dirtyComponents;
+
+ HashMap workDirtyComponents;
+
+ /**
+ * Stores the order in which the components get repainted.
+ */
+ ArrayList repaintOrder;
+ ArrayList workRepaintOrder;
+
+ /**
+ * The comparator used for ordered inserting into the repaintOrder list.
+ */
+ Comparator comparator;
/**
* A single, shared instance of the helper class. Any methods which mark
@@ -146,14 +214,15 @@ public class RepaintManager
* @see #removeInvalidComponent
* @see #validateInvalidComponents
*/
- Vector invalidComponents;
+ ArrayList invalidComponents;
+ ArrayList workInvalidComponents;
/**
* Whether or not double buffering is enabled on this repaint
* manager. This is merely a hint to clients; the RepaintManager will
* always return an offscreen buffer when one is requested.
*
- * @see #getDoubleBufferingEnabled
+ * @see #isDoubleBufferingEnabled
* @see #setDoubleBufferingEnabled
*/
boolean doubleBufferingEnabled;
@@ -184,7 +253,7 @@ public class RepaintManager
* components in all windows. This is package-private to avoid an accessor
* method.
*
- * @see #currentManager
+ * @see #currentManager(JComponent)
* @see #setCurrentManager
*/
static RepaintManager globalManager;
@@ -194,8 +263,12 @@ public class RepaintManager
*/
public RepaintManager()
{
- dirtyComponents = new Hashtable();
- invalidComponents = new Vector();
+ dirtyComponents = new HashMap();
+ workDirtyComponents = new HashMap();
+ repaintOrder = new ArrayList();
+ workRepaintOrder = new ArrayList();
+ invalidComponents = new ArrayList();
+ workInvalidComponents = new ArrayList();
repaintWorker = new RepaintWorker();
doubleBufferMaximumSize = new Dimension(2000,2000);
doubleBufferingEnabled = true;
@@ -291,7 +364,7 @@ public class RepaintManager
*/
public synchronized void removeInvalidComponent(JComponent component)
{
- invalidComponents.removeElement(component);
+ invalidComponents.remove(component);
}
/**
@@ -315,12 +388,13 @@ public class RepaintManager
public synchronized void addDirtyRegion(JComponent component, int x, int y,
int w, int h)
{
- if (w == 0 || h == 0)
+ if (w == 0 || h == 0 || !component.isShowing())
return;
-
Rectangle r = new Rectangle(x, y, w, h);
if (dirtyComponents.containsKey(component))
r = r.union((Rectangle)dirtyComponents.get(component));
+ else
+ insertInRepaintOrder(component);
dirtyComponents.put(component, r);
if (! repaintWorker.isLive())
{
@@ -328,7 +402,23 @@ public class RepaintManager
SwingUtilities.invokeLater(repaintWorker);
}
}
-
+
+ /**
+ * Inserts a component into the repaintOrder list in an ordered fashion,
+ * using a binary search.
+ *
+ * @param c the component to be inserted
+ */
+ private void insertInRepaintOrder(JComponent c)
+ {
+ if (comparator == null)
+ comparator = new ComponentComparator();
+ int insertIndex = Collections.binarySearch(repaintOrder, c, comparator);
+ if (insertIndex < 0)
+ insertIndex = -(insertIndex + 1);
+ repaintOrder.add(insertIndex, c);
+ }
+
/**
* Get the dirty region associated with a component, or <code>null</code>
* if the component has no dirty region.
@@ -345,7 +435,10 @@ public class RepaintManager
*/
public Rectangle getDirtyRegion(JComponent component)
{
- return (Rectangle) dirtyComponents.get(component);
+ Rectangle dirty = (Rectangle) dirtyComponents.get(component);
+ if (dirty == null)
+ dirty = new Rectangle();
+ return dirty;
}
/**
@@ -363,6 +456,7 @@ public class RepaintManager
{
Rectangle r = component.getBounds();
addDirtyRegion(component, r.x, r.y, r.width, r.height);
+ component.isCompletelyDirty = true;
}
/**
@@ -378,7 +472,11 @@ public class RepaintManager
*/
public void markCompletelyClean(JComponent component)
{
- dirtyComponents.remove(component);
+ synchronized (this)
+ {
+ dirtyComponents.remove(component);
+ }
+ component.isCompletelyDirty = false;
}
/**
@@ -397,13 +495,9 @@ public class RepaintManager
*/
public boolean isCompletelyDirty(JComponent component)
{
- Rectangle dirty = (Rectangle) dirtyComponents.get(component);
- if (dirty == null)
+ if (! dirtyComponents.containsKey(component))
return false;
- Rectangle r = component.getBounds();
- if (r == null)
- return true;
- return dirty.contains(r);
+ return component.isCompletelyDirty;
}
/**
@@ -412,58 +506,56 @@ public class RepaintManager
*/
public void validateInvalidComponents()
{
- for (Enumeration e = invalidComponents.elements(); e.hasMoreElements(); )
+ // In order to keep the blocking of application threads minimal, we switch
+ // the invalidComponents field with the workInvalidComponents field and
+ // work with the workInvalidComponents field.
+ synchronized(this)
+ {
+ ArrayList swap = invalidComponents;
+ invalidComponents = workInvalidComponents;
+ workInvalidComponents = swap;
+ }
+ for (Iterator i = workInvalidComponents.iterator(); i.hasNext(); )
{
- JComponent comp = (JComponent) e.nextElement();
+ JComponent comp = (JComponent) i.next();
if (! (comp.isVisible() && comp.isShowing()))
continue;
comp.validate();
}
- invalidComponents.clear();
+ workInvalidComponents.clear();
}
/**
* Repaint all regions of all components which have been marked dirty in
* the {@link #dirtyComponents} table.
*/
- public void paintDirtyRegions()
+ public synchronized void paintDirtyRegions()
{
- // step 1: pull out roots and calculate spanning damage
-
- HashMap roots = new HashMap();
- for (Enumeration e = dirtyComponents.keys(); e.hasMoreElements(); )
+ // In order to keep the blocking of application threads minimal, we switch
+ // the dirtyComponents field with the workdirtyComponents field and the
+ // repaintOrder field with the workRepaintOrder field and work with the
+ // work* fields.
+ synchronized(this)
+ {
+ ArrayList swap = workRepaintOrder;
+ workRepaintOrder = repaintOrder;
+ repaintOrder = swap;
+ HashMap swap2 = workDirtyComponents;
+ workDirtyComponents = dirtyComponents;
+ dirtyComponents = swap2;
+ }
+ for (Iterator i = workRepaintOrder.iterator(); i.hasNext();)
{
- JComponent comp = (JComponent) e.nextElement();
- if (! (comp.isVisible() && comp.isShowing()))
- continue;
- Rectangle damaged = getDirtyRegion(comp);
- if (damaged.width == 0 || damaged.height == 0)
- continue;
- JRootPane root = comp.getRootPane();
- // If the component has no root, no repainting will occur.
- if (root == null)
+ JComponent comp = (JComponent) i.next();
+ // If a component is marked completely clean in the meantime, then skip
+ // it.
+ Rectangle damaged = (Rectangle) workDirtyComponents.get(comp);
+ if (damaged == null || damaged.isEmpty())
continue;
- Rectangle rootDamage = SwingUtilities.convertRectangle(comp, damaged, root);
- if (! roots.containsKey(root))
- {
- roots.put(root, rootDamage);
- }
- else
- {
- roots.put(root, ((Rectangle)roots.get(root)).union(rootDamage));
- }
- }
- dirtyComponents.clear();
-
- // step 2: paint those roots
- Iterator i = roots.entrySet().iterator();
- while(i.hasNext())
- {
- Map.Entry ent = (Map.Entry) i.next();
- JRootPane root = (JRootPane) ent.getKey();
- Rectangle rect = (Rectangle) ent.getValue();
- root.paintImmediately(rect);
+ comp.paintImmediately(damaged);
}
+ workRepaintOrder.clear();
+ workDirtyComponents.clear();
}
/**
diff --git a/javax/swing/ScrollPaneLayout.java b/javax/swing/ScrollPaneLayout.java
index 940d47d35..edf1f1f42 100644
--- a/javax/swing/ScrollPaneLayout.java
+++ b/javax/swing/ScrollPaneLayout.java
@@ -43,12 +43,9 @@ import java.awt.Container;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.LayoutManager;
-import java.awt.Point;
import java.awt.Rectangle;
import java.io.Serializable;
-import javax.swing.border.Border;
-
/**
* ScrollPaneLayout
* @author Andrew Selkirk
@@ -60,8 +57,11 @@ public class ScrollPaneLayout
private static final long serialVersionUID = -4480022884523193743L;
public static class UIResource extends ScrollPaneLayout
- implements javax.swing.plaf.UIResource {
- public UIResource() {
+ implements javax.swing.plaf.UIResource
+ {
+ public UIResource()
+ {
+ super();
}
}
@@ -77,8 +77,9 @@ public class ScrollPaneLayout
protected int vsbPolicy;
protected int hsbPolicy;
- public ScrollPaneLayout() {
-
+ public ScrollPaneLayout()
+ {
+ // Nothing to do here.
}
public void syncWithScrollPane(JScrollPane scrollPane) {
@@ -251,151 +252,53 @@ public class ScrollPaneLayout
return null;
}
- private static void maybeSetPreferredSize(JComponent src, Dimension dim)
- {
- Dimension tmp = null;
- if (src != null)
- tmp = src.getPreferredSize();
- if (tmp != null)
- dim.setSize(tmp);
- }
-
- private static void maybeSetMinimumSize(JComponent src, Dimension dim)
- {
- Dimension tmp = null;
- if (src != null)
- tmp = src.getMinimumSize();
- if (tmp != null)
- dim.setSize(tmp);
- }
-
public Dimension preferredLayoutSize(Container parent)
{
- if (parent != null && parent instanceof JScrollPane)
- {
- JScrollPane sc = (JScrollPane) parent;
- synchronized (sc.getTreeLock ())
- {
- Dimension insetsSize = new Dimension(0,0);
- Dimension viewportSize = new Dimension(0,0);
- Dimension viewportInsetsSize = new Dimension(0,0);
- Dimension columnHeaderSize = new Dimension(0,0);
- Dimension rowHeaderSize = new Dimension(0,0);
- Dimension verticalScrollBarSize = new Dimension(0,0);
- Dimension horizontalScrollBarSize = new Dimension(0,0);
-
- Insets insets = sc.getInsets();
- Border viewportBorder = sc.getViewportBorder();
- Insets viewportInsets = null;
-
- if (viewportBorder != null)
- {
- viewportInsets = viewportBorder.getBorderInsets(parent);
- if (viewportInsets != null)
- viewportInsetsSize.setSize(viewportInsets.left + viewportInsets.right,
- viewportInsets.top + viewportInsets.bottom);
- }
-
- if (insets != null)
- insetsSize.setSize(insets.left + insets.right,
- insets.top + insets.bottom);
-
- if (viewport != null)
- {
- Component view = null;
- Scrollable scr = null;
- Dimension pref = null;
-
- view = viewport.getView();
- if (view != null && view instanceof Scrollable)
- scr = (Scrollable) view;
- if (scr != null)
- pref = scr.getPreferredScrollableViewportSize();
- if (pref == null)
- pref = viewport.getPreferredSize();
- if (pref != null)
- viewportSize.setSize(pref);
- }
-
- maybeSetPreferredSize(colHead, columnHeaderSize);
- maybeSetPreferredSize(rowHead, rowHeaderSize);
- maybeSetPreferredSize(vsb, verticalScrollBarSize);
- maybeSetPreferredSize(hsb, horizontalScrollBarSize);
-
- return new Dimension(insetsSize.width
- + viewportSize.width
- + viewportInsetsSize.width
- + rowHeaderSize.width
- + verticalScrollBarSize.width,
- insetsSize.height
- + viewportSize.height
- + viewportInsetsSize.height
- + columnHeaderSize.height
- + horizontalScrollBarSize.height);
- }
- }
- else
- {
- return new Dimension(0,0);
- }
+ // Sun's implementation simply throws a ClassCastException if
+ // parent is no JScrollPane, so do we.
+ JScrollPane sc = (JScrollPane) parent;
+ Dimension viewportSize = viewport.getPreferredSize();
+ Dimension viewSize = viewport.getViewSize();
+ int width = viewportSize.width;
+ int height = viewportSize.height;
+
+ // horizontal scrollbar needed if the view's preferred width
+ // is larger than the viewport's preferred width
+ if (hsb != null && viewSize.width > viewportSize.width)
+ height += hsb.getPreferredSize().height;
+
+ // vertical scrollbar needed if the view's preferred height
+ // is larger than the viewport's preferred height
+ if (vsb != null && viewSize.height > viewportSize.height)
+ width += vsb.getPreferredSize().width;
+ if (rowHead != null && rowHead.isVisible())
+ width += rowHead.getPreferredSize().width;
+ if (colHead != null && colHead.isVisible())
+ height += colHead.getPreferredSize().height;
+ Insets i = sc.getInsets();
+ return new Dimension(width + i.left + i.right,
+ height + i.left + i.right);
}
public Dimension minimumLayoutSize(Container parent)
{
- if (parent instanceof JScrollPane)
- {
- JScrollPane sc = (JScrollPane) parent;
- synchronized (sc.getTreeLock ())
- {
- Dimension insetsSize = new Dimension(0,0);
- Dimension viewportSize = new Dimension(0,0);
- Dimension viewportInsetsSize = new Dimension(0,0);
- Dimension columnHeaderSize = new Dimension(0,0);
- Dimension rowHeaderSize = new Dimension(0,0);
- Dimension verticalScrollBarSize = new Dimension(0,0);
- Dimension horizontalScrollBarSize = new Dimension(0,0);
-
- Insets insets = sc.getInsets();
- Border viewportBorder = sc.getViewportBorder();
- Insets viewportInsets = null;
-
- if (viewportBorder != null)
- {
- viewportInsets = viewportBorder.getBorderInsets(parent);
- if (viewportInsets != null)
- viewportInsetsSize.setSize(viewportInsets.left + viewportInsets.right,
- viewportInsets.top + viewportInsets.bottom);
- }
-
- if (insets != null)
- insetsSize.setSize(insets.left + insets.right,
- insets.top + insets.bottom);
-
- maybeSetMinimumSize(colHead, columnHeaderSize);
- maybeSetMinimumSize(rowHead, rowHeaderSize);
-
- if (vsbPolicy != VERTICAL_SCROLLBAR_NEVER)
- maybeSetMinimumSize(vsb, verticalScrollBarSize);
-
- if (hsbPolicy != HORIZONTAL_SCROLLBAR_NEVER)
- maybeSetMinimumSize(hsb, horizontalScrollBarSize);
-
- return new Dimension(insetsSize.width
- + viewportSize.width
- + viewportInsetsSize.width
- + rowHeaderSize.width
- + verticalScrollBarSize.width,
- insetsSize.height
- + viewportSize.height
- + viewportInsetsSize.height
- + columnHeaderSize.height
- + horizontalScrollBarSize.height);
- }
- }
- else
- {
- return new Dimension(0,0);
- }
+ // Sun's implementation simply throws a ClassCastException if
+ // parent is no JScrollPane, so do we.
+ JScrollPane sc = (JScrollPane) parent;
+ Dimension viewportSize = viewport.getMinimumSize();
+ int width = viewportSize.width;
+ int height = viewportSize.height;
+ if (hsb != null && hsb.isVisible())
+ height += hsb.getMinimumSize().height;
+ if (vsb != null && vsb.isVisible())
+ width += vsb.getMinimumSize().width;
+ if (rowHead != null && rowHead.isVisible())
+ width += rowHead.getMinimumSize().width;
+ if (colHead != null && colHead.isVisible())
+ height += colHead.getMinimumSize().height;
+ Insets i = sc.getInsets();
+ return new Dimension(width + i.left + i.right,
+ height + i.top + i.bottom);
}
/**
@@ -421,100 +324,91 @@ public class ScrollPaneLayout
*/
public void layoutContainer(Container parent)
{
- if (parent instanceof JScrollPane)
+ // Sun's implementation simply throws a ClassCastException if
+ // parent is no JScrollPane, so do we.
+ JScrollPane sc = (JScrollPane) parent;
+ JViewport viewport = sc.getViewport();
+ Dimension viewSize = viewport.getViewSize();
+
+ int x1 = 0, x2 = 0, x3 = 0, x4 = 0;
+ int y1 = 0, y2 = 0, y3 = 0, y4 = 0;
+ Rectangle scrollPaneBounds = SwingUtilities.calculateInnerArea(sc, null);
+
+ x1 = scrollPaneBounds.x;
+ y1 = scrollPaneBounds.y;
+ x4 = scrollPaneBounds.x + scrollPaneBounds.width;
+ y4 = scrollPaneBounds.y + scrollPaneBounds.height;
+ if (colHead != null)
+ y2 = y1 + colHead.getPreferredSize().height;
+ else
+ y2 = y1;
+
+ if (rowHead != null)
+ x2 = x1 + rowHead.getPreferredSize().width;
+ else
+ x2 = x1;
+
+ int vsbPolicy = sc.getVerticalScrollBarPolicy();
+ int hsbPolicy = sc.getHorizontalScrollBarPolicy();
+
+ boolean showVsb =
+ (vsb != null)
+ && ((vsbPolicy == VERTICAL_SCROLLBAR_ALWAYS)
+ || (vsbPolicy == VERTICAL_SCROLLBAR_AS_NEEDED
+ && viewSize.height > (y4 - y2)));
+ boolean showHsb =
+ (hsb != null)
+ && ((hsbPolicy == HORIZONTAL_SCROLLBAR_ALWAYS)
+ || (hsbPolicy == HORIZONTAL_SCROLLBAR_AS_NEEDED
+ && viewSize.width > (x4 - x2)));
+
+ if (!showVsb)
+ x3 = x4;
+ else
+ x3 = x4 - vsb.getPreferredSize().width;
+
+ if (!showHsb)
+ y3 = y4;
+ else
+ y3 = y4 - hsb.getPreferredSize().height;
+
+ // now set the layout
+ if (viewport != null)
+ viewport.setBounds(new Rectangle(x2, y2, x3 - x2, y3 - y2));
+
+ if (colHead != null)
+ colHead.setBounds(new Rectangle(x2, y1, x3 - x2, y2 - y1));
+
+ if (rowHead != null)
+ rowHead.setBounds(new Rectangle(x1, y2, x2 - x1, y3 - y2));
+
+ if (showVsb)
+ {
+ vsb.setVisible(true);
+ vsb.setBounds(new Rectangle(x3, y2, x4 - x3, y3 - y2));
+ }
+ else if (vsb != null)
+ vsb.setVisible(false);
+
+ if (showHsb)
{
- JScrollPane sc = (JScrollPane) parent;
- synchronized (sc.getTreeLock ())
- {
- JViewport viewport = sc.getViewport();
- Dimension viewSize = viewport.getViewSize();
- Point viewPos = viewport.getViewPosition();
-
- int x1 = 0, x2 = 0, x3 = 0, x4 = 0;
- int y1 = 0, y2 = 0, y3 = 0, y4 = 0;
-
- Rectangle scrollPaneBounds = SwingUtilities.calculateInnerArea(sc, null);
-
- x1 = scrollPaneBounds.x;
- y1 = scrollPaneBounds.y;
- x4 = scrollPaneBounds.x + scrollPaneBounds.width;
- y4 = scrollPaneBounds.y + scrollPaneBounds.height;
-
- if (colHead != null)
- y2 = y1 + colHead.getPreferredSize().height;
- else
- y2 = y1;
-
- if (rowHead != null)
- x2 = x1 + rowHead.getPreferredSize().width;
- else
- x2 = x1;
-
- int vsbPolicy = sc.getVerticalScrollBarPolicy();
- int hsbPolicy = sc.getHorizontalScrollBarPolicy();
-
- x3 = x4 - vsb.getPreferredSize().width;
- y3 = y4 - hsb.getPreferredSize().height;
-
- boolean showVsb =
- (vsb != null)
- && ((vsbPolicy == VERTICAL_SCROLLBAR_ALWAYS)
- || (vsbPolicy == VERTICAL_SCROLLBAR_AS_NEEDED
- && viewSize.height > (y3 - y2)));
-
- boolean showHsb =
- (hsb != null)
- && ((hsbPolicy == HORIZONTAL_SCROLLBAR_ALWAYS)
- || (hsbPolicy == HORIZONTAL_SCROLLBAR_AS_NEEDED
- && viewSize.width > (x3 - x2)));
-
- if (!showVsb)
- x3 = x4;
-
- if (!showHsb)
- y3 = y4;
-
- // now set the layout
-
- if (viewport != null)
- viewport.setBounds(new Rectangle(x2, y2, x3-x2, y3-y2));
-
- if (colHead != null)
- colHead.setBounds(new Rectangle(x2, y1, x3-x2, y2-y1));
-
- if (rowHead != null)
- rowHead.setBounds(new Rectangle(x1, y2, x2-x1, y3-y2));
-
- if (showVsb)
- {
- vsb.setVisible(true);
- vsb.setBounds(new Rectangle(x3, y2, x4-x3, y3-y2));
- }
- else if (vsb != null)
- vsb.setVisible(false);
-
- if (showHsb)
- {
- hsb.setVisible(true);
- hsb.setBounds(new Rectangle(x2, y3, x3-x2, y4-y3));
- }
- else if (hsb != null)
- hsb.setVisible(false);
-
- if (upperLeft != null)
- upperLeft.setBounds(new Rectangle(x1, y1, x2-x1, y2-y1));
-
- if (upperRight != null)
- upperRight.setBounds(new Rectangle(x3, y1, x4-x3, y2-y1));
-
- if (lowerLeft != null)
- lowerLeft.setBounds(new Rectangle(x1, y3, x2-x1, y4-y3));
-
- if (lowerRight != null)
- lowerRight.setBounds(new Rectangle(x3, y3, x4-x3, y4-y3));
-
- }
+ hsb.setVisible(true);
+ hsb.setBounds(new Rectangle(x2, y3, x3 - x2, y4 - y3));
}
+ else if (hsb != null)
+ hsb.setVisible(false);
+
+ if (upperLeft != null)
+ upperLeft.setBounds(new Rectangle(x1, y1, x2 - x1, y2 - y1));
+
+ if (upperRight != null)
+ upperRight.setBounds(new Rectangle(x3, y1, x4 - x3, y2 - y1));
+
+ if (lowerLeft != null)
+ lowerLeft.setBounds(new Rectangle(x1, y3, x2 - x1, y4 - y3));
+
+ if (lowerRight != null)
+ lowerRight.setBounds(new Rectangle(x3, y3, x4 - x3, y4 - y3));
}
/**
diff --git a/javax/swing/SizeRequirements.java b/javax/swing/SizeRequirements.java
index 4f9d41824..dc855dd32 100644
--- a/javax/swing/SizeRequirements.java
+++ b/javax/swing/SizeRequirements.java
@@ -166,7 +166,34 @@ public class SizeRequirements implements Serializable
public static SizeRequirements
getAlignedSizeRequirements(SizeRequirements[] children)
{
- return null; // TODO
+ float minLeft = 0;
+ float minRight = 0;
+ float prefLeft = 0;
+ float prefRight = 0;
+ float maxLeft = 0;
+ float maxRight = 0;
+ for (int i = 0; i < children.length; i++)
+ {
+ float myMinLeft = children[i].minimum * children[i].alignment;
+ float myMinRight = children[i].minimum - myMinLeft;
+ minLeft = Math.max(myMinLeft, minLeft);
+ minRight = Math.max(myMinRight, minRight);
+ float myPrefLeft = children[i].preferred * children[i].alignment;
+ float myPrefRight = children[i].preferred - myPrefLeft;
+ prefLeft = Math.max(myPrefLeft, prefLeft);
+ prefRight = Math.max(myPrefRight, prefRight);
+ float myMaxLeft = children[i].maximum * children[i].alignment;
+ float myMaxRight = children[i].maximum - myMaxLeft;
+ maxLeft = Math.max(myMaxLeft, maxLeft);
+ maxRight = Math.max(myMaxRight, maxRight);
+ }
+ int minSize = (int) (minLeft + minRight);
+ int prefSize = (int) (prefLeft + prefRight);
+ int maxSize = (int) (maxLeft + maxRight);
+ float align = prefLeft / (prefRight + prefLeft);
+ if (Float.isNaN(align))
+ align = 0;
+ return new SizeRequirements(minSize, prefSize, maxSize, align);
}
/**
@@ -232,6 +259,7 @@ public class SizeRequirements implements Serializable
int[] offsets, int[] spans,
boolean forward)
{
+ int span = 0;
if (forward)
{
int offset = 0;
@@ -239,6 +267,7 @@ public class SizeRequirements implements Serializable
{
offsets[i] = offset;
spans[i] = children[i].preferred;
+ span += spans[i];
offset += children[i].preferred;
}
}
@@ -249,9 +278,86 @@ public class SizeRequirements implements Serializable
{
offset -= children[i].preferred;
offsets[i] = offset;
+ span += spans[i];
spans[i] = children[i].preferred;
}
}
+ // Adjust spans so that we exactly fill the allocated region. If
+ if (span > allocated)
+ adjustSmaller(allocated, children, spans, span);
+ else if (span < allocated)
+ adjustGreater(allocated, children, spans, span);
+
+ // Adjust offsets.
+ if (forward)
+ {
+ int offset = 0;
+ for (int i = 0; i < children.length; i++)
+ {
+ offsets[i] = offset;
+ offset += spans[i];
+ }
+ }
+ else
+ {
+ int offset = allocated;
+ for (int i = 0; i < children.length; i++)
+ {
+ offset -= spans[i];
+ offsets[i] = offset;
+ }
+ }
+ }
+
+ private static void adjustSmaller(int allocated, SizeRequirements[] children,
+ int[] spans, int span)
+ {
+ // Sum up (prefSize - minSize) over all children
+ int sumDelta = 0;
+ for (int i = 0; i < children.length; i++)
+ sumDelta += children[i].preferred - children[i].minimum;
+
+ // If we have sumDelta == 0, then all components have prefSize == maxSize
+ // and we can't do anything about it.
+ if (sumDelta == 0)
+ return;
+
+ // Adjust all sizes according to their preferred and minimum sizes.
+ for (int i = 0; i < children.length; i++)
+ {
+ double factor = ((double) (children[i].preferred - children[i].minimum))
+ / ((double) sumDelta);
+ // In case we have a sumDelta of 0, the factor should also be 0.
+ if (Double.isNaN(factor))
+ factor = 0;
+ spans[i] -= factor * (span - allocated);
+ }
+ }
+
+ private static void adjustGreater(int allocated, SizeRequirements[] children,
+ int[] spans, int span)
+ {
+ // Sum up (maxSize - prefSize) over all children
+ int sumDelta = 0;
+ for (int i = 0; i < children.length; i++)
+ {
+ sumDelta += children[i].maximum - children[i].preferred;
+ if (sumDelta < 0)
+ sumDelta = Integer.MAX_VALUE;
+ }
+
+ // If we have sumDelta == 0, then all components have prefSize == maxSize
+ // and we can't do anything about it.
+ if (sumDelta == 0)
+ return;
+
+ // Adjust all sizes according to their preferred and minimum sizes.
+ for (int i = 0; i < children.length; i++)
+ {
+ double factor = ((double) (children[i].maximum - children[i].preferred))
+ / ((double) sumDelta);
+ spans[i] -= factor * (span - allocated);
+ }
}
/**
@@ -317,15 +423,77 @@ public class SizeRequirements implements Serializable
int[] offset, int[] spans,
boolean forward)
{
- // TODO: Implement this correctly.
- for (int i = 0; i < children.length; ++i)
+ // First we compute the position of the baseline.
+ float baseline = allocated * total.alignment;
+
+ // Now we can layout the components along the baseline.
+ for (int i = 0; i < children.length; i++)
{
- // This is only a hack to make things work a little.
- spans[i] = Math.min(allocated, children[i].maximum);
+ float align = children[i].alignment;
+ // Try to fit the component into the available space.
+ int[] spanAndOffset = new int[2];
+ if (align < .5F || baseline == 0)
+ adjustFromRight(children[i], baseline, allocated, spanAndOffset);
+ else
+ adjustFromLeft(children[i], baseline, allocated, spanAndOffset);
+ spans[i] = spanAndOffset[0];
+ offset[i] = spanAndOffset[1];
}
}
/**
+ * Adjusts the span and offset of a component for the aligned layout.
+ *
+ * @param reqs
+ * @param baseline
+ * @param allocated
+ * @param spanAndOffset
+ */
+ private static void adjustFromRight(SizeRequirements reqs, float baseline,
+ int allocated, int[] spanAndOffset)
+ {
+ float right = allocated - baseline;
+ // If the resulting span exceeds the maximum of the component, then adjust
+ // accordingly.
+ float maxRight = ((float) reqs.maximum) * (1.F - reqs.alignment);
+ if (right / (1.F - reqs.alignment) > reqs.maximum)
+ right = maxRight;
+ // If we have not enough space on the left side, then adjust accordingly.
+ if (right / (1.F - reqs.alignment) * reqs.alignment > allocated - baseline)
+ right = ((float) (allocated - baseline))
+ / reqs.alignment * (1.F - reqs.alignment);
+
+ spanAndOffset[0] = (int) (right / (1.F - reqs.alignment));
+ spanAndOffset[1] = (int) (baseline - spanAndOffset[0] * reqs.alignment);
+ }
+
+ /**
+ * Adjusts the span and offset of a component for the aligned layout.
+ *
+ * @param reqs
+ * @param baseline
+ * @param allocated
+ * @param spanAndOffset
+ */
+ private static void adjustFromLeft(SizeRequirements reqs, float baseline,
+ int allocated, int[] spanAndOffset)
+ {
+ float left = baseline;
+ // If the resulting span exceeds the maximum of the component, then adjust
+ // accordingly.
+ float maxLeft = ((float) reqs.maximum) * reqs.alignment;
+ if (left / reqs.alignment > reqs.maximum)
+ left = maxLeft;
+ // If we have not enough space on the right side, then adjust accordingly.
+ if (left / reqs.alignment * (1.F - reqs.alignment) > allocated - baseline)
+ left = ((float) (allocated - baseline))
+ / (1.F - reqs.alignment) * reqs.alignment;
+
+ spanAndOffset[0] = (int) (left / reqs.alignment);
+ spanAndOffset[1] = (int) (baseline - spanAndOffset[0] * reqs.alignment);
+ }
+
+ /**
* Returns an array of new preferred sizes for the children based on
* <code>delta</code>. <code>delta</code> specifies a change in the
* allocated space. The sizes of the children will be shortened or
diff --git a/javax/swing/SortingFocusTraversalPolicy.java b/javax/swing/SortingFocusTraversalPolicy.java
index fada17c63..96ef38329 100644
--- a/javax/swing/SortingFocusTraversalPolicy.java
+++ b/javax/swing/SortingFocusTraversalPolicy.java
@@ -72,7 +72,7 @@ public class SortingFocusTraversalPolicy
* simply advance within the containing focus cycle, subject to the
* {@link #comparator} order and the {@link #accept} judgment.</p>
*
- * @see #getNextFocusableComponent
+ * @see #getImplicitDownCycleTraversal()
*/
boolean implicitDownCycleTraversal = true;
diff --git a/javax/swing/Spring.java b/javax/swing/Spring.java
index 69c88c77d..8f7105d49 100644
--- a/javax/swing/Spring.java
+++ b/javax/swing/Spring.java
@@ -65,6 +65,7 @@ public abstract class Spring
*/
protected Spring()
{
+ // Nothing to do here.
}
/**
diff --git a/javax/swing/SwingUtilities.java b/javax/swing/SwingUtilities.java
index 216057e0e..a1fba1cbd 100644
--- a/javax/swing/SwingUtilities.java
+++ b/javax/swing/SwingUtilities.java
@@ -890,7 +890,7 @@ public class SwingUtilities
iconR.y = 0;
textR.y = (horizontalTextPosition == CENTER
? iconR.height + textIconGap
- : iconR.height - textR.height);
+ : Math.max(iconR.height - textR.height, 0));
break;
case CENTER:
int centerLine = Math.max(textR.height, iconR.height) / 2;
@@ -1116,7 +1116,7 @@ public class SwingUtilities
* <pre>
* [{@link javax.swing.JComponent#getActionMap()}]
* --&gt; [{@link javax.swing.ActionMap}]
- * parent --&gt; [{@link javax.swing.text.KeymapActionMap}]
+ * parent --&gt; [{@link javax.swing.text.JTextComponent.KeymapActionMap}]
* parent --&gt; [{@link javax.swing.plaf.ActionMapUIResource}]
* </pre>
*
@@ -1159,7 +1159,7 @@ public class SwingUtilities
* <pre>
* [{@link javax.swing.JComponent#getInputMap()}]
* --&gt; [{@link javax.swing.InputMap}]
- * parent --&gt; [{@link javax.swing.text.KeymapWrapper}]
+ * parent --&gt; [{@link javax.swing.text.JTextComponent.KeymapWrapper}]
* parent --&gt; [{@link javax.swing.plaf.InputMapUIResource}]
* </pre>
*
diff --git a/javax/swing/ToolTipManager.java b/javax/swing/ToolTipManager.java
index 227144f44..03835794b 100644
--- a/javax/swing/ToolTipManager.java
+++ b/javax/swing/ToolTipManager.java
@@ -44,7 +44,6 @@ import java.awt.FlowLayout;
import java.awt.LayoutManager;
import java.awt.Panel;
import java.awt.Point;
-import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
@@ -68,6 +67,7 @@ public class ToolTipManager extends MouseAdapter implements MouseMotionListener
*/
protected stillInsideTimerAction()
{
+ // Nothing to do here.
}
/**
@@ -93,6 +93,7 @@ public class ToolTipManager extends MouseAdapter implements MouseMotionListener
*/
protected outsideTimerAction()
{
+ // Nothing to do here.
}
/**
@@ -103,6 +104,7 @@ public class ToolTipManager extends MouseAdapter implements MouseMotionListener
*/
public void actionPerformed(ActionEvent event)
{
+ // TODO: What should be done here, if anything?
}
}
@@ -118,6 +120,7 @@ public class ToolTipManager extends MouseAdapter implements MouseMotionListener
*/
protected insideTimerAction()
{
+ // Nothing to do here.
}
/**
@@ -421,13 +424,6 @@ public class ToolTipManager extends MouseAdapter implements MouseMotionListener
insideTimer.stop();
hideTip();
}
-
- if (currentComponent == null)
- currentComponent = (Component) event.getSource();
-
- currentComponent.invalidate();
- currentComponent.validate();
- currentComponent.repaint();
}
/**
@@ -452,16 +448,8 @@ public class ToolTipManager extends MouseAdapter implements MouseMotionListener
public void mouseMoved(MouseEvent event)
{
currentPoint = event.getPoint();
- if (currentTip != null)
- {
- if (currentComponent == null)
- currentComponent = (Component) event.getSource();
-
- String text = ((JComponent) currentComponent).getToolTipText(event);
- currentTip.setTipText(text);
- }
if (enterTimer.isRunning())
- enterTimer.restart();
+ enterTimer.restart();
}
/**
@@ -471,78 +459,103 @@ public class ToolTipManager extends MouseAdapter implements MouseMotionListener
*/
void showTip()
{
- if (! enabled || currentComponent == null ||
- (currentTip != null && currentTip.isVisible()))
+ if (!enabled || currentComponent == null || !currentComponent.isEnabled()
+ || (currentTip != null && currentTip.isVisible()))
return;
- if (currentTip == null
- || currentTip.getComponent() != currentComponent
+ if (currentTip == null || currentTip.getComponent() != currentComponent
&& currentComponent instanceof JComponent)
currentTip = ((JComponent) currentComponent).createToolTip();
-
+
+ currentTip.setVisible(true);
+ Container parent = currentComponent.getParent();
Point p = currentPoint;
Dimension dims = currentTip.getPreferredSize();
- if (canToolTipFit(currentTip))
- {
- JLayeredPane pane = ((JRootPane) SwingUtilities.getAncestorOfClass(JRootPane.class,
- currentComponent))
- .getLayeredPane();
-
- // This should never happen, but just in case.
- if (pane == null)
- return;
-
- if (containerPanel != null)
- hideTip();
- if (isLightWeightPopupEnabled())
- {
- containerPanel = new Panel();
- JRootPane root = new JRootPane();
- root.getContentPane().add(currentTip);
- containerPanel.add(root);
- }
- else
- {
- containerPanel = new JPanel();
- containerPanel.add(currentTip);
- }
- LayoutManager lm = containerPanel.getLayout();
- if (lm instanceof FlowLayout)
- {
- FlowLayout fm = (FlowLayout) lm;
- fm.setVgap(0);
- fm.setHgap(0);
- }
-
- p = getGoodPoint(p, pane, currentTip, dims);
-
- pane.add(containerPanel);
- containerPanel.setBounds(p.x, p.y, dims.width, dims.height);
- currentTip.setBounds(0, 0, dims.width, dims.height);
-
- pane.revalidate();
- pane.repaint();
- }
+
+ if (parent instanceof JPopupMenu)
+ setLightWeightPopupEnabled(((JPopupMenu) parent).isLightWeightPopupEnabled());
else
+ setLightWeightPopupEnabled(true);
+
+ if (isLightWeightPopupEnabled())
{
- if (currentComponent.isShowing())
+ JLayeredPane pane = null;
+ JRootPane r = ((JRootPane) SwingUtilities.
+ getAncestorOfClass(JRootPane.class, currentComponent));
+ if (r != null)
+ pane = r.getLayeredPane();
+ if (pane == null)
+ return;
+
+ if (containerPanel != null)
+ hideTip();
+
+ containerPanel = new Panel();
+ JRootPane root = new JRootPane();
+ root.getContentPane().add(currentTip);
+ containerPanel.add(root);
+
+ LayoutManager lm = containerPanel.getLayout();
+ if (lm instanceof FlowLayout)
{
- SwingUtilities.convertPointToScreen(p, currentComponent);
- tooltipWindow = new JDialog();
- tooltipWindow.getContentPane().add(currentTip);
- tooltipWindow.setUndecorated(true);
- tooltipWindow.getRootPane().
- setWindowDecorationStyle(JRootPane.PLAIN_DIALOG);
- tooltipWindow.setFocusable(false);
- tooltipWindow.pack();
- tooltipWindow.setBounds(p.x, p.y, dims.width, dims.height);
- tooltipWindow.show();
+ FlowLayout fm = (FlowLayout) lm;
+ fm.setVgap(0);
+ fm.setHgap(0);
}
+
+ p = SwingUtilities.convertPoint(currentComponent, p, pane);
+ p = adjustLocation(p, pane, dims);
+
+ pane.add(containerPanel);
+ containerPanel.setBounds(p.x, p.y, dims.width, dims.height);
+ currentTip.setBounds(0, 0, dims.width, dims.height);
+ containerPanel.validate();
+ containerPanel.repaint();
+ }
+ else if (currentComponent.isShowing())
+ {
+ SwingUtilities.convertPointToScreen(p, currentComponent);
+ p = adjustLocation(p, SwingUtilities.getWindowAncestor(currentComponent),
+ dims);
+
+ tooltipWindow = new JDialog();
+ tooltipWindow.setContentPane(currentTip);
+ tooltipWindow.setUndecorated(true);
+ tooltipWindow.getRootPane().
+ setWindowDecorationStyle(JRootPane.PLAIN_DIALOG);
+ tooltipWindow.pack();
+ tooltipWindow.setBounds(p.x, p.y, dims.width, dims.height);
+ tooltipWindow.show();
+ tooltipWindow.validate();
+ tooltipWindow.repaint();
+ currentTip.revalidate();
+ currentTip.repaint();
}
- currentTip.setVisible(true);
}
/**
+ * Adjusts the point to a new location on the component,
+ * using the currentTip's dimensions.
+ *
+ * @param p - the point to convert.
+ * @param c - the component the point is on.
+ * @param d - the dimensions of the currentTip.
+ */
+ private Point adjustLocation(Point p, Component c, Dimension d)
+ {
+ if (p.x + d.width > c.getWidth())
+ p.x -= d.width;
+ if (p.x < 0)
+ p.x = 0;
+ if (p.y + d.height < c.getHeight())
+ p.y += d.height;
+ if (p.y + d.height > c.getHeight())
+ p.y -= d.height*2;
+
+ return p;
+ }
+
+ /**
* This method hides the ToolTip.
* This is package-private to avoid an accessor method.
*/
@@ -557,15 +570,11 @@ public class ToolTipManager extends MouseAdapter implements MouseMotionListener
if (parent == null)
return;
parent.remove(containerPanel);
- parent.invalidate();
- parent.validate();
- parent.repaint();
parent = currentTip.getParent();
if (parent == null)
return;
parent.remove(currentTip);
-
containerPanel = null;
}
if (tooltipWindow != null)
@@ -574,35 +583,7 @@ public class ToolTipManager extends MouseAdapter implements MouseMotionListener
tooltipWindow.dispose();
tooltipWindow = null;
}
- }
-
- /**
- * This method returns a point in the LayeredPane where the ToolTip can be
- * shown. The point returned (if the ToolTip is to be displayed at the
- * preferred dimensions) will always place the ToolTip inside the
- * currentComponent if possible.
- *
- * @param p The last known good point for the mouse.
- * @param c The JLayeredPane in the first RootPaneContainer up from the
- * currentComponent.
- * @param tip The ToolTip to display.
- * @param dims The ToolTip preferred dimensions (can be null).
- *
- * @return A good point to place the ToolTip.
- */
- private Point getGoodPoint(Point p, JLayeredPane c, JToolTip tip,
- Dimension dims)
- {
- if (dims == null)
- dims = tip.getPreferredSize();
- Rectangle bounds = currentComponent.getBounds();
- if (p.x + dims.width > bounds.width)
- p.x = bounds.width - dims.width;
- if (p.y + dims.height > bounds.height)
- p.y = bounds.height - dims.height;
-
- p = SwingUtilities.convertPoint(currentComponent, p, c);
- return p;
+ currentTip = null;
}
/**
@@ -627,25 +608,4 @@ public class ToolTipManager extends MouseAdapter implements MouseMotionListener
Component target = SwingUtilities.getDeepestComponentAt(parent, p.x, p.y);
return target;
}
-
- /**
- * This method returns whether the ToolTip can fit in the first
- * RootPaneContainer up from the currentComponent.
- *
- * @param tip The ToolTip.
- *
- * @return Whether the ToolTip can fit.
- */
- private boolean canToolTipFit(JToolTip tip)
- {
- JRootPane root = (JRootPane) SwingUtilities.getAncestorOfClass(JRootPane.class,
- currentComponent);
- if (root == null)
- return false;
- Dimension pref = tip.getPreferredSize();
- Dimension rootSize = root.getSize();
- if (rootSize.width > pref.width && rootSize.height > pref.height)
- return true;
- return false;
- }
}
diff --git a/javax/swing/TransferHandler.java b/javax/swing/TransferHandler.java
index 96cb9d42a..73479f5c8 100644
--- a/javax/swing/TransferHandler.java
+++ b/javax/swing/TransferHandler.java
@@ -162,15 +162,18 @@ public class TransferHandler implements Serializable
}
public void exportAsDrag (JComponent c, InputEvent e, int action)
- {
+ {
+ // TODO: Implement this properly
}
protected void exportDone (JComponent c, Transferable data, int action)
{
+ // TODO: Implement this properly
}
public void exportToClipboard(JComponent c, Clipboard clip, int action)
{
+ // TODO: Implement this properly
}
public int getSourceActions (JComponent c)
diff --git a/javax/swing/UIDefaults.java b/javax/swing/UIDefaults.java
index ab78ca644..f6aee1b94 100644
--- a/javax/swing/UIDefaults.java
+++ b/javax/swing/UIDefaults.java
@@ -577,8 +577,8 @@ public class UIDefaults extends Hashtable
*
* @param key the key to the requested entry
*
- * @return the boolean entry for <code>key</code> or null if no such entry
- * exists
+ * @return The boolean entry for <code>key</code> or <code>false</code> if no
+ * such entry exists.
*/
public boolean getBoolean(Object key)
{
@@ -674,9 +674,9 @@ public class UIDefaults extends Hashtable
return null;
try
{
- if (loader != null)
- return loader.loadClass (className);
- return Class.forName (className);
+ if (loader == null)
+ loader = ClassLoader.getSystemClassLoader();
+ return loader.loadClass (className);
}
catch (Exception e)
{
diff --git a/javax/swing/UIManager.java b/javax/swing/UIManager.java
index f4648f1e2..aca816d33 100644
--- a/javax/swing/UIManager.java
+++ b/javax/swing/UIManager.java
@@ -146,19 +146,29 @@ public class UIManager implements Serializable
LookAndFeel laf = (LookAndFeel) lafClass.newInstance();
setLookAndFeel(laf);
}
+ else
+ {
+ setLookAndFeel(new MetalLookAndFeel());
+ }
}
catch (Exception ex)
{
System.err.println("cannot initialize Look and Feel: " + defaultlaf);
System.err.println("error: " + ex.getMessage());
System.err.println("falling back to Metal Look and Feel");
+ try
+ {
+ setLookAndFeel(new MetalLookAndFeel());
+ }
+ catch (Exception ex2)
+ {
+ throw (Error) new AssertionError("There must be no problem installing"
+ + " the MetalLookAndFeel.")
+ .initCause(ex2);
+ }
}
- currentLookAndFeel = new MetalLookAndFeel();
- currentLookAndFeel.initialize();
- currentUIDefaults = currentLookAndFeel.getDefaults();
-
}
-
+
/**
* Creates a new instance of the <code>UIManager</code>. There is no need
* to construct an instance of this class, since all methods are static.
diff --git a/javax/swing/ViewportLayout.java b/javax/swing/ViewportLayout.java
index fe7453fc6..884f7cb27 100644
--- a/javax/swing/ViewportLayout.java
+++ b/javax/swing/ViewportLayout.java
@@ -56,14 +56,17 @@ public class ViewportLayout implements LayoutManager, Serializable
public ViewportLayout()
{
+ // Nothing to do here.
}
public void addLayoutComponent(String name, Component c)
{
+ // Nothing to do here.
}
public void removeLayoutComponent(Component c)
{
+ // Nothing to do here.
}
public Dimension preferredLayoutSize(Container parent)
diff --git a/javax/swing/border/AbstractBorder.java b/javax/swing/border/AbstractBorder.java
index 951debd52..7cbbcdaa8 100644
--- a/javax/swing/border/AbstractBorder.java
+++ b/javax/swing/border/AbstractBorder.java
@@ -52,20 +52,18 @@ import java.io.Serializable;
* @author Sascha Brawer (brawer@dandelis.ch)
* @author Ronald Veldema (rveldema@cs.vu.nl)
*/
-public abstract class AbstractBorder
- implements Border, Serializable
+public abstract class AbstractBorder implements Border, Serializable
{
static final long serialVersionUID = -545885975315191844L;
-
/**
* Constructs a new AbstractBorder.
*/
- public AbstractBorder ()
+ public AbstractBorder()
{
+ // Nothing to do here.
}
-
/**
* Performs nothing, because the default implementation provided by
* this class is an invisible, zero-width border. Subclasses will
@@ -79,17 +77,15 @@ public abstract class AbstractBorder
* @param width the width of the available area for painting the border.
* @param height the height of the available area for painting the border.
*/
- public void paintBorder (Component c, Graphics g,
- int x, int y, int width, int height)
+ public void paintBorder(Component c, Graphics g, int x, int y, int width,
+ int height)
{
- /* A previous version of Classpath had emitted a warning when
- * this method was called. The warning was removed because it is
- * perfectly legal for a subclass to not override the paintBorder
- * method. An example would be EmptyBorder.
- */
+ // A previous version of Classpath had emitted a warning when
+ // this method was called. The warning was removed because it is
+ // perfectly legal for a subclass to not override the paintBorder
+ // method. An example would be EmptyBorder.
}
-
/**
* Measures the width of this border.
*
@@ -102,31 +98,29 @@ public abstract class AbstractBorder
*
* @see #getBorderInsets(java.awt.Component, java.awt.Insets)
*/
- public Insets getBorderInsets (Component c)
+ public Insets getBorderInsets(Component c)
{
- return new Insets (0, 0, 0, 0);
+ return new Insets(0, 0, 0, 0);
}
-
/**
* Determines the insets of this border. The implementation provided
* by AbstractButton sets the <code>left</code>, <code>right</code>,
* <code>top</code> and <code>bottom</code> fields of the passed
* <code>insets</code> parameter to zero.
*
- * @param c the component whose border is to be measured.
+ * @param c the component whose border is to be measured
*
- * @return the same object that was passed for <code>insets</code>.
+ * @return the same object that was passed for <code>insets</code>
*
* @see #getBorderInsets(Component)
*/
- public Insets getBorderInsets (Component c, Insets insets)
+ public Insets getBorderInsets(Component c, Insets insets)
{
insets.left = insets.right = insets.top = insets.bottom = 0;
return insets;
}
-
/**
* Determines whether or not this border is opaque. An opaque border
* fills every pixel in its area when painting. Partially
@@ -136,12 +130,11 @@ public abstract class AbstractBorder
*
* @return <code>false</code>.
*/
- public boolean isBorderOpaque ()
+ public boolean isBorderOpaque()
{
return false;
}
-
/**
* Returns a rectangle that covers the specified area minus this
* border. Components that wish to determine an area into which
@@ -154,12 +147,11 @@ public abstract class AbstractBorder
* @param width the width of the available area for the border.
* @param height the height of the available area for the border.
*/
- public Rectangle getInteriorRectangle (Component c,
- int x, int y, int width, int height)
+ public Rectangle getInteriorRectangle(Component c, int x, int y, int width,
+ int height)
{
return getInteriorRectangle (c, this, x, y, width, height);
}
-
/**
* Returns a rectangle that covers the specified area minus a
@@ -173,8 +165,8 @@ public abstract class AbstractBorder
* @param width the width of the available area for the border.
* @param height the height of the available area for the border.
*/
- public static Rectangle getInteriorRectangle (Component c, Border b,
- int x, int y, int width, int height)
+ public static Rectangle getInteriorRectangle(Component c, Border b, int x,
+ int y, int width, int height)
{
Insets borderInsets;
diff --git a/javax/swing/border/BevelBorder.java b/javax/swing/border/BevelBorder.java
index fcdc1c646..45b758cae 100644
--- a/javax/swing/border/BevelBorder.java
+++ b/javax/swing/border/BevelBorder.java
@@ -55,8 +55,7 @@ import java.awt.Insets;
*
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public class BevelBorder
- extends AbstractBorder
+public class BevelBorder extends AbstractBorder
{
/**
* Determined using the <code>serialver</code> tool
@@ -508,11 +507,11 @@ public class BevelBorder
* Paints a two-pixel bevel in four colors.
*
* <pre>
- * @@@@@@@@@@@@
- * @..........# @ = color a
- * @. X# . = color b
- * @. X# X = color c
- * @.XXXXXXXXX# # = color d
+ * ++++++++++++
+ * +..........# + = color a
+ * +. X# . = color b
+ * +. X# X = color c
+ * +.XXXXXXXXX# # = color d
* ############</pre>
*
* @param g the graphics for painting.
diff --git a/javax/swing/border/Border.java b/javax/swing/border/Border.java
index 11bddfe78..f4af3fb38 100644
--- a/javax/swing/border/Border.java
+++ b/javax/swing/border/Border.java
@@ -77,9 +77,8 @@ public interface Border
* @param width the width of the available area for painting the border.
* @param height the height of the available area for painting the border.
*/
- void paintBorder(Component c, Graphics g,
- int x, int y, int width, int height);
-
+ void paintBorder(Component c, Graphics g, int x, int y, int width,
+ int height);
/**
* Measures the width of this border.
@@ -92,7 +91,6 @@ public interface Border
*/
Insets getBorderInsets(Component c);
-
/**
* Determines whether this border fills every pixel in its area
* when painting.
diff --git a/javax/swing/border/CompoundBorder.java b/javax/swing/border/CompoundBorder.java
index 2130a0e34..998a9bab3 100644
--- a/javax/swing/border/CompoundBorder.java
+++ b/javax/swing/border/CompoundBorder.java
@@ -48,8 +48,7 @@ import java.awt.Insets;
*
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public class CompoundBorder
- extends AbstractBorder
+public class CompoundBorder extends AbstractBorder
{
/**
* Determined using the <code>serialver</code> tool
@@ -57,7 +56,6 @@ public class CompoundBorder
*/
static final long serialVersionUID = 9054540377030555103L;
-
/**
* The inside border, which is painted between the bordered
* Component and the outside border. It is valid for
@@ -65,7 +63,6 @@ public class CompoundBorder
*/
protected Border insideBorder;
-
/**
* The outside border, which is painted outside both the
* bordered Component and the inside border. It is valid for
@@ -73,7 +70,6 @@ public class CompoundBorder
*/
protected Border outsideBorder;
-
/**
* Constructs a CompoundBorder whose inside and outside borders
* are both <code>null</code>. While this does not really make
@@ -83,12 +79,11 @@ public class CompoundBorder
*
* @see EmptyBorder
*/
- public CompoundBorder ()
+ public CompoundBorder()
{
this (null, null);
}
-
/**
* Constructs a CompoundBorder with the specified inside and
* outside borders.
@@ -103,13 +98,12 @@ public class CompoundBorder
* component. It is acceptable to pass <code>null</code>, in
* which case no inside border is painted.
*/
- public CompoundBorder (Border outsideBorder, Border insideBorder)
+ public CompoundBorder(Border outsideBorder, Border insideBorder)
{
this.outsideBorder = outsideBorder;
this.insideBorder = insideBorder;
}
-
/**
* Determines whether or not this border is opaque. An opaque
* border fills every pixel in its area when painting. Partially
@@ -119,20 +113,18 @@ public class CompoundBorder
* @return <code>true</code> if both the inside and outside borders
* are opaque, or <code>false</code> otherwise.
*/
- public boolean isBorderOpaque ()
+ public boolean isBorderOpaque()
{
- /* While it would be safe to assume true for the opacity of
- * a null border, this behavior would not be according to
- * the API specification. Also, it is pathological to have
- * null borders anyway.
- */
+ // While it would be safe to assume true for the opacity of
+ // a null border, this behavior would not be according to
+ // the API specification. Also, it is pathological to have
+ // null borders anyway.
if ((insideBorder == null) || (outsideBorder == null))
return false;
return insideBorder.isBorderOpaque()
&& outsideBorder.isBorderOpaque();
}
-
/**
* Paints the compound border by first painting the outside border,
@@ -148,9 +140,9 @@ public class CompoundBorder
public void paintBorder(Component c, Graphics g,
int x, int y, int width, int height)
{
- /* If there is an outside border, paint it and reduce the
- * bounding box by its insets.
- */
+ // If there is an outside border, paint it and reduce the
+ // bounding box by its insets.
+ //
if (outsideBorder != null)
{
Insets outsideInsets;
@@ -161,9 +153,8 @@ public class CompoundBorder
x += outsideInsets.left;
y += outsideInsets.top;
- /* Reduce width and height by the respective extent of the
- * outside border.
- */
+ // Reduce width and height by the respective extent of the
+ // outside border.
width -= outsideInsets.left + outsideInsets.right;
height -= outsideInsets.top + outsideInsets.bottom;
}
@@ -172,7 +163,6 @@ public class CompoundBorder
insideBorder.paintBorder(c, g, x, y, width, height);
}
-
/**
* Changes the specified insets to the insets of this border,
* which is the sum of the insets of the inside and the outside
@@ -192,7 +182,7 @@ public class CompoundBorder
else
insets.left = insets.right = insets.top = insets.bottom = 0;
- /* If there is an outside border, add it to insets. */
+ // If there is an outside border, add it to insets.
if (outsideBorder != null)
{
borderInsets = outsideBorder.getBorderInsets(c);
@@ -202,7 +192,7 @@ public class CompoundBorder
insets.bottom += borderInsets.bottom;
}
- /* If there is an inside border, add it to insets. */
+ // If there is an inside border, add it to insets.
if (insideBorder != null)
{
borderInsets = insideBorder.getBorderInsets(c);
@@ -215,35 +205,31 @@ public class CompoundBorder
return insets;
}
-
/**
* Determines the insets of this border, which is the sum of the
* insets of the inside and the outside border.
*
* @param c the component in the center of this border.
*/
- public Insets getBorderInsets (Component c)
+ public Insets getBorderInsets(Component c)
{
- /* It is not clear why CompoundBorder does not simply inherit
- * the implementation from AbstractBorder. However, we want
- * to be compatible with the API specification, which overrides
- * the getBorderInsets(Component) method.
- */
+ // It is not clear why CompoundBorder does not simply inherit
+ // the implementation from AbstractBorder. However, we want
+ // to be compatible with the API specification, which overrides
+ // the getBorderInsets(Component) method.
return getBorderInsets (c, null);
}
-
/**
* Returns the outside border, which is painted outside both the
* bordered Component and the inside border. It is valid for the
* result to be <code>null</code>.
*/
- public Border getOutsideBorder ()
+ public Border getOutsideBorder()
{
return outsideBorder;
}
-
/**
* Returns the inside border, which is painted between the bordered
* Component and the outside border. It is valid for the result to
@@ -254,4 +240,3 @@ public class CompoundBorder
return insideBorder;
}
}
-
diff --git a/javax/swing/border/EmptyBorder.java b/javax/swing/border/EmptyBorder.java
index 0f3b7b693..c8e9c6044 100644
--- a/javax/swing/border/EmptyBorder.java
+++ b/javax/swing/border/EmptyBorder.java
@@ -53,8 +53,7 @@ import java.awt.Insets;
*
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public class EmptyBorder
- extends AbstractBorder
+public class EmptyBorder extends AbstractBorder
{
/**
* Determined using the <code>serialver</code> tool
@@ -142,6 +141,7 @@ public class EmptyBorder
public void paintBorder(Component c, Graphics g,
int x, int y, int width, int height)
{
+ // Nothing to do here.
}
diff --git a/javax/swing/border/EtchedBorder.java b/javax/swing/border/EtchedBorder.java
index 0bd76ff0f..22882b78c 100644
--- a/javax/swing/border/EtchedBorder.java
+++ b/javax/swing/border/EtchedBorder.java
@@ -56,8 +56,7 @@ import java.awt.Insets;
*
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public class EtchedBorder
- extends AbstractBorder
+public class EtchedBorder extends AbstractBorder
{
/**
* Determined using the <code>serialver</code> tool
@@ -199,8 +198,8 @@ public class EtchedBorder
* @param width the width of the available area for painting the border.
* @param height the height of the available area for painting the border.
*/
- public void paintBorder(Component c, Graphics g,
- int x, int y, int width, int height)
+ public void paintBorder(Component c, Graphics g, int x, int y, int width,
+ int height)
{
switch (etchType)
{
@@ -270,16 +269,14 @@ public class EtchedBorder
*/
public boolean isBorderOpaque()
{
- /* If the colors are to be drived from the enclosed Component's
- * background color, the border is guaranteed to be fully opaque
- * because Color.brighten() and Color.darken() always return an
- * opaque color.
- */
+ // If the colors are to be derived from the enclosed Component's
+ // background color, the border is guaranteed to be fully opaque
+ // because Color.brighten() and Color.darken() always return an
+ // opaque color.
return
((highlight == null) || (highlight.getAlpha() == 255))
&& ((shadow == null) || (shadow.getAlpha() == 255));
}
-
/**
* Returns the appearance of this EtchedBorder, which is either
@@ -310,8 +307,7 @@ public class EtchedBorder
else
return c.getBackground().brighter();
}
-
-
+
/**
* Returns the color that will be used for highlighted parts when
* painting the border, or <code>null</code> if that color will be
@@ -359,11 +355,11 @@ public class EtchedBorder
* Paints a two-pixel etching in two colors.
*
* <pre>
- * @@@@@@@@@@@.
- * @.........@. @ = color a
- * @. @. . = color b
- * @. @.
- * @@@@@@@@@@@.
+ * +++++++++++.
+ * +.........+. + = color a
+ * +. +. . = color b
+ * +. +.
+ * +++++++++++.
* ............</pre>
*
* @param g the graphics for painting.
@@ -374,9 +370,8 @@ public class EtchedBorder
* @param a one of the two colors.
* @param b the second of the two colors.
*/
- private static void paintEtchedBorder(Graphics g,
- int x, int y, int width, int height,
- Color a, Color b)
+ private static void paintEtchedBorder(Graphics g, int x, int y, int width,
+ int height, Color a, Color b)
{
Color oldColor;
@@ -387,11 +382,10 @@ public class EtchedBorder
try
{
- /* To understand this code, it might be helpful to look at the
- * images that are included with the JavaDoc. They are located
- * in the "doc-files" subdirectory. EtchedBorder-2.png might
- * be especially informative.
- */
+ // To understand this code, it might be helpful to look at the
+ // images that are included with the JavaDoc. They are located
+ // in the "doc-files" subdirectory. EtchedBorder-2.png might
+ // be especially informative.
g.setColor(a);
g.drawRect(0, 0, width - 1, height - 1);
@@ -408,4 +402,3 @@ public class EtchedBorder
}
}
}
-
diff --git a/javax/swing/border/LineBorder.java b/javax/swing/border/LineBorder.java
index c34e38c57..36abddd91 100644
--- a/javax/swing/border/LineBorder.java
+++ b/javax/swing/border/LineBorder.java
@@ -50,8 +50,7 @@ import java.awt.Insets;
*
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public class LineBorder
- extends AbstractBorder
+public class LineBorder extends AbstractBorder
{
/**
* Determined using the <code>serialver</code> tool
@@ -71,7 +70,7 @@ public class LineBorder
/**
* A shared instance of a gray, one pixel thick, plain LineBorder.
* The singleton object is lazily created by {@link
- * #createBlackGrayBorder()} upon its first invocation.
+ * #createGrayLineBorder()} upon its first invocation.
*/
private static LineBorder grayLineBorder;
@@ -213,29 +212,27 @@ public class LineBorder
{
g.setColor(lineColor);
- /* If width and height were not adjusted, the border would
- * appear one pixel too large in both directions.
- */
+ // If width and height were not adjusted, the border would
+ // appear one pixel too large in both directions.
width -= 1;
height -= 1;
- /* Blurred, too large appearance
- * -----------------------------
- * While Java 2D has introduced line strokes of arbitrary width,
- * it seems desirable to keep this code independent of Java 2D.
- * Therefore, multiple nested rectangles (or rounded rectangles)
- * are drawn in order to simulate a line whose thickness is
- * greater than one pixel.
- *
- * This hack causes a blurred appearance when anti-aliasing is
- * on. Interestingly enough, though, the Sun JDK 1.3.1 (at least
- * on MacOS X 10.1.5) shows exactly the same appearance under
- * this condition. It thus seems likely that Sun does the same
- * hack for simulating thick lines. For this reason, the
- * blurred appearance seems acceptable -- especially since GNU
- * Classpath tries to be compatible with the Sun reference
- * implementation.
- */
+ // Blurred, too large appearance
+ // -----------------------------
+ // While Java 2D has introduced line strokes of arbitrary width,
+ // it seems desirable to keep this code independent of Java 2D.
+ // Therefore, multiple nested rectangles (or rounded rectangles)
+ // are drawn in order to simulate a line whose thickness is
+ // greater than one pixel.
+ //
+ // This hack causes a blurred appearance when anti-aliasing is
+ // on. Interestingly enough, though, the Sun JDK 1.3.1 (at least
+ // on MacOS X 10.1.5) shows exactly the same appearance under
+ // this condition. It thus seems likely that Sun does the same
+ // hack for simulating thick lines. For this reason, the
+ // blurred appearance seems acceptable -- especially since GNU
+ // Classpath tries to be compatible with the Sun reference
+ // implementation.
for (int i = 0; i < thickness; i++)
{
if (roundedCorners)
@@ -340,4 +337,3 @@ public class LineBorder
return (!roundedCorners) && (lineColor.getAlpha() == 255);
}
}
-
diff --git a/javax/swing/border/MatteBorder.java b/javax/swing/border/MatteBorder.java
index f7ff1ca01..4d5b8c253 100644
--- a/javax/swing/border/MatteBorder.java
+++ b/javax/swing/border/MatteBorder.java
@@ -54,8 +54,7 @@ import javax.swing.Icon;
*
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public class MatteBorder
- extends EmptyBorder
+public class MatteBorder extends EmptyBorder
{
/**
* Determined using the <code>serialver</code> tool
@@ -401,4 +400,3 @@ public class MatteBorder
}
}
}
-
diff --git a/javax/swing/border/SoftBevelBorder.java b/javax/swing/border/SoftBevelBorder.java
index 379ecb65a..028fd00e0 100644
--- a/javax/swing/border/SoftBevelBorder.java
+++ b/javax/swing/border/SoftBevelBorder.java
@@ -55,8 +55,7 @@ import java.awt.Insets;
*
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public class SoftBevelBorder
- extends BevelBorder
+public class SoftBevelBorder extends BevelBorder
{
/**
* Determined using the <code>serialver</code> tool
@@ -264,10 +263,10 @@ public class SoftBevelBorder
* Paints a soft bevel in four colors.
*
* <pre>
- * @@@@@@@@@@@.
- * @@.........# @ = color a
- * @.. # . = color b
- * @. # X = color c
+ * +++++++++++.
+ * ++.........# + = color a
+ * +.. # . = color b
+ * +. # X = color c
* .. X# # = color d
* . ##########</pre>
*
@@ -326,4 +325,3 @@ public class SoftBevelBorder
}
}
}
-
diff --git a/javax/swing/border/TitledBorder.java b/javax/swing/border/TitledBorder.java
index 3ed60815a..8d3ee13d4 100644
--- a/javax/swing/border/TitledBorder.java
+++ b/javax/swing/border/TitledBorder.java
@@ -1,5 +1,5 @@
/* TitledBorder.java --
- Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -58,8 +58,7 @@ import javax.swing.UIManager;
*
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public class TitledBorder
- extends AbstractBorder
+public class TitledBorder extends AbstractBorder
{
/**
* A value for the <code>titlePosition</code> property that vertically
@@ -304,7 +303,7 @@ public class TitledBorder
public TitledBorder(String title)
{
this(/* border */ null,
- title, DEFAULT_JUSTIFICATION, DEFAULT_POSITION,
+ title, LEADING, TOP,
/* titleFont */ null, /* titleColor */ null);
}
@@ -317,7 +316,7 @@ public class TitledBorder
*/
public TitledBorder(Border border)
{
- this(border, /* title */ "", DEFAULT_JUSTIFICATION, DEFAULT_POSITION,
+ this(border, /* title */ "", LEADING, TOP,
/* titleFont */ null, /* titleColor */ null);
}
@@ -333,7 +332,7 @@ public class TitledBorder
*/
public TitledBorder(Border border, String title)
{
- this(border, title, DEFAULT_JUSTIFICATION, DEFAULT_POSITION,
+ this(border, title, LEADING, TOP,
/* titleFont */ null, /* titleColor */ null);
}
@@ -507,7 +506,7 @@ public class TitledBorder
public void paint(Graphics g)
{
if (b != null)
- b.paintBorder(c, g, x, y, width - 1, height - 1);
+ b.paintBorder(c, g, x, y, width, height);
}
@@ -565,7 +564,7 @@ public class TitledBorder
if (stripeHeight > 0)
{
paint(g, x, holeY, holeX - x, stripeHeight); // patches #2 and #3
- paint(g, holeX + holeWidth, holeY, width - (holeX + holeWidth), stripeHeight);
+ paint(g, holeX + holeWidth, holeY, x + width - (holeX + holeWidth), stripeHeight);
}
stripeHeight = height - (holeY - y + holeHeight);
@@ -577,16 +576,16 @@ public class TitledBorder
BorderPainter bp;
int textX, textY, borderWidth, borderHeight;
- borderWidth = width - (mes.borderSpacing.left + mes.borderSpacing.right);
- borderHeight = height - (mes.borderSpacing.top + mes.borderSpacing.bottom);
+ borderWidth = width - (mes.outerSpacing.left + mes.outerSpacing.right);
+ borderHeight = height - (mes.outerSpacing.top + mes.outerSpacing.bottom);
bp = new BorderPainter(c, getBorder(),
- x + mes.borderSpacing.left, y + mes.borderSpacing.top,
+ x + mes.outerSpacing.left, y + mes.outerSpacing.top,
borderWidth, borderHeight);
switch (getRealTitleJustification(c))
{
case LEFT:
- textX = x + TEXT_INSET_H;
+ textX = x + EDGE_SPACING + TEXT_INSET_H;
break;
case CENTER:
@@ -604,22 +603,22 @@ public class TitledBorder
switch (titlePosition)
{
case ABOVE_TOP:
- textY = y;
+ textY = y + EDGE_SPACING;
break;
case TOP:
case DEFAULT_POSITION:
default:
- textY = y + mes.borderSpacing.top + mes.borderInsets.top - mes.textAscent
+ textY = y + mes.outerSpacing.top + mes.borderInsets.top - mes.textAscent
+ mes.lineHeight;
break;
case BELOW_TOP:
- textY = y + mes.borderSpacing.top + mes.borderInsets.top + TEXT_SPACING;
+ textY = y + mes.outerSpacing.top + mes.borderInsets.top + TEXT_SPACING;
break;
case ABOVE_BOTTOM:
- textY = y + height - mes.borderSpacing.bottom - mes.borderInsets.bottom
+ textY = y + height - mes.outerSpacing.bottom - mes.borderInsets.bottom
- TEXT_SPACING - (mes.textAscent + mes.textDescent);
break;
@@ -644,8 +643,8 @@ public class TitledBorder
g.setFont(oldFont);
g.setColor(oldColor);
}
- bp.paintExcept(g, textX - 2, textY,
- mes.textWidth + 2, mes.textAscent + mes.textDescent);
+ bp.paintExcept(g, textX, textY,
+ mes.textWidth, mes.textAscent + mes.textDescent);
}
}
@@ -1002,49 +1001,63 @@ public class TitledBorder
m.trimmedText = null;
}
- m.textAscent = fmet.getAscent();
- m.textDescent = fmet.getDescent();
-
- FontRenderContext frc = new FontRenderContext(new AffineTransform(), false,
- false);
- LineMetrics lmet = m.font.getLineMetrics(m.trimmedText, 0,
- m.trimmedText.length(), frc);
- m.lineHeight = (int) lmet.getStrikethroughOffset();
- // Fallback in case that LineMetrics is not available/working.
- if (m.lineHeight == 0)
- m.lineHeight = (int) (0.3333 * (double) m.textAscent);
-
if (m.trimmedText != null)
- m.textWidth = fmet.stringWidth(m.trimmedText) + 3;
+ {
+ m.textAscent = fmet.getAscent();
+ m.textDescent = fmet.getDescent() + fmet.getLeading();
+
+ FontRenderContext frc = new FontRenderContext(new AffineTransform(),
+ false, false);
+ LineMetrics lmet = m.font.getLineMetrics(m.trimmedText, 0,
+ m.trimmedText.length(), frc);
+ m.lineHeight = (int) lmet.getStrikethroughOffset();
+
+ // Fallback in case that LineMetrics is not available/working.
+ if (m.lineHeight == 0)
+ m.lineHeight = (int) (0.3333 * (double) m.textAscent);
+ m.textWidth = fmet.stringWidth(m.trimmedText) + 3;
+ }
+ else
+ {
+ m.textAscent = 0;
+ m.textDescent = 0;
+ }
- m.edgeSpacing = new Insets(EDGE_SPACING, EDGE_SPACING, EDGE_SPACING, EDGE_SPACING);
- m.borderSpacing = new Insets(0, 0, 0, 0);
+ m.innerSpacing = new Insets(EDGE_SPACING, EDGE_SPACING, EDGE_SPACING,
+ EDGE_SPACING);
+ m.outerSpacing = new Insets(EDGE_SPACING, EDGE_SPACING, EDGE_SPACING,
+ EDGE_SPACING);
switch (titlePosition)
{
case ABOVE_TOP:
- m.borderSpacing.top += m.textAscent + m.textDescent + TEXT_SPACING;
+ m.outerSpacing.top += m.textAscent + m.textDescent + TEXT_SPACING;
break;
+ case TOP:
+ m.outerSpacing.top += m.textDescent + m.lineHeight;
+ m.innerSpacing.top += m.textAscent - m.lineHeight;
+ break;
+
case BELOW_TOP:
- m.edgeSpacing.top += m.textAscent + m.textDescent + TEXT_SPACING;
+ m.innerSpacing.top += m.textAscent + m.textDescent + TEXT_SPACING;
break;
case ABOVE_BOTTOM:
- m.edgeSpacing.bottom += m.textAscent + m.textDescent + TEXT_SPACING;
+ m.innerSpacing.bottom += m.textAscent + m.textDescent + TEXT_SPACING;
break;
case BOTTOM:
- m.edgeSpacing.bottom += Math.max(m.textAscent - m.borderInsets.bottom, 0);
- m.borderSpacing.bottom += m.textDescent;
+ m.innerSpacing.bottom += Math.max(m.textAscent - m.lineHeight, 0);
+ m.outerSpacing.bottom += m.textDescent + m.lineHeight;
break;
case BELOW_BOTTOM:
- m.borderSpacing.bottom += m.textAscent + m.textDescent + TEXT_SPACING;
+ m.outerSpacing.bottom += m.textAscent + m.textDescent;
break;
default:
- m.borderSpacing.top += m.textAscent;
+ m.outerSpacing.top += m.textAscent;
}
return m;
@@ -1067,7 +1080,7 @@ public class TitledBorder
* which means that the font is to be retrieved from the current
* LookAndFeel. In this case, this <code>font</code> field will
* contain the result of the retrieval. Therefore, it is safe
- * to assume that his <code>font</code> field will never have
+ * to assume that this <code>font</code> field will never have
* a <code>null</code> value.
*/
Font font;
@@ -1107,7 +1120,7 @@ public class TitledBorder
/**
- * The border that constitues the interior border
+ * The border that constitutes the interior border
* underneath the title text.
*/
Border border;
@@ -1116,8 +1129,7 @@ public class TitledBorder
/**
* The distance between the TitledBorder and the interior border.
*/
- Insets borderSpacing;
-
+ Insets outerSpacing;
/**
* The width of the interior border, as returned by
@@ -1130,7 +1142,7 @@ public class TitledBorder
* The distance between the interior border and the nested
* Component for which this TitledBorder is a border.
*/
- Insets edgeSpacing;
+ Insets innerSpacing;
/**
@@ -1149,10 +1161,10 @@ public class TitledBorder
{
if (i == null)
i = new Insets(0, 0, 0, 0);
- i.left = borderSpacing.left + borderInsets.left + edgeSpacing.left;
- i.right = borderSpacing.right + borderInsets.right + edgeSpacing.right;
- i.top = borderSpacing.top + borderInsets.top + edgeSpacing.top;
- i.bottom = borderSpacing.bottom + borderInsets.bottom + edgeSpacing.bottom;
+ i.left = outerSpacing.left + borderInsets.left + innerSpacing.left;
+ i.right = outerSpacing.right + borderInsets.right + innerSpacing.right;
+ i.top = outerSpacing.top + borderInsets.top + innerSpacing.top;
+ i.bottom = outerSpacing.bottom + borderInsets.bottom + innerSpacing.bottom;
return i;
}
@@ -1167,7 +1179,8 @@ public class TitledBorder
Insets insets;
insets = getContentInsets(null);
- width = Math.max(insets.left + insets.right, textWidth + 2 * TEXT_INSET_H);
+ width = Math.max(insets.left + insets.right, textWidth + 2
+ * TEXT_INSET_H);
return new Dimension(width, insets.top + insets.bottom);
}
}
diff --git a/javax/swing/colorchooser/AbstractColorChooserPanel.java b/javax/swing/colorchooser/AbstractColorChooserPanel.java
index d55346aaf..efb527725 100644
--- a/javax/swing/colorchooser/AbstractColorChooserPanel.java
+++ b/javax/swing/colorchooser/AbstractColorChooserPanel.java
@@ -1,5 +1,5 @@
/* AbstractColorChooserPanel.java --
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -64,7 +64,8 @@ public abstract class AbstractColorChooserPanel extends JPanel
*/
public AbstractColorChooserPanel()
{
- } // AbstractColorChooserPanel()
+ // Nothing to do here.
+ }
/**
* This method returns the name displayed in the tab for this chooser panel.
@@ -74,6 +75,36 @@ public abstract class AbstractColorChooserPanel extends JPanel
public abstract String getDisplayName();
/**
+ * Returns the key code for the mnemonic for this panel. This method returns
+ * zero to indicate no mnemonic, subclasses can override this.
+ *
+ * @return <code>0</code>, to indicate no mnemonic key code.
+ *
+ * @see #getDisplayedMnemonicIndex()
+ * @since 1.4
+ */
+ public int getMnemonic()
+ {
+ return 0;
+ }
+
+ /**
+ * Returns the index of the character in the display name that is the
+ * mnemonic. This method returns <code>-1</code> to indicate no mnemonic,
+ * subclasses can override.
+ *
+ * @return <code>-1</code>, to indicate no mnemonic.
+ *
+ * @see #getDisplayName()
+ * @see #getMnemonic()
+ * @since 1.4
+ */
+ public int getDisplayedMnemonicIndex()
+ {
+ return -1;
+ }
+
+ /**
* This method updates the chooser panel when the JColorChooser's color has
* changed.
*/
diff --git a/javax/swing/colorchooser/ColorChooserComponentFactory.java b/javax/swing/colorchooser/ColorChooserComponentFactory.java
index 77e319c70..923ea531f 100644
--- a/javax/swing/colorchooser/ColorChooserComponentFactory.java
+++ b/javax/swing/colorchooser/ColorChooserComponentFactory.java
@@ -53,7 +53,8 @@ public class ColorChooserComponentFactory
*/
private ColorChooserComponentFactory()
{
- } // ColorChooserComponentFactory()
+ // Nothing to do here.
+ }
/**
* This method returns the three default chooser panels to be used in
diff --git a/javax/swing/colorchooser/DefaultSwatchChooserPanel.java b/javax/swing/colorchooser/DefaultSwatchChooserPanel.java
index f28af4cac..ff3436808 100644
--- a/javax/swing/colorchooser/DefaultSwatchChooserPanel.java
+++ b/javax/swing/colorchooser/DefaultSwatchChooserPanel.java
@@ -587,6 +587,7 @@ class DefaultSwatchChooserPanel extends AbstractColorChooserPanel
*/
public void addLayoutComponent(String name, Component comp)
{
+ // Nothing to do here.
}
/**
@@ -634,6 +635,7 @@ class DefaultSwatchChooserPanel extends AbstractColorChooserPanel
*/
public void removeLayoutComponent(Component comp)
{
+ // Nothing to do here.
}
/**
@@ -786,6 +788,7 @@ class DefaultSwatchChooserPanel extends AbstractColorChooserPanel
*/
public void updateChooser()
{
+ // Nothing to do here yet.
}
/**
diff --git a/javax/swing/event/EventListenerList.java b/javax/swing/event/EventListenerList.java
index 7ed8582bd..fca248dfc 100644
--- a/javax/swing/event/EventListenerList.java
+++ b/javax/swing/event/EventListenerList.java
@@ -119,6 +119,7 @@ public class EventListenerList
*/
public EventListenerList()
{
+ // Nothing to do here.
}
diff --git a/javax/swing/event/InternalFrameAdapter.java b/javax/swing/event/InternalFrameAdapter.java
index a2878e76e..dfa88c3d4 100644
--- a/javax/swing/event/InternalFrameAdapter.java
+++ b/javax/swing/event/InternalFrameAdapter.java
@@ -39,75 +39,88 @@ exception statement from your version. */
package javax.swing.event;
/**
- * InternalFrameAdapter
+ * InternalFrameAdapter.
+ *
* @author Andrew Selkirk
*/
public abstract class InternalFrameAdapter implements InternalFrameListener
{
-
- //-------------------------------------------------------------
- // Initialization ---------------------------------------------
- //-------------------------------------------------------------
-
- /**
- * InternalFrameAdapter constructor
- */
- public InternalFrameAdapter() {
- } // InternalFrameAdapter()
-
-
- //-------------------------------------------------------------
- // Interface: InternalFrameListener ---------------------------
- //-------------------------------------------------------------
+ /**
+ * InternalFrameAdapter constructor.
+ */
+ public InternalFrameAdapter()
+ {
+ // Nothing to do here.
+ }
- /**
- * Internal frame activated
- * @param event Internal frame event
- */
- public void internalFrameActivated(InternalFrameEvent event) {
- } // internalFrameActivated()
-
- /**
- * Internal frame closed
- * @param event Internal frame event
- */
- public void internalFrameClosed(InternalFrameEvent event) {
- } // internalFrameClosed()
-
- /**
- * Internal frame closing
- * @param event Internal frame event
- */
- public void internalFrameClosing(InternalFrameEvent event) {
- } // internalFrameClosing()
-
- /**
- * Internal frame deactivated
- * @param event Internal frame event
- */
- public void internalFrameDeactivated(InternalFrameEvent event) {
- } // internalFrameDeactivated()
-
- /**
- * Internal frame deiconified
- * @param event Internal frame event
- */
- public void internalFrameDeiconified(InternalFrameEvent event) {
- } // internalFrameDeiconified()
-
- /**
- * Internal frame iconified
- * @param event Internal frame event
- */
- public void internalFrameIconified(InternalFrameEvent event) {
- } // internalFrameIconified()
-
- /**
- * Internal frame opened
- * @param event Internal frame event
- */
- public void internalFrameOpened(InternalFrameEvent event) {
- } // internalFrameOpened()
-
-
-} // InternalFrameAdapter
+ /**
+ * Internal frame activated.
+ *
+ * @param event internal frame event
+ */
+ public void internalFrameActivated(InternalFrameEvent event)
+ {
+ // Nothing to do here.
+ }
+
+ /**
+ * Internal frame closed.
+ *
+ * @param event internal frame event
+ */
+ public void internalFrameClosed(InternalFrameEvent event)
+ {
+ // Nothing to do here.
+ }
+
+ /**
+ * Internal frame closing.
+ *
+ * @param event internal frame event
+ */
+ public void internalFrameClosing(InternalFrameEvent event)
+ {
+ // Nothing to do here.
+ }
+
+ /**
+ * Internal frame deactivated.
+ *
+ * @param event internal frame event
+ */
+ public void internalFrameDeactivated(InternalFrameEvent event)
+ {
+ // Nothing to do here.
+ }
+
+ /**
+ * Internal frame deiconified.
+ *
+ * @param event internal frame event
+ */
+ public void internalFrameDeiconified(InternalFrameEvent event)
+ {
+ // Nothing to do here.
+ }
+
+ /**
+ * Internal frame iconified.
+ *
+ * @param event internal frame event
+ */
+ public void internalFrameIconified(InternalFrameEvent event)
+ {
+ // Nothing to do here.
+ }
+
+ /**
+ * Internal frame opened.
+ *
+ * @param event internal frame event
+ */
+ public void internalFrameOpened(InternalFrameEvent event)
+ {
+ // Nothing to do here.
+ }
+
+}
diff --git a/javax/swing/event/ListDataListener.java b/javax/swing/event/ListDataListener.java
index 7ce17d86f..f42777d09 100644
--- a/javax/swing/event/ListDataListener.java
+++ b/javax/swing/event/ListDataListener.java
@@ -1,5 +1,5 @@
/* ListDataListener.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,33 +37,46 @@ exception statement from your version. */
package javax.swing.event;
-// Imports
import java.util.EventListener;
+import javax.swing.ListModel;
+
/**
- * ListDataListener public interface
+ * A <code>ListDataListener</code> can register with a {@link ListModel} and
+ * receive notification of updates to the model.
+ *
* @author Andrew Selkirk
* @author Ronald Veldema
*/
-public interface ListDataListener extends EventListener {
-
- /**
- * Contents Changed
- * @param event ListDataEvent Event
- */
- void contentsChanged(ListDataEvent event);
+public interface ListDataListener extends EventListener
+{
- /**
- * Interval Added
- * @param event ListDataEvent Event
- */
- void intervalAdded(ListDataEvent event);
+ /**
+ * Notifies the listener that the contents of the list have changed
+ * in some way. This method will be called if the change cannot be
+ * notified via the {@link #intervalAdded(ListDataEvent)} or the
+ * {@link #intervalRemoved(ListDataEvent)} methods.
+ *
+ * @param event the event.
+ */
+ void contentsChanged(ListDataEvent event);
- /**
- * Interval Removed
- * @param event ListDataEvent Event
- */
- void intervalRemoved(ListDataEvent event);
+ /**
+ * Notifies the listener that one or more items have been added to the
+ * list. The <code>event</code> argument can supply the indices for the
+ * range of items added.
+ *
+ * @param event the event.
+ */
+ void intervalAdded(ListDataEvent event);
+ /**
+ * Notifies the listener that one or more items have been removed from
+ * the list. The <code>event</code> argument can supply the indices for
+ * the range of items removed.
+ *
+ * @param event the event.
+ */
+ void intervalRemoved(ListDataEvent event);
-} // ListDataListener
+}
diff --git a/javax/swing/event/MouseInputListener.java b/javax/swing/event/MouseInputListener.java
index 3c3ca2347..3d879b9e7 100644
--- a/javax/swing/event/MouseInputListener.java
+++ b/javax/swing/event/MouseInputListener.java
@@ -37,16 +37,17 @@ exception statement from your version. */
package javax.swing.event;
-// Imports
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
/**
- * MouseInputListener public interface
+ * MouseInputListener public interface.
+ *
* @author Andrew Selkirk
*/
public interface MouseInputListener extends MouseListener,
- MouseMotionListener {
-
-} // MouseInputListener
-
+ MouseMotionListener
+{
+ // This interface only pulls together MouseListener and MouseMotionListener
+ // without adding any methods on its own.
+}
diff --git a/javax/swing/event/SwingPropertyChangeSupport.java b/javax/swing/event/SwingPropertyChangeSupport.java
index 408ca957e..7e8ff0dc2 100644
--- a/javax/swing/event/SwingPropertyChangeSupport.java
+++ b/javax/swing/event/SwingPropertyChangeSupport.java
@@ -289,10 +289,9 @@ public final class SwingPropertyChangeSupport
int index;
PropertyChangeListener listener;
- // Check Values if they are equal
- if (event.getOldValue() == null && event.getNewValue() == null ||
- (event.getOldValue() != null && event.getNewValue() != null &&
- event.getOldValue().equals(event.getNewValue())))
+ // if the old and new values are non-null and equal, don't notify listeners
+ if (event.getOldValue() != null && event.getNewValue() != null &&
+ event.getOldValue().equals(event.getNewValue()))
return;
// Process Main Listener List
diff --git a/javax/swing/filechooser/FileFilter.java b/javax/swing/filechooser/FileFilter.java
index 42770d981..ecfa54b58 100644
--- a/javax/swing/filechooser/FileFilter.java
+++ b/javax/swing/filechooser/FileFilter.java
@@ -1,5 +1,5 @@
/* FileFilter.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -40,41 +40,46 @@ package javax.swing.filechooser;
import java.io.File;
+import javax.swing.JFileChooser;
+
/**
- * FileFilter
+ * The base class for filters that control the visibility of files in the
+ * {@link JFileChooser} component.
+ *
+ * @see JFileChooser#addChoosableFileFilter(FileFilter)
+ *
* @author Andrew Selkirk
- * @version 1.0
*/
-public abstract class FileFilter {
-
- //-------------------------------------------------------------
- // Initialization ---------------------------------------------
- //-------------------------------------------------------------
-
- /**
- * Constructor FileFilter
- */
- public FileFilter() {
- // TODO
- } // FileFilter()
-
-
- //-------------------------------------------------------------
- // Methods ----------------------------------------------------
- //-------------------------------------------------------------
-
- /**
- * accept
- * @param file TODO
- * @returns boolean
- */
- public abstract boolean accept(File file);
-
- /**
- * getDescription
- * @returns String
- */
- public abstract String getDescription();
-
-
-} // FileFilter
+public abstract class FileFilter
+{
+
+ /**
+ * Default constructor.
+ */
+ public FileFilter()
+ {
+ // Nothing to do here.
+ }
+
+ /**
+ * Returns <code>true</code> if the specified file matches the filter, and
+ * <code>false</code> otherwise.
+ *
+ * @param file the file.
+ *
+ * @returns A boolean.
+ */
+ public abstract boolean accept(File file);
+
+ /**
+ * Returns a description of the files that will be selected by the filter
+ * (for example, "Java source files"). This description will usually be
+ * displayed on the {@link JFileChooser} component, often in a combo box that
+ * is used to select the appropriate filter (in cases where more than one
+ * filter is available).
+ *
+ * @returns A description of the filter.
+ */
+ public abstract String getDescription();
+
+}
diff --git a/javax/swing/filechooser/FileSystemView.java b/javax/swing/filechooser/FileSystemView.java
index 0c3dfbf6e..5867cdbe3 100644
--- a/javax/swing/filechooser/FileSystemView.java
+++ b/javax/swing/filechooser/FileSystemView.java
@@ -48,6 +48,9 @@ import javax.swing.Icon;
*/
public abstract class FileSystemView
{
+ /** The instance returned by {@link #getFileSystemView()}. */
+ private static FileSystemView defaultFileSystemView;
+
/**
* DOCUMENT ME!
*
@@ -148,20 +151,22 @@ public abstract class FileSystemView
}
/**
- * DOCUMENT ME!
+ * Returns a default {@link FileSystemView} appropriate for the platform.
*
- * @return DOCUMENT ME!
+ * @return A default {@link FileSystemView} appropriate for the platform.
*/
public static FileSystemView getFileSystemView()
{
- if (File.separator.equals("/"))
- return new UnixFileSystemView();
-
- // else if (File.Separator.equals("\"))
- // return new Win32FileSystemView();
- // else
- // return new GenericFileSystemView();
- return null;
+ if (defaultFileSystemView == null)
+ {
+ if (File.separator.equals("/"))
+ defaultFileSystemView = new UnixFileSystemView();
+ // else if (File.Separator.equals("\"))
+ // return new Win32FileSystemView();
+ // else
+ // return new GenericFileSystemView();
+ }
+ return defaultFileSystemView;
}
/**
diff --git a/javax/swing/filechooser/FileView.java b/javax/swing/filechooser/FileView.java
index f07114342..ea1989f93 100644
--- a/javax/swing/filechooser/FileView.java
+++ b/javax/swing/filechooser/FileView.java
@@ -56,6 +56,7 @@ public abstract class FileView
*/
public FileView()
{
+ // Nothing to do here.
}
/**
diff --git a/javax/swing/plaf/ActionMapUIResource.java b/javax/swing/plaf/ActionMapUIResource.java
index f6af0880d..07292fe24 100644
--- a/javax/swing/plaf/ActionMapUIResource.java
+++ b/javax/swing/plaf/ActionMapUIResource.java
@@ -50,9 +50,7 @@ import javax.swing.ActionMap;
* @author Andrew Selkirk
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public class ActionMapUIResource
- extends ActionMap
- implements UIResource
+public class ActionMapUIResource extends ActionMap implements UIResource
{
/**
* Constructs a new ActionMapUIResource.
diff --git a/javax/swing/plaf/BorderUIResource.java b/javax/swing/plaf/BorderUIResource.java
index 4402bbb48..317cb09ac 100644
--- a/javax/swing/plaf/BorderUIResource.java
+++ b/javax/swing/plaf/BorderUIResource.java
@@ -71,9 +71,7 @@ import javax.swing.border.TitledBorder;
* @author Brian Jones (cbj@gnu.org)
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public class BorderUIResource
- extends Object
- implements Border, UIResource, Serializable
+public class BorderUIResource implements Border, UIResource, Serializable
{
/**
* Verified using the <code>serialver</code> tool
diff --git a/javax/swing/plaf/ButtonUI.java b/javax/swing/plaf/ButtonUI.java
index 197299e0c..6910e4298 100644
--- a/javax/swing/plaf/ButtonUI.java
+++ b/javax/swing/plaf/ButtonUI.java
@@ -46,7 +46,7 @@ package javax.swing.plaf;
*
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public abstract class ButtonUI
- extends ComponentUI
+public abstract class ButtonUI extends ComponentUI
{
+ // This abstract class does not define any methods of its own.
}
diff --git a/javax/swing/plaf/ColorChooserUI.java b/javax/swing/plaf/ColorChooserUI.java
index 68ffd916d..16091416a 100644
--- a/javax/swing/plaf/ColorChooserUI.java
+++ b/javax/swing/plaf/ColorChooserUI.java
@@ -46,8 +46,7 @@ package javax.swing.plaf;
* @author Andrew Selkirk
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public abstract class ColorChooserUI
- extends ComponentUI
+public abstract class ColorChooserUI extends ComponentUI
{
/**
* Constructs a ColorChooserUI.
diff --git a/javax/swing/plaf/ColorUIResource.java b/javax/swing/plaf/ColorUIResource.java
index 33b1676e0..36e10f2d1 100644
--- a/javax/swing/plaf/ColorUIResource.java
+++ b/javax/swing/plaf/ColorUIResource.java
@@ -50,9 +50,7 @@ import java.awt.Color;
*
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public class ColorUIResource
- extends Color
- implements UIResource
+public class ColorUIResource extends Color implements UIResource
{
/**
* Constructs a <code>ColorUIResource</code> using the specified
diff --git a/javax/swing/plaf/ComboBoxUI.java b/javax/swing/plaf/ComboBoxUI.java
index 9498a4815..3e81ed75a 100644
--- a/javax/swing/plaf/ComboBoxUI.java
+++ b/javax/swing/plaf/ComboBoxUI.java
@@ -48,14 +48,14 @@ import javax.swing.JComboBox;
* @author Andrew Selkirk
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public abstract class ComboBoxUI
- extends ComponentUI
+public abstract class ComboBoxUI extends ComponentUI
{
/**
* Constructs a new <code>ComboBoxUI</code>.
*/
public ComboBoxUI()
{
+ // Nothing to do here.
}
diff --git a/javax/swing/plaf/ComponentInputMapUIResource.java b/javax/swing/plaf/ComponentInputMapUIResource.java
index e1418710f..cfc43e4fc 100644
--- a/javax/swing/plaf/ComponentInputMapUIResource.java
+++ b/javax/swing/plaf/ComponentInputMapUIResource.java
@@ -52,8 +52,7 @@ import javax.swing.JComponent;
* @author Andrew Selkirk
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public class ComponentInputMapUIResource
- extends ComponentInputMap
+public class ComponentInputMapUIResource extends ComponentInputMap
implements UIResource
{
/**
diff --git a/javax/swing/plaf/ComponentUI.java b/javax/swing/plaf/ComponentUI.java
index 0e7680542..ced3904c7 100644
--- a/javax/swing/plaf/ComponentUI.java
+++ b/javax/swing/plaf/ComponentUI.java
@@ -40,6 +40,7 @@ package javax.swing.plaf;
import java.awt.Dimension;
import java.awt.Graphics;
+import java.awt.Rectangle;
import javax.accessibility.Accessible;
import javax.swing.JComponent;
@@ -86,6 +87,7 @@ public abstract class ComponentUI
*/
public ComponentUI()
{
+ // Nothing to do here.
}
@@ -157,6 +159,8 @@ public abstract class ComponentUI
*/
public void paint(Graphics g, JComponent c)
{
+ // Nothing is done here. This method is meant to be overridden by
+ // subclasses.
}
@@ -182,12 +186,12 @@ public abstract class ComponentUI
if (c.isOpaque())
{
g.setColor(c.getBackground());
+ Rectangle clip = g.getClipBounds();
g.fillRect(0, 0, c.getWidth(), c.getHeight());
}
paint(g, c);
}
-
-
+
/**
* Determines the preferred size of a component. The default
* implementation returns <code>null</code>, which means that
diff --git a/javax/swing/plaf/DesktopIconUI.java b/javax/swing/plaf/DesktopIconUI.java
index 2e44088ca..676233ec2 100644
--- a/javax/swing/plaf/DesktopIconUI.java
+++ b/javax/swing/plaf/DesktopIconUI.java
@@ -44,13 +44,13 @@ package javax.swing.plaf;
* @author Andrew Selkirk (aselkirk@sympatico.ca)
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public abstract class DesktopIconUI
- extends ComponentUI
+public abstract class DesktopIconUI extends ComponentUI
{
/**
* Constructs a new <code>DesktopIconUI</code>.
*/
public DesktopIconUI()
{
+ // Nothing to do here.
}
}
diff --git a/javax/swing/plaf/DesktopPaneUI.java b/javax/swing/plaf/DesktopPaneUI.java
index de553eaf4..3d4cfc830 100644
--- a/javax/swing/plaf/DesktopPaneUI.java
+++ b/javax/swing/plaf/DesktopPaneUI.java
@@ -46,14 +46,13 @@ package javax.swing.plaf;
* @author Andrew Selkirk (aselkirk@sympatico.ca)
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public abstract class DesktopPaneUI
- extends ComponentUI
+public abstract class DesktopPaneUI extends ComponentUI
{
/**
* Constructs a new <code>DesktopPaneUI</code>.
*/
public DesktopPaneUI()
{
+ // Nothing to do here.
}
}
-
diff --git a/javax/swing/plaf/DimensionUIResource.java b/javax/swing/plaf/DimensionUIResource.java
index 63c6838c4..618c22036 100644
--- a/javax/swing/plaf/DimensionUIResource.java
+++ b/javax/swing/plaf/DimensionUIResource.java
@@ -51,9 +51,7 @@ import java.awt.Dimension;
* @author Andrew Selkirk (aselkirk@sympatico.ca)
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public class DimensionUIResource
- extends Dimension
- implements UIResource
+public class DimensionUIResource extends Dimension implements UIResource
{
/**
* Constructs a new DimensionUIResource, given its width and height.
diff --git a/javax/swing/plaf/FileChooserUI.java b/javax/swing/plaf/FileChooserUI.java
index 8b661e399..e9be8f2ba 100644
--- a/javax/swing/plaf/FileChooserUI.java
+++ b/javax/swing/plaf/FileChooserUI.java
@@ -53,14 +53,14 @@ import javax.swing.filechooser.FileView;
* @author Andrew Selkirk (aselkirk@sympatico.ca)
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public abstract class FileChooserUI
- extends ComponentUI
+public abstract class FileChooserUI extends ComponentUI
{
/**
* Constructs a new <code>FileChooserUI</code>.
*/
public FileChooserUI()
{
+ // Nothing to do here.
}
diff --git a/javax/swing/plaf/FontUIResource.java b/javax/swing/plaf/FontUIResource.java
index 1c1731048..c54f987fd 100644
--- a/javax/swing/plaf/FontUIResource.java
+++ b/javax/swing/plaf/FontUIResource.java
@@ -50,9 +50,7 @@ import java.awt.Font;
* @author Andrew Selkirk (aselkirk@sympatico.ca)
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public class FontUIResource
- extends Font
- implements UIResource
+public class FontUIResource extends Font implements UIResource
{
/**
* Constructs a new <code>FontUIResource</code> given
diff --git a/javax/swing/plaf/IconUIResource.java b/javax/swing/plaf/IconUIResource.java
index 1b09ed31f..659c8e7ba 100644
--- a/javax/swing/plaf/IconUIResource.java
+++ b/javax/swing/plaf/IconUIResource.java
@@ -53,8 +53,7 @@ import javax.swing.Icon;
* @author Andrew Selkirk (aselkirk@sympatico.ca)
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public class IconUIResource
- implements Icon, UIResource, Serializable
+public class IconUIResource implements Icon, UIResource, Serializable
{
/**
* Verified using the <code>serialver</code> tool of Sun JDK 1.4.1_01
diff --git a/javax/swing/plaf/InputMapUIResource.java b/javax/swing/plaf/InputMapUIResource.java
index ae032e51f..0c5f6f9e9 100644
--- a/javax/swing/plaf/InputMapUIResource.java
+++ b/javax/swing/plaf/InputMapUIResource.java
@@ -49,15 +49,13 @@ import javax.swing.InputMap;
* @author Andrew Selkirk (aselkirk@sympatico.ca)
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public class InputMapUIResource
- extends InputMap
- implements UIResource
+public class InputMapUIResource extends InputMap implements UIResource
{
/**
* Constructs a new <code>InputMapUIResource</code>.
*/
public InputMapUIResource()
{
+ // Nothing to do here.
}
}
-
diff --git a/javax/swing/plaf/InsetsUIResource.java b/javax/swing/plaf/InsetsUIResource.java
index 755d8add1..d64feb44c 100644
--- a/javax/swing/plaf/InsetsUIResource.java
+++ b/javax/swing/plaf/InsetsUIResource.java
@@ -50,8 +50,7 @@ import java.io.Serializable;
* @author Andrew Selkirk (aselkirk@sympatico.ca)
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public class InsetsUIResource
- extends Insets
+public class InsetsUIResource extends Insets
implements Cloneable, UIResource, Serializable
{
/**
diff --git a/javax/swing/plaf/InternalFrameUI.java b/javax/swing/plaf/InternalFrameUI.java
index fd1e3374c..0b2f77caa 100644
--- a/javax/swing/plaf/InternalFrameUI.java
+++ b/javax/swing/plaf/InternalFrameUI.java
@@ -47,13 +47,13 @@ package javax.swing.plaf;
* @author Andrew Selkirk (aselkirk@sympatico.ca)
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public abstract class InternalFrameUI
- extends ComponentUI
+public abstract class InternalFrameUI extends ComponentUI
{
/**
* Constructs a new <code>InternalFrameUI</code>.
*/
public InternalFrameUI()
{
+ // Nothing to do here.
}
}
diff --git a/javax/swing/plaf/LabelUI.java b/javax/swing/plaf/LabelUI.java
index 8fc1d711b..f4b74d59e 100644
--- a/javax/swing/plaf/LabelUI.java
+++ b/javax/swing/plaf/LabelUI.java
@@ -47,13 +47,13 @@ package javax.swing.plaf;
* @author Andrew Selkirk (aselkirk@sympatico.ca)
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public abstract class LabelUI
- extends ComponentUI
+public abstract class LabelUI extends ComponentUI
{
/**
* Constructs a new <code>LabelUI</code>.
*/
public LabelUI()
{
+ // Nothing to do here.
}
}
diff --git a/javax/swing/plaf/ListUI.java b/javax/swing/plaf/ListUI.java
index 66d5cf588..bdfe4b307 100644
--- a/javax/swing/plaf/ListUI.java
+++ b/javax/swing/plaf/ListUI.java
@@ -49,14 +49,14 @@ import javax.swing.JList;
*
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public abstract class ListUI
- extends ComponentUI
+public abstract class ListUI extends ComponentUI
{
/**
* Constructs a new <code>ListUI</code>.
*/
public ListUI()
{
+ // Nothing to do here.
}
diff --git a/javax/swing/plaf/MenuBarUI.java b/javax/swing/plaf/MenuBarUI.java
index 8835571ac..2c82adfa0 100644
--- a/javax/swing/plaf/MenuBarUI.java
+++ b/javax/swing/plaf/MenuBarUI.java
@@ -47,13 +47,13 @@ package javax.swing.plaf;
* @author Andrew Selkirk (aselkirk@sympatico.ca)
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public abstract class MenuBarUI
- extends ComponentUI
+public abstract class MenuBarUI extends ComponentUI
{
/**
* Constructs a new <code>MenuBarUI</code>.
*/
public MenuBarUI()
{
+ // Nothing to do here.
}
}
diff --git a/javax/swing/plaf/MenuItemUI.java b/javax/swing/plaf/MenuItemUI.java
index 31d73194a..83ad52fb1 100644
--- a/javax/swing/plaf/MenuItemUI.java
+++ b/javax/swing/plaf/MenuItemUI.java
@@ -47,13 +47,13 @@ package javax.swing.plaf;
* @author Andrew Selkirk (aselkirk@sympatico.ca)
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public abstract class MenuItemUI
- extends ButtonUI
+public abstract class MenuItemUI extends ButtonUI
{
/**
* Constructs a new <code>MenuItemUI</code>.
*/
public MenuItemUI()
{
+ // Nothing to do here.
}
}
diff --git a/javax/swing/plaf/PanelUI.java b/javax/swing/plaf/PanelUI.java
index b1171b80d..12a6f52cf 100644
--- a/javax/swing/plaf/PanelUI.java
+++ b/javax/swing/plaf/PanelUI.java
@@ -46,13 +46,13 @@ package javax.swing.plaf;
*
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public abstract class PanelUI
- extends ComponentUI
+public abstract class PanelUI extends ComponentUI
{
/**
* Constructs a new <code>PanelUI</code>.
*/
public PanelUI()
{
+ // Nothing to do here.
}
}
diff --git a/javax/swing/plaf/PopupMenuUI.java b/javax/swing/plaf/PopupMenuUI.java
index c70ad2a4e..de351f2ef 100644
--- a/javax/swing/plaf/PopupMenuUI.java
+++ b/javax/swing/plaf/PopupMenuUI.java
@@ -53,14 +53,14 @@ import javax.swing.PopupFactory;
* @author Andrew Selkirk (aselkirk@sympatico.ca)
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public abstract class PopupMenuUI
- extends ComponentUI
+public abstract class PopupMenuUI extends ComponentUI
{
/**
* Constructs a new <code>PopupMenuUI</code>.
*/
public PopupMenuUI()
{
+ // Nothing to do here.
}
diff --git a/javax/swing/plaf/ProgressBarUI.java b/javax/swing/plaf/ProgressBarUI.java
index 79c1b95a3..013b8c5c2 100644
--- a/javax/swing/plaf/ProgressBarUI.java
+++ b/javax/swing/plaf/ProgressBarUI.java
@@ -47,13 +47,13 @@ package javax.swing.plaf;
* @author Andrew Selkirk (aselkirk@sympatico.ca)
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public abstract class ProgressBarUI
- extends ComponentUI
+public abstract class ProgressBarUI extends ComponentUI
{
/**
* Constructs a new <code>ProgressBarUI</code>.
*/
public ProgressBarUI()
{
+ // Nothing to do here.
}
}
diff --git a/javax/swing/plaf/RootPaneUI.java b/javax/swing/plaf/RootPaneUI.java
index ff7d0a6e7..9637c9cf2 100644
--- a/javax/swing/plaf/RootPaneUI.java
+++ b/javax/swing/plaf/RootPaneUI.java
@@ -46,13 +46,13 @@ package javax.swing.plaf;
* @author Andrew Selkirk (aselkirk@sympatico.ca)
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public abstract class RootPaneUI
- extends ComponentUI
+public abstract class RootPaneUI extends ComponentUI
{
/**
* Constructs a new <code>RootPaneUI</code>.
*/
public RootPaneUI()
{
+ // Nothing to do here.
}
}
diff --git a/javax/swing/plaf/ScrollBarUI.java b/javax/swing/plaf/ScrollBarUI.java
index 3cad39327..51b4bf2d8 100644
--- a/javax/swing/plaf/ScrollBarUI.java
+++ b/javax/swing/plaf/ScrollBarUI.java
@@ -46,13 +46,13 @@ package javax.swing.plaf;
* @author Andrew Selkirk (aselkirk@sympatico.ca)
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public abstract class ScrollBarUI
- extends ComponentUI
+public abstract class ScrollBarUI extends ComponentUI
{
/**
* Constructs a new <code>ScrollBarUI</code>.
*/
public ScrollBarUI()
{
+ // Nothing to do here.
}
}
diff --git a/javax/swing/plaf/ScrollPaneUI.java b/javax/swing/plaf/ScrollPaneUI.java
index 14d2ac61e..8b37fed22 100644
--- a/javax/swing/plaf/ScrollPaneUI.java
+++ b/javax/swing/plaf/ScrollPaneUI.java
@@ -47,13 +47,13 @@ package javax.swing.plaf;
* @author Andrew Selkirk (aselkirk@sympatico.ca)
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public abstract class ScrollPaneUI
- extends ComponentUI
+public abstract class ScrollPaneUI extends ComponentUI
{
/**
* Constructs a new <code>ScrollPaneUI</code>.
*/
public ScrollPaneUI()
{
+ // Nothing to do here.
}
}
diff --git a/javax/swing/plaf/SeparatorUI.java b/javax/swing/plaf/SeparatorUI.java
index 6855bd035..8a9f8cf4d 100644
--- a/javax/swing/plaf/SeparatorUI.java
+++ b/javax/swing/plaf/SeparatorUI.java
@@ -54,5 +54,6 @@ public abstract class SeparatorUI
*/
public SeparatorUI()
{
+ // Nothing to do here.
}
}
diff --git a/javax/swing/plaf/SliderUI.java b/javax/swing/plaf/SliderUI.java
index 775f19620..570e962aa 100644
--- a/javax/swing/plaf/SliderUI.java
+++ b/javax/swing/plaf/SliderUI.java
@@ -47,13 +47,13 @@ package javax.swing.plaf;
* @author Andrew Selkirk (aselkirk@sympatico.ca)
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public abstract class SliderUI
- extends ComponentUI
+public abstract class SliderUI extends ComponentUI
{
/**
* Constructs a new <code>SliderUI</code>.
*/
public SliderUI()
{
+ // Nothing to do here.
}
}
diff --git a/javax/swing/plaf/SpinnerUI.java b/javax/swing/plaf/SpinnerUI.java
index fb4a3b13a..ca29ddb8e 100644
--- a/javax/swing/plaf/SpinnerUI.java
+++ b/javax/swing/plaf/SpinnerUI.java
@@ -47,13 +47,13 @@ package javax.swing.plaf;
*
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public abstract class SpinnerUI
- extends ComponentUI
+public abstract class SpinnerUI extends ComponentUI
{
/**
* Constructs a new <code>SpinnerUI</code>.
*/
public SpinnerUI()
{
+ // Nothing to do here.
}
}
diff --git a/javax/swing/plaf/SplitPaneUI.java b/javax/swing/plaf/SplitPaneUI.java
index ea9af2b17..59ededf58 100644
--- a/javax/swing/plaf/SplitPaneUI.java
+++ b/javax/swing/plaf/SplitPaneUI.java
@@ -51,14 +51,14 @@ import javax.swing.JSplitPane;
* @author Andrew Selkirk (aselkirk@sympatico.ca)
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public abstract class SplitPaneUI
- extends ComponentUI
+public abstract class SplitPaneUI extends ComponentUI
{
/**
* Constructs a new <code>SplitPaneUI</code>.
*/
public SplitPaneUI()
{
+ // Nothing to do here.
}
diff --git a/javax/swing/plaf/TabbedPaneUI.java b/javax/swing/plaf/TabbedPaneUI.java
index 6ab823b50..01a772014 100644
--- a/javax/swing/plaf/TabbedPaneUI.java
+++ b/javax/swing/plaf/TabbedPaneUI.java
@@ -51,14 +51,14 @@ import javax.swing.JTabbedPane;
* @author Andrew Selkirk (aselkirk@sympatico.ca)
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public abstract class TabbedPaneUI
- extends ComponentUI
+public abstract class TabbedPaneUI extends ComponentUI
{
/**
* Constructs a new <code>TabbedPaneUI</code>.
*/
public TabbedPaneUI()
{
+ // Nothing to do here.
}
diff --git a/javax/swing/plaf/TableHeaderUI.java b/javax/swing/plaf/TableHeaderUI.java
index f23ca74d7..34ac0e0fc 100644
--- a/javax/swing/plaf/TableHeaderUI.java
+++ b/javax/swing/plaf/TableHeaderUI.java
@@ -47,13 +47,13 @@ package javax.swing.plaf;
* @author Andrew Selkirk (aselkirk@sympatico.ca)
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public abstract class TableHeaderUI
- extends ComponentUI
+public abstract class TableHeaderUI extends ComponentUI
{
/**
* Constructs a new <code>TableHeaderUI</code>.
*/
public TableHeaderUI()
{
+ // Nothing to do here.
}
}
diff --git a/javax/swing/plaf/TableUI.java b/javax/swing/plaf/TableUI.java
index e56bcd131..a8c6bf909 100644
--- a/javax/swing/plaf/TableUI.java
+++ b/javax/swing/plaf/TableUI.java
@@ -47,13 +47,13 @@ package javax.swing.plaf;
* @author Andrew Selkirk (aselkirk@sympatico.ca)
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public abstract class TableUI
- extends ComponentUI
+public abstract class TableUI extends ComponentUI
{
/**
* Constructs a new <code>TableUI</code>.
*/
public TableUI()
{
+ // Nothing to do here.
}
}
diff --git a/javax/swing/plaf/TextUI.java b/javax/swing/plaf/TextUI.java
index dcabdfcdb..9f2737cc2 100644
--- a/javax/swing/plaf/TextUI.java
+++ b/javax/swing/plaf/TextUI.java
@@ -57,14 +57,14 @@ import javax.swing.text.View;
* @author Ronald Veldema (rveldema@cs.vu.nl)
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public abstract class TextUI
- extends ComponentUI
+public abstract class TextUI extends ComponentUI
{
/**
* Constructs a new <code>TextUI</code>.
*/
public TextUI()
{
+ // Nothing to do here.
}
diff --git a/javax/swing/plaf/ToolBarUI.java b/javax/swing/plaf/ToolBarUI.java
index 730cf4887..9a26e7b59 100644
--- a/javax/swing/plaf/ToolBarUI.java
+++ b/javax/swing/plaf/ToolBarUI.java
@@ -47,13 +47,13 @@ package javax.swing.plaf;
* @author Andrew Selkirk (aselkirk@sympatico.ca)
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public abstract class ToolBarUI
- extends ComponentUI
+public abstract class ToolBarUI extends ComponentUI
{
/**
* Constructs a new <code>ToolBarUI</code>.
*/
public ToolBarUI()
{
+ // Nothing to do here.
}
}
diff --git a/javax/swing/plaf/ToolTipUI.java b/javax/swing/plaf/ToolTipUI.java
index 4383d0edd..ae2d465e5 100644
--- a/javax/swing/plaf/ToolTipUI.java
+++ b/javax/swing/plaf/ToolTipUI.java
@@ -47,13 +47,13 @@ package javax.swing.plaf;
* @author Andrew Selkirk (aselkirk@sympatico.ca)
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public abstract class ToolTipUI
- extends ComponentUI
+public abstract class ToolTipUI extends ComponentUI
{
/**
* Constructs a new <code>ToolTipUI</code>.
*/
public ToolTipUI()
{
+ // Nothing to do here.
}
}
diff --git a/javax/swing/plaf/TreeUI.java b/javax/swing/plaf/TreeUI.java
index e32952de7..308ec63e2 100644
--- a/javax/swing/plaf/TreeUI.java
+++ b/javax/swing/plaf/TreeUI.java
@@ -51,14 +51,14 @@ import javax.swing.tree.TreePath;
*
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public abstract class TreeUI
- extends ComponentUI
+public abstract class TreeUI extends ComponentUI
{
/**
* Constructs a new <code>TreeUI</code>.
*/
public TreeUI()
{
+ // Nothing to do here.
}
diff --git a/javax/swing/plaf/UIResource.java b/javax/swing/plaf/UIResource.java
index 59edf5666..fe398fe54 100644
--- a/javax/swing/plaf/UIResource.java
+++ b/javax/swing/plaf/UIResource.java
@@ -50,6 +50,10 @@ package javax.swing.plaf;
* they are initialized or set to <code>null</code>.
*
* @author Brian Jones
+ *
* @see ComponentUI
*/
-public interface UIResource { }
+public interface UIResource
+{
+ // This is a marker interface and declares no methods.
+}
diff --git a/javax/swing/plaf/ViewportUI.java b/javax/swing/plaf/ViewportUI.java
index 087938f1e..db514de1a 100644
--- a/javax/swing/plaf/ViewportUI.java
+++ b/javax/swing/plaf/ViewportUI.java
@@ -48,13 +48,13 @@ package javax.swing.plaf;
* @author Andrew Selkirk (aselkirk@sympatico.ca)
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public abstract class ViewportUI
- extends ComponentUI
+public abstract class ViewportUI extends ComponentUI
{
/**
* Constructs a new <code>ViewportUI</code>.
*/
public ViewportUI()
{
+ // Nothing to do here.
}
}
diff --git a/javax/swing/plaf/basic/BasicArrowButton.java b/javax/swing/plaf/basic/BasicArrowButton.java
index e6d7188c4..69d441537 100644
--- a/javax/swing/plaf/basic/BasicArrowButton.java
+++ b/javax/swing/plaf/basic/BasicArrowButton.java
@@ -39,43 +39,30 @@ exception statement from your version. */
package javax.swing.plaf.basic;
import java.awt.Color;
-import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
-import java.awt.Insets;
import java.awt.Polygon;
import java.awt.Rectangle;
-import javax.swing.AbstractButton;
+import javax.swing.ButtonModel;
import javax.swing.JButton;
import javax.swing.SwingConstants;
-import javax.swing.border.Border;
/**
- * This class draws simple arrow buttons for the Basic Look and Feel.
+ * A button that displays an arrow (triangle) that points {@link #NORTH},
+ * {@link #SOUTH}, {@link #EAST} or {@link #WEST}. This button is used by
+ * the {@link BasicComboBoxUI} class.
+ *
+ * @see BasicComboBoxUI#createArrowButton
*/
public class BasicArrowButton extends JButton implements SwingConstants
{
- /** The default size of the Arrow buttons. */
- private static int defaultSize = 12;
- /** The Polygon that points up. */
- private static Polygon upIcon = new Polygon(new int[] { 0, 5, 9 },
- new int[] { 7, 2, 7 }, 3);
-
- /** The Polygon that points down. */
- private static Polygon downIcon = new Polygon(new int[] { 1, 5, 9 },
- new int[] { 3, 7, 3 }, 3);
-
- /** The Polygon that points left. */
- private static Polygon leftIcon = new Polygon(new int[] { 7, 3, 7 },
- new int[] { 1, 5, 9 }, 3);
-
- /** The Polygon that points right. */
- private static Polygon rightIcon = new Polygon(new int[] { 3, 7, 3 },
- new int[] { 1, 5, 9 }, 3);
-
- /** The direction to point in. */
+ /**
+ * The direction that the arrow points.
+ *
+ * @see #getDirection()
+ */
protected int direction;
/**
@@ -90,7 +77,7 @@ public class BasicArrowButton extends JButton implements SwingConstants
* edges of the button.
* This is package-private to avoid an accessor method.
*/
- transient Color darkShadow = Color.DARK_GRAY;
+ transient Color darkShadow = new Color(102, 102, 102);
/**
* The top and left edges of the button.
@@ -98,57 +85,15 @@ public class BasicArrowButton extends JButton implements SwingConstants
*/
transient Color highlight = Color.WHITE;
- /** The border around the ArrowButton. */
- private transient Border buttonBorder = new Border()
- {
- public Insets getBorderInsets(Component c)
- {
- return new Insets(2, 2, 2, 2);
- }
-
- public boolean isBorderOpaque()
- {
- return true;
- }
-
- public void paintBorder(Component c, Graphics g, int x, int y, int w,
- int h)
- {
- Color saved = g.getColor();
- AbstractButton b = (AbstractButton) c;
- if (b.getModel().isPressed())
- {
- g.setColor(darkShadow);
- g.drawRect(x, y, x + w - 1, y + h - 1);
- }
- else
- {
- g.setColor(highlight);
- g.drawLine(x + 1, y + 1, x + w - 3, y + 1);
- g.drawLine(x + 1, y + 1, x + 1, y + h - 2);
-
- g.setColor(shadow);
- g.drawLine(x + 1, y + h - 2, x + w - 1, y + h - 2);
- g.drawLine(x + w - 2, y + 1, x + w - 2, y + h - 2);
-
- g.setColor(darkShadow);
- g.drawLine(x, y + h - 1, x + w - 1, y + h - 1);
- g.drawLine(x + w - 1, y, x + w - 1, y + h - 1);
-
- g.setColor(saved);
- }
- }
- };
-
/**
- * Creates a new BasicArrowButton object.
+ * Creates a new <code>BasicArrowButton</code> object.
*
- * @param direction The direction the arrow points in.
+ * @param direction The direction the arrow points in (one of:
+ * {@link #NORTH}, {@link #SOUTH}, {@link #EAST} and {@link #WEST}).
*/
public BasicArrowButton(int direction)
{
super();
- setBorder(buttonBorder);
setDirection(direction);
}
@@ -156,7 +101,8 @@ public class BasicArrowButton extends JButton implements SwingConstants
* Creates a new BasicArrowButton object with the given colors and
* direction.
*
- * @param direction The direction to point in.
+ * @param direction The direction to point in (one of:
+ * {@link #NORTH}, {@link #SOUTH}, {@link #EAST} and {@link #WEST}).
* @param background The background color.
* @param shadow The shadow color.
* @param darkShadow The dark shadow color.
@@ -173,9 +119,10 @@ public class BasicArrowButton extends JButton implements SwingConstants
}
/**
- * This method returns whether the focus can traverse to this component.
+ * Returns whether the focus can traverse to this component. This method
+ * always returns <code>false</code>.
*
- * @return Whether the focus can traverse to this component.
+ * @return <code>false</code>.
*/
public boolean isFocusTraversable()
{
@@ -183,7 +130,8 @@ public class BasicArrowButton extends JButton implements SwingConstants
}
/**
- * This method returns the direction of the arrow.
+ * Returns the direction of the arrow (one of: {@link #NORTH},
+ * {@link #SOUTH}, {@link #EAST} and {@link #WEST}).
*
* @return The direction of the arrow.
*/
@@ -193,9 +141,10 @@ public class BasicArrowButton extends JButton implements SwingConstants
}
/**
- * This method changes the direction of the arrow.
+ * Sets the direction of the arrow.
*
- * @param dir The new direction of the arrow.
+ * @param dir The new direction of the arrow (one of: {@link #NORTH},
+ * {@link #SOUTH}, {@link #EAST} and {@link #WEST}).
*/
public void setDirection(int dir)
{
@@ -203,7 +152,7 @@ public class BasicArrowButton extends JButton implements SwingConstants
}
/**
- * This method paints the arrow button. The painting is delegated to the
+ * Paints the arrow button. The painting is delegated to the
* paintTriangle method.
*
* @param g The Graphics object to paint with.
@@ -211,13 +160,17 @@ public class BasicArrowButton extends JButton implements SwingConstants
public void paint(Graphics g)
{
super.paint(g);
- Insets insets = getInsets();
Rectangle bounds = getBounds();
- int x = insets.left
- + (bounds.width - insets.left - insets.right - defaultSize) / 2;
- int y = insets.top
- + (bounds.height - insets.left - insets.right - defaultSize) / 2;
- paintTriangle(g, x, y, defaultSize, direction, isEnabled());
+ int size = bounds.height / 4;
+ int x = (bounds.width - size) / 2;
+ int y = (bounds.height - size) / 2;
+ ButtonModel m = getModel();
+ if (m.isArmed())
+ {
+ x++;
+ y++;
+ }
+ paintTriangle(g, x, y, size, direction, isEnabled());
}
/** The preferred size for the button. */
@@ -231,9 +184,9 @@ public class BasicArrowButton extends JButton implements SwingConstants
= new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
/**
- * This method returns the preferred size of the arrow button.
+ * Returns the preferred size of the arrow button.
*
- * @return The preferred size.
+ * @return The preferred size (always 16 x 16).
*/
public Dimension getPreferredSize()
{
@@ -241,9 +194,9 @@ public class BasicArrowButton extends JButton implements SwingConstants
}
/**
- * This method returns the minimum size of the arrow button.
+ * Returns the minimum size of the arrow button.
*
- * @return The minimum size.
+ * @return The minimum size (always 5 x 5).
*/
public Dimension getMinimumSize()
{
@@ -251,7 +204,7 @@ public class BasicArrowButton extends JButton implements SwingConstants
}
/**
- * This method returns the maximum size of the arrow button.
+ * Returns the maximum size of the arrow button.
*
* @return The maximum size.
*/
@@ -261,103 +214,203 @@ public class BasicArrowButton extends JButton implements SwingConstants
}
/**
- * The method paints a triangle with the given size and direction at the
- * given x and y coordinates.
+ * Paints a triangle with the given size, location and direction. It is
+ * difficult to explain the rationale behind the positioning of the triangle
+ * relative to the given (x, y) position - by trial and error we seem to
+ * match the behaviour of the reference implementation (which is missing a
+ * specification for this method).
*
- * @param g The Graphics object to paint with.
- * @param x The x coordinate to paint at.
- * @param y The y coordinate to paint at.
- * @param size The size of the icon.
- * @param direction The direction of the icon.
- * @param isEnabled Whether it is enabled.
+ * @param g the graphics device.
+ * @param x the x-coordinate for the triangle's location.
+ * @param y the y-coordinate for the triangle's location.
+ * @param size the arrow size (depth).
+ * @param direction the direction of the arrow (one of: {@link #NORTH},
+ * {@link #SOUTH}, {@link #EAST} and {@link #WEST}).
+ * @param isEnabled if <code>true</code> the arrow is drawn in the enabled
+ * state, otherwise it is drawn in the disabled state.
*/
public void paintTriangle(Graphics g, int x, int y, int size, int direction,
boolean isEnabled)
{
- Polygon arrow = null;
- switch (direction)
- {
- case NORTH:
- arrow = upIcon;
- break;
- case SOUTH:
- arrow = downIcon;
- break;
- case EAST:
- case RIGHT:
- arrow = rightIcon;
- break;
- case WEST:
- case LEFT:
- arrow = leftIcon;
- break;
- }
-
- int[] xPoints = arrow.xpoints;
- int[] yPoints = arrow.ypoints;
- int x1;
- int y1;
- int x2;
- int y2;
- x1 = y1 = x2 = y2 = 0;
-
- if (size != defaultSize)
- {
- float scale = size * 1f / defaultSize;
- for (int i = 0; i < 3; i++)
- {
- xPoints[i] *= scale;
- yPoints[i] *= scale;
- }
- }
- g.translate(x, y);
-
+ Color savedColor = g.getColor();
switch (direction)
{
case NORTH:
- x1 = xPoints[0] + 2;
- y1 = yPoints[0];
- y2 = y1;
- x2 = xPoints[2] - 1;
- break;
+ paintTriangleNorth(g, x, y, size, isEnabled);
+ break;
case SOUTH:
- x1 = xPoints[1];
- y1 = yPoints[1];
- x2 = xPoints[2];
- y2 = yPoints[2];
- break;
+ paintTriangleSouth(g, x, y, size, isEnabled);
+ break;
case LEFT:
case WEST:
- x1 = xPoints[0] + 1;
- y1 = yPoints[0] + 1;
- x2 = x1;
- y2 = yPoints[2] + 1;
- break;
+ paintTriangleWest(g, x, y, size, isEnabled);
+ break;
case RIGHT:
case EAST:
- x1 = xPoints[2];
- y1 = yPoints[2] + 1;
- x2 = xPoints[1] - 1;
- y2 = yPoints[1] + 1;
- break;
+ paintTriangleEast(g, x, y, size, isEnabled);
+ break;
}
- Color saved = g.getColor();
-
+ g.setColor(savedColor);
+ }
+
+ /**
+ * Paints an upward-pointing triangle. This method is called by the
+ * {@link #paintTriangle(Graphics, int, int, int, int, boolean)} method.
+ *
+ * @param g the graphics device.
+ * @param x the x-coordinate for the anchor point.
+ * @param y the y-coordinate for the anchor point.
+ * @param size the arrow size (depth).
+ * @param isEnabled if <code>true</code> the arrow is drawn in the enabled
+ * state, otherwise it is drawn in the disabled state.
+ */
+ private void paintTriangleNorth(Graphics g, int x, int y, int size,
+ boolean isEnabled)
+ {
+ int tipX = x + (size - 2) / 2;
+ int tipY = y;
+ int baseX1 = tipX - (size - 1);
+ int baseX2 = tipX + (size - 1);
+ int baseY = y + (size - 1);
+ Polygon triangle = new Polygon();
+ triangle.addPoint(tipX, tipY);
+ triangle.addPoint(baseX1, baseY);
+ triangle.addPoint(baseX2, baseY);
if (isEnabled)
- {
- g.setColor(Color.DARK_GRAY);
-
- if (arrow != null)
- g.fillPolygon(xPoints, yPoints, 3);
- }
+ {
+ g.setColor(Color.DARK_GRAY);
+ g.fillPolygon(triangle);
+ g.drawPolygon(triangle);
+ }
else
- {
- g.setColor(Color.GRAY);
- g.fillPolygon(xPoints, yPoints, 3);
- g.setColor(Color.WHITE);
- g.drawLine(x1, y1, x2, y2);
- }
- g.setColor(saved);
- g.translate(-x, -y);
+ {
+ g.setColor(Color.GRAY);
+ g.fillPolygon(triangle);
+ g.drawPolygon(triangle);
+ g.setColor(Color.WHITE);
+ g.drawLine(baseX1 + 1, baseY + 1, baseX2 + 1, baseY + 1);
+ }
}
+
+ /**
+ * Paints an downward-pointing triangle. This method is called by the
+ * {@link #paintTriangle(Graphics, int, int, int, int, boolean)} method.
+ *
+ * @param g the graphics device.
+ * @param x the x-coordinate for the anchor point.
+ * @param y the y-coordinate for the anchor point.
+ * @param size the arrow size (depth).
+ * @param isEnabled if <code>true</code> the arrow is drawn in the enabled
+ * state, otherwise it is drawn in the disabled state.
+ */
+ private void paintTriangleSouth(Graphics g, int x, int y, int size,
+ boolean isEnabled)
+ {
+ int tipX = x + (size - 2) / 2;
+ int tipY = y + (size - 1);
+ int baseX1 = tipX - (size - 1);
+ int baseX2 = tipX + (size - 1);
+ int baseY = y;
+ Polygon triangle = new Polygon();
+ triangle.addPoint(tipX, tipY);
+ triangle.addPoint(baseX1, baseY);
+ triangle.addPoint(baseX2, baseY);
+ if (isEnabled)
+ {
+ g.setColor(Color.DARK_GRAY);
+ g.fillPolygon(triangle);
+ g.drawPolygon(triangle);
+ }
+ else
+ {
+ g.setColor(Color.GRAY);
+ g.fillPolygon(triangle);
+ g.drawPolygon(triangle);
+ g.setColor(Color.WHITE);
+ g.drawLine(tipX + 1, tipY, baseX2, baseY + 1);
+ g.drawLine(tipX + 1, tipY + 1, baseX2 + 1, baseY + 1);
+ }
+ }
+
+ /**
+ * Paints a right-pointing triangle. This method is called by the
+ * {@link #paintTriangle(Graphics, int, int, int, int, boolean)} method.
+ *
+ * @param g the graphics device.
+ * @param x the x-coordinate for the anchor point.
+ * @param y the y-coordinate for the anchor point.
+ * @param size the arrow size (depth).
+ * @param isEnabled if <code>true</code> the arrow is drawn in the enabled
+ * state, otherwise it is drawn in the disabled state.
+ */
+ private void paintTriangleEast(Graphics g, int x, int y, int size,
+ boolean isEnabled)
+ {
+ int tipX = x + (size - 1);
+ int tipY = y + (size - 2) / 2;
+ int baseX = x;
+ int baseY1 = tipY - (size - 1);
+ int baseY2 = tipY + (size - 1);
+
+ Polygon triangle = new Polygon();
+ triangle.addPoint(tipX, tipY);
+ triangle.addPoint(baseX, baseY1);
+ triangle.addPoint(baseX, baseY2);
+ if (isEnabled)
+ {
+ g.setColor(Color.DARK_GRAY);
+ g.fillPolygon(triangle);
+ g.drawPolygon(triangle);
+ }
+ else
+ {
+ g.setColor(Color.GRAY);
+ g.fillPolygon(triangle);
+ g.drawPolygon(triangle);
+ g.setColor(Color.WHITE);
+ g.drawLine(baseX + 1, baseY2, tipX, tipY + 1);
+ g.drawLine(baseX + 1, baseY2 + 1, tipX + 1, tipY + 1);
+ }
+ }
+
+ /**
+ * Paints a left-pointing triangle. This method is called by the
+ * {@link #paintTriangle(Graphics, int, int, int, int, boolean)} method.
+ *
+ * @param g the graphics device.
+ * @param x the x-coordinate for the anchor point.
+ * @param y the y-coordinate for the anchor point.
+ * @param size the arrow size (depth).
+ * @param isEnabled if <code>true</code> the arrow is drawn in the enabled
+ * state, otherwise it is drawn in the disabled state.
+ */
+ private void paintTriangleWest(Graphics g, int x, int y, int size,
+ boolean isEnabled)
+ {
+ int tipX = x;
+ int tipY = y + (size - 2) / 2;
+ int baseX = x + (size - 1);
+ int baseY1 = tipY - (size - 1);
+ int baseY2 = tipY + (size - 1);
+
+ Polygon triangle = new Polygon();
+ triangle.addPoint(tipX, tipY);
+ triangle.addPoint(baseX, baseY1);
+ triangle.addPoint(baseX, baseY2);
+ if (isEnabled)
+ {
+ g.setColor(Color.DARK_GRAY);
+ g.fillPolygon(triangle);
+ g.drawPolygon(triangle);
+ }
+ else
+ {
+ g.setColor(Color.GRAY);
+ g.fillPolygon(triangle);
+ g.drawPolygon(triangle);
+ g.setColor(Color.WHITE);
+ g.drawLine(baseX + 1, baseY1 + 1, baseX + 1, baseY2 + 1);
+ }
+ }
+
}
diff --git a/javax/swing/plaf/basic/BasicBorders.java b/javax/swing/plaf/basic/BasicBorders.java
index e7d6e4338..cec7bec85 100644
--- a/javax/swing/plaf/basic/BasicBorders.java
+++ b/javax/swing/plaf/basic/BasicBorders.java
@@ -806,9 +806,9 @@ public class BasicBorders
*/
public MarginBorder()
{
+ // Nothing to do here.
}
-
/**
* Measures the width of this border.
*
@@ -1313,33 +1313,32 @@ public class BasicBorders
*
* @author Sascha Brawer (brawer@dandelis.ch)
*/
- public static class SplitPaneBorder
- implements Border, UIResource
+ public static class SplitPaneBorder implements Border, UIResource
{
/**
* Indicates that the top edge shall be not be painted
- * by {@link #paintRect(java.awt.Graphics, int, int, int, int, int)}.
+ * by {@link #paintRect}.
*/
private static final int SUPPRESS_TOP = 1;
/**
* Indicates that the left edge shall be not be painted
- * by {@link #paintRect(java.awt.Graphics, int, int, int, int, int)}.
+ * by {@link #paintRect}.
*/
private static final int SUPPRESS_LEFT = 2;
/**
* Indicates that the bottom edge shall be not be painted
- * by {@link #paintRect(java.awt.Graphics, int, int, int, int, int)}.
+ * by {@link #paintRect}.
*/
private static final int SUPPRESS_BOTTOM = 4;
/**
* Indicates that the right edge shall be not be painted
- * by {@link #paintRect(java.awt.Graphics, int, int, int, int, int)}.
+ * by {@link #paintRect}.
*/
private static final int SUPPRESS_RIGHT = 8;
diff --git a/javax/swing/plaf/basic/BasicButtonListener.java b/javax/swing/plaf/basic/BasicButtonListener.java
index 5349f5240..1fca69451 100644
--- a/javax/swing/plaf/basic/BasicButtonListener.java
+++ b/javax/swing/plaf/basic/BasicButtonListener.java
@@ -55,9 +55,8 @@ import javax.swing.JComponent;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
-public class BasicButtonListener
- implements MouseListener, MouseMotionListener, FocusListener,
- ChangeListener, PropertyChangeListener
+public class BasicButtonListener implements MouseListener, MouseMotionListener,
+ FocusListener, ChangeListener, PropertyChangeListener
{
public BasicButtonListener(AbstractButton b)
{
@@ -66,10 +65,12 @@ public class BasicButtonListener
public void propertyChange(PropertyChangeEvent e)
{
+ // TODO: What should be done here, if anything?
}
protected void checkOpacity(AbstractButton b)
{
+ // TODO: What should be done here?
}
public void focusGained(FocusEvent e)
@@ -129,18 +130,22 @@ public class BasicButtonListener
public void stateChanged(ChangeEvent e)
{
+ // TODO: What should be done here, if anything?
}
public void mouseMoved(MouseEvent e)
{
+ // TODO: What should be done here, if anything?
}
public void mouseDragged(MouseEvent e)
{
+ // TODO: What should be done here, if anything?
}
public void mouseClicked(MouseEvent e)
{
+ // TODO: What should be done here, if anything?
}
/**
diff --git a/javax/swing/plaf/basic/BasicButtonUI.java b/javax/swing/plaf/basic/BasicButtonUI.java
index acc1265a6..2d3dbd350 100644
--- a/javax/swing/plaf/basic/BasicButtonUI.java
+++ b/javax/swing/plaf/basic/BasicButtonUI.java
@@ -38,7 +38,6 @@ exception statement from your version. */
package javax.swing.plaf.basic;
-import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
@@ -49,7 +48,9 @@ import javax.swing.AbstractButton;
import javax.swing.ButtonModel;
import javax.swing.Icon;
import javax.swing.InputMap;
+import javax.swing.JButton;
import javax.swing.JComponent;
+import javax.swing.LookAndFeel;
import javax.swing.SwingUtilities;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
@@ -57,6 +58,9 @@ import javax.swing.plaf.ButtonUI;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.UIResource;
+/**
+ * A UI delegate for the {@link JButton} component.
+ */
public class BasicButtonUI extends ButtonUI
{
/**
@@ -73,13 +77,11 @@ public class BasicButtonUI extends ButtonUI
private int textShiftOffset;
- private Color focusColor;
-
/**
* Factory method to create an instance of BasicButtonUI for a given
* {@link JComponent}, which should be an {@link AbstractButton}.
*
- * @param c The component to create a UI got
+ * @param c The component.
*
* @return A new UI capable of drawing the component
*/
@@ -88,21 +90,46 @@ public class BasicButtonUI extends ButtonUI
return new BasicButtonUI();
}
+ /**
+ * Returns the default gap between the button's text and icon (in pixels).
+ *
+ * @param b the button (ignored).
+ *
+ * @return The gap.
+ */
public int getDefaultTextIconGap(AbstractButton b)
{
return defaultTextIconGap;
}
+ /**
+ * Sets the text shift offset to zero.
+ *
+ * @see #setTextShiftOffset()
+ */
protected void clearTextShiftOffset()
{
textShiftOffset = 0;
}
+ /**
+ * Returns the text shift offset.
+ *
+ * @return The text shift offset.
+ *
+ * @see #clearTextShiftOffset()
+ * @see #setTextShiftOffset()
+ */
protected int getTextShiftOffset()
{
return textShiftOffset;
}
+ /**
+ * Sets the text shift offset to the value in {@link #defaultTextShiftOffset}.
+ *
+ * @see #clearTextShiftOffset()
+ */
protected void setTextShiftOffset()
{
textShiftOffset = defaultTextShiftOffset;
@@ -119,23 +146,29 @@ public class BasicButtonUI extends ButtonUI
return "Button.";
}
+ /**
+ * Installs the default settings.
+ *
+ * @param b the button (<code>null</code> not permitted).
+ */
protected void installDefaults(AbstractButton b)
{
- UIDefaults defaults = UIManager.getLookAndFeelDefaults();
String prefix = getPropertyPrefix();
- b.setFont(defaults.getFont(prefix + "font"));
- focusColor = defaults.getColor(prefix + "focus");
- b.setForeground(defaults.getColor(prefix + "foreground"));
- b.setBackground(defaults.getColor(prefix + "background"));
- b.setMargin(defaults.getInsets(prefix + "margin"));
- b.setBorder(defaults.getBorder(prefix + "border"));
- b.setIconTextGap(defaults.getInt(prefix + "textIconGap"));
+ LookAndFeel.installColorsAndFont(b, prefix + "background",
+ prefix + "foreground", prefix + "font");
+ LookAndFeel.installBorder(b, prefix + "border");
+ b.setMargin(UIManager.getInsets(prefix + "margin"));
+ b.setIconTextGap(UIManager.getInt(prefix + "textIconGap"));
b.setInputMap(JComponent.WHEN_FOCUSED,
- (InputMap) defaults.get(prefix + "focusInputMap"));
- b.setRolloverEnabled(defaults.getBoolean(prefix + "rollover"));
- b.setOpaque(true);
+ (InputMap) UIManager.get(prefix + "focusInputMap"));
+ b.setRolloverEnabled(UIManager.getBoolean(prefix + "rollover"));
}
+ /**
+ * Removes the defaults added by {@link #installDefaults(AbstractButton)}.
+ *
+ * @param b the button (<code>null</code> not permitted).
+ */
protected void uninstallDefaults(AbstractButton b)
{
if (b.getFont() instanceof UIResource)
@@ -149,11 +182,25 @@ public class BasicButtonUI extends ButtonUI
protected BasicButtonListener listener;
+ /**
+ * Creates and returns a new instance of {@link BasicButtonListener}. This
+ * method provides a hook to make it easy for subclasses to install a
+ * different listener.
+ *
+ * @param b the button.
+ *
+ * @return A new listener.
+ */
protected BasicButtonListener createButtonListener(AbstractButton b)
{
return new BasicButtonListener(b);
}
+ /**
+ * Installs listeners for the button.
+ *
+ * @param b the button (<code>null</code> not permitted).
+ */
protected void installListeners(AbstractButton b)
{
listener = createButtonListener(b);
@@ -164,6 +211,11 @@ public class BasicButtonUI extends ButtonUI
b.addMouseMotionListener(listener);
}
+ /**
+ * Uninstalls listeners for the button.
+ *
+ * @param b the button (<code>null</code> not permitted).
+ */
protected void uninstallListeners(AbstractButton b)
{
b.removeChangeListener(listener);
@@ -220,12 +272,12 @@ public class BasicButtonUI extends ButtonUI
return d;
}
- private static Icon currentIcon(AbstractButton b)
+ static Icon currentIcon(AbstractButton b)
{
Icon i = b.getIcon();
ButtonModel model = b.getModel();
- if (model.isPressed() && b.getPressedIcon() != null)
+ if (model.isPressed() && b.getPressedIcon() != null && b.isEnabled())
i = b.getPressedIcon();
else if (model.isRollover())
@@ -236,7 +288,7 @@ public class BasicButtonUI extends ButtonUI
i = b.getRolloverIcon();
}
- else if (b.isSelected())
+ else if (b.isSelected() && b.isEnabled())
{
if (b.isEnabled() && b.getSelectedIcon() != null)
i = b.getSelectedIcon();
@@ -287,13 +339,11 @@ public class BasicButtonUI extends ButtonUI
if ((b.getModel().isArmed() && b.getModel().isPressed())
|| b.isSelected())
paintButtonPressed(g, b);
- else
- paintButtonNormal(g, vr, c);
paintIcon(g, c, ir);
if (text != null)
paintText(g, b, tr, text);
- if (b.isFocusOwner())
+ if (b.isFocusOwner() && b.isFocusPainted())
paintFocus(g, b, vr, tr, ir);
}
@@ -339,44 +389,25 @@ public class BasicButtonUI extends ButtonUI
/**
* Paints the background area of an {@link AbstractButton} in the pressed
- * state. This means filling the supplied area with the {@link
- * pressedBackgroundColor}.
+ * state. This means filling the supplied area with a darker than normal
+ * background.
*
* @param g The graphics context to paint with
* @param b The button to paint the state of
*/
protected void paintButtonPressed(Graphics g, AbstractButton b)
{
- if (b.isContentAreaFilled())
- {
- Rectangle area = new Rectangle();
- SwingUtilities.calculateInnerArea(b, area);
- g.setColor(b.getBackground().darker());
- g.fillRect(area.x, area.y, area.width, area.height);
- }
- }
-
- /**
- * Paints the background area of an {@link AbstractButton} in the normal,
- * non-pressed state. This means filling the supplied area with the
- * {@link normalBackgroundColor}.
- *
- * @param g The graphics context to paint with
- * @param area The area in which to paint
- * @param b The component to paint the state of
- */
- private void paintButtonNormal(Graphics g, Rectangle area, JComponent b)
- {
- if (((AbstractButton)b).isContentAreaFilled() && b.isOpaque())
+ if (b.isContentAreaFilled() && b.isOpaque())
{
- g.setColor(b.getBackground());
+ Rectangle area = new Rectangle();
+ SwingUtilities.calculateInnerArea(b, area);
+ g.setColor(UIManager.getColor(getPropertyPrefix() + "shadow"));
g.fillRect(area.x, area.y, area.width, area.height);
}
}
/**
- * Paints the "text" property of an {@link AbstractButton}, using the
- * {@link textColor} color.
+ * Paints the "text" property of an {@link AbstractButton}.
*
* @param g The graphics context to paint with
* @param c The component to paint the state of
@@ -390,8 +421,7 @@ public class BasicButtonUI extends ButtonUI
}
/**
- * Paints the "text" property of an {@link AbstractButton}, using the
- * {@link textColor} color.
+ * Paints the "text" property of an {@link AbstractButton}.
*
* @param g The graphics context to paint with
* @param b The button to paint the state of
diff --git a/javax/swing/plaf/basic/BasicCheckBoxMenuItemUI.java b/javax/swing/plaf/basic/BasicCheckBoxMenuItemUI.java
index 945aea53d..95e0dc982 100644
--- a/javax/swing/plaf/basic/BasicCheckBoxMenuItemUI.java
+++ b/javax/swing/plaf/basic/BasicCheckBoxMenuItemUI.java
@@ -53,6 +53,15 @@ import javax.swing.plaf.ComponentUI;
*/
public class BasicCheckBoxMenuItemUI extends BasicMenuItemUI
{
+
+ /**
+ * Creates a new BasicCheckBoxMenuItemUI object.
+ */
+ public BasicCheckBoxMenuItemUI()
+ {
+ super();
+ }
+
/**
* Factory method to create a BasicCheckBoxMenuItemUI for the given {@link
* JComponent}, which should be a JCheckBoxMenuItem
@@ -77,18 +86,6 @@ public class BasicCheckBoxMenuItemUI extends BasicMenuItemUI
}
/**
- * This method installs the defaults that are defined in the Basic look and
- * feel for this JRadioButtonMenuItem
- */
- protected void installDefaults()
- {
- super.installDefaults();
-
- UIDefaults defaults = UIManager.getLookAndFeelDefaults();
- checkIcon = defaults.getIcon("CheckBoxMenuItem.checkIcon");
- }
-
- /**
* DOCUMENT ME!
*
* @param item DOCUMENT ME!
@@ -100,5 +97,7 @@ public class BasicCheckBoxMenuItemUI extends BasicMenuItemUI
MenuElement[] path,
MenuSelectionManager manager)
{
+ // TODO: May not be implemented properly.
+ item.processMouseEvent(e, path, manager);
}
}
diff --git a/javax/swing/plaf/basic/BasicColorChooserUI.java b/javax/swing/plaf/basic/BasicColorChooserUI.java
index 4e6d38154..5a872ae63 100644
--- a/javax/swing/plaf/basic/BasicColorChooserUI.java
+++ b/javax/swing/plaf/basic/BasicColorChooserUI.java
@@ -47,8 +47,7 @@ import javax.swing.JColorChooser;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
-import javax.swing.UIDefaults;
-import javax.swing.UIManager;
+import javax.swing.LookAndFeel;
import javax.swing.colorchooser.AbstractColorChooserPanel;
import javax.swing.colorchooser.ColorChooserComponentFactory;
import javax.swing.event.ChangeEvent;
@@ -243,12 +242,21 @@ public class BasicColorChooserUI extends ColorChooserUI
{
uninstallListeners();
uninstallDefaults();
+ uninstallDefaultChoosers();
pane = null;
chooser = null;
}
/**
+ * Uninstalls the default color choosers that have been installed by this UI.
+ */
+ protected void uninstallDefaultChoosers()
+ {
+ defaultChoosers = null;
+ }
+
+ /**
* This method installs the preview panel for the JColorChooser.
*/
protected void installPreviewPanel()
@@ -281,11 +289,9 @@ public class BasicColorChooserUI extends ColorChooserUI
*/
protected void installDefaults()
{
- UIDefaults defaults = UIManager.getLookAndFeelDefaults();
-
- chooser.setFont(defaults.getFont("ColorChooser.font"));
- chooser.setForeground(defaults.getColor("ColorChooser.foreground"));
- chooser.setBackground(defaults.getColor("ColorChooser.background"));
+ LookAndFeel.installColorsAndFont(chooser, "ColorChooser.background",
+ "ColorChooser.foreground",
+ "ColorChooser.font");
}
/**
diff --git a/javax/swing/plaf/basic/BasicComboBoxEditor.java b/javax/swing/plaf/basic/BasicComboBoxEditor.java
index dd867f0dc..be8c776aa 100644
--- a/javax/swing/plaf/basic/BasicComboBoxEditor.java
+++ b/javax/swing/plaf/basic/BasicComboBoxEditor.java
@@ -168,6 +168,7 @@ public class BasicComboBoxEditor extends Object implements ComboBoxEditor,
*/
public UIResource()
{
+ // Nothing to do here.
}
}
}
diff --git a/javax/swing/plaf/basic/BasicComboBoxRenderer.java b/javax/swing/plaf/basic/BasicComboBoxRenderer.java
index 94a35bc69..8115605b7 100644
--- a/javax/swing/plaf/basic/BasicComboBoxRenderer.java
+++ b/javax/swing/plaf/basic/BasicComboBoxRenderer.java
@@ -156,6 +156,7 @@ public class BasicComboBoxRenderer
*/
public UIResource()
{
+ // Nothing to do here.
}
}
}
diff --git a/javax/swing/plaf/basic/BasicComboBoxUI.java b/javax/swing/plaf/basic/BasicComboBoxUI.java
index b4267e56a..7356423d3 100644
--- a/javax/swing/plaf/basic/BasicComboBoxUI.java
+++ b/javax/swing/plaf/basic/BasicComboBoxUI.java
@@ -43,6 +43,7 @@ import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
+import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.LayoutManager;
@@ -70,8 +71,8 @@ import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JList;
import javax.swing.ListCellRenderer;
+import javax.swing.LookAndFeel;
import javax.swing.SwingUtilities;
-import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
@@ -157,12 +158,29 @@ public class BasicComboBoxUI extends ComboBoxUI
*/
protected PropertyChangeListener propertyChangeListener;
+ /**
+ * The button background.
+ * @see #installDefaults()
+ */
+ private Color buttonBackground;
+
+ /**
+ * The button shadow.
+ * @see #installDefaults()
+ */
+ private Color buttonShadow;
+
/**
- * Colors that are used to render selected item in the combo box.
+ * The button dark shadow.
+ * @see #installDefaults()
+ */
+ private Color buttonDarkShadow;
+
+ /**
+ * The button highlight.
+ * @see #installDefaults()
*/
- private Color shadow;
- private Color darkShadow;
- private Color highlight;
+ private Color buttonHighlight;
/* Size of the largest item in the comboBox
* This is package-private to avoid an accessor method.
@@ -179,6 +197,7 @@ public class BasicComboBoxUI extends ComboBoxUI
*/
public BasicComboBoxUI()
{
+ // Nothing to do here.
}
/**
@@ -207,13 +226,13 @@ public class BasicComboBoxUI extends ComboBoxUI
if (c instanceof JComboBox)
{
- comboBox = (JComboBox) c;
- comboBox.setOpaque(true);
- comboBox.setLayout(createLayoutManager());
- installDefaults();
- installComponents();
- installListeners();
- installKeyboardActions();
+ comboBox = (JComboBox) c;
+ comboBox.setOpaque(true);
+ comboBox.setLayout(createLayoutManager());
+ installDefaults();
+ installComponents();
+ installListeners();
+ installKeyboardActions();
}
}
@@ -241,21 +260,14 @@ public class BasicComboBoxUI extends ComboBoxUI
*/
protected void installDefaults()
{
- UIDefaults defaults = UIManager.getLookAndFeelDefaults();
-
- if (comboBox.getFont() instanceof UIResource)
- comboBox.setFont(defaults.getFont("ComboBox.font"));
+ LookAndFeel.installColorsAndFont(comboBox, "ComboBox.background",
+ "ComboBox.foreground", "ComboBox.font");
- if (comboBox.getForeground() instanceof UIResource)
- comboBox.setForeground(defaults.getColor("ComboBox.foreground"));
-
- if (comboBox.getBackground() instanceof UIResource)
- comboBox.setBackground(defaults.getColor("ComboBox.background"));
-
// fetch the button color scheme
- shadow = defaults.getColor("ComboBox.buttonShadow");
- darkShadow = defaults.getColor("ComboBox.buttonDarkShadow");
- highlight = defaults.getColor("ComboBox.buttonHighlight");
+ buttonBackground = UIManager.getColor("ComboBox.buttonBackground");
+ buttonShadow = UIManager.getColor("ComboBox.buttonShadow");
+ buttonDarkShadow = UIManager.getColor("ComboBox.buttonDarkShadow");
+ buttonHighlight = UIManager.getColor("ComboBox.buttonHighlight");
}
/**
@@ -303,9 +315,10 @@ public class BasicComboBoxUI extends ComboBoxUI
if (comboBox.getBackground() instanceof UIResource)
comboBox.setBackground(null);
- shadow = null;
- darkShadow = null;
- highlight = null;
+ buttonBackground = null;
+ buttonShadow = null;
+ buttonDarkShadow = null;
+ buttonHighlight = null;
}
/**
@@ -440,7 +453,7 @@ public class BasicComboBoxUI extends ComboBoxUI
*/
protected ComboBoxEditor createEditor()
{
- return new BasicComboBoxEditor();
+ return new BasicComboBoxEditor.UIResource();
}
/**
@@ -450,25 +463,26 @@ public class BasicComboBoxUI extends ComboBoxUI
*/
protected void installComponents()
{
- // create and install arrow button
- arrowButton = createArrowButton();
- configureArrowButton();
- comboBox.add(arrowButton);
-
- // Set list that will be used by BasicComboBoxRender
- // in order to determine the right colors when rendering
- listBox = new JList();
+ // create drop down list of items
+ popup = createPopup();
+ listBox = popup.getList();
// set editor and renderer for the combo box. Editor is used
// only if combo box becomes editable, otherwise renderer is used
// to paint the selected item; combobox is not editable by default.
comboBox.setRenderer(createRenderer());
- comboBox.setEditor(createEditor());
- editor = comboBox.getEditor().getEditorComponent();
+ // create and install arrow button
+ arrowButton = createArrowButton();
+ configureArrowButton();
+ comboBox.add(arrowButton);
- // create drop down list of items
- popup = createPopup();
+ ComboBoxEditor currentEditor = comboBox.getEditor();
+ if (currentEditor == null || currentEditor instanceof UIResource)
+ {
+ comboBox.setEditor(createEditor());
+ editor = comboBox.getEditor().getEditorComponent();
+ }
comboBox.revalidate();
}
@@ -490,8 +504,14 @@ public class BasicComboBoxUI extends ComboBoxUI
comboBox.setRenderer(null);
- comboBox.setEditor(null);
- editor = null;
+ // if the editor is not an instanceof UIResource, it was not set by the
+ // UI delegate, so don't clear it...
+ ComboBoxEditor currentEditor = comboBox.getEditor();
+ if (currentEditor instanceof UIResource)
+ {
+ comboBox.setEditor(null);
+ editor = null;
+ }
}
/**
@@ -537,16 +557,19 @@ public class BasicComboBoxUI extends ComboBoxUI
{
arrowButton.setEnabled(comboBox.isEnabled());
arrowButton.setFont(comboBox.getFont());
- arrowButton.setMargin(new Insets(0, 0, 0, 0));
}
/**
* Unconfigures the arrow button.
*
* @see #configureArrowButton()
+ *
+ * @specnote The specification says this method is implementation specific
+ * and should not be used or overridden.
*/
public void unconfigureArrowButton()
{
+ // Nothing to do here yet.
}
/**
@@ -558,7 +581,8 @@ public class BasicComboBoxUI extends ComboBoxUI
*/
protected JButton createArrowButton()
{
- return new BasicArrowButton(BasicArrowButton.SOUTH);
+ return new BasicArrowButton(BasicArrowButton.SOUTH, buttonBackground,
+ buttonShadow, buttonDarkShadow, buttonHighlight);
}
/**
@@ -627,6 +651,9 @@ public class BasicComboBoxUI extends ComboBoxUI
*/
public Dimension getPreferredSize(JComponent c)
{
+ // note: overriding getMinimumSize() (for example in the MetalComboBoxUI
+ // class) affects the getPreferredSize() result, so it seems logical that
+ // this method is implemented by delegating to the getMinimumSize() method
return getMinimumSize(c);
}
@@ -641,9 +668,8 @@ public class BasicComboBoxUI extends ComboBoxUI
public Dimension getMinimumSize(JComponent c)
{
Dimension d = getDisplaySize();
- Dimension arrowDim = arrowButton.getPreferredSize();
- Dimension result = new Dimension(d.width + arrowDim.width,
- Math.max(d.height, arrowDim.height));
+ int arrowButtonWidth = d.height;
+ Dimension result = new Dimension(d.width + arrowButtonWidth, d.height);
return result;
}
@@ -656,7 +682,7 @@ public class BasicComboBoxUI extends ComboBoxUI
*
* @param c The {@link JComponent} to find the maximum size for
*
- * @return The dimensions of the minimum size.
+ * @return The maximum size (<code>Dimension(32767, 32767)</code>).
*/
public Dimension getMaximumSize(JComponent c)
{
@@ -804,15 +830,24 @@ public class BasicComboBoxUI extends ComboBoxUI
}
/**
- * Returns default size for the combo box that doesn't contain any elements
- * in it
+ * Returns the default size for the display area of a combo box that does
+ * not contain any elements. This method returns the width and height of
+ * a single space in the current font, plus a margin of 1 pixel.
*
- * @return Default size of the combo box with no elements in it.
+ * @return The default display size.
+ *
+ * @see #getDisplaySize()
*/
protected Dimension getDefaultSize()
{
- // FIXME: Not implemented properly.
- return new Dimension(100, 5);
+ // There is nothing in the spec to say how this method should be
+ // implemented...so I've done some guessing, written some Mauve tests,
+ // and written something that gives dimensions that are close to the
+ // reference implementation.
+ FontMetrics fm = comboBox.getFontMetrics(comboBox.getFont());
+ int w = fm.charWidth(' ') + 2;
+ int h = fm.getHeight() + 2;
+ return new Dimension(w, h);
}
/**
@@ -823,40 +858,52 @@ public class BasicComboBoxUI extends ComboBoxUI
*/
protected Dimension getDisplaySize()
{
- ComboBoxModel model = comboBox.getModel();
- int numItems = model.getSize();
-
- // if combo box doesn't have any items then simply
- // return its default size
- if (numItems == 0)
+ Object prototype = comboBox.getPrototypeDisplayValue();
+ if (prototype != null)
{
- displaySize = getDefaultSize();
- return displaySize;
+ // calculate result based on prototype
+ ListCellRenderer renderer = comboBox.getRenderer();
+ Component comp = renderer.getListCellRendererComponent(listBox,
+ prototype, -1, false, false);
+ Dimension compSize = comp.getPreferredSize();
+ compSize.width += 2; // add 1 pixel margin around area
+ compSize.height += 2;
+ return compSize;
}
+ else
+ {
+ ComboBoxModel model = comboBox.getModel();
+ int numItems = model.getSize();
- Dimension size = new Dimension(0, 0);
+ // if combo box doesn't have any items then simply
+ // return its default size
+ if (numItems == 0)
+ {
+ displaySize = getDefaultSize();
+ return displaySize;
+ }
- // ComboBox's display size should be equal to the
- // size of the largest item in the combo box.
- ListCellRenderer renderer = comboBox.getRenderer();
+ Dimension size = new Dimension(0, 0);
- // FIXME: use the JComboBox.getPrototypeDisplayValue() if there is
- // one
- for (int i = 0; i < numItems; i++)
- {
- Object item = model.getElementAt(i);
- String s = item.toString();
- Component comp = renderer.getListCellRendererComponent(listBox, item,
- -1, false, false);
+ // ComboBox's display size should be equal to the
+ // size of the largest item in the combo box.
+ ListCellRenderer renderer = comboBox.getRenderer();
- Dimension compSize = comp.getPreferredSize();
- if (compSize.width > size.width)
- size.width = compSize.width;
- if (compSize.height > size.height)
- size.height = compSize.height;
+ for (int i = 0; i < numItems; i++)
+ {
+ Object item = model.getElementAt(i);
+ Component comp = renderer.getListCellRendererComponent(listBox,
+ item, -1, false, false);
+
+ Dimension compSize = comp.getPreferredSize();
+ if (compSize.width + 2 > size.width)
+ size.width = compSize.width + 2;
+ if (compSize.height + 2 > size.height)
+ size.height = compSize.height + 2;
+ }
+ displaySize = size;
+ return displaySize;
}
- displaySize = size;
- return displaySize;
}
/**
@@ -890,6 +937,7 @@ public class BasicComboBoxUI extends ComboBoxUI
*/
public ComboBoxLayoutManager()
{
+ // Nothing to do here.
}
/**
@@ -976,6 +1024,7 @@ public class BasicComboBoxUI extends ComboBoxUI
*/
public FocusHandler()
{
+ // Nothing to do here.
}
/**
@@ -999,6 +1048,7 @@ public class BasicComboBoxUI extends ComboBoxUI
public void focusLost(FocusEvent e)
{
hasFocus = false;
+ setPopupVisible(comboBox, false);
comboBox.repaint();
}
}
@@ -1014,6 +1064,7 @@ public class BasicComboBoxUI extends ComboBoxUI
*/
public ItemHandler()
{
+ // Nothing to do here.
}
/**
@@ -1024,6 +1075,8 @@ public class BasicComboBoxUI extends ComboBoxUI
*/
public void itemStateChanged(ItemEvent e)
{
+ if (e.getStateChange() == ItemEvent.SELECTED && comboBox.isEditable())
+ comboBox.getEditor().setItem(e.getItem());
comboBox.repaint();
}
}
@@ -1035,6 +1088,7 @@ public class BasicComboBoxUI extends ComboBoxUI
{
public KeyHandler()
{
+ // Nothing to do here.
}
/**
@@ -1057,6 +1111,7 @@ public class BasicComboBoxUI extends ComboBoxUI
*/
public ListDataHandler()
{
+ // Nothing to do here.
}
/**
@@ -1114,6 +1169,7 @@ public class BasicComboBoxUI extends ComboBoxUI
*/
public PropertyChangeHandler()
{
+ // Nothing to do here.
}
/**
diff --git a/javax/swing/plaf/basic/BasicComboPopup.java b/javax/swing/plaf/basic/BasicComboPopup.java
index 73aac8d4e..7f3fab8f1 100644
--- a/javax/swing/plaf/basic/BasicComboPopup.java
+++ b/javax/swing/plaf/basic/BasicComboPopup.java
@@ -40,6 +40,7 @@ package javax.swing.plaf.basic;
import java.awt.Component;
import java.awt.Dimension;
+import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ItemEvent;
@@ -179,7 +180,10 @@ public class BasicComboPopup extends JPopupMenu implements ComboPopup
int popupHeight = getPopupHeightForRowCount(comboBox.getMaximumRowCount());
list.setPreferredSize(new Dimension(cbBounds.width, popupHeight));
- super.setPopupSize(cbBounds.width, popupHeight);
+ Insets insets1 = getInsets();
+ Insets insets2 = scroller.getInsets();
+ super.setPopupSize(cbBounds.width, popupHeight + insets1.top
+ + insets1.bottom + insets2.top + insets2.bottom);
// Highlight selected item in the combo box's drop down list
if (comboBox.getSelectedIndex() != -1)
@@ -714,7 +718,11 @@ public class BasicComboPopup extends JPopupMenu implements ComboPopup
protected void updateListBoxSelectionForEvent(MouseEvent anEvent,
boolean shouldScroll)
{
- // FIXME: Need to implement
+ // TODO: We need to handle the shouldScroll parameter somehow.
+ int index = list.locationToIndex(anEvent.getPoint());
+ // Check for valid index.
+ if (index >= 0)
+ list.setSelectedIndex(index);
}
/**
@@ -732,6 +740,7 @@ public class BasicComboPopup extends JPopupMenu implements ComboPopup
*/
protected InvocationMouseHandler()
{
+ // Nothing to do here.
}
/**
@@ -744,7 +753,7 @@ public class BasicComboPopup extends JPopupMenu implements ComboPopup
public void mousePressed(MouseEvent e)
{
if (comboBox.isEnabled())
- togglePopup();
+ togglePopup();
}
/**
@@ -768,15 +777,15 @@ public class BasicComboPopup extends JPopupMenu implements ComboPopup
// then change selection and close popup
if (! (releasedComponent instanceof JComboBox))
{
- // List model contains the item over which mouse is released,
- // since it is updated every time the mouse is moved over a different
- // item in the list. Now that the mouse is released we need to
- // update model of the combo box as well.
- comboBox.setSelectedIndex(list.getSelectedIndex());
-
- if (isAutoScrolling)
- stopAutoScrolling();
- hide();
+ // List model contains the item over which mouse is released,
+ // since it is updated every time the mouse is moved over a different
+ // item in the list. Now that the mouse is released we need to
+ // update model of the combo box as well.
+ comboBox.setSelectedIndex(list.getSelectedIndex());
+
+ if (isAutoScrolling)
+ stopAutoScrolling();
+ hide();
}
}
}
@@ -792,6 +801,7 @@ public class BasicComboPopup extends JPopupMenu implements ComboPopup
*/
protected InvocationMouseMotionHandler()
{
+ // Nothing to do here.
}
/**
@@ -868,6 +878,7 @@ public class BasicComboPopup extends JPopupMenu implements ComboPopup
*/
protected ItemHandler()
{
+ // Nothing to do here.
}
/**
@@ -877,6 +888,7 @@ public class BasicComboPopup extends JPopupMenu implements ComboPopup
*/
public void itemStateChanged(ItemEvent e)
{
+ // TODO: What should be done here?
}
}
@@ -890,16 +902,20 @@ public class BasicComboPopup extends JPopupMenu implements ComboPopup
{
protected ListMouseHandler()
{
+ // Nothing to do here.
}
public void mousePressed(MouseEvent e)
{
+ // TODO: What should be do here?
}
public void mouseReleased(MouseEvent anEvent)
{
int index = list.locationToIndex(anEvent.getPoint());
- comboBox.setSelectedIndex(index);
+ // Check for valid index.
+ if (index >= 0)
+ comboBox.setSelectedIndex(index);
hide();
}
}
@@ -913,15 +929,12 @@ public class BasicComboPopup extends JPopupMenu implements ComboPopup
{
protected ListMouseMotionHandler()
{
+ // Nothing to do here.
}
public void mouseMoved(MouseEvent anEvent)
{
- // Highlight list cells over which the mouse is located.
- // This changes list model, but has no effect on combo box's data model
- int index = list.locationToIndex(anEvent.getPoint());
- list.setSelectedIndex(index);
- list.repaint();
+ updateListBoxSelectionForEvent(anEvent, false);
}
}
@@ -934,6 +947,7 @@ public class BasicComboPopup extends JPopupMenu implements ComboPopup
{
protected PropertyChangeHandler()
{
+ // Nothing to do here.
}
public void propertyChange(PropertyChangeEvent e)
@@ -1009,18 +1023,22 @@ public class BasicComboPopup extends JPopupMenu implements ComboPopup
{
public ListDataHandler()
{
+ // Nothing to do here.
}
public void contentsChanged(ListDataEvent e)
{
+ // Nothing to do here.
}
public void intervalAdded(ListDataEvent e)
{
+ // Nothing to do here.
}
public void intervalRemoved(ListDataEvent e)
{
+ // Nothing to do here.
}
}
@@ -1032,10 +1050,12 @@ public class BasicComboPopup extends JPopupMenu implements ComboPopup
{
protected ListSelectionHandler()
{
+ // Nothing to do here.
}
public void valueChanged(ListSelectionEvent e)
{
+ // Nothing to do here.
}
}
@@ -1046,10 +1066,12 @@ public class BasicComboPopup extends JPopupMenu implements ComboPopup
{
public InvocationKeyHandler()
{
+ // Nothing to do here.
}
public void keyReleased(KeyEvent e)
{
+ // Nothing to do here.
}
}
}
diff --git a/javax/swing/plaf/basic/BasicDesktopIconUI.java b/javax/swing/plaf/basic/BasicDesktopIconUI.java
index 561b497f1..3f8730249 100644
--- a/javax/swing/plaf/basic/BasicDesktopIconUI.java
+++ b/javax/swing/plaf/basic/BasicDesktopIconUI.java
@@ -365,6 +365,7 @@ public class BasicDesktopIconUI extends DesktopIconUI
*/
public BasicDesktopIconUI()
{
+ // Nothing to do here.
}
/**
@@ -585,6 +586,7 @@ public class BasicDesktopIconUI extends DesktopIconUI
}
catch (PropertyVetoException pve)
{
+ // We do nothing if the attempt has been vetoed.
}
}
}
diff --git a/javax/swing/plaf/basic/BasicDesktopPaneUI.java b/javax/swing/plaf/basic/BasicDesktopPaneUI.java
index b59261b17..4116858da 100644
--- a/javax/swing/plaf/basic/BasicDesktopPaneUI.java
+++ b/javax/swing/plaf/basic/BasicDesktopPaneUI.java
@@ -38,6 +38,7 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.beans.PropertyVetoException;
@@ -49,10 +50,10 @@ import javax.swing.JComponent;
import javax.swing.JDesktopPane;
import javax.swing.JInternalFrame;
import javax.swing.KeyStroke;
-import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.DesktopPaneUI;
+import javax.swing.plaf.UIResource;
/**
* This class is the UI delegate for JDesktopPane for the Basic look and feel.
@@ -74,13 +75,14 @@ public class BasicDesktopPaneUI extends DesktopPaneUI
{
if (desktop.getSelectedFrame() != null)
{
- try
- {
- desktop.getSelectedFrame().setClosed(true);
- }
- catch (PropertyVetoException pve)
- {
- }
+ try
+ {
+ desktop.getSelectedFrame().setClosed(true);
+ }
+ catch (PropertyVetoException pve)
+ {
+ // We do nothing if the attempts has been vetoed.
+ }
}
}
@@ -112,13 +114,14 @@ public class BasicDesktopPaneUI extends DesktopPaneUI
{
if (desktop.getSelectedFrame() != null)
{
- try
- {
- desktop.getSelectedFrame().setMaximum(true);
- }
- catch (PropertyVetoException pve)
- {
- }
+ try
+ {
+ desktop.getSelectedFrame().setMaximum(true);
+ }
+ catch (PropertyVetoException pve)
+ {
+ // We do nothing if the attempts has been vetoed.
+ }
}
}
@@ -150,13 +153,14 @@ public class BasicDesktopPaneUI extends DesktopPaneUI
{
if (desktop.getSelectedFrame() != null)
{
- try
- {
- desktop.getSelectedFrame().setIcon(true);
- }
- catch (PropertyVetoException pve)
- {
- }
+ try
+ {
+ desktop.getSelectedFrame().setIcon(true);
+ }
+ catch (PropertyVetoException pve)
+ {
+ // We do nothing if the attempt has been vetoed.
+ }
}
}
@@ -236,16 +240,17 @@ public class BasicDesktopPaneUI extends DesktopPaneUI
JInternalFrame frame = desktop.getSelectedFrame();
if (frame != null)
{
- try
- {
- if (frame.isIcon())
- frame.setIcon(false);
- else if (frame.isMaximum())
- frame.setMaximum(false);
- }
- catch (PropertyVetoException pve)
- {
- }
+ try
+ {
+ if (frame.isIcon())
+ frame.setIcon(false);
+ else if (frame.isMaximum())
+ frame.setMaximum(false);
+ }
+ catch (PropertyVetoException pve)
+ {
+ // We do nothing if the attempt has been vetoed.
+ }
}
}
@@ -304,6 +309,7 @@ public class BasicDesktopPaneUI extends DesktopPaneUI
*/
public BasicDesktopPaneUI()
{
+ // Nothing to do here.
}
/**
@@ -361,9 +367,9 @@ public class BasicDesktopPaneUI extends DesktopPaneUI
*/
protected void installDefaults()
{
- UIDefaults defaults = UIManager.getLookAndFeelDefaults();
-
- desktop.setBackground(defaults.getColor("desktop"));
+ Color bg = desktop.getBackground();
+ if (bg == null || bg instanceof UIResource)
+ desktop.setBackground(UIManager.getColor("desktop"));
}
/**
@@ -381,7 +387,7 @@ public class BasicDesktopPaneUI extends DesktopPaneUI
protected void installKeyboardActions()
{
// FIXME: create actions and keystrokes.
- registerKeyboardAction();
+ registerKeyboardActions();
}
/**
@@ -405,7 +411,7 @@ public class BasicDesktopPaneUI extends DesktopPaneUI
* This method registers the actions to the appropriate Action and Input
* maps.
*/
- protected void registerKeyboardAction()
+ protected void registerKeyboardActions()
{
// FIXME: Do the binding.
// XXX: the gtk windows tend to intercept a lot of the
diff --git a/javax/swing/plaf/basic/BasicFileChooserUI.java b/javax/swing/plaf/basic/BasicFileChooserUI.java
index 49013e199..9c6396565 100644
--- a/javax/swing/plaf/basic/BasicFileChooserUI.java
+++ b/javax/swing/plaf/basic/BasicFileChooserUI.java
@@ -48,7 +48,6 @@ import java.awt.Point;
import java.awt.Polygon;
import java.awt.Window;
import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
@@ -60,9 +59,9 @@ import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Hashtable;
+
import javax.swing.AbstractAction;
import javax.swing.Action;
-import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.Icon;
import javax.swing.JButton;
@@ -92,25 +91,31 @@ import javax.swing.plaf.FileChooserUI;
/**
- * DOCUMENT ME!
+ * A UI delegate for the {@link JFileChooser} component under the
+ * {@link BasicLookAndFeel}.
*/
public class BasicFileChooserUI extends FileChooserUI
{
/**
- * DOCUMENT ME!
+ * A file filter that accepts all files.
*/
protected class AcceptAllFileFilter extends FileFilter
{
+ /**
+ * Creates a new instance.
+ */
public AcceptAllFileFilter()
{
+ // Nothing to do here.
}
/**
- * DOCUMENT ME!
+ * Returns <code>true</code> always, as all files are accepted by this
+ * filter.
*
- * @param f DOCUMENT ME!
+ * @param f the file.
*
- * @return DOCUMENT ME!
+ * @return Always <code>true</code>.
*/
public boolean accept(File f)
{
@@ -118,9 +123,9 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Returns a description for this filter.
*
- * @return DOCUMENT ME!
+ * @return A description for the file filter.
*/
public String getDescription()
{
@@ -129,7 +134,9 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Handles a user action to approve the dialog selection.
+ *
+ * @see BasicFileChooserUI#getApproveSelectionAction()
*/
protected class ApproveSelectionAction extends AbstractAction
{
@@ -138,13 +145,13 @@ public class BasicFileChooserUI extends FileChooserUI
*/
protected ApproveSelectionAction()
{
+ // Nothing to do here.
}
/**
- * DOCUMENT ME!
+ * Sets the current selection and closes the dialog.
*
- * @param e
- * DOCUMENT ME!
+ * @param e the action event.
*/
public void actionPerformed(ActionEvent e)
{
@@ -167,22 +174,26 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Provides presentation information about files and directories.
*/
protected class BasicFileView extends FileView
{
- /** DOCUMENT ME! */
+ /** Storage for cached icons. */
protected Hashtable iconCache = new Hashtable();
+ /**
+ * Creates a new instance.
+ */
public BasicFileView()
{
+ // Nothing to do here.
}
/**
- * DOCUMENT ME!
+ * Adds an icon to the cache, associating it with the given file/directory.
*
- * @param f DOCUMENT ME!
- * @param i DOCUMENT ME!
+ * @param f the file/directory.
+ * @param i the icon.
*/
public void cacheIcon(File f, Icon i)
{
@@ -190,7 +201,7 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Clears the icon cache.
*/
public void clearIconCache()
{
@@ -198,11 +209,12 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Retrieves the icon associated with the specified file/directory, if
+ * there is one.
*
- * @param f DOCUMENT ME!
+ * @param f the file/directory.
*
- * @return DOCUMENT ME!
+ * @return The cached icon (or <code>null</code>).
*/
public Icon getCachedIcon(File f)
{
@@ -210,11 +222,13 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Returns a description of the given file/directory. In this
+ * implementation, the description is the same as the name returned by
+ * {@link #getName(File)}.
*
- * @param f DOCUMENT ME!
+ * @param f the file/directory.
*
- * @return DOCUMENT ME!
+ * @return A description of the given file/directory.
*/
public String getDescription(File f)
{
@@ -222,11 +236,11 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Returns an icon appropriate for the given file or directory.
*
- * @param f DOCUMENT ME!
+ * @param f the file/directory.
*
- * @return DOCUMENT ME!
+ * @return An icon.
*/
public Icon getIcon(File f)
{
@@ -242,11 +256,11 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Returns the name for the given file/directory.
*
- * @param f DOCUMENT ME!
+ * @param f the file/directory.
*
- * @return DOCUMENT ME!
+ * @return The name of the file/directory.
*/
public String getName(File f)
{
@@ -254,11 +268,11 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Returns a localised description for the type of file/directory.
*
- * @param f DOCUMENT ME!
+ * @param f the file/directory.
*
- * @return DOCUMENT ME!
+ * @return A type description for the given file/directory.
*/
public String getTypeDescription(File f)
{
@@ -269,11 +283,12 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Returns {@link Boolean#TRUE} if the given file/directory is hidden,
+ * and {@link Boolean#FALSE} otherwise.
*
- * @param f DOCUMENT ME!
+ * @param f the file/directory.
*
- * @return DOCUMENT ME!
+ * @return {@link Boolean#TRUE} or {@link Boolean#FALSE}.
*/
public Boolean isHidden(File f)
{
@@ -282,21 +297,24 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Handles an action to cancel the file chooser.
+ *
+ * @see BasicFileChooserUI#getCancelSelectionAction()
*/
protected class CancelSelectionAction extends AbstractAction
{
/**
- * Creates a new CancelSelectionAction object.
+ * Creates a new <code>CancelSelectionAction</code> object.
*/
protected CancelSelectionAction()
{
+ // Nothing to do here.
}
/**
- * DOCUMENT ME!
+ * Cancels the selection and closes the dialog.
*
- * @param e DOCUMENT ME!
+ * @param e the action event (ignored).
*/
public void actionPerformed(ActionEvent e)
{
@@ -306,21 +324,25 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * An action to handle changes to the parent directory (for example, via
+ * a click on the "up folder" button).
+ *
+ * @see BasicFileChooserUI#getChangeToParentDirectoryAction()
*/
protected class ChangeToParentDirectoryAction extends AbstractAction
{
/**
- * Creates a new ChangeToParentDirectoryAction object.
+ * Creates a new <code>ChangeToParentDirectoryAction</code> object.
*/
protected ChangeToParentDirectoryAction()
{
+ // Nothing to do here.
}
/**
- * DOCUMENT ME!
+ * Handles the action event.
*
- * @param e DOCUMENT ME!
+ * @param e the action event.
*/
public void actionPerformed(ActionEvent e)
{
@@ -331,11 +353,13 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * A mouse listener that handles double-click events.
+ *
+ * @see BasicFileChooserUI#createDoubleClickListener(JFileChooser, JList)
*/
protected class DoubleClickListener extends MouseAdapter
{
- /** DOCUMENT ME! */
+ /** A timer. */
private Timer timer = null;
/** DOCUMENT ME! */
@@ -359,10 +383,9 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Handles a mouse click event.
*
- * @param e
- * DOCUMENT ME!
+ * @param e the event.
*/
public void mouseClicked(MouseEvent e)
{
@@ -408,10 +431,9 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Handles a mouse entered event (NOT IMPLEMENTED).
*
- * @param e
- * DOCUMENT ME!
+ * @param e the mouse event.
*/
public void mouseEntered(MouseEvent e)
{
@@ -420,21 +442,26 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * An action that changes the file chooser to display the user's home
+ * directory.
+ *
+ * @see BasicFileChooserUI#getGoHomeAction()
*/
protected class GoHomeAction extends AbstractAction
{
/**
- * Creates a new GoHomeAction object.
+ * Creates a new <code>GoHomeAction</code> object.
*/
protected GoHomeAction()
{
+ // Nothing to do here.
}
/**
- * DOCUMENT ME!
+ * Sets the directory to the user's home directory, and repaints the
+ * file chooser component.
*
- * @param e DOCUMENT ME!
+ * @param e the action event (ignored).
*/
public void actionPerformed(ActionEvent e)
{
@@ -446,21 +473,24 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * An action that handles the creation of a new folder/directory.
+ *
+ * @see BasicFileChooserUI#getNewFolderAction()
*/
protected class NewFolderAction extends AbstractAction
{
/**
- * Creates a new NewFolderAction object.
+ * Creates a new <code>NewFolderAction</code> object.
*/
protected NewFolderAction()
{
+ // Nothing to do here.
}
/**
- * DOCUMENT ME!
+ * Handles the event by creating a new folder.
*
- * @param e DOCUMENT ME!
+ * @param e the action event (ignored).
*/
public void actionPerformed(ActionEvent e)
{
@@ -479,15 +509,18 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * A listener for selection events in the file list.
+ *
+ * @see BasicFileChooserUI#createListSelectionListener(JFileChooser)
*/
protected class SelectionListener implements ListSelectionListener
{
/**
- * Creates a new SelectionListener object.
+ * Creates a new <code>SelectionListener</code> object.
*/
protected SelectionListener()
{
+ // Nothing to do here.
}
/**
@@ -510,6 +543,8 @@ public class BasicFileChooserUI extends FileChooserUI
/**
* DOCUMENT ME!
+ *
+ * @see BasicFileChooserUI#getUpdateAction()
*/
protected class UpdateAction extends AbstractAction
{
@@ -518,28 +553,30 @@ public class BasicFileChooserUI extends FileChooserUI
*/
protected UpdateAction()
{
+ // Nothing to do here.
}
/**
- * DOCUMENT ME!
+ * NOT YET IMPLEMENTED.
*
- * @param e DOCUMENT ME!
+ * @param e the action event.
*/
public void actionPerformed(ActionEvent e)
{
+ // FIXME: implement this
}
}
- /** DOCUMENT ME! */
+ /** The localised mnemonic for the cancel button. */
protected int cancelButtonMnemonic;
- /** DOCUMENT ME! */
+ /** The localised text for the cancel button. */
protected String cancelButtonText;
- /** DOCUMENT ME! */
+ /** The localised tool tip text for the cancel button. */
protected String cancelButtonToolTipText;
- /** DOCUMENT ME! */
+ /** An icon representing a computer. */
protected Icon computerIcon = new Icon()
{
public int getIconHeight()
@@ -554,10 +591,11 @@ public class BasicFileChooserUI extends FileChooserUI
public void paintIcon(Component c, Graphics g, int x, int y)
{
+ // FIXME: is this not implemented, or is the icon intentionally blank?
}
};
- /** DOCUMENT ME! */
+ /** An icon for the "details view" button. */
protected Icon detailsViewIcon = new Icon()
{
public int getIconHeight()
@@ -586,7 +624,7 @@ public class BasicFileChooserUI extends FileChooserUI
}
};
- /** DOCUMENT ME! */
+ /** An icon representing a directory. */
protected Icon directoryIcon = new Icon()
{
public int getIconHeight()
@@ -625,16 +663,16 @@ public class BasicFileChooserUI extends FileChooserUI
}
};
- /** DOCUMENT ME! */
+ /** The localised Mnemonic for the open button. */
protected int directoryOpenButtonMnemonic;
- /** DOCUMENT ME! */
+ /** The localised text for the open button. */
protected String directoryOpenButtonText;
- /** DOCUMENT ME! */
+ /** The localised tool tip text for the open button. */
protected String directoryOpenButtonToolTipText;
- /** DOCUMENT ME! */
+ /** An icon representing a file. */
protected Icon fileIcon = new Icon()
{
public int getIconHeight()
@@ -674,7 +712,7 @@ public class BasicFileChooserUI extends FileChooserUI
}
};
- /** DOCUMENT ME! */
+ /** An icon representing a floppy drive. */
protected Icon floppyDriveIcon = new Icon()
{
public int getIconHeight()
@@ -689,10 +727,11 @@ public class BasicFileChooserUI extends FileChooserUI
public void paintIcon(Component c, Graphics g, int x, int y)
{
+ // FIXME: is this not implemented, or is the icon intentionally blank?
}
};
- /** DOCUMENT ME! */
+ /** An icon representing a hard drive. */
protected Icon hardDriveIcon = new Icon()
{
public int getIconHeight()
@@ -707,19 +746,20 @@ public class BasicFileChooserUI extends FileChooserUI
public void paintIcon(Component c, Graphics g, int x, int y)
{
+ // FIXME: is this not implemented, or is the icon intentionally blank?
}
};
- /** DOCUMENT ME! */
+ /** The localised mnemonic for the "help" button. */
protected int helpButtonMnemonic;
- /** DOCUMENT ME! */
+ /** The localised text for the "help" button. */
protected String helpButtonText;
- /** DOCUMENT ME! */
+ /** The localised tool tip text for the help button. */
protected String helpButtonToolTipText;
- /** DOCUMENT ME! */
+ /** An icon representing the user's home folder. */
protected Icon homeFolderIcon = new Icon()
{
public int getIconHeight()
@@ -759,7 +799,7 @@ public class BasicFileChooserUI extends FileChooserUI
}
};
- /** DOCUMENT ME! */
+ /** An icon for the "list view" button. */
protected Icon listViewIcon = new Icon()
{
public int getIconHeight()
@@ -801,37 +841,37 @@ public class BasicFileChooserUI extends FileChooserUI
}
};
- /** DOCUMENT ME! */
+ /** An icon for the "new folder" button. */
protected Icon newFolderIcon = directoryIcon;
- /** DOCUMENT ME! */
+ /** The localised mnemonic for the "open" button. */
protected int openButtonMnemonic;
- /** DOCUMENT ME! */
+ /** The localised text for the "open" button. */
protected String openButtonText;
- /** DOCUMENT ME! */
+ /** The localised tool tip text for the "open" button. */
protected String openButtonToolTipText;
- /** DOCUMENT ME! */
+ /** The localised mnemonic for the "save" button. */
protected int saveButtonMnemonic;
- /** DOCUMENT ME! */
+ /** The localised text for the "save" button. */
protected String saveButtonText;
- /** DOCUMENT ME! */
+ /** The localised tool tip text for the save button. */
protected String saveButtonToolTipText;
- /** DOCUMENT ME! */
+ /** The localised mnemonic for the "update" button. */
protected int updateButtonMnemonic;
- /** DOCUMENT ME! */
+ /** The localised text for the "update" button. */
protected String updateButtonText;
- /** DOCUMENT ME! */
+ /** The localised tool tip text for the "update" button. */
protected String updateButtonToolTipText;
- /** DOCUMENT ME! */
+ /** An icon for the "up folder" button. */
protected Icon upFolderIcon = new Icon()
{
public int getIconHeight()
@@ -882,71 +922,74 @@ public class BasicFileChooserUI extends FileChooserUI
// -- begin private, but package local since used in inner classes --
+ /** The file chooser component represented by this UI delegate. */
JFileChooser filechooser;
- /** DOCUMENT ME! */
+ /** The file list. */
JList filelist;
- /** DOCUMENT ME! */
+ /** The combo box used to display/select file filters. */
JComboBox filters;
- /** DOCUMENT ME! */
+ /** The model for the directory list. */
BasicDirectoryModel model;
- /** DOCUMENT ME! */
+ /** The file filter for all files. */
FileFilter acceptAll = new AcceptAllFileFilter();
- /** DOCUMENT ME! */
+ /** The default file view. */
FileView fv = new BasicFileView();
- /** DOCUMENT ME! */
+ /** The icon size. */
static final int ICON_SIZE = 24;
- /** DOCUMENT ME! */
+ /** A combo box for display/selection of parent directories. */
JComboBox parents;
- /** DOCUMENT ME! */
+ /** The current file name. */
String filename;
- /** DOCUMENT ME! */
+ /** The accept (open/save) button. */
JButton accept;
- /** DOCUMENT ME! */
+ /** The cancel button. */
JButton cancel;
- /** DOCUMENT ME! */
+ /** The button to move up to the parent directory. */
JButton upFolderButton;
- /** DOCUMENT ME! */
+ /** The button to create a new directory. */
JButton newFolderButton;
- /** DOCUMENT ME! */
+ /** The button to move to the user's home directory. */
JButton homeFolderButton;
- /** DOCUMENT ME! */
+ /** An optional accessory panel. */
JPanel accessoryPanel;
- /** DOCUMENT ME! */
+ /** A property change listener. */
PropertyChangeListener propertyChangeListener;
- /** DOCUMENT ME! */
+ /** The text describing the filter for "all files". */
String acceptAllFileFilterText;
- /** DOCUMENT ME! */
+ /** The text describing a directory type. */
String dirDescText;
- /** DOCUMENT ME! */
+ /** The text describing a file type. */
String fileDescText;
- /** DOCUMENT ME! */
+ /** Is a directory selected? */
boolean dirSelected = false;
- /** DOCUMENT ME! */
+ /** The current directory. */
File currDir = null;
+ // FIXME: describe what is contained in the bottom panel
+ /** The bottom panel. */
JPanel bottomPanel;
- /** DOCUMENT ME! */
+ /** The close panel. */
JPanel closePanel;
/** Text box that displays file name */
@@ -997,6 +1040,9 @@ public class BasicFileChooserUI extends FileChooserUI
}
}
+ /**
+ * Closes the dialog.
+ */
void closeDialog()
{
Window owner = SwingUtilities.windowForComponent(filechooser);
@@ -1005,9 +1051,9 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * Creates a new BasicFileChooserUI object.
+ * Creates a new <code>BasicFileChooserUI</code> object.
*
- * @param b DOCUMENT ME!
+ * @param b the file chooser component.
*/
public BasicFileChooserUI(JFileChooser b)
{
@@ -1015,11 +1061,11 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Returns a UI delegate for the given component.
*
- * @param c DOCUMENT ME!
+ * @param c the component (should be a {@link JFileChooser}).
*
- * @return DOCUMENT ME!
+ * @return A new UI delegate.
*/
public static ComponentUI createUI(JComponent c)
{
@@ -1027,10 +1073,9 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Installs the UI for the specified component.
*
- * @param c
- * DOCUMENT ME!
+ * @param c the component (should be a {@link JFileChooser}).
*/
public void installUI(JComponent c)
{
@@ -1051,10 +1096,9 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Uninstalls this UI from the given component.
*
- * @param c
- * DOCUMENT ME!
+ * @param c the component (should be a {@link JFileChooser}).
*/
public void uninstallUI(JComponent c)
{
@@ -1161,9 +1205,9 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Creates and install the subcomponents for the file chooser.
*
- * @param fc DOCUMENT ME!
+ * @param fc the file chooser.
*/
public void installComponents(JFileChooser fc)
{
@@ -1285,9 +1329,9 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Uninstalls the components from the file chooser.
*
- * @param fc DOCUMENT ME!
+ * @param fc the file chooser.
*/
public void uninstallComponents(JFileChooser fc)
{
@@ -1303,9 +1347,9 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Installs the listeners required by this UI delegate.
*
- * @param fc DOCUMENT ME!
+ * @param fc the file chooser.
*/
protected void installListeners(JFileChooser fc)
{
@@ -1325,9 +1369,9 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Uninstalls the listeners previously installed by this UI delegate.
*
- * @param fc DOCUMENT ME!
+ * @param fc the file chooser.
*/
protected void uninstallListeners(JFileChooser fc)
{
@@ -1336,9 +1380,9 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Installs the defaults for this UI delegate.
*
- * @param fc DOCUMENT ME!
+ * @param fc the file chooser.
*/
protected void installDefaults(JFileChooser fc)
{
@@ -1347,9 +1391,9 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Uninstalls the defaults previously added by this UI delegate.
*
- * @param fc DOCUMENT ME!
+ * @param fc the file chooser.
*/
protected void uninstallDefaults(JFileChooser fc)
{
@@ -1358,9 +1402,9 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Installs the icons for this UI delegate (NOT YET IMPLEMENTED).
*
- * @param fc DOCUMENT ME!
+ * @param fc the file chooser.
*/
protected void installIcons(JFileChooser fc)
{
@@ -1368,9 +1412,10 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Uninstalls the icons previously added by this UI delegate (NOT YET
+ * IMPLEMENTED).
*
- * @param fc DOCUMENT ME!
+ * @param fc the file chooser.
*/
protected void uninstallIcons(JFileChooser fc)
{
@@ -1378,9 +1423,9 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Installs the strings used by this UI delegate.
*
- * @param fc DOCUMENT ME!
+ * @param fc the file chooser.
*/
protected void installStrings(JFileChooser fc)
{
@@ -1408,9 +1453,9 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Uninstalls the strings previously added by this UI delegate.
*
- * @param fc DOCUMENT ME!
+ * @param fc the file chooser.
*/
protected void uninstallStrings(JFileChooser fc)
{
@@ -1436,7 +1481,7 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Creates a new directory model.
*/
protected void createModel()
{
@@ -1444,9 +1489,9 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Returns the directory model.
*
- * @return DOCUMENT ME!
+ * @return The directory model.
*/
public BasicDirectoryModel getModel()
{
@@ -1454,11 +1499,12 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Creates a listener to handle changes to the properties of the given
+ * file chooser component.
*
- * @param fc
- * DOCUMENT ME!
- * @return DOCUMENT ME!
+ * @param fc the file chooser component.
+ *
+ * @return A new listener.
*/
public PropertyChangeListener createPropertyChangeListener(JFileChooser fc)
{
@@ -1575,9 +1621,9 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Returns the current file name.
*
- * @return DOCUMENT ME!
+ * @return The current file name.
*/
public String getFileName()
{
@@ -1585,9 +1631,11 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Returns the current directory name.
*
- * @return DOCUMENT ME!
+ * @return The directory name.
+ *
+ * @see #setDirectoryName(String)
*/
public String getDirectoryName()
{
@@ -1596,9 +1644,11 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Sets the file name.
*
- * @param filename DOCUMENT ME!
+ * @param filename the file name.
+ *
+ * @see #getFileName()
*/
public void setFileName(String filename)
{
@@ -1606,9 +1656,11 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Sets the directory name (NOT IMPLEMENTED).
*
- * @param dirname DOCUMENT ME!
+ * @param dirname the directory name.
+ *
+ * @see #getDirectoryName()
*/
public void setDirectoryName(String dirname)
{
@@ -1616,9 +1668,9 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Rescans the current directory.
*
- * @param fc DOCUMENT ME!
+ * @param fc the file chooser.
*/
public void rescanCurrentDirectory(JFileChooser fc)
{
@@ -1627,10 +1679,10 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * NOT YET IMPLEMENTED.
*
- * @param fc DOCUMENT ME!
- * @param f DOCUMENT ME!
+ * @param fc the file chooser.
+ * @param f the file.
*/
public void ensureFileIsVisible(JFileChooser fc, File f)
{
@@ -1638,9 +1690,10 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Returns the {@link JFileChooser} component that this UI delegate
+ * represents.
*
- * @return DOCUMENT ME!
+ * @return The component represented by this UI delegate.
*/
public JFileChooser getFileChooser()
{
@@ -1648,9 +1701,9 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Returns the optional accessory panel.
*
- * @return DOCUMENT ME!
+ * @return The optional accessory panel.
*/
public JPanel getAccessoryPanel()
{
@@ -1658,11 +1711,11 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Creates and returns an approve (open or save) button for the dialog.
*
- * @param fc DOCUMENT ME!
+ * @param fc the file chooser.
*
- * @return DOCUMENT ME!
+ * @return The button.
*/
public JButton getApproveButton(JFileChooser fc)
{
@@ -1673,11 +1726,14 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Returns the tool tip text for the approve (open/save) button. This first
+ * checks the file chooser to see if a value has been explicitly set - if
+ * not, a default value appropriate for the type of file chooser is
+ * returned.
*
- * @param fc DOCUMENT ME!
+ * @param fc the file chooser.
*
- * @return DOCUMENT ME!
+ * @return The tool tip text.
*/
public String getApproveButtonToolTipText(JFileChooser fc)
{
@@ -1690,7 +1746,7 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Clears the icon cache.
*/
public void clearIconCache()
{
@@ -1699,11 +1755,11 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Creates a new listener to handle selections in the file list.
*
- * @param fc DOCUMENT ME!
+ * @param fc the file chooser component.
*
- * @return DOCUMENT ME!
+ * @return A new instance of {@link SelectionListener}.
*/
public ListSelectionListener createListSelectionListener(JFileChooser fc)
{
@@ -1711,12 +1767,12 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Creates a new listener to handle double-click events.
*
- * @param fc DOCUMENT ME!
- * @param list DOCUMENT ME!
+ * @param fc the file chooser component.
+ * @param list the list.
*
- * @return DOCUMENT ME!
+ * @return A new instance of {@link DoubleClickListener}.
*/
protected MouseListener createDoubleClickListener(JFileChooser fc, JList list)
{
@@ -1724,9 +1780,10 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Returns <code>true</code> if a directory is selected, and
+ * <code>false</code> otherwise.
*
- * @return DOCUMENT ME!
+ * @return A boolean.
*/
protected boolean isDirectorySelected()
{
@@ -1734,9 +1791,9 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Sets the flag that indicates whether the current directory is selected.
*
- * @param selected DOCUMENT ME!
+ * @param selected the new flag value.
*/
protected void setDirectorySelected(boolean selected)
{
@@ -1744,9 +1801,9 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Returns the current directory.
*
- * @return DOCUMENT ME!
+ * @return The current directory.
*/
protected File getDirectory()
{
@@ -1754,9 +1811,9 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Sets the current directory.
*
- * @param f DOCUMENT ME!
+ * @param f the directory.
*/
protected void setDirectory(File f)
{
@@ -1764,11 +1821,11 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Returns the "accept all" file filter.
*
- * @param fc DOCUMENT ME!
+ * @param fc the file chooser component.
*
- * @return DOCUMENT ME!
+ * @return The "accept all" file filter.
*/
public FileFilter getAcceptAllFileFilter(JFileChooser fc)
{
@@ -1776,25 +1833,29 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Returns the file view for the file chooser. This returns either the
+ * file view that has been explicitly set for the {@link JFileChooser}, or
+ * a default file view.
*
- * @param fc DOCUMENT ME!
+ * @param fc the file chooser component.
*
- * @return DOCUMENT ME!
+ * @return The file view.
+ *
+ * @see JFileChooser#getFileView()
*/
public FileView getFileView(JFileChooser fc)
{
- if (fc.getFileView() != null)
- return fc.getFileView();
return fv;
}
/**
- * DOCUMENT ME!
+ * Returns the dialog title.
*
- * @param fc DOCUMENT ME!
+ * @param fc the file chooser (<code>null</code> not permitted).
*
- * @return DOCUMENT ME!
+ * @return The dialog title.
+ *
+ * @see JFileChooser#getDialogTitle()
*/
public String getDialogTitle(JFileChooser fc)
{
@@ -1819,11 +1880,13 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Returns the approve button mnemonic.
*
- * @param fc DOCUMENT ME!
+ * @param fc the file chooser (<code>null</code> not permitted).
*
- * @return DOCUMENT ME!
+ * @return The approve button mnemonic.
+ *
+ * @see JFileChooser#getApproveButtonMnemonic()
*/
public int getApproveButtonMnemonic(JFileChooser fc)
{
@@ -1836,11 +1899,13 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Returns the approve button text.
*
- * @param fc DOCUMENT ME!
+ * @param fc the file chooser (<code>null</code> not permitted).
*
- * @return DOCUMENT ME!
+ * @return The approve button text.
+ *
+ * @see JFileChooser#getApproveButtonText()
*/
public String getApproveButtonText(JFileChooser fc)
{
@@ -1853,9 +1918,10 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Creates and returns a new action that will be used with the "new folder"
+ * button.
*
- * @return DOCUMENT ME!
+ * @return A new instance of {@link GoHomeAction}.
*/
public Action getNewFolderAction()
{
@@ -1863,9 +1929,10 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Creates and returns a new action that will be used with the "home folder"
+ * button.
*
- * @return DOCUMENT ME!
+ * @return A new instance of {@link GoHomeAction}.
*/
public Action getGoHomeAction()
{
@@ -1873,9 +1940,10 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Creates and returns a new action that will be used with the "up folder"
+ * button.
*
- * @return DOCUMENT ME!
+ * @return A new instance of {@link ChangeToParentDirectoryAction}.
*/
public Action getChangeToParentDirectoryAction()
{
@@ -1883,9 +1951,10 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Creates and returns a new action that will be used with the "approve"
+ * button.
*
- * @return DOCUMENT ME!
+ * @return A new instance of {@link ApproveSelectionAction}.
*/
public Action getApproveSelectionAction()
{
@@ -1893,9 +1962,10 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Creates and returns a new action that will be used with the "cancel"
+ * button.
*
- * @return DOCUMENT ME!
+ * @return A new instance of {@link CancelSelectionAction}.
*/
public Action getCancelSelectionAction()
{
@@ -1903,9 +1973,9 @@ public class BasicFileChooserUI extends FileChooserUI
}
/**
- * DOCUMENT ME!
+ * Creates and returns a new instance of {@link UpdateAction}.
*
- * @return DOCUMENT ME!
+ * @return An action.
*/
public Action getUpdateAction()
{
diff --git a/javax/swing/plaf/basic/BasicFormattedTextFieldUI.java b/javax/swing/plaf/basic/BasicFormattedTextFieldUI.java
index efef5d6d7..9c7f1c4c5 100644
--- a/javax/swing/plaf/basic/BasicFormattedTextFieldUI.java
+++ b/javax/swing/plaf/basic/BasicFormattedTextFieldUI.java
@@ -49,6 +49,7 @@ public class BasicFormattedTextFieldUI extends BasicTextFieldUI
{
public BasicFormattedTextFieldUI()
{
+ // Nothing to do here.
}
public static ComponentUI createUI(JComponent c)
diff --git a/javax/swing/plaf/basic/BasicGraphicsUtils.java b/javax/swing/plaf/basic/BasicGraphicsUtils.java
index 757ac47c9..068de345b 100644
--- a/javax/swing/plaf/basic/BasicGraphicsUtils.java
+++ b/javax/swing/plaf/basic/BasicGraphicsUtils.java
@@ -71,6 +71,7 @@ public class BasicGraphicsUtils
*/
public BasicGraphicsUtils()
{
+ // Nothing to do here.
}
diff --git a/javax/swing/plaf/basic/BasicIconFactory.java b/javax/swing/plaf/basic/BasicIconFactory.java
index 56a67b029..6debd6495 100644
--- a/javax/swing/plaf/basic/BasicIconFactory.java
+++ b/javax/swing/plaf/basic/BasicIconFactory.java
@@ -41,7 +41,6 @@ package javax.swing.plaf.basic;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
-import java.awt.Polygon;
import java.io.Serializable;
import javax.swing.Icon;
@@ -241,34 +240,33 @@ public class BasicIconFactory implements Serializable
{
return new DummyIcon();
}
+
+ /**
+ * Returns a new instance of a 4 x 8 icon showing a small black triangle that
+ * points to the right. This is displayed in menu items that have a
+ * sub menu.
+ *
+ * @return The icon.
+ */
public static Icon getMenuArrowIcon()
{
return new Icon()
{
public int getIconHeight()
{
- return 12;
+ return 8;
}
-
public int getIconWidth()
{
- return 12;
+ return 4;
}
-
public void paintIcon(Component c, Graphics g, int x, int y)
{
- g.translate(x, y);
-
Color saved = g.getColor();
-
g.setColor(Color.BLACK);
-
- g.fillPolygon(new Polygon(new int[] { 3, 9, 3 },
- new int[] { 2, 6, 10 },
- 3));
-
+ for (int i = 0; i < 4; i++)
+ g.drawLine(x + i, y + i, x + i, y + 7 - i);
g.setColor(saved);
- g.translate(-x, -y);
}
};
}
diff --git a/javax/swing/plaf/basic/BasicInternalFrameTitlePane.java b/javax/swing/plaf/basic/BasicInternalFrameTitlePane.java
index eded1c7fa..aced2769a 100644
--- a/javax/swing/plaf/basic/BasicInternalFrameTitlePane.java
+++ b/javax/swing/plaf/basic/BasicInternalFrameTitlePane.java
@@ -100,13 +100,14 @@ public class BasicInternalFrameTitlePane extends JComponent
{
if (frame.isClosable())
{
- try
- {
- frame.setClosed(true);
- }
- catch (PropertyVetoException pve)
- {
- }
+ try
+ {
+ frame.setClosed(true);
+ }
+ catch (PropertyVetoException pve)
+ {
+ // We do nothing if the attempt has been vetoed.
+ }
}
}
}
@@ -138,13 +139,14 @@ public class BasicInternalFrameTitlePane extends JComponent
{
if (frame.isIconifiable() && ! frame.isIcon())
{
- try
- {
- frame.setIcon(true);
- }
- catch (PropertyVetoException pve)
- {
- }
+ try
+ {
+ frame.setIcon(true);
+ }
+ catch (PropertyVetoException pve)
+ {
+ // We do nothing if the attempt has been vetoed.
+ }
}
}
}
@@ -175,13 +177,14 @@ public class BasicInternalFrameTitlePane extends JComponent
{
try
{
- if (frame.isMaximizable() && ! frame.isMaximum())
- frame.setMaximum(true);
- else if (frame.isMaximum())
- frame.setMaximum(false);
+ if (frame.isMaximizable() && ! frame.isMaximum())
+ frame.setMaximum(true);
+ else if (frame.isMaximum())
+ frame.setMaximum(false);
}
catch (PropertyVetoException pve)
{
+ // We do nothing if the attempt has been vetoed.
}
}
}
@@ -240,13 +243,14 @@ public class BasicInternalFrameTitlePane extends JComponent
{
if (frame.isMaximum())
{
- try
- {
- frame.setMaximum(false);
- }
- catch (PropertyVetoException pve)
- {
- }
+ try
+ {
+ frame.setMaximum(false);
+ }
+ catch (PropertyVetoException pve)
+ {
+ // We do nothing if the attempt has been vetoed.
+ }
}
}
}
@@ -481,6 +485,7 @@ public class BasicInternalFrameTitlePane extends JComponent
*/
public void removeLayoutComponent(Component c)
{
+ // Nothing to do here.
}
}
diff --git a/javax/swing/plaf/basic/BasicInternalFrameUI.java b/javax/swing/plaf/basic/BasicInternalFrameUI.java
index 5f20fecff..6bc3aace3 100644
--- a/javax/swing/plaf/basic/BasicInternalFrameUI.java
+++ b/javax/swing/plaf/basic/BasicInternalFrameUI.java
@@ -56,20 +56,17 @@ import java.beans.PropertyChangeListener;
import java.beans.PropertyVetoException;
import java.beans.VetoableChangeListener;
-import javax.swing.BorderFactory;
import javax.swing.DefaultDesktopManager;
import javax.swing.DesktopManager;
import javax.swing.JComponent;
import javax.swing.JDesktopPane;
import javax.swing.JInternalFrame;
import javax.swing.KeyStroke;
+import javax.swing.LookAndFeel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
-import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.border.AbstractBorder;
-import javax.swing.border.BevelBorder;
-import javax.swing.border.Border;
import javax.swing.event.InternalFrameEvent;
import javax.swing.event.InternalFrameListener;
import javax.swing.event.MouseInputAdapter;
@@ -448,6 +445,7 @@ public class BasicInternalFrameUI extends InternalFrameUI
*/
public void addLayoutComponent(String name, Component c)
{
+ // Nothing to do here.
}
/**
@@ -637,6 +635,7 @@ public class BasicInternalFrameUI extends InternalFrameUI
*/
public void removeLayoutComponent(Component c)
{
+ // Nothing to do here.
}
}
@@ -950,7 +949,7 @@ public class BasicInternalFrameUI extends InternalFrameUI
if (frame.isSelected())
activateFrame(frame);
else
- getDesktopManager().deactivateFrame(frame);
+ deactivateFrame(frame);
}
else if (evt.getPropertyName().equals(JInternalFrame.ROOT_PANE_PROPERTY)
|| evt.getPropertyName().equals(
@@ -1138,6 +1137,7 @@ public class BasicInternalFrameUI extends InternalFrameUI
*/
public BasicInternalFrameUI(JInternalFrame b)
{
+ // Nothing to do here.
}
/**
@@ -1204,10 +1204,8 @@ public class BasicInternalFrameUI extends InternalFrameUI
*/
protected void installDefaults()
{
- UIDefaults defaults = UIManager.getLookAndFeelDefaults();
- Border border = defaults.getBorder("InternalFrame.border");
- frame.setBorder(border);
- frame.setFrameIcon(defaults.getIcon("InternalFrame.icon"));
+ LookAndFeel.installBorder(frame, "InternalFrame.border");
+ frame.setFrameIcon(UIManager.getIcon("InternalFrame.icon"));
// InternalFrames are invisible by default.
frame.setVisible(false);
}
@@ -1705,6 +1703,16 @@ public class BasicInternalFrameUI extends InternalFrameUI
}
/**
+ * This is a convenience method that deactivates the JInternalFrame.
+ *
+ * @param f the JInternalFrame to deactivate
+ */
+ protected void deactivateFrame(JInternalFrame f)
+ {
+ getDesktopManager().deactivateFrame(f);
+ }
+
+ /**
* This method returns a new ComponentListener for the JDesktopPane.
*
* @return A new ComponentListener.
diff --git a/javax/swing/plaf/basic/BasicLabelUI.java b/javax/swing/plaf/basic/BasicLabelUI.java
index bb9ce6cb1..c8f677fa0 100644
--- a/javax/swing/plaf/basic/BasicLabelUI.java
+++ b/javax/swing/plaf/basic/BasicLabelUI.java
@@ -50,9 +50,8 @@ import java.beans.PropertyChangeListener;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JLabel;
+import javax.swing.LookAndFeel;
import javax.swing.SwingUtilities;
-import javax.swing.UIDefaults;
-import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.LabelUI;
@@ -60,9 +59,7 @@ import javax.swing.plaf.LabelUI;
* This is the Basic Look and Feel class for the JLabel. One BasicLabelUI
* object is used to paint all JLabels that utilize the Basic Look and Feel.
*/
-public class BasicLabelUI
- extends LabelUI
- implements PropertyChangeListener
+public class BasicLabelUI extends LabelUI implements PropertyChangeListener
{
/** The labelUI that is shared by all labels. */
protected static BasicLabelUI labelUI;
@@ -345,11 +342,8 @@ public class BasicLabelUI
*/
protected void installDefaults(JLabel c)
{
- UIDefaults defaults = UIManager.getLookAndFeelDefaults();
-
- c.setForeground(defaults.getColor("Label.foreground"));
- c.setBackground(defaults.getColor("Label.background"));
- c.setFont(defaults.getFont("Label.font"));
+ LookAndFeel.installColorsAndFont(c, "Label.background", "Label.foreground",
+ "Label.font");
//XXX: There are properties we don't use called disabledForeground
//and disabledShadow.
}
@@ -417,8 +411,6 @@ public class BasicLabelUI
*/
public void propertyChange(PropertyChangeEvent e)
{
- JLabel c = (JLabel) e.getSource();
- c.revalidate();
- c.repaint();
+ // What to do here?
}
}
diff --git a/javax/swing/plaf/basic/BasicListUI.java b/javax/swing/plaf/basic/BasicListUI.java
index 841bd670f..1616d5e4f 100644
--- a/javax/swing/plaf/basic/BasicListUI.java
+++ b/javax/swing/plaf/basic/BasicListUI.java
@@ -44,25 +44,31 @@ import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
-import java.awt.event.InputEvent;
-import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
+import javax.swing.AbstractAction;
+import javax.swing.ActionMap;
import javax.swing.CellRendererPane;
+import javax.swing.DefaultListSelectionModel;
+import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JList;
import javax.swing.JViewport;
+import javax.swing.KeyStroke;
import javax.swing.ListCellRenderer;
import javax.swing.ListModel;
import javax.swing.ListSelectionModel;
+import javax.swing.LookAndFeel;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.event.ListDataEvent;
@@ -71,6 +77,7 @@ import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.MouseInputListener;
import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.InputMapUIResource;
import javax.swing.plaf.ListUI;
/**
@@ -125,8 +132,9 @@ public class BasicListUI extends ListUI
* Helper method to repaint the focused cell's
* lost or acquired focus state.
*/
- void repaintCellFocus()
+ protected void repaintCellFocus()
{
+ // TODO: Implement this properly.
}
}
@@ -183,141 +191,228 @@ public class BasicListUI extends ListUI
*/
public void valueChanged(ListSelectionEvent e)
{
+ // TODO: Implement this properly.
}
}
/**
- * A helper class which listens for {@link KeyEvents}s
- * from the {@link JList}.
+ * This class is used to mimmic the behaviour of the JDK when registering
+ * keyboard actions. It is the same as the private class used in JComponent
+ * for the same reason. This class receives an action event and dispatches
+ * it to the true receiver after altering the actionCommand property of the
+ * event.
*/
- private class KeyHandler extends KeyAdapter
+ private static class ActionListenerProxy
+ extends AbstractAction
{
- public KeyHandler()
+ ActionListener target;
+ String bindingCommandName;
+
+ public ActionListenerProxy(ActionListener li,
+ String cmd)
+ {
+ target = li;
+ bindingCommandName = cmd;
+ }
+
+ public void actionPerformed(ActionEvent e)
{
+ ActionEvent derivedEvent = new ActionEvent(e.getSource(),
+ e.getID(),
+ bindingCommandName,
+ e.getModifiers());
+ target.actionPerformed(derivedEvent);
}
-
- public void keyPressed( KeyEvent evt )
+ }
+
+ class ListAction extends AbstractAction
+ {
+ public void actionPerformed (ActionEvent e)
{
- int lead = BasicListUI.this.list.getLeadSelectionIndex();
- int max = BasicListUI.this.list.getModel().getSize() - 1;
+ int lead = list.getLeadSelectionIndex();
+ int max = list.getModel().getSize() - 1;
+ DefaultListSelectionModel selModel = (DefaultListSelectionModel)list.getSelectionModel();
+ String command = e.getActionCommand();
// Do nothing if list is empty
if (max == -1)
return;
-
- // Process the key event. Bindings can be found in
- // javax.swing.plaf.basic.BasicLookAndFeel.java
- if ((evt.getKeyCode() == KeyEvent.VK_DOWN)
- || (evt.getKeyCode() == KeyEvent.VK_KP_DOWN))
+
+ if (command.equals("selectNextRow"))
{
- if (evt.getModifiers() == 0)
- {
- BasicListUI.this.list.clearSelection();
- BasicListUI.this.list.setSelectedIndex(Math.min(lead+1,max));
- }
- else if (evt.getModifiers() == InputEvent.SHIFT_MASK)
+ selectNextIndex();
+ }
+ else if (command.equals("selectPreviousRow"))
+ {
+ selectPreviousIndex();
+ }
+ else if (command.equals("clearSelection"))
+ {
+ list.clearSelection();
+ }
+ else if (command.equals("selectAll"))
+ {
+ list.setSelectionInterval(0, max);
+ // this next line is to restore the lead selection index to the old
+ // position, because select-all should not change the lead index
+ list.addSelectionInterval(lead, lead);
+ }
+ else if (command.equals("selectLastRow"))
+ {
+ list.setSelectedIndex(list.getModel().getSize() - 1);
+ }
+ else if (command.equals("selectLastRowChangeLead"))
+ {
+ selModel.moveLeadSelectionIndex(list.getModel().getSize() - 1);
+ }
+ else if (command.equals("scrollDownExtendSelection"))
+ {
+ int target;
+ if (lead == list.getLastVisibleIndex())
{
- BasicListUI.this.list.getSelectionModel().
- setLeadSelectionIndex(Math.min(lead+1,max));
+ target = Math.min
+ (max, lead + (list.getLastVisibleIndex() -
+ list.getFirstVisibleIndex() + 1));
}
+ else
+ target = list.getLastVisibleIndex();
+ selModel.setLeadSelectionIndex(target);
}
- else if ((evt.getKeyCode() == KeyEvent.VK_UP)
- || (evt.getKeyCode() == KeyEvent.VK_KP_UP))
+ else if (command.equals("scrollDownChangeLead"))
{
- if (evt.getModifiers() == 0)
+ int target;
+ if (lead == list.getLastVisibleIndex())
{
- BasicListUI.this.list.clearSelection();
- BasicListUI.this.list.setSelectedIndex(Math.max(lead-1,0));
+ target = Math.min
+ (max, lead + (list.getLastVisibleIndex() -
+ list.getFirstVisibleIndex() + 1));
}
- else if (evt.getModifiers() == InputEvent.SHIFT_MASK)
+ else
+ target = list.getLastVisibleIndex();
+ selModel.moveLeadSelectionIndex(target);
+ }
+ else if (command.equals("scrollUpExtendSelection"))
+ {
+ int target;
+ if (lead == list.getFirstVisibleIndex())
{
- BasicListUI.this.list.getSelectionModel().
- setLeadSelectionIndex(Math.max(lead-1,0));
+ target = Math.max
+ (0, lead - (list.getLastVisibleIndex() -
+ list.getFirstVisibleIndex() + 1));
}
+ else
+ target = list.getFirstVisibleIndex();
+ selModel.setLeadSelectionIndex(target);
}
- else if (evt.getKeyCode() == KeyEvent.VK_PAGE_UP)
+ else if (command.equals("scrollUpChangeLead"))
{
int target;
- if (lead == BasicListUI.this.list.getFirstVisibleIndex())
+ if (lead == list.getFirstVisibleIndex())
{
target = Math.max
- (0, lead - (BasicListUI.this.list.getLastVisibleIndex() -
- BasicListUI.this.list.getFirstVisibleIndex() + 1));
+ (0, lead - (list.getLastVisibleIndex() -
+ list.getFirstVisibleIndex() + 1));
}
else
+ target = list.getFirstVisibleIndex();
+ selModel.moveLeadSelectionIndex(target);
+ }
+ else if (command.equals("selectNextRowExtendSelection"))
+ {
+ selModel.setLeadSelectionIndex(Math.min(lead + 1,max));
+ }
+ else if (command.equals("selectFirstRow"))
+ {
+ list.setSelectedIndex(0);
+ }
+ else if (command.equals("selectFirstRowChangeLead"))
+ {
+ selModel.moveLeadSelectionIndex(0);
+ }
+ else if (command.equals("selectFirstRowExtendSelection"))
+ {
+ selModel.setLeadSelectionIndex(0);
+ }
+ else if (command.equals("selectPreviousRowExtendSelection"))
+ {
+ selModel.setLeadSelectionIndex(Math.max(0,lead - 1));
+ }
+ else if (command.equals("scrollUp"))
+ {
+ int target;
+ if (lead == list.getFirstVisibleIndex())
{
- target = BasicListUI.this.list.getFirstVisibleIndex();
+ target = Math.max
+ (0, lead - (list.getLastVisibleIndex() -
+ list.getFirstVisibleIndex() + 1));
}
- if (evt.getModifiers() == 0)
- BasicListUI.this.list.setSelectedIndex(target);
- else if (evt.getModifiers() == InputEvent.SHIFT_MASK)
- BasicListUI.this.list.getSelectionModel().
- setLeadSelectionIndex(target);
+ else
+ target = list.getFirstVisibleIndex();
+ list.setSelectedIndex(target);
}
- else if (evt.getKeyCode() == KeyEvent.VK_PAGE_DOWN)
+ else if (command.equals("selectLastRowExtendSelection"))
+ {
+ selModel.setLeadSelectionIndex(list.getModel().getSize() - 1);
+ }
+ else if (command.equals("scrollDown"))
{
int target;
- if (lead == BasicListUI.this.list.getLastVisibleIndex())
+ if (lead == list.getLastVisibleIndex())
{
target = Math.min
- (max, lead + (BasicListUI.this.list.getLastVisibleIndex() -
- BasicListUI.this.list.getFirstVisibleIndex() + 1));
+ (max, lead + (list.getLastVisibleIndex() -
+ list.getFirstVisibleIndex() + 1));
}
else
+ target = list.getLastVisibleIndex();
+ list.setSelectedIndex(target);
+ }
+ else if (command.equals("selectNextRowChangeLead"))
+ {
+ if (selModel.getSelectionMode() != ListSelectionModel.MULTIPLE_INTERVAL_SELECTION)
+ selectNextIndex();
+ else
+ {
+ selModel.moveLeadSelectionIndex(Math.min(max, lead + 1));
+ }
+ }
+ else if (command.equals("selectPreviousRowChangeLead"))
+ {
+ if (selModel.getSelectionMode() != ListSelectionModel.MULTIPLE_INTERVAL_SELECTION)
+ selectPreviousIndex();
+ else
{
- target = BasicListUI.this.list.getLastVisibleIndex();
+ selModel.moveLeadSelectionIndex(Math.max(0, lead - 1));
}
- if (evt.getModifiers() == 0)
- BasicListUI.this.list.setSelectedIndex(target);
- else if (evt.getModifiers() == InputEvent.SHIFT_MASK)
- BasicListUI.this.list.getSelectionModel().
- setLeadSelectionIndex(target);
- }
- else if (evt.getKeyCode() == KeyEvent.VK_BACK_SLASH
- && (evt.getModifiers() == InputEvent.CTRL_MASK))
+ }
+ else if (command.equals("addToSelection"))
{
- BasicListUI.this.list.clearSelection();
+ list.addSelectionInterval(lead, lead);
}
- else if ((evt.getKeyCode() == KeyEvent.VK_HOME)
- || evt.getKeyCode() == KeyEvent.VK_END)
+ else if (command.equals("extendTo"))
{
- if (evt.getModifiers() != 0 &&
- evt.getModifiers() != InputEvent.SHIFT_MASK)
- return;
- // index is either 0 for HOME, or last cell for END
- int index = (evt.getKeyCode() == KeyEvent.VK_HOME) ? 0 : max;
-
- if (!evt.isShiftDown() ||(BasicListUI.this.list.getSelectionMode()
- == ListSelectionModel.SINGLE_SELECTION))
- BasicListUI.this.list.setSelectedIndex(index);
- else if (BasicListUI.this.list.getSelectionMode() ==
- ListSelectionModel.SINGLE_INTERVAL_SELECTION)
- BasicListUI.this.list.setSelectionInterval
- (BasicListUI.this.list.getAnchorSelectionIndex(), index);
- else
- BasicListUI.this.list.getSelectionModel().
- setLeadSelectionIndex(index);
+ selModel.setSelectionInterval(selModel.getAnchorSelectionIndex(),
+ lead);
}
- else if ((evt.getKeyCode() == KeyEvent.VK_A || evt.getKeyCode()
- == KeyEvent.VK_SLASH) && (evt.getModifiers() ==
- InputEvent.CTRL_MASK))
+ else if (command.equals("toggleAndAnchor"))
{
- BasicListUI.this.list.setSelectionInterval(0, max);
- // this next line is to restore the lead selection index to the old
- // position, because select-all should not change the lead index
- BasicListUI.this.list.addSelectionInterval(lead, lead);
+ if (!list.isSelectedIndex(lead))
+ list.addSelectionInterval(lead, lead);
+ else
+ list.removeSelectionInterval(lead, lead);
+ selModel.setAnchorSelectionIndex(lead);
}
- else if (evt.getKeyCode() == KeyEvent.VK_SPACE &&
- (evt.getModifiers() == InputEvent.CTRL_MASK))
+ else
{
- BasicListUI.this.list.getSelectionModel().
- setLeadSelectionIndex(Math.min(lead+1,max));
+ // DEBUG: uncomment the following line to print out
+ // key bindings that aren't implemented yet
+
+ // System.out.println ("not implemented: "+e.getActionCommand());
}
-
- BasicListUI.this.list.ensureIndexIsVisible
- (BasicListUI.this.list.getLeadSelectionIndex());
+
+ list.ensureIndexIsVisible(list.getLeadSelectionIndex());
}
}
-
+
/**
* A helper class which listens for {@link MouseEvent}s
* from the {@link JList}.
@@ -333,48 +428,46 @@ public class BasicListUI extends ListUI
public void mouseClicked(MouseEvent event)
{
Point click = event.getPoint();
- int index = BasicListUI.this.locationToIndex(list, click);
+ int index = locationToIndex(list, click);
if (index == -1)
return;
if (event.isShiftDown())
{
- if (BasicListUI.this.list.getSelectionMode() ==
- ListSelectionModel.SINGLE_SELECTION)
- BasicListUI.this.list.setSelectedIndex(index);
- else if (BasicListUI.this.list.getSelectionMode() ==
+ if (list.getSelectionMode() == ListSelectionModel.SINGLE_SELECTION)
+ list.setSelectedIndex(index);
+ else if (list.getSelectionMode() ==
ListSelectionModel.SINGLE_INTERVAL_SELECTION)
// COMPAT: the IBM VM is compatible with the following line of code.
// However, compliance with Sun's VM would correspond to replacing
// getAnchorSelectionIndex() with getLeadSelectionIndex().This is
// both unnatural and contradictory to the way they handle other
// similar UI interactions.
- BasicListUI.this.list.setSelectionInterval
- (BasicListUI.this.list.getAnchorSelectionIndex(), index);
+ list.setSelectionInterval(list.getAnchorSelectionIndex(), index);
else
// COMPAT: both Sun and IBM are compatible instead with:
- // BasicListUI.this.list.setSelectionInterval
- // (BasicListUI.this.list.getLeadSelectionIndex(),index);
+ // list.setSelectionInterval
+ // (list.getLeadSelectionIndex(),index);
// Note that for IBM this is contradictory to what they did in
// the above situation for SINGLE_INTERVAL_SELECTION.
// The most natural thing to do is the following:
- BasicListUI.this.list.getSelectionModel().
- setLeadSelectionIndex(index);
+ if (list.isSelectedIndex(list.getAnchorSelectionIndex()))
+ list.getSelectionModel().setLeadSelectionIndex(index);
+ else
+ list.addSelectionInterval(list.getAnchorSelectionIndex(), index);
}
else if (event.isControlDown())
{
- if (BasicListUI.this.list.getSelectionMode() ==
- ListSelectionModel.SINGLE_SELECTION)
- BasicListUI.this.list.setSelectedIndex(index);
- else if (BasicListUI.this.list.isSelectedIndex(index))
- BasicListUI.this.list.removeSelectionInterval(index,index);
+ if (list.getSelectionMode() == ListSelectionModel.SINGLE_SELECTION)
+ list.setSelectedIndex(index);
+ else if (list.isSelectedIndex(index))
+ list.removeSelectionInterval(index,index);
else
- BasicListUI.this.list.addSelectionInterval(index,index);
+ list.addSelectionInterval(index,index);
}
else
- BasicListUI.this.list.setSelectedIndex(index);
+ list.setSelectedIndex(index);
- BasicListUI.this.list.ensureIndexIsVisible
- (BasicListUI.this.list.getLeadSelectionIndex());
+ list.ensureIndexIsVisible(list.getLeadSelectionIndex());
}
/**
@@ -385,6 +478,7 @@ public class BasicListUI extends ListUI
*/
public void mousePressed(MouseEvent event)
{
+ // TODO: What should be done here, if anything?
}
/**
@@ -395,6 +489,7 @@ public class BasicListUI extends ListUI
*/
public void mouseReleased(MouseEvent event)
{
+ // TODO: What should be done here, if anything?
}
/**
@@ -405,6 +500,7 @@ public class BasicListUI extends ListUI
*/
public void mouseEntered(MouseEvent event)
{
+ // TODO: What should be done here, if anything?
}
/**
@@ -415,6 +511,7 @@ public class BasicListUI extends ListUI
*/
public void mouseExited(MouseEvent event)
{
+ // TODO: What should be done here, if anything?
}
/**
@@ -425,6 +522,7 @@ public class BasicListUI extends ListUI
*/
public void mouseDragged(MouseEvent event)
{
+ // TODO: What should be done here, if anything?
}
/**
@@ -435,6 +533,7 @@ public class BasicListUI extends ListUI
*/
public void mouseMoved(MouseEvent event)
{
+ // TODO: What should be done here, if anything?
}
}
@@ -459,11 +558,62 @@ public class BasicListUI extends ListUI
if (e.getNewValue() != null && e.getNewValue() instanceof ListModel)
((ListModel) e.getNewValue()).addListDataListener(BasicListUI.this.listDataListener);
}
+ // Update the updateLayoutStateNeeded flag.
+ if (e.getPropertyName().equals("model"))
+ updateLayoutStateNeeded += modelChanged;
+ else if (e.getPropertyName().equals("selectionModel"))
+ updateLayoutStateNeeded += selectionModelChanged;
+ else if (e.getPropertyName().equals("font"))
+ updateLayoutStateNeeded += fontChanged;
+ else if (e.getPropertyName().equals("fixedCellWidth"))
+ updateLayoutStateNeeded += fixedCellWidthChanged;
+ else if (e.getPropertyName().equals("fixedCellHeight"))
+ updateLayoutStateNeeded += fixedCellHeightChanged;
+ else if (e.getPropertyName().equals("prototypeCellValue"))
+ updateLayoutStateNeeded += prototypeCellValueChanged;
+ else if (e.getPropertyName().equals("cellRenderer"))
+ updateLayoutStateNeeded += cellRendererChanged;
+
BasicListUI.this.damageLayout();
}
}
/**
+ * A constant to indicate that the model has changed.
+ */
+ protected static final int modelChanged = 1;
+
+ /**
+ * A constant to indicate that the selection model has changed.
+ */
+ protected static final int selectionModelChanged = 2;
+
+ /**
+ * A constant to indicate that the font has changed.
+ */
+ protected static final int fontChanged = 4;
+
+ /**
+ * A constant to indicate that the fixedCellWidth has changed.
+ */
+ protected static final int fixedCellWidthChanged = 8;
+
+ /**
+ * A constant to indicate that the fixedCellHeight has changed.
+ */
+ protected static final int fixedCellHeightChanged = 16;
+
+ /**
+ * A constant to indicate that the prototypeCellValue has changed.
+ */
+ protected static final int prototypeCellValueChanged = 32;
+
+ /**
+ * A constant to indicate that the cellRenderer has changed.
+ */
+ protected static final int cellRendererChanged = 64;
+
+ /**
* Creates a new BasicListUI for the component.
*
* @param c The component to create a UI for
@@ -487,9 +637,6 @@ public class BasicListUI extends ListUI
/** The mouse listener listening to the list. */
protected MouseInputListener mouseInputListener;
- /** The key listener listening to the list */
- private KeyHandler keyListener;
-
/** The property change listener listening to the list. */
protected PropertyChangeListener propertyChangeListener;
@@ -514,9 +661,18 @@ public class BasicListUI extends ListUI
protected int[] cellHeights;
/**
- * A simple counter. When nonzero, indicates that the UI class is out of
+ * A bitmask that indicates which properties of the JList have changed.
+ * When nonzero, indicates that the UI class is out of
* date with respect to the underlying list, and must recalculate the
* list layout before painting or performing size calculations.
+ *
+ * @see #modelChanged
+ * @see #selectionModelChanged
+ * @see #fontChanged
+ * @see #fixedCellWidthChanged
+ * @see #fixedCellHeightChanged
+ * @see #prototypeCellValueChanged
+ * @see #cellRendererChanged
*/
protected int updateLayoutStateNeeded;
@@ -524,6 +680,9 @@ public class BasicListUI extends ListUI
* The {@link CellRendererPane} that is used for painting.
*/
protected CellRendererPane rendererPane;
+
+ /** The action bound to KeyStrokes. */
+ ListAction action;
/**
* Calculate the height of a particular row. If there is a fixed {@link
@@ -694,13 +853,6 @@ public class BasicListUI extends ListUI
*/
public BasicListUI()
{
- focusListener = new FocusHandler();
- listDataListener = new ListDataHandler();
- listSelectionListener = new ListSelectionHandler();
- mouseInputListener = new MouseInputHandler();
- keyListener = new KeyHandler();
- propertyChangeListener = new PropertyChangeHandler();
- componentListener = new ComponentHandler();
updateLayoutStateNeeded = 1;
rendererPane = new CellRendererPane();
}
@@ -713,11 +865,10 @@ public class BasicListUI extends ListUI
*/
protected void installDefaults()
{
- UIDefaults defaults = UIManager.getLookAndFeelDefaults();
- list.setForeground(defaults.getColor("List.foreground"));
- list.setBackground(defaults.getColor("List.background"));
- list.setSelectionForeground(defaults.getColor("List.selectionForeground"));
- list.setSelectionBackground(defaults.getColor("List.selectionBackground"));
+ LookAndFeel.installColorsAndFont(list, "List.background",
+ "List.foreground", "List.font");
+ list.setSelectionForeground(UIManager.getColor("List.selectionForeground"));
+ list.setSelectionBackground(UIManager.getColor("List.selectionBackground"));
list.setOpaque(true);
}
@@ -742,14 +893,28 @@ public class BasicListUI extends ListUI
*/
protected void installListeners()
{
+ if (focusListener == null)
+ focusListener = createFocusListener();
list.addFocusListener(focusListener);
+ if (listDataListener == null)
+ listDataListener = createListDataListener();
list.getModel().addListDataListener(listDataListener);
+ if (listSelectionListener == null)
+ listSelectionListener = createListSelectionListener();
list.addListSelectionListener(listSelectionListener);
+ if (mouseInputListener == null)
+ mouseInputListener = createMouseInputListener();
list.addMouseListener(mouseInputListener);
- list.addKeyListener(keyListener);
list.addMouseMotionListener(mouseInputListener);
+ if (propertyChangeListener == null)
+ propertyChangeListener = createPropertyChangeListener();
list.addPropertyChangeListener(propertyChangeListener);
+
+ // FIXME: Are these two really needed? At least they are not documented.
+ //keyListener = new KeyHandler();
list.addComponentListener(componentListener);
+ componentListener = new ComponentHandler();
+ //list.addKeyListener(keyListener);
}
/**
@@ -761,16 +926,41 @@ public class BasicListUI extends ListUI
list.getModel().removeListDataListener(listDataListener);
list.removeListSelectionListener(listSelectionListener);
list.removeMouseListener(mouseInputListener);
- list.removeKeyListener(keyListener);
+ //list.removeKeyListener(keyListener);
list.removeMouseMotionListener(mouseInputListener);
list.removePropertyChangeListener(propertyChangeListener);
}
-
+
/**
* Installs keyboard actions for this UI in the {@link JList}.
*/
protected void installKeyboardActions()
{
+ UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+ InputMap focusInputMap = (InputMap)defaults.get("List.focusInputMap");
+ InputMapUIResource parentInputMap = new InputMapUIResource();
+ // FIXME: The JDK uses a LazyActionMap for parentActionMap
+ ActionMap parentActionMap = new ActionMap();
+ action = new ListAction();
+ Object keys[] = focusInputMap.allKeys();
+ // Register key bindings in the UI InputMap-ActionMap pair
+ for (int i = 0; i < keys.length; i++)
+ {
+ KeyStroke stroke = (KeyStroke)keys[i];
+ String actionString = (String) focusInputMap.get(stroke);
+ parentInputMap.put(KeyStroke.getKeyStroke(stroke.getKeyCode(),
+ stroke.getModifiers()),
+ actionString);
+
+ parentActionMap.put (actionString,
+ new ActionListenerProxy(action, actionString));
+ }
+ // Register the new InputMap-ActionMap as the parents of the list's
+ // InputMap and ActionMap
+ parentInputMap.setParent(list.getInputMap().getParent());
+ parentActionMap.setParent(list.getActionMap().getParent());
+ list.getInputMap().setParent(parentInputMap);
+ list.getActionMap().setParent(parentActionMap);
}
/**
@@ -778,6 +968,7 @@ public class BasicListUI extends ListUI
*/
protected void uninstallKeyboardActions()
{
+ // TODO: Implement this properly.
}
/**
@@ -1045,4 +1236,82 @@ public class BasicListUI extends ListUI
}
return loc;
}
+
+ /**
+ * Creates and returns the focus listener for this UI.
+ *
+ * @return the focus listener for this UI
+ */
+ protected FocusListener createFocusListener()
+ {
+ return new FocusHandler();
+ }
+
+ /**
+ * Creates and returns the list data listener for this UI.
+ *
+ * @return the list data listener for this UI
+ */
+ protected ListDataListener createListDataListener()
+ {
+ return new ListDataHandler();
+ }
+
+ /**
+ * Creates and returns the list selection listener for this UI.
+ *
+ * @return the list selection listener for this UI
+ */
+ protected ListSelectionListener createListSelectionListener()
+ {
+ return new ListSelectionHandler();
+ }
+
+ /**
+ * Creates and returns the mouse input listener for this UI.
+ *
+ * @return the mouse input listener for this UI
+ */
+ protected MouseInputListener createMouseInputListener()
+ {
+ return new MouseInputHandler();
+ }
+
+ /**
+ * Creates and returns the property change listener for this UI.
+ *
+ * @return the property change listener for this UI
+ */
+ protected PropertyChangeListener createPropertyChangeListener()
+ {
+ return new PropertyChangeHandler();
+ }
+
+ /**
+ * Selects the next list item and force it to be visible.
+ */
+ protected void selectNextIndex()
+ {
+ int index = list.getSelectionModel().getLeadSelectionIndex();
+ if (index < list.getModel().getSize() - 1)
+ {
+ index++;
+ list.setSelectedIndex(index);
+ }
+ list.ensureIndexIsVisible(index);
+ }
+
+ /**
+ * Selects the previous list item and force it to be visible.
+ */
+ protected void selectPreviousIndex()
+ {
+ int index = list.getSelectionModel().getLeadSelectionIndex();
+ if (index > 0)
+ {
+ index--;
+ list.setSelectedIndex(index);
+ }
+ list.ensureIndexIsVisible(index);
+ }
}
diff --git a/javax/swing/plaf/basic/BasicLookAndFeel.java b/javax/swing/plaf/basic/BasicLookAndFeel.java
index 0c21d4256..64a9b2d08 100644
--- a/javax/swing/plaf/basic/BasicLookAndFeel.java
+++ b/javax/swing/plaf/basic/BasicLookAndFeel.java
@@ -273,7 +273,7 @@ public abstract class BasicLookAndFeel extends LookAndFeel
"Button.foreground", new ColorUIResource(Color.BLACK),
"Button.highlight", new ColorUIResource(Color.WHITE),
"Button.light", new ColorUIResource(Color.LIGHT_GRAY),
- "Button.margin", new InsetsUIResource(2, 2, 2, 2),
+ "Button.margin", new InsetsUIResource(2, 14, 2, 14),
"Button.shadow", new ColorUIResource(Color.GRAY),
"Button.textIconGap", new Integer(4),
"Button.textShiftOffset", new Integer(0),
@@ -364,7 +364,7 @@ public abstract class BasicLookAndFeel extends LookAndFeel
}),
"ComboBox.background", new ColorUIResource(Color.white),
"ComboBox.buttonBackground", new ColorUIResource(light),
- "ComboBox.buttonDarkShadow", new ColorUIResource(shadow),
+ "ComboBox.buttonDarkShadow", new ColorUIResource(darkShadow),
"ComboBox.buttonHighlight", new ColorUIResource(highLight),
"ComboBox.buttonShadow", new ColorUIResource(shadow),
"ComboBox.disabledBackground", new ColorUIResource(light),
@@ -467,6 +467,8 @@ public abstract class BasicLookAndFeel extends LookAndFeel
"FocusManagerClassName", "TODO",
"FormattedTextField.background", new ColorUIResource(light),
"FormattedTextField.caretForeground", new ColorUIResource(Color.black),
+ "FormattedTextField.font",
+ new FontUIResource("SansSerif", Font.PLAIN, 12),
"FormattedTextField.foreground", new ColorUIResource(Color.black),
"FormattedTextField.inactiveBackground", new ColorUIResource(light),
"FormattedTextField.inactiveForeground", new ColorUIResource(Color.gray),
@@ -532,25 +534,69 @@ public abstract class BasicLookAndFeel extends LookAndFeel
"List.background", new ColorUIResource(Color.white),
"List.border", new BasicBorders.MarginBorder(),
"List.focusInputMap", new UIDefaults.LazyInputMap(new Object[] {
- "PAGE_UP", "scrollUp",
- "ctrl \\", "clearSelection",
- "PAGE_DOWN", "scrollDown",
- "shift PAGE_DOWN","scrollDownExtendSelection",
+ "ctrl DOWN", "selectNextRowChangeLead",
+ "shift UP", "selectPreviousRowExtendSelection",
+ "ctrl RIGHT", "selectNextColumnChangeLead",
+ "shift ctrl LEFT", "selectPreviousColumnExtendSelection",
+ "shift KP_UP", "selectPreviousRowChangeLead",
+ "DOWN", "selectNextRow",
+ "ctrl UP", "selectPreviousRowChangeLead",
+ "ctrl LEFT", "selectPreviousColumnChangeLead",
+ "CUT", "cut",
"END", "selectLastRow",
- "HOME", "selectFirstRow",
- "shift END", "selectLastRowExtendSelection",
+ "shift PAGE_UP","scrollUpExtendSelection",
+ "KP_UP", "selectPreviousRow",
+ "shift ctrl UP", "selectPreviousRowExtendSelection",
+ "ctrl HOME", "selectFirstRowChangeLead",
+ "shift LEFT", "selectPreviousColumnExtendSelection",
+ "ctrl END", "selectLastRowChangeLead",
+ "ctrl PAGE_DOWN", "scrollDownChangeLead",
+ "shift ctrl RIGHT", "selectNextColumnExtendSelection",
+ "LEFT", "selectPreviousColumn",
+ "ctrl PAGE_UP", "scrollUpChangeLead",
+ "KP_LEFT", "selectPreviousColumn",
+ "shift KP_RIGHT", "selectNextColumnExtendSelection",
+ "SPACE", "addToSelection",
+ "ctrl SPACE", "toggleAndAnchor",
+ "shift SPACE", "extendTo",
+ "shift ctrl SPACE", "moveSelectionTo",
+ "shift ctrl DOWN", "selectNextRowExtendSelection",
+ "ctrl BACK_SLASH", "clearSelection",
"shift HOME", "selectFirstRowExtendSelection",
- "UP", "selectPreviousRow",
- "ctrl /", "selectAll",
- "ctrl A", "selectAll",
- "DOWN", "selectNextRow",
- "shift UP", "selectPreviousRowExtendSelection",
- "ctrl SPACE", "selectNextRowExtendSelection",
+ "RIGHT", "selectNextColumn",
+ "shift ctrl PAGE_UP", "scrollUpExtendSelection",
"shift DOWN", "selectNextRowExtendSelection",
- "KP_UP", "selectPreviousRow",
- "shift PAGE_UP","scrollUpExtendSelection",
- "KP_DOWN", "selectNextRow"
+ "PAGE_DOWN", "scrollDown",
+ "shift ctrl KP_UP", "selectPreviousRowExtendSelection",
+ "shift KP_LEFT", "selectPreviousColumnExtendSelection",
+ "ctrl X", "cut",
+ "shift ctrl PAGE_DOWN", "scrollDownExtendSelection",
+ "ctrl SLASH", "selectAll",
+ "ctrl C", "copy",
+ "ctrl KP_RIGHT", "selectNextColumnChangeLead",
+ "shift END", "selectLastRowExtendSelection",
+ "shift ctrl KP_DOWN", "selectNextRowExtendSelection",
+ "ctrl KP_LEFT", "selectPreviousColumnChangeLead",
+ "HOME", "selectFirstRow",
+ "ctrl V", "paste",
+ "KP_DOWN", "selectNextRow",
+ "ctrl KP_DOWN", "selectNextRowChangeLead",
+ "shift RIGHT", "selectNextColumnExtendSelection",
+ "ctrl A", "selectAll",
+ "shift ctrl END", "selectLastRowExtendSelection",
+ "COPY", "copy",
+ "ctrl KP_UP", "selectPreviousRowChangeLead",
+ "shift ctrl KP_LEFT", "selectPreviousColumnExtendSelection",
+ "shift KP_DOWN", "selectNextRowExtendSelection",
+ "UP", "selectPreviousRow",
+ "shift ctrl HOME", "selectFirstRowExtendSelection",
+ "shift PAGE_DOWN", "scrollDownExtendSelection",
+ "KP_RIGHT", "selectNextColumn",
+ "shift ctrl KP_RIGHT", "selectNextColumnExtendSelection",
+ "PAGE_UP", "scrollUp",
+ "PASTE", "paste"
}),
+ "List.font", new FontUIResource("Dialog", Font.PLAIN, 12),
"List.foreground", new ColorUIResource(Color.black),
"List.selectionBackground", new ColorUIResource(0, 0, 128),
"List.selectionForeground", new ColorUIResource(Color.white),
@@ -602,7 +648,6 @@ public abstract class BasicLookAndFeel extends LookAndFeel
"MenuItem.background", new ColorUIResource(light),
"MenuItem.border", new BasicBorders.MarginBorder(),
"MenuItem.borderPainted", Boolean.FALSE,
- "MenuItem.checkIcon", BasicIconFactory.getMenuItemCheckIcon(),
"MenuItem.font", new FontUIResource("Dialog", Font.PLAIN, 12),
"MenuItem.foreground", new ColorUIResource(darkShadow),
"MenuItem.margin", new InsetsUIResource(2, 2, 2, 2),
@@ -625,7 +670,9 @@ public abstract class BasicLookAndFeel extends LookAndFeel
"OptionPane.messageAreaBorder",
new BorderUIResource.EmptyBorderUIResource(0, 0, 0, 0),
"OptionPane.messageForeground", new ColorUIResource(darkShadow),
- "OptionPane.minimumSize", new DimensionUIResource(262, 90),
+ "OptionPane.minimumSize",
+ new DimensionUIResource(BasicOptionPaneUI.MinimumWidth,
+ BasicOptionPaneUI.MinimumHeight),
"OptionPane.noButtonText", "No",
"OptionPane.okButtonText", "OK",
// XXX Don't use gif
@@ -848,6 +895,24 @@ public abstract class BasicLookAndFeel extends LookAndFeel
"TabbedPane.tabRunOverlay", new Integer(2),
"TabbedPane.textIconGap", new Integer(4),
"Table.ancestorInputMap", new UIDefaults.LazyInputMap(new Object[] {
+ "ctrl DOWN", "selectNextRowChangeLead",
+ "ctrl RIGHT", "selectNextColumnChangeLead",
+ "ctrl UP", "selectPreviousRowChangeLead",
+ "ctrl LEFT", "selectPreviousColumnChangeLead",
+ "CUT", "cut",
+ "SPACE", "addToSelection",
+ "ctrl SPACE", "toggleAndAnchor",
+ "shift SPACE", "extendTo",
+ "shift ctrl SPACE", "moveSelectionTo",
+ "ctrl X", "cut",
+ "ctrl C", "copy",
+ "ctrl KP_RIGHT", "selectNextColumnChangeLead",
+ "ctrl KP_LEFT", "selectPreviousColumnChangeLead",
+ "ctrl V", "paste",
+ "ctrl KP_DOWN", "selectNextRowChangeLead",
+ "COPY", "copy",
+ "ctrl KP_UP", "selectPreviousRowChangeLead",
+ "PASTE", "paste",
"shift PAGE_DOWN","scrollDownExtendSelection",
"PAGE_DOWN", "scrollDownChangeSelection",
"END", "selectLastColumn",
@@ -898,22 +963,22 @@ public abstract class BasicLookAndFeel extends LookAndFeel
"ctrl SLASH", "selectAll",
"ctrl shift KP_DOWN", "selectNextRowExtendSelection",
}),
- "Table.background", new ColorUIResource(light),
- "Table.focusCellBackground", new ColorUIResource(light),
- "Table.focusCellForeground", new ColorUIResource(darkShadow),
+ "Table.background", new ColorUIResource(new ColorUIResource(255, 255, 255)),
+ "Table.focusCellBackground", new ColorUIResource(new ColorUIResource(255, 255, 255)),
+ "Table.focusCellForeground", new ColorUIResource(new ColorUIResource(0, 0, 0)),
"Table.focusCellHighlightBorder",
new BorderUIResource.LineBorderUIResource(
new ColorUIResource(255, 255, 0)),
"Table.font", new FontUIResource("Dialog", Font.PLAIN, 12),
- "Table.foreground", new ColorUIResource(darkShadow),
- "Table.gridColor", new ColorUIResource(Color.gray),
+ "Table.foreground", new ColorUIResource(new ColorUIResource(0, 0, 0)),
+ "Table.gridColor", new ColorUIResource(new ColorUIResource(128, 128, 128)),
"Table.scrollPaneBorder", new BorderUIResource.BevelBorderUIResource(0),
- "Table.selectionBackground", new ColorUIResource(Color.black),
- "Table.selectionForeground", new ColorUIResource(Color.white),
- "TableHeader.background", new ColorUIResource(light),
+ "Table.selectionBackground", new ColorUIResource(new ColorUIResource(0, 0, 128)),
+ "Table.selectionForeground", new ColorUIResource(new ColorUIResource(255, 255, 255)),
+ "TableHeader.background", new ColorUIResource(new ColorUIResource(192, 192, 192)),
"TableHeader.cellBorder", new BorderUIResource.BevelBorderUIResource(0),
"TableHeader.font", new FontUIResource("Dialog", Font.PLAIN, 12),
- "TableHeader.foreground", new ColorUIResource(darkShadow),
+ "TableHeader.foreground", new ColorUIResource(new ColorUIResource(0, 0, 0)),
"TextArea.background", new ColorUIResource(light),
"TextArea.border",
@@ -1040,7 +1105,7 @@ public abstract class BasicLookAndFeel extends LookAndFeel
"Tree.ancestorInputMap", new UIDefaults.LazyInputMap(new Object[] {
"ESCAPE", "cancel"
}),
- "Tree.background", new ColorUIResource(light),
+ "Tree.background", new ColorUIResource(new Color(255, 255, 255)),
"Tree.changeSelectionWithFocus", Boolean.TRUE,
// "Tree.closedIcon", new IconUIResource(new ImageIcon("icons/TreeClosed.png")),
// "Tree.collapsedIcon", new IconUIResource(new ImageIcon("icons/TreeCollapsed.png")),
@@ -1090,20 +1155,20 @@ public abstract class BasicLookAndFeel extends LookAndFeel
"PAGE_UP", "scrollUpChangeSelection",
"ctrl PAGE_DOWN", "scrollDownChangeLead"
}),
- "Tree.font", new FontUIResource(new Font("Helvetica", Font.PLAIN, 12)),
+ "Tree.font", new FontUIResource("Dialog", Font.PLAIN, 12),
"Tree.foreground", new ColorUIResource(Color.black),
"Tree.hash", new ColorUIResource(new Color(128, 128, 128)),
"Tree.leftChildIndent", new Integer(7),
"Tree.rightChildIndent", new Integer(13),
- "Tree.rowHeight", new Integer(20), // FIXME
+ "Tree.rowHeight", new Integer(16),
"Tree.scrollsOnExpand", Boolean.TRUE,
"Tree.selectionBackground", new ColorUIResource(Color.black),
- "Tree.nonSelectionBackground", new ColorUIResource(new Color(239, 235, 231)),
+ "Tree.nonSelectionBackground", new ColorUIResource(new Color(255, 255, 255)),
"Tree.selectionBorderColor", new ColorUIResource(Color.black),
"Tree.selectionBorder", new BorderUIResource.LineBorderUIResource(Color.black),
"Tree.selectionForeground", new ColorUIResource(new Color(255, 255, 255)),
- "Tree.textBackground", new ColorUIResource(new Color(255, 255, 255)),
- "Tree.textForeground", new ColorUIResource(Color.black),
+ "Tree.textBackground", new ColorUIResource(new Color(192, 192, 192)),
+ "Tree.textForeground", new ColorUIResource(new Color(0, 0, 0)),
"Viewport.background", new ColorUIResource(light),
"Viewport.foreground", new ColorUIResource(Color.black),
"Viewport.font", new FontUIResource("Dialog", Font.PLAIN, 12)
diff --git a/javax/swing/plaf/basic/BasicMenuBarUI.java b/javax/swing/plaf/basic/BasicMenuBarUI.java
index 6b9cad89c..daa9b0d6b 100644
--- a/javax/swing/plaf/basic/BasicMenuBarUI.java
+++ b/javax/swing/plaf/basic/BasicMenuBarUI.java
@@ -38,9 +38,6 @@ exception statement from your version. */
package javax.swing.plaf.basic;
-import java.awt.Component;
-import java.awt.Container;
-import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
@@ -50,10 +47,10 @@ import java.beans.PropertyChangeListener;
import javax.swing.BoxLayout;
import javax.swing.JComponent;
+import javax.swing.JMenu;
import javax.swing.JMenuBar;
+import javax.swing.LookAndFeel;
import javax.swing.MenuElement;
-import javax.swing.UIDefaults;
-import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.MouseInputListener;
@@ -169,12 +166,9 @@ public class BasicMenuBarUI extends MenuBarUI
*/
protected void installDefaults()
{
- UIDefaults defaults = UIManager.getLookAndFeelDefaults();
-
- menuBar.setBackground(defaults.getColor("MenuBar.background"));
- menuBar.setBorder(defaults.getBorder("MenuBar.border"));
- menuBar.setFont(defaults.getFont("MenuBar.font"));
- menuBar.setForeground(defaults.getColor("MenuBar.foreground"));
+ LookAndFeel.installBorder(menuBar, "MenuBar.border");
+ LookAndFeel.installColorsAndFont(menuBar, "MenuBar.background",
+ "MenuBar.foreground", "MenuBar.font");
menuBar.setOpaque(true);
}
@@ -262,6 +256,7 @@ public class BasicMenuBarUI extends MenuBarUI
{
public void stateChanged(ChangeEvent event)
{
+ // TODO: What should be done here, if anything?
}
}
@@ -326,7 +321,11 @@ public class BasicMenuBarUI extends MenuBarUI
MenuElement[] me = menuBar.getSubElements();
for (int i = 0; i < me.length; i++)
- menuBar.getMenu(i).setSelected(false);
+ {
+ JMenu menu = menuBar.getMenu(i);
+ if (menu != null)
+ menu.setSelected(false);
+ }
}
/**
@@ -336,6 +335,7 @@ public class BasicMenuBarUI extends MenuBarUI
*/
public void mousePressed(MouseEvent e)
{
+ // TODO: What should be done here, if anything?
}
/**
@@ -345,6 +345,7 @@ public class BasicMenuBarUI extends MenuBarUI
*/
public void mouseReleased(MouseEvent e)
{
+ // TODO: What should be done here, if anything?
}
/**
@@ -354,6 +355,7 @@ public class BasicMenuBarUI extends MenuBarUI
*/
public void mouseExited(MouseEvent e)
{
+ // TODO: What should be done here, if anything?
}
/**
@@ -363,6 +365,7 @@ public class BasicMenuBarUI extends MenuBarUI
*/
public void mouseDragged(MouseEvent e)
{
+ // TODO: What should be done here, if anything?
}
/**
@@ -372,6 +375,7 @@ public class BasicMenuBarUI extends MenuBarUI
*/
public void mouseMoved(MouseEvent e)
{
+ // TODO: What should be done here, if anything?
}
/**
@@ -381,6 +385,7 @@ public class BasicMenuBarUI extends MenuBarUI
*/
public void mouseEntered(MouseEvent e)
{
+ // TODO: What should be done here, if anything?
}
}
}
diff --git a/javax/swing/plaf/basic/BasicMenuItemUI.java b/javax/swing/plaf/basic/BasicMenuItemUI.java
index 488844336..f8f577a76 100644
--- a/javax/swing/plaf/basic/BasicMenuItemUI.java
+++ b/javax/swing/plaf/basic/BasicMenuItemUI.java
@@ -48,16 +48,19 @@ import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
import java.util.ArrayList;
+import javax.swing.ButtonModel;
import javax.swing.Icon;
+import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComponent;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.KeyStroke;
+import javax.swing.LookAndFeel;
import javax.swing.MenuElement;
import javax.swing.MenuSelectionManager;
import javax.swing.SwingConstants;
@@ -109,7 +112,7 @@ public class BasicMenuItemUI extends MenuItemUI
* Number of spaces between icon and text.
*/
protected int defaultTextIconGap = 4;
-
+
/**
* Color of the text when menu item is disabled
*/
@@ -156,16 +159,21 @@ public class BasicMenuItemUI extends MenuItemUI
private String acceleratorDelimiter;
/**
- * PropertyChangeListener to listen for property changes in the menu item
+ * ItemListener to listen for item changes in the menu item
*/
- private PropertyChangeListener propertyChangeListener;
+ private ItemListener itemListener;
/**
* Number of spaces between accelerator and menu item's label.
*/
- private int defaultAcceleratorLabelGap = 4;
+ private int defaultAcceleratorLabelGap = 10;
/**
+ * Number of spaces between the text and the arrow icon.
+ */
+ private int defaultTextArrowIconGap = 10;
+
+ /**
* Creates a new BasicMenuItemUI object.
*/
public BasicMenuItemUI()
@@ -173,7 +181,7 @@ public class BasicMenuItemUI extends MenuItemUI
mouseInputListener = createMouseInputListener(menuItem);
menuDragMouseListener = createMenuDragMouseListener(menuItem);
menuKeyListener = createMenuKeyListener(menuItem);
- propertyChangeListener = new PropertyChangeHandler();
+ itemListener = new ItemHandler();
}
/**
@@ -325,7 +333,7 @@ public class BasicMenuItemUI extends MenuItemUI
m.getToolkit().getFontMetrics(acceleratorFont));
// add width of accelerator's text
- d.width = d.width + rect.width + defaultAcceleratorLabelGap;
+ d.width += rect.width + defaultAcceleratorLabelGap;
// adjust the heigth of the preferred size if necessary
if (d.height < rect.height)
@@ -342,7 +350,7 @@ public class BasicMenuItemUI extends MenuItemUI
if (arrowIcon != null && (c instanceof JMenu))
{
- d.width = d.width + arrowIcon.getIconWidth() + defaultTextIconGap;
+ d.width = d.width + arrowIcon.getIconWidth() + defaultTextArrowIconGap;
if (arrowIcon.getIconHeight() > d.height)
d.height = arrowIcon.getIconHeight();
@@ -390,23 +398,22 @@ public class BasicMenuItemUI extends MenuItemUI
*/
protected void installDefaults()
{
- UIDefaults defaults = UIManager.getLookAndFeelDefaults();
-
- menuItem.setBackground(defaults.getColor("MenuItem.background"));
- menuItem.setBorder(defaults.getBorder("MenuItem.border"));
- menuItem.setFont(defaults.getFont("MenuItem.font"));
- menuItem.setForeground(defaults.getColor("MenuItem.foreground"));
- menuItem.setMargin(defaults.getInsets("MenuItem.margin"));
- menuItem.setOpaque(true);
- acceleratorFont = defaults.getFont("MenuItem.acceleratorFont");
- acceleratorForeground = defaults.getColor("MenuItem.acceleratorForeground");
- acceleratorSelectionForeground = defaults.getColor("MenuItem.acceleratorSelectionForeground");
- selectionBackground = defaults.getColor("MenuItem.selectionBackground");
- selectionForeground = defaults.getColor("MenuItem.selectionForeground");
- acceleratorDelimiter = defaults.getString("MenuItem.acceleratorDelimiter");
-
+ String prefix = getPropertyPrefix();
+ LookAndFeel.installBorder(menuItem, prefix + ".border");
+ LookAndFeel.installColorsAndFont(menuItem, prefix + ".background",
+ prefix + ".foreground", prefix + ".font");
+ menuItem.setMargin(UIManager.getInsets(prefix + ".margin"));
+ acceleratorFont = UIManager.getFont(prefix + ".acceleratorFont");
+ acceleratorForeground = UIManager.getColor(prefix + ".acceleratorForeground");
+ acceleratorSelectionForeground = UIManager.getColor(prefix + ".acceleratorSelectionForeground");
+ selectionBackground = UIManager.getColor(prefix + ".selectionBackground");
+ selectionForeground = UIManager.getColor(prefix + ".selectionForeground");
+ acceleratorDelimiter = UIManager.getString(prefix + ".acceleratorDelimiter");
+ checkIcon = UIManager.getIcon(prefix + ".checkIcon");
+
menuItem.setHorizontalTextPosition(SwingConstants.TRAILING);
menuItem.setHorizontalAlignment(SwingConstants.LEADING);
+ menuItem.setOpaque(true);
}
/**
@@ -426,7 +433,7 @@ public class BasicMenuItemUI extends MenuItemUI
menuItem.addMouseMotionListener(mouseInputListener);
menuItem.addMenuDragMouseListener(menuDragMouseListener);
menuItem.addMenuKeyListener(menuKeyListener);
- menuItem.addPropertyChangeListener(propertyChangeListener);
+ menuItem.addItemListener(itemListener);
}
/**
@@ -533,7 +540,9 @@ public class BasicMenuItemUI extends MenuItemUI
// Menu item is considered to be highlighted when it is selected.
// But we don't want to paint the background of JCheckBoxMenuItems
- if ((m.isSelected() && checkIcon == null) || m.getModel().isArmed()
+ ButtonModel mod = m.getModel();
+ if ((m.isSelected() && checkIcon == null) || (mod != null &&
+ mod.isArmed())
&& (m.getParent() instanceof MenuElement))
{
if (m.isContentAreaFilled())
@@ -572,9 +581,8 @@ public class BasicMenuItemUI extends MenuItemUI
{
int width = arrowIcon.getIconWidth();
int height = arrowIcon.getIconHeight();
-
- arrowIcon.paintIcon(m, g, vr.width - width + defaultTextIconGap,
- vr.y + 2);
+ int offset = (vr.height - height) / 2;
+ arrowIcon.paintIcon(m, g, vr.width - width, vr.y + offset);
}
}
@@ -633,8 +641,9 @@ public class BasicMenuItemUI extends MenuItemUI
{
// Menu item is considered to be highlighted when it is selected.
// But not if it's a JCheckBoxMenuItem
+ ButtonModel mod = menuItem.getModel();
if ((menuItem.isSelected() && checkIcon == null)
- || menuItem.getModel().isArmed()
+ || (mod != null && mod.isArmed())
&& (menuItem.getParent() instanceof MenuElement))
g.setColor(selectionForeground);
else
@@ -712,7 +721,7 @@ public class BasicMenuItemUI extends MenuItemUI
menuItem.removeMouseListener(mouseInputListener);
menuItem.removeMenuDragMouseListener(menuDragMouseListener);
menuItem.removeMenuKeyListener(menuKeyListener);
- menuItem.removePropertyChangeListener(propertyChangeListener);
+ menuItem.removeItemListener(itemListener);
}
/**
@@ -828,6 +837,7 @@ public class BasicMenuItemUI extends MenuItemUI
*/
protected MouseInputHandler()
{
+ // Nothing to do here.
}
/**
@@ -942,7 +952,7 @@ public class BasicMenuItemUI extends MenuItemUI
/**
* This class handles mouse dragged events.
*/
- protected class MenuDragMouseHandler implements MenuDragMouseListener
+ private class MenuDragMouseHandler implements MenuDragMouseListener
{
/**
* Tbis method is invoked when mouse is dragged over the menu item.
@@ -973,11 +983,11 @@ public class BasicMenuItemUI extends MenuItemUI
* Tbis method is invoked when mouse exits the menu item while it is being
* dragged
*
- * @param e
- * The MenuDragMouseEvent
+ * @param e the MenuDragMouseEvent
*/
public void menuDragMouseExited(MenuDragMouseEvent e)
{
+ // TODO: What should be done here, if anything?
}
/**
@@ -1003,7 +1013,7 @@ public class BasicMenuItemUI extends MenuItemUI
* This class handles key events occuring when menu item is visible on the
* screen.
*/
- protected class MenuKeyHandler implements MenuKeyListener
+ private class MenuKeyHandler implements MenuKeyListener
{
/**
* This method is invoked when key has been pressed
@@ -1013,6 +1023,7 @@ public class BasicMenuItemUI extends MenuItemUI
*/
public void menuKeyPressed(MenuKeyEvent e)
{
+ // TODO: What should be done here, if anything?
}
/**
@@ -1023,6 +1034,7 @@ public class BasicMenuItemUI extends MenuItemUI
*/
public void menuKeyReleased(MenuKeyEvent e)
{
+ // TODO: What should be done here, if anything?
}
/**
@@ -1034,22 +1046,30 @@ public class BasicMenuItemUI extends MenuItemUI
*/
public void menuKeyTyped(MenuKeyEvent e)
{
+ // TODO: What should be done here, if anything?
}
}
-
+
/**
- * Helper class that listens for changes to the properties of the {@link
+ * Helper class that listens for item changes to the properties of the {@link
* JMenuItem}.
*/
- protected class PropertyChangeHandler implements PropertyChangeListener
+ private class ItemHandler implements ItemListener
{
/**
- * This method is called when one of the menu item's properties change.
+ * This method is called when one of the menu item changes.
*
- * @param evt A {@link PropertyChangeEvent}.
+ * @param evt A {@link ItemEvent}.
*/
- public void propertyChange(PropertyChangeEvent evt)
+ public void itemStateChanged(ItemEvent evt)
{
+ boolean state = false;
+ if (menuItem instanceof JCheckBoxMenuItem)
+ {
+ if (evt.getStateChange() == ItemEvent.SELECTED)
+ state = true;
+ ((JCheckBoxMenuItem) menuItem).setState(state);
+ }
menuItem.revalidate();
menuItem.repaint();
}
diff --git a/javax/swing/plaf/basic/BasicMenuUI.java b/javax/swing/plaf/basic/BasicMenuUI.java
index 30be592ee..827cbb0f5 100644
--- a/javax/swing/plaf/basic/BasicMenuUI.java
+++ b/javax/swing/plaf/basic/BasicMenuUI.java
@@ -38,6 +38,7 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
@@ -46,8 +47,8 @@ import java.beans.PropertyChangeListener;
import javax.swing.JComponent;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
-import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
+import javax.swing.LookAndFeel;
import javax.swing.MenuSelectionManager;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
@@ -92,7 +93,7 @@ public class BasicMenuUI extends BasicMenuItemUI
*/
protected ChangeListener createChangeListener(JComponent c)
{
- return new ChangeHandler();
+ return new ChangeHandler((JMenu) c, this);
}
/**
@@ -180,12 +181,6 @@ public class BasicMenuUI extends BasicMenuItemUI
*/
public Dimension getMaximumSize(JComponent c)
{
- // If this menu is in a popup menu, treat it like a regular JMenuItem
- if (!((JMenu)c).isTopLevelMenu())
- {
- JMenuItem menuItem = new JMenuItem(((JMenu)c).getText(), ((JMenu)c).getIcon());
- return menuItem.getMaximumSize();
- }
return c.getPreferredSize();
}
@@ -205,20 +200,17 @@ public class BasicMenuUI extends BasicMenuItemUI
*/
protected void installDefaults()
{
- UIDefaults defaults = UIManager.getLookAndFeelDefaults();
-
- menuItem.setBackground(defaults.getColor("Menu.background"));
- menuItem.setBorder(defaults.getBorder("Menu.border"));
- menuItem.setFont(defaults.getFont("Menu.font"));
- menuItem.setForeground(defaults.getColor("Menu.foreground"));
- menuItem.setMargin(defaults.getInsets("Menu.margin"));
- acceleratorFont = defaults.getFont("Menu.acceleratorFont");
- acceleratorForeground = defaults.getColor("Menu.acceleratorForeground");
- acceleratorSelectionForeground = defaults.getColor("Menu.acceleratorSelectionForeground");
- selectionBackground = defaults.getColor("Menu.selectionBackground");
- selectionForeground = defaults.getColor("Menu.selectionForeground");
- arrowIcon = defaults.getIcon("Menu.arrowIcon");
- oldBorderPainted = defaults.getBoolean("Menu.borderPainted");
+ LookAndFeel.installBorder(menuItem, "Menu.border");
+ LookAndFeel.installColorsAndFont(menuItem, "Menu.background",
+ "Menu.foreground", "Menu.font");
+ menuItem.setMargin(UIManager.getInsets("Menu.margin"));
+ acceleratorFont = UIManager.getFont("Menu.acceleratorFont");
+ acceleratorForeground = UIManager.getColor("Menu.acceleratorForeground");
+ acceleratorSelectionForeground = UIManager.getColor("Menu.acceleratorSelectionForeground");
+ selectionBackground = UIManager.getColor("Menu.selectionBackground");
+ selectionForeground = UIManager.getColor("Menu.selectionForeground");
+ arrowIcon = UIManager.getIcon("Menu.arrowIcon");
+ oldBorderPainted = UIManager.getBoolean("Menu.borderPainted");
menuItem.setOpaque(true);
}
@@ -245,6 +237,7 @@ public class BasicMenuUI extends BasicMenuItemUI
protected void setupPostTimer(JMenu menu)
{
+ // TODO: Implement this properly.
}
/**
@@ -356,6 +349,7 @@ public class BasicMenuUI extends BasicMenuItemUI
public void mouseMoved(MouseEvent e)
{
+ // TODO: What should be done here, if anything?
}
public void mousePressed(MouseEvent e)
@@ -421,10 +415,13 @@ public class BasicMenuUI extends BasicMenuItemUI
public void menuDeselected(MenuEvent e)
{
JMenu menu = (JMenu) menuItem;
- if (menu.isTopLevelMenu())
- ((JMenuBar) menu.getParent()).getSelectionModel().clearSelection();
- else
- ((JPopupMenu) menu.getParent()).getSelectionModel().clearSelection();
+ if (menu.getParent() != null)
+ {
+ if (menu.isTopLevelMenu())
+ ((JMenuBar) menu.getParent()).getSelectionModel().clearSelection();
+ else
+ ((JPopupMenu) menu.getParent()).getSelectionModel().clearSelection();
+ }
}
/**
@@ -456,6 +453,7 @@ public class BasicMenuUI extends BasicMenuItemUI
*/
public void propertyChange(PropertyChangeEvent e)
{
+ // TODO: Implement this properly.
}
}
@@ -464,9 +462,40 @@ public class BasicMenuUI extends BasicMenuItemUI
*/
public class ChangeHandler implements ChangeListener
{
+ /**
+ * Not used.
+ */
+ public boolean isSelected;
+
+ /**
+ * Not used.
+ */
+ public JMenu menu;
+
+ /**
+ * Not used.
+ */
+ public BasicMenuUI ui;
+
+ /**
+ * Not used.
+ */
+ public Component wasFocused;
+
+ /**
+ * Not used.
+ */
+ public ChangeHandler(JMenu m, BasicMenuUI ui)
+ {
+ // Not used.
+ }
+
+ /**
+ * Not used.
+ */
public void stateChanged(ChangeEvent e)
{
- // FIXME: It seems that this class is not used anywhere
+ // Not used.
}
}
@@ -506,6 +535,7 @@ public class BasicMenuUI extends BasicMenuItemUI
*/
public void menuDragMouseExited(MenuDragMouseEvent e)
{
+ // TODO: What should be done here, if anything?
}
/**
@@ -516,6 +546,7 @@ public class BasicMenuUI extends BasicMenuItemUI
*/
public void menuDragMouseReleased(MenuDragMouseEvent e)
{
+ // TODO: What should be done here, if anything?
}
}
@@ -532,6 +563,7 @@ public class BasicMenuUI extends BasicMenuItemUI
*/
public void menuKeyPressed(MenuKeyEvent e)
{
+ // TODO: What should be done here, if anything?
}
/**
@@ -541,6 +573,7 @@ public class BasicMenuUI extends BasicMenuItemUI
*/
public void menuKeyReleased(MenuKeyEvent e)
{
+ // TODO: What should be done here, if anything?
}
/**
@@ -551,6 +584,7 @@ public class BasicMenuUI extends BasicMenuItemUI
*/
public void menuKeyTyped(MenuKeyEvent e)
{
+ // TODO: What should be done here, if anything?
}
}
}
diff --git a/javax/swing/plaf/basic/BasicOptionPaneUI.java b/javax/swing/plaf/basic/BasicOptionPaneUI.java
index aa648d74d..6b37d315f 100644
--- a/javax/swing/plaf/basic/BasicOptionPaneUI.java
+++ b/javax/swing/plaf/basic/BasicOptionPaneUI.java
@@ -70,8 +70,8 @@ import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
+import javax.swing.LookAndFeel;
import javax.swing.SwingUtilities;
-import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.plaf.ComponentUI;
@@ -141,13 +141,14 @@ public class BasicOptionPaneUI extends OptionPaneUI
optionPane);
if (inf != null)
{
- try
- {
- inf.setClosed(true);
- }
- catch (PropertyVetoException pve)
- {
- }
+ try
+ {
+ inf.setClosed(true);
+ }
+ catch (PropertyVetoException pve)
+ {
+ // We do nothing if attempt has been vetoed.
+ }
}
}
}
@@ -405,16 +406,30 @@ public class BasicOptionPaneUI extends OptionPaneUI
|| e.getPropertyName().equals(JOptionPane.WANTS_INPUT_PROPERTY)
|| e.getPropertyName().equals(JOptionPane.SELECTION_VALUES_PROPERTY))
{
- optionPane.removeAll();
- messageAreaContainer = createMessageArea();
- optionPane.add(messageAreaContainer);
- optionPane.add(buttonContainer);
+ optionPane.remove(messageAreaContainer);
+ messageAreaContainer = createMessageArea();
+ optionPane.add(messageAreaContainer);
+ Container newButtons = createButtonArea();
+ optionPane.remove(buttonContainer);
+ optionPane.add(newButtons);
+ buttonContainer = newButtons;
+ optionPane.add(buttonContainer);
}
optionPane.invalidate();
optionPane.repaint();
}
}
+ /**
+ * The minimum width for JOptionPanes.
+ */
+ public static final int MinimumWidth = 262;
+
+ /**
+ * The minimum height for JOptionPanes.
+ */
+ public static final int MinimumHeight = 90;
+
/** Whether the JOptionPane contains custom components. */
protected boolean hasCustomComponents = false;
@@ -433,12 +448,6 @@ public class BasicOptionPaneUI extends OptionPaneUI
/** The component that receives input when the JOptionPane needs it. */
protected JComponent inputComponent;
- /** The minimum height of the JOptionPane. */
- public static int minimumHeight;
-
- /** The minimum width of the JOptionPane. */
- public static int minimumWidth;
-
/** The minimum dimensions of the JOptionPane. */
protected Dimension minimumSize;
@@ -518,6 +527,7 @@ public class BasicOptionPaneUI extends OptionPaneUI
*/
public void paintIcon(Component c, Graphics g, int x, int y)
{
+ // Nothing to do here.
}
}
@@ -637,6 +647,7 @@ public class BasicOptionPaneUI extends OptionPaneUI
*/
public BasicOptionPaneUI()
{
+ // Nothing to do here.
}
/**
@@ -941,11 +952,17 @@ public class BasicOptionPaneUI extends OptionPaneUI
{
case JOptionPane.YES_NO_OPTION:
return new Object[] { YES_STRING, NO_STRING };
- case JOptionPane.DEFAULT_OPTION:
case JOptionPane.YES_NO_CANCEL_OPTION:
return new Object[] { YES_STRING, NO_STRING, CANCEL_STRING };
case JOptionPane.OK_CANCEL_OPTION:
return new Object[] { OK_STRING, CANCEL_STRING };
+ case JOptionPane.DEFAULT_OPTION:
+ return (optionPane.getWantsInput() ) ?
+ new Object[] { OK_STRING, CANCEL_STRING } :
+ ( optionPane.getMessageType() == JOptionPane.QUESTION_MESSAGE ) ?
+ new Object[] { YES_STRING, NO_STRING, CANCEL_STRING } :
+ // ERROR_MESSAGE, INFORMATION_MESSAGE, WARNING_MESSAGE, PLAIN_MESSAGE
+ new Object[] { OK_STRING };
}
return null;
}
@@ -1142,21 +1159,17 @@ public class BasicOptionPaneUI extends OptionPaneUI
*/
protected void installDefaults()
{
- UIDefaults defaults = UIManager.getLookAndFeelDefaults();
-
- optionPane.setFont(defaults.getFont("OptionPane.font"));
- optionPane.setBackground(defaults.getColor("OptionPane.background"));
- optionPane.setForeground(defaults.getColor("OptionPane.foreground"));
- optionPane.setBorder(defaults.getBorder("OptionPane.border"));
+ LookAndFeel.installColorsAndFont(optionPane, "OptionPane.background",
+ "OptionPane.foreground",
+ "OptionPane.font");
+ LookAndFeel.installBorder(optionPane, "OptionPane.border");
optionPane.setOpaque(true);
- messageBorder = defaults.getBorder("OptionPane.messageAreaBorder");
- messageForeground = defaults.getColor("OptionPane.messageForeground");
- buttonBorder = defaults.getBorder("OptionPane.buttonAreaBorder");
+ messageBorder = UIManager.getBorder("OptionPane.messageAreaBorder");
+ messageForeground = UIManager.getColor("OptionPane.messageForeground");
+ buttonBorder = UIManager.getBorder("OptionPane.buttonAreaBorder");
- minimumSize = defaults.getDimension("OptionPane.minimumSize");
- minimumWidth = minimumSize.width;
- minimumHeight = minimumSize.height;
+ minimumSize = UIManager.getDimension("OptionPane.minimumSize");
// FIXME: Image icons don't seem to work properly right now.
// Once they do, replace the synthetic icons with these ones.
diff --git a/javax/swing/plaf/basic/BasicPanelUI.java b/javax/swing/plaf/basic/BasicPanelUI.java
index b715c57b3..783cec473 100644
--- a/javax/swing/plaf/basic/BasicPanelUI.java
+++ b/javax/swing/plaf/basic/BasicPanelUI.java
@@ -40,8 +40,7 @@ package javax.swing.plaf.basic;
import javax.swing.JComponent;
import javax.swing.JPanel;
-import javax.swing.UIDefaults;
-import javax.swing.UIManager;
+import javax.swing.LookAndFeel;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.PanelUI;
@@ -64,8 +63,29 @@ public class BasicPanelUI extends PanelUI
public void installDefaults(JPanel p)
{
- UIDefaults defaults = UIManager.getLookAndFeelDefaults();
- p.setBackground(defaults.getColor("Panel.background"));
+ LookAndFeel.installColorsAndFont(p, "Panel.background", "Panel.foreground",
+ "Panel.font");
p.setOpaque(true);
}
+
+ /**
+ * Uninstalls this UI from the JPanel.
+ *
+ * @param c the JPanel from which to uninstall this UI
+ */
+ public void uninstallUI(JComponent c)
+ {
+ uninstallDefaults((JPanel) c);
+ }
+
+ /**
+ * Uninstalls the UI defaults that have been install through
+ * {@link #installDefaults}.
+ *
+ * @param p the panel from which to uninstall the UI defaults
+ */
+ protected void uninstallDefaults(JPanel p)
+ {
+ // Nothing to do here.
+ }
}
diff --git a/javax/swing/plaf/basic/BasicPasswordFieldUI.java b/javax/swing/plaf/basic/BasicPasswordFieldUI.java
index 089162ce3..76dcfc435 100644
--- a/javax/swing/plaf/basic/BasicPasswordFieldUI.java
+++ b/javax/swing/plaf/basic/BasicPasswordFieldUI.java
@@ -49,6 +49,7 @@ public class BasicPasswordFieldUI extends BasicTextFieldUI
{
public BasicPasswordFieldUI()
{
+ // Nothing to do here.
}
public View create(Element elem)
diff --git a/javax/swing/plaf/basic/BasicPopupMenuUI.java b/javax/swing/plaf/basic/BasicPopupMenuUI.java
index 247117bc9..46bcd3679 100644
--- a/javax/swing/plaf/basic/BasicPopupMenuUI.java
+++ b/javax/swing/plaf/basic/BasicPopupMenuUI.java
@@ -53,12 +53,11 @@ import javax.swing.JLayeredPane;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
+import javax.swing.LookAndFeel;
import javax.swing.MenuElement;
import javax.swing.MenuSelectionManager;
import javax.swing.RootPaneContainer;
import javax.swing.SwingUtilities;
-import javax.swing.UIDefaults;
-import javax.swing.UIManager;
import javax.swing.event.MouseInputListener;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
@@ -131,12 +130,9 @@ public class BasicPopupMenuUI extends PopupMenuUI
*/
public void installDefaults()
{
- UIDefaults defaults = UIManager.getLookAndFeelDefaults();
-
- popupMenu.setBackground(defaults.getColor("PopupMenu.background"));
- popupMenu.setBorder(defaults.getBorder("PopupMenu.border"));
- popupMenu.setFont(defaults.getFont("PopupMenu.font"));
- popupMenu.setForeground(defaults.getColor("PopupMenu.foreground"));
+ LookAndFeel.installColorsAndFont(popupMenu, "PopupMenu.background",
+ "PopupMenu.foreground", "PopupMenu.font");
+ LookAndFeel.installBorder(popupMenu, "PopupMenu.border");
popupMenu.setOpaque(true);
}
diff --git a/javax/swing/plaf/basic/BasicProgressBarUI.java b/javax/swing/plaf/basic/BasicProgressBarUI.java
index d00628f53..744ddf712 100644
--- a/javax/swing/plaf/basic/BasicProgressBarUI.java
+++ b/javax/swing/plaf/basic/BasicProgressBarUI.java
@@ -56,10 +56,10 @@ import java.beans.PropertyChangeListener;
import javax.swing.JComponent;
import javax.swing.JProgressBar;
+import javax.swing.LookAndFeel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
-import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
@@ -712,21 +712,19 @@ public class BasicProgressBarUI extends ProgressBarUI
*/
protected void installDefaults()
{
- UIDefaults defaults = UIManager.getLookAndFeelDefaults();
-
- progressBar.setFont(defaults.getFont("ProgressBar.font"));
- progressBar.setForeground(defaults.getColor("ProgressBar.foreground"));
- progressBar.setBackground(defaults.getColor("ProgressBar.background"));
- progressBar.setBorder(defaults.getBorder("ProgressBar.border"));
+ LookAndFeel.installColorsAndFont(progressBar, "ProgressBar.background",
+ "ProgressBar.foreground",
+ "ProgressBar.font");
+ LookAndFeel.installBorder(progressBar, "ProgressBar.border");
progressBar.setOpaque(true);
- selectionForeground = defaults.getColor("ProgressBar.selectionForeground");
- selectionBackground = defaults.getColor("ProgressBar.selectionBackground");
- cellLength = defaults.getInt("ProgressBar.cellLength");
- cellSpacing = defaults.getInt("ProgressBar.cellSpacing");
+ selectionForeground = UIManager.getColor("ProgressBar.selectionForeground");
+ selectionBackground = UIManager.getColor("ProgressBar.selectionBackground");
+ cellLength = UIManager.getInt("ProgressBar.cellLength");
+ cellSpacing = UIManager.getInt("ProgressBar.cellSpacing");
- int repaintInterval = defaults.getInt("ProgressBar.repaintInterval");
- int cycleTime = defaults.getInt("ProgressBar.cycleTime");
+ int repaintInterval = UIManager.getInt("ProgressBar.repaintInterval");
+ int cycleTime = UIManager.getInt("ProgressBar.cycleTime");
if (cycleTime % repaintInterval != 0
&& (cycleTime / repaintInterval) % 2 != 0)
diff --git a/javax/swing/plaf/basic/BasicRadioButtonMenuItemUI.java b/javax/swing/plaf/basic/BasicRadioButtonMenuItemUI.java
index fa74a008b..8af5ff7f9 100644
--- a/javax/swing/plaf/basic/BasicRadioButtonMenuItemUI.java
+++ b/javax/swing/plaf/basic/BasicRadioButtonMenuItemUI.java
@@ -59,8 +59,6 @@ public class BasicRadioButtonMenuItemUI extends BasicMenuItemUI
public BasicRadioButtonMenuItemUI()
{
super();
- UIDefaults defaults = UIManager.getLookAndFeelDefaults();
- checkIcon = defaults.getIcon("RadioButtonMenuItem.checkIcon");
}
/**
@@ -98,5 +96,7 @@ public class BasicRadioButtonMenuItemUI extends BasicMenuItemUI
MenuElement[] path,
MenuSelectionManager manager)
{
+ // TODO: May not be implemented properly.
+ item.processMouseEvent(e, path, manager);
}
}
diff --git a/javax/swing/plaf/basic/BasicRadioButtonUI.java b/javax/swing/plaf/basic/BasicRadioButtonUI.java
index fbd21241a..f3698e859 100644
--- a/javax/swing/plaf/basic/BasicRadioButtonUI.java
+++ b/javax/swing/plaf/basic/BasicRadioButtonUI.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import java.awt.Color;
+import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Rectangle;
@@ -93,6 +95,10 @@ public class BasicRadioButtonUI extends BasicToggleButtonUI
b.setIcon(icon);
if (b.getSelectedIcon() == null)
b.setSelectedIcon(icon);
+ if (b.getDisabledIcon() == null)
+ b.setDisabledIcon(icon);
+ if (b.getDisabledSelectedIcon() == null)
+ b.setDisabledSelectedIcon(icon);
}
/**
@@ -139,10 +145,14 @@ public class BasicRadioButtonUI extends BasicToggleButtonUI
g.setFont(f);
Icon currentIcon = null;
- if (b.isSelected())
+ if (b.isSelected() && b.isEnabled())
currentIcon = b.getSelectedIcon();
- else
+ else if (!b.isSelected() && b.isEnabled())
currentIcon = b.getIcon();
+ else if (b.isSelected() && !b.isEnabled())
+ currentIcon = b.getDisabledSelectedIcon();
+ else // (!b.isSelected() && !b.isEnabled())
+ currentIcon = b.getDisabledIcon();
SwingUtilities.calculateInnerArea(b, vr);
String text = SwingUtilities.layoutCompoundLabel
@@ -157,6 +167,25 @@ public class BasicRadioButtonUI extends BasicToggleButtonUI
}
if (text != null)
paintText(g, b, tr, text);
- paintFocus(g, b, vr, tr, ir);
+ // TODO: Figure out what is the size parameter?
+ if (b.hasFocus() && b.isFocusPainted() && b.isEnabled())
+ paintFocus(g, tr, null);
+ }
+
+ /**
+ * Paints the focus indicator for JRadioButtons.
+ *
+ * @param g the graphics context
+ * @param tr the rectangle for the text label
+ * @param size the size (??)
+ */
+ // TODO: Figure out what for is the size parameter.
+ protected void paintFocus(Graphics g, Rectangle tr, Dimension size)
+ {
+ Color focusColor = UIManager.getColor(getPropertyPrefix() + ".focus");
+ Color saved = g.getColor();
+ g.setColor(focusColor);
+ g.drawRect(tr.x, tr.y, tr.width, tr.height);
+ g.setColor(saved);
}
}
diff --git a/javax/swing/plaf/basic/BasicRootPaneUI.java b/javax/swing/plaf/basic/BasicRootPaneUI.java
index d97f7baea..2a698e8a1 100644
--- a/javax/swing/plaf/basic/BasicRootPaneUI.java
+++ b/javax/swing/plaf/basic/BasicRootPaneUI.java
@@ -42,6 +42,7 @@ import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JComponent;
+import javax.swing.JRootPane;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.RootPaneUI;
@@ -56,11 +57,127 @@ public class BasicRootPaneUI extends RootPaneUI
public void installUI(JComponent c)
{
- c.setBackground(UIManager.getColor("control"));
super.installUI(c);
+ if (c instanceof JRootPane)
+ {
+ JRootPane rp = (JRootPane) c;
+ installDefaults(rp);
+ installComponents(rp);
+ installListeners(rp);
+ installKeyboardActions(rp);
+ }
+ }
+
+ /**
+ * Installs the look and feel defaults for JRootPane.
+ *
+ * @param rp the root pane to install the defaults to
+ */
+ protected void installDefaults(JRootPane rp)
+ {
+ // Is this ok?
+ rp.setBackground(UIManager.getColor("control"));
+ }
+
+ /**
+ * Installs additional look and feel components to the root pane.
+ *
+ * @param rp the root pane to install the components to
+ */
+ protected void installComponents(JRootPane rp)
+ {
+ // All components are initialized in the JRootPane constructor, and since
+ // the createXXXPane methods are protected, I see no reasonable way,
+ // and no need to initialize them here. This method is here anyway
+ // for compatibility and to provide the necessary hooks to subclasses.
+ }
+
+ /**
+ * Installs any look and feel specific listeners on the root pane.
+ *
+ * @param rp the root pane to install the listeners to
+ */
+ protected void installListeners(JRootPane rp)
+ {
+ rp.addPropertyChangeListener(this);
+ }
+
+ /**
+ * Installs look and feel keyboard actions on the root pane.
+ *
+ * @param rp the root pane to install the keyboard actions to
+ */
+ protected void installKeyboardActions(JRootPane rp)
+ {
+ // We currently do not install any keyboard actions here.
+ // This method is here anyway for compatibility and to provide
+ // the necessary hooks to subclasses.
}
public void propertyChange(PropertyChangeEvent event)
{
+ // TODO: Implement this properly.
+ }
+
+ /**
+ * Uninstalls this UI from the root pane. This calls
+ * {@link #uninstallDefaults}, {@link #uninstallComponents},
+ * {@link #uninstallListeners}, {@link #uninstallKeyboardActions}
+ * in this order.
+ *
+ * @param c the root pane to uninstall the UI from
+ */
+ public void uninstallUI(JComponent c)
+ {
+ super.uninstallUI(c);
+ if (c instanceof JRootPane)
+ {
+ JRootPane rp = (JRootPane) c;
+ uninstallDefaults(rp);
+ uninstallComponents(rp);
+ uninstallListeners(rp);
+ uninstallKeyboardActions(rp);
+ }
+ }
+
+ /**
+ * Uninstalls the look and feel defaults that have been installed in
+ * {@link #installDefaults}.
+ *
+ * @param rp the root pane to uninstall the defaults from
+ */
+ protected void uninstallDefaults(JRootPane rp)
+ {
+ // We do nothing here.
+ }
+
+ /**
+ * Uninstalls look and feel components from the root pane.
+ *
+ * @param rp the root pane to uninstall the components from
+ */
+ protected void uninstallComponents(JRootPane rp)
+ {
+ // We do nothing here.
+ }
+
+ /**
+ * Uninstalls any look and feel specific listeners from the root pane.
+ *
+ * @param rp the root pane to uninstall the listeners from
+ */
+ protected void uninstallListeners(JRootPane rp)
+ {
+ rp.removePropertyChangeListener(this);
+ }
+
+ /**
+ * Uninstalls look and feel keyboard actions from the root pane.
+ *
+ * @param rp the root pane to uninstall the keyboard actions from
+ */
+ protected void uninstallKeyboardActions(JRootPane rp)
+ {
+ // We do nothing here.
}
}
diff --git a/javax/swing/plaf/basic/BasicScrollBarUI.java b/javax/swing/plaf/basic/BasicScrollBarUI.java
index 58d8fc1f7..2f5eaf391 100644
--- a/javax/swing/plaf/basic/BasicScrollBarUI.java
+++ b/javax/swing/plaf/basic/BasicScrollBarUI.java
@@ -58,6 +58,7 @@ import javax.swing.BoundedRangeModel;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JScrollBar;
+import javax.swing.LookAndFeel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
@@ -80,6 +81,7 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager,
*/
protected class ArrowButtonListener extends MouseAdapter
{
+
/**
* Move the thumb in the direction specified by the button's arrow. If
* this button is held down, then it should keep moving the thumb.
@@ -91,9 +93,10 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager,
scrollTimer.stop();
scrollListener.setScrollByBlock(false);
if (e.getSource() == incrButton)
- scrollListener.setDirection(POSITIVE_SCROLL);
- else
- scrollListener.setDirection(NEGATIVE_SCROLL);
+ scrollListener.setDirection(POSITIVE_SCROLL);
+ else if (e.getSource() == decrButton)
+ scrollListener.setDirection(NEGATIVE_SCROLL);
+ scrollTimer.setDelay(100);
scrollTimer.start();
}
@@ -105,6 +108,11 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager,
public void mouseReleased(MouseEvent e)
{
scrollTimer.stop();
+ scrollTimer.setDelay(300);
+ if (e.getSource() == incrButton)
+ scrollByUnit(POSITIVE_SCROLL);
+ else if (e.getSource() == decrButton)
+ scrollByUnit(NEGATIVE_SCROLL);
}
}
@@ -120,9 +128,8 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager,
*/
public void stateChanged(ChangeEvent e)
{
- // System.err.println(this + ".stateChanged()");
calculatePreferredSize();
- getThumbBounds();
+ updateThumbRect();
scrollbar.repaint();
}
}
@@ -141,31 +148,27 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager,
{
if (e.getPropertyName().equals("model"))
{
- ((BoundedRangeModel) e.getOldValue()).removeChangeListener(modelListener);
- scrollbar.getModel().addChangeListener(modelListener);
- getThumbBounds();
+ ((BoundedRangeModel) e.getOldValue()).removeChangeListener(modelListener);
+ scrollbar.getModel().addChangeListener(modelListener);
+ updateThumbRect();
}
else if (e.getPropertyName().equals("orientation"))
{
- incrButton.removeMouseListener(buttonListener);
- decrButton.removeMouseListener(buttonListener);
- int orientation = scrollbar.getOrientation();
- switch (orientation)
- {
- case (JScrollBar.HORIZONTAL):
- incrButton = createIncreaseButton(EAST);
- decrButton = createDecreaseButton(WEST);
- break;
- default:
- incrButton = createIncreaseButton(SOUTH);
- decrButton = createDecreaseButton(NORTH);
- break;
- }
- incrButton.addMouseListener(buttonListener);
- decrButton.addMouseListener(buttonListener);
- calculatePreferredSize();
+ uninstallListeners();
+ uninstallComponents();
+ uninstallDefaults();
+ installDefaults();
+ installComponents();
+ installListeners();
+ }
+ else if (e.getPropertyName().equals("enabled"))
+ {
+ Boolean b = (Boolean) e.getNewValue();
+ if (incrButton != null)
+ incrButton.setEnabled(b.booleanValue());
+ if (decrButton != null)
+ decrButton.setEnabled(b.booleanValue());
}
- scrollbar.repaint();
}
}
@@ -242,7 +245,7 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager,
scrollbar.repaint();
return;
}
- scrollByBlock(direction);
+ scrollByBlock(direction);
}
else
scrollByUnit(direction);
@@ -316,9 +319,6 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager,
else
value = valueForYPosition(currentMouseY);
- if (value == scrollbar.getValue())
- return;
-
if (! thumbRect.contains(e.getPoint()))
{
scrollTimer.stop();
@@ -333,6 +333,7 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager,
trackHighlight = DECREASE_HIGHLIGHT;
scrollListener.setDirection(NEGATIVE_SCROLL);
}
+ scrollTimer.setDelay(100);
scrollTimer.start();
}
else
@@ -343,8 +344,10 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager,
// "lower" edge of the thumb. The value at which
// the cursor is at must be greater or equal
// to that value.
+
+ scrollListener.setScrollByBlock(false);
scrollbar.setValueIsAdjusting(true);
- offset = value - scrollbar.getValue();
+ offset = value - scrollbar.getValue();
}
scrollbar.repaint();
}
@@ -357,11 +360,19 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager,
*/
public void mouseReleased(MouseEvent e)
{
- trackHighlight = NO_HIGHLIGHT;
scrollTimer.stop();
+ scrollTimer.setDelay(300);
+ currentMouseX = e.getX();
+ currentMouseY = e.getY();
- if (scrollbar.getValueIsAdjusting())
- scrollbar.setValueIsAdjusting(false);
+ if (shouldScroll(POSITIVE_SCROLL))
+ scrollByBlock(POSITIVE_SCROLL);
+ else if (shouldScroll(NEGATIVE_SCROLL))
+ scrollByBlock(NEGATIVE_SCROLL);
+
+ trackHighlight = NO_HIGHLIGHT;
+ scrollListener.setScrollByBlock(false);
+ scrollbar.setValueIsAdjusting(true);
scrollbar.repaint();
}
@@ -381,6 +392,9 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager,
else
value = valueForYPosition(currentMouseY);
+ if (thumbRect.contains(currentMouseX, currentMouseY))
+ return false;
+
if (direction == POSITIVE_SCROLL)
return (value > scrollbar.getValue());
else
@@ -517,11 +531,7 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager,
*/
protected JButton createIncreaseButton(int orientation)
{
- if (incrButton == null)
- incrButton = new BasicArrowButton(orientation);
- else
- ((BasicArrowButton) incrButton).setDirection(orientation);
- return incrButton;
+ return new BasicArrowButton(orientation);
}
/**
@@ -534,11 +544,7 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager,
*/
protected JButton createDecreaseButton(int orientation)
{
- if (decrButton == null)
- decrButton = new BasicArrowButton(orientation);
- else
- ((BasicArrowButton) decrButton).setDirection(orientation);
- return decrButton;
+ return new BasicArrowButton(orientation);
}
/**
@@ -602,7 +608,7 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager,
*/
public Dimension getMaximumSize(JComponent c)
{
- return getPreferredSize(c);
+ return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
}
/**
@@ -644,7 +650,6 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager,
*/
void calculatePreferredSize()
{
- // System.err.println(this + ".calculatePreferredSize()");
int height;
int width;
height = width = 0;
@@ -707,48 +712,6 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager,
*/
protected Rectangle getThumbBounds()
{
- int max = scrollbar.getMaximum();
- int min = scrollbar.getMinimum();
- int value = scrollbar.getValue();
- int extent = scrollbar.getVisibleAmount();
-
- // System.err.println(this + ".getThumbBounds()");
- if (max == min)
- {
- thumbRect.x = trackRect.x;
- thumbRect.y = trackRect.y;
- if (scrollbar.getOrientation() == HORIZONTAL)
- {
- thumbRect.width = getMinimumThumbSize().width;
- thumbRect.height = trackRect.height;
- }
- else
- {
- thumbRect.width = trackRect.width;
- thumbRect.height = getMinimumThumbSize().height;
- }
- return thumbRect;
- }
-
- if (scrollbar.getOrientation() == HORIZONTAL)
- {
- thumbRect.x = trackRect.x;
- thumbRect.x += (value - min) * trackRect.width / (max - min);
- thumbRect.y = trackRect.y;
-
- thumbRect.width = Math.max(extent * trackRect.width / (max - min),
- getMinimumThumbSize().width);
- thumbRect.height = trackRect.height;
- }
- else
- {
- thumbRect.x = trackRect.x;
- thumbRect.y = trackRect.y + value * trackRect.height / (max - min);
-
- thumbRect.width = trackRect.width;
- thumbRect.height = Math.max(extent * trackRect.height / (max - min),
- getMinimumThumbSize().height);
- }
return thumbRect;
}
@@ -760,22 +723,6 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager,
*/
protected Rectangle getTrackBounds()
{
- SwingUtilities.calculateInnerArea(scrollbar, trackRect);
-
- if (scrollbar.getOrientation() == SwingConstants.HORIZONTAL)
- {
- trackRect.width -= incrButton.getPreferredSize().getWidth();
- trackRect.width -= decrButton.getPreferredSize().getWidth();
-
- trackRect.x += decrButton.getPreferredSize().getWidth();
- }
- else
- {
- trackRect.height -= incrButton.getPreferredSize().getHeight();
- trackRect.height -= decrButton.getPreferredSize().getHeight();
-
- trackRect.y += incrButton.getPreferredSize().getHeight();
- }
return trackRect;
}
@@ -785,6 +732,18 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager,
*/
protected void installComponents()
{
+ if (incrButton != null)
+ scrollbar.add(incrButton);
+ if (decrButton != null)
+ scrollbar.add(decrButton);
+ }
+
+ /**
+ * This method installs the defaults for the scrollbar specified by the
+ * Basic Look and Feel.
+ */
+ protected void installDefaults()
+ {
int orientation = scrollbar.getOrientation();
switch (orientation)
{
@@ -797,31 +756,20 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager,
decrButton = createDecreaseButton(NORTH);
break;
}
- scrollbar.add(incrButton);
- scrollbar.add(decrButton);
- }
- /**
- * This method installs the defaults for the scrollbar specified by the
- * Basic Look and Feel.
- */
- protected void installDefaults()
- {
- UIDefaults defaults = UIManager.getLookAndFeelDefaults();
-
- scrollbar.setForeground(defaults.getColor("ScrollBar.foreground"));
- scrollbar.setBackground(defaults.getColor("ScrollBar.background"));
- scrollbar.setBorder(defaults.getBorder("ScrollBar.border"));
+ LookAndFeel.installColors(scrollbar, "ScrollBar.background",
+ "ScrollBar.foreground");
+ LookAndFeel.installBorder(scrollbar, "ScrollBar.border");
scrollbar.setOpaque(true);
scrollbar.setLayout(this);
- thumbColor = defaults.getColor("ScrollBar.thumb");
- thumbDarkShadowColor = defaults.getColor("ScrollBar.thumbDarkShadow");
- thumbHighlightColor = defaults.getColor("ScrollBar.thumbHighlight");
- thumbLightShadowColor = defaults.getColor("ScrollBar.thumbShadow");
+ thumbColor = UIManager.getColor("ScrollBar.thumb");
+ thumbDarkShadowColor = UIManager.getColor("ScrollBar.thumbDarkShadow");
+ thumbHighlightColor = UIManager.getColor("ScrollBar.thumbHighlight");
+ thumbLightShadowColor = UIManager.getColor("ScrollBar.thumbShadow");
- maximumThumbSize = defaults.getDimension("ScrollBar.maximumThumbSize");
- minimumThumbSize = defaults.getDimension("ScrollBar.minimumThumbSize");
+ maximumThumbSize = UIManager.getDimension("ScrollBar.maximumThumbSize");
+ minimumThumbSize = UIManager.getDimension("ScrollBar.minimumThumbSize");
}
/**
@@ -873,11 +821,10 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager,
trackRect = new Rectangle();
thumbRect = new Rectangle();
- scrollTimer = new Timer(50, null);
- scrollTimer.setRepeats(true);
+ scrollTimer = new Timer(300, null);
+ installDefaults();
installComponents();
- installDefaults();
configureScrollBarColors();
installListeners();
@@ -908,17 +855,20 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager,
*/
protected void layoutHScrollbar(JScrollBar sb)
{
- // All we have to do is layout the 2 buttons?
Rectangle vr = new Rectangle();
SwingUtilities.calculateInnerArea(scrollbar, vr);
- // Update the rectangles.
- getTrackBounds();
- getThumbBounds();
-
Dimension incrDims = incrButton.getPreferredSize();
Dimension decrDims = decrButton.getPreferredSize();
+
+ // calculate and update the track bounds
+ SwingUtilities.calculateInnerArea(scrollbar, trackRect);
+ trackRect.width -= incrDims.getWidth();
+ trackRect.width -= decrDims.getWidth();
+ trackRect.x += decrDims.getWidth();
+ updateThumbRect();
+
decrButton.setBounds(vr.x, vr.y, decrDims.width, trackRect.height);
incrButton.setBounds(trackRect.x + trackRect.width, vr.y, incrDims.width,
trackRect.height);
@@ -934,12 +884,16 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager,
Rectangle vr = new Rectangle();
SwingUtilities.calculateInnerArea(scrollbar, vr);
- // Update rectangles
- getTrackBounds();
- getThumbBounds();
-
Dimension incrDims = incrButton.getPreferredSize();
Dimension decrDims = decrButton.getPreferredSize();
+
+ // Update rectangles
+ SwingUtilities.calculateInnerArea(scrollbar, trackRect);
+ trackRect.height -= incrDims.getHeight();
+ trackRect.height -= decrDims.getHeight();
+ trackRect.y += decrDims.getHeight();
+
+ updateThumbRect();
decrButton.setBounds(vr.x, vr.y, trackRect.width, decrDims.height);
incrButton.setBounds(vr.x, trackRect.y + trackRect.height,
@@ -947,6 +901,58 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager,
}
/**
+ * Updates the thumb rect.
+ */
+ void updateThumbRect()
+ {
+ int max = scrollbar.getMaximum();
+ int min = scrollbar.getMinimum();
+ int value = scrollbar.getValue();
+ int extent = scrollbar.getVisibleAmount();
+ if (max - extent <= min)
+ {
+ if (scrollbar.getOrientation() == JScrollBar.HORIZONTAL)
+ {
+ thumbRect.x = trackRect.x;
+ thumbRect.y = trackRect.y;
+ thumbRect.width = getMinimumThumbSize().width;
+ thumbRect.height = trackRect.height;
+ }
+ else
+ {
+ thumbRect.x = trackRect.x;
+ thumbRect.y = trackRect.y;
+ thumbRect.width = trackRect.width;
+ thumbRect.height = getMinimumThumbSize().height;
+ }
+ }
+ else
+ {
+ if (scrollbar.getOrientation() == JScrollBar.HORIZONTAL)
+ {
+ thumbRect.x = trackRect.x;
+ thumbRect.width = Math.max(extent * trackRect.width / (max - min),
+ getMinimumThumbSize().width);
+ int availableWidth = trackRect.width - thumbRect.width;
+ thumbRect.x += (value - min) * availableWidth / (max - min - extent);
+ thumbRect.y = trackRect.y;
+ thumbRect.height = trackRect.height;
+ }
+ else
+ {
+ thumbRect.x = trackRect.x;
+ thumbRect.height = Math.max(extent * trackRect.height / (max - min),
+ getMinimumThumbSize().height);
+ int availableHeight = trackRect.height - thumbRect.height;
+ thumbRect.y = trackRect.y
+ + (value - min) * availableHeight / (max - min - extent);
+ thumbRect.width = trackRect.width;
+ }
+ }
+
+ }
+
+ /**
* This method returns the minimum size required for the layout.
*
* @param scrollbarContainer The Container that is laid out.
@@ -1124,10 +1130,10 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager,
*/
protected void uninstallComponents()
{
- scrollbar.remove(incrButton);
- scrollbar.remove(decrButton);
- incrButton = null;
- decrButton = null;
+ if (incrButton != null)
+ scrollbar.remove(incrButton);
+ if (decrButton != null)
+ scrollbar.remove(decrButton);
}
/**
@@ -1138,7 +1144,9 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager,
{
scrollbar.setForeground(null);
scrollbar.setBackground(null);
- scrollbar.setBorder(null);
+ LookAndFeel.uninstallBorder(scrollbar);
+ incrButton = null;
+ decrButton = null;
}
/**
@@ -1155,17 +1163,22 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager,
*/
protected void uninstallListeners()
{
- scrollTimer.removeActionListener(scrollListener);
+ if (scrollTimer != null)
+ scrollTimer.removeActionListener(scrollListener);
- scrollbar.getModel().removeChangeListener(modelListener);
- scrollbar.removePropertyChangeListener(propertyChangeListener);
-
- decrButton.removeMouseListener(buttonListener);
- incrButton.removeMouseListener(buttonListener);
-
- scrollbar.removeMouseListener(trackListener);
- scrollbar.removeMouseMotionListener(trackListener);
+ if (scrollbar != null)
+ {
+ scrollbar.getModel().removeChangeListener(modelListener);
+ scrollbar.removePropertyChangeListener(propertyChangeListener);
+ scrollbar.removeMouseListener(trackListener);
+ scrollbar.removeMouseMotionListener(trackListener);
+ }
+ if (decrButton != null)
+ decrButton.removeMouseListener(buttonListener);
+ if (incrButton != null)
+ incrButton.removeMouseListener(buttonListener);
+
propertyChangeListener = null;
modelListener = null;
buttonListener = null;
@@ -1182,8 +1195,8 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager,
*/
public void uninstallUI(JComponent c)
{
- uninstallDefaults();
uninstallListeners();
+ uninstallDefaults();
uninstallComponents();
scrollTimer = null;
diff --git a/javax/swing/plaf/basic/BasicScrollPaneUI.java b/javax/swing/plaf/basic/BasicScrollPaneUI.java
index bd1576f37..277b25a00 100644
--- a/javax/swing/plaf/basic/BasicScrollPaneUI.java
+++ b/javax/swing/plaf/basic/BasicScrollPaneUI.java
@@ -40,13 +40,21 @@ package javax.swing.plaf.basic;
import java.awt.Dimension;
import java.awt.Graphics;
+import java.awt.Point;
+import java.awt.event.MouseWheelEvent;
+import java.awt.event.MouseWheelListener;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
import javax.swing.JComponent;
+import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
+import javax.swing.JViewport;
+import javax.swing.LookAndFeel;
import javax.swing.ScrollPaneConstants;
import javax.swing.ScrollPaneLayout;
-import javax.swing.UIDefaults;
-import javax.swing.UIManager;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.ScrollPaneUI;
@@ -54,9 +62,192 @@ public class BasicScrollPaneUI extends ScrollPaneUI
implements ScrollPaneConstants
{
+ /**
+ * Listens for changes in the state of the horizontal scrollbar's model and
+ * updates the scrollpane accordingly.
+ *
+ * @author Roman Kennke (kennke@aicas.com)
+ */
+ public class HSBChangeListener implements ChangeListener
+ {
+
+ /**
+ * Receives notification when the state of the horizontal scrollbar
+ * model has changed.
+ *
+ * @param event the change event
+ */
+ public void stateChanged(ChangeEvent event)
+ {
+ JScrollBar hsb = scrollpane.getHorizontalScrollBar();
+ JViewport vp = scrollpane.getViewport();
+ Point viewPosition = vp.getViewPosition();
+ int xpos = hsb.getValue();
+
+ if (xpos != viewPosition.x)
+ {
+ viewPosition.x = xpos;
+ vp.setViewPosition(viewPosition);
+ }
+
+ viewPosition.y = 0;
+ JViewport columnHeader = scrollpane.getColumnHeader();
+ if (columnHeader != null
+ && !columnHeader.getViewPosition().equals(viewPosition))
+ columnHeader.setViewPosition(viewPosition);
+ }
+
+ }
+
+ /**
+ * Listens for changes in the state of the vertical scrollbar's model and
+ * updates the scrollpane accordingly.
+ *
+ * @author Roman Kennke (kennke@aicas.com)
+ */
+ public class VSBChangeListener implements ChangeListener
+ {
+
+ /**
+ * Receives notification when the state of the vertical scrollbar
+ * model has changed.
+ *
+ * @param event the change event
+ */
+ public void stateChanged(ChangeEvent event)
+ {
+ JScrollBar vsb = scrollpane.getVerticalScrollBar();
+ JViewport vp = scrollpane.getViewport();
+ Point viewPosition = vp.getViewPosition();
+ int ypos = vsb.getValue();
+ if (ypos != viewPosition.y)
+ {
+ viewPosition.y = ypos;
+ vp.setViewPosition(viewPosition);
+ }
+
+ viewPosition.x = 0;
+ JViewport rowHeader = scrollpane.getRowHeader();
+ if (rowHeader != null
+ && !rowHeader.getViewPosition().equals(viewPosition))
+ rowHeader.setViewPosition(viewPosition);
+ }
+
+ }
+
+ /**
+ * Listens for changes of the viewport's extent size and updates the
+ * scrollpane accordingly.
+ *
+ * @author Roman Kennke (kennke@aicas.com)
+ */
+ public class ViewportChangeHandler implements ChangeListener
+ {
+
+ /**
+ * Receives notification when the view's size, position or extent size
+ * changes. When the extents size has changed, this method calls
+ * {@link BasicScrollPaneUI#syncScrollPaneWithViewport()} to adjust the
+ * scrollbars extents as well.
+ *
+ * @param event the change event
+ */
+ public void stateChanged(ChangeEvent event)
+ {
+ JViewport vp = scrollpane.getViewport();
+ JScrollBar hsb = scrollpane.getHorizontalScrollBar();
+ JScrollBar vsb = scrollpane.getVerticalScrollBar();
+ syncScrollPaneWithViewport();
+ }
+
+ }
+
+ /**
+ * Listens for property changes on the scrollpane and update the view
+ * accordingly.
+ *
+ * @author Roman Kennke (kennke@aicas.com)
+ */
+ public class PropertyChangeHandler implements PropertyChangeListener
+ {
+
+ /**
+ * Receives notification when any of the scrollpane's bound property
+ * changes. This method calls the appropriate update method on the
+ * <code>ScrollBarUI</code>.
+ *
+ * @param e the property change event
+ *
+ * @see BasicScrollPaneUI#updateColumnHeader(PropertyChangeEvent)
+ * @see BasicScrollPaneUI#updateRowHeader(PropertyChangeEvent)
+ * @see BasicScrollPaneUI#updateScrollBarDisplayPolicy(PropertyChangeEvent)
+ * @see BasicScrollPaneUI#updateViewport(PropertyChangeEvent)
+ */
+ public void propertyChange(PropertyChangeEvent e)
+ {
+ if (e.getPropertyName().equals("viewport"))
+ updateViewport(e);
+ else if (e.getPropertyName().equals("rowHeader"))
+ updateRowHeader(e);
+ else if (e.getPropertyName().equals("columnHeader"))
+ updateColumnHeader(e);
+ else if (e.getPropertyName().equals("horizontalScrollBarPolicy")
+ || e.getPropertyName().equals("verticalScrollBarPolicy"))
+ updateScrollBarDisplayPolicy(e);
+ }
+
+ }
+
+ /**
+ * Listens for mouse wheel events and update the scrollpane accordingly.
+ *
+ * @author Roman Kennke (kennke@aicas.com)
+ *
+ * @since 1.4
+ */
+ protected class MouseWheelHandler implements MouseWheelListener
+ {
+
+ /**
+ * Receives notification whenever the mouse wheel is moved.
+ *
+ * @param event the mouse wheel event
+ */
+ public void mouseWheelMoved(MouseWheelEvent event)
+ {
+ // TODO: Implement this properly.
+ }
+
+ }
+
/** The Scrollpane for which the UI is provided by this class. */
protected JScrollPane scrollpane;
+ /**
+ * The horizontal scrollbar listener.
+ */
+ protected ChangeListener hsbChangeListener;
+
+ /**
+ * The vertical scrollbar listener.
+ */
+ protected ChangeListener vsbChangeListener;
+
+ /**
+ * The viewport listener.
+ */
+ protected ChangeListener viewportChangeListener;
+
+ /**
+ * The scrollpane property change listener.
+ */
+ protected PropertyChangeListener spPropertyChangeListener;
+
+ /**
+ * The mousewheel listener for the scrollpane.
+ */
+ MouseWheelListener mouseWheelListener;
+
public static ComponentUI createUI(final JComponent c)
{
return new BasicScrollPaneUI();
@@ -65,11 +256,10 @@ public class BasicScrollPaneUI extends ScrollPaneUI
protected void installDefaults(JScrollPane p)
{
scrollpane = p;
- UIDefaults defaults = UIManager.getLookAndFeelDefaults();
- p.setForeground(defaults.getColor("ScrollPane.foreground"));
- p.setBackground(defaults.getColor("ScrollPane.background"));
- p.setFont(defaults.getFont("ScrollPane.font"));
- p.setBorder(defaults.getBorder("ScrollPane.border"));
+ LookAndFeel.installColorsAndFont(p, "ScrollPane.background",
+ "ScrollPane.foreground",
+ "ScrollPane.font");
+ LookAndFeel.installBorder(p, "ScrollPane.border");
p.setOpaque(true);
}
@@ -85,16 +275,141 @@ public class BasicScrollPaneUI extends ScrollPaneUI
public void installUI(final JComponent c)
{
super.installUI(c);
- this.installDefaults((JScrollPane)c);
+ installDefaults((JScrollPane) c);
+ installListeners((JScrollPane) c);
+ installKeyboardActions((JScrollPane) c);
+ }
+
+ /**
+ * Installs the listeners on the scrollbars, the viewport and the scrollpane.
+ *
+ * @param sp the scrollpane on which to install the listeners
+ */
+ protected void installListeners(JScrollPane sp)
+ {
+ if (spPropertyChangeListener == null)
+ spPropertyChangeListener = createPropertyChangeListener();
+ sp.addPropertyChangeListener(spPropertyChangeListener);
+
+ if (hsbChangeListener == null)
+ hsbChangeListener = createHSBChangeListener();
+ sp.getHorizontalScrollBar().getModel().addChangeListener(hsbChangeListener);
+
+ if (vsbChangeListener == null)
+ vsbChangeListener = createVSBChangeListener();
+ sp.getVerticalScrollBar().getModel().addChangeListener(vsbChangeListener);
+
+ if (viewportChangeListener == null)
+ viewportChangeListener = createViewportChangeListener();
+ sp.getViewport().addChangeListener(viewportChangeListener);
+
+ if (mouseWheelListener == null)
+ mouseWheelListener = createMouseWheelListener();
+ sp.addMouseWheelListener(mouseWheelListener);
+ }
+
+ /**
+ * Installs additional keyboard actions on the scrollpane. This is a hook
+ * method provided to subclasses in order to install their own keyboard
+ * actions.
+ *
+ * @param sp the scrollpane to install keyboard actions on
+ */
+ protected void installKeyboardActions(JScrollPane sp)
+ {
+ // TODO: Is this only a hook method or should we actually do something
+ // here? If the latter, than figure out what and implement this.
+ }
+
+ /**
+ * Creates and returns the change listener for the horizontal scrollbar.
+ *
+ * @return the change listener for the horizontal scrollbar
+ */
+ protected ChangeListener createHSBChangeListener()
+ {
+ return new HSBChangeListener();
+ }
+
+ /**
+ * Creates and returns the change listener for the vertical scrollbar.
+ *
+ * @return the change listener for the vertical scrollbar
+ */
+ protected ChangeListener createVSBChangeListener()
+ {
+ return new VSBChangeListener();
+ }
+
+ /**
+ * Creates and returns the change listener for the viewport.
+ *
+ * @return the change listener for the viewport
+ */
+ protected ChangeListener createViewportChangeListener()
+ {
+ return new ViewportChangeHandler();
+ }
+
+ /**
+ * Creates and returns the property change listener for the scrollpane.
+ *
+ * @return the property change listener for the scrollpane
+ */
+ protected PropertyChangeListener createPropertyChangeListener()
+ {
+ return new PropertyChangeHandler();
+ }
+
+ /**
+ * Creates and returns the mouse wheel listener for the scrollpane.
+ *
+ * @return the mouse wheel listener for the scrollpane
+ */
+ protected MouseWheelListener createMouseWheelListener()
+ {
+ return new MouseWheelHandler();
}
public void uninstallUI(final JComponent c)
{
super.uninstallUI(c);
this.uninstallDefaults((JScrollPane)c);
+ uninstallListeners((JScrollPane) c);
+ installKeyboardActions((JScrollPane) c);
+ }
+
+ /**
+ * Uninstalls all the listeners that have been installed in
+ * {@link #installListeners(JScrollPane)}.
+ *
+ * @param c the scrollpane from which to uninstall the listeners
+ */
+ protected void uninstallListeners(JComponent c)
+ {
+ JScrollPane sp = (JScrollPane) c;
+ sp.removePropertyChangeListener(spPropertyChangeListener);
+ sp.getHorizontalScrollBar().getModel()
+ .removeChangeListener(hsbChangeListener);
+ sp.getVerticalScrollBar().getModel()
+ .removeChangeListener(vsbChangeListener);
+ sp.getViewport().removeChangeListener(viewportChangeListener);
+ sp.removeMouseWheelListener(mouseWheelListener);
+ }
+
+ /**
+ * Uninstalls all keyboard actions from the JScrollPane that have been
+ * installed by {@link #installKeyboardActions}. This is a hook method
+ * provided to subclasses to add their own keyboard actions.
+ *
+ * @param sp the scrollpane to uninstall keyboard actions from
+ */
+ protected void uninstallKeyboardActions(JScrollPane sp)
+ {
+ // TODO: Is this only a hook method or should we actually do something
+ // here? If the latter, than figure out what and implement this.
}
-
public Dimension getMinimumSize(JComponent c)
{
JScrollPane p = (JScrollPane ) c;
@@ -107,6 +422,76 @@ public class BasicScrollPaneUI extends ScrollPaneUI
// do nothing; the normal painting-of-children algorithm, along with
// ScrollPaneLayout, does all the relevant work.
}
+
+ /**
+ * Synchronizes the scrollbars with the viewport's extents.
+ */
+ protected void syncScrollPaneWithViewport()
+ {
+ JViewport vp = scrollpane.getViewport();
+
+ // Update the horizontal scrollbar.
+ JScrollBar hsb = scrollpane.getHorizontalScrollBar();
+ hsb.setMaximum(vp.getViewSize().width);
+ hsb.setValue(vp.getViewPosition().x);
+ hsb.setVisibleAmount(vp.getExtentSize().width);
+
+ // Update the vertical scrollbar.
+ JScrollBar vsb = scrollpane.getVerticalScrollBar();
+ vsb.setMaximum(vp.getViewSize().height);
+ vsb.setValue(vp.getViewPosition().y);
+ vsb.setVisibleAmount(vp.getExtentSize().height);
+ }
+
+ /**
+ * Receives notification when the <code>columnHeader</code> property has
+ * changed on the scrollpane.
+ *
+ * @param ev the property change event
+ */
+ protected void updateColumnHeader(PropertyChangeEvent ev)
+ {
+ // TODO: Find out what should be done here. Or is this only a hook?
+ }
+
+ /**
+ * Receives notification when the <code>rowHeader</code> property has changed
+ * on the scrollpane.
+ *
+ * @param ev the property change event
+ */
+ protected void updateRowHeader(PropertyChangeEvent ev)
+ {
+ // TODO: Find out what should be done here. Or is this only a hook?
+ }
+
+ /**
+ * Receives notification when the <code>scrollBarDisplayPolicy</code>
+ * property has changed on the scrollpane.
+ *
+ * @param ev the property change event
+ */
+ protected void updateScrollBarDisplayPolicy(PropertyChangeEvent ev)
+ {
+ // TODO: Find out what should be done here. Or is this only a hook?
+ }
+
+ /**
+ * Receives notification when the <code>viewport</code> property has changed
+ * on the scrollpane.
+ *
+ * This method sets removes the viewportChangeListener from the old viewport
+ * and adds it to the new viewport.
+ *
+ * @param ev the property change event
+ */
+ protected void updateViewport(PropertyChangeEvent ev)
+ {
+ JViewport oldViewport = (JViewport) ev.getOldValue();
+ oldViewport.removeChangeListener(viewportChangeListener);
+ JViewport newViewport = (JViewport) ev.getNewValue();
+ oldViewport.addChangeListener(viewportChangeListener);
+ }
}
diff --git a/javax/swing/plaf/basic/BasicSeparatorUI.java b/javax/swing/plaf/basic/BasicSeparatorUI.java
index 38c9c7a28..97caa3af7 100644
--- a/javax/swing/plaf/basic/BasicSeparatorUI.java
+++ b/javax/swing/plaf/basic/BasicSeparatorUI.java
@@ -41,13 +41,11 @@ package javax.swing.plaf.basic;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
-import java.awt.Insets;
import java.awt.Rectangle;
import javax.swing.JComponent;
import javax.swing.JSeparator;
import javax.swing.SwingUtilities;
-import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.SeparatorUI;
@@ -121,10 +119,8 @@ public class BasicSeparatorUI extends SeparatorUI
*/
protected void installDefaults(JSeparator s)
{
- UIDefaults defaults = UIManager.getLookAndFeelDefaults();
-
- shadow = defaults.getColor("Separator.shadow");
- highlight = defaults.getColor("Separator.highlight");
+ shadow = UIManager.getColor("Separator.shadow");
+ highlight = UIManager.getColor("Separator.highlight");
s.setOpaque(false);
}
@@ -165,8 +161,8 @@ public class BasicSeparatorUI extends SeparatorUI
/**
* The separator is made of two lines. The top line will be
- * the highlight color (or left line if it's vertical). The bottom
- * or right line will be the shadow color. The two lines will
+ * the shadow color (or left line if it's vertical). The bottom
+ * or right line will be the highlight color. The two lines will
* be centered inside the bounds box. If the separator is horizontal,
* then it will be vertically centered, or if it's vertical, it will
* be horizontally centered.
@@ -180,9 +176,6 @@ public class BasicSeparatorUI extends SeparatorUI
SwingUtilities.calculateInnerArea(c, r);
Color saved = g.getColor();
- int midAB = r.width / 2 + r.x;
- int midAD = r.height / 2 + r.y;
-
JSeparator s;
if (c instanceof JSeparator)
s = (JSeparator) c;
@@ -190,21 +183,24 @@ public class BasicSeparatorUI extends SeparatorUI
return;
if (s.getOrientation() == JSeparator.HORIZONTAL)
- {
- g.setColor(highlight);
- g.drawLine(r.x, midAD, r.x + r.width, midAD);
-
- g.setColor(shadow);
- g.drawLine(r.x, midAD + 1, r.x + r.width, midAD + 1);
- }
- else
- {
- g.setColor(highlight);
- g.drawLine(midAB, r.y, midAB, r.y + r.height);
-
- g.setColor(shadow);
- g.drawLine(midAB + 1, r.y, midAB + 1, r.y + r.height);
- }
+ {
+ int midAB = r.height / 2;
+ g.setColor(shadow);
+ g.drawLine(r.x, r.y + midAB - 1, r.x + r.width, r.y + midAB - 1);
+
+ g.setColor(highlight);
+ g.fillRect(r.x, r.y + midAB, r.x + r.width, r.y + midAB);
+ }
+ else
+ {
+ int midAD = r.height / 2 + r.y;
+ g.setColor(shadow);
+ g.drawLine(r.x, r.y, r.x, r.y + r.height);
+
+ g.setColor(highlight);
+ g.fillRect(r.x + midAD, r.y + r.height, r.x + midAD, r.y + r.height);
+ }
+ g.setColor(saved);
}
/**
@@ -217,28 +213,14 @@ public class BasicSeparatorUI extends SeparatorUI
*/
public Dimension getPreferredSize(JComponent c)
{
- Dimension dims = new Dimension(0, 0);
- Insets insets = c.getInsets();
-
+ Dimension pref = new Dimension(2, 0);
if (c instanceof JSeparator)
{
JSeparator s = (JSeparator) c;
-
if (s.getOrientation() == JSeparator.HORIZONTAL)
- {
- dims.height = 2;
- dims.width = 40;
- }
- else
- {
- dims.width = 2;
- dims.height = 40;
- }
+ pref = new Dimension(0, 2);
}
- dims.width += insets.left + insets.right;
- dims.height += insets.top + insets.bottom;
-
- return dims;
+ return pref;
}
/**
@@ -251,7 +233,7 @@ public class BasicSeparatorUI extends SeparatorUI
*/
public Dimension getMinimumSize(JComponent c)
{
- return getPreferredSize(c);
+ return new Dimension(0, 0);
}
/**
@@ -264,6 +246,7 @@ public class BasicSeparatorUI extends SeparatorUI
*/
public Dimension getMaximumSize(JComponent c)
{
- return getPreferredSize(c);
+ return new Dimension(Short.MAX_VALUE,
+ Short.MAX_VALUE);
}
}
diff --git a/javax/swing/plaf/basic/BasicSliderUI.java b/javax/swing/plaf/basic/BasicSliderUI.java
index 0b4058429..26f580519 100644
--- a/javax/swing/plaf/basic/BasicSliderUI.java
+++ b/javax/swing/plaf/basic/BasicSliderUI.java
@@ -60,13 +60,14 @@ import java.beans.PropertyChangeListener;
import java.util.Dictionary;
import java.util.Enumeration;
+import javax.swing.AbstractAction;
import javax.swing.BoundedRangeModel;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JSlider;
+import javax.swing.LookAndFeel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
-import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
@@ -470,6 +471,34 @@ public class BasicSliderUI extends SliderUI
}
}
+ /**
+ * This class is no longer used as of JDK1.3.
+ */
+ public class ActionScroller extends AbstractAction
+ {
+ /**
+ * Not used.
+ *
+ * @param slider not used
+ * @param dir not used
+ * @param block not used
+ */
+ public ActionScroller(JSlider slider, int dir, boolean block)
+ {
+ // Not used.
+ }
+
+ /**
+ * Not used.
+ *
+ * @param event not used
+ */
+ public void actionPerformed(ActionEvent event)
+ {
+ // Not used.
+ }
+ }
+
/** Listener for changes from the model. */
protected ChangeListener changeListener;
@@ -680,16 +709,14 @@ public class BasicSliderUI extends SliderUI
*/
protected void installDefaults(JSlider slider)
{
- UIDefaults defaults = UIManager.getLookAndFeelDefaults();
-
- slider.setForeground(defaults.getColor("Slider.foreground"));
- slider.setBackground(defaults.getColor("Slider.background"));
- shadowColor = defaults.getColor("Slider.shadow");
- highlightColor = defaults.getColor("Slider.highlight");
- focusColor = defaults.getColor("Slider.focus");
- slider.setBorder(defaults.getBorder("Slider.border"));
+ LookAndFeel.installColors(slider, "Slider.background",
+ "Slider.foreground");
+ LookAndFeel.installBorder(slider, "Slider.border");
+ shadowColor = UIManager.getColor("Slider.shadow");
+ highlightColor = UIManager.getColor("Slider.highlight");
+ focusColor = UIManager.getColor("Slider.focus");
+ focusInsets = UIManager.getInsets("Slider.focusInsets");
slider.setOpaque(true);
- focusInsets = defaults.getInsets("Slider.focusInsets");
}
/**
@@ -1465,7 +1492,7 @@ public class BasicSliderUI extends SliderUI
// FIXME: Move this to propertyChangeEvent handler, when we get those.
leftToRightCache = slider.getComponentOrientation() != ComponentOrientation.RIGHT_TO_LEFT;
// FIXME: This next line is only here because the above line is here.
- calculateThumbLocation();
+ calculateGeometry();
if (slider.getPaintTrack())
paintTrack(g);
@@ -1958,7 +1985,7 @@ public class BasicSliderUI extends SliderUI
public void paintThumb(Graphics g)
{
Color saved_color = g.getColor();
-
+
Point a = new Point(thumbRect.x, thumbRect.y);
Point b = new Point(a);
Point c = new Point(a);
diff --git a/javax/swing/plaf/basic/BasicSpinnerUI.java b/javax/swing/plaf/basic/BasicSpinnerUI.java
index 97ab97b89..3b7399eaf 100644
--- a/javax/swing/plaf/basic/BasicSpinnerUI.java
+++ b/javax/swing/plaf/basic/BasicSpinnerUI.java
@@ -53,9 +53,8 @@ import java.beans.PropertyChangeListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JSpinner;
+import javax.swing.LookAndFeel;
import javax.swing.Timer;
-import javax.swing.UIDefaults;
-import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.SpinnerUI;
@@ -167,16 +166,9 @@ public class BasicSpinnerUI extends SpinnerUI
*/
protected void installDefaults()
{
- /* most of it copied from BasicLabelUI, I don't know what keys are
- available, so someone may want to update this. Hence: TODO
- */
- UIDefaults defaults = UIManager.getLookAndFeelDefaults();
- /*
- spinner.setForeground(defaults.getColor("Spinner.foreground"));
- spinner.setBackground(defaults.getColor("Spinner.background"));
- spinner.setFont(defaults.getFont("Spinner.font"));
- spinner.setBorder(defaults.getBorder("Spinner.border"));
- */
+ LookAndFeel.installColorsAndFont(spinner, "Spinner.background",
+ "Spinner.foreground", "Spinner.font");
+ LookAndFeel.installBorder(spinner, "Spinner.border");
spinner.setLayout(createLayout());
spinner.setOpaque(true);
}
diff --git a/javax/swing/plaf/basic/BasicSplitPaneDivider.java b/javax/swing/plaf/basic/BasicSplitPaneDivider.java
index b8674ed2f..69ed2be7c 100644
--- a/javax/swing/plaf/basic/BasicSplitPaneDivider.java
+++ b/javax/swing/plaf/basic/BasicSplitPaneDivider.java
@@ -802,6 +802,7 @@ public class BasicSplitPaneDivider extends Container
*/
protected DividerLayout()
{
+ // Nothing to do here.
}
/**
diff --git a/javax/swing/plaf/basic/BasicSplitPaneUI.java b/javax/swing/plaf/basic/BasicSplitPaneUI.java
index ef8e22823..f9b558eab 100644
--- a/javax/swing/plaf/basic/BasicSplitPaneUI.java
+++ b/javax/swing/plaf/basic/BasicSplitPaneUI.java
@@ -58,7 +58,7 @@ import java.beans.PropertyChangeListener;
import javax.swing.JComponent;
import javax.swing.JSplitPane;
import javax.swing.KeyStroke;
-import javax.swing.UIDefaults;
+import javax.swing.LookAndFeel;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.SplitPaneUI;
@@ -404,7 +404,7 @@ public class BasicSplitPaneUI extends SplitPaneUI
*/
protected void setComponentToSize(Component c, int size, int location,
Insets insets, Dimension containerSize)
- {
+ {
int w = size;
int h = containerSize.height - insets.top - insets.bottom;
int x = location;
@@ -637,7 +637,6 @@ public class BasicSplitPaneUI extends SplitPaneUI
int x = insets.left;
int h = size;
int w = containerSize.width - insets.left - insets.right;
-
c.setBounds(x, y, w, h);
}
@@ -817,15 +816,12 @@ public class BasicSplitPaneUI extends SplitPaneUI
int newSize = splitPane.getDividerSize();
int[] tmpSizes = layoutManager.getSizes();
dividerSize = tmpSizes[2];
- Component left = splitPane.getLeftComponent();
- Component right = splitPane.getRightComponent();
- int newSpace = newSize - tmpSizes[2];
-
+ int newSpace = newSize - tmpSizes[2];
tmpSizes[2] = newSize;
tmpSizes[0] += newSpace / 2;
tmpSizes[1] += newSpace / 2;
-
+
layoutManager.setSizes(tmpSizes);
}
else if (e.getPropertyName().equals(JSplitPane.ORIENTATION_PROPERTY))
@@ -942,6 +938,7 @@ public class BasicSplitPaneUI extends SplitPaneUI
*/
public BasicSplitPaneUI()
{
+ // Nothing to do here.
}
/**
@@ -991,16 +988,16 @@ public class BasicSplitPaneUI extends SplitPaneUI
*/
protected void installDefaults()
{
+ LookAndFeel.installColors(splitPane, "SplitPane.background",
+ "SplitPane.foreground");
+ LookAndFeel.installBorder(splitPane, "SplitPane.border");
divider = createDefaultDivider();
resetLayoutManager();
nonContinuousLayoutDivider = createDefaultNonContinuousLayoutDivider();
splitPane.add(divider, JSplitPane.DIVIDER);
// There is no need to add the nonContinuousLayoutDivider
- UIDefaults defaults = UIManager.getLookAndFeelDefaults();
- splitPane.setBackground(defaults.getColor("SplitPane.background"));
- splitPane.setBorder(defaults.getBorder("SplitPane.border"));
- splitPane.setDividerSize(defaults.getInt("SplitPane.dividerSize"));
+ splitPane.setDividerSize(UIManager.getInt("SplitPane.dividerSize"));
splitPane.setOpaque(true);
}
@@ -1301,15 +1298,41 @@ public class BasicSplitPaneUI extends SplitPaneUI
*/
public void setDividerLocation(JSplitPane jc, int location)
{
+ location = validLocation(location);
+ Container p = jc.getParent();
+ Dimension rightPrefSize = jc.getRightComponent().getPreferredSize();
+ Dimension size = jc.getSize();
+ // check if the size has been set for the splitpane
+ if (size.width == 0 && size.height == 0)
+ size = jc.getPreferredSize();
+
+ if (getOrientation() == 0 && location > size.height)
+ {
+ location = size.height;
+ while (p != null)
+ {
+ p.setSize(p.getWidth(), p.getHeight() + rightPrefSize.height);
+ p = p.getParent();
+ }
+ }
+ else if (location > size.width)
+ {
+ location = size.width;
+ while (p != null)
+ {
+ p.setSize(p.getWidth() + rightPrefSize.width, p.getHeight());
+ p = p.getParent();
+ }
+ }
+
setLastDragLocation(getDividerLocation(splitPane));
splitPane.setLastDividerLocation(getDividerLocation(splitPane));
int[] tmpSizes = layoutManager.getSizes();
- tmpSizes[0] = location
+ tmpSizes[0] = location
- layoutManager.getInitialLocation(splitPane.getInsets());
tmpSizes[1] = layoutManager.getAvailableSize(splitPane.getSize(),
splitPane.getInsets())
- - tmpSizes[0] - tmpSizes[1];
-
+ - tmpSizes[0];
layoutManager.setSizes(tmpSizes);
splitPane.revalidate();
splitPane.repaint();
@@ -1388,6 +1411,7 @@ public class BasicSplitPaneUI extends SplitPaneUI
*/
public void paint(Graphics g, JComponent jc)
{
+ // TODO: What should be done here?
}
/**
@@ -1550,10 +1574,12 @@ public class BasicSplitPaneUI extends SplitPaneUI
*/
private int validLocation(int location)
{
- if (location < getMinimumDividerLocation(splitPane))
- return getMinimumDividerLocation(splitPane);
- if (location > getMaximumDividerLocation(splitPane))
- return getMaximumDividerLocation(splitPane);
+ int min = getMinimumDividerLocation(splitPane);
+ int max = getMaximumDividerLocation(splitPane);
+ if (min > 0 && location < min)
+ return min;
+ if (max > 0 && location > max)
+ return max;
return location;
}
}
diff --git a/javax/swing/plaf/basic/BasicTabbedPaneUI.java b/javax/swing/plaf/basic/BasicTabbedPaneUI.java
index 232136fc2..ce9ea3ec7 100644
--- a/javax/swing/plaf/basic/BasicTabbedPaneUI.java
+++ b/javax/swing/plaf/basic/BasicTabbedPaneUI.java
@@ -64,9 +64,9 @@ import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JViewport;
import javax.swing.KeyStroke;
+import javax.swing.LookAndFeel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
-import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
@@ -354,7 +354,6 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
for (int i = 0; i < tabCount; i++)
{
width = calculateTabWidth(tabPlacement, i, fm);
-
if (runWidth + width > max)
{
runWidth = tabAreaInsets.left + insets.left
@@ -1182,6 +1181,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
*/
private class ScrollingViewport extends JViewport implements UIResource
{
+ // TODO: Maybe remove this inner class.
}
/**
@@ -1536,28 +1536,26 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
*/
protected void installDefaults()
{
- UIDefaults defaults = UIManager.getLookAndFeelDefaults();
-
- tabPane.setFont(defaults.getFont("TabbedPane.font"));
- tabPane.setForeground(defaults.getColor("TabbedPane.foreground"));
- tabPane.setBackground(defaults.getColor("TabbedPane.background"));
+ LookAndFeel.installColorsAndFont(tabPane, "TabbedPane.background",
+ "TabbedPane.foreground",
+ "TabbedPane.font");
tabPane.setOpaque(false);
- highlight = defaults.getColor("TabbedPane.highlight");
- lightHighlight = defaults.getColor("TabbedPane.lightHighlight");
+ highlight = UIManager.getColor("TabbedPane.highlight");
+ lightHighlight = UIManager.getColor("TabbedPane.lightHighlight");
- shadow = defaults.getColor("TabbedPane.shadow");
- darkShadow = defaults.getColor("TabbedPane.darkShadow");
+ shadow = UIManager.getColor("TabbedPane.shadow");
+ darkShadow = UIManager.getColor("TabbedPane.darkShadow");
- focus = defaults.getColor("TabbedPane.focus");
+ focus = UIManager.getColor("TabbedPane.focus");
- textIconGap = defaults.getInt("TabbedPane.textIconGap");
- tabRunOverlay = defaults.getInt("TabbedPane.tabRunOverlay");
+ textIconGap = UIManager.getInt("TabbedPane.textIconGap");
+ tabRunOverlay = UIManager.getInt("TabbedPane.tabRunOverlay");
- tabInsets = defaults.getInsets("TabbedPane.tabbedPaneTabInsets");
- selectedTabPadInsets = defaults.getInsets("TabbedPane.tabbedPaneTabPadInsets");
- tabAreaInsets = defaults.getInsets("TabbedPane.tabbedPaneTabAreaInsets");
- contentBorderInsets = defaults.getInsets("TabbedPane.tabbedPaneContentBorderInsets");
+ tabInsets = UIManager.getInsets("TabbedPane.tabbedPaneTabInsets");
+ selectedTabPadInsets = UIManager.getInsets("TabbedPane.tabbedPaneTabPadInsets");
+ tabAreaInsets = UIManager.getInsets("TabbedPane.tabbedPaneTabAreaInsets");
+ contentBorderInsets = UIManager.getInsets("TabbedPane.tabbedPaneContentBorderInsets");
calcRect = new Rectangle();
tabRuns = new int[10];
@@ -1737,11 +1735,15 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
// we WANT to paint the outermost run first and then work our way in.
int tabCount = tabPane.getTabCount();
int currRun = 1;
+
+ if (tabCount > runCount)
+ runCount = tabCount;
+
if (tabCount < 1)
return;
-
+
if (runCount > 1)
- currRun = 0;
+ currRun = 0;
for (int i = 0; i < runCount; i++)
{
int first = lastTabInRun(tabCount, getPreviousTabRun(currRun)) + 1;
@@ -1856,7 +1858,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
SwingConstants.CENTER,
SwingConstants.CENTER,
SwingConstants.CENTER,
- SwingConstants.CENTER, tabRect,
+ SwingConstants.RIGHT, tabRect,
iconRect, textRect, textIconGap);
int shiftX = getTabLabelShiftX(tabPlacement, tabIndex, isSelected);
diff --git a/javax/swing/plaf/basic/BasicTableHeaderUI.java b/javax/swing/plaf/basic/BasicTableHeaderUI.java
index 700b406d0..ec0467a74 100644
--- a/javax/swing/plaf/basic/BasicTableHeaderUI.java
+++ b/javax/swing/plaf/basic/BasicTableHeaderUI.java
@@ -46,7 +46,7 @@ import java.awt.event.MouseEvent;
import javax.swing.CellRendererPane;
import javax.swing.JComponent;
-import javax.swing.UIDefaults;
+import javax.swing.LookAndFeel;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.event.MouseInputListener;
@@ -57,8 +57,7 @@ import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
-public class BasicTableHeaderUI
- extends TableHeaderUI
+public class BasicTableHeaderUI extends TableHeaderUI
{
public static ComponentUI createUI(JComponent h)
@@ -71,16 +70,42 @@ public class BasicTableHeaderUI
protected CellRendererPane rendererPane;
protected Border cellBorder;
- class MouseInputHandler
- implements MouseInputListener
+ public class MouseInputHandler implements MouseInputListener
{
- public void mouseClicked(MouseEvent e) {}
- public void mouseDragged(MouseEvent e) {}
- public void mouseEntered(MouseEvent e) {}
- public void mouseExited(MouseEvent e) {}
- public void mouseMoved(MouseEvent e) {}
- public void mousePressed(MouseEvent e) {}
- public void mouseReleased(MouseEvent e) {}
+ public void mouseClicked(MouseEvent e)
+ {
+ // TODO: Implement this properly.
+ }
+
+ public void mouseDragged(MouseEvent e)
+ {
+ // TODO: Implement this properly.
+ }
+
+ public void mouseEntered(MouseEvent e)
+ {
+ // TODO: Implement this properly.
+ }
+
+ public void mouseExited(MouseEvent e)
+ {
+ // TODO: Implement this properly.
+ }
+
+ public void mouseMoved(MouseEvent e)
+ {
+ // TODO: Implement this properly.
+ }
+
+ public void mousePressed(MouseEvent e)
+ {
+ // TODO: Implement this properly.
+ }
+
+ public void mouseReleased(MouseEvent e)
+ {
+ // TODO: Implement this properly.
+ }
}
protected MouseInputListener createMouseInputListener()
@@ -95,15 +120,15 @@ public class BasicTableHeaderUI
protected void installDefaults()
{
- UIDefaults defaults = UIManager.getLookAndFeelDefaults();
- header.setBackground(defaults.getColor("TableHeader.background"));
- header.setForeground(defaults.getColor("TableHeader.foreground"));
- header.setFont(defaults.getFont("TableHeader.font"));
- cellBorder = defaults.getBorder("TableHeader.cellBorder");
+ LookAndFeel.installColorsAndFont(header, "TableHeader.background",
+ "TableHeader.foreground",
+ "TableHeader.font");
+ cellBorder = UIManager.getBorder("TableHeader.cellBorder");
}
protected void installKeyboardActions()
{
+ // TODO: Implement this properly.
}
protected void installListeners()
@@ -128,6 +153,7 @@ public class BasicTableHeaderUI
protected void uninstallKeyboardActions()
{
+ // TODO: Implement this properly.
}
protected void uninstallListeners()
@@ -157,6 +183,7 @@ public class BasicTableHeaderUI
Rectangle bounds = header.getHeaderRect(i);
if (bounds.intersects(clip))
{
+ Rectangle oldClip = gfx.getClipBounds();
TableColumn col = cmod.getColumn(i);
TableCellRenderer rend = col.getHeaderRenderer();
if (rend == null)
@@ -173,10 +200,12 @@ public class BasicTableHeaderUI
if (comp instanceof JComponent)
((JComponent)comp).setBorder(cellBorder);
gfx.translate(bounds.x, bounds.y);
+ gfx.setClip(0, 0, bounds.width, bounds.height);
comp.setSize(bounds.width, bounds.height);
comp.setLocation(0,0);
comp.paint(gfx);
gfx.translate(-bounds.x, -bounds.y);
+ gfx.setClip(oldClip);
}
}
diff --git a/javax/swing/plaf/basic/BasicTableUI.java b/javax/swing/plaf/basic/BasicTableUI.java
index 2308dc279..5946a3bdd 100644
--- a/javax/swing/plaf/basic/BasicTableUI.java
+++ b/javax/swing/plaf/basic/BasicTableUI.java
@@ -49,21 +49,23 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
-import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
-import javax.swing.BorderFactory;
import javax.swing.CellRendererPane;
+import javax.swing.DefaultListSelectionModel;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.ListSelectionModel;
+import javax.swing.LookAndFeel;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.border.Border;
@@ -75,9 +77,9 @@ import javax.swing.plaf.TableUI;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
+import javax.swing.table.TableModel;
-public class BasicTableUI
- extends TableUI
+public class BasicTableUI extends TableUI
{
public static ComponentUI createUI(JComponent comp)
{
@@ -93,23 +95,72 @@ public class BasicTableUI
/** The normal cell border. */
Border cellBorder;
- /** The cell border for selected/highlighted cells. */
- Border highlightCellBorder;
-
/** The action bound to KeyStrokes. */
TableAction action;
- class FocusHandler implements FocusListener
+ /**
+ * Listens for changes to the tables properties.
+ */
+ private PropertyChangeListener propertyChangeListener;
+
+ /**
+ * Handles key events for the JTable. Key events should be handled through
+ * the InputMap/ActionMap mechanism since JDK1.3. This class is only there
+ * for backwards compatibility.
+ *
+ * @author Roman Kennke (kennke@aicas.com)
+ */
+ public class KeyHandler implements KeyListener
+ {
+
+ /**
+ * Receives notification that a key has been pressed and released.
+ *
+ * @param event the key event
+ */
+ public void keyTyped(KeyEvent event)
+ {
+ // Key events should be handled through the InputMap/ActionMap mechanism
+ // since JDK1.3. This class is only there for backwards compatibility.
+ }
+
+ /**
+ * Receives notification that a key has been pressed.
+ *
+ * @param event the key event
+ */
+ public void keyPressed(KeyEvent event)
+ {
+ // Key events should be handled through the InputMap/ActionMap mechanism
+ // since JDK1.3. This class is only there for backwards compatibility.
+ }
+
+ /**
+ * Receives notification that a key has been released.
+ *
+ * @param event the key event
+ */
+ public void keyReleased(KeyEvent event)
+ {
+ // Key events should be handled through the InputMap/ActionMap mechanism
+ // since JDK1.3. This class is only there for backwards compatibility.
+ }
+ }
+
+ public class FocusHandler implements FocusListener
{
public void focusGained(FocusEvent e)
{
+ // TODO: Implement this properly.
}
+
public void focusLost(FocusEvent e)
{
+ // TODO: Implement this properly.
}
}
- class MouseInputHandler implements MouseInputListener
+ public class MouseInputHandler implements MouseInputListener
{
Point begin, curr;
@@ -145,54 +196,123 @@ public class BasicTableUI
public void mouseClicked(MouseEvent e)
{
+ // TODO: What should be done here, if anything?
}
+
public void mouseDragged(MouseEvent e)
{
- curr = new Point(e.getX(), e.getY());
- updateSelection(e.isControlDown());
+ if (table.isEnabled())
+ {
+ curr = new Point(e.getX(), e.getY());
+ updateSelection(e.isControlDown());
+ }
}
+
public void mouseEntered(MouseEvent e)
{
+ // TODO: What should be done here, if anything?
}
+
public void mouseExited(MouseEvent e)
{
+ // TODO: What should be done here, if anything?
}
+
public void mouseMoved(MouseEvent e)
{
+ // TODO: What should be done here, if anything?
}
+
public void mousePressed(MouseEvent e)
{
- ListSelectionModel rowModel = table.getSelectionModel();
- ListSelectionModel colModel = table.getColumnModel().getSelectionModel();
- int rowLead = rowModel.getLeadSelectionIndex();
- int colLead = colModel.getLeadSelectionIndex();
+ if (table.isEnabled())
+ {
+ ListSelectionModel rowModel = table.getSelectionModel();
+ ListSelectionModel colModel = table.getColumnModel().getSelectionModel();
+ int rowLead = rowModel.getLeadSelectionIndex();
+ int colLead = colModel.getLeadSelectionIndex();
- begin = new Point(e.getX(), e.getY());
- curr = new Point(e.getX(), e.getY());
- //if control is pressed and the cell is already selected, deselect it
- if (e.isControlDown() && table.
- isCellSelected(table.rowAtPoint(begin),table.columnAtPoint(begin)))
- {
- table.getSelectionModel().
- removeSelectionInterval(table.rowAtPoint(begin),
- table.rowAtPoint(begin));
- table.getColumnModel().getSelectionModel().
- removeSelectionInterval(table.columnAtPoint(begin),
- table.columnAtPoint(begin));
- }
- else
- updateSelection(e.isControlDown());
+ begin = new Point(e.getX(), e.getY());
+ curr = new Point(e.getX(), e.getY());
+ //if control is pressed and the cell is already selected, deselect it
+ if (e.isControlDown() && table.
+ isCellSelected(table.rowAtPoint(begin),table.columnAtPoint(begin)))
+ {
+ table.getSelectionModel().
+ removeSelectionInterval(table.rowAtPoint(begin),
+ table.rowAtPoint(begin));
+ table.getColumnModel().getSelectionModel().
+ removeSelectionInterval(table.columnAtPoint(begin),
+ table.columnAtPoint(begin));
+ }
+ else
+ updateSelection(e.isControlDown());
- // If we were editing, but the moved to another cell, stop editing
- if (rowLead != rowModel.getLeadSelectionIndex() ||
- colLead != colModel.getLeadSelectionIndex())
- if (table.isEditing())
- table.editingStopped(new ChangeEvent(e));
+ // If we were editing, but the moved to another cell, stop editing
+ if (rowLead != rowModel.getLeadSelectionIndex() ||
+ colLead != colModel.getLeadSelectionIndex())
+ if (table.isEditing())
+ table.editingStopped(new ChangeEvent(e));
+ }
}
+
public void mouseReleased(MouseEvent e)
{
- begin = null;
- curr = null;
+ if (table.isEnabled())
+ {
+ begin = null;
+ curr = null;
+ }
+ }
+ }
+
+ /**
+ * Listens for changes to the model property of the JTable and adjusts some
+ * settings.
+ *
+ * @author Roman Kennke (kennke@aicas.com)
+ */
+ private class PropertyChangeHandler implements PropertyChangeListener
+ {
+ /**
+ * Receives notification if one of the JTable's properties changes.
+ *
+ * @param ev the property change event
+ */
+ public void propertyChange(PropertyChangeEvent ev)
+ {
+ String propName = ev.getPropertyName();
+ if (propName.equals("model"))
+ {
+ ListSelectionModel rowSel = table.getSelectionModel();
+ rowSel.clearSelection();
+ ListSelectionModel colSel = table.getColumnModel().getSelectionModel();
+ colSel.clearSelection();
+ TableModel model = table.getModel();
+
+ // Adjust lead and anchor selection indices of the row and column
+ // selection models.
+ if (model.getRowCount() > 0)
+ {
+ rowSel.setAnchorSelectionIndex(0);
+ rowSel.setLeadSelectionIndex(0);
+ }
+ else
+ {
+ rowSel.setAnchorSelectionIndex(-1);
+ rowSel.setLeadSelectionIndex(-1);
+ }
+ if (model.getColumnCount() > 0)
+ {
+ colSel.setAnchorSelectionIndex(0);
+ colSel.setLeadSelectionIndex(0);
+ }
+ else
+ {
+ colSel.setAnchorSelectionIndex(-1);
+ colSel.setLeadSelectionIndex(-1);
+ }
+ }
}
}
@@ -206,6 +326,17 @@ public class BasicTableUI
return new MouseInputHandler();
}
+
+ /**
+ * Creates and returns a key listener for the JTable.
+ *
+ * @return a key listener for the JTable
+ */
+ protected KeyListener createKeyListener()
+ {
+ return new KeyHandler();
+ }
+
/**
* Return the maximum size of the table. The maximum height is the row
* height times the number of rows. The maximum width is the sum of
@@ -255,47 +386,13 @@ public class BasicTableUI
protected void installDefaults()
{
- UIDefaults defaults = UIManager.getLookAndFeelDefaults();
- table.setFont(defaults.getFont("Table.font"));
- table.setGridColor(defaults.getColor("Table.gridColor"));
- table.setForeground(defaults.getColor("Table.foreground"));
- table.setBackground(defaults.getColor("Table.background"));
- table.setSelectionForeground(defaults.getColor("Table.selectionForeground"));
- table.setSelectionBackground(defaults.getColor("Table.selectionBackground"));
+ LookAndFeel.installColorsAndFont(table, "Table.background",
+ "Table.foreground", "Table.font");
+ table.setGridColor(UIManager.getColor("Table.gridColor"));
+ table.setSelectionForeground(UIManager.getColor("Table.selectionForeground"));
+ table.setSelectionBackground(UIManager.getColor("Table.selectionBackground"));
table.setOpaque(true);
-
- highlightCellBorder = defaults.getBorder("Table.focusCellHighlightBorder");
- cellBorder = BorderFactory.createEmptyBorder(1, 1, 1, 1);
- }
-
- private int convertModifiers(int mod)
- {
- if ((mod & KeyEvent.SHIFT_DOWN_MASK) != 0)
- {
- mod |= KeyEvent.SHIFT_MASK;
- mod &= ~KeyEvent.SHIFT_DOWN_MASK;
- }
- if ((mod & KeyEvent.CTRL_DOWN_MASK) != 0)
- {
- mod |= KeyEvent.CTRL_MASK;
- mod &= ~KeyEvent.CTRL_DOWN_MASK;
- }
- if ((mod & KeyEvent.META_DOWN_MASK) != 0)
- {
- mod |= KeyEvent.META_MASK;
- mod &= ~KeyEvent.META_DOWN_MASK;
- }
- if ((mod & KeyEvent.ALT_DOWN_MASK) != 0)
- {
- mod |= KeyEvent.ALT_MASK;
- mod &= ~KeyEvent.ALT_DOWN_MASK;
- }
- if ((mod & KeyEvent.ALT_GRAPH_DOWN_MASK) != 0)
- {
- mod |= KeyEvent.ALT_GRAPH_MASK;
- mod &= ~KeyEvent.ALT_GRAPH_DOWN_MASK;
- }
- return mod;
+ rendererPane = new CellRendererPane();
}
protected void installKeyboardActions()
@@ -308,23 +405,17 @@ public class BasicTableUI
action = new TableAction();
Object keys[] = ancestorMap.allKeys();
// Register key bindings in the UI InputMap-ActionMap pair
- // Note that we register key bindings with both the old and new modifier
- // masks: InputEvent.SHIFT_MASK and InputEvent.SHIFT_DOWN_MASK and so on.
for (int i = 0; i < keys.length; i++)
{
- parentInputMap.put(KeyStroke.getKeyStroke
- (((KeyStroke)keys[i]).getKeyCode(), convertModifiers
- (((KeyStroke)keys[i]).getModifiers())),
- (String)ancestorMap.get((KeyStroke)keys[i]));
+ KeyStroke stroke = (KeyStroke)keys[i];
+ String actionString = (String) ancestorMap.get(stroke);
- parentInputMap.put(KeyStroke.getKeyStroke
- (((KeyStroke)keys[i]).getKeyCode(),
- ((KeyStroke)keys[i]).getModifiers()),
- (String)ancestorMap.get((KeyStroke)keys[i]));
+ parentInputMap.put(KeyStroke.getKeyStroke(stroke.getKeyCode(),
+ stroke.getModifiers()),
+ actionString);
- parentActionMap.put
- ((String)ancestorMap.get((KeyStroke)keys[i]), new ActionListenerProxy
- (action, (String)ancestorMap.get((KeyStroke)keys[i])));
+ parentActionMap.put (actionString,
+ new ActionListenerProxy (action, actionString));
}
// Set the UI InputMap-ActionMap pair to be the parents of the
@@ -383,8 +474,8 @@ public class BasicTableUI
*/
public void actionPerformed (ActionEvent e)
{
- ListSelectionModel rowModel = table.getSelectionModel();
- ListSelectionModel colModel = table.getColumnModel().getSelectionModel();
+ DefaultListSelectionModel rowModel = (DefaultListSelectionModel) table.getSelectionModel();
+ DefaultListSelectionModel colModel = (DefaultListSelectionModel) table.getColumnModel().getSelectionModel();
int rowLead = rowModel.getLeadSelectionIndex();
int rowMax = table.getModel().getRowCount() - 1;
@@ -392,74 +483,75 @@ public class BasicTableUI
int colLead = colModel.getLeadSelectionIndex();
int colMax = table.getModel().getColumnCount() - 1;
- if (e.getActionCommand().equals("selectPreviousRowExtendSelection"))
+ String command = e.getActionCommand();
+
+ if (command.equals("selectPreviousRowExtendSelection"))
{
rowModel.setLeadSelectionIndex(Math.max(rowLead - 1, 0));
colModel.setLeadSelectionIndex(colLead);
}
- else if (e.getActionCommand().equals("selectLastColumn"))
+ else if (command.equals("selectLastColumn"))
{
- table.clearSelection();
rowModel.setSelectionInterval(rowLead, rowLead);
colModel.setSelectionInterval(colMax, colMax);
}
- else if (e.getActionCommand().equals("startEditing"))
+ else if (command.equals("startEditing"))
{
if (table.isCellEditable(rowLead, colLead))
table.editCellAt(rowLead,colLead);
}
- else if (e.getActionCommand().equals("selectFirstRowExtendSelection"))
+ else if (command.equals("selectFirstRowExtendSelection"))
{
rowModel.setLeadSelectionIndex(0);
colModel.setLeadSelectionIndex(colLead);
}
- else if (e.getActionCommand().equals("selectFirstColumn"))
+ else if (command.equals("selectFirstColumn"))
{
rowModel.setSelectionInterval(rowLead, rowLead);
colModel.setSelectionInterval(0, 0);
}
- else if (e.getActionCommand().equals("selectFirstColumnExtendSelection"))
+ else if (command.equals("selectFirstColumnExtendSelection"))
{
colModel.setLeadSelectionIndex(0);
rowModel.setLeadSelectionIndex(rowLead);
- }
- else if (e.getActionCommand().equals("selectLastRow"))
+ }
+ else if (command.equals("selectLastRow"))
{
rowModel.setSelectionInterval(rowMax,rowMax);
colModel.setSelectionInterval(colLead, colLead);
}
- else if (e.getActionCommand().equals("selectNextRowExtendSelection"))
+ else if (command.equals("selectNextRowExtendSelection"))
{
rowModel.setLeadSelectionIndex(Math.min(rowLead + 1, rowMax));
colModel.setLeadSelectionIndex(colLead);
}
- else if (e.getActionCommand().equals("selectFirstRow"))
+ else if (command.equals("selectFirstRow"))
{
rowModel.setSelectionInterval(0,0);
colModel.setSelectionInterval(colLead, colLead);
}
- else if (e.getActionCommand().equals("selectNextColumnExtendSelection"))
+ else if (command.equals("selectNextColumnExtendSelection"))
{
colModel.setLeadSelectionIndex(Math.min(colLead + 1, colMax));
rowModel.setLeadSelectionIndex(rowLead);
}
- else if (e.getActionCommand().equals("selectLastColumnExtendSelection"))
+ else if (command.equals("selectLastColumnExtendSelection"))
{
colModel.setLeadSelectionIndex(colMax);
rowModel.setLeadSelectionIndex(rowLead);
}
- else if (e.getActionCommand().equals("selectPreviousColumnExtendSelection"))
+ else if (command.equals("selectPreviousColumnExtendSelection"))
{
colModel.setLeadSelectionIndex(Math.max(colLead - 1, 0));
rowModel.setLeadSelectionIndex(rowLead);
}
- else if (e.getActionCommand().equals("selectNextRow"))
+ else if (command.equals("selectNextRow"))
{
rowModel.setSelectionInterval(Math.min(rowLead + 1, rowMax),
Math.min(rowLead + 1, rowMax));
colModel.setSelectionInterval(colLead,colLead);
}
- else if (e.getActionCommand().equals("scrollUpExtendSelection"))
+ else if (command.equals("scrollUpExtendSelection"))
{
int target;
if (rowLead == getFirstVisibleRowIndex())
@@ -472,13 +564,13 @@ public class BasicTableUI
rowModel.setLeadSelectionIndex(target);
colModel.setLeadSelectionIndex(colLead);
}
- else if (e.getActionCommand().equals("selectPreviousRow"))
+ else if (command.equals("selectPreviousRow"))
{
rowModel.setSelectionInterval(Math.max(rowLead - 1, 0),
Math.max(rowLead - 1, 0));
colModel.setSelectionInterval(colLead,colLead);
}
- else if (e.getActionCommand().equals("scrollRightChangeSelection"))
+ else if (command.equals("scrollRightChangeSelection"))
{
int target;
if (colLead == getLastVisibleColumnIndex())
@@ -491,13 +583,13 @@ public class BasicTableUI
colModel.setSelectionInterval(target, target);
rowModel.setSelectionInterval(rowLead, rowLead);
}
- else if (e.getActionCommand().equals("selectPreviousColumn"))
+ else if (command.equals("selectPreviousColumn"))
{
rowModel.setSelectionInterval(rowLead,rowLead);
colModel.setSelectionInterval(Math.max(colLead - 1, 0),
Math.max(colLead - 1, 0));
}
- else if (e.getActionCommand().equals("scrollLeftChangeSelection"))
+ else if (command.equals("scrollLeftChangeSelection"))
{
int target;
if (colLead == getFirstVisibleColumnIndex())
@@ -510,11 +602,11 @@ public class BasicTableUI
colModel.setSelectionInterval(target, target);
rowModel.setSelectionInterval(rowLead, rowLead);
}
- else if (e.getActionCommand().equals("clearSelection"))
+ else if (command.equals("clearSelection"))
{
table.clearSelection();
}
- else if (e.getActionCommand().equals("cancel"))
+ else if (command.equals("cancel"))
{
// FIXME: implement other parts of "cancel" like undo-ing last
// selection. Right now it just calls editingCancelled if
@@ -522,10 +614,10 @@ public class BasicTableUI
if (table.isEditing())
table.editingCanceled(new ChangeEvent("cancel"));
}
- else if (e.getActionCommand().equals("selectNextRowCell")
- || e.getActionCommand().equals("selectPreviousRowCell")
- || e.getActionCommand().equals("selectNextColumnCell")
- || e.getActionCommand().equals("selectPreviousColumnCell"))
+ else if (command.equals("selectNextRowCell")
+ || command.equals("selectPreviousRowCell")
+ || command.equals("selectNextColumnCell")
+ || command.equals("selectPreviousColumnCell"))
{
// If nothing is selected, select the first cell in the table
if (table.getSelectedRowCount() == 0 &&
@@ -561,13 +653,13 @@ public class BasicTableUI
// when you get to the edges of the table.
if (!multColsSelected && !multRowsSelected)
{
- if (e.getActionCommand().indexOf("Column") != -1)
+ if (command.indexOf("Column") != -1)
advanceSingleSelection(colModel, colMax, rowModel, rowMax,
- (e.getActionCommand().equals
+ (command.equals
("selectPreviousColumnCell")));
else
advanceSingleSelection(rowModel, rowMax, colModel, colMax,
- (e.getActionCommand().equals
+ (command.equals
("selectPreviousRowCell")));
return;
}
@@ -588,25 +680,25 @@ public class BasicTableUI
// If there are multiple rows and columns selected, select the next
// cell and wrap at the edges of the selection.
- if (e.getActionCommand().indexOf("Column") != -1)
+ if (command.indexOf("Column") != -1)
advanceMultipleSelection(colModel, colMinSelected, colMaxSelected,
rowModel, rowMinSelected, rowMaxSelected,
- (e.getActionCommand().equals
+ (command.equals
("selectPreviousColumnCell")), true);
else
advanceMultipleSelection(rowModel, rowMinSelected, rowMaxSelected,
colModel, colMinSelected, colMaxSelected,
- (e.getActionCommand().equals
+ (command.equals
("selectPreviousRowCell")), false);
}
- else if (e.getActionCommand().equals("selectNextColumn"))
+ else if (command.equals("selectNextColumn"))
{
rowModel.setSelectionInterval(rowLead,rowLead);
colModel.setSelectionInterval(Math.min(colLead + 1, colMax),
Math.min(colLead + 1, colMax));
}
- else if (e.getActionCommand().equals("scrollLeftExtendSelection"))
+ else if (command.equals("scrollLeftExtendSelection"))
{
int target;
if (colLead == getFirstVisibleColumnIndex())
@@ -619,7 +711,7 @@ public class BasicTableUI
colModel.setLeadSelectionIndex(target);
rowModel.setLeadSelectionIndex(rowLead);
}
- else if (e.getActionCommand().equals("scrollDownChangeSelection"))
+ else if (command.equals("scrollDownChangeSelection"))
{
int target;
if (rowLead == getLastVisibleRowIndex())
@@ -632,7 +724,7 @@ public class BasicTableUI
rowModel.setSelectionInterval(target, target);
colModel.setSelectionInterval(colLead, colLead);
}
- else if (e.getActionCommand().equals("scrollRightExtendSelection"))
+ else if (command.equals("scrollRightExtendSelection"))
{
int target;
if (colLead == getLastVisibleColumnIndex())
@@ -645,16 +737,16 @@ public class BasicTableUI
colModel.setLeadSelectionIndex(target);
rowModel.setLeadSelectionIndex(rowLead);
}
- else if (e.getActionCommand().equals("selectAll"))
+ else if (command.equals("selectAll"))
{
table.selectAll();
}
- else if (e.getActionCommand().equals("selectLastRowExtendSelection"))
+ else if (command.equals("selectLastRowExtendSelection"))
{
rowModel.setLeadSelectionIndex(rowMax);
colModel.setLeadSelectionIndex(colLead);
}
- else if (e.getActionCommand().equals("scrollDownExtendSelection"))
+ else if (command.equals("scrollDownExtendSelection"))
{
int target;
if (rowLead == getLastVisibleRowIndex())
@@ -666,8 +758,8 @@ public class BasicTableUI
rowModel.setLeadSelectionIndex(target);
colModel.setLeadSelectionIndex(colLead);
- }
- else if (e.getActionCommand().equals("scrollUpChangeSelection"))
+ }
+ else if (command.equals("scrollUpChangeSelection"))
{
int target;
if (rowLead == getFirstVisibleRowIndex())
@@ -680,22 +772,119 @@ public class BasicTableUI
rowModel.setSelectionInterval(target, target);
colModel.setSelectionInterval(colLead, colLead);
}
+ else if (command.equals("selectNextRowChangeLead"))
+ {
+ if (rowModel.getSelectionMode() != ListSelectionModel.MULTIPLE_INTERVAL_SELECTION)
+ {
+ // just "selectNextRow"
+ rowModel.setSelectionInterval(Math.min(rowLead + 1, rowMax),
+ Math.min(rowLead + 1, rowMax));
+ colModel.setSelectionInterval(colLead,colLead);
+ }
+ else
+ rowModel.moveLeadSelectionIndex(Math.min(rowLead + 1, rowMax));
+ }
+ else if (command.equals("selectPreviousRowChangeLead"))
+ {
+ if (rowModel.getSelectionMode() != ListSelectionModel.MULTIPLE_INTERVAL_SELECTION)
+ {
+ // just selectPreviousRow
+ rowModel.setSelectionInterval(Math.max(rowLead - 1, 0),
+ Math.min(rowLead -1, 0));
+ colModel.setSelectionInterval(colLead,colLead);
+ }
+ else
+ rowModel.moveLeadSelectionIndex(Math.max(rowLead - 1, 0));
+ }
+ else if (command.equals("selectNextColumnChangeLead"))
+ {
+ if (colModel.getSelectionMode() != ListSelectionModel.MULTIPLE_INTERVAL_SELECTION)
+ {
+ // just selectNextColumn
+ rowModel.setSelectionInterval(rowLead,rowLead);
+ colModel.setSelectionInterval(Math.min(colLead + 1, colMax),
+ Math.min(colLead + 1, colMax));
+ }
+ else
+ colModel.moveLeadSelectionIndex(Math.min(colLead + 1, colMax));
+ }
+ else if (command.equals("selectPreviousColumnChangeLead"))
+ {
+ if (colModel.getSelectionMode() != ListSelectionModel.MULTIPLE_INTERVAL_SELECTION)
+ {
+ // just selectPreviousColumn
+ rowModel.setSelectionInterval(rowLead,rowLead);
+ colModel.setSelectionInterval(Math.max(colLead - 1, 0),
+ Math.max(colLead - 1, 0));
+
+ }
+ else
+ colModel.moveLeadSelectionIndex(Math.max(colLead - 1, 0));
+ }
+ else if (command.equals("addToSelection"))
+ {
+ if (!table.isEditing())
+ {
+ int oldRowAnchor = rowModel.getAnchorSelectionIndex();
+ int oldColAnchor = colModel.getAnchorSelectionIndex();
+ rowModel.addSelectionInterval(rowLead, rowLead);
+ colModel.addSelectionInterval(colLead, colLead);
+ rowModel.setAnchorSelectionIndex(oldRowAnchor);
+ colModel.setAnchorSelectionIndex(oldColAnchor);
+ }
+ }
+ else if (command.equals("extendTo"))
+ {
+ rowModel.setSelectionInterval(rowModel.getAnchorSelectionIndex(),
+ rowLead);
+ colModel.setSelectionInterval(colModel.getAnchorSelectionIndex(),
+ colLead);
+ }
+ else if (command.equals("toggleAndAnchor"))
+ {
+ if (rowModel.isSelectedIndex(rowLead))
+ rowModel.removeSelectionInterval(rowLead, rowLead);
+ else
+ rowModel.addSelectionInterval(rowLead, rowLead);
+
+ if (colModel.isSelectedIndex(colLead))
+ colModel.removeSelectionInterval(colLead, colLead);
+ else
+ colModel.addSelectionInterval(colLead, colLead);
+
+ rowModel.setAnchorSelectionIndex(rowLead);
+ colModel.setAnchorSelectionIndex(colLead);
+ }
else
{
// If we're here that means we bound this TableAction class
// to a keyboard input but we either want to ignore that input
// or we just haven't implemented its action yet.
+
+ // Uncomment the following line to print the names of unused bindings
+ // when their keys are pressed
+
+ // System.out.println ("not implemented: "+e.getActionCommand());
}
- if (table.isEditing() && e.getActionCommand() != "startEditing")
- table.editingCanceled(new ChangeEvent("update"));
- table.repaint();
-
+ // Any commands whose keyStrokes should be used by the Editor should not
+ // cause editing to be stopped: ie, the SPACE sends "addToSelection" but
+ // if the table is in editing mode, the space should not cause us to stop
+ // editing because it should be used by the Editor.
+ if (table.isEditing() && command != "startEditing"
+ && command != "addToSelection")
+ table.editingStopped(new ChangeEvent("update"));
+
table.scrollRectToVisible
(table.getCellRect(rowModel.getLeadSelectionIndex(),
colModel.getLeadSelectionIndex(), false));
+ table.repaint();
}
+ /**
+ * Returns the column index of the first visible column.
+ * @return the column index of the first visible column.
+ */
int getFirstVisibleColumnIndex()
{
ComponentOrientation or = table.getComponentOrientation();
@@ -922,10 +1111,19 @@ public class BasicTableUI
protected void installListeners()
{
- table.addFocusListener(focusListener);
+ if (focusListener == null)
+ focusListener = createFocusListener();
+ table.addFocusListener(focusListener);
+ if (keyListener == null)
+ keyListener = createKeyListener();
table.addKeyListener(keyListener);
+ if (mouseInputListener == null)
+ mouseInputListener = createMouseInputListener();
table.addMouseListener(mouseInputListener);
table.addMouseMotionListener(mouseInputListener);
+ if (propertyChangeListener == null)
+ propertyChangeListener = new PropertyChangeHandler();
+ table.addPropertyChangeListener(propertyChangeListener);
}
protected void uninstallDefaults()
@@ -950,6 +1148,7 @@ public class BasicTableUI
protected void uninstallKeyboardActions()
{
+ // TODO: Implement this properly.
}
protected void uninstallListeners()
@@ -958,13 +1157,13 @@ public class BasicTableUI
table.removeKeyListener(keyListener);
table.removeMouseListener(mouseInputListener);
table.removeMouseMotionListener(mouseInputListener);
+ table.removePropertyChangeListener(propertyChangeListener);
+ propertyChangeListener = null;
}
public void installUI(JComponent comp)
{
table = (JTable)comp;
- focusListener = createFocusListener();
- mouseInputListener = createMouseInputListener();
installDefaults();
installKeyboardActions();
installListeners();
@@ -977,6 +1176,60 @@ public class BasicTableUI
uninstallDefaults();
}
+ /**
+ * Paints a single cell in the table.
+ *
+ * @param g The graphics context to paint in
+ * @param row The row number to paint
+ * @param col The column number to paint
+ * @param bounds The bounds of the cell to paint, assuming a coordinate
+ * system beginning at <code>(0,0)</code> in the upper left corner of the
+ * table
+ * @param rend A cell renderer to paint with
+ * @param data The data to provide to the cell renderer
+ * @param rowLead The lead selection for the rows of the table.
+ * @param colLead The lead selection for the columns of the table.
+ */
+ void paintCell(Graphics g, int row, int col, Rectangle bounds,
+ TableCellRenderer rend, TableModel data,
+ int rowLead, int colLead)
+ {
+ boolean rowSelAllowed = table.getRowSelectionAllowed();
+ boolean colSelAllowed = table.getColumnSelectionAllowed();
+ boolean isSel = false;
+ if (rowSelAllowed && colSelAllowed || !rowSelAllowed && !colSelAllowed)
+ isSel = table.isCellSelected(row, col);
+ else
+ isSel = table.isRowSelected(row) && table.getRowSelectionAllowed()
+ || table.isColumnSelected(col) && table.getColumnSelectionAllowed();
+
+ // Determine the focused cell. The focused cell is the cell at the
+ // leadSelectionIndices of the row and column selection model.
+ ListSelectionModel rowSel = table.getSelectionModel();
+ ListSelectionModel colSel = table.getColumnModel().getSelectionModel();
+ boolean hasFocus = table.hasFocus() && table.isEnabled()
+ && rowSel.getLeadSelectionIndex() == row
+ && colSel.getLeadSelectionIndex() == col;
+
+ Component comp = rend.getTableCellRendererComponent(table,
+ data.getValueAt(row, col),
+ isSel, hasFocus, row, col);
+
+ rendererPane.paintComponent(g, comp, table, bounds);
+
+ // FIXME: this is manual painting of the Caret, why doesn't the
+ // JTextField take care of this itself?
+ if (comp instanceof JTextField)
+ {
+ Rectangle oldClip = g.getClipBounds();
+ g.translate(bounds.x, bounds.y);
+ g.clipRect(0, 0, bounds.width, bounds.height);
+ ((JTextField)comp).getCaret().paint(g);
+ g.translate(-bounds.x, -bounds.y);
+ g.setClip(oldClip);
+ }
+ }
+
public void paint(Graphics gfx, JComponent ignored)
{
int ncols = table.getColumnCount();
@@ -1002,34 +1255,22 @@ public class BasicTableUI
y = y0;
TableColumn col = cols.getColumn(c);
int width = col.getWidth();
- int modelCol = col.getModelIndex();
-
+ int halfGapWidth = gap.width / 2;
+ int halfGapHeight = gap.height / 2;
for (int r = 0; r < nrows && y < ymax; ++r)
{
- Rectangle bounds = new Rectangle(x, y, width, height);
- if (bounds.intersects(clip))
- {
- TableCellRenderer rend = table.getCellRenderer(r, c);
- Component comp = table.prepareRenderer(rend, r, c);
- gfx.translate(x, y);
- comp.setBounds(new Rectangle(0, 0, width, height));
- // Set correct border on cell renderer.
- // Only the lead selection cell gets a border
- if (comp instanceof JComponent)
- {
- if (table.getSelectionModel().getLeadSelectionIndex() == r
- && table.getColumnModel().getSelectionModel().
- getLeadSelectionIndex() == c)
- ((JComponent) comp).setBorder(highlightCellBorder);
- else
- ((JComponent) comp).setBorder(cellBorder);
- }
- comp.paint(gfx);
- if (comp instanceof JTextField)
- ((JTextField)comp).getCaret().paint(gfx);
- gfx.translate(-x, -y);
+ Rectangle bounds = new Rectangle(x + halfGapWidth,
+ y + halfGapHeight + 1,
+ width - gap.width + 1,
+ height - gap.height);
+ if (bounds.intersects(clip))
+ {
+ paintCell(gfx, r, c, bounds, table.getCellRenderer(r, c),
+ table.getModel(),
+ table.getSelectionModel().getLeadSelectionIndex(),
+ table.getColumnModel().getSelectionModel().getLeadSelectionIndex());
}
- y += height;
+ y += height;
}
x += width;
}
@@ -1040,7 +1281,7 @@ public class BasicTableUI
Color grid = table.getGridColor();
- // paint vertical grid lines
+ // paint vertical grid lines
if (grid != null && table.getShowVerticalLines())
{
x = x0;
@@ -1050,7 +1291,7 @@ public class BasicTableUI
for (int c = 0; c < ncols && x < xmax; ++c)
{
x += cols.getColumn(c).getWidth();
- gfx.drawLine(x - gap.width, y0, x - gap.width, ymax);
+ gfx.drawLine(x, y0, x, ymax);
paintedLine = true;
}
gfx.setColor(save);
diff --git a/javax/swing/plaf/basic/BasicTextAreaUI.java b/javax/swing/plaf/basic/BasicTextAreaUI.java
index 4c69f5707..36854e07f 100644
--- a/javax/swing/plaf/basic/BasicTextAreaUI.java
+++ b/javax/swing/plaf/basic/BasicTextAreaUI.java
@@ -39,12 +39,16 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import java.beans.PropertyChangeEvent;
+
import javax.swing.JComponent;
+import javax.swing.JTextArea;
import javax.swing.UIDefaults;
import javax.swing.plaf.ComponentUI;
import javax.swing.text.Element;
import javax.swing.text.PlainView;
import javax.swing.text.View;
+import javax.swing.text.WrappedPlainView;
public class BasicTextAreaUI extends BasicTextUI
{
@@ -55,11 +59,30 @@ public class BasicTextAreaUI extends BasicTextUI
public BasicTextAreaUI()
{
+ // Nothing to do here.
}
+ /**
+ * Create the view. Returns a WrappedPlainView if the text area
+ * has lineWrap set to true, otherwise returns a PlainView. If
+ * lineWrap is true has to check whether the wrap style is word
+ * or character and return an appropriate WrappedPlainView.
+ *
+ * @param elem the element to create a View for
+ * @return an appropriate View for the element
+ */
public View create(Element elem)
{
- return new PlainView(elem);
+ JTextArea comp = (JTextArea)getComponent();
+ if (comp.getLineWrap())
+ {
+ if (comp.getWrapStyleWord())
+ return new WrappedPlainView(elem, true);
+ else
+ return new WrappedPlainView(elem, false);
+ }
+ else
+ return new PlainView(elem);
}
/**
@@ -71,4 +94,20 @@ public class BasicTextAreaUI extends BasicTextUI
{
return "TextArea";
}
+
+ /**
+ * Receives notification whenever one of the text component's bound
+ * properties changes. This changes the view to WrappedPlainView
+ * if setLineWrap(true) is called, and back to PlainView if
+ * setLineWrap(false) is called.
+ *
+ * @param ev the property change event
+ */
+ protected void propertyChange(PropertyChangeEvent ev)
+ {
+ JTextArea comp = (JTextArea)getComponent();
+ if (ev.getPropertyName() == "lineWrap"
+ || ev.getPropertyName() == "wrapStyleWord")
+ modelChanged();
+ }
}
diff --git a/javax/swing/plaf/basic/BasicTextFieldUI.java b/javax/swing/plaf/basic/BasicTextFieldUI.java
index 07d1691fb..e1422c438 100644
--- a/javax/swing/plaf/basic/BasicTextFieldUI.java
+++ b/javax/swing/plaf/basic/BasicTextFieldUI.java
@@ -79,8 +79,21 @@ public class BasicTextFieldUI extends BasicTextUI
super.installUI(c);
}
+ /**
+ * Receives notification whenever one of the text component's bound
+ * properties changes. Here we check for the editable and enabled
+ * properties and adjust the background color accordingly.
+ *
+ * @param event the property change event
+ */
protected void propertyChange(PropertyChangeEvent event)
{
- // Does nothing by default.
+ if (event.getPropertyName().equals("editable"))
+ {
+ if (textComponent.isEditable())
+ textComponent.setBackground(background);
+ else
+ textComponent.setBackground(inactiveBackground);
+ }
}
}
diff --git a/javax/swing/plaf/basic/BasicTextUI.java b/javax/swing/plaf/basic/BasicTextUI.java
index 2bbf45d9c..225c4a9dd 100644
--- a/javax/swing/plaf/basic/BasicTextUI.java
+++ b/javax/swing/plaf/basic/BasicTextUI.java
@@ -55,6 +55,7 @@ import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JComponent;
+import javax.swing.LookAndFeel;
import javax.swing.SwingUtilities;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
@@ -74,7 +75,6 @@ import javax.swing.text.Element;
import javax.swing.text.Highlighter;
import javax.swing.text.JTextComponent;
import javax.swing.text.Keymap;
-import javax.swing.text.PlainView;
import javax.swing.text.Position;
import javax.swing.text.View;
import javax.swing.text.ViewFactory;
@@ -93,11 +93,11 @@ public abstract class BasicTextUI extends TextUI
/**
* A {@link DefaultCaret} that implements {@link UIResource}.
*/
- public static class BasicCaret extends DefaultCaret
- implements UIResource
+ public static class BasicCaret extends DefaultCaret implements UIResource
{
public BasicCaret()
{
+ // Nothing to do here.
}
}
@@ -109,6 +109,7 @@ public abstract class BasicTextUI extends TextUI
{
public BasicHighlighter()
{
+ // Nothing to do here.
}
}
@@ -253,10 +254,10 @@ public abstract class BasicTextUI extends TextUI
*
* This is delegated to the real root view.
*
- * @param pos the position of the character in the model
+ * @param position the position of the character in the model
* @param a the area that is occupied by the view
- * @param bias either {@link Position.Bias.Forward} or
- * {@link Position.Bias.Backward} depending on the preferred
+ * @param bias either {@link Position.Bias#Forward} or
+ * {@link Position.Bias#Backward} depending on the preferred
* direction bias. If <code>null</code> this defaults to
* <code>Position.Bias.Forward</code>
*
@@ -333,7 +334,7 @@ public abstract class BasicTextUI extends TextUI
/**
* Receives notifications when properties of the text component change.
*/
- class UpdateHandler implements PropertyChangeListener
+ class PropertyChangeHandler implements PropertyChangeListener
{
/**
* Notifies when a property of the text component changes.
@@ -347,13 +348,8 @@ public abstract class BasicTextUI extends TextUI
// Document changed.
modelChanged();
}
- else if (event.getPropertyName().equals("editable"))
- {
- if (textComponent.isEditable())
- textComponent.setBackground(background);
- else
- textComponent.setBackground(inactiveBackground);
- }
+
+ BasicTextUI.this.propertyChange(event);
}
}
@@ -372,11 +368,10 @@ public abstract class BasicTextUI extends TextUI
*/
public void changedUpdate(DocumentEvent ev)
{
- Dimension size = textComponent.getSize();
- rootView.changedUpdate(ev, new Rectangle(0, 0, size.width, size.height),
+ rootView.changedUpdate(ev, getVisibleEditorRect(),
rootView.getViewFactory());
}
-
+
/**
* Notification about a document insert event.
*
@@ -384,12 +379,8 @@ public abstract class BasicTextUI extends TextUI
*/
public void insertUpdate(DocumentEvent ev)
{
- Dimension size = textComponent.getSize();
- rootView.insertUpdate(ev, new Rectangle(0, 0, size.width, size.height),
+ rootView.insertUpdate(ev, getVisibleEditorRect(),
rootView.getViewFactory());
- int caretPos = textComponent.getCaretPosition();
- if (caretPos >= ev.getOffset())
- textComponent.setCaretPosition(caretPos + ev.getLength());
}
/**
@@ -399,12 +390,8 @@ public abstract class BasicTextUI extends TextUI
*/
public void removeUpdate(DocumentEvent ev)
{
- Dimension size = textComponent.getSize();
- rootView.removeUpdate(ev, new Rectangle(0, 0, size.width, size.height),
+ rootView.removeUpdate(ev, getVisibleEditorRect(),
rootView.getViewFactory());
- int caretPos = textComponent.getCaretPosition();
- if (caretPos >= ev.getOffset())
- textComponent.setCaretPosition(ev.getOffset());
}
}
@@ -427,7 +414,7 @@ public abstract class BasicTextUI extends TextUI
/**
* Receives notification when the model changes.
*/
- UpdateHandler updateHandler = new UpdateHandler();
+ PropertyChangeHandler updateHandler = new PropertyChangeHandler();
/** The DocumentEvent handler. */
DocumentHandler documentHandler = new DocumentHandler();
@@ -449,6 +436,7 @@ public abstract class BasicTextUI extends TextUI
*/
public BasicTextUI()
{
+ // Nothing to do here.
}
/**
@@ -526,19 +514,18 @@ public abstract class BasicTextUI extends TextUI
textComponent.setHighlighter(createHighlighter());
String prefix = getPropertyPrefix();
- UIDefaults defaults = UIManager.getLookAndFeelDefaults();
- textComponent.setMargin(defaults.getInsets(prefix + ".margin"));
- textComponent.setBorder(defaults.getBorder(prefix + ".border"));
- textComponent.setFont(defaults.getFont(prefix + ".font"));
+ LookAndFeel.installColorsAndFont(textComponent, prefix + ".background",
+ prefix + ".foreground", prefix + ".font");
+ LookAndFeel.installBorder(textComponent, prefix + ".border");
+ textComponent.setMargin(UIManager.getInsets(prefix + ".margin"));
- caret.setBlinkRate(defaults.getInt(prefix + ".caretBlinkRate"));
+ caret.setBlinkRate(UIManager.getInt(prefix + ".caretBlinkRate"));
// Fetch the colors for enabled/disabled text components.
- background = defaults.getColor(prefix + ".background");
- inactiveBackground = defaults.getColor(prefix + ".inactiveBackground");
- textComponent.setForeground(defaults.getColor(prefix + ".foreground"));
+ inactiveBackground = UIManager.getColor(prefix + ".inactiveBackground");
textComponent.setDisabledTextColor
- (defaults.getColor(prefix + ".inactiveForeground"));
+ (UIManager.getColor(prefix + ".inactiveForeground"));
+ textComponent.setSelectedTextColor(UIManager.getColor(prefix + ".selectionForeground"));
}
/**
@@ -824,8 +811,8 @@ public abstract class BasicTextUI extends TextUI
{
// This method does nothing. All the background filling is done by the
// ComponentUI update method. However, the method is called by paint
- // to provide a way for subclasses to draw something different (e.g. background
- // images etc) on the background.
+ // to provide a way for subclasses to draw something different (e.g.
+ // background images etc) on the background.
}
/**
@@ -912,10 +899,10 @@ public abstract class BasicTextUI extends TextUI
/**
* Maps a position in the document into the coordinate space of the View.
* The output rectangle usually reflects the font height but has a width
- * of zero. A bias of {@link Position.Bias.Forward} is used in this method.
+ * of zero. A bias of {@link Position.Bias#Forward} is used in this method.
*
+ * @param t the text component
* @param pos the position of the character in the model
- * @param a the area that is occupied by the view
*
* @return a rectangle that gives the location of the document position
* inside the view coordinate space
@@ -935,10 +922,10 @@ public abstract class BasicTextUI extends TextUI
* The output rectangle usually reflects the font height but has a width
* of zero.
*
+ * @param t the text component
* @param pos the position of the character in the model
- * @param a the area that is occupied by the view
- * @param bias either {@link Position.Bias.Forward} or
- * {@link Position.Bias.Backward} depending on the preferred
+ * @param bias either {@link Position.Bias#Forward} or
+ * {@link Position.Bias#Backward} depending on the preferred
* direction bias. If <code>null</code> this defaults to
* <code>Position.Bias.Forward</code>
*
@@ -984,7 +971,7 @@ public abstract class BasicTextUI extends TextUI
*/
public int viewToModel(JTextComponent t, Point pt, Position.Bias[] biasReturn)
{
- return 0; // FIXME: Implement me.
+ return rootView.viewToModel(pt.x, pt.y, getVisibleEditorRect(), biasReturn);
}
/**
@@ -1030,7 +1017,7 @@ public abstract class BasicTextUI extends TextUI
int height = textComponent.getHeight();
if (width <= 0 || height <= 0)
- return null;
+ return new Rectangle(0, 0, 0, 0);
Insets insets = textComponent.getInsets();
return new Rectangle(insets.left, insets.top,
@@ -1047,6 +1034,8 @@ public abstract class BasicTextUI extends TextUI
{
rootView.setView(view);
view.setParent(rootView);
+ textComponent.revalidate();
+ textComponent.repaint();
}
/**
@@ -1070,4 +1059,17 @@ public abstract class BasicTextUI extends TextUI
View view = factory.create(elem);
setView(view);
}
+
+ /**
+ * Receives notification whenever one of the text component's bound
+ * properties changes. This default implementation does nothing.
+ * It is a hook that enables subclasses to react to property changes
+ * on the text component.
+ *
+ * @param ev the property change event
+ */
+ protected void propertyChange(PropertyChangeEvent ev)
+ {
+ // The default implementation does nothing.
+ }
}
diff --git a/javax/swing/plaf/basic/BasicToggleButtonUI.java b/javax/swing/plaf/basic/BasicToggleButtonUI.java
index 9106b0b66..896ea0c89 100644
--- a/javax/swing/plaf/basic/BasicToggleButtonUI.java
+++ b/javax/swing/plaf/basic/BasicToggleButtonUI.java
@@ -38,7 +38,13 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import java.awt.Font;
+import java.awt.Graphics;
+import java.awt.Rectangle;
+
+import javax.swing.AbstractButton;
import javax.swing.JComponent;
+import javax.swing.SwingUtilities;
import javax.swing.plaf.ComponentUI;
public class BasicToggleButtonUI extends BasicButtonUI
@@ -58,5 +64,62 @@ public class BasicToggleButtonUI extends BasicButtonUI
{
return "ToggleButton.";
}
-}
+ /**
+ * Paint the component, which is an {@link AbstractButton}, according to
+ * its current state.
+ *
+ * @param g The graphics context to paint with
+ * @param c The component to paint the state of
+ */
+ public void paint(Graphics g, JComponent c)
+ {
+ AbstractButton b = (AbstractButton) c;
+
+ Rectangle tr = new Rectangle();
+ Rectangle ir = new Rectangle();
+ Rectangle vr = new Rectangle();
+
+ Font f = c.getFont();
+
+ g.setFont(f);
+
+ if (b.isBorderPainted())
+ SwingUtilities.calculateInnerArea(b, vr);
+ else
+ vr = SwingUtilities.getLocalBounds(b);
+ String text = SwingUtilities.layoutCompoundLabel(c, g.getFontMetrics(f),
+ b.getText(),
+ currentIcon(b),
+ b.getVerticalAlignment(),
+ b.getHorizontalAlignment(),
+ b.getVerticalTextPosition(),
+ b.getHorizontalTextPosition(),
+ vr, ir, tr,
+ b.getIconTextGap()
+ + defaultTextShiftOffset);
+
+ if ((b.getModel().isArmed() && b.getModel().isPressed())
+ || b.isSelected())
+ paintButtonPressed(g, b);
+
+ paintIcon(g, b, ir);
+ if (text != null)
+ paintText(g, b, tr, text);
+ if (b.isFocusOwner() && b.isFocusPainted())
+ paintFocus(g, b, vr, tr, ir);
+ }
+
+ /**
+ * Paints the icon for the toggle button. This delegates to
+ * {@link BasicButtonUI#paintIcon(Graphics, JComponent, Rectangle)}.
+ *
+ * @param g the graphics context
+ * @param b the button to paint the icon for
+ * @param iconRect the area allocated for the icon
+ */
+ protected void paintIcon(Graphics g, AbstractButton b, Rectangle iconRect)
+ {
+ super.paintIcon(g, b, iconRect);
+ }
+}
diff --git a/javax/swing/plaf/basic/BasicToolBarSeparatorUI.java b/javax/swing/plaf/basic/BasicToolBarSeparatorUI.java
index db29fdca5..79cf0b0c2 100644
--- a/javax/swing/plaf/basic/BasicToolBarSeparatorUI.java
+++ b/javax/swing/plaf/basic/BasicToolBarSeparatorUI.java
@@ -43,7 +43,6 @@ import java.awt.Graphics;
import javax.swing.JComponent;
import javax.swing.JSeparator;
-import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
@@ -73,9 +72,7 @@ public class BasicToolBarSeparatorUI extends BasicSeparatorUI
*/
protected void installDefaults(JSeparator s)
{
- UIDefaults defaults = UIManager.getLookAndFeelDefaults();
-
- size = defaults.getDimension("ToolBar.separatorSize");
+ size = UIManager.getDimension("ToolBar.separatorSize");
}
/**
diff --git a/javax/swing/plaf/basic/BasicToolBarUI.java b/javax/swing/plaf/basic/BasicToolBarUI.java
index 807582d9f..d02922f74 100644
--- a/javax/swing/plaf/basic/BasicToolBarUI.java
+++ b/javax/swing/plaf/basic/BasicToolBarUI.java
@@ -65,10 +65,11 @@ import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JToolBar;
+import javax.swing.KeyStroke;
+import javax.swing.LookAndFeel;
import javax.swing.RootPaneContainer;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
-import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.event.MouseInputListener;
@@ -133,6 +134,26 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants
protected FocusListener toolBarFocusListener;
/**
+ * @deprecated since JDK1.3.
+ */
+ protected KeyStroke leftKey;
+
+ /**
+ * @deprecated since JDK1.3.
+ */
+ protected KeyStroke rightKey;
+
+ /**
+ * @deprecated since JDK1.3.
+ */
+ protected KeyStroke upKey;
+
+ /**
+ * @deprecated since JDK1.3.
+ */
+ protected KeyStroke downKey;
+
+ /**
* The floating window that is responsible for holding the JToolBar when it
* is dragged outside of its original parent.
*/
@@ -566,18 +587,15 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants
*/
protected void installDefaults()
{
- UIDefaults defaults = UIManager.getLookAndFeelDefaults();
-
- toolBar.setBorder(new ToolBarBorder());
- toolBar.setBackground(defaults.getColor("ToolBar.background"));
- toolBar.setForeground(defaults.getColor("ToolBar.foreground"));
- toolBar.setFont(defaults.getFont("ToolBar.font"));
+ LookAndFeel.installBorder(toolBar, "ToolBar.border");
+ LookAndFeel.installColorsAndFont(toolBar, "ToolBar.background",
+ "ToolBar.foreground", "ToolBar.font");
- dockingBorderColor = defaults.getColor("ToolBar.dockingForeground");
- dockingColor = defaults.getColor("ToolBar.dockingBackground");
+ dockingBorderColor = UIManager.getColor("ToolBar.dockingForeground");
+ dockingColor = UIManager.getColor("ToolBar.dockingBackground");
- floatingBorderColor = defaults.getColor("ToolBar.floatingForeground");
- floatingColor = defaults.getColor("ToolBar.floatingBackground");
+ floatingBorderColor = UIManager.getColor("ToolBar.floatingForeground");
+ floatingColor = UIManager.getColor("ToolBar.floatingBackground");
}
/**
@@ -591,10 +609,8 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants
/**
* This method installs listeners for the JToolBar.
- *
- * @param toolbar The JToolBar to register listeners for.
*/
- protected void installListeners(JToolBar toolbar)
+ protected void installListeners()
{
dockingListener = createDockingListener();
toolBar.addMouseListener(dockingListener);
@@ -694,7 +710,7 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants
toolBar.setOpaque(true);
installDefaults();
installComponents();
- installListeners(toolBar);
+ installListeners();
installKeyboardActions();
}
}
@@ -1000,6 +1016,7 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants
*/
public void mouseMoved(MouseEvent e)
{
+ // TODO: What should be done here, if anything?
}
/**
diff --git a/javax/swing/plaf/basic/BasicToolTipUI.java b/javax/swing/plaf/basic/BasicToolTipUI.java
index b7a08aa72..5cec2e333 100644
--- a/javax/swing/plaf/basic/BasicToolTipUI.java
+++ b/javax/swing/plaf/basic/BasicToolTipUI.java
@@ -1,5 +1,5 @@
/* BasicToolTipUI.java --
- Copyright (C) 2004 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,20 +39,18 @@ exception statement from your version. */
package javax.swing.plaf.basic;
import java.awt.Color;
-import java.awt.Component;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Rectangle;
+import java.awt.Toolkit;
import javax.swing.JComponent;
import javax.swing.JToolTip;
+import javax.swing.LookAndFeel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
-import javax.swing.UIDefaults;
-import javax.swing.UIManager;
-import javax.swing.border.Border;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.ToolTipUI;
@@ -61,58 +59,12 @@ import javax.swing.plaf.ToolTipUI;
*/
public class BasicToolTipUI extends ToolTipUI
{
- /** The default Border around the JToolTip. */
- private static Border defaultBorder = new Border()
- {
- // FIXME: This needs to go into Basic Look and Feel
- // defaults.
- /**
- * This method returns the border insets.
- *
- * @param c The Component to find Border insets for.
- *
- * @return The Border insets.
- */
- public Insets getBorderInsets(Component c)
- {
- return new Insets(4, 4, 4, 4);
- }
+ /** The shared instance of BasicToolTipUI used for all ToolTips. */
+ private static BasicToolTipUI shared;
- /**
- * This method returns whether the border is opaque.
- *
- * @return Whether the border is opaque.
- */
- public boolean isBorderOpaque()
- {
- return false;
- }
-
- /**
- * This method paints the border.
- *
- * @param c The Component to paint this border around.
- * @param g The Graphics object to paint with.
- * @param x The x coordinate to start painting at.
- * @param y The y coordinate to start painting at.
- * @param w The width of the Component.
- * @param h The height of the Component.
- */
- public void paintBorder(Component c, Graphics g, int x, int y, int w,
- int h)
- {
- Color saved = g.getColor();
- g.setColor(Color.BLACK);
-
- g.drawRect(0, 0, w - 1, h - 1);
-
- g.setColor(saved);
- }
- };
-
- /** The shared instance of BasicToolTipUI used for all ToolTips. */
- private static BasicToolTipUI shared;
+ /** The tooltip's text */
+ private String text;
/**
* Creates a new BasicToolTipUI object.
@@ -124,7 +76,7 @@ public class BasicToolTipUI extends ToolTipUI
/**
* This method creates a new BasicToolTip UI for the given
- * JComponent.
+ * JComponent.
*
* @param c The JComponent to create a UI for.
*
@@ -132,9 +84,9 @@ public class BasicToolTipUI extends ToolTipUI
*/
public static ComponentUI createUI(JComponent c)
{
- if (shared == null)
- shared = new BasicToolTipUI();
- return shared;
+ if (shared == null)
+ shared = new BasicToolTipUI();
+ return shared;
}
/**
@@ -171,12 +123,16 @@ public class BasicToolTipUI extends ToolTipUI
public Dimension getPreferredSize(JComponent c)
{
JToolTip tip = (JToolTip) c;
+ FontMetrics fm;
+ Toolkit g = tip.getToolkit();
+ text = tip.getTipText();
+
Rectangle vr = new Rectangle();
Rectangle ir = new Rectangle();
Rectangle tr = new Rectangle();
Insets insets = tip.getInsets();
- FontMetrics fm = tip.getToolkit().getFontMetrics(tip.getFont());
- SwingUtilities.layoutCompoundLabel(tip, fm, tip.getTipText(), null,
+ fm = g.getFontMetrics(tip.getFont());
+ SwingUtilities.layoutCompoundLabel(tip, fm, text, null,
SwingConstants.CENTER,
SwingConstants.CENTER,
SwingConstants.CENTER,
@@ -192,11 +148,9 @@ public class BasicToolTipUI extends ToolTipUI
*/
protected void installDefaults(JComponent c)
{
- UIDefaults defaults = UIManager.getLookAndFeelDefaults();
- c.setBackground(defaults.getColor("ToolTip.background"));
- c.setForeground(defaults.getColor("ToolTip.foreground"));
- c.setFont(defaults.getFont("ToolTip.font"));
- c.setBorder(defaultBorder);
+ LookAndFeel.installColorsAndFont(c, "ToolTip.background",
+ "ToolTip.foreground", "ToolTip.font");
+ LookAndFeel.installBorder(c, "ToolTip.border");
}
/**
@@ -206,6 +160,7 @@ public class BasicToolTipUI extends ToolTipUI
*/
protected void installListeners(JComponent c)
{
+ // TODO: Implement this properly.
}
/**
@@ -231,6 +186,7 @@ public class BasicToolTipUI extends ToolTipUI
JToolTip tip = (JToolTip) c;
String text = tip.getTipText();
+ Toolkit t = tip.getToolkit();
if (text == null)
return;
@@ -238,19 +194,19 @@ public class BasicToolTipUI extends ToolTipUI
vr = SwingUtilities.calculateInnerArea(tip, vr);
Rectangle ir = new Rectangle();
Rectangle tr = new Rectangle();
- FontMetrics fm = tip.getToolkit().getFontMetrics(tip.getFont());
- SwingUtilities.layoutCompoundLabel(tip, fm, tip.getTipText(), null,
+ FontMetrics fm = t.getFontMetrics(tip.getFont());
+ int ascent = fm.getAscent();
+ SwingUtilities.layoutCompoundLabel(tip, fm, text, null,
SwingConstants.CENTER,
SwingConstants.CENTER,
SwingConstants.CENTER,
SwingConstants.CENTER, vr, ir, tr, 0);
-
Color saved = g.getColor();
g.setColor(Color.BLACK);
- g.drawString(text, vr.x, vr.y + fm.getAscent());
+ g.drawString(text, vr.x, vr.y + ascent);
- g.setColor(saved);
+ g.setColor(saved);
}
/**
@@ -273,6 +229,7 @@ public class BasicToolTipUI extends ToolTipUI
*/
protected void uninstallListeners(JComponent c)
{
+ // TODO: Implement this properly.
}
/**
diff --git a/javax/swing/plaf/basic/BasicTreeUI.java b/javax/swing/plaf/basic/BasicTreeUI.java
index df763a83d..4f4646c8a 100644
--- a/javax/swing/plaf/basic/BasicTreeUI.java
+++ b/javax/swing/plaf/basic/BasicTreeUI.java
@@ -78,6 +78,7 @@ import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.KeyStroke;
+import javax.swing.LookAndFeel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIDefaults;
@@ -111,11 +112,11 @@ import javax.swing.tree.TreeSelectionModel;
* the Basic look and feel.
*
* @see javax.swing.JTree
- * @author Sascha Brawer (brawer@dandelis.ch)
+ *
* @author Lillian Angel (langel@redhat.com)
+ * @author Sascha Brawer (brawer@dandelis.ch)
*/
-public class BasicTreeUI
- extends TreeUI
+public class BasicTreeUI extends TreeUI
{
/** Collapse Icon for the tree. */
protected transient Icon collapsedIcon;
@@ -137,9 +138,6 @@ public class BasicTreeUI
*/
protected int totalChildIndent;
- /** Minimum preferred size. */
- protected Dimension preferredMinsize;
-
/** Index of the row that was last selected. */
protected int lastSelectedRow;
@@ -227,7 +225,7 @@ public class BasicTreeUI
/** Set to true if the editor has a different size than the renderer. */
protected boolean editorHasDifferentSize;
-
+
/** The action listener for the editor's Timer. */
Timer editorTimer = new EditorUpdateTimer();
@@ -242,16 +240,22 @@ public class BasicTreeUI
/** The bounds of the current cell. */
Rectangle bounds;
+
+ /** The current path of the visible nodes in the tree. */
+ TreePath currentVisiblePath;
+
+ /** The gap between the icon and text. */
+ int gap = 4;
/** Listeners */
private PropertyChangeListener propertyChangeListener;
private FocusListener focusListener;
private TreeSelectionListener treeSelectionListener;
- private MouseInputListener mouseInputListener;
+ private MouseListener mouseListener;
private KeyListener keyListener;
private PropertyChangeListener selectionModelPropertyChangeListener;
private ComponentListener componentListener;
- private CellEditorListener cellEditorListener;
+ CellEditorListener cellEditorListener;
private TreeExpansionListener treeExpansionListener;
private TreeModelListener treeModelListener;
@@ -260,6 +264,7 @@ public class BasicTreeUI
*/
public BasicTreeUI()
{
+ validCachedPreferredSize = false;
drawingCache = new Hashtable();
nodeDimensions = createNodeDimensions();
configureLayoutCache();
@@ -267,7 +272,7 @@ public class BasicTreeUI
propertyChangeListener = createPropertyChangeListener();
focusListener = createFocusListener();
treeSelectionListener = createTreeSelectionListener();
- mouseInputListener = new MouseInputHandler(null, null, null);
+ mouseListener = createMouseListener();
keyListener = createKeyListener();
selectionModelPropertyChangeListener = createSelectionModelPropertyChangeListener();
componentListener = createComponentListener();
@@ -329,7 +334,7 @@ public class BasicTreeUI
*
* @return the indent value for the left child.
*/
- public int getLeftChildIndent(int newAmount)
+ public int getLeftChildIndent()
{
return leftChildIndent;
}
@@ -625,6 +630,7 @@ public class BasicTreeUI
if (treeModel != null)
{
Object root = treeModel.getRoot();
+
if (!tree.isRootVisible() && tree.isExpanded(new TreePath(root)))
root = getNextNode(root);
@@ -646,20 +652,11 @@ public class BasicTreeUI
*/
public TreePath getPathForRow(JTree tree, int row)
{
- if (treeModel != null)
+ if (treeModel != null && currentVisiblePath != null)
{
- Object node = treeModel.getRoot();
- if (!tree.isRootVisible()
- && tree.isExpanded(new TreePath(getPathToRoot(node, 0))))
- node = getNextNode(node);
-
- for (int i = 0; i < row; i++)
- node = getNextVisibleNode(node);
-
- if (node == null)
- return null;
-
- return new TreePath(getPathToRoot(node, 0));
+ Object[] nodes = currentVisiblePath.getPath();
+ if (row < nodes.length)
+ return new TreePath(getPathToRoot(nodes[row], 0));
}
return null;
}
@@ -680,13 +677,18 @@ public class BasicTreeUI
{
int row = 0;
Object dest = path.getLastPathComponent();
- Object curr = treeModel.getRoot();
- while (curr != null && !curr.equals(dest))
+ int rowCount = getRowCount(tree);
+ if (currentVisiblePath != null)
{
- ++row;
- curr = getNextVisibleNode(curr);
+ Object[] nodes = currentVisiblePath.getPath();
+ while (row < rowCount)
+ {
+ if (dest.equals(nodes[row]))
+ return row;
+ row++;
+ }
}
- return row;
+ return -1;
}
/**
@@ -698,21 +700,9 @@ public class BasicTreeUI
*/
public int getRowCount(JTree tree)
{
- int count = 0;
- if (treeModel != null)
- {
- Object node = treeModel.getRoot();
- if (!tree.isRootVisible()
- && tree.isExpanded(new TreePath((getPathToRoot(node, 0)))))
- node = getNextNode(node);
-
- while (node != null)
- {
- count++;
- node = getNextVisibleNode(node);
- }
- }
- return count;
+ if (currentVisiblePath != null)
+ return currentVisiblePath.getPathCount();
+ return 0;
}
/**
@@ -733,7 +723,7 @@ public class BasicTreeUI
{
// FIXME: what if root is hidden? should not depend on (0,0)
// should start counting rows from where root is.
-
+
int row = Math.round(y / getRowHeight());
TreePath path = getPathForRow(tree, row);
@@ -820,6 +810,7 @@ public class BasicTreeUI
*/
protected void prepareForUIInstall()
{
+ // TODO: Implement this properly.
}
/**
@@ -828,6 +819,7 @@ public class BasicTreeUI
*/
protected void completeUIInstall()
{
+ // TODO: Implement this properly.
}
/**
@@ -836,6 +828,7 @@ public class BasicTreeUI
*/
protected void completeUIUninstall()
{
+ // TODO: Implement this properly.
}
/**
@@ -1026,7 +1019,7 @@ public class BasicTreeUI
tree.removePropertyChangeListener(propertyChangeListener);
tree.removeFocusListener(focusListener);
tree.removeTreeSelectionListener(treeSelectionListener);
- tree.removeMouseListener(mouseInputListener);
+ tree.removeMouseListener(mouseListener);
tree.removeKeyListener(keyListener);
tree.removePropertyChangeListener(selectionModelPropertyChangeListener);
tree.removeComponentListener(componentListener);
@@ -1044,6 +1037,7 @@ public class BasicTreeUI
*/
protected void uninstallKeyboardActions()
{
+ // TODO: Implement this properly.
}
/**
@@ -1087,8 +1081,7 @@ public class BasicTreeUI
protected void updateLayoutCacheExpandedNodes()
{
if (treeModel != null)
- updateExpandedDescendants(new TreePath(getPathToRoot(treeModel.
- getRoot(), 0)));
+ updateExpandedDescendants(new TreePath(treeModel.getRoot()));
}
/**
@@ -1144,7 +1137,14 @@ public class BasicTreeUI
protected void updateRenderer()
{
if (tree != null)
- tree.setCellRenderer(currentCellRenderer);
+ {
+ if(tree.getCellRenderer() == null)
+ {
+ if(currentCellRenderer == null)
+ currentCellRenderer = createDefaultCellRenderer();
+ tree.setCellRenderer(currentCellRenderer);
+ }
+ }
}
/**
@@ -1169,14 +1169,30 @@ public class BasicTreeUI
/**
* Updates the <code>preferredSize</code> instance variable, which is
- * returned from <code>getPreferredSize()</code>. For left to right
- * orientations, the size is determined from the current AbstractLayoutCache.
- * For RTL orientations, the preferred size becomes the width minus the
- * minimum x position.
+ * returned from <code>getPreferredSize()</code>.
*/
protected void updateCachedPreferredSize()
{
- // FIXME: not implemented
+ int maxWidth = 0;
+ boolean isLeaf = false;
+ if (currentVisiblePath != null)
+ {
+ Object[] path = currentVisiblePath.getPath();
+ for (int i = 0; i < path.length; i++)
+ {
+ TreePath curr = new TreePath(getPathToRoot(path[i], 0));
+ Rectangle bounds = getPathBounds(tree, curr);
+
+ if (treeModel != null)
+ isLeaf = treeModel.isLeaf(path[i]);
+ if (!isLeaf && hasControlIcons())
+ bounds.width += getCurrentControlIcon(curr).getIconWidth();
+ maxWidth = Math.max(maxWidth, bounds.x + bounds.width);
+ }
+ preferredSize = new Dimension(maxWidth, (getRowHeight() * path.length));
+ }
+ else preferredSize = new Dimension(0, 0);
+ validCachedPreferredSize = true;
}
/**
@@ -1187,7 +1203,9 @@ public class BasicTreeUI
*/
protected void pathWasExpanded(TreePath path)
{
- // FIXME: not implemented
+ validCachedPreferredSize = false;
+ tree.revalidate();
+ tree.repaint();
}
/**
@@ -1195,31 +1213,28 @@ public class BasicTreeUI
*/
protected void pathWasCollapsed(TreePath path)
{
- // FIXME: not implemented
+ validCachedPreferredSize = false;
+ tree.revalidate();
+ tree.repaint();
}
/**
* Install all defaults for the tree.
- *
- * @param tree
- * is the JTree to install defaults for
*/
protected void installDefaults()
{
- UIDefaults defaults = UIManager.getLookAndFeelDefaults();
-
- tree.setFont(defaults.getFont("Tree.font"));
- tree.setForeground(defaults.getColor("Tree.foreground"));
- tree.setBackground(defaults.getColor("Tree.background"));
+ LookAndFeel.installColorsAndFont(tree, "Tree.background",
+ "Tree.foreground", "Tree.font");
tree.setOpaque(true);
- rightChildIndent = defaults.getInt("Tree.rightChildIndent");
- leftChildIndent = defaults.getInt("Tree.leftChildIndent");
- setRowHeight(defaults.getInt("Tree.rowHeight"));
+ rightChildIndent = UIManager.getInt("Tree.rightChildIndent");
+ leftChildIndent = UIManager.getInt("Tree.leftChildIndent");
+ setRowHeight(UIManager.getInt("Tree.rowHeight"));
+ tree.setRowHeight(UIManager.getInt("Tree.rowHeight"));
tree.requestFocusInWindow(false);
- tree.setScrollsOnExpand(defaults.getBoolean("Tree.scrollsOnExpand"));
- setExpandedIcon(defaults.getIcon("Tree.expandedIcon"));
- setCollapsedIcon(defaults.getIcon("Tree.collapsedIcon"));
+ tree.setScrollsOnExpand(UIManager.getBoolean("Tree.scrollsOnExpand"));
+ setExpandedIcon(UIManager.getIcon("Tree.expandedIcon"));
+ setCollapsedIcon(UIManager.getIcon("Tree.collapsedIcon"));
}
/**
@@ -1309,7 +1324,7 @@ public class BasicTreeUI
tree.addPropertyChangeListener(propertyChangeListener);
tree.addFocusListener(focusListener);
tree.addTreeSelectionListener(treeSelectionListener);
- tree.addMouseListener(mouseInputListener);
+ tree.addMouseListener(mouseListener);
tree.addKeyListener(keyListener);
tree.addPropertyChangeListener(selectionModelPropertyChangeListener);
tree.addComponentListener(componentListener);
@@ -1326,34 +1341,34 @@ public class BasicTreeUI
*/
public void installUI(JComponent c)
{
+ tree = (JTree) c;
prepareForUIInstall();
super.installUI(c);
- tree = (JTree) c;
installDefaults();
installComponents();
-
+ installKeyboardActions();
+ installListeners();
+
setCellEditor(createDefaultCellEditor());
createdCellEditor = true;
isEditing = false;
-
+
TreeModel mod = tree.getModel();
setModel(mod);
- tree.setRootVisible(true);
if (mod != null)
- tree.expandPath(new TreePath(mod.getRoot()));
+ {
+ TreePath path = new TreePath(mod.getRoot());
+ if (!tree.isExpanded(path))
+ toggleExpandState(path);
+ }
treeSelectionModel = tree.getSelectionModel();
- installKeyboardActions();
- installListeners();
completeUIInstall();
}
/**
* Uninstall the defaults for the tree
- *
- * @param tree
- * to uninstall defaults for
*/
protected void uninstallDefaults()
{
@@ -1395,18 +1410,16 @@ public class BasicTreeUI
public void paint(Graphics g, JComponent c)
{
JTree tree = (JTree) c;
-
+ if (currentVisiblePath == null)
+ updateCurrentVisiblePath();
+
if (treeModel != null)
{
Object root = treeModel.getRoot();
-
- if (!tree.isRootVisible())
- tree.expandPath(new TreePath(root));
-
- paintRecursive(g, 0, 0, 0, 0, tree, treeModel, root);
-
+ paintRecursive(g, 0, 0, 0, tree, treeModel, root);
+
if (hasControlIcons())
- paintControlIcons(g, 0, 0, 0, 0, tree, treeModel, root);
+ paintControlIcons(g, 0, 0, 0, tree, treeModel, root);
}
}
@@ -1443,7 +1456,7 @@ public class BasicTreeUI
*/
public void setPreferredMinSize(Dimension newSize)
{
- // FIXME: not implemented
+ preferredMinSize = newSize;
}
/**
@@ -1453,8 +1466,7 @@ public class BasicTreeUI
*/
public Dimension getPreferredMinSize()
{
- // FIXME: not implemented
- return null;
+ return preferredMinSize;
}
/**
@@ -1484,27 +1496,10 @@ public class BasicTreeUI
*/
public Dimension getPreferredSize(JComponent c, boolean checkConsistancy)
{
- // FIXME: checkConsistancy not implemented, c not used
- int maxWidth = 0;
- int count = 0;
- if (treeModel != null)
- {
- Object node = treeModel.getRoot();
- if (node != null)
- {
- maxWidth = (int) (getCellBounds(0, 0, node).getWidth());
- while (node != null)
- {
- count++;
- Object nextNode = getNextVisibleNode(node);
- if (nextNode != null)
- maxWidth = Math.max(maxWidth,
- (int) (getCellBounds(0, 0, nextNode).getWidth()));
- node = nextNode;
- }
- }
- }
- return new Dimension(maxWidth, (getRowHeight() * count));
+ // FIXME: checkConsistancy not implemented, c not used
+ if(!validCachedPreferredSize)
+ updateCachedPreferredSize();
+ return preferredSize;
}
/**
@@ -1598,7 +1593,7 @@ public class BasicTreeUI
int y;
if (event == null)
{
- Rectangle bounds = getPathBounds(tree, path);
+ bounds = getPathBounds(tree, path);
x = bounds.x;
y = bounds.y;
}
@@ -1628,6 +1623,8 @@ public class BasicTreeUI
editingComponent.getParent().validate();
tree.add(editingComponent.getParent());
editingComponent.getParent().validate();
+ validCachedPreferredSize = false;
+ tree.revalidate();
((JTextField) editingComponent).requestFocusInWindow(false);
editorTimer.start();
return true;
@@ -1676,16 +1673,10 @@ public class BasicTreeUI
if (!isLeaf(row))
{
- if (bounds == null)
- bounds = getPathBounds(tree, path);
- if (tree.isExpanded(path) && expandedIcon != null)
- bounds.x -= expandedIcon.getIconWidth() - 4;
- else if (collapsedIcon != null)
- bounds.x -= collapsedIcon.getIconWidth() - 4;
-
- Icon controlIcon = getCurrentControlIcon(path);
- if (controlIcon != null && (mouseX < bounds.x)
- && (mouseX > (bounds.x - controlIcon.getIconWidth())))
+ bounds = getPathBounds(tree, path);
+
+ if (hasControlIcons() && (mouseX < bounds.x)
+ && (mouseX > (bounds.x - getCurrentControlIcon(path).getIconWidth() - gap)))
cntlClick = true;
}
return cntlClick;
@@ -1722,6 +1713,7 @@ public class BasicTreeUI
tree.collapsePath(path);
else
tree.expandPath(path);
+ updateCurrentVisiblePath();
}
/**
@@ -1856,7 +1848,7 @@ public class BasicTreeUI
(new TreeTraverseAction(0, "")).actionPerformed(e);
else if (e.getActionCommand().equals("selectAll"))
{
- TreePath[] paths = new TreePath[tree.getRowCount()];
+ TreePath[] paths = new TreePath[tree.getVisibleRowCount()];
Object curr = getNextVisibleNode(treeModel.getRoot());
int i = 0;
@@ -1971,8 +1963,7 @@ public class BasicTreeUI
/**
* Updates the preferred size when scrolling, if necessary.
*/
- public class ComponentHandler
- extends ComponentAdapter
+ public class ComponentHandler extends ComponentAdapter
implements ActionListener
{
/**
@@ -1988,6 +1979,7 @@ public class BasicTreeUI
*/
public ComponentHandler()
{
+ // Nothing to do here.
}
/**
@@ -1998,6 +1990,7 @@ public class BasicTreeUI
*/
public void componentMoved(ComponentEvent e)
{
+ // TODO: What should be done here, if anything?
}
/**
@@ -2006,6 +1999,7 @@ public class BasicTreeUI
*/
protected void startTimer()
{
+ // TODO: Implement this properly.
}
/**
@@ -2027,21 +2021,22 @@ public class BasicTreeUI
*/
public void actionPerformed(ActionEvent ae)
{
+ // TODO: Implement this properly.
}
- }// ComponentHandler
+ }
/**
* Listener responsible for getting cell editing events and updating the tree
* accordingly.
*/
- public class CellEditorHandler
- implements CellEditorListener
+ public class CellEditorHandler implements CellEditorListener
{
/**
* Constructor
*/
public CellEditorHandler()
{
+ // Nothing to do here.
}
/**
@@ -2074,6 +2069,9 @@ public class BasicTreeUI
isEditing = false;
tree.requestFocusInWindow(false);
editorTimer.stop();
+ validCachedPreferredSize = false;
+ tree.revalidate();
+ tree.repaint();
}
/**
@@ -2102,6 +2100,8 @@ public class BasicTreeUI
tree.requestFocusInWindow(false);
editorTimer.stop();
isEditing = false;
+ validCachedPreferredSize = false;
+ tree.revalidate();
tree.repaint();
}
}// CellEditorHandler
@@ -2117,6 +2117,7 @@ public class BasicTreeUI
*/
public FocusHandler()
{
+ // Nothing to do here.
}
/**
@@ -2128,6 +2129,7 @@ public class BasicTreeUI
*/
public void focusGained(FocusEvent e)
{
+ // TODO: Implement this properly.
}
/**
@@ -2139,8 +2141,9 @@ public class BasicTreeUI
*/
public void focusLost(FocusEvent e)
{
+ // TODO: Implement this properly.
}
- }// FocusHandler
+ }
/**
* This is used to get multiple key down events to appropriately genereate
@@ -2160,6 +2163,7 @@ public class BasicTreeUI
*/
public KeyHandler()
{
+ // Nothing to do here.
}
/**
@@ -2173,6 +2177,7 @@ public class BasicTreeUI
*/
public void keyTyped(KeyEvent e)
{
+ // TODO: What should be done here, if anything?
}
/**
@@ -2183,6 +2188,7 @@ public class BasicTreeUI
*/
public void keyPressed(KeyEvent e)
{
+ // TODO: What should be done here, if anything?
}
/**
@@ -2193,22 +2199,22 @@ public class BasicTreeUI
*/
public void keyReleased(KeyEvent e)
{
+ // TODO: What should be done here, if anything?
}
- }// KeyHandler
+ }
/**
* MouseListener is responsible for updating the selection based on mouse
* events.
*/
- public class MouseHandler
- extends MouseAdapter
- implements MouseMotionListener
+ public class MouseHandler extends MouseAdapter implements MouseMotionListener
{
/**
* Constructor
*/
public MouseHandler()
{
+ // Nothing to do here.
}
/**
@@ -2219,6 +2225,54 @@ public class BasicTreeUI
*/
public void mousePressed(MouseEvent e)
{
+ Point click = e.getPoint();
+ TreePath path = getClosestPathForLocation(tree, click.x, click.y);
+
+ if (path != null)
+ {
+ bounds = getPathBounds(tree, path);
+ int row = getRowForPath(tree, path);
+ boolean cntlClick = isLocationInExpandControl(path, click.x, click.y);
+
+ boolean isLeaf = isLeaf(row);
+
+ TreeCellRenderer tcr = getCellRenderer();
+ Icon icon;
+ if (isLeaf)
+ icon = UIManager.getIcon("Tree.leafIcon");
+ else if (tree.isExpanded(path))
+ icon = UIManager.getIcon("Tree.openIcon");
+ else
+ icon = UIManager.getIcon("Tree.closedIcon");
+
+ if (tcr instanceof DefaultTreeCellRenderer)
+ {
+ Icon tmp = ((DefaultTreeCellRenderer) tcr).getIcon();
+ if (tmp != null)
+ icon = tmp;
+ }
+
+ // add gap*2 for the space before and after the text
+ if (icon != null)
+ bounds.width += icon.getIconWidth() + gap*2;
+
+ boolean inBounds = bounds.contains(click.x, click.y);
+ if ((inBounds || cntlClick) && tree.isVisible(path))
+ {
+ selectPath(tree, path);
+ if (inBounds && e.getClickCount() == 2 && !isLeaf(row))
+ toggleExpandState(path);
+
+ if (cntlClick)
+ {
+ handleExpandControlClick(path, click.x, click.y);
+ if (cellEditor != null)
+ cellEditor.cancelCellEditing();
+ }
+ else if (tree.isEditable())
+ startEditing(path, e);
+ }
+ }
}
/**
@@ -2232,6 +2286,7 @@ public class BasicTreeUI
*/
public void mouseDragged(MouseEvent e)
{
+ // TODO: What should be done here, if anything?
}
/**
@@ -2243,6 +2298,7 @@ public class BasicTreeUI
*/
public void mouseMoved(MouseEvent e)
{
+ // TODO: What should be done here, if anything?
}
/**
@@ -2253,16 +2309,16 @@ public class BasicTreeUI
*/
public void mouseReleased(MouseEvent e)
{
+ // TODO: What should be done here, if anything?
}
- }// MouseHandler
+ }
/**
* MouseInputHandler handles passing all mouse events, including mouse motion
* events, until the mouse is released to the destination it is constructed
* with.
*/
- public class MouseInputHandler
- implements MouseInputListener
+ public class MouseInputHandler implements MouseInputListener
{
/** Source that events are coming from */
protected Component source;
@@ -2283,6 +2339,8 @@ public class BasicTreeUI
public MouseInputHandler(Component source, Component destination,
MouseEvent e)
{
+ this.source = source;
+ this.destination = destination;
}
/**
@@ -2294,6 +2352,7 @@ public class BasicTreeUI
*/
public void mouseClicked(MouseEvent e)
{
+ // TODO: What should be done here, if anything?
}
/**
@@ -2304,42 +2363,7 @@ public class BasicTreeUI
*/
public void mousePressed(MouseEvent e)
{
- Point click = e.getPoint();
- TreePath path = getClosestPathForLocation(tree, click.x, click.y);
-
- if (path != null)
- {
- bounds = getPathBounds(tree, path);
- int row = getRowForPath(tree, path);
- boolean cntlClick = isLocationInExpandControl(path, click.x, click.y);
-
- if (isLeaf(row))
- {
- bounds.x -= rightChildIndent - 4;
- bounds.width += rightChildIndent + 4;
- }
- else if (tree.isExpanded(path) && expandedIcon != null)
- bounds.width += expandedIcon.getIconWidth() + 4;
- else if (collapsedIcon != null)
- bounds.width += collapsedIcon.getIconWidth() + 4;
-
- boolean inBounds = bounds.contains(click.x, click.y);
- if ((inBounds || cntlClick) && tree.isVisible(path))
- {
- selectPath(tree, path);
- if (inBounds && e.getClickCount() == 2 && !isLeaf(row))
- toggleExpandState(path);
-
- if (cntlClick)
- {
- handleExpandControlClick(path, click.x, click.y);
- if (cellEditor != null)
- cellEditor.cancelCellEditing();
- }
- else if (tree.isEditable())
- startEditing(path, e);
- }
- }
+ // TODO: What should be done here, if anything?
}
/**
@@ -2350,6 +2374,7 @@ public class BasicTreeUI
*/
public void mouseReleased(MouseEvent e)
{
+ // TODO: What should be done here, if anything?
}
/**
@@ -2360,6 +2385,7 @@ public class BasicTreeUI
*/
public void mouseEntered(MouseEvent e)
{
+ // TODO: What should be done here, if anything?
}
/**
@@ -2370,6 +2396,7 @@ public class BasicTreeUI
*/
public void mouseExited(MouseEvent e)
{
+ // TODO: What should be done here, if anything?
}
/**
@@ -2383,6 +2410,7 @@ public class BasicTreeUI
*/
public void mouseDragged(MouseEvent e)
{
+ // TODO: What should be done here, if anything?
}
/**
@@ -2394,6 +2422,7 @@ public class BasicTreeUI
*/
public void mouseMoved(MouseEvent e)
{
+ // TODO: What should be done here, if anything?
}
/**
@@ -2401,8 +2430,9 @@ public class BasicTreeUI
*/
protected void removeFromSource()
{
+ // TODO: Implement this properly.
}
- }// MouseInputHandler
+ }
/**
* Class responsible for getting size of node, method is forwarded to
@@ -2417,6 +2447,7 @@ public class BasicTreeUI
*/
public NodeDimensionsHandler()
{
+ // Nothing to do here.
}
/**
@@ -2464,6 +2495,7 @@ public class BasicTreeUI
*/
public PropertyChangeHandler()
{
+ // Nothing to do here.
}
/**
@@ -2475,8 +2507,9 @@ public class BasicTreeUI
*/
public void propertyChange(PropertyChangeEvent event)
{
+ // TODO: What should be done here, if anything?
}
- }// PropertyChangeHandler
+ }
/**
* Listener on the TreeSelectionModel, resets the row selection if any of the
@@ -2491,6 +2524,7 @@ public class BasicTreeUI
*/
public SelectionModelPropertyChangeHandler()
{
+ // Nothing to do here.
}
/**
@@ -2502,8 +2536,9 @@ public class BasicTreeUI
*/
public void propertyChange(PropertyChangeEvent event)
{
+ // TODO: What should be done here, if anything?
}
- }// SelectionModelPropertyChangeHandler
+ }
/**
* ActionListener that invokes cancelEditing when action performed.
@@ -2517,6 +2552,7 @@ public class BasicTreeUI
*/
public TreeCancelEditingAction(String name)
{
+ // TODO: Implement this properly.
}
/**
@@ -2527,6 +2563,7 @@ public class BasicTreeUI
*/
public void actionPerformed(ActionEvent e)
{
+ // TODO: Implement this properly.
}
/**
@@ -2536,9 +2573,10 @@ public class BasicTreeUI
*/
public boolean isEnabled()
{
+ // TODO: Implement this properly.
return false;
}
- }// TreeCancelEditingAction
+ }
/**
* Updates the TreeState in response to nodes expanding/collapsing.
@@ -2552,6 +2590,7 @@ public class BasicTreeUI
*/
public TreeExpansionHandler()
{
+ // Nothing to do here.
}
/**
@@ -2562,6 +2601,9 @@ public class BasicTreeUI
*/
public void treeExpanded(TreeExpansionEvent event)
{
+ validCachedPreferredSize = false;
+ updateCurrentVisiblePath();
+ tree.revalidate();
tree.repaint();
}
@@ -2573,6 +2615,9 @@ public class BasicTreeUI
*/
public void treeCollapsed(TreeExpansionEvent event)
{
+ validCachedPreferredSize = false;
+ updateCurrentVisiblePath();
+ tree.revalidate();
tree.repaint();
}
}// TreeExpansionHandler
@@ -2598,6 +2643,7 @@ public class BasicTreeUI
*/
public TreeHomeAction(int direction, String name)
{
+ // TODO: Implement this properly
}
/**
@@ -2608,6 +2654,7 @@ public class BasicTreeUI
*/
public void actionPerformed(ActionEvent e)
{
+ // TODO: Implement this properly
}
/**
@@ -2617,9 +2664,10 @@ public class BasicTreeUI
*/
public boolean isEnabled()
{
+ // TODO: Implement this properly
return false;
}
- }// TreeHomeAction
+ }
/**
* TreeIncrementAction is used to handle up/down actions. Selection is moved
@@ -2642,6 +2690,7 @@ public class BasicTreeUI
*/
public TreeIncrementAction(int direction, String name)
{
+ // TODO: Implement this properly
}
/**
@@ -2661,7 +2710,7 @@ public class BasicTreeUI
if (prev != null)
{
TreePath newPath = new TreePath(getPathToRoot(prev, 0));
- selectPath(tree, new TreePath(getPathToRoot(prev, 0)));
+ selectPath(tree, newPath);
tree.setLeadSelectionPath(newPath);
}
}
@@ -2681,7 +2730,7 @@ public class BasicTreeUI
if (prev != null)
{
TreePath newPath = new TreePath(getPathToRoot(prev, 0));
- selectPath(tree, new TreePath(getPathToRoot(prev, 0)));
+ selectPath(tree, newPath);
}
}
else if (e.getActionCommand().equals("selectNext"))
@@ -2722,21 +2771,22 @@ public class BasicTreeUI
*/
public boolean isEnabled()
{
+ // TODO: Implement this properly
return false;
}
- }// TreeIncrementAction
+ }
/**
* Forwards all TreeModel events to the TreeState.
*/
- public class TreeModelHandler
- implements TreeModelListener
+ public class TreeModelHandler implements TreeModelListener
{
/**
* Constructor
*/
public TreeModelHandler()
{
+ // Nothing to do here.
}
/**
@@ -2754,6 +2804,9 @@ public class BasicTreeUI
*/
public void treeNodesChanged(TreeModelEvent e)
{
+ validCachedPreferredSize = false;
+ updateCurrentVisiblePath();
+ tree.revalidate();
tree.repaint();
}
@@ -2767,6 +2820,9 @@ public class BasicTreeUI
*/
public void treeNodesInserted(TreeModelEvent e)
{
+ validCachedPreferredSize = false;
+ updateCurrentVisiblePath();
+ tree.revalidate();
tree.repaint();
}
@@ -2783,6 +2839,9 @@ public class BasicTreeUI
*/
public void treeNodesRemoved(TreeModelEvent e)
{
+ validCachedPreferredSize = false;
+ updateCurrentVisiblePath();
+ tree.revalidate();
tree.repaint();
}
@@ -2798,6 +2857,9 @@ public class BasicTreeUI
*/
public void treeStructureChanged(TreeModelEvent e)
{
+ validCachedPreferredSize = false;
+ updateCurrentVisiblePath();
+ tree.revalidate();
tree.repaint();
}
}// TreeModelHandler
@@ -2805,8 +2867,7 @@ public class BasicTreeUI
/**
* TreePageAction handles page up and page down events.
*/
- public class TreePageAction
- extends AbstractAction
+ public class TreePageAction extends AbstractAction
{
/** Specifies the direction to adjust the selection by. */
protected int direction;
@@ -2821,6 +2882,7 @@ public class BasicTreeUI
*/
public TreePageAction(int direction, String name)
{
+ this.direction = direction;
}
/**
@@ -2831,6 +2893,7 @@ public class BasicTreeUI
*/
public void actionPerformed(ActionEvent e)
{
+ // TODO: Implement this properly.
}
/**
@@ -2848,14 +2911,14 @@ public class BasicTreeUI
* Listens for changes in the selection model and updates the display
* accordingly.
*/
- public class TreeSelectionHandler
- implements TreeSelectionListener
+ public class TreeSelectionHandler implements TreeSelectionListener
{
/**
* Constructor
*/
public TreeSelectionHandler()
{
+ // Nothing to do here.
}
/**
@@ -2875,8 +2938,7 @@ public class BasicTreeUI
/**
* For the first selected row expandedness will be toggled.
*/
- public class TreeToggleAction
- extends AbstractAction
+ public class TreeToggleAction extends AbstractAction
{
/**
* Constructor
@@ -2886,6 +2948,7 @@ public class BasicTreeUI
*/
public TreeToggleAction(String name)
{
+ // Nothing to do here.
}
/**
@@ -2896,6 +2959,7 @@ public class BasicTreeUI
*/
public void actionPerformed(ActionEvent e)
{
+ // TODO: Implement this properly.
}
/**
@@ -2913,8 +2977,7 @@ public class BasicTreeUI
* TreeTraverseAction is the action used for left/right keys. Will toggle the
* expandedness of a node, as well as potentially incrementing the selection.
*/
- public class TreeTraverseAction
- extends AbstractAction
+ public class TreeTraverseAction extends AbstractAction
{
/**
* Determines direction to traverse, 1 means expand, -1 means collapse.
@@ -2931,6 +2994,7 @@ public class BasicTreeUI
*/
public TreeTraverseAction(int direction, String name)
{
+ this.direction = direction;
}
/**
@@ -2948,8 +3012,8 @@ public class BasicTreeUI
TreePath path = new TreePath(getPathToRoot(last, 0));
Object p = getParent(treeModel.getRoot(), last);
- if (!treeModel.isLeaf(last) && tree.isExpanded(path))
- tree.collapsePath(path);
+ if (!treeModel.isLeaf(last))
+ toggleExpandState(path);
else if (p != null)
selectPath(tree, new TreePath(getPathToRoot(p, 0)));
}
@@ -2957,8 +3021,8 @@ public class BasicTreeUI
{
TreePath path = new TreePath(getPathToRoot(last, 0));
- if (!treeModel.isLeaf(last) && tree.isCollapsed(path))
- tree.expandPath(path);
+ if (!treeModel.isLeaf(last))
+ toggleExpandState(path);
else
{
Object next = getNextVisibleNode(last);
@@ -2976,9 +3040,10 @@ public class BasicTreeUI
*/
public boolean isEnabled()
{
+ // TODO: Implement this properly
return false;
}
- } // TreeTraverseAction
+ }
/**
* Returns the cell bounds for painting selected cells Package private for use
@@ -3001,8 +3066,7 @@ public class BasicTreeUI
FontMetrics fm = tree.getToolkit().getFontMetrics(f);
if (s != null)
- return new Rectangle(x, y,
- SwingUtilities.computeStringWidth(fm, s) + 4,
+ return new Rectangle(x, y, SwingUtilities.computeStringWidth(fm, s),
fm.getHeight());
}
return new Rectangle(x, y, 0, 0);
@@ -3032,80 +3096,19 @@ public class BasicTreeUI
int rowHeight = getRowHeight();
if (startNode == null || startNode.equals(node))
{
- if (!tree.isRootVisible()
- && tree.isExpanded(new TreePath(mod.getRoot())))
- return new Point(x + ((getLevel(node)) * rightChildIndent), y);
-
- return new Point(x + ((getLevel(node) + 1) * rightChildIndent), y);
- }
-
- if (!mod.isLeaf(startNode)
- && tree.isExpanded(new TreePath(getPathToRoot(startNode, 0)))
- && !mod.isLeaf(startNode) && mod.getChildCount(startNode) > 0)
- {
- Object child = mod.getChild(startNode, 0);
- if (child != null)
- return getCellLocation(x, y + rowHeight, tree, mod, node, child);
+ int level = getLevel(node);
+ if (level == 0)
+ return new Point(x, y);
+ if (!tree.isRootVisible() &&
+ tree.isExpanded(new TreePath(mod.getRoot())))
+ return new Point(x + ((level - 1) * rightChildIndent), y);
+ return new Point(x + (level * rightChildIndent), y);
}
-
return getCellLocation(x, y + rowHeight, tree, mod, node,
getNextVisibleNode(startNode));
}
/**
- * Paints a node in the tree Package private for use in inner classes.
- *
- * @param g
- * the Graphics context in which to paint
- * @param x
- * the x location of the node
- * @param y
- * the y location of the node
- * @param tree
- * the tree to draw on
- * @param node
- * the object to draw
- */
- void paintNode(Graphics g, int x, int y, JTree tree, Object node,
- boolean isLeaf)
- {
- TreePath curr = new TreePath(getPathToRoot(node, 0));
- boolean selected = tree.isPathSelected(curr);
- boolean expanded = false;
- boolean hasIcons = false;
-
- if (tree.isVisible(curr))
- {
- if (!isLeaf)
- expanded = tree.isExpanded(curr);
-
- if (editingComponent != null && editingPath != null && isEditing(tree)
- && node.equals(editingPath.getLastPathComponent()))
- {
- Rectangle bounds = getPathBounds(tree, editingPath);
- rendererPane.paintComponent(g, editingComponent.getParent(), null,
- new Rectangle(0, 0, bounds.width,
- bounds.height));
- }
- else
- {
- TreeCellRenderer dtcr = tree.getCellRenderer();
- if (dtcr == null)
- dtcr = createDefaultCellRenderer();
-
- int row = getRowForPath(tree, curr);
-
- Component c = dtcr.getTreeCellRendererComponent(tree, node,
- selected, expanded,
- isLeaf, row, false);
-
- rendererPane.paintComponent(g, c, c.getParent(),
- getCellBounds(x, y, node));
- }
- }
- }
-
- /**
* Recursively paints all elements of the tree Package private for use in
* inner classes.
*
@@ -3115,8 +3118,6 @@ public class BasicTreeUI
* of the current object
* @param descent
* is the number of elements drawn
- * @param childNumber
- * is the index of the current child in the tree
* @param depth
* is the depth of the current object in the tree
* @param tree
@@ -3127,46 +3128,50 @@ public class BasicTreeUI
* is the current object to draw
* @return int - current descent of the tree
*/
- int paintRecursive(Graphics g, int indentation, int descent, int childNumber,
+ int paintRecursive(Graphics g, int indentation, int descent,
int depth, JTree tree, TreeModel mod, Object curr)
{
- Rectangle clip = g.getClipBounds();
+ Rectangle clip = tree.getVisibleRect();
if (indentation > clip.x + clip.width + rightChildIndent
|| descent > clip.y + clip.height + getRowHeight())
return descent;
+ TreePath path = new TreePath(getPathToRoot(curr, 0));
int halfHeight = getRowHeight() / 2;
int halfWidth = rightChildIndent / 2;
int y0 = descent + halfHeight;
int heightOfLine = descent + halfHeight;
+ int row = getRowForPath(tree, path);
boolean isRootVisible = tree.isRootVisible();
+ boolean isExpanded = tree.isExpanded(path);
+ boolean isLeaf = mod.isLeaf(curr);
+ Rectangle bounds = getPathBounds(tree, path);
+ Object root = mod.getRoot();
- if (mod.isLeaf(curr))
+ if (isLeaf)
{
- paintNode(g, indentation + 4, descent, tree, curr, true);
+ paintRow(g, clip, null, bounds, path, row, true, false, true);
descent += getRowHeight();
}
else
{
if (depth > 0 || isRootVisible)
{
- paintNode(g, indentation + 4, descent, tree, curr, false);
+ paintRow(g, clip, null, bounds, path, row, isExpanded, false, false);
descent += getRowHeight();
y0 += halfHeight;
}
-
- int max = 0;
- if (!mod.isLeaf(curr))
- max = mod.getChildCount(curr);
- if (tree.isExpanded(new TreePath(getPathToRoot(curr, 0))))
+
+ int max = mod.getChildCount(curr);
+ if (isExpanded)
{
for (int i = 0; i < max; i++)
{
int indent = indentation + rightChildIndent;
if (!isRootVisible && depth == 0)
indent = 0;
- else if ((!isRootVisible && !curr.equals(mod.getRoot()))
- || isRootVisible)
+ else if (isRootVisible ||
+ (!isRootVisible && !curr.equals(root)))
{
g.setColor(getHashColor());
heightOfLine = descent + halfHeight;
@@ -3174,14 +3179,14 @@ public class BasicTreeUI
indentation + halfWidth, indentation + rightChildIndent);
}
- descent = paintRecursive(g, indent, descent, i, depth + 1,
+ descent = paintRecursive(g, indent, descent, depth + 1,
tree, mod, mod.getChild(curr, i));
}
}
}
- if (tree.isExpanded(new TreePath(getPathToRoot(curr, 0))))
- if (y0 != heightOfLine && !mod.isLeaf(curr)
+ if (isExpanded)
+ if (y0 != heightOfLine && !isLeaf
&& mod.getChildCount(curr) > 0)
{
g.setColor(getHashColor());
@@ -3191,7 +3196,7 @@ public class BasicTreeUI
return descent;
}
-
+
/**
* Recursively paints all the control icons on the tree. Package private for
* use in inner classes.
@@ -3202,90 +3207,98 @@ public class BasicTreeUI
* of the current object
* @param descent
* is the number of elements drawn
- * @param childNumber
- * is the index of the current child in the tree
* @param depth
* is the depth of the current object in the tree
* @param tree
* is the tree to draw to
* @param mod
* is the TreeModel we are using to draw
- * @param curr
+ * @param node
* is the current object to draw
- * @return int - current descent of the tree
+ * @return int current descent of the tree
*/
int paintControlIcons(Graphics g, int indentation, int descent,
- int childNumber, int depth, JTree tree, TreeModel mod,
+ int depth, JTree tree, TreeModel mod,
Object node)
{
- int h = descent;
int rowHeight = getRowHeight();
TreePath path = new TreePath(getPathToRoot(node, 0));
Icon icon = getCurrentControlIcon(path);
-
- Rectangle clip = g.getClipBounds();
+
+ Rectangle clip = tree.getVisibleRect();
if (indentation > clip.x + clip.width + rightChildIndent
|| descent > clip.y + clip.height + getRowHeight())
return descent;
-
+
if (mod.isLeaf(node))
descent += rowHeight;
else
- {
+ {
+ if (!node.equals(mod.getRoot()) &&
+ (tree.isRootVisible() || getLevel(node) != 1))
+ {
+ int width = icon.getIconWidth();
+ int height = icon.getIconHeight() + 2;
+ int posX = indentation - rightChildIndent;
+ int posY = descent;
+ if (width > rightChildIndent)
+ posX -= gap;
+ else posX += width/2;
+
+ if (height < rowHeight)
+ posY += height/2;
+
+ icon.paintIcon(tree, g, posX, posY);
+ }
+
if (depth > 0 || tree.isRootVisible())
descent += rowHeight;
-
- int max = 0;
- if (!mod.isLeaf(node))
- max = mod.getChildCount(node);
-
- if (!node.equals(mod.getRoot()))
- icon.paintIcon(tree, g, indentation - rightChildIndent - 3, h);
-
+
if (tree.isExpanded(path))
{
+ int max = 0;
+ if (!mod.isLeaf(node))
+ max = mod.getChildCount(node);
+
for (int i = 0; i < max; i++)
{
int indent = indentation + rightChildIndent;
if (depth == 0 && !tree.isRootVisible())
- indent = -1;
-
- descent = paintControlIcons(g, indent, descent, i, depth + 1,
+ indent = 1;
+
+ descent = paintControlIcons(g, indent, descent, depth + 1,
tree, mod, mod.getChild(node, i));
}
}
}
-
+
return descent;
}
/**
- * Returns control icon. It is null if the LookAndFeel does not
- * implements the control icons.
- * Package private for use in inner classes.
+ * Returns true if the LookAndFeel implements the control icons. Package
+ * private for use in inner classes.
*
- * @return control icon if it exists.
+ * @returns true if there are control icons
*/
- Icon getCurrentControlIcon(TreePath path)
+ boolean hasControlIcons()
{
- if (tree.isExpanded(path))
- return UIManager.getLookAndFeelDefaults().getIcon("Tree.expandedIcon");
- return UIManager.getLookAndFeelDefaults().getIcon("Tree.collapsedIcon");
+ if (expandedIcon != null || collapsedIcon != null)
+ return true;
+ return false;
}
/**
- * Returns true if the LookAndFeel implements the control icons.
- * Package private for use in inner classes.
+ * Returns control icon. It is null if the LookAndFeel does not implements the
+ * control icons. Package private for use in inner classes.
*
- * @returns true if there are control icons
+ * @return control icon if it exists.
*/
- boolean hasControlIcons()
+ Icon getCurrentControlIcon(TreePath path)
{
- if (UIManager.getLookAndFeelDefaults().getIcon("Tree.expandedIcon") != null
- || UIManager.getLookAndFeelDefaults().getIcon("Tree.collapsedIcon")
- != null)
- return true;
- return false;
+ if (tree.isExpanded(path))
+ return expandedIcon;
+ return collapsedIcon;
}
/**
@@ -3333,77 +3346,33 @@ public class BasicTreeUI
}
/**
- * Get next visible node in the tree. Package private for use in inner
- * classes.
- *
- * @param the
- * current node
- * @return the next visible node in the JTree. Return null if there are no
- * more.
- */
- Object getNextVisibleNode(Object node)
- {
- Object next = null;
- TreePath current = null;
-
- if (node != null)
- next = getNextNode(node);
-
- if (next != null)
- {
- current = new TreePath(getPathToRoot(next, 0));
- if (tree.isVisible(current))
- return next;
-
- while (next != null && !tree.isVisible(current))
- {
- next = getNextNode(next);
-
- if (next != null)
- current = new TreePath(getPathToRoot(next, 0));
- }
- }
- return next;
- }
-
- /**
* Get previous visible node in the tree. Package private for use in inner
* classes.
*
- * @param the
+ * @param node -
* current node
* @return the next visible node in the JTree. Return null if there are no
* more.
*/
Object getPreviousVisibleNode(Object node)
{
- Object prev = null;
- TreePath current = null;
-
- if (node != null)
- prev = getPreviousNode(node);
-
- if (prev != null)
+ if (currentVisiblePath != null)
{
- current = new TreePath(getPathToRoot(prev, 0));
- if (tree.isVisible(current))
- return prev;
-
- while (prev != null && !tree.isVisible(current))
- {
- prev = getPreviousNode(prev);
-
- if (prev != null)
- current = new TreePath(getPathToRoot(prev, 0));
- }
+ Object[] nodes = currentVisiblePath.getPath();
+ int i = 0;
+ while (i < nodes.length && !node.equals(nodes[i]))
+ i++;
+ // return the next node
+ if (i-1 > 0)
+ return nodes[i-1];
}
- return prev;
+ return null;
}
/**
* Returns the next node in the tree Package private for use in inner classes.
*
- * @param the
+ * @param curr -
* current node
* @return the next node in the tree
*/
@@ -3429,7 +3398,7 @@ public class BasicTreeUI
* Returns the previous node in the tree Package private for use in inner
* classes.
*
- * @param the
+ * @param node
* current node
* @return the previous node in the tree
*/
@@ -3463,7 +3432,7 @@ public class BasicTreeUI
* Returns the next sibling in the tree Package private for use in inner
* classes.
*
- * @param the
+ * @param node -
* current node
* @return the next sibling in the tree
*/
@@ -3488,7 +3457,7 @@ public class BasicTreeUI
* Returns the previous sibling in the tree Package private for use in inner
* classes.
*
- * @param the
+ * @param node -
* current node
* @return the previous sibling in the tree
*/
@@ -3572,7 +3541,7 @@ public class BasicTreeUI
/**
* Returns the level of the node in the tree.
*
- * @param the
+ * @param node -
* current node
* @return the number of the level
*/
@@ -3646,7 +3615,7 @@ public class BasicTreeUI
* is the center position in y-direction FIXME what to do if x <
* (icon.width / 2). Same with y
*/
- protected void drawCentered(JComponent c, Graphics g, Icon icon, int x, int y)
+ protected void drawCentered(Component c, Graphics g, Icon icon, int x, int y)
{
int beginPositionX = x - icon.getIconWidth() / 2;
int beginPositionY = y - icon.getIconHeight() / 2;
@@ -3701,8 +3670,8 @@ public class BasicTreeUI
boolean isExpanded, boolean hasBeenExpanded,
boolean isLeaf)
{
- if (treeModel != null)
- paintControlIcons(g, 0, 0, 0, 0, tree, treeModel, path.getLastPathComponent());
+ if (treeModel != null && hasControlIcons())
+ paintControlIcons(g, 0, 0, 0, tree, treeModel, path.getLastPathComponent());
}
/**
@@ -3734,7 +3703,7 @@ public class BasicTreeUI
* clipBounds, insets.
*
* @param g - the graphics configuration.
- * @param clipbounds -
+ * @param clipBounds -
* @param insets -
* @param path - the path to draw the vertical part for.
*/
@@ -3764,7 +3733,32 @@ public class BasicTreeUI
boolean isExpanded, boolean hasBeenExpanded,
boolean isLeaf)
{
- // FIXME: not implemented.
+ boolean selected = tree.isPathSelected(path);
+ boolean hasIcons = false;
+ Object node = path.getLastPathComponent();
+
+ if (tree.isVisible(path))
+ {
+ bounds.width = preferredSize.width;
+ bounds.x += gap;
+
+ if (editingComponent != null && editingPath != null && isEditing(tree)
+ && node.equals(editingPath.getLastPathComponent()))
+ {
+ rendererPane.paintComponent(g, editingComponent.getParent(), null,
+ bounds);
+ }
+ else
+ {
+ TreeCellRenderer dtcr = tree.getCellRenderer();
+ if (dtcr == null)
+ dtcr = createDefaultCellRenderer();
+
+ Component c = dtcr.getTreeCellRendererComponent(tree, node,
+ selected, isExpanded, isLeaf, row, false);
+ rendererPane.paintComponent(g, c, c.getParent(), bounds);
+ }
+ }
}
/**
@@ -3772,6 +3766,7 @@ public class BasicTreeUI
*/
protected void prepareForUIUninstall()
{
+ // TODO: Implement this properly.
}
/**
@@ -3789,7 +3784,72 @@ public class BasicTreeUI
boolean hasBeenExpanded,
boolean isLeaf)
{
- // FIXME: not implemented.
+ Object node = path.getLastPathComponent();
+ if (treeModel != null && (!isLeaf && !node.equals(treeModel.getRoot())) &&
+ (tree.isRootVisible() || getLevel(node) != 1))
+ return true;
return false;
}
+
+ /**
+ * Updates the cached current TreePath of all visible
+ * nodes in the tree.
+ */
+ void updateCurrentVisiblePath()
+ {
+ if (treeModel == null)
+ return;
+
+ Object next = treeModel.getRoot();
+ Rectangle bounds = getCellBounds(0, 0, next);
+
+ // If root is not a valid size to be visible, or is
+ // not visible and the tree is expanded, then the next node acts
+ // as the root
+ if ((bounds.width == 0 && bounds.height == 0) || (!isRootVisible()
+ && tree.isExpanded(new TreePath(next))))
+ next = getNextNode(next);
+ TreePath current = null;
+
+ while (next != null)
+ {
+ if (current == null)
+ current = new TreePath(next);
+ else
+ current = current.pathByAddingChild(next);
+ do
+ next = getNextNode(next);
+ while (next != null &&
+ !tree.isVisible(new TreePath(getPathToRoot(next, 0))));
+ }
+ currentVisiblePath = current;
+ tree.setVisibleRowCount(getRowCount(tree));
+ if (tree.getSelectionModel() != null && tree.getSelectionCount() == 0 &&
+ currentVisiblePath != null)
+ tree.addSelectionRow(0);
+ }
+
+ /**
+ * Get next visible node in the currentVisiblePath. Package private for use in
+ * inner classes.
+ *
+ * @param node
+ * current node
+ * @return the next visible node in the JTree. Return null if there are no
+ * more.
+ */
+ Object getNextVisibleNode(Object node)
+ {
+ if (currentVisiblePath != null)
+ {
+ Object[] nodes = currentVisiblePath.getPath();
+ int i = 0;
+ while (i < nodes.length && !node.equals(nodes[i]))
+ i++;
+ // return the next node
+ if (i+1 < nodes.length)
+ return nodes[i+1];
+ }
+ return null;
+ }
} // BasicTreeUI
diff --git a/javax/swing/plaf/basic/BasicViewportUI.java b/javax/swing/plaf/basic/BasicViewportUI.java
index 0d461332a..51b902d64 100644
--- a/javax/swing/plaf/basic/BasicViewportUI.java
+++ b/javax/swing/plaf/basic/BasicViewportUI.java
@@ -38,61 +38,22 @@ exception statement from your version. */
package javax.swing.plaf.basic;
-import java.awt.Component;
-import java.awt.Dimension;
-import java.awt.Graphics;
-import java.awt.Image;
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.image.ImageObserver;
-
import javax.swing.JComponent;
-import javax.swing.JViewport;
-import javax.swing.ViewportLayout;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
+import javax.swing.LookAndFeel;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.ViewportUI;
public class BasicViewportUI extends ViewportUI
{
-
- ChangeListener changeListener;
- Image backingStoreImage;
- int backingStoreWidth = -1;
- int backingStoreHeight = -1;
-
- class ChangeHandler implements ChangeListener
+ protected void installDefaults(JComponent c)
{
- public void stateChanged(ChangeEvent event)
- {
- JViewport v = (JViewport) event.getSource();
- v.repaint();
- }
- }
-
- void installDefaults(JComponent c)
- {
c.setOpaque(true);
+ LookAndFeel.installColorsAndFont(c, "Viewport.background",
+ "Viewport.foreground", "Viewport.font");
}
-
- void uninstallDefaults(JComponent c)
- {
- }
-
- void installListeners(JComponent c)
+ protected void uninstallDefaults(JComponent c)
{
- ((JViewport)c).addChangeListener(changeListener);
- }
-
- void uninstallListeners(JComponent c)
- {
- ((JViewport)c).removeChangeListener(changeListener);
- }
-
- public BasicViewportUI()
- {
- changeListener = new ChangeHandler();
+ // TODO: Implement this properly.
}
public static ComponentUI createUI(JComponent c)
@@ -103,132 +64,12 @@ public class BasicViewportUI extends ViewportUI
public void installUI(JComponent c)
{
super.installUI(c);
- installListeners(c);
+ installDefaults(c);
}
public void uninstallUI(JComponent c)
{
- uninstallListeners(c);
- }
-
-
- public Dimension getPreferredSize(JComponent c)
- {
- // let the ViewportLayout decide
- return null;
- }
-
- public void paint(Graphics g, JComponent c)
- {
- JViewport port = (JViewport)c;
- Component view = port.getView();
-
- if (view == null)
- return;
-
- Point pos = port.getViewPosition();
- Rectangle viewBounds = view.getBounds();
- Rectangle portBounds = port.getBounds();
-
- if (viewBounds.width == 0
- || viewBounds.height == 0
- || portBounds.width == 0
- || portBounds.height == 0)
- return;
-
- switch (port.getScrollMode())
- {
-
- case JViewport.BACKINGSTORE_SCROLL_MODE:
- paintBackingStore(g, port, view, pos, viewBounds, portBounds);
- break;
-
- case JViewport.BLIT_SCROLL_MODE:
- // FIXME: implement separate blit mode
-
- case JViewport.SIMPLE_SCROLL_MODE:
- default:
- paintSimple(g, port, view, pos, viewBounds, portBounds);
- break;
- }
- }
-
- private void paintSimple(Graphics g,
- JViewport v,
- Component view,
- Point pos,
- Rectangle viewBounds,
- Rectangle portBounds)
- {
- Rectangle oldClip = g.getClipBounds();
- g.setClip(new Rectangle(0, 0, portBounds.width, portBounds.height));
- g.translate (-pos.x, -pos.y);
- try
- {
- view.paint(g);
- }
- finally
- {
- g.translate (pos.x, pos.y);
- g.setClip (oldClip);
- }
- }
-
- private void paintBackingStore(Graphics g,
- JViewport v,
- Component view,
- Point pos,
- Rectangle viewBounds,
- Rectangle portBounds)
- {
- if (backingStoreImage == null
- || backingStoreWidth != viewBounds.width
- || backingStoreHeight != viewBounds.height)
- {
- backingStoreImage = v.createImage(viewBounds.width, viewBounds.height);
- backingStoreWidth = viewBounds.width;
- backingStoreHeight = viewBounds.height;
- }
-
- Graphics g2 = backingStoreImage.getGraphics();
-
- if (v.getBackground() != null)
- {
- // fill the backing store background
- java.awt.Color save = g2.getColor();
- g2.setColor(v.getBackground());
- g2.fillRect (0, 0, backingStoreWidth, backingStoreHeight);
- g2.setColor(save);
-
- // fill the viewport background
- save = g.getColor();
- g.setColor(v.getBackground());
- g.fillRect (0, 0, portBounds.width, portBounds.height);
- g.setColor(save);
-
- }
- else
- {
- // clear the backing store background
- g2.clearRect(0, 0, backingStoreWidth, backingStoreHeight);
-
- // clear the viewport background
- g.clearRect(0, 0, portBounds.width, portBounds.height);
- }
-
- g2.setClip(g.getClipBounds());
- g2.translate(-pos.x, -pos.y);
- try
- {
- view.paint(g2);
- }
- finally
- {
- g2.translate(pos.x, pos.y);
- }
- g2 = null;
- g.drawImage(backingStoreImage,
- 0, 0,
- (ImageObserver)null);
+ super.uninstallUI(c);
+ uninstallDefaults(c);
}
}
diff --git a/javax/swing/plaf/metal/MetalBorders.java b/javax/swing/plaf/metal/MetalBorders.java
index 3d2800657..4fa3b3640 100644
--- a/javax/swing/plaf/metal/MetalBorders.java
+++ b/javax/swing/plaf/metal/MetalBorders.java
@@ -44,14 +44,20 @@ import java.awt.Graphics;
import java.awt.Insets;
import javax.swing.AbstractButton;
-import javax.swing.BorderFactory;
import javax.swing.ButtonModel;
+import javax.swing.JButton;
import javax.swing.JInternalFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JToggleButton;
+import javax.swing.JToolBar;
+import javax.swing.SwingConstants;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
import javax.swing.border.AbstractBorder;
import javax.swing.border.Border;
import javax.swing.plaf.BorderUIResource;
@@ -61,8 +67,7 @@ import javax.swing.text.JTextComponent;
/**
- * This factory class creates borders for the different Swing components
- * UI.
+ * A factory class that creates borders for the different Swing components.
*
* @author Roman Kennke (roman@kennke.org)
*/
@@ -84,11 +89,12 @@ public class MetalBorders
/** The shared instance for getTextFieldBorder(). */
private static Border textFieldBorder;
- /**
- * The shared instance for getTextBorder().
- */
+ /** The shared instance for getTextBorder(). */
private static Border textBorder;
+ /** The shared instance for getRolloverBorder(). */
+ private static Border rolloverBorder;
+
/**
* A MarginBorder that gets shared by multiple components.
* Created on demand by the private helper function {@link
@@ -97,20 +103,19 @@ public class MetalBorders
private static BasicBorders.MarginBorder marginBorder;
/**
- * The border that is drawn around Swing buttons.
+ * A border used for {@link JButton} components.
*/
- public static class ButtonBorder
- extends AbstractBorder
- implements UIResource
+ public static class ButtonBorder extends AbstractBorder implements UIResource
{
/** The borders insets. */
protected static Insets borderInsets = new Insets(3, 3, 3, 3);
/**
- * Creates a new instance of ButtonBorder.
+ * Creates a new instance of <code>ButtonBorder</code>.
*/
public ButtonBorder()
{
+ // Nothing to do here.
}
/**
@@ -180,11 +185,11 @@ public class MetalBorders
}
/**
- * Returns the insets of the ButtonBorder.
+ * Returns the insets of the <code>ButtonBorder</code>.
*
* @param c the component for which the border is used
*
- * @return the insets of the ButtonBorder
+ * @return The insets of the ButtonBorder
*/
public Insets getBorderInsets(Component c)
{
@@ -192,19 +197,20 @@ public class MetalBorders
}
/**
- * Returns the insets of the ButtonBorder in the specified Insets object.
+ * Returns the insets of the <code>ButtonBorder</code> in the specified
+ * <code>newInsets</code> object.
*
* @param c the component for which the border is used
- * @param newInsets the insets object where to put the values
+ * @param newInsets the insets object where to put the values (if
+ * <code>null</code>, a new instance is created).
*
- * @return the insets of the ButtonBorder
+ * @return The insets.
*/
public Insets getBorderInsets(Component c, Insets newInsets)
{
if (newInsets == null)
newInsets = new Insets(0, 0, 0, 0);
- AbstractButton b = (AbstractButton) c;
newInsets.bottom = borderInsets.bottom;
newInsets.left = borderInsets.left;
newInsets.right = borderInsets.right;
@@ -224,6 +230,7 @@ public class MetalBorders
*/
public DesktopIconBorder()
{
+ // Nothing to do here.
}
/**
@@ -288,6 +295,7 @@ public class MetalBorders
*/
public Flush3DBorder()
{
+ // Nothing to do here.
}
/**
@@ -354,8 +362,7 @@ public class MetalBorders
*
* @since 1.3
*/
- public static class PaletteBorder
- extends AbstractBorder
+ public static class PaletteBorder extends AbstractBorder
implements UIResource
{
/**
@@ -363,6 +370,7 @@ public class MetalBorders
*/
public PaletteBorder()
{
+ // Nothing to do here.
}
/**
@@ -441,6 +449,7 @@ public class MetalBorders
*/
public TextFieldBorder()
{
+ // Nothing to do here.
}
/**
@@ -456,8 +465,16 @@ public class MetalBorders
public void paintBorder(Component c, Graphics g, int x, int y, int w,
int h)
{
- JTextComponent tc = (JTextComponent) c;
- if (tc.isEnabled() && tc.isEditable())
+ boolean enabledTextBorder;
+ if (c instanceof JTextComponent)
+ {
+ JTextComponent tc = (JTextComponent) c;
+ enabledTextBorder = tc.isEnabled() && tc.isEditable();
+ }
+ else
+ enabledTextBorder = false;
+
+ if (enabledTextBorder)
super.paintBorder(c, g, x, y, w, h);
else
{
@@ -471,7 +488,7 @@ public class MetalBorders
}
/**
- * A border used when painting {@link JInternalFrame} instances.
+ * A border used for the {@link JInternalFrame} component.
*/
public static class InternalFrameBorder extends AbstractBorder
implements UIResource
@@ -481,6 +498,7 @@ public class MetalBorders
*/
public InternalFrameBorder()
{
+ // Nothing to do here.
}
/**
@@ -569,24 +587,129 @@ public class MetalBorders
}
/**
+ * A border used for {@link JInternalFrame} components that are
+ * presented as dialogs (by the {@link JOptionPane} class).
+ */
+ public static class OptionDialogBorder extends AbstractBorder
+ implements UIResource
+ {
+
+ /**
+ * Creates a new border instance.
+ */
+ public OptionDialogBorder()
+ {
+ // Nothing to do here.
+ }
+
+ /**
+ * Returns the border insets.
+ *
+ * @param c the component (ignored).
+ *
+ * @return The border insets.
+ */
+ public Insets getBorderInsets(Component c)
+ {
+ return getBorderInsets(c, null);
+ }
+
+ /**
+ * Returns the border insets.
+ *
+ * @param c the component (ignored).
+ * @return The border insets.
+ */
+ public Insets getBorderInsets(Component c, Insets newInsets)
+ {
+ if (newInsets == null)
+ newInsets = new Insets(3, 3, 3, 3);
+ else
+ {
+ newInsets.top = 3;
+ newInsets.left = 3;
+ newInsets.bottom = 3;
+ newInsets.right = 3;
+ }
+ return newInsets;
+ }
+
+ /**
+ * Paints the border for the specified component.
+ *
+ * @param c the component.
+ * @param g the graphics device.
+ * @param x the x-coordinate.
+ * @param y the y-coordinate.
+ * @param w the width.
+ * @param h the height.
+ */
+ public void paintBorder(Component c, Graphics g, int x, int y, int w,
+ int h)
+ {
+
+ JInternalFrame f = (JInternalFrame) c;
+ g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow());
+ if (f.getContentPane() instanceof JOptionPane)
+ {
+ JOptionPane pane = (JOptionPane) f.getContentPane();
+ int type = pane.getMessageType();
+ UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+ if (type == JOptionPane.QUESTION_MESSAGE)
+ {
+ Color bc = defaults.getColor(
+ "OptionPane.questionDialog.border.background");
+ if (bc != null)
+ g.setColor(bc);
+ }
+ if (type == JOptionPane.WARNING_MESSAGE)
+ {
+ Color bc = defaults.getColor(
+ "OptionPane.warningDialog.border.background");
+ if (bc != null)
+ g.setColor(bc);
+ }
+ else if (type == JOptionPane.ERROR_MESSAGE)
+ {
+ Color bc = defaults.getColor(
+ "OptionPane.errorDialog.border.background");
+ if (bc != null)
+ g.setColor(bc);
+ }
+ }
+
+ // fill the border background
+ g.fillRect(x, y, w, 3);
+ g.fillRect(x, y, 3, h);
+ g.fillRect(x + w - 3, y, 3, h);
+ g.fillRect(x, y + h - 3, w, 3);
+
+ // draw a dot in each corner
+ g.setColor(MetalLookAndFeel.getControl());
+ g.fillRect(x, y, 1, 1);
+ g.fillRect(x + w - 1, y, 1, 1);
+ g.fillRect(x + w - 1, y + h - 1, 1, 1);
+ g.fillRect(x, y + h - 1, 1, 1);
+
+ }
+
+ }
+
+ /**
* A border used for {@link JMenu} and {@link JMenuItem} components.
*/
- public static class MenuItemBorder
- extends AbstractBorder
- implements UIResource
+ public static class MenuItemBorder extends AbstractBorder
+ implements UIResource
{
/** The border insets. */
- protected static Insets borderInsets = new Insets(2, 2, 2, 2);
-
- // TODO: find where the real colors come from
- private static Color borderColorDark = new Color(102, 102, 153);
- private static Color borderColorLight = new Color(255, 255, 255);
+ protected static Insets borderInsets = new Insets(1, 1, 1, 1);
/**
* Creates a new border instance.
*/
public MenuItemBorder()
{
+ // Nothing to do here.
}
/**
@@ -603,15 +726,17 @@ public class MetalBorders
public void paintBorder(Component c, Graphics g, int x, int y, int w,
int h)
{
+ Color dark = MetalLookAndFeel.getPrimaryControlDarkShadow();
+ Color light = MetalLookAndFeel.getPrimaryControlHighlight();
if (c instanceof JMenu) {
JMenu menu = (JMenu) c;
if (menu.isSelected())
{
- g.setColor(borderColorDark);
+ g.setColor(dark);
g.drawLine(x, y, x, y + h);
g.drawLine(x, y, x + w, y);
g.drawLine(x + w - 2, y + 1, x + w - 2, y + h);
- g.setColor(borderColorLight);
+ g.setColor(light);
g.drawLine(x + w - 1, y + 1, x + w - 1, y + h);
}
}
@@ -619,12 +744,18 @@ public class MetalBorders
{
JMenuItem item = (JMenuItem) c;
if (item.isArmed())
- {
- g.setColor(borderColorDark);
- g.drawLine(x, y, x + w, y);
- g.setColor(borderColorLight);
- g.drawLine(x, y + h - 1, x + w, y + h - 1);
- }
+ {
+ g.setColor(dark);
+ g.drawLine(x, y, x + w, y);
+ g.setColor(light);
+ g.drawLine(x, y + h - 1, x + w, y + h - 1);
+ }
+ else
+ {
+ // Normally we draw a light line on the left.
+ g.setColor(light);
+ g.drawLine(x, y, x, y + h);
+ }
}
}
@@ -678,6 +809,7 @@ public class MetalBorders
*/
public MenuBarBorder()
{
+ // Nothing to do here.
}
/**
@@ -731,7 +863,7 @@ public class MetalBorders
}
/**
- * A border for JScrollPanes.
+ * A border for {@link JScrollPane} components.
*/
public static class ScrollPaneBorder
extends AbstractBorder
@@ -745,6 +877,7 @@ public class MetalBorders
*/
public ScrollPaneBorder()
{
+ // Nothing to do here.
}
/**
@@ -807,6 +940,45 @@ public class MetalBorders
}
/**
+ * A button border that is only visible when the mouse pointer is within
+ * the button's bounds.
+ */
+ public static class RolloverButtonBorder
+ extends MetalBorders.ButtonBorder
+ {
+ /**
+ * Creates a new border instance.
+ */
+ public RolloverButtonBorder()
+ {
+ // Nothing to do here.
+ }
+
+ /**
+ * Paints the border.
+ *
+ * @param c the component.
+ * @param g the graphics device.
+ * @param x the x-coordinate.
+ * @param y the y-coordinate.
+ * @param w the width.
+ * @param h the height.
+ */
+ public void paintBorder(Component c, Graphics g, int x, int y, int w,
+ int h)
+ {
+ boolean mouseIsOver = false;
+ if (c instanceof AbstractButton)
+ {
+ ButtonModel bmodel = ((AbstractButton) c).getModel();
+ mouseIsOver = bmodel.isRollover();
+ }
+ if (mouseIsOver)
+ super.paintBorder(c, g, x, y, w, h);
+ }
+ }
+
+ /**
* This border is used in Toolbar buttons as inner border.
*/
static class RolloverMarginBorder extends AbstractBorder
@@ -819,6 +991,7 @@ public class MetalBorders
*/
public RolloverMarginBorder()
{
+ // Nothing to do here.
}
/**
@@ -866,13 +1039,14 @@ public class MetalBorders
{
/** The border's insets. */
- protected static Insets borderInsets = new Insets(2, 2, 1, 1);
+ protected static Insets borderInsets = new Insets(3, 1, 2, 1);
/**
* Constructs a new PopupMenuBorder.
*/
public PopupMenuBorder()
{
+ // Nothing to do here.
}
/**
@@ -936,14 +1110,13 @@ public class MetalBorders
// draw highlighted inner border (only top and left)
g.setColor(light);
- g.drawLine(x + 1, y + 1, x + 1, y + h - 2);
g.drawLine(x + 1, y + 1, x + w - 2, y + 1);
}
}
/**
- * A border used for {@link JToggleButton} components.
+ * A border used for the {@link JToggleButton} component.
*
* @since 1.3
*/
@@ -955,6 +1128,7 @@ public class MetalBorders
*/
public ToggleButtonBorder()
{
+ // Nothing to do here.
}
/**
@@ -1035,6 +1209,101 @@ public class MetalBorders
}
/**
+ * A border used for the {@link JToolBar} component.
+ */
+ public static class ToolBarBorder extends AbstractBorder
+ implements UIResource, SwingConstants
+ {
+ /**
+ * Creates a new border instance.
+ */
+ public ToolBarBorder()
+ {
+ // Nothing to do here.
+ }
+
+ /**
+ * Returns the border insets.
+ *
+ * @param c the component (ignored).
+ *
+ * @return The border insets.
+ */
+ public Insets getBorderInsets(Component c)
+ {
+ return getBorderInsets(c, null);
+ }
+
+ /**
+ * Returns the border insets.
+ *
+ * @param c the component (ignored).
+ * @return The border insets.
+ */
+ public Insets getBorderInsets(Component c, Insets newInsets)
+ {
+ JToolBar tb = (JToolBar) c;
+ if (tb.getOrientation() == JToolBar.HORIZONTAL)
+ {
+ if (newInsets == null)
+ newInsets = new Insets(2, 16, 2, 2);
+ else
+ {
+ newInsets.top = 2;
+ newInsets.left = 16;
+ newInsets.bottom = 2;
+ newInsets.right = 2;
+ }
+ return newInsets;
+ }
+ else // assume JToolBar.VERTICAL
+ {
+ if (newInsets == null)
+ newInsets = new Insets(16, 2, 2, 2);
+ else
+ {
+ newInsets.top = 16;
+ newInsets.left = 2;
+ newInsets.bottom = 2;
+ newInsets.right = 2;
+ }
+ return newInsets;
+ }
+
+ }
+
+ /**
+ * Paints the border for the specified component.
+ *
+ * @param c the component.
+ * @param g the graphics device.
+ * @param x the x-coordinate.
+ * @param y the y-coordinate.
+ * @param w the width.
+ * @param h the height.
+ */
+ public void paintBorder(Component c, Graphics g, int x, int y, int w,
+ int h)
+ {
+
+ JToolBar tb = (JToolBar) c;
+ if (tb.getOrientation() == JToolBar.HORIZONTAL)
+ {
+ MetalUtils.fillMetalPattern(tb, g, x + 2, y + 2, x + 11, y + h - 5,
+ MetalLookAndFeel.getControlHighlight(),
+ MetalLookAndFeel.getControlDarkShadow());
+ }
+ else
+ {
+ MetalUtils.fillMetalPattern(tb, g, x + 2, y + 2, x + w - 5, y + 11,
+ MetalLookAndFeel.getControlHighlight(),
+ MetalLookAndFeel.getControlDarkShadow());
+ }
+ }
+
+ }
+
+ /**
* A border for table header cells.
*
* @since 1.3
@@ -1156,7 +1425,8 @@ public class MetalBorders
{
Border inner = getMarginBorder();
Border outer = new TextFieldBorder();
- textFieldBorder = BorderFactory.createCompoundBorder(outer, inner);
+ textFieldBorder =
+ new BorderUIResource.CompoundBorderUIResource(outer, inner);
}
return textFieldBorder;
}
@@ -1209,4 +1479,22 @@ public class MetalBorders
marginBorder = new BasicBorders.MarginBorder();
return marginBorder;
}
+
+ /**
+ * Returns a shared instance of a compound border for rollover buttons.
+ *
+ * @return A shared border instance.
+ */
+ static Border getRolloverBorder()
+ {
+ if (rolloverBorder == null)
+ {
+ Border outer = new MetalBorders.RolloverButtonBorder();
+ Border inner = MetalBorders.getMarginBorder();
+ rolloverBorder = new BorderUIResource.CompoundBorderUIResource(outer,
+ inner);
+ }
+ return rolloverBorder;
+ }
+
}
diff --git a/javax/swing/plaf/metal/MetalButtonListener.java b/javax/swing/plaf/metal/MetalButtonListener.java
new file mode 100644
index 000000000..e6fb22e92
--- /dev/null
+++ b/javax/swing/plaf/metal/MetalButtonListener.java
@@ -0,0 +1,86 @@
+/* MetalButtonListener.java
+ Copyright (C) 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.plaf.metal;
+
+import java.beans.PropertyChangeEvent;
+
+import javax.swing.AbstractButton;
+import javax.swing.plaf.UIResource;
+import javax.swing.plaf.basic.BasicButtonListener;
+
+/**
+ * A listener for buttons under the {@link MetalLookAndFeel}.
+ *
+ * @see MetalButtonUI#createButtonListener
+ */
+class MetalButtonListener extends BasicButtonListener
+{
+
+ /**
+ * Creates a new instance.
+ *
+ * @param button the button.
+ */
+ public MetalButtonListener(AbstractButton button)
+ {
+ super(button);
+ }
+
+ /**
+ * Handles property change events.
+ *
+ * @param e the event.
+ */
+ public void propertyChange(PropertyChangeEvent e)
+ {
+ super.propertyChange(e);
+ if (e.getPropertyName().equals(
+ AbstractButton.ROLLOVER_ENABLED_CHANGED_PROPERTY))
+ {
+ AbstractButton b = (AbstractButton) e.getSource();
+ if (b.getBorder() instanceof UIResource)
+ {
+ if (Boolean.TRUE.equals(e.getNewValue()))
+ b.setBorder(MetalBorders.getRolloverBorder());
+ else if (Boolean.FALSE.equals(e.getNewValue()))
+ b.setBorder(MetalBorders.getButtonBorder());
+ }
+ }
+ }
+}
diff --git a/javax/swing/plaf/metal/MetalButtonUI.java b/javax/swing/plaf/metal/MetalButtonUI.java
index 0dac5ec39..4e148dbe9 100644
--- a/javax/swing/plaf/metal/MetalButtonUI.java
+++ b/javax/swing/plaf/metal/MetalButtonUI.java
@@ -39,18 +39,23 @@ exception statement from your version. */
package javax.swing.plaf.metal;
import java.awt.Color;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Rectangle;
import javax.swing.AbstractButton;
+import javax.swing.JButton;
import javax.swing.JComponent;
-import javax.swing.JToolBar;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.UIResource;
+import javax.swing.plaf.basic.BasicButtonListener;
import javax.swing.plaf.basic.BasicButtonUI;
/**
- * The Metal Look &amp; Feel implementation for
- * {@link javax.swing.AbstractButton}s.
+ * A UI delegate for the {@link JButton} component.
*
* @author Roman Kennke (roman@kennke.org)
*/
@@ -58,27 +63,25 @@ public class MetalButtonUI
extends BasicButtonUI
{
- /** The cached MetalButtonUI instance. */
- private static MetalButtonUI instance = null;
-
- /** The color for the focus border. */
+ /** The color used to draw the focus rectangle around the text and/or icon. */
protected Color focusColor;
-
- /** The color that indicates a selected button. */
+
+ /** The background color for the button when it is pressed. */
protected Color selectColor;
/** The color for disabled button labels. */
protected Color disabledTextColor;
/**
- * Creates a new instance of MetalButtonUI.
+ * Creates a new instance.
*/
public MetalButtonUI()
{
super();
- focusColor = getFocusColor();
- selectColor = getSelectColor();
- disabledTextColor = getDisabledTextColor();
+ UIDefaults def = UIManager.getLookAndFeelDefaults();
+ focusColor = def.getColor(getPropertyPrefix() + "focus");
+ selectColor = def.getColor(getPropertyPrefix() + "select");
+ disabledTextColor = def.getColor(getPropertyPrefix() + "disabledText");
}
/**
@@ -88,8 +91,7 @@ public class MetalButtonUI
*/
protected Color getFocusColor()
{
- UIDefaults def = UIManager.getLookAndFeelDefaults();
- return def.getColor(getPropertyPrefix() + ".focus");
+ return focusColor;
}
/**
@@ -99,8 +101,7 @@ public class MetalButtonUI
*/
protected Color getSelectColor()
{
- UIDefaults def = UIManager.getLookAndFeelDefaults();
- return def.getColor(getPropertyPrefix() + ".select");
+ return selectColor;
}
/**
@@ -110,36 +111,123 @@ public class MetalButtonUI
*/
protected Color getDisabledTextColor()
{
- UIDefaults def = UIManager.getLookAndFeelDefaults();
- return def.getColor(getPropertyPrefix() + ".disabledText");
+ return disabledTextColor;
}
/**
- * Returns an instance of MetalButtonUI.
- *
- * @param component a button for which a UI instance should be returned
+ * Returns a UI delegate for the specified component.
+ *
+ * @param c the component (should be a subclass of {@link AbstractButton}).
+ *
+ * @return A new instance of <code>MetalButtonUI</code>.
*/
- public static ComponentUI createUI(JComponent component)
- {
- if (instance == null)
- instance = new MetalButtonUI();
- return instance;
+ public static ComponentUI createUI(JComponent c) {
+ return new MetalButtonUI();
}
/**
- * Install the Look &amp; Feel defaults for Buttons.
- *
- * @param button the button for which to install the Look &amp; Feel
+ * Installs the default settings for the specified button.
+ *
+ * @param button the button.
+ *
+ * @see #uninstallDefaults(AbstractButton)
*/
public void installDefaults(AbstractButton button)
{
super.installDefaults(button);
+ if (button.isRolloverEnabled())
+ {
+ if (button.getBorder() instanceof UIResource)
+ button.setBorder(MetalBorders.getRolloverBorder());
+ }
+ }
+
+ /**
+ * Removes the defaults added by {@link #installDefaults(AbstractButton)}.
+ */
+ public void uninstallDefaults(AbstractButton button)
+ {
+ super.uninstallDefaults(button);
+ if (button.getBorder() instanceof UIResource)
+ button.setBorder(null);
+ }
- UIDefaults defaults = UIManager.getLookAndFeelDefaults();
- button.setFont(defaults.getFont("Button.font"));
+ /**
+ * Returns a button listener for the specified button.
+ *
+ * @param button the button.
+ *
+ * @return A button listener.
+ */
+ protected BasicButtonListener createButtonListener(AbstractButton button)
+ {
+ return new MetalButtonListener(button);
+ }
- if (button.getParent() instanceof JToolBar)
- button.setBorder(MetalBorders.getToolbarButtonBorder());
+ /**
+ * Paints the background of the button to indicate that it is in the "pressed"
+ * state.
+ *
+ * @param g the graphics context.
+ * @param b the button.
+ */
+ protected void paintButtonPressed(Graphics g, AbstractButton b)
+ {
+ if (b.isContentAreaFilled())
+ {
+ Rectangle area = b.getVisibleRect();
+ g.setColor(selectColor);
+ g.fillRect(area.x, area.y, area.width, area.height);
+ }
+ }
+
+ /**
+ * Paints the focus rectangle around the button text and/or icon.
+ *
+ * @param g the graphics context.
+ * @param b the button.
+ * @param viewRect the button bounds.
+ * @param textRect the text bounds.
+ * @param iconRect the icon bounds.
+ */
+ protected void paintFocus(Graphics g, AbstractButton b, Rectangle viewRect,
+ Rectangle textRect, Rectangle iconRect) {
+ if (b.hasFocus() && b.isFocusPainted())
+ {
+ Color savedColor = g.getColor();
+ g.setColor(getFocusColor());
+ Rectangle focusRect = iconRect.union(textRect);
+ g.drawRect(focusRect.x - 1, focusRect.y - 1,
+ focusRect.width + 1, focusRect.height + 1);
+ g.setColor(savedColor);
+ }
+ }
+
+ /**
+ * Paints the button text.
+ *
+ * @param g the graphics context.
+ * @param c the button.
+ * @param textRect the text bounds.
+ * @param text the text to display.
+ */
+ protected void paintText(Graphics g, JComponent c, Rectangle textRect,
+ String text)
+ {
+ AbstractButton b = (AbstractButton) c;
+ Font f = b.getFont();
+ g.setFont(f);
+ FontMetrics fm = g.getFontMetrics(f);
+
+ if (b.isEnabled())
+ {
+ g.setColor(b.getForeground());
+ g.drawString(text, textRect.x, textRect.y + fm.getAscent());
+ }
+ else
+ {
+ g.setColor(getDisabledTextColor());
+ g.drawString(text, textRect.x, textRect.y + fm.getAscent());
+ }
}
-
}
diff --git a/javax/swing/plaf/metal/MetalCheckBoxIcon.java b/javax/swing/plaf/metal/MetalCheckBoxIcon.java
index 5536e7957..6b9f31b85 100644
--- a/javax/swing/plaf/metal/MetalCheckBoxIcon.java
+++ b/javax/swing/plaf/metal/MetalCheckBoxIcon.java
@@ -47,8 +47,7 @@ import javax.swing.JCheckBox;
import javax.swing.plaf.UIResource;
/**
- * An {@link Icon} implementation for {@link JCheckBox}es in the
- * Metal Look &amp; Feel.
+ * An {@link Icon} used by the {@link MetalCheckBoxUI} class.
*
* @author Roman Kennke (roman@kennke.org)
*/
diff --git a/javax/swing/plaf/metal/MetalCheckBoxUI.java b/javax/swing/plaf/metal/MetalCheckBoxUI.java
index c46cb5f2f..b4f6f0a56 100644
--- a/javax/swing/plaf/metal/MetalCheckBoxUI.java
+++ b/javax/swing/plaf/metal/MetalCheckBoxUI.java
@@ -44,8 +44,7 @@ import javax.swing.UIDefaults;
import javax.swing.plaf.ComponentUI;
/**
- * A UI delegate for the {@link JCheckBox} component under the
- * {@link MetalLookAndFeel}.
+ * A UI delegate for the {@link JCheckBox} component.
*/
public class MetalCheckBoxUI
extends MetalRadioButtonUI
@@ -64,11 +63,11 @@ public class MetalCheckBoxUI
}
/**
- * Returns an instance of MetalCheckBoxUI.
+ * Returns a shared instance of <code>MetalCheckBoxUI</code>.
*
* @param component the component for which we return an UI instance
*
- * @return an instance of MetalCheckBoxUI
+ * @return A shared instance of <code>MetalCheckBoxUI</code>.
*/
public static ComponentUI createUI(JComponent component)
{
diff --git a/javax/swing/plaf/metal/MetalComboBoxButton.java b/javax/swing/plaf/metal/MetalComboBoxButton.java
index f9b802ab7..6993e18e9 100644
--- a/javax/swing/plaf/metal/MetalComboBoxButton.java
+++ b/javax/swing/plaf/metal/MetalComboBoxButton.java
@@ -38,7 +38,7 @@ exception statement from your version. */
package javax.swing.plaf.metal;
-import java.awt.FontMetrics;
+import java.awt.Component;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Rectangle;
@@ -99,7 +99,9 @@ public class MetalComboBoxButton extends JButton {
public MetalComboBoxButton(JComboBox cb, Icon i, boolean onlyIcon,
CellRendererPane pane, JList list)
{
- super(i);
+ super();
+ if (cb == null)
+ throw new NullPointerException("Null 'cb' argument");
comboBox = cb;
comboIcon = i;
iconOnly = onlyIcon;
@@ -200,6 +202,7 @@ public class MetalComboBoxButton extends JButton {
*/
public void paintComponent(Graphics g)
{
+ super.paintComponent(g);
if (iconOnly)
{
Rectangle bounds = getBounds();
@@ -209,28 +212,30 @@ public class MetalComboBoxButton extends JButton {
}
else
{
- String text = comboBox.getModel().getSelectedItem().toString();
+ Object selected = comboBox.getModel().getSelectedItem();
+ if (selected == null)
+ selected = "";
Rectangle bounds = comboBox.getBounds();
Rectangle innerArea = SwingUtilities.calculateInnerArea(this, null);
+ Insets insets = comboBox.getInsets();
+ Rectangle renderArea = new Rectangle(innerArea.x, innerArea.y,
+ innerArea.width - comboIcon.getIconWidth() - 4, innerArea.height);
+ Component cellRenderer
+ = comboBox.getRenderer().getListCellRendererComponent(this.listBox,
+ selected, comboBox.getSelectedIndex(), false, false);
+ cellRenderer.setBackground(comboBox.getBackground());
+ cellRenderer.setEnabled(comboBox.isEnabled());
+ rendererPane.paintComponent(g, cellRenderer, this, renderArea);
if (comboBox.hasFocus())
{
g.setColor(MetalLookAndFeel.getFocusColor());
g.drawRect(innerArea.x, innerArea.y - 1, innerArea.width - 1,
innerArea.height);
}
- Insets insets = comboBox.getInsets();
int iconX = bounds.width - insets.right - comboIcon.getIconWidth() - 7;
int iconY = insets.top
+ (bounds.height - comboIcon.getIconHeight()) / 2;
comboIcon.paintIcon(comboBox, g, iconX, iconY);
- if (comboBox.isEnabled())
- g.setColor(MetalLookAndFeel.getBlack());
- else
- g.setColor(MetalLookAndFeel.getControlDisabled());
- FontMetrics fm = g.getFontMetrics(comboBox.getFont());
- // FIXME: the label may need truncating with '...' and the
- // alignment needs work
- g.drawString(text, insets.left + 5, fm.getAscent() + 4);
}
}
}
diff --git a/javax/swing/plaf/metal/MetalComboBoxEditor.java b/javax/swing/plaf/metal/MetalComboBoxEditor.java
index c086ee70c..c2bea9f5f 100644
--- a/javax/swing/plaf/metal/MetalComboBoxEditor.java
+++ b/javax/swing/plaf/metal/MetalComboBoxEditor.java
@@ -51,8 +51,7 @@ import javax.swing.plaf.metal.MetalBorders.Flush3DBorder;
/**
* An editor used by the {@link MetalComboBoxUI} class.
*/
-public class MetalComboBoxEditor
- extends BasicComboBoxEditor
+public class MetalComboBoxEditor extends BasicComboBoxEditor
{
/**
* A border used for the {@link JTextField} component.
@@ -64,6 +63,7 @@ public class MetalComboBoxEditor
*/
public MetalComboBoxEditorBorder()
{
+ // Nothing to do here.
}
/**
@@ -116,8 +116,7 @@ public class MetalComboBoxEditor
* A subclass of {@link MetalComboBoxEditor} that implements the
* {@link javax.swing.plaf.UIResource} interface.
*/
- public static class UIResource
- extends MetalComboBoxEditor
+ public static class UIResource extends MetalComboBoxEditor
implements javax.swing.plaf.UIResource
{
/**
@@ -125,6 +124,7 @@ public class MetalComboBoxEditor
*/
public UIResource()
{
+ // Nothing to do here.
}
}
diff --git a/javax/swing/plaf/metal/MetalComboBoxUI.java b/javax/swing/plaf/metal/MetalComboBoxUI.java
index 7297d1a30..81bb3e768 100644
--- a/javax/swing/plaf/metal/MetalComboBoxUI.java
+++ b/javax/swing/plaf/metal/MetalComboBoxUI.java
@@ -41,6 +41,7 @@ package javax.swing.plaf.metal;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
+import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
@@ -49,6 +50,7 @@ import java.beans.PropertyChangeListener;
import javax.swing.CellRendererPane;
import javax.swing.ComboBoxEditor;
+import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
@@ -61,8 +63,7 @@ import javax.swing.plaf.basic.ComboPopup;
/**
* A UI delegate for the {@link JComboBox} component.
*/
-public class MetalComboBoxUI
- extends BasicComboBoxUI
+public class MetalComboBoxUI extends BasicComboBoxUI
{
/**
* A layout manager that arranges the editor component (if active) and the
@@ -75,7 +76,8 @@ public class MetalComboBoxUI
* Creates a new instance of the layout manager.
*/
public MetalComboBoxLayoutManager()
- {
+ {
+ // Nothing to do here.
}
/**
@@ -121,6 +123,7 @@ public class MetalComboBoxUI
*/
public MetalPropertyChangeListener()
{
+ // Nothing to do here.
}
/**
@@ -209,8 +212,10 @@ public class MetalComboBoxUI
*/
protected JButton createArrowButton()
{
- return new MetalComboBoxButton(comboBox, new MetalComboBoxIcon(),
+ JButton button = new MetalComboBoxButton(comboBox, new MetalComboBoxIcon(),
new CellRendererPane(), listBox);
+ button.setMargin(new Insets(0, 1, 1, 3));
+ return button;
}
/**
@@ -251,7 +256,11 @@ public class MetalComboBoxUI
}
else
{
- arrowButton.setText(comboBox.getSelectedItem().toString());
+ String text = "";
+ Object selected = comboBox.getSelectedItem();
+ if (selected != null)
+ text = selected.toString();
+ arrowButton.setText(text);
if (editor != null)
editor.setVisible(true);
}
@@ -286,10 +295,15 @@ public class MetalComboBoxUI
*/
public Dimension getMinimumSize(JComponent c)
{
- // FIXME: this needs work
- Dimension result = super.getMinimumSize(c);
- result.height = result.height + 9;
- return result;
+ MetalComboBoxButton b = (MetalComboBoxButton) arrowButton;
+ Icon icon = b.getComboIcon();
+ Insets insets = b.getInsets();
+ Dimension d = getDisplaySize();
+ int insetsH = insets.top + insets.bottom;
+ int insetsW = insets.left + insets.right;
+ int iconWidth = icon.getIconWidth() + 6;
+ return new Dimension(d.width + insetsW + iconWidth,
+ d.height + insetsH);
}
}
diff --git a/javax/swing/plaf/metal/MetalDesktopIconUI.java b/javax/swing/plaf/metal/MetalDesktopIconUI.java
index 00870545b..ecbb76e6e 100644
--- a/javax/swing/plaf/metal/MetalDesktopIconUI.java
+++ b/javax/swing/plaf/metal/MetalDesktopIconUI.java
@@ -39,9 +39,13 @@ exception statement from your version. */
package javax.swing.plaf.metal;
import javax.swing.JComponent;
+import javax.swing.JInternalFrame;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicDesktopIconUI;
+/**
+ * A UI delegate for the {@link JInternalFrame.JDesktopIcon} component.
+ */
public class MetalDesktopIconUI
extends BasicDesktopIconUI
{
@@ -51,7 +55,7 @@ public class MetalDesktopIconUI
private static MetalDesktopIconUI instance = null;
/**
- * Constructs a new instance of MetalDesktopIconUI.
+ * Constructs a new instance of <code>MetalDesktopIconUI</code>.
*/
public MetalDesktopIconUI()
{
@@ -59,11 +63,11 @@ public class MetalDesktopIconUI
}
/**
- * Returns an instance of MetalDesktopIconUI.
+ * Returns a shared instance of <code>MetalDesktopIconUI</code>.
*
* @param component the component for which we return an UI instance
*
- * @return an instance of MetalDesktopIconUI
+ * @return A shared instance of <code>MetalDesktopIconUI</code>.
*/
public static ComponentUI createUI(JComponent component)
{
diff --git a/javax/swing/plaf/metal/MetalFileChooserUI.java b/javax/swing/plaf/metal/MetalFileChooserUI.java
new file mode 100644
index 000000000..3a2e1c135
--- /dev/null
+++ b/javax/swing/plaf/metal/MetalFileChooserUI.java
@@ -0,0 +1,430 @@
+/* MetalFileChooserUI.java --
+ Copyright (C) 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.plaf.metal;
+
+import java.awt.Component;
+import java.awt.event.ActionEvent;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.File;
+import java.util.List;
+
+import javax.swing.AbstractAction;
+import javax.swing.AbstractListModel;
+import javax.swing.ComboBoxModel;
+import javax.swing.DefaultListCellRenderer;
+import javax.swing.JComponent;
+import javax.swing.JFileChooser;
+import javax.swing.JList;
+import javax.swing.UIManager;
+import javax.swing.filechooser.FileFilter;
+import javax.swing.filechooser.FileSystemView;
+import javax.swing.filechooser.FileView;
+import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.basic.BasicFileChooserUI;
+
+
+/**
+ * A UI delegate for the {@link JFileChooser} component. This class is only
+ * partially implemented and is not usable yet.
+ */
+public class MetalFileChooserUI extends BasicFileChooserUI
+{
+ /**
+ * A combo box model containing the selected directory and all its parent
+ * directories.
+ */
+ protected class DirectoryComboBoxModel extends AbstractListModel
+ implements ComboBoxModel
+ {
+ /** Storage for the items in the model. */
+ private List items;
+
+ /** The index of the selected item. */
+ private int selectedIndex;
+
+ /**
+ * Creates a new model.
+ */
+ public DirectoryComboBoxModel()
+ {
+ items = new java.util.ArrayList();
+ selectedIndex = -1;
+ }
+
+ /**
+ * Returns the number of items in the model.
+ *
+ * @return The number of items in the model.
+ */
+ public int getSize()
+ {
+ return items.size();
+ }
+
+ /**
+ * Returns the item at the specified index.
+ *
+ * @param index the item index.
+ *
+ * @return The item.
+ */
+ public Object getElementAt(int index)
+ {
+ return items.get(index);
+ }
+
+ /**
+ * Returns the depth of the item at the given <code>index</code>.
+ *
+ * @param index the item index.
+ *
+ * @return The depth.
+ */
+ public int getDepth(int index)
+ {
+ return Math.max(index, 0);
+ }
+
+ /**
+ * Returns the selected item, or <code>null</code> if no item is selected.
+ *
+ * @return The selected item, or <code>null</code>.
+ */
+ public Object getSelectedItem()
+ {
+ if (selectedIndex >= 0)
+ return items.get(selectedIndex);
+ else
+ return null;
+ }
+
+ /**
+ * Sets the selected item. This clears all the directories from the
+ * existing list, and repopulates it with the new selected directory
+ * and all its parent directories.
+ *
+ * @param selectedDirectory the selected directory.
+ */
+ public void setSelectedItem(Object selectedDirectory)
+ {
+ items.clear();
+ FileSystemView fsv = getFileChooser().getFileSystemView();
+ File parent = (File) selectedDirectory;
+ while (parent != null)
+ {
+ items.add(0, parent);
+ parent = fsv.getParentDirectory(parent);
+ }
+ selectedIndex = items.indexOf(selectedDirectory);
+ fireContentsChanged(this, 0, items.size() - 1);
+ }
+
+ }
+
+ /**
+ * Handles changes to the selection in the directory combo box.
+ */
+ protected class DirectoryComboBoxAction extends AbstractAction
+ {
+ /**
+ * Creates a new action.
+ */
+ protected DirectoryComboBoxAction()
+ {
+ // Nothing to do here.
+ }
+
+ /**
+ * Handles the action event.
+ *
+ * @param e the event.
+ */
+ public void actionPerformed(ActionEvent e)
+ {
+ JFileChooser fc = getFileChooser();
+ fc.setCurrentDirectory((File) directoryModel.getSelectedItem());
+ }
+ }
+
+ /**
+ * A renderer for the files and directories in the file chooser.
+ */
+ protected class FileRenderer extends DefaultListCellRenderer
+ {
+
+ /**
+ * Creates a new renderer.
+ */
+ protected FileRenderer()
+ {
+ // Nothing to do here.
+ }
+
+ /**
+ * Returns a component that can render the specified value.
+ *
+ * @param list the list.
+ * @param value the value (a {@link File}).
+ * @param index the index.
+ * @param isSelected is the item selected?
+ * @param cellHasFocus does the item have the focus?
+ *
+ * @return The renderer.
+ */
+ public Component getListCellRendererComponent(JList list, Object value,
+ int index, boolean isSelected, boolean cellHasFocus)
+ {
+ FileView v = getFileView(getFileChooser());
+ File f = (File) value;
+ setText(v.getName(f));
+ setIcon(v.getIcon(f));
+ if (isSelected)
+ {
+ setBackground(list.getSelectionBackground());
+ setForeground(list.getSelectionForeground());
+ }
+ else
+ {
+ setBackground(list.getBackground());
+ setForeground(list.getForeground());
+ }
+
+ setEnabled(list.isEnabled());
+ setFont(list.getFont());
+
+ if (cellHasFocus)
+ setBorder(UIManager.getBorder("List.focusCellHighlightBorder"));
+ else
+ setBorder(noFocusBorder);
+ return this;
+ }
+ }
+
+ /**
+ * A combo box model for the file selection filters.
+ */
+ protected class FilterComboBoxModel
+ extends AbstractListModel
+ implements ComboBoxModel, PropertyChangeListener
+ {
+
+ /** Storage for the filters in the model. */
+ protected FileFilter[] filters;
+
+ /** The index of the selected file filter. */
+ private int selectedIndex;
+
+ /**
+ * Creates a new model.
+ */
+ protected FilterComboBoxModel()
+ {
+ filters = new FileFilter[1];
+ filters[0] = getAcceptAllFileFilter(getFileChooser());
+ selectedIndex = 0;
+ }
+
+ /**
+ * Handles property changes.
+ *
+ * @param e the property change event.
+ */
+ public void propertyChange(PropertyChangeEvent e)
+ {
+ if (e.getPropertyName().equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY))
+ {
+ selectedIndex = -1;
+ FileFilter selected = (FileFilter) e.getNewValue();
+ for (int i = 0; i < filters.length; i++)
+ if (filters[i].equals(selected))
+ selectedIndex = i;
+ fireContentsChanged(this, -1, -1);
+ }
+ else if (e.getPropertyName().equals(
+ JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY))
+ {
+ // repopulate list
+ JFileChooser fc = getFileChooser();
+ FileFilter[] choosableFilters = fc.getChoosableFileFilters();
+ filters = choosableFilters;
+ fireContentsChanged(this, 0, filters.length);
+ }
+ }
+
+ /**
+ * Sets the selected filter.
+ *
+ * @param filter the filter.
+ */
+ public void setSelectedItem(Object filter)
+ {
+ // change the filter in the file chooser and let the property change
+ // event trigger the change to the selected item
+ getFileChooser().setFileFilter((FileFilter) filter);
+ }
+
+ /**
+ * Returns the selected file filter.
+ *
+ * @return The selected file filter.
+ */
+ public Object getSelectedItem()
+ {
+ if (selectedIndex >= 0)
+ return filters[selectedIndex];
+ return null;
+ }
+
+ /**
+ * Returns the number of items in the model.
+ *
+ * @return The number of items in the model.
+ */
+ public int getSize()
+ {
+ return filters.length;
+ }
+
+ /**
+ * Returns the item at the specified index.
+ *
+ * @param index the item index.
+ *
+ * @return The item at the specified index.
+ */
+ public Object getElementAt(int index)
+ {
+ return filters[index];
+ }
+
+ }
+
+ /**
+ * A renderer for the items in the file filter combo box.
+ */
+ public class FilterComboBoxRenderer extends DefaultListCellRenderer
+ {
+ /**
+ * Creates a new renderer.
+ */
+ public FilterComboBoxRenderer()
+ {
+ // Nothing to do here.
+ }
+
+ /**
+ * Returns a component that can be used to paint the given value within
+ * the list.
+ *
+ * @param list the list.
+ * @param value the value (a {@link FileFilter}).
+ * @param index the item index.
+ * @param isSelected is the item selected?
+ * @param cellHasFocus does the list cell have focus?
+ *
+ * @return A component.
+ */
+ public Component getListCellRendererComponent(JList list, Object value,
+ int index, boolean isSelected, boolean cellHasFocus)
+ {
+ FileFilter filter = (FileFilter) value;
+ return super.getListCellRendererComponent(list, filter.getDescription(),
+ index, isSelected, cellHasFocus);
+ }
+ }
+
+ /** The model for the directory combo box. */
+ DirectoryComboBoxModel directoryModel;
+
+ /**
+ * A factory method that returns a UI delegate for the specified
+ * component.
+ *
+ * @param c the component (which should be a {@link JFileChooser}).
+ */
+ public static ComponentUI createUI(JComponent c)
+ {
+ JFileChooser chooser = (JFileChooser) c;
+ return new MetalFileChooserUI(chooser);
+ }
+
+ /**
+ * Creates a new instance of this UI delegate.
+ *
+ * @param filechooser the file chooser component.
+ */
+ public MetalFileChooserUI(JFileChooser filechooser)
+ {
+ super(filechooser);
+ }
+
+ /**
+ * Creates and returns a new instance of {@link DirectoryComboBoxModel}.
+ *
+ * @return A new instance of {@link DirectoryComboBoxModel}.
+ */
+ protected MetalFileChooserUI.DirectoryComboBoxModel
+ createDirectoryComboBoxModel(JFileChooser fc)
+ {
+ return new DirectoryComboBoxModel();
+ }
+
+ /**
+ * Creates and returns a new instance of {@link FilterComboBoxModel}.
+ *
+ * @return A new instance of {@link FilterComboBoxModel}.
+ */
+ protected FilterComboBoxModel createFilterComboBoxModel()
+ {
+ return new FilterComboBoxModel();
+ }
+
+ /**
+ * Creates and returns a new instance of {@link FilterComboBoxRenderer}.
+ *
+ * @return A new instance of {@link FilterComboBoxRenderer}.
+ */
+ protected MetalFileChooserUI.FilterComboBoxRenderer
+ createFilterComboBoxRenderer()
+ {
+ return new FilterComboBoxRenderer();
+ }
+
+}
diff --git a/javax/swing/plaf/metal/MetalIconFactory.java b/javax/swing/plaf/metal/MetalIconFactory.java
index 0c52272e2..6f4feccfc 100644
--- a/javax/swing/plaf/metal/MetalIconFactory.java
+++ b/javax/swing/plaf/metal/MetalIconFactory.java
@@ -77,6 +77,7 @@ public class MetalIconFactory implements Serializable
*/
public CheckBoxMenuItemIcon()
{
+ // Nothing to do here.
}
/**
@@ -144,14 +145,15 @@ public class MetalIconFactory implements Serializable
*
* @see MetalIconFactory#getFileChooserDetailViewIcon()
*/
- private static class FileChooserDetailViewIcon
- implements Icon, Serializable {
-
+ private static class FileChooserDetailViewIcon implements Icon, Serializable
+ {
+
/**
* Creates a new icon.
*/
public FileChooserDetailViewIcon()
{
+ // Nothing to do here.
}
/**
@@ -223,14 +225,15 @@ public class MetalIconFactory implements Serializable
*
* @see MetalIconFactory#getFileChooserHomeFolderIcon()
*/
- private static class FileChooserHomeFolderIcon
- implements Icon, Serializable {
-
+ private static class FileChooserHomeFolderIcon implements Icon, Serializable
+ {
+
/**
* Creates a new icon.
*/
public FileChooserHomeFolderIcon()
{
+ // Nothing to do here.
}
/**
@@ -318,6 +321,7 @@ public class MetalIconFactory implements Serializable
*/
public FileChooserListViewIcon()
{
+ // Nothing to do here.
}
/**
@@ -406,14 +410,14 @@ public class MetalIconFactory implements Serializable
*
* @see MetalIconFactory#getFileChooserNewFolderIcon()
*/
- private static class FileChooserNewFolderIcon
- implements Icon, Serializable
+ private static class FileChooserNewFolderIcon implements Icon, Serializable
{
/**
* Creates a new icon.
*/
public FileChooserNewFolderIcon()
{
+ // Nothing to do here.
}
/**
@@ -478,8 +482,7 @@ public class MetalIconFactory implements Serializable
*
* @see MetalIconFactory#getFileChooserNewFolderIcon()
*/
- private static class FileChooserUpFolderIcon
- extends FileChooserNewFolderIcon
+ private static class FileChooserUpFolderIcon extends FileChooserNewFolderIcon
implements Icon, Serializable
{
/**
@@ -487,6 +490,7 @@ public class MetalIconFactory implements Serializable
*/
public FileChooserUpFolderIcon()
{
+ // Nothing to do here.
}
/**
@@ -531,13 +535,15 @@ public class MetalIconFactory implements Serializable
}
/**
- * Returns the height of the icon, in pixels.
+ * Returns the height of the icon, in pixels. The height returned is
+ * <code>16</code> plus the value returned by
+ * {@link #getAdditionalHeight()}.
*
* @return The height of the icon.
*/
public int getIconHeight()
{
- return 16;
+ return 16 + getAdditionalHeight();
}
/**
@@ -570,9 +576,11 @@ public class MetalIconFactory implements Serializable
}
/**
- * Returns the additional height (???).
+ * Returns the additional height for the icon. The
+ * {@link #getIconHeight()} method adds this value to the icon height it
+ * returns. Subclasses can override this method to adjust the icon height.
*
- * @return The additional height.
+ * @return The additional height (<code>0</code> unless overridden).
*/
public int getAdditionalHeight()
{
@@ -606,13 +614,15 @@ public class MetalIconFactory implements Serializable
}
/**
- * Returns the height of the icon, in pixels.
+ * Returns the height of the icon, in pixels. The height returned is
+ * <code>16</code> plus the value returned by
+ * {@link #getAdditionalHeight()}.
*
* @return The height of the icon.
*/
public int getIconHeight()
{
- return 16;
+ return 16 + getAdditionalHeight();
}
/**
@@ -643,9 +653,11 @@ public class MetalIconFactory implements Serializable
}
/**
- * Returns the additional height (???).
+ * Returns the additional height for the icon. The
+ * {@link #getIconHeight()} method adds this value to the icon height it
+ * returns. Subclasses can override this method to adjust the icon height.
*
- * @return The additional height.
+ * @return The additional height (<code>0</code> unless overridden).
*/
public int getAdditionalHeight()
{
@@ -670,7 +682,7 @@ public class MetalIconFactory implements Serializable
*
* @since 1.3
*/
- public static class PaletteCloseIcon
+ public static class PaletteCloseIcon
implements Icon, Serializable, UIResource
{
/**
@@ -732,8 +744,7 @@ public class MetalIconFactory implements Serializable
*
* @author Roman Kennke (roman@kennke.org)
*/
- static class RadioButtonIcon
- implements Icon, UIResource, Serializable
+ static class RadioButtonIcon implements Icon, UIResource, Serializable
{
/**
@@ -847,14 +858,14 @@ public class MetalIconFactory implements Serializable
/**
* An icon displayed for {@link JRadioButtonMenuItem} components.
*/
- private static class RadioButtonMenuItemIcon
- implements Icon, Serializable
+ private static class RadioButtonMenuItemIcon implements Icon, Serializable
{
/**
* Creates a new icon instance.
*/
public RadioButtonMenuItemIcon()
- {
+ {
+ // Nothing to do here.
}
/**
@@ -924,8 +935,7 @@ public class MetalIconFactory implements Serializable
* The icon used to display the thumb control on a horizontally oriented
* {@link JSlider} component.
*/
- private static class HorizontalSliderThumbIcon
- implements Icon, Serializable
+ private static class HorizontalSliderThumbIcon implements Icon, Serializable
{
/**
@@ -933,6 +943,7 @@ public class MetalIconFactory implements Serializable
*/
public HorizontalSliderThumbIcon()
{
+ // Nothing to do here.
}
/**
@@ -1042,7 +1053,7 @@ public class MetalIconFactory implements Serializable
* An icon used for the 'close' button in the title frame of a
* {@link JInternalFrame}.
*/
- private static class InternalFrameCloseIcon implements Icon, Serializable
+ private static class InternalFrameCloseIcon implements Icon, Serializable
{
/** The icon size in pixels. */
private int size;
@@ -1158,8 +1169,8 @@ public class MetalIconFactory implements Serializable
/**
* The icon displayed at the top-left corner of a {@link JInternalFrame}.
*/
- private static class InternalFrameDefaultMenuIcon
- implements Icon, Serializable
+ private static class InternalFrameDefaultMenuIcon
+ implements Icon, Serializable
{
/**
@@ -1167,6 +1178,7 @@ public class MetalIconFactory implements Serializable
*/
public InternalFrameDefaultMenuIcon()
{
+ // Nothing to do here.
}
/**
@@ -1229,8 +1241,8 @@ public class MetalIconFactory implements Serializable
* maximise an internal frame, this icon will replace the 'maximise' icon to
* provide a 'restore' option.
*/
- private static class InternalFrameAltMaximizeIcon
- implements Icon, Serializable
+ private static class InternalFrameAltMaximizeIcon
+ implements Icon, Serializable
{
/** The icon size in pixels. */
private int size;
@@ -1340,8 +1352,7 @@ public class MetalIconFactory implements Serializable
* An icon used for the 'maximize' button in the title frame of a
* {@link JInternalFrame}.
*/
- private static class InternalFrameMaximizeIcon
- implements Icon, Serializable
+ private static class InternalFrameMaximizeIcon implements Icon, Serializable
{
/**
@@ -1349,6 +1360,7 @@ public class MetalIconFactory implements Serializable
*/
public InternalFrameMaximizeIcon()
{
+ // Nothing to do here.
}
/**
@@ -1452,8 +1464,7 @@ public class MetalIconFactory implements Serializable
/**
* An icon used in the title frame of a {@link JInternalFrame}.
*/
- private static class InternalFrameMinimizeIcon
- implements Icon, Serializable
+ private static class InternalFrameMinimizeIcon implements Icon, Serializable
{
/**
@@ -1461,6 +1472,7 @@ public class MetalIconFactory implements Serializable
*/
public InternalFrameMinimizeIcon()
{
+ // Nothing to do here.
}
/**
@@ -1556,13 +1568,14 @@ public class MetalIconFactory implements Serializable
* The icon used to display the thumb control on a horizontally oriented
* {@link JSlider} component.
*/
- private static class VerticalSliderThumbIcon implements Icon, Serializable
+ private static class VerticalSliderThumbIcon implements Icon, Serializable
{
/**
* Creates a new instance.
*/
public VerticalSliderThumbIcon()
{
+ // Nothing to do here.
}
/**
@@ -1673,7 +1686,7 @@ public class MetalIconFactory implements Serializable
* A tree control icon. This icon can be in one of two states: expanded and
* collapsed.
*/
- public static class TreeControlIcon implements Icon, Serializable
+ public static class TreeControlIcon implements Icon, Serializable
{
/** ???. */
@@ -1806,19 +1819,21 @@ public class MetalIconFactory implements Serializable
/**
* A tree folder icon.
*/
- public static class TreeFolderIcon extends FolderIcon16
+ public static class TreeFolderIcon extends FolderIcon16
{
/**
* Creates a new instance.
*/
public TreeFolderIcon()
- {
+ {
+ // Nothing to do here.
}
/**
- * Returns the additional height (???).
+ * Returns the additional height for this icon, in this case <code>2</code>
+ * pixels.
*
- * @return The additional height.
+ * @return <code>2</code>.
*/
public int getAdditionalHeight()
{
@@ -1839,19 +1854,21 @@ public class MetalIconFactory implements Serializable
/**
* A tree leaf icon.
*/
- public static class TreeLeafIcon extends FileIcon16
+ public static class TreeLeafIcon extends FileIcon16
{
/**
* Creates a new instance.
*/
public TreeLeafIcon()
{
+ // Nothing to do here.
}
/**
- * Returns the additional height (???).
+ * Returns the additional height for this icon, in this case <code>4</code>
+ * pixels.
*
- * @return The additional height.
+ * @return <code>4</code>.
*/
public int getAdditionalHeight()
{
@@ -1868,16 +1885,310 @@ public class MetalIconFactory implements Serializable
return 2;
}
}
+
+ /**
+ * An icon representing a hard disk.
+ *
+ * @see MetalIconFactory#getTreeHardDriveIcon()
+ */
+ private static class TreeHardDriveIcon implements Icon, Serializable
+ {
+
+ /**
+ * Creates a new icon instance.
+ */
+ public TreeHardDriveIcon()
+ {
+ // Nothing to do here.
+ }
+
+ /**
+ * Returns the width of the icon, in pixels.
+ *
+ * @return <code>16</code>.
+ */
+ public int getIconWidth()
+ {
+ return 16;
+ }
+
+ /**
+ * Returns the height of the icon, in pixels.
+ *
+ * @return <code>16</code>.
+ */
+ public int getIconHeight()
+ {
+ return 16;
+ }
+
+ /**
+ * Paints the icon at the specified location, using colors from the
+ * current theme.
+ *
+ * @param c the component (ignored).
+ * @param g the graphics device.
+ * @param x the x-coordinate for the top-left of the icon.
+ * @param y the y-coordinate for the top-left of the icon.
+ */
+ public void paintIcon(Component c, Graphics g, int x, int y)
+ {
+ Color saved = g.getColor();
+ g.setColor(MetalLookAndFeel.getBlack());
+ g.drawLine(x + 1, y + 4, x + 1, y + 5);
+ g.drawLine(x + 14, y + 4, x + 14, y + 5);
+ g.drawLine(x + 1, y + 7, x + 1, y + 8);
+ g.drawLine(x + 14, y + 7, x + 14, y + 8);
+ g.drawLine(x + 1, y + 10, x + 1, y + 11);
+ g.drawLine(x + 14, y + 10, x + 14, y + 11);
+
+ g.drawLine(x + 2, y + 3, x + 3, y + 3);
+ g.drawLine(x + 12, y + 3, x + 13, y + 3);
+ g.drawLine(x + 2, y + 6, x + 3, y + 6);
+ g.drawLine(x + 12, y + 6, x + 13, y + 6);
+ g.drawLine(x + 2, y + 9, x + 3, y + 9);
+ g.drawLine(x + 12, y + 9, x + 13, y + 9);
+ g.drawLine(x + 2, y + 12, x + 3, y + 12);
+ g.drawLine(x + 12, y + 12, x + 13, y + 12);
+
+ g.drawLine(x + 4, y + 2, x + 11, y + 2);
+ g.drawLine(x + 4, y + 7, x + 11, y + 7);
+ g.drawLine(x + 4, y + 10, x + 11, y + 10);
+ g.drawLine(x + 4, y + 13, x + 11, y + 13);
+
+ g.setColor(MetalLookAndFeel.getWhite());
+ g.fillRect(x + 4, y + 3, 2, 2);
+ g.drawLine(x + 6, y + 4, x + 6, y + 4);
+ g.drawLine(x + 7, y + 3, x + 9, y + 3);
+ g.drawLine(x + 8, y + 4, x + 8, y + 4);
+ g.drawLine(x + 11, y + 3, x + 11, y + 3);
+ g.fillRect(x + 2, y + 4, 2, 2);
+ g.fillRect(x + 2, y + 7, 2, 2);
+ g.fillRect(x + 2, y + 10, 2, 2);
+ g.drawLine(x + 4, y + 6, x + 4, y + 6);
+ g.drawLine(x + 4, y + 9, x + 4, y + 9);
+ g.drawLine(x + 4, y + 12, x + 4, y + 12);
+
+ g.setColor(MetalLookAndFeel.getControlShadow());
+ g.drawLine(x + 13, y + 4, x + 13, y + 4);
+ g.drawLine(x + 12, y + 5, x + 13, y + 5);
+ g.drawLine(x + 13, y + 7, x + 13, y + 7);
+ g.drawLine(x + 12, y + 8, x + 13, y + 8);
+ g.drawLine(x + 13, y + 10, x + 13, y + 10);
+ g.drawLine(x + 12, y + 11, x + 13, y + 11);
+
+ g.drawLine(x + 10, y + 5, x + 10, y + 5);
+ g.drawLine(x + 7, y + 6, x + 7, y + 6);
+ g.drawLine(x + 9, y + 6, x + 9, y + 6);
+ g.drawLine(x + 11, y + 6, x + 11, y + 6);
+
+ g.drawLine(x + 10, y + 8, x + 10, y + 8);
+ g.drawLine(x + 7, y + 9, x + 7, y + 9);
+ g.drawLine(x + 9, y + 9, x + 9, y + 9);
+ g.drawLine(x + 11, y + 9, x + 11, y + 9);
+
+ g.drawLine(x + 10, y + 11, x + 10, y + 11);
+ g.drawLine(x + 7, y + 12, x + 7, y + 12);
+ g.drawLine(x + 9, y + 12, x + 9, y + 12);
+ g.drawLine(x + 11, y + 12, x + 11, y + 12);
+
+ g.setColor(saved);
+ }
+ }
+
+ /**
+ * An icon representing a floppy disk.
+ *
+ * @see MetalIconFactory#getTreeFloppyDriveIcon()
+ */
+ private static class TreeFloppyDriveIcon implements Icon, Serializable
+ {
+
+ /**
+ * Creates a new icon instance.
+ */
+ public TreeFloppyDriveIcon()
+ {
+ // Nothing to do here.
+ }
+
+ /**
+ * Returns the width of the icon, in pixels.
+ *
+ * @return <code>16</code>.
+ */
+ public int getIconWidth()
+ {
+ return 16;
+ }
+
+ /**
+ * Returns the height of the icon, in pixels.
+ *
+ * @return <code>16</code>.
+ */
+ public int getIconHeight()
+ {
+ return 16;
+ }
+
+ /**
+ * Paints the icon at the specified location, using colors from the
+ * current theme.
+ *
+ * @param c the component (ignored).
+ * @param g the graphics device.
+ * @param x the x-coordinate for the top-left of the icon.
+ * @param y the y-coordinate for the top-left of the icon.
+ */
+ public void paintIcon(Component c, Graphics g, int x, int y)
+ {
+ Color saved = g.getColor();
+
+ g.setColor(MetalLookAndFeel.getBlack());
+ g.drawLine(x + 1, y + 1, x + 13, y + 1);
+ g.drawLine(x + 1, y + 1, x + 1, y + 14);
+ g.drawLine(x + 1, y + 14, x + 14, y + 14);
+ g.drawLine(x + 14, y + 2, x + 14, y + 14);
+
+ g.setColor(MetalLookAndFeel.getPrimaryControl());
+ g.fillRect(x + 2, y + 2, 12, 12);
+
+ g.setColor(MetalLookAndFeel.getControlShadow());
+ g.fillRect(x + 5, y + 2, 6, 5);
+ g.drawLine(x + 4, y + 8, x + 11, y + 8);
+ g.drawLine(x + 3, y + 9, x + 3, y + 13);
+ g.drawLine(x + 12, y + 9, x + 12, y + 13);
+
+ g.setColor(MetalLookAndFeel.getWhite());
+ g.fillRect(x + 8, y + 3, 2, 3);
+ g.fillRect(x + 4, y + 9, 8, 5);
+
+ g.setColor(MetalLookAndFeel.getPrimaryControlShadow());
+ g.drawLine(x + 5, y + 10, x + 9, y + 10);
+ g.drawLine(x + 5, y + 12, x + 8, y + 12);
+
+ g.setColor(saved);
+ }
+ }
+
+ /**
+ * An icon representing a computer.
+ *
+ * @see MetalIconFactory#getTreeComputerIcon()
+ */
+ private static class TreeComputerIcon implements Icon, Serializable
+ {
+
+ /**
+ * Creates a new icon instance.
+ */
+ public TreeComputerIcon()
+ {
+ // Nothing to do here.
+ }
+
+ /**
+ * Returns the width of the icon, in pixels.
+ *
+ * @return <code>16</code>.
+ */
+ public int getIconWidth()
+ {
+ return 16;
+ }
+
+ /**
+ * Returns the height of the icon, in pixels.
+ *
+ * @return <code>16</code>.
+ */
+ public int getIconHeight()
+ {
+ return 16;
+ }
+
+ /**
+ * Paints the icon at the specified location, using colors from the
+ * current theme.
+ *
+ * @param c the component (ignored).
+ * @param g the graphics device.
+ * @param x the x-coordinate for the top-left of the icon.
+ * @param y the y-coordinate for the top-left of the icon.
+ */
+ public void paintIcon(Component c, Graphics g, int x, int y)
+ {
+ Color saved = g.getColor();
+
+ g.setColor(MetalLookAndFeel.getBlack());
+ g.drawLine(x + 3, y + 1, x + 12, y + 1);
+ g.drawLine(x + 2, y + 2, x + 2, y + 8);
+ g.drawLine(x + 13, y + 2, x + 13, y + 8);
+ g.drawLine(x + 3, y + 9, x + 3, y + 9);
+ g.drawLine(x + 12, y + 9, x + 12, y + 9);
+ g.drawRect(x + 1, y + 10, 13, 4);
+ g.drawLine(x + 5, y + 3, x + 10, y + 3);
+ g.drawLine(x + 5, y + 8, x + 10, y + 8);
+ g.drawLine(x + 4, y + 4, x + 4, y + 7);
+ g.drawLine(x + 11, y + 4, x + 11, y + 7);
+
+ g.setColor(MetalLookAndFeel.getPrimaryControl());
+ g.fillRect(x + 5, y + 4, 6, 4);
+
+ g.setColor(MetalLookAndFeel.getControlShadow());
+ g.drawLine(x + 6, y + 12, x + 8, y + 12);
+ g.drawLine(x + 10, y + 12, x + 12, y + 12);
+ g.setColor(saved);
+ }
+ }
+ /** The icon returned by {@link #getCheckBoxIcon()}. */
+ private static Icon checkBoxIcon;
+
+ /** The icon returned by {@link #getCheckBoxMenuItemIcon()}. */
+ private static Icon checkBoxMenuItemIcon;
+
+ /** The icon returned by {@link #getFileChooserDetailViewIcon()}. */
+ private static Icon fileChooserDetailViewIcon;
+
+ /** The icon returned by {@link #getFileChooserHomeFolderIcon()}. */
+ private static Icon fileChooserHomeFolderIcon;
+
+ /** The icon returned by {@link #getFileChooserListViewIcon()}. */
+ private static Icon fileChooserListViewIcon;
+
+ /** The icon returned by {@link #getFileChooserNewFolderIcon()}. */
+ private static Icon fileChooserNewFolderIcon;
+
+ /** The icon returned by {@link #getFileChooserUpFolderIcon()}. */
+ private static Icon fileChooserUpFolderIcon;
+
/** The cached RadioButtonIcon instance. */
private static RadioButtonIcon radioButtonIcon;
+ /** The icon returned by {@link #getRadioButtonMenuItemIcon()}. */
+ private static Icon radioButtonMenuItemIcon;
+
+ /** The icon returned by {@link #getInternalFrameDefaultMenuIcon()}. */
+ private static Icon internalFrameDefaultMenuIcon;
+
+ /** The icon returned by {@link #getTreeComputerIcon()}. */
+ private static Icon treeComputerIcon;
+
+ /** The icon instance returned by {@link #getTreeFloppyDriveIcon()}. */
+ private static Icon treeFloppyDriveIcon;
+
+ /** The icon instance returned by {@link #getTreeHardDriveIcon()}. */
+ private static Icon treeHardDriveIcon;
+
/**
* Creates a new instance. All the methods are static, so creating an
* instance isn't necessary.
*/
public MetalIconFactory()
- {
+ {
+ // Nothing to do here.
}
/**
@@ -1889,7 +2200,9 @@ public class MetalIconFactory implements Serializable
*/
public static Icon getCheckBoxIcon()
{
- return new MetalCheckBoxIcon();
+ if (checkBoxIcon == null)
+ checkBoxIcon = new MetalCheckBoxIcon();
+ return checkBoxIcon;
}
/**
@@ -1900,7 +2213,9 @@ public class MetalIconFactory implements Serializable
*/
public static Icon getCheckBoxMenuItemIcon()
{
- return new CheckBoxMenuItemIcon();
+ if (checkBoxMenuItemIcon == null)
+ checkBoxMenuItemIcon = new CheckBoxMenuItemIcon();
+ return checkBoxMenuItemIcon;
}
/**
@@ -1910,7 +2225,9 @@ public class MetalIconFactory implements Serializable
*/
public static Icon getFileChooserDetailViewIcon()
{
- return new FileChooserDetailViewIcon();
+ if (fileChooserDetailViewIcon == null)
+ fileChooserDetailViewIcon = new FileChooserDetailViewIcon();
+ return fileChooserDetailViewIcon;
}
/**
@@ -1920,7 +2237,9 @@ public class MetalIconFactory implements Serializable
*/
public static Icon getFileChooserHomeFolderIcon()
{
- return new FileChooserHomeFolderIcon();
+ if (fileChooserHomeFolderIcon == null)
+ fileChooserHomeFolderIcon = new FileChooserHomeFolderIcon();
+ return fileChooserHomeFolderIcon;
}
/**
@@ -1930,7 +2249,9 @@ public class MetalIconFactory implements Serializable
*/
public static Icon getFileChooserListViewIcon()
{
- return new FileChooserListViewIcon();
+ if (fileChooserListViewIcon == null)
+ fileChooserListViewIcon = new FileChooserListViewIcon();
+ return fileChooserListViewIcon;
}
/**
@@ -1940,7 +2261,9 @@ public class MetalIconFactory implements Serializable
*/
public static Icon getFileChooserNewFolderIcon()
{
- return new FileChooserNewFolderIcon();
+ if (fileChooserNewFolderIcon == null)
+ fileChooserNewFolderIcon = new FileChooserNewFolderIcon();
+ return fileChooserNewFolderIcon;
}
/**
@@ -1950,7 +2273,9 @@ public class MetalIconFactory implements Serializable
*/
public static Icon getFileChooserUpFolderIcon()
{
- return new FileChooserUpFolderIcon();
+ if (fileChooserUpFolderIcon == null)
+ fileChooserUpFolderIcon = new FileChooserUpFolderIcon();
+ return fileChooserUpFolderIcon;
}
/**
@@ -1972,7 +2297,9 @@ public class MetalIconFactory implements Serializable
*/
public static Icon getRadioButtonMenuItemIcon()
{
- return new RadioButtonMenuItemIcon();
+ if (radioButtonMenuItemIcon == null)
+ radioButtonMenuItemIcon = new RadioButtonMenuItemIcon();
+ return radioButtonMenuItemIcon;
}
/**
@@ -2007,7 +2334,9 @@ public class MetalIconFactory implements Serializable
*/
public static Icon getInternalFrameDefaultMenuIcon()
{
- return new InternalFrameDefaultMenuIcon();
+ if (internalFrameDefaultMenuIcon == null)
+ internalFrameDefaultMenuIcon = new InternalFrameDefaultMenuIcon();
+ return internalFrameDefaultMenuIcon;
}
/**
@@ -2096,4 +2425,40 @@ public class MetalIconFactory implements Serializable
return new TreeControlIcon(isCollapsed);
}
+ /**
+ * Returns a <code>16x16</code> icon representing a computer.
+ *
+ * @return The icon.
+ */
+ public static Icon getTreeComputerIcon()
+ {
+ if (treeComputerIcon == null)
+ treeComputerIcon = new TreeComputerIcon();
+ return treeComputerIcon;
+ }
+
+ /**
+ * Returns a <code>16x16</code> icon representing a floppy disk.
+ *
+ * @return The icon.
+ */
+ public static Icon getTreeFloppyDriveIcon()
+ {
+ if (treeFloppyDriveIcon == null)
+ treeFloppyDriveIcon = new TreeFloppyDriveIcon();
+ return treeFloppyDriveIcon;
+ }
+
+ /**
+ * Returns a <code>16x16</code> icon representing a hard disk.
+ *
+ * @return The icon.
+ */
+ public static Icon getTreeHardDriveIcon()
+ {
+ if (treeHardDriveIcon == null)
+ treeHardDriveIcon = new TreeHardDriveIcon();
+ return treeHardDriveIcon;
+ }
+
}
diff --git a/javax/swing/plaf/metal/MetalInternalFrameTitlePane.java b/javax/swing/plaf/metal/MetalInternalFrameTitlePane.java
index efae78417..33eb3491a 100644
--- a/javax/swing/plaf/metal/MetalInternalFrameTitlePane.java
+++ b/javax/swing/plaf/metal/MetalInternalFrameTitlePane.java
@@ -61,9 +61,10 @@ import javax.swing.plaf.basic.BasicInternalFrameTitlePane;
/**
- * The title pane for a {@link JInternalFrame}. This can be displayed in two
- * styles: one for regular internal frames, and the other for "palette" style
- * internal frames.
+ * The title pane for a {@link JInternalFrame} (see
+ * {@link MetalInternalFrameUI#createNorthPane(JInternalFrame)}). This can
+ * be displayed in two styles: one for regular internal frames, and the other
+ * for "palette" style internal frames.
*/
public class MetalInternalFrameTitlePane extends BasicInternalFrameTitlePane
{
@@ -86,7 +87,7 @@ public class MetalInternalFrameTitlePane extends BasicInternalFrameTitlePane
/**
* Handles <code>JInternalFrame.isPalette</code> property changes, with all
- * other propert changes being passed to the superclass.
+ * other property changes being passed to the superclass.
*
* @param e the event.
*/
@@ -214,6 +215,7 @@ public class MetalInternalFrameTitlePane extends BasicInternalFrameTitlePane
*/
public void removeLayoutComponent(Component c)
{
+ // Nothing to do here.
}
}
@@ -234,7 +236,7 @@ public class MetalInternalFrameTitlePane extends BasicInternalFrameTitlePane
protected int paletteTitleHeight;
/** The label used to display the title for the internal frame. */
- private JLabel title;
+ JLabel title;
/**
* Creates a new title pane for the specified frame.
@@ -315,6 +317,9 @@ public class MetalInternalFrameTitlePane extends BasicInternalFrameTitlePane
// do nothing
}
+ /**
+ * Adds the sub components of the title pane.
+ */
protected void addSubComponents()
{
// FIXME: this method is probably overridden to only add the required
@@ -348,7 +353,7 @@ public class MetalInternalFrameTitlePane extends BasicInternalFrameTitlePane
Rectangle b = SwingUtilities.getLocalBounds(this);
g.setColor(MetalLookAndFeel.getPrimaryControlShadow());
g.fillRect(b.x, b.y, b.width, b.height);
- MetalUtils.fillMetalPattern(g, b.x + 4, b.y + 2, b.width
+ MetalUtils.fillMetalPattern(this, g, b.x + 4, b.y + 2, b.width
- paletteCloseIcon.getIconWidth() - 13, b.height - 5,
MetalLookAndFeel.getPrimaryControlHighlight(),
MetalLookAndFeel.getBlack());
@@ -399,7 +404,7 @@ public class MetalInternalFrameTitlePane extends BasicInternalFrameTitlePane
endX = Math.max(closeButton.getX(), endX);
endX -= 7;
if (endX > startX)
- MetalUtils.fillMetalPattern(g, startX, 3, endX - startX, getHeight() - 6, Color.white, Color.gray);
+ MetalUtils.fillMetalPattern(this, g, startX, 3, endX - startX, getHeight() - 6, Color.white, Color.gray);
}
g.setColor(savedColor);
}
@@ -422,6 +427,11 @@ public class MetalInternalFrameTitlePane extends BasicInternalFrameTitlePane
closeButton.setIcon(closeIcon);
}
+ /**
+ * Creates and returns a property change handler for the title pane.
+ *
+ * @return The property change handler.
+ */
protected PropertyChangeListener createPropertyChangeListener()
{
return new MetalInternalFrameTitlePanePropertyChangeHandler();
diff --git a/javax/swing/plaf/metal/MetalInternalFrameUI.java b/javax/swing/plaf/metal/MetalInternalFrameUI.java
index 49b8a0661..6be573f4b 100644
--- a/javax/swing/plaf/metal/MetalInternalFrameUI.java
+++ b/javax/swing/plaf/metal/MetalInternalFrameUI.java
@@ -47,15 +47,15 @@ import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicInternalFrameUI;
/**
- * A UI delegate for the {@link JInternalFrame} component under the
- * {@link MetalLookAndFeel}.
+ * A UI delegate for the {@link JInternalFrame} component.
*/
public class MetalInternalFrameUI
extends BasicInternalFrameUI
{
/**
- * The key for the client property that controls whether the internal frame
- * is displayed using the palette style.
+ * The key (<code>JInternalFrame.isPalette</code>) for the client property
+ * that controls whether the internal frame is displayed using the palette
+ * style.
*/
protected static String IS_PALETTE = "JInternalFrame.isPalette";
diff --git a/javax/swing/plaf/metal/MetalLabelUI.java b/javax/swing/plaf/metal/MetalLabelUI.java
index fe8a9e4e4..e4eaa7172 100644
--- a/javax/swing/plaf/metal/MetalLabelUI.java
+++ b/javax/swing/plaf/metal/MetalLabelUI.java
@@ -50,17 +50,17 @@ import javax.swing.plaf.basic.BasicGraphicsUtils;
import javax.swing.plaf.basic.BasicLabelUI;
/**
- * A UI delegate used for {@link JLabel}s in the {@link MetalLookAndFeel}.
+ * A UI delegate for the {@link JLabel} component.
*/
public class MetalLabelUI
extends BasicLabelUI
{
- /** The shared UI instance for JLabels. */
+ /** The shared instance of the UI delegate. */
protected static MetalLabelUI metalLabelUI;
/**
- * Constructs a new instance of MetalLabelUI.
+ * Constructs a new instance of <code>MetalLabelUI</code>.
*/
public MetalLabelUI()
{
@@ -68,11 +68,11 @@ public class MetalLabelUI
}
/**
- * Returns an instance of MetalLabelUI.
+ * Returns a shared instance of <code>MetalLabelUI</code>.
*
* @param component the component for which we return an UI instance
*
- * @return an instance of MetalLabelUI
+ * @return A shared instance of <code>MetalLabelUI</code>.
*/
public static ComponentUI createUI(JComponent component)
{
diff --git a/javax/swing/plaf/metal/MetalLookAndFeel.java b/javax/swing/plaf/metal/MetalLookAndFeel.java
index 3bc9b25c8..5542c0b76 100644
--- a/javax/swing/plaf/metal/MetalLookAndFeel.java
+++ b/javax/swing/plaf/metal/MetalLookAndFeel.java
@@ -42,11 +42,14 @@ import java.awt.Color;
import java.awt.Font;
import java.awt.Insets;
+import javax.swing.LookAndFeel;
import javax.swing.UIDefaults;
+import javax.swing.UIManager;
import javax.swing.plaf.BorderUIResource;
import javax.swing.plaf.ColorUIResource;
import javax.swing.plaf.FontUIResource;
import javax.swing.plaf.InsetsUIResource;
+import javax.swing.plaf.BorderUIResource.LineBorderUIResource;
import javax.swing.plaf.basic.BasicLookAndFeel;
@@ -78,7 +81,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
protected void createDefaultTheme()
{
- setCurrentTheme(new OceanTheme());
+ setCurrentTheme(new DefaultMetalTheme());
}
/**
@@ -602,12 +605,21 @@ public class MetalLookAndFeel extends BasicLookAndFeel
}
/**
- * Sets the current theme for the look and feel.
+ * Sets the current theme for the look and feel. Note that the theme must be
+ * set <em>before</em> the look and feel is installed. To change the theme
+ * for an already running application that is using the
+ * {@link MetalLookAndFeel}, first set the theme with this method, then
+ * create a new instance of {@link MetalLookAndFeel} and install it in the
+ * usual way (see {@link UIManager#setLookAndFeel(LookAndFeel)}).
*
- * @param theme the theme.
+ * @param theme the theme (<code>null</code> not permitted).
+ *
+ * @throws NullPointerException if <code>theme</code> is <code>null</code>.
*/
public static void setCurrentTheme(MetalTheme theme)
{
+ if (theme == null)
+ throw new NullPointerException("Null 'theme' not permitted.");
MetalLookAndFeel.theme = theme;
}
@@ -769,7 +781,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel
"Button.foreground", getControlTextColor(),
"Button.highlight", getControlHighlight(),
"Button.light", getControlHighlight(),
- "Button.margin", new Insets(2, 14, 2, 14),
+ "Button.margin", new InsetsUIResource(2, 14, 2, 14),
"Button.select", getControlShadow(),
"Button.shadow", getControlShadow(),
@@ -845,6 +857,11 @@ public class MetalLookAndFeel extends BasicLookAndFeel
"FormattedTextField.selectionBackground", getTextHighlightColor(),
"FormattedTextField.selectionForeground", getHighlightedTextColor(),
+ "FileView.computerIcon", MetalIconFactory.getTreeComputerIcon(),
+ "FileView.directoryIcon", MetalIconFactory.getTreeFolderIcon(),
+ "FileView.fileIcon", MetalIconFactory.getTreeLeafIcon(),
+ "FileView.floppyDriveIcon", MetalIconFactory.getTreeFloppyDriveIcon(),
+ "FileView.hardDriveIcon", MetalIconFactory.getTreeHardDriveIcon(),
"InternalFrame.activeTitleBackground", getWindowTitleBackground(),
"InternalFrame.activeTitleForeground", getWindowTitleForeground(),
@@ -873,10 +890,13 @@ public class MetalLookAndFeel extends BasicLookAndFeel
"Label.font", getControlTextFont(),
"Label.foreground", getSystemTextColor(),
+ "List.font", getControlTextFont(),
"List.background", getWindowBackground(),
"List.foreground", getUserTextColor(),
"List.selectionBackground", getTextHighlightColor(),
"List.selectionForeground", getHighlightedTextColor(),
+ "List.focusCellHighlightBorder",
+ new LineBorderUIResource(MetalLookAndFeel.getFocusColor()),
"Menu.acceleratorFont", new FontUIResource("Dialog", Font.PLAIN, 10),
"Menu.acceleratorForeground", getAcceleratorForeground(),
@@ -996,6 +1016,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel
"ScrollBar.thumbShadow", getPrimaryControlDarkShadow(),
"ScrollBar.track", getControl(),
"ScrollBar.trackHighlight", getControlDarkShadow(),
+ "ScrollBar.width", new Integer(17),
"ScrollPane.background", getControl(),
"ScrollPane.border", new MetalBorders.ScrollPaneBorder(),
@@ -1050,9 +1071,12 @@ public class MetalLookAndFeel extends BasicLookAndFeel
"Table.focusCellBackground", getWindowBackground(),
"Table.focusCellForeground", getControlTextColor(),
"Table.foreground", getControlTextColor(),
- "Table.focusCellHighlightBorder", getControlShadow(),
+ "Table.focusCellHighlightBorder",
+ new BorderUIResource.LineBorderUIResource(getControlShadow()),
"Table.focusCellBackground", getWindowBackground(),
"Table.gridColor", getControlDarkShadow(),
+ "Table.selectionBackground", new ColorUIResource(204, 204, 255),
+ "Table.selectionForeground", new ColorUIResource(0, 0, 0),
"TableHeader.background", getControl(),
"TableHeader.cellBorder", new MetalBorders.TableHeaderBorder(),
@@ -1116,6 +1140,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel
"ToolBar.highlight", getControlHighlight(),
"ToolBar.light", getControlHighlight(),
"ToolBar.shadow", getControlShadow(),
+ "ToolBar.border", new MetalBorders.ToolBarBorder(),
"ToolTip.background", getPrimaryControl(),
"ToolTip.backgroundInactive", getControl(),
diff --git a/javax/swing/plaf/metal/MetalPopupMenuSeparatorUI.java b/javax/swing/plaf/metal/MetalPopupMenuSeparatorUI.java
index ec9bf2b55..44a2d3bcd 100644
--- a/javax/swing/plaf/metal/MetalPopupMenuSeparatorUI.java
+++ b/javax/swing/plaf/metal/MetalPopupMenuSeparatorUI.java
@@ -39,8 +39,12 @@ exception statement from your version. */
package javax.swing.plaf.metal;
import javax.swing.JComponent;
+import javax.swing.JPopupMenu;
import javax.swing.plaf.ComponentUI;
+/**
+ * A UI delegate for the {@link JPopupMenu.Separator} component.
+ */
public class MetalPopupMenuSeparatorUI
extends MetalSeparatorUI
{
@@ -50,7 +54,7 @@ public class MetalPopupMenuSeparatorUI
private static MetalPopupMenuSeparatorUI instance = null;
/**
- * Constructs a new instance of MetalPopupMenuSeparatorUI.
+ * Constructs a new instance of <code>MetalPopupMenuSeparatorUI</code>.
*/
public MetalPopupMenuSeparatorUI()
{
@@ -58,11 +62,11 @@ public class MetalPopupMenuSeparatorUI
}
/**
- * Returns an instance of MetalPopupMenuSeparatorUI.
+ * Returns a shared instance of <code>MetalPopupMenuSeparatorUI</code>.
*
* @param component the component for which we return an UI instance
*
- * @return an instance of MetalPopupMenuSeparatorUI
+ * @return A shared instance of <code>MetalPopupMenuSeparatorUI</code>.
*/
public static ComponentUI createUI(JComponent component)
{
diff --git a/javax/swing/plaf/metal/MetalProgressBarUI.java b/javax/swing/plaf/metal/MetalProgressBarUI.java
index a32590d0a..9241cf13c 100644
--- a/javax/swing/plaf/metal/MetalProgressBarUI.java
+++ b/javax/swing/plaf/metal/MetalProgressBarUI.java
@@ -38,20 +38,18 @@ exception statement from your version. */
package javax.swing.plaf.metal;
-import java.util.HashMap;
-
import javax.swing.JComponent;
+import javax.swing.JProgressBar;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicProgressBarUI;
-public class MetalProgressBarUI
- extends BasicProgressBarUI
+/**
+ * A UI delegate for the {@link JProgressBar} component.
+ */
+public class MetalProgressBarUI extends BasicProgressBarUI
{
- /** The UI instances for MetalTreeUIs */
- private static HashMap instances = null;
-
/**
- * Constructs a new instance of MetalProgressBarUI.
+ * Constructs a new instance of <code>MetalProgressBarUI</code>.
*/
public MetalProgressBarUI()
{
@@ -59,27 +57,14 @@ public class MetalProgressBarUI
}
/**
- * Returns an instance of MetalProgressBarUI.
+ * Returns a new instance of <code>MetalProgressBarUI</code>.
*
* @param component the component for which we return an UI instance
*
- * @return an instance of MetalProgressBarUI
+ * @return A new instance of <code>MetalProgressBarUI</code>.
*/
public static ComponentUI createUI(JComponent component)
{
- if (instances == null)
- instances = new HashMap();
-
- Object o = instances.get(component);
- MetalProgressBarUI instance;
- if (o == null)
- {
- instance = new MetalProgressBarUI();
- instances.put(component, instance);
- }
- else
- instance = (MetalProgressBarUI) o;
-
- return instance;
+ return new MetalProgressBarUI();
}
}
diff --git a/javax/swing/plaf/metal/MetalRadioButtonUI.java b/javax/swing/plaf/metal/MetalRadioButtonUI.java
index 4e80718a7..c2e4ca546 100644
--- a/javax/swing/plaf/metal/MetalRadioButtonUI.java
+++ b/javax/swing/plaf/metal/MetalRadioButtonUI.java
@@ -53,8 +53,7 @@ import javax.swing.plaf.basic.BasicRadioButtonUI;
/**
- * A UI delegate for the {@link JRadioButton} component under the
- * {@link MetalLookAndFeel}.
+ * A UI delegate for the {@link JRadioButton} component.
*/
public class MetalRadioButtonUI
extends BasicRadioButtonUI
@@ -70,7 +69,7 @@ public class MetalRadioButtonUI
protected Color disabledTextColor;
/**
- * Constructs a new instance of MetalRadioButtonUI.
+ * Constructs a new instance of <code>MetalRadioButtonUI</code>.
*/
public MetalRadioButtonUI()
{
@@ -78,11 +77,11 @@ public class MetalRadioButtonUI
}
/**
- * Returns an instance of MetalRadioButtonUI.
+ * Returns a new instance of <code>MetalRadioButtonUI</code>.
*
* @param component the component for which we return an UI instance
*
- * @return an instance of MetalRadioButtonUI
+ * @return A new instance of <code>MetalRadioButtonUI</code>.
*/
public static ComponentUI createUI(JComponent component)
{
@@ -179,9 +178,9 @@ public class MetalRadioButtonUI
protected void paintFocus(Graphics g, Rectangle t, Dimension d)
{
g.setColor(focusColor);
- g.drawRect(t.x, t.y, t.width, t.height);
- // FIXME: we seem to be drawing too tight a rectangle here, perhaps there
- // is some padding to do somewhere???
+ // minus 2 because of line thickness. Prevents border
+ // from being cutoff.
+ g.drawRect(t.x, t.y, t.width - 2, t.height - 2);
}
}
diff --git a/javax/swing/plaf/metal/MetalRootPaneUI.java b/javax/swing/plaf/metal/MetalRootPaneUI.java
index 4196a4e47..faed80382 100644
--- a/javax/swing/plaf/metal/MetalRootPaneUI.java
+++ b/javax/swing/plaf/metal/MetalRootPaneUI.java
@@ -39,9 +39,16 @@ exception statement from your version. */
package javax.swing.plaf.metal;
import javax.swing.JComponent;
+import javax.swing.JRootPane;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicRootPaneUI;
+/**
+ * A UI delegate for the {@link JRootPane} component. This class is not fully
+ * implemented.
+ *
+ * @since 1.4
+ */
public class MetalRootPaneUI
extends BasicRootPaneUI
{
@@ -51,7 +58,7 @@ public class MetalRootPaneUI
private static MetalRootPaneUI instance = null;
/**
- * Constructs a new instance of MetalRootPaneUI.
+ * Constructs a shared instance of <code>MetalRootPaneUI</code>.
*/
public MetalRootPaneUI()
{
@@ -59,11 +66,11 @@ public class MetalRootPaneUI
}
/**
- * Returns an instance of MetalRootPaneUI.
+ * Returns a shared instance of <code>MetalRootPaneUI</code>.
*
* @param component the component for which we return an UI instance
*
- * @return an instance of MetalRootPaneUI
+ * @return A shared instance of <code>MetalRootPaneUI</code>.
*/
public static ComponentUI createUI(JComponent component)
{
diff --git a/javax/swing/plaf/metal/MetalScrollBarUI.java b/javax/swing/plaf/metal/MetalScrollBarUI.java
index 5d7905a35..9602ade99 100644
--- a/javax/swing/plaf/metal/MetalScrollBarUI.java
+++ b/javax/swing/plaf/metal/MetalScrollBarUI.java
@@ -56,8 +56,7 @@ import javax.swing.plaf.basic.BasicScrollBarUI;
/**
* A UI delegate for the {@link JScrollBar} component.
*/
-public class MetalScrollBarUI
- extends BasicScrollBarUI
+public class MetalScrollBarUI extends BasicScrollBarUI
{
/**
@@ -75,6 +74,7 @@ public class MetalScrollBarUI
*/
public MetalScrollBarPropertyChangeHandler()
{
+ // Nothing to do here.
}
/**
@@ -90,25 +90,35 @@ public class MetalScrollBarUI
{
Boolean prop = (Boolean) e.getNewValue();
isFreeStanding = (prop == null ? true : prop.booleanValue());
- increaseButton.setFreeStanding(isFreeStanding);
- decreaseButton.setFreeStanding(isFreeStanding);
+ if (increaseButton != null)
+ increaseButton.setFreeStanding(isFreeStanding);
+ if (decreaseButton != null)
+ decreaseButton.setFreeStanding(isFreeStanding);
}
+ else
+ super.propertyChange(e);
}
}
/** The name for the 'free standing' property. */
public static final String FREE_STANDING_PROP = "JScrollBar.isFreeStanding";
- /** The minimum thumb size */
- private static final Dimension MIN_THUMB_SIZE = new Dimension(17, 17);
+ /** The minimum thumb size for a scroll bar that is not free standing. */
+ private static final Dimension MIN_THUMB_SIZE = new Dimension(15, 15);
+ /** The minimum thumb size for a scroll bar that is free standing. */
+ private static final Dimension MIN_THUMB_SIZE_FREE_STANDING
+ = new Dimension(17, 17);
+
/** The button that increases the value in the scroll bar. */
protected MetalScrollButton increaseButton;
/** The button that decreases the value in the scroll bar. */
protected MetalScrollButton decreaseButton;
- /** The scroll bar width. */
+ /**
+ * The scroll bar width.
+ */
protected int scrollBarWidth;
/**
@@ -117,10 +127,17 @@ public class MetalScrollBarUI
* scroll bar which is not free standing has borders missing from one
* side, and relies on being part of another container with its own borders
* to look right visually. */
- protected boolean isFreeStanding;
+ protected boolean isFreeStanding = true;
+
+ /**
+ * The color for the scroll bar shadow (this is read from the UIDefaults in
+ * the installDefaults() method).
+ */
+ Color scrollBarShadowColor;
/**
- * Constructs a new instance of MetalScrollBarUI.
+ * Constructs a new instance of <code>MetalScrollBarUI</code>, with no
+ * specific initialisation.
*/
public MetalScrollBarUI()
{
@@ -128,11 +145,11 @@ public class MetalScrollBarUI
}
/**
- * Returns an instance of MetalScrollBarUI.
+ * Returns a new instance of <code>MetalScrollBarUI</code>.
*
* @param component the component for which we return an UI instance
*
- * @return an instance of MetalScrollBarUI
+ * @return An instance of MetalScrollBarUI
*/
public static ComponentUI createUI(JComponent component)
{
@@ -150,6 +167,7 @@ public class MetalScrollBarUI
// that we can do this).
Boolean prop = (Boolean) scrollbar.getClientProperty(FREE_STANDING_PROP);
isFreeStanding = (prop == null ? true : prop.booleanValue());
+ scrollBarShadowColor = UIManager.getColor("ScrollBar.shadow");
super.installDefaults();
}
@@ -179,7 +197,9 @@ public class MetalScrollBarUI
{
UIDefaults defaults = UIManager.getLookAndFeelDefaults();
scrollBarWidth = defaults.getInt("ScrollBar.width");
- return new MetalScrollButton(orientation, scrollBarWidth, isFreeStanding);
+ decreaseButton = new MetalScrollButton(orientation, scrollBarWidth,
+ isFreeStanding);
+ return decreaseButton;
}
/**
@@ -195,7 +215,9 @@ public class MetalScrollBarUI
{
UIDefaults defaults = UIManager.getLookAndFeelDefaults();
scrollBarWidth = defaults.getInt("ScrollBar.width");
- return new MetalScrollButton(orientation, scrollBarWidth, isFreeStanding);
+ increaseButton = new MetalScrollButton(orientation, scrollBarWidth,
+ isFreeStanding);
+ return increaseButton;
}
/**
@@ -239,7 +261,7 @@ public class MetalScrollBarUI
g.drawLine(x, y, x + w - 1, y);
g.drawLine(x + w - 1, y, x + w - 1, y + h - 1);
- g.setColor(MetalLookAndFeel.getControlShadow());
+ g.setColor(scrollBarShadowColor);
g.drawLine(x + 1, y + 1, x + 1, y + h - 1);
g.drawLine(x + 1, y + 1, x + w - 2, y + 1);
@@ -247,14 +269,21 @@ public class MetalScrollBarUI
{
g.setColor(MetalLookAndFeel.getControlDarkShadow());
g.drawLine(x, y + h - 2, x + w - 1, y + h - 2);
- g.setColor(MetalLookAndFeel.getControlShadow());
+ g.setColor(scrollBarShadowColor);
g.drawLine(x, y + h - 1, x + w - 1, y + h - 1);
}
}
else
{
g.setColor(MetalLookAndFeel.getControlDisabled());
- g.drawRect(x, y, w - 1, h - 1);
+ if (isFreeStanding)
+ g.drawRect(x, y, w - 1, h - 1);
+ else
+ {
+ g.drawLine(x, y, x + w - 1, y);
+ g.drawLine(x, y, x, y + h - 1);
+ g.drawLine(x + w - 1, y, x + w - 1, y + h - 1);
+ }
}
}
@@ -268,7 +297,7 @@ public class MetalScrollBarUI
* @param w the width for the track bounds.
* @param h the height for the track bounds.
*/
- protected void paintTrackVertical(Graphics g, JComponent c,
+ private void paintTrackVertical(Graphics g, JComponent c,
int x, int y, int w, int h)
{
if (c.isEnabled())
@@ -278,10 +307,9 @@ public class MetalScrollBarUI
g.drawLine(x, y, x + w - 1, y);
g.drawLine(x, y + h - 1, x + w - 1, y + h - 1);
- g.setColor(MetalLookAndFeel.getControlShadow());
+ g.setColor(scrollBarShadowColor);
g.drawLine(x + 1, y + 1, x + w - 1, y + 1);
g.drawLine(x + 1, y + 1, x + 1, y + h - 2);
- g.drawLine(x + 1, y + h - 2, x + w - 1, y + h - 2);
if (isFreeStanding)
{
@@ -294,7 +322,14 @@ public class MetalScrollBarUI
else
{
g.setColor(MetalLookAndFeel.getControlDisabled());
- g.drawRect(x, y, w - 1, h - 1);
+ if (isFreeStanding)
+ g.drawRect(x, y, w - 1, h - 1);
+ else
+ {
+ g.drawLine(x, y, x + w - 1, y);
+ g.drawLine(x, y, x, y + h - 1);
+ g.drawLine(x, y + h - 1, x + w - 1, y + h - 1);
+ }
}
}
@@ -310,54 +345,135 @@ public class MetalScrollBarUI
// a disabled scrollbar has no thumb in the metal look and feel
if (!c.isEnabled())
return;
+ if (scrollbar.getOrientation() == HORIZONTAL)
+ paintThumbHorizontal(g, c, thumbBounds);
+ else
+ paintThumbVertical(g, c, thumbBounds);
+
+ // draw the pattern
+ MetalUtils.fillMetalPattern(c, g, thumbBounds.x + 3, thumbBounds.y + 3,
+ thumbBounds.width - 6, thumbBounds.height - 6,
+ thumbHighlightColor, thumbLightShadowColor);
+ }
+
+ /**
+ * Paints the thumb for a horizontal scroll bar.
+ *
+ * @param g the graphics device.
+ * @param c the scroll bar component.
+ * @param thumbBounds the thumb bounds.
+ */
+ private void paintThumbHorizontal(Graphics g, JComponent c,
+ Rectangle thumbBounds)
+ {
+ int x = thumbBounds.x;
+ int y = thumbBounds.y;
+ int w = thumbBounds.width;
+ int h = thumbBounds.height;
// first we fill the background
g.setColor(thumbColor);
- g.fillRect(thumbBounds.x, thumbBounds.y, thumbBounds.width,
- thumbBounds.height);
-
- // draw the outer dark line
- int hAdj = 1;
- int wAdj = 1;
- if (scrollbar.getOrientation() == HORIZONTAL)
- hAdj++;
+ if (isFreeStanding)
+ g.fillRect(x, y, w, h - 1);
else
- wAdj++;
+ g.fillRect(x, y, w, h);
- g.setColor(new Color(102, 102, 153));
- g.drawRect(thumbBounds.x, thumbBounds.y, thumbBounds.width - wAdj,
- thumbBounds.height - hAdj);
-
- // draw the inner light line
+ // then draw the dark box
+ g.setColor(thumbLightShadowColor);
+ if (isFreeStanding)
+ g.drawRect(x, y, w - 1, h - 2);
+ else
+ {
+ g.drawLine(x, y, x + w - 1, y);
+ g.drawLine(x, y, x, y + h - 1);
+ g.drawLine(x + w - 1, y, x + w - 1, y + h -1);
+ }
+
+ // then the highlight
g.setColor(thumbHighlightColor);
- g.drawLine(thumbBounds.x + 1, thumbBounds.y + 1,
- thumbBounds.x + thumbBounds.width - 2,
- thumbBounds.y + 1);
- g.drawLine(thumbBounds.x + 1, thumbBounds.y + 1,
- thumbBounds.x + 1,
- thumbBounds.y + thumbBounds.height - 2);
-
+ if (isFreeStanding)
+ {
+ g.drawLine(x + 1, y + 1, x + w - 3, y + 1);
+ g.drawLine(x + 1, y + 1, x + 1, y + h - 3);
+ }
+ else
+ {
+ g.drawLine(x + 1, y + 1, x + w - 3, y + 1);
+ g.drawLine(x + 1, y + 1, x + 1, y + h - 1);
+ }
+
// draw the shadow line
UIDefaults def = UIManager.getLookAndFeelDefaults();
g.setColor(def.getColor("ScrollBar.shadow"));
- g.drawLine(thumbBounds.x + 1, thumbBounds.y + thumbBounds.height,
- thumbBounds.x + thumbBounds.width,
- thumbBounds.y + thumbBounds.height);
+ g.drawLine(x + w, y + 1, x + w, y + h - 1);
- // draw the pattern
- MetalUtils.fillMetalPattern(g, thumbBounds.x + 3, thumbBounds.y + 3,
- thumbBounds.width - 6, thumbBounds.height - 6,
- thumbHighlightColor, new Color(102, 102, 153));
}
-
+
+ /**
+ * Paints the thumb for a vertical scroll bar.
+ *
+ * @param g the graphics device.
+ * @param c the scroll bar component.
+ * @param thumbBounds the thumb bounds.
+ */
+ private void paintThumbVertical(Graphics g, JComponent c,
+ Rectangle thumbBounds)
+ {
+ int x = thumbBounds.x;
+ int y = thumbBounds.y;
+ int w = thumbBounds.width;
+ int h = thumbBounds.height;
+
+ // first we fill the background
+ g.setColor(thumbColor);
+ if (isFreeStanding)
+ g.fillRect(x, y, w - 1, h);
+ else
+ g.fillRect(x, y, w, h);
+
+ // then draw the dark box
+ g.setColor(thumbLightShadowColor);
+ if (isFreeStanding)
+ g.drawRect(x, y, w - 2, h - 1);
+ else
+ {
+ g.drawLine(x, y, x + w - 1, y);
+ g.drawLine(x, y, x, y + h - 1);
+ g.drawLine(x, y + h - 1, x + w - 1, y + h - 1);
+ }
+
+ // then the highlight
+ g.setColor(thumbHighlightColor);
+ if (isFreeStanding)
+ {
+ g.drawLine(x + 1, y + 1, x + w - 3, y + 1);
+ g.drawLine(x + 1, y + 1, x + 1, y + h - 3);
+ }
+ else
+ {
+ g.drawLine(x + 1, y + 1, x + w - 1, y + 1);
+ g.drawLine(x + 1, y + 1, x + 1, y + h - 3);
+ }
+
+ // draw the shadow line
+ UIDefaults def = UIManager.getLookAndFeelDefaults();
+ g.setColor(def.getColor("ScrollBar.shadow"));
+ g.drawLine(x + 1, y + h, x + w - 2, y + h);
+ }
+
/**
- * This method returns the minimum thumb size.
+ * Returns the minimum thumb size. For a free standing scroll bar the
+ * minimum size is <code>17 x 17</code> pixels, whereas for a non free
+ * standing scroll bar the minimum size is <code>15 x 15</code> pixels.
*
* @return The minimum thumb size.
*/
protected Dimension getMinimumThumbSize()
{
- return MIN_THUMB_SIZE;
+ if (isFreeStanding)
+ return MIN_THUMB_SIZE_FREE_STANDING;
+ else
+ return MIN_THUMB_SIZE;
}
}
diff --git a/javax/swing/plaf/metal/MetalScrollButton.java b/javax/swing/plaf/metal/MetalScrollButton.java
index b9f53dc87..84f9cfe49 100644
--- a/javax/swing/plaf/metal/MetalScrollButton.java
+++ b/javax/swing/plaf/metal/MetalScrollButton.java
@@ -38,6 +38,7 @@ exception statement from your version. */
package javax.swing.plaf.metal;
+import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Rectangle;
@@ -206,13 +207,13 @@ public class MetalScrollButton extends BasicArrowButton
g.drawLine(w - 2, 2, w - 2, h - 1);
g.setColor(MetalLookAndFeel.getControlHighlight());
- g.drawLine(1, 1, 1, h - 1);
- g.drawLine(1, 1, w - 1, 1);
+ g.drawLine(1, 1, 1, h - 2);
+ g.drawLine(1, 1, w - 3, 1);
g.drawLine(w - 1, 1, w - 1, h - 1);
g.setColor(MetalLookAndFeel.getControl());
g.drawLine(1, h - 1, 1, h - 1);
- g.drawLine(w - 1, 1, w - 1, 1);
+ g.drawLine(w - 2, 1, w - 2, 1);
}
else
{
diff --git a/javax/swing/plaf/metal/MetalScrollPaneUI.java b/javax/swing/plaf/metal/MetalScrollPaneUI.java
index 3e1198b39..31fd19d26 100644
--- a/javax/swing/plaf/metal/MetalScrollPaneUI.java
+++ b/javax/swing/plaf/metal/MetalScrollPaneUI.java
@@ -39,9 +39,13 @@ exception statement from your version. */
package javax.swing.plaf.metal;
import javax.swing.JComponent;
+import javax.swing.JScrollPane;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicScrollPaneUI;
+/**
+ * A UI delegate for the {@link JScrollPane} component.
+ */
public class MetalScrollPaneUI
extends BasicScrollPaneUI
{
@@ -51,7 +55,7 @@ public class MetalScrollPaneUI
private static MetalScrollPaneUI instance = null;
/**
- * Constructs a new instance of MetalScrollPaneUI.
+ * Constructs a new instance of <code>MetalScrollPaneUI</code>.
*/
public MetalScrollPaneUI()
{
@@ -59,11 +63,11 @@ public class MetalScrollPaneUI
}
/**
- * Returns an instance of MetalScrollPaneUI.
+ * Returns a shared instance of <code>MetalScrollPaneUI</code>.
*
* @param component the component for which we return an UI instance
*
- * @return an instance of MetalScrollPaneUI
+ * @return A shared instance of <code>MetalScrollPaneUI</code>.
*/
public static ComponentUI createUI(JComponent component)
{
diff --git a/javax/swing/plaf/metal/MetalSeparatorUI.java b/javax/swing/plaf/metal/MetalSeparatorUI.java
index 6e78ccb70..1d48e9be2 100644
--- a/javax/swing/plaf/metal/MetalSeparatorUI.java
+++ b/javax/swing/plaf/metal/MetalSeparatorUI.java
@@ -38,10 +38,20 @@ exception statement from your version. */
package javax.swing.plaf.metal;
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Rectangle;
+
import javax.swing.JComponent;
+import javax.swing.JSeparator;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicSeparatorUI;
+/**
+ * A UI delegate for the {@link JSeparator} component.
+ */
public class MetalSeparatorUI
extends BasicSeparatorUI
{
@@ -51,7 +61,7 @@ public class MetalSeparatorUI
private static MetalSeparatorUI instance = null;
/**
- * Constructs a new instance of MetalSeparatorUI.
+ * Constructs a new instance of <code>MetalSeparatorUI</code>.
*/
public MetalSeparatorUI()
{
@@ -59,11 +69,11 @@ public class MetalSeparatorUI
}
/**
- * Returns an instance of MetalSeparatorUI.
+ * Returns a shared instance of <code>MetalSeparatorUI</code>.
*
* @param component the component for which we return an UI instance
*
- * @return an instance of MetalSeparatorUI
+ * @return A shared instance of <code>MetalSeparatorUI</code>.
*/
public static ComponentUI createUI(JComponent component)
{
@@ -71,4 +81,51 @@ public class MetalSeparatorUI
instance = new MetalSeparatorUI();
return instance;
}
+
+ /**
+ * The separator is made of two lines. The top line will be
+ * the Metal theme color separatorForeground (or left line if it's vertical).
+ * The bottom or right line will be the Metal theme color
+ * separatorBackground.
+ * The two lines will
+ * be centered inside the bounds box. If the separator is horizontal,
+ * then it will be vertically centered, or if it's vertical, it will
+ * be horizontally centered.
+ *
+ * @param g The Graphics object to paint with
+ * @param c The JComponent to paint.
+ */
+ public void paint(Graphics g, JComponent c)
+ {
+ Rectangle r = new Rectangle();
+ SwingUtilities.calculateInnerArea(c, r);
+ Color saved = g.getColor();
+ Color c1 = UIManager.getColor("Separator.foreground");
+ Color c2 = UIManager.getColor("Separator.background");
+ JSeparator s;
+ if (c instanceof JSeparator)
+ s = (JSeparator) c;
+ else
+ return;
+
+ if (s.getOrientation() == JSeparator.HORIZONTAL)
+ {
+ int midAB = r.height / 2;
+ g.setColor(c1);
+ g.drawLine(r.x, r.y + midAB - 1, r.x + r.width, r.y + midAB - 1);
+
+ g.setColor(c2);
+ g.fillRect(r.x, r.y + midAB, r.x + r.width, r.y + midAB);
+ }
+ else
+ {
+ int midAD = r.height / 2 + r.y;
+ g.setColor(c1);
+ g.drawLine(r.x, r.y, r.x, r.y + r.height);
+
+ g.setColor(c2);
+ g.fillRect(r.x + midAD, r.y + r.height, r.x + midAD, r.y + r.height);
+ }
+ g.setColor(saved);
+ }
}
diff --git a/javax/swing/plaf/metal/MetalSliderUI.java b/javax/swing/plaf/metal/MetalSliderUI.java
index bd3212c84..08fb99d21 100644
--- a/javax/swing/plaf/metal/MetalSliderUI.java
+++ b/javax/swing/plaf/metal/MetalSliderUI.java
@@ -56,8 +56,7 @@ import javax.swing.plaf.basic.BasicSliderUI;
/**
* A UI delegate for the {@link JSlider} component.
*/
-public class MetalSliderUI
- extends BasicSliderUI
+public class MetalSliderUI extends BasicSliderUI
{
/**
* A property change handler that updates the rendered component in response
@@ -66,13 +65,14 @@ public class MetalSliderUI
* the {@link MetalLookAndFeel}.
*/
protected class MetalPropertyListener
- extends BasicSliderUI.PropertyChangeHandler
+ extends BasicSliderUI.PropertyChangeHandler
{
/**
* Creates a new listener.
*/
protected MetalPropertyListener()
{
+ // Nothing to do here.
}
/**
@@ -149,11 +149,11 @@ public class MetalSliderUI
}
/**
- * Returns an instance of MetalSliderUI.
+ * Returns a new instance of <code>MetalSliderUI</code>.
*
* @param component the component (ignored).
*
- * @return an instance of MetalSliderUI
+ * @return A new instance of <code>MetalSliderUI</code>.
*/
public static ComponentUI createUI(JComponent component)
{
diff --git a/javax/swing/plaf/metal/MetalSplitPaneDivider.java b/javax/swing/plaf/metal/MetalSplitPaneDivider.java
index 60e9c0559..016e09557 100644
--- a/javax/swing/plaf/metal/MetalSplitPaneDivider.java
+++ b/javax/swing/plaf/metal/MetalSplitPaneDivider.java
@@ -78,7 +78,7 @@ class MetalSplitPaneDivider extends BasicSplitPaneDivider
{
//super.paint(g);
Dimension s = getSize();
- MetalUtils.fillMetalPattern(g, 2, 2, s.width - 4, s.height - 4,
+ MetalUtils.fillMetalPattern(splitPane, g, 2, 2, s.width - 4, s.height - 4,
light, dark);
}
}
diff --git a/javax/swing/plaf/metal/MetalSplitPaneUI.java b/javax/swing/plaf/metal/MetalSplitPaneUI.java
index b7ea8984b..b39fb2336 100644
--- a/javax/swing/plaf/metal/MetalSplitPaneUI.java
+++ b/javax/swing/plaf/metal/MetalSplitPaneUI.java
@@ -39,24 +39,22 @@ exception statement from your version. */
package javax.swing.plaf.metal;
import java.awt.Color;
-import java.util.HashMap;
import javax.swing.JComponent;
+import javax.swing.JSplitPane;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
-import javax.swing.plaf.basic.BasicSplitPaneUI;
import javax.swing.plaf.basic.BasicSplitPaneDivider;
+import javax.swing.plaf.basic.BasicSplitPaneUI;
-public class MetalSplitPaneUI
- extends BasicSplitPaneUI
+/**
+ * A UI delegate for the {@link JSplitPane} component.
+ */
+public class MetalSplitPaneUI extends BasicSplitPaneUI
{
-
- /** The UI instances for MetalSplitPaneUIs */
- private static HashMap instances;
-
/**
- * Constructs a new instance of MetalSplitPaneUI.
+ * Constructs a new instance of <code>MetalSplitPaneUI</code>.
*/
public MetalSplitPaneUI()
{
@@ -64,28 +62,15 @@ public class MetalSplitPaneUI
}
/**
- * Returns an instance of MetalSplitPaneUI.
+ * Returns a new instance of <code>MetalSplitPaneUI</code>.
*
* @param component the component for which we return an UI instance
*
- * @return an instance of MetalSplitPaneUI
+ * @return A new instance of <code>MetalSplitPaneUI</code>.
*/
public static ComponentUI createUI(JComponent component)
{
- if (instances == null)
- instances = new HashMap();
-
- Object o = instances.get(component);
- MetalSplitPaneUI instance;
- if (o == null)
- {
- instance = new MetalSplitPaneUI();
- instances.put(component, instance);
- }
- else
- instance = (MetalSplitPaneUI) o;
-
- return instance;
+ return new MetalSplitPaneUI();
}
/**
diff --git a/javax/swing/plaf/metal/MetalTabbedPaneUI.java b/javax/swing/plaf/metal/MetalTabbedPaneUI.java
index 1b5fe144f..68aeaaf7c 100644
--- a/javax/swing/plaf/metal/MetalTabbedPaneUI.java
+++ b/javax/swing/plaf/metal/MetalTabbedPaneUI.java
@@ -40,7 +40,6 @@ package javax.swing.plaf.metal;
import java.awt.Graphics;
import java.awt.LayoutManager;
-import java.util.HashMap;
import javax.swing.JComponent;
import javax.swing.JTabbedPane;
@@ -48,11 +47,9 @@ import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicTabbedPaneUI;
/**
- * A UI delegate used for the {@link JTabbedPane} component in the
- * {@link MetalLookAndFeel}.
+ * A UI delegate for the {@link JTabbedPane} component.
*/
-public class MetalTabbedPaneUI
- extends BasicTabbedPaneUI
+public class MetalTabbedPaneUI extends BasicTabbedPaneUI
{
/**
@@ -65,13 +62,14 @@ public class MetalTabbedPaneUI
* public for compatibility.
*/
public class TabbedPaneLayout
- extends BasicTabbedPaneUI.TabbedPaneLayout
+ extends BasicTabbedPaneUI.TabbedPaneLayout
{
/**
* Creates a new instance of the layout manager.
*/
public TabbedPaneLayout()
{
+ // Nothing to do here.
}
/**
@@ -102,9 +100,6 @@ public class MetalTabbedPaneUI
}
}
- /** The shared UI instance for JTabbedPanes. */
- private static HashMap instances = null;
-
/**
* Constructs a new instance of MetalTabbedPaneUI.
*/
@@ -122,20 +117,7 @@ public class MetalTabbedPaneUI
*/
public static ComponentUI createUI(JComponent component)
{
- if (instances == null)
- instances = new HashMap();
-
- Object o = instances.get(component);
- MetalTabbedPaneUI instance;
- if (o == null)
- {
- instance = new MetalTabbedPaneUI();
- instances.put(component, instance);
- }
- else
- instance = (MetalTabbedPaneUI) o;
-
- return instance;
+ return new MetalTabbedPaneUI();
}
/**
diff --git a/javax/swing/plaf/metal/MetalTextFieldUI.java b/javax/swing/plaf/metal/MetalTextFieldUI.java
index d6e50e122..6984daecc 100644
--- a/javax/swing/plaf/metal/MetalTextFieldUI.java
+++ b/javax/swing/plaf/metal/MetalTextFieldUI.java
@@ -38,19 +38,16 @@ exception statement from your version. */
package javax.swing.plaf.metal;
-import java.util.HashMap;
-
import javax.swing.JComponent;
+import javax.swing.JTextField;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicTextFieldUI;
-public class MetalTextFieldUI
- extends BasicTextFieldUI
+/**
+ * A UI delegate for the {@link JTextField} component.
+ */
+public class MetalTextFieldUI extends BasicTextFieldUI
{
-
- /** The UI instances for MetalTextFieldUIs */
- private static HashMap instances = null;
-
/**
* Constructs a new instance of MetalTextFieldUI.
*/
@@ -60,27 +57,14 @@ public class MetalTextFieldUI
}
/**
- * Returns an instance of MetalTextFieldUI.
+ * Returns a new instance of <code>MetalTextFieldUI</code>.
*
* @param component the component for which we return an UI instance
*
- * @return an instance of MetalTextFieldUI
+ * @return A new instance of <code>MetalTextFieldUI</code>.
*/
public static ComponentUI createUI(JComponent component)
{
- if (instances == null)
- instances = new HashMap();
-
- Object o = instances.get(component);
- MetalTextFieldUI instance;
- if (o == null)
- {
- instance = new MetalTextFieldUI();
- instances.put(component, instance);
- }
- else
- instance = (MetalTextFieldUI) o;
-
- return instance;
+ return new MetalTextFieldUI();
}
}
diff --git a/javax/swing/plaf/metal/MetalToggleButtonUI.java b/javax/swing/plaf/metal/MetalToggleButtonUI.java
index 5079562e8..46a19bdbe 100644
--- a/javax/swing/plaf/metal/MetalToggleButtonUI.java
+++ b/javax/swing/plaf/metal/MetalToggleButtonUI.java
@@ -55,7 +55,7 @@ import javax.swing.plaf.basic.BasicButtonUI;
import javax.swing.plaf.basic.BasicToggleButtonUI;
/**
- * A UI delegate for {@link JToggleButton} components.
+ * A UI delegate for the {@link JToggleButton} component.
*/
public class MetalToggleButtonUI
extends BasicToggleButtonUI
@@ -71,11 +71,11 @@ public class MetalToggleButtonUI
protected Color disabledTextColor;
/**
- * Returns an instance of MetalToggleButtonUI.
+ * Returns a new instance of <code>MetalToggleButtonUI</code>.
*
* @param component the component for which we return an UI instance
*
- * @return an instance of MetalToggleButtonUI
+ * @return A new instance of <code>MetalToggleButtonUI</code>.
*/
public static ComponentUI createUI(JComponent component)
{
@@ -83,15 +83,11 @@ public class MetalToggleButtonUI
}
/**
- * Constructs a new instance of MetalToggleButtonUI.
+ * Constructs a new instance of <code>MetalToggleButtonUI</code>.
*/
public MetalToggleButtonUI()
{
super();
- UIDefaults defaults = UIManager.getLookAndFeelDefaults();
- focusColor = defaults.getColor(getPropertyPrefix() + "focus");
- selectColor = defaults.getColor(getPropertyPrefix() + "select");
- disabledTextColor = defaults.getColor(getPropertyPrefix() + "disabledText");
}
/**
@@ -115,9 +111,12 @@ public class MetalToggleButtonUI
}
/**
- * Returns the color for the text label of disabled buttons.
+ * Returns the color for the text label of disabled buttons. The value
+ * is initialised in the {@link #installDefaults(AbstractButton)} method
+ * by reading the <code>ToggleButton.disabledText</code> item from the UI
+ * defaults.
*
- * @return the color for the text label of disabled buttons
+ * @return The color for the text label of disabled buttons.
*/
protected Color getDisabledTextColor()
{
@@ -131,9 +130,11 @@ public class MetalToggleButtonUI
*/
public void installDefaults(AbstractButton b)
{
- // FIXME: for now, this override just changes the visibility of the method
- // in the super-class, to satisfy japi...but there must be something else.
super.installDefaults(b);
+ UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+ focusColor = defaults.getColor(getPropertyPrefix() + "focus");
+ selectColor = defaults.getColor(getPropertyPrefix() + "select");
+ disabledTextColor = defaults.getColor(getPropertyPrefix() + "disabledText");
}
/**
@@ -144,11 +145,14 @@ public class MetalToggleButtonUI
*/
protected void paintButtonPressed(Graphics g, AbstractButton b)
{
- Color saved = g.getColor();
- Rectangle bounds = SwingUtilities.getLocalBounds(b);
- g.setColor(selectColor);
- g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);
- g.setColor(saved);
+ if (b.isContentAreaFilled() && b.isOpaque())
+ {
+ Color saved = g.getColor();
+ Rectangle bounds = SwingUtilities.getLocalBounds(b);
+ g.setColor(selectColor);
+ g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);
+ g.setColor(saved);
+ }
}
/**
diff --git a/javax/swing/plaf/metal/MetalToolBarUI.java b/javax/swing/plaf/metal/MetalToolBarUI.java
index 39af0011a..c5ca91399 100644
--- a/javax/swing/plaf/metal/MetalToolBarUI.java
+++ b/javax/swing/plaf/metal/MetalToolBarUI.java
@@ -38,20 +38,73 @@ exception statement from your version. */
package javax.swing.plaf.metal;
+import java.awt.event.ContainerListener;
+import java.beans.PropertyChangeListener;
+
import javax.swing.JComponent;
+import javax.swing.JToolBar;
+import javax.swing.border.Border;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicToolBarUI;
-public class MetalToolBarUI
- extends BasicToolBarUI
+/**
+ * A UI delegate for the {@link JToolBar} component.
+ */
+public class MetalToolBarUI extends BasicToolBarUI
{
+
+ /**
+ * A listener (no longer used) that responds when components are added to or
+ * removed from the {@link JToolBar}. The required behaviour is now
+ * handled in the super class.
+ *
+ * @see MetalToolBarUI#createContainerListener()
+ */
+ protected class MetalContainerListener
+ extends BasicToolBarUI.ToolBarContListener
+ {
+ /**
+ * Creates a new instance.
+ */
+ protected MetalContainerListener()
+ {
+ // Nothing to do here.
+ }
+ }
- // FIXME: maybe replace by a Map of instances when this becomes stateful
- /** The shared UI instance for MetalToolBarUIs */
- private static MetalToolBarUI instance = null;
+ /**
+ * A listener (no longer used) that responds to property change events in a
+ * {@link JToolBar} component. The required behaviour is now handled in the
+ * super class.
+ *
+ * @see MetalToolBarUI#createRolloverListener()
+ */
+ protected class MetalRolloverListener
+ extends BasicToolBarUI.PropertyListener
+ {
+ /**
+ * Creates a new instance.
+ */
+ protected MetalRolloverListener()
+ {
+ // Nothing to do here.
+ }
+ }
+
+ /**
+ * The container listener (an implementation specific field, according to the
+ * spec, and not used in GNU Classpath).
+ */
+ protected ContainerListener contListener;
+
+ /**
+ * The rollover listener (an implementation specific field, according to the
+ * spec, and not used in GNU Classpath).
+ */
+ protected PropertyChangeListener rolloverListener;
/**
- * Constructs a new instance of MetalToolBarUI.
+ * Creates a new instance of this UI delegate.
*/
public MetalToolBarUI()
{
@@ -59,16 +112,51 @@ public class MetalToolBarUI
}
/**
- * Returns an instance of MetalToolBarUI.
+ * Returns a new instance of <code>MetalToolBarUI</code>.
*
- * @param component the component for which we return an UI instance
+ * @param component the component for which we return an UI instance
*
- * @return an instance of MetalToolBarUI
+ * @return A new instance of <code>MetalToolBarUI</code>.
*/
public static ComponentUI createUI(JComponent component)
{
- if (instance == null)
- instance = new MetalToolBarUI();
- return instance;
+ return new MetalToolBarUI();
+ }
+
+ /**
+ * Returns <code>null</code> as permitted by recent versions of the API
+ * specification. Originally it seems this method returned a new instance of
+ * {@link MetalRolloverListener}, but this is now redundant.
+ *
+ * @return <code>null</code>.
+ */
+ protected PropertyChangeListener createRolloverListener()
+ {
+ return null;
+ }
+
+ /**
+ * Returns <code>null</code> as permitted by recent versions of the API
+ * specification. Originally it seems this method returned a new instance of
+ * {@link MetalContainerListener}, but this is now redundant.
+ *
+ * @return <code>null</code>.
+ */
+ protected ContainerListener createContainerListener()
+ {
+ return null;
+ }
+
+ /**
+ * Returns a border with no rollover effect for buttons in the tool bar.
+ *
+ * @return A border.
+ *
+ * @see MetalBorders#getToolbarButtonBorder()
+ */
+ protected Border createNonRolloverBorder()
+ {
+ return MetalBorders.getToolbarButtonBorder();
}
+
}
diff --git a/javax/swing/plaf/metal/MetalToolTipUI.java b/javax/swing/plaf/metal/MetalToolTipUI.java
index c88b6534a..5085d170a 100644
--- a/javax/swing/plaf/metal/MetalToolTipUI.java
+++ b/javax/swing/plaf/metal/MetalToolTipUI.java
@@ -38,32 +38,92 @@ exception statement from your version. */
package javax.swing.plaf.metal;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Insets;
+import java.awt.Rectangle;
+import java.awt.Toolkit;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+
+import javax.swing.AbstractButton;
import javax.swing.JComponent;
+import javax.swing.JMenuItem;
+import javax.swing.JToolTip;
+import javax.swing.KeyStroke;
+import javax.swing.SwingConstants;
+import javax.swing.SwingUtilities;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
+import javax.swing.border.Border;
import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.UIResource;
import javax.swing.plaf.basic.BasicToolTipUI;
+/**
+ * A UI delegate for the {@link JToolTip} component.
+ */
public class MetalToolTipUI
extends BasicToolTipUI
{
+ /**
+ * The amount of space between the tool tip text and the accelerator
+ * description (if visible).
+ */
+ public static final int padSpaceBetweenStrings = 12;
- // FIXME: maybe replace by a Map of instances when this becomes stateful
- /** The shared UI instance for MetalToolTipUIs */
+ /** The shared UI instance. */
private static MetalToolTipUI instance = null;
-
+
+ /** A flag controlling the visibility of the accelerator (if there is one). */
+ private boolean isAcceleratorHidden;
+
+ /** A string representing the accelerator key for the component. */
+ private String acceleratorString;
+
+ /**
+ * The delimiter for the accelerator string.
+ */
+ private String acceleratorDelimiter;
+
+ /** The font for the accelerator string. */
+ private Font acceleratorFont;
+
+ /** The color for the accelerator string. */
+ private Color acceleratorForeground;
+
+ /** The active border. */
+ private Border activeBorder;
+
+ /** The inactive border. */
+ private Border inactiveBorder;
+
/**
- * Constructs a new instance of MetalToolTipUI.
+ * Constructs a new instance of <code>MetalToolTipUI</code>.
*/
public MetalToolTipUI()
{
super();
+ UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+ activeBorder = defaults.getBorder("ToolTip.border");
+ inactiveBorder = defaults.getBorder("ToolTip.borderInactive");
+ isAcceleratorHidden = defaults.getBoolean("ToolTip.hideAccelerator");
+ acceleratorFont = defaults.getFont("MenuItem.acceleratorFont");
+ acceleratorForeground = defaults.getColor("MenuItem.acceleratorForeground");
+ acceleratorDelimiter = defaults.getString("MenuItem.acceleratorDelimiter");
}
/**
- * Returns an instance of MetalToolTipUI.
+ * Returns a shared instance of the <code>MetalToolTipUI</code> class.
+ * Although this UI delegate does maintain state information, there is never
+ * more than one tool tip visible, so it is OK to use a shared instance.
*
- * @param component the component for which we return an UI instance
+ * @param component the component (a {@link JToolTip}).
*
- * @return an instance of MetalToolTipUI
+ * @return A shared instance of the <code>MetalToolTipUI</code> class.
*/
public static ComponentUI createUI(JComponent component)
{
@@ -71,4 +131,202 @@ public class MetalToolTipUI
instance = new MetalToolTipUI();
return instance;
}
+
+ /**
+ * Returns a string representing the accelerator key (if there is one) for
+ * the component that the tool tip belongs to.
+ *
+ * @return A string representing the accelerator key.
+ */
+ public String getAcceleratorString()
+ {
+ return acceleratorString;
+ }
+
+ /**
+ * Installs the UI for the specified component (a {@link JToolTip}).
+ *
+ * @param c the {@link JToolTip} component.
+ */
+ public void installUI(JComponent c)
+ {
+ super.installUI(c);
+ Border existingBorder = c.getBorder();
+ if (existingBorder == null || existingBorder instanceof UIResource)
+ {
+ if (c.isEnabled())
+ c.setBorder(activeBorder);
+ else
+ c.setBorder(inactiveBorder);
+ }
+ }
+
+ /**
+ * Clears the defaults set in {@link #installUI(JComponent)}.
+ *
+ * @param c the component.
+ */
+ public void uninstallUI(JComponent c)
+ {
+ super.uninstallUI(c);
+ if (c.getBorder() instanceof UIResource)
+ c.setBorder(null);
+ }
+
+ /**
+ * Returns <code>true</code> if the accelerator string is hidden, and
+ * <code>false</code> otherwise. This setting is controlled by the
+ * <code>ToolTip.hideAccelerator</code> entry in the UI defaults table.
+ *
+ * @return A boolean.
+ */
+ protected boolean isAcceleratorHidden()
+ {
+ return isAcceleratorHidden;
+ }
+
+ /**
+ * Returns the preferred size for the {@link JToolTip} component.
+ *
+ * @param c the component (a {@link JToolTip}).
+ *
+ * @return The preferred size.
+ */
+ public Dimension getPreferredSize(JComponent c)
+ {
+ if (isAcceleratorHidden())
+ return super.getPreferredSize(c);
+ else
+ {
+ Insets insets = c.getInsets();
+ JToolTip tt = (JToolTip) c;
+ String tipText = tt.getTipText();
+ if (tipText != null)
+ {
+ FontMetrics fm = c.getFontMetrics(c.getFont());
+ int prefH = fm.getHeight() + insets.top + insets.bottom;
+ int prefW = fm.stringWidth(tipText) + insets.left + insets.right;
+
+ // this seems to be the first opportunity we have to get the
+ // accelerator string from the component (if it has one)
+ acceleratorString = fetchAcceleratorString(c);
+ if (acceleratorString != null)
+ {
+ prefW += padSpaceBetweenStrings;
+ fm = c.getFontMetrics(acceleratorFont);
+ prefW += fm.stringWidth(acceleratorString);
+ }
+ return new Dimension(prefW, prefH);
+ }
+ else return new Dimension(0, 0);
+ }
+ }
+
+ /**
+ * Paints the tool tip.
+ *
+ * @param g the graphics context.
+ * @param c the {@link JToolTip} component.
+ */
+ public void paint(Graphics g, JComponent c)
+ {
+ JToolTip tip = (JToolTip) c;
+
+ String text = tip.getTipText();
+ Toolkit t = tip.getToolkit();
+ if (text == null)
+ return;
+
+ Rectangle vr = new Rectangle();
+ vr = SwingUtilities.calculateInnerArea(tip, vr);
+ Rectangle ir = new Rectangle();
+ Rectangle tr = new Rectangle();
+ FontMetrics fm = t.getFontMetrics(tip.getFont());
+ int ascent = fm.getAscent();
+ SwingUtilities.layoutCompoundLabel(tip, fm, text, null,
+ SwingConstants.CENTER, SwingConstants.LEFT,
+ SwingConstants.CENTER, SwingConstants.CENTER, vr, ir, tr, 0);
+ Color saved = g.getColor();
+ g.setColor(Color.BLACK);
+
+ g.drawString(text, vr.x, vr.y + ascent);
+
+ // paint accelerator
+ if (acceleratorString != null)
+ {
+ g.setFont(acceleratorFont);
+ g.setColor(acceleratorForeground);
+ fm = t.getFontMetrics(acceleratorFont);
+ int width = fm.stringWidth(acceleratorString);
+ g.drawString(acceleratorString, vr.x + vr.width - width - padSpaceBetweenStrings/2,
+ vr.y + vr.height - fm.getDescent());
+ }
+
+ g.setColor(saved);
+ }
+
+ /**
+ * Returns a string representing the accelerator for the component, or
+ * <code>null</code> if the component has no accelerator.
+ *
+ * @param c the component.
+ *
+ * @return A string representing the accelerator (possibly
+ * <code>null</code>).
+ */
+ private String fetchAcceleratorString(JComponent c)
+ {
+ String result = null;
+ if (c instanceof JToolTip)
+ {
+ JToolTip toolTip = (JToolTip) c;
+ JComponent component = toolTip.getComponent();
+ KeyStroke ks = null;
+ int mne = 0;
+ if (component instanceof JMenuItem)
+ {
+ JMenuItem item = (JMenuItem) component;
+ ks = item.getAccelerator();
+ if (ks == null)
+ mne = item.getMnemonic();
+ }
+ else if (component instanceof AbstractButton)
+ {
+ AbstractButton button = (AbstractButton) component;
+ mne = button.getMnemonic();
+ }
+ if (mne > 0)
+ ks = KeyStroke.getKeyStroke(Character.toUpperCase((char) mne),
+ InputEvent.ALT_MASK, false);
+ if (ks != null)
+ result = acceleratorToString(ks);
+ }
+ return result;
+ }
+
+ /**
+ * Returns a string representing an accelerator.
+ *
+ * @param accelerator the accelerator (<code>null</code> not permitted).
+ *
+ * @return A string representing an accelerator.
+ */
+ private String acceleratorToString(KeyStroke accelerator)
+ {
+ // convert keystroke into string format
+ String modifiersText = "";
+ int modifiers = accelerator.getModifiers();
+ char keyChar = accelerator.getKeyChar();
+ int keyCode = accelerator.getKeyCode();
+
+ if (modifiers != 0)
+ modifiersText = KeyEvent.getKeyModifiersText(modifiers)
+ + acceleratorDelimiter;
+
+ if (keyCode == KeyEvent.VK_UNDEFINED)
+ return modifiersText + keyChar;
+ else
+ return modifiersText + KeyEvent.getKeyText(keyCode);
+ }
+
}
diff --git a/javax/swing/plaf/metal/MetalTreeUI.java b/javax/swing/plaf/metal/MetalTreeUI.java
index a5ca3fe11..0ffa0d174 100644
--- a/javax/swing/plaf/metal/MetalTreeUI.java
+++ b/javax/swing/plaf/metal/MetalTreeUI.java
@@ -44,8 +44,8 @@ import java.awt.Rectangle;
import java.awt.event.ComponentListener;
import java.awt.event.FocusListener;
import java.awt.event.KeyListener;
+import java.awt.event.MouseListener;
import java.beans.PropertyChangeListener;
-import java.util.HashMap;
import java.util.Hashtable;
import javax.swing.JComponent;
@@ -56,23 +56,23 @@ import javax.swing.tree.TreeCellEditor;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
import javax.swing.event.CellEditorListener;
-import javax.swing.event.MouseInputListener;
import javax.swing.event.TreeExpansionListener;
import javax.swing.event.TreeModelListener;
import javax.swing.event.TreeSelectionListener;
-
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicTreeUI;
-public class MetalTreeUI
- extends BasicTreeUI
+/**
+ * A UI delegate for the {@link JTree} component.
+ */
+public class MetalTreeUI extends BasicTreeUI
{
/** Listeners */
private PropertyChangeListener propertyChangeListener;
private FocusListener focusListener;
private TreeSelectionListener treeSelectionListener;
- private MouseInputListener mouseInputListener;
+ private MouseListener mouseListener;
private KeyListener keyListener;
private PropertyChangeListener selectionModelPropertyChangeListener;
private ComponentListener componentListener;
@@ -80,11 +80,8 @@ public class MetalTreeUI
private TreeExpansionListener treeExpansionListener;
private TreeModelListener treeModelListener;
- /** The UI instances for MetalTreeUIs */
- private static HashMap instances = null;
-
/**
- * Constructs a new instance of MetalTreeUI.
+ * Constructs a new instance of <code>MetalTreeUI</code>.
*/
public MetalTreeUI()
{
@@ -92,28 +89,15 @@ public class MetalTreeUI
}
/**
- * Returns an instance of MetalTreeUI.
+ * Returns a new instance of <code>MetalTreeUI</code>.
*
* @param component the component for which we return an UI instance
*
- * @return an instance of MetalTreeUI
+ * @return A new instance of <code>MetalTreeUI</code>.
*/
public static ComponentUI createUI(JComponent component)
{
- if (instances == null)
- instances = new HashMap();
-
- Object o = instances.get(component);
- MetalTreeUI instance;
- if (o == null)
- {
- instance = new MetalTreeUI();
- instances.put(component, instance);
- }
- else
- instance = (MetalTreeUI) o;
-
- return instance;
+ return new MetalTreeUI();
}
/**
@@ -156,6 +140,7 @@ public class MetalTreeUI
rightChildIndent = defaults.getInt("Tree.rightChildIndent");
leftChildIndent = defaults.getInt("Tree.leftChildIndent");
setRowHeight(defaults.getInt("Tree.rowHeight"));
+ tree.setRowHeight(defaults.getInt("Tree.rowHeight"));
tree.requestFocusInWindow(false);
setExpandedIcon(defaults.getIcon("Tree.expandedIcon"));
@@ -168,9 +153,7 @@ public class MetalTreeUI
createdCellEditor = true;
TreeModel mod = tree.getModel();
setModel(mod);
- tree.setRootVisible(true);
- if (mod != null)
- tree.expandPath(new TreePath(mod.getRoot()));
+
treeSelectionModel = tree.getSelectionModel();
drawingCache = new Hashtable();
nodeDimensions = createNodeDimensions();
@@ -178,7 +161,7 @@ public class MetalTreeUI
propertyChangeListener = createPropertyChangeListener();
focusListener = createFocusListener();
treeSelectionListener = createTreeSelectionListener();
- mouseInputListener = new MouseInputHandler(null, null, null);
+ mouseListener = createMouseListener();
keyListener = createKeyListener();
selectionModelPropertyChangeListener = createSelectionModelPropertyChangeListener();
componentListener = createComponentListener();
@@ -194,7 +177,7 @@ public class MetalTreeUI
tree.addPropertyChangeListener(propertyChangeListener);
tree.addFocusListener(focusListener);
tree.addTreeSelectionListener(treeSelectionListener);
- tree.addMouseListener(mouseInputListener);
+ tree.addMouseListener(mouseListener);
tree.addKeyListener(keyListener);
tree.addPropertyChangeListener(selectionModelPropertyChangeListener);
tree.addComponentListener(componentListener);
@@ -202,6 +185,13 @@ public class MetalTreeUI
if (treeModel != null)
treeModel.addTreeModelListener(treeModelListener);
+ if (mod != null)
+ {
+ TreePath path = new TreePath(mod.getRoot());
+ if (!tree.isExpanded(path))
+ toggleExpandState(path);
+ }
+
completeUIInstall();
}
@@ -231,7 +221,7 @@ public class MetalTreeUI
tree.removePropertyChangeListener(propertyChangeListener);
tree.removeFocusListener(focusListener);
tree.removeTreeSelectionListener(treeSelectionListener);
- tree.removeMouseListener(mouseInputListener);
+ tree.removeMouseListener(mouseListener);
tree.removeKeyListener(keyListener);
tree.removePropertyChangeListener(selectionModelPropertyChangeListener);
tree.removeComponentListener(componentListener);
diff --git a/javax/swing/plaf/metal/MetalUtils.java b/javax/swing/plaf/metal/MetalUtils.java
index 6480365f8..991518d11 100644
--- a/javax/swing/plaf/metal/MetalUtils.java
+++ b/javax/swing/plaf/metal/MetalUtils.java
@@ -38,7 +38,12 @@ exception statement from your version. */
package javax.swing.plaf.metal;
import java.awt.Color;
+import java.awt.Component;
import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.TexturePaint;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
/**
* Some utility and helper methods for the Metal Look &amp; Feel.
@@ -49,6 +54,21 @@ class MetalUtils
{
/**
+ * The typical metal pattern for use with Graphics2D.
+ */
+ static BufferedImage pattern2D;
+
+ /**
+ * The light color to draw the pattern.
+ */
+ static Color lightColor;
+
+ /**
+ * The dark color to draw to draw the pattern.
+ */
+ static Color darkColor;
+
+ /**
* Fills a rectangle with the typical Metal pattern.
*
* @param g the <code>Graphics</code> context to use
@@ -61,27 +81,74 @@ class MetalUtils
* @param light the light color to use
* @param dark the dark color to use
*/
- static void fillMetalPattern(Graphics g, int x, int y, int w, int h,
+ static void fillMetalPattern(Component c, Graphics g, int x, int y, int w, int h,
Color light, Color dark)
{
- int xOff = 0;
- for (int mY = y; mY < (y + h); mY++)
+ if (g instanceof Graphics2D)
+ fillMetalPattern2D((Graphics2D) g, x, y, w, h, light, dark);
+ else
{
- // set color alternating with every line
- if (((mY - y) % 2) == 0)
- g.setColor(light);
- else
- g.setColor(dark);
-
- for (int mX = x + (xOff); mX < (x + w); mX += 4)
+ int xOff = 0;
+ for (int mY = y; mY < (y + h); mY++)
{
- g.drawLine(mX, mY, mX, mY);
+ // set color alternating with every line
+ if (((mY - y) % 2) == 0)
+ g.setColor(light);
+ else
+ g.setColor(dark);
+
+ for (int mX = x + (xOff); mX < (x + w); mX += 4)
+ {
+ g.drawLine(mX, mY, mX, mY);
+ }
+
+ // increase x offset
+ xOff++;
+ if (xOff > 3)
+ xOff = 0;
}
+ }
+ }
- // increase x offset
- xOff++;
- if (xOff > 3)
- xOff = 0;
- }
+ /**
+ * Fills a rectangle with the typical Metal pattern using Java2D.
+ *
+ * @param g2d the <code>Graphics2D</code> context to use
+ * @param x the X coordinate of the upper left corner of the rectangle to
+ * fill
+ * @param y the Y coordinate of the upper left corner of the rectangle to
+ * fill
+ * @param w the width of the rectangle to fill
+ * @param h the height of the rectangle to fill
+ */
+ static void fillMetalPattern2D(Graphics2D g2d, int x, int y, int w, int h,
+ Color light, Color dark)
+ {
+ if (pattern2D == null || !darkColor.equals(dark) || !lightColor.equals(light))
+ initializePattern(light, dark);
+
+ // Prepare the texture.
+ TexturePaint texture =
+ new TexturePaint(pattern2D, new Rectangle2D.Double(0., 0., 4., 2.));
+ g2d.setPaint(texture);
+ g2d.fillRect(x, y, w, h);
+ }
+
+ /**
+ * Initializes the pattern image.
+ */
+ static void initializePattern(Color light, Color dark)
+ {
+ pattern2D = new BufferedImage(4, 4, BufferedImage.TYPE_INT_RGB);
+ lightColor = light;
+ darkColor = dark;
+ Graphics g = pattern2D.getGraphics();
+ g.setColor(light);
+ g.fillRect(0, 0, 1, 1);
+ g.fillRect(2, 2, 1, 1);
+ g.setColor(dark);
+ g.fillRect(1, 1, 1, 1);
+ g.fillRect(3, 3, 1, 1);
+ g.dispose();
}
}
diff --git a/javax/swing/plaf/metal/OceanTheme.java b/javax/swing/plaf/metal/OceanTheme.java
index 3a837cb5a..85a8cb1ff 100644
--- a/javax/swing/plaf/metal/OceanTheme.java
+++ b/javax/swing/plaf/metal/OceanTheme.java
@@ -37,6 +37,7 @@ exception statement from your version. */
package javax.swing.plaf.metal;
+import javax.swing.UIDefaults;
import javax.swing.plaf.ColorUIResource;
/**
@@ -195,4 +196,14 @@ public class OceanTheme extends DefaultMetalTheme
{
return SECONDARY3;
}
+
+ /**
+ * Adds customized entries to the UIDefaults table.
+ *
+ * @param defaults the UI defaults table
+ */
+ public void addCustomEntriesToTable(UIDefaults defaults)
+ {
+ defaults.put("Button.rollover", Boolean.TRUE);
+ }
}
diff --git a/javax/swing/plaf/metal/package.html b/javax/swing/plaf/metal/package.html
index 2ea787bb5..8675493b6 100644
--- a/javax/swing/plaf/metal/package.html
+++ b/javax/swing/plaf/metal/package.html
@@ -40,7 +40,16 @@ exception statement from your version. -->
<head><title>GNU Classpath - javax.swing.plaf.metal</title></head>
<body>
-<p>Provides a cross-platform look and feel known as "Metal".</p>
-
+<p>Provides a cross-platform look and feel known as "Metal". To install this
+look and feel, add the following code (or something similar)
+near the start of your application:</p>
+<pre>try
+ {
+&nbsp;&nbsp;UIManager.setLookAndFeel(new MetalLookAndFeel());
+ }
+catch (UnsupportedLookAndFeelException e)
+ {
+&nbsp;&nbsp;e.printStackTrace();
+ }</pre>
</body>
</html>
diff --git a/javax/swing/plaf/multi/MultiLookAndFeel.java b/javax/swing/plaf/multi/MultiLookAndFeel.java
index a70a8ff69..2bd358dd0 100644
--- a/javax/swing/plaf/multi/MultiLookAndFeel.java
+++ b/javax/swing/plaf/multi/MultiLookAndFeel.java
@@ -56,6 +56,7 @@ public class MultiLookAndFeel extends LookAndFeel {
*/
public MultiLookAndFeel()
{
+ // Nothing to do here.
}
/**
diff --git a/javax/swing/table/DefaultTableCellRenderer.java b/javax/swing/table/DefaultTableCellRenderer.java
index 349f4baad..ef80a7e22 100644
--- a/javax/swing/table/DefaultTableCellRenderer.java
+++ b/javax/swing/table/DefaultTableCellRenderer.java
@@ -43,8 +43,10 @@ import java.awt.Component;
import java.awt.Rectangle;
import java.io.Serializable;
+import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JTable;
+import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.JTextField;
@@ -64,6 +66,7 @@ public class DefaultTableCellRenderer extends JLabel
{
public UIResource()
{
+ super();
}
}
@@ -145,9 +148,17 @@ public class DefaultTableCellRenderer extends JLabel
setBackground(table.getBackground());
setForeground(table.getForeground());
}
+ if (hasFocus)
+ {
+ setBackground(table.getBackground());
+ setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
+ }
+ else
+ setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
setEnabled(table.isEnabled());
setFont(table.getFont());
+
return this;
}
diff --git a/javax/swing/table/JTableHeader.java b/javax/swing/table/JTableHeader.java
index 45586da20..163509a45 100644
--- a/javax/swing/table/JTableHeader.java
+++ b/javax/swing/table/JTableHeader.java
@@ -61,9 +61,14 @@ import javax.accessibility.AccessibleValue;
import javax.swing.JComponent;
import javax.swing.JTable;
import javax.swing.UIManager;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.TableColumnModelEvent;
+import javax.swing.event.TableColumnModelListener;
import javax.swing.plaf.TableHeaderUI;
public class JTableHeader extends JComponent
+ implements TableColumnModelListener, Accessible
{
protected class AccessibleJTableHeader extends AccessibleJComponent
{
@@ -305,11 +310,6 @@ public class JTableHeader extends JComponent
private static final long serialVersionUID = 5144633983372967710L;
/**
- * The accessibleContext property.
- */
- AccessibleContext accessibleContext;
-
- /**
* The columnModel property.
*/
protected TableColumnModel columnModel;
@@ -373,17 +373,8 @@ public class JTableHeader extends JComponent
*/
public JTableHeader(TableColumnModel cm)
{
- accessibleContext = new AccessibleJTableHeader();
columnModel = cm == null ? createDefaultColumnModel() : cm;
- draggedColumn = null;
- draggedDistance = 0;
- opaque = true;
- reorderingAllowed = true;
- resizingAllowed = true;
- resizingColumn = null;
- table = null;
- updateTableInRealTime = true;
- cellRenderer = createDefaultRenderer();
+ initializeLocalVars();
updateUI();
}
@@ -504,7 +495,9 @@ public class JTableHeader extends JComponent
*/
public void setColumnModel(TableColumnModel c)
{
+ columnModel.removeColumnModelListener(this);
columnModel = c;
+ columnModel.addColumnModelListener(this);
}
/**
@@ -619,7 +612,7 @@ public class JTableHeader extends JComponent
public Rectangle getHeaderRect(int column)
{
- Rectangle r = getTable().getCellRect(-1, column, true);
+ Rectangle r = getTable().getCellRect(-1, column, false);
r.height = getHeight();
return r;
}
@@ -665,4 +658,88 @@ public class JTableHeader extends JComponent
return -1;
}
+
+ /**
+ * Receives notification when a column is added to the column model.
+ *
+ * @param event the table column model event
+ */
+ public void columnAdded(TableColumnModelEvent event)
+ {
+ // TODO: What else to do here (if anything)?
+ resizeAndRepaint();
+ }
+
+ /**
+ * Receives notification when a column margin changes in the column model.
+ *
+ * @param event the table column model event
+ */
+ public void columnMarginChanged(ChangeEvent event)
+ {
+ // TODO: What else to do here (if anything)?
+ resizeAndRepaint();
+ }
+
+ /**
+ * Receives notification when a column is moved within the column model.
+ *
+ * @param event the table column model event
+ */
+ public void columnMoved(TableColumnModelEvent event)
+ {
+ // TODO: What else to do here (if anything)?
+ resizeAndRepaint();
+ }
+
+ /**
+ * Receives notification when a column is removed from the column model.
+ *
+ * @param event the table column model event
+ */
+ public void columnRemoved(TableColumnModelEvent event)
+ {
+ // TODO: What else to do here (if anything)?
+ resizeAndRepaint();
+ }
+
+ /**
+ * Receives notification when the column selection has changed.
+ *
+ * @param event the table column model event
+ */
+ public void columnSelectionChanged(ListSelectionEvent event)
+ {
+ // TODO: What else to do here (if anything)?
+ resizeAndRepaint();
+ }
+
+ /**
+ * Validates the layout of this table header and repaints it. This is
+ * equivalent to <code>revalidate()</code> followed by
+ * <code>repaint()</code>.
+ */
+ public void resizeAndRepaint()
+ {
+ revalidate();
+ repaint();
+ }
+
+ /**
+ * Initializes the fields and properties of this class with default values.
+ * This is called by the constructors.
+ */
+ protected void initializeLocalVars()
+ {
+ accessibleContext = new AccessibleJTableHeader();
+ draggedColumn = null;
+ draggedDistance = 0;
+ opaque = true;
+ reorderingAllowed = true;
+ resizingAllowed = true;
+ resizingColumn = null;
+ table = null;
+ updateTableInRealTime = true;
+ cellRenderer = createDefaultRenderer();
+ }
}
diff --git a/javax/swing/table/TableColumnModel.java b/javax/swing/table/TableColumnModel.java
index 76a145604..b006f9ad4 100644
--- a/javax/swing/table/TableColumnModel.java
+++ b/javax/swing/table/TableColumnModel.java
@@ -50,6 +50,7 @@ import javax.swing.event.TableColumnModelListener;
*
* @author Andrew Selkirk
*/
+// FIXME: The API documentation in this class is incomplete.
public interface TableColumnModel
{
/**
@@ -107,7 +108,7 @@ public interface TableColumnModel
* @throws IllegalArgumentException if <code>identifier</code> is
* <code>null</code> or there is no column with that identifier.
*/
- int getColumnIndex(Object columnIdentifier);
+ int getColumnIndex(Object identifier);
/**
* Returns the <code>TableColumn</code> at the specified index.
@@ -169,7 +170,6 @@ public interface TableColumnModel
/**
* getSelectionModel
- * @param column TableColumn
*/
ListSelectionModel getSelectionModel();
diff --git a/javax/swing/text/AbstractDocument.java b/javax/swing/text/AbstractDocument.java
index 54213dcb1..b66c895ec 100644
--- a/javax/swing/text/AbstractDocument.java
+++ b/javax/swing/text/AbstractDocument.java
@@ -127,8 +127,29 @@ public abstract class AbstractDocument implements Document, Serializable
* Manages event listeners for this <code>Document</code>.
*/
protected EventListenerList listenerList = new EventListenerList();
+
+ /**
+ * Stores the current writer thread. Used for locking.
+ */
+ private Thread currentWriter = null;
+
+ /**
+ * The number of readers. Used for locking.
+ */
+ private int numReaders = 0;
+
+ /**
+ * Tells if there are one or more writers waiting.
+ */
+ private int numWritersWaiting = 0;
/**
+ * A condition variable that readers and writers wait on.
+ */
+ Object documentCV = new Object();
+
+
+ /**
* Creates a new <code>AbstractDocument</code> with the specified
* {@link Content} model.
*
@@ -347,8 +368,7 @@ public abstract class AbstractDocument implements Document, Serializable
*/
protected Thread getCurrentWriter()
{
- // FIXME: Implement locking!
- return null;
+ return currentWriter;
}
/**
@@ -515,13 +535,18 @@ public abstract class AbstractDocument implements Document, Serializable
// Just return when no text to insert was given.
if (text == null || text.length() == 0)
return;
-
DefaultDocumentEvent event =
new DefaultDocumentEvent(offset, text.length(),
DocumentEvent.EventType.INSERT);
- content.insertString(offset, text);
+
+ writeLock();
+ UndoableEdit undo = content.insertString(offset, text);
insertUpdate(event, attributes);
+ writeUnlock();
+
fireInsertUpdate(event);
+ if (undo != null)
+ fireUndoableEditUpdate(new UndoableEditEvent(this, undo));
}
/**
@@ -565,10 +590,28 @@ public abstract class AbstractDocument implements Document, Serializable
}
/**
- * Blocks until a read lock can be obtained.
+ * Blocks until a read lock can be obtained. Must block if there is
+ * currently a writer modifying the <code>Document</code>.
*/
public void readLock()
{
+ if (currentWriter != null && currentWriter.equals(Thread.currentThread()))
+ return;
+ synchronized (documentCV)
+ {
+ while (currentWriter != null || numWritersWaiting > 0)
+ {
+ try
+ {
+ documentCV.wait();
+ }
+ catch (InterruptedException ie)
+ {
+ throw new Error("interrupted trying to get a readLock");
+ }
+ }
+ numReaders++;
+ }
}
/**
@@ -577,6 +620,40 @@ public abstract class AbstractDocument implements Document, Serializable
*/
public void readUnlock()
{
+ // Note we could have a problem here if readUnlock was called without a
+ // prior call to readLock but the specs simply warn users to ensure that
+ // balance by using a finally block:
+ // readLock()
+ // try
+ // {
+ // doSomethingHere
+ // }
+ // finally
+ // {
+ // readUnlock();
+ // }
+
+ // All that the JDK seems to check for is that you don't call unlock
+ // more times than you've previously called lock, but it doesn't make
+ // sure that the threads calling unlock were the same ones that called lock
+
+ // FIXME: the reference implementation throws a
+ // javax.swing.text.StateInvariantError here
+ if (numReaders == 0)
+ throw new IllegalStateException("document lock failure");
+
+ synchronized (documentCV)
+ {
+ // If currentWriter is not null, the application code probably had a
+ // writeLock and then tried to obtain a readLock, in which case
+ // numReaders wasn't incremented
+ if (currentWriter == null)
+ {
+ numReaders --;
+ if (numReaders == 0 && numWritersWaiting != 0)
+ documentCV.notify();
+ }
+ }
}
/**
@@ -594,10 +671,42 @@ public abstract class AbstractDocument implements Document, Serializable
DefaultDocumentEvent event =
new DefaultDocumentEvent(offset, length,
DocumentEvent.EventType.REMOVE);
+
+ // Here we set up the parameters for an ElementChange, if one
+ // needs to be added to the DocumentEvent later
+ Element root = getDefaultRootElement();
+ int start = root.getElementIndex(offset);
+ int end = root.getElementIndex(offset + length);
+
+ Element[] removed = new Element[end - start + 1];
+ for (int i = start; i <= end; i++)
+ removed[i - start] = root.getElement(i);
+
removeUpdate(event);
- content.remove(offset, length);
+
+ Element[] added = new Element[1];
+ added[0] = root.getElement(start);
+ boolean shouldFire = content.getString(offset, length).length() != 0;
+
+ writeLock();
+ UndoableEdit temp = content.remove(offset, length);
+ writeUnlock();
+
postRemoveUpdate(event);
- fireRemoveUpdate(event);
+
+ GapContent.UndoRemove changes = null;
+ if (content instanceof GapContent)
+ changes = (GapContent.UndoRemove) temp;
+
+ if (changes != null && !(start == end))
+ {
+ // We need to add an ElementChange to our DocumentEvent
+ ElementEdit edit = new ElementEdit (root, start, removed, added);
+ event.addEdit(edit);
+ }
+
+ if (shouldFire)
+ fireRemoveUpdate(event);
}
/**
@@ -712,7 +821,15 @@ public abstract class AbstractDocument implements Document, Serializable
*/
public void render(Runnable runnable)
{
- // FIXME: Implement me!
+ readLock();
+ try
+ {
+ runnable.run();
+ }
+ finally
+ {
+ readUnlock();
+ }
}
/**
@@ -724,6 +841,7 @@ public abstract class AbstractDocument implements Document, Serializable
*/
public void setAsynchronousLoadPriority(int p)
{
+ // TODO: Implement this properly.
}
/**
@@ -738,11 +856,30 @@ public abstract class AbstractDocument implements Document, Serializable
}
/**
- * Blocks until a write lock can be obtained.
+ * Blocks until a write lock can be obtained. Must wait if there are
+ * readers currently reading or another thread is currently writing.
*/
protected void writeLock()
{
- // FIXME: Implement me.
+ if (currentWriter!= null && currentWriter.equals(Thread.currentThread()))
+ return;
+ synchronized (documentCV)
+ {
+ numWritersWaiting++;
+ while (numReaders > 0)
+ {
+ try
+ {
+ documentCV.wait();
+ }
+ catch (InterruptedException ie)
+ {
+ throw new Error("interruped while trying to obtain write lock");
+ }
+ }
+ numWritersWaiting --;
+ currentWriter = Thread.currentThread();
+ }
}
/**
@@ -751,7 +888,14 @@ public abstract class AbstractDocument implements Document, Serializable
*/
protected void writeUnlock()
{
- // FIXME: Implement me.
+ synchronized (documentCV)
+ {
+ if (Thread.currentThread().equals(currentWriter))
+ {
+ currentWriter = null;
+ documentCV.notifyAll();
+ }
+ }
}
/**
@@ -1230,6 +1374,9 @@ public abstract class AbstractDocument implements Document, Serializable
/**
* Returns the resolve parent of this element.
+ * This is taken from the AttributeSet, but if this is null,
+ * this method instead returns the Element's parent's
+ * AttributeSet
*
* @return the resolve parent of this element
*
@@ -1237,7 +1384,9 @@ public abstract class AbstractDocument implements Document, Serializable
*/
public AttributeSet getResolveParent()
{
- return attributes.getResolveParent();
+ if (attributes.getResolveParent() != null)
+ return attributes.getResolveParent();
+ return element_parent.getAttributes();
}
/**
@@ -1407,6 +1556,7 @@ public abstract class AbstractDocument implements Document, Serializable
+ "must not be thrown "
+ "here.");
err.initCause(ex);
+ throw err;
}
b.append("]\n");
}
@@ -1514,19 +1664,30 @@ public abstract class AbstractDocument implements Document, Serializable
*/
public int getElementIndex(int offset)
{
- // If we have no children, return -1.
- if (getElementCount() == 0)
- return - 1;
-
+ // If offset is less than the start offset of our first child,
+ // return 0
+ if (offset < getStartOffset())
+ return 0;
+
// XXX: There is surely a better algorithm
// as beginning from first element each time.
- for (int index = 0; index < children.length; ++index)
+ for (int index = 0; index < children.length - 1; ++index)
{
Element elem = children[index];
if ((elem.getStartOffset() <= offset)
&& (offset < elem.getEndOffset()))
return index;
+ // If the next element's start offset is greater than offset
+ // then we have to return the closest Element, since no Elements
+ // will contain the offset
+ if (children[index + 1].getStartOffset() > offset)
+ {
+ if ((offset - elem.getEndOffset()) > (children[index + 1].getStartOffset() - offset))
+ return index + 1;
+ else
+ return index;
+ }
}
// If offset is greater than the index of the last element, return
@@ -1759,7 +1920,7 @@ public abstract class AbstractDocument implements Document, Serializable
return (DocumentEvent.ElementChange) changes.get(elem);
}
}
-
+
/**
* An implementation of {@link DocumentEvent.ElementChange} to be added
* to {@link DefaultDocumentEvent}s.
diff --git a/javax/swing/text/AttributeSet.java b/javax/swing/text/AttributeSet.java
index 2f1f1890b..01d148c06 100644
--- a/javax/swing/text/AttributeSet.java
+++ b/javax/swing/text/AttributeSet.java
@@ -58,6 +58,7 @@ public interface AttributeSet
*/
static interface CharacterAttribute
{
+ // This interface is a marker interface and has no methods.
}
/**
@@ -65,6 +66,7 @@ public interface AttributeSet
*/
static interface ColorAttribute
{
+ // This interface is a marker interface and has no methods.
}
/**
@@ -72,6 +74,7 @@ public interface AttributeSet
*/
static interface FontAttribute
{
+ // This interface is a marker interface and has no methods.
}
/**
@@ -79,6 +82,7 @@ public interface AttributeSet
*/
static interface ParagraphAttribute
{
+ // This interface is a marker interface and has no methods.
}
/**
@@ -99,7 +103,7 @@ public interface AttributeSet
* <code>false</code> otherwise.
*
* @param name the name of the requested attribute
- * @param the value of the requested attribute
+ * @param value the value of the requested attribute
*
* @return <code>true</code> if this <code>AttributeSet</code> contains
* an attribute with the specified <code>name</code> and
diff --git a/javax/swing/text/BoxView.java b/javax/swing/text/BoxView.java
index bc08626bd..b57df732c 100644
--- a/javax/swing/text/BoxView.java
+++ b/javax/swing/text/BoxView.java
@@ -155,8 +155,9 @@ public class BoxView
* automatically when any of the child view changes its preferences
* via {@link #preferenceChanged(View, boolean, boolean)}.
*
- * The layout will be updated the next time when {@link #setSize()} is
- * called, typically from within the {@link #paint()} method.
+ * The layout will be updated the next time when
+ * {@link #setSize(float, float)} is called, typically from within the
+ * {@link #paint(Graphics, Shape)} method.
*
* Valid values for the axis are {@link View#X_AXIS} and
* {@link View#Y_AXIS}.
@@ -216,7 +217,7 @@ public class BoxView
* @param alloc the allocated region for the child to paint into
* @param index the index of the child to be painted
*
- * @see {@link #childAllocation}
+ * @see #childAllocation(int, Rectangle)
*/
protected void paintChild(Graphics g, Rectangle alloc, int index)
{
@@ -300,14 +301,14 @@ public class BoxView
setSize(bounds.width, bounds.height);
Rectangle inside = getInsideAllocation(a);
-
Rectangle copy = new Rectangle(inside);
int count = getViewCount();
for (int i = 0; i < count; ++i)
{
copy.setBounds(inside);
childAllocation(i, copy);
- paintChild(g, copy, i);
+ if (!copy.isEmpty())
+ paintChild(g, copy, i);
}
}
@@ -357,6 +358,24 @@ public class BoxView
}
/**
+ * Calculates the layout of the children of this <code>BoxView</code> along
+ * the specified axis.
+ *
+ * @param span the target span
+ * @param axis the axis that is examined
+ * @param offsets an empty array, filled with the offsets of the children
+ * @param spans an empty array, filled with the spans of the children
+ */
+ protected void baselineLayout(int span, int axis, int[] offsets,
+ int[] spans)
+ {
+ if (axis == myAxis)
+ layoutMajorAxis(span, axis, offsets, spans);
+ else
+ layoutMinorAxis(span, axis, offsets, spans);
+ }
+
+ /**
* Calculates the size requirements of this <code>BoxView</code> along
* its major axis, that is the axis specified in the constructor.
*
@@ -370,27 +389,8 @@ public class BoxView
protected SizeRequirements calculateMajorAxisRequirements(int axis,
SizeRequirements sr)
{
- if (sr == null)
- sr = new SizeRequirements();
- else
- {
- sr.maximum = 0;
- sr.minimum = 0;
- sr.preferred = 0;
- sr.alignment = 0.5F;
- }
-
- int count = getViewCount();
-
- // Sum up the sizes of the children along the specified axis.
- for (int i = 0; i < count; ++i)
- {
- View child = getView(i);
- sr.minimum += child.getMinimumSpan(axis);
- sr.preferred += child.getPreferredSpan(axis);
- sr.maximum += child.getMaximumSpan(axis);
- }
- return sr;
+ SizeRequirements[] childReqs = getChildRequirements(axis);
+ return SizeRequirements.getTiledSizeRequirements(childReqs);
}
/**
@@ -408,48 +408,8 @@ public class BoxView
protected SizeRequirements calculateMinorAxisRequirements(int axis,
SizeRequirements sr)
{
- if (sr == null)
- sr = new SizeRequirements();
- else
- {
- sr.maximum = 0;
- sr.minimum = 0;
- sr.preferred = 0;
- sr.alignment = 0.5F;
- }
-
- int count = getViewCount();
-
- int aboveBaseline = 0;
- int belowBaseline = 0;
- int aboveBaselineMin = 0;
- int belowBaselineMin = 0;
- int aboveBaselineMax = 0;
- int belowBaselineMax = 0;
-
- for (int i = 0; i < count; ++i)
- {
- View child = getView(i);
- float align = child.getAlignment(axis);
- int pref = (int) child.getPreferredSpan(axis);
- int min = (int) child.getMinimumSpan(axis);
- int max = (int) child.getMaximumSpan(axis);
- aboveBaseline += (int) (align * pref);
- belowBaseline += (int) ((1.F - align) * pref);
- aboveBaselineMin += (int) (align * min);
- belowBaselineMin += (int) ((1.F - align) * min);
- aboveBaselineMax += (int) (align * max);
- belowBaselineMax += (int) ((1.F - align) * max);
- }
- sr.minimum = aboveBaselineMin + belowBaselineMin;
- sr.maximum = aboveBaselineMax + belowBaselineMax;
- sr.preferred = aboveBaseline + belowBaseline;
- if (aboveBaseline == 0)
- sr.alignment = 1.0F;
- else
- sr.alignment = (float) (sr.preferred / aboveBaseline);
-
- return sr;
+ SizeRequirements[] childReqs = getChildRequirements(axis);
+ return SizeRequirements.getAlignedSizeRequirements(childReqs);
}
/**
@@ -564,19 +524,8 @@ public class BoxView
*/
protected void layout(int width, int height)
{
- this.width = width;
- this.height = height;
-
- if (myAxis == X_AXIS)
- {
- layoutMajorAxis(width, X_AXIS, offsetsX, spansX);
- layoutMinorAxis(height, Y_AXIS, offsetsY, spansY);
- }
- else
- {
- layoutMajorAxis(height, Y_AXIS, offsetsY, spansY);
- layoutMinorAxis(width, X_AXIS, offsetsX, spansX);
- }
+ baselineLayout(width, X_AXIS, offsetsX, spansX);
+ baselineLayout(height, Y_AXIS, offsetsY, spansY);
}
/**
@@ -586,28 +535,16 @@ public class BoxView
* to layout the children
* @param axis the axis along which the layout is performed
* @param offsets the array that holds the offsets of the children on exit
- * @param offsets the array that holds the spans of the children on exit
+ * @param spans the array that holds the spans of the children on exit
*/
protected void layoutMajorAxis(int targetSpan, int axis, int[] offsets,
int[] spans)
{
- // Allocate SizeRequirements for each child view.
- int count = getViewCount();
- SizeRequirements[] childReqs = new SizeRequirements[count];
- for (int i = 0; i < count; ++i)
- {
- View view = getView(i);
- childReqs[i] = new SizeRequirements((int) view.getMinimumSpan(axis),
- (int) view.getPreferredSpan(axis),
- (int) view.getMaximumSpan(axis),
- view.getAlignment(axis));
- }
-
+ SizeRequirements[] childReqs = getChildRequirements(axis);
// Calculate the spans and offsets using the SizeRequirements uility
// methods.
SizeRequirements.calculateTiledPositions(targetSpan, null, childReqs,
offsets, spans);
-
validateLayout(axis);
}
@@ -618,26 +555,21 @@ public class BoxView
* to layout the children
* @param axis the axis along which the layout is performed
* @param offsets the array that holds the offsets of the children on exit
- * @param offsets the array that holds the spans of the children on exit
+ * @param spans the array that holds the spans of the children on exit
*/
protected void layoutMinorAxis(int targetSpan, int axis, int[] offsets,
int[] spans)
{
- // Allocate SizeRequirements for each child view.
- int count = getViewCount();
- SizeRequirements[] childReqs = new SizeRequirements[count];
- for (int i = 0; i < count; ++i)
- {
- View view = getView(i);
- childReqs[i] = new SizeRequirements((int) view.getMinimumSpan(axis),
- (int) view.getPreferredSpan(axis),
- (int) view.getMaximumSpan(axis),
- view.getAlignment(axis));
- }
-
+ SizeRequirements[] childReqs = getChildRequirements(axis);
// Calculate the spans and offsets using the SizeRequirements uility
// methods.
- SizeRequirements.calculateAlignedPositions(targetSpan, null, childReqs,
+ // TODO: This might be an opportunity for performance optimization. Here
+ // we could use a cached instance of SizeRequirements instead of passing
+ // null to baselineRequirements. However, this would involve rewriting
+ // the baselineRequirements() method to not use the SizeRequirements
+ // utility method, since they cannot reuse a cached instance.
+ SizeRequirements total = baselineRequirements(axis, null);
+ SizeRequirements.calculateAlignedPositions(targetSpan, total, childReqs,
offsets, spans);
validateLayout(axis);
}
@@ -687,6 +619,9 @@ public class BoxView
layoutChanged(X_AXIS);
if (this.height != (int) height)
layoutChanged(Y_AXIS);
+
+ this.width = (int) width;
+ this.height = (int) height;
Rectangle outside = new Rectangle(0, 0, this.width, this.height);
Rectangle inside = getInsideAllocation(outside);
@@ -706,4 +641,99 @@ public class BoxView
if (axis == Y_AXIS)
yLayoutValid = true;
}
+
+ /**
+ * Returns the size requirements of this view's children for the major
+ * axis.
+ *
+ * @return the size requirements of this view's children for the major
+ * axis
+ */
+ SizeRequirements[] getChildRequirements(int axis)
+ {
+ // Allocate SizeRequirements for each child view.
+ int count = getViewCount();
+ SizeRequirements[] childReqs = new SizeRequirements[count];
+ for (int i = 0; i < count; ++i)
+ {
+ View view = getView(i);
+ childReqs[i] = new SizeRequirements((int) view.getMinimumSpan(axis),
+ (int) view.getPreferredSpan(axis),
+ (int) view.getMaximumSpan(axis),
+ view.getAlignment(axis));
+ }
+ return childReqs;
+ }
+
+ /**
+ * Returns the span for the child view with the given index for the specified
+ * axis.
+ *
+ * @param axis the axis to examine, either <code>X_AXIS</code> or
+ * <code>Y_AXIS</code>
+ * @param childIndex the index of the child for for which to return the span
+ *
+ * @return the span for the child view with the given index for the specified
+ * axis
+ */
+ protected int getSpan(int axis, int childIndex)
+ {
+ if (axis == X_AXIS)
+ return spansX[childIndex];
+ else
+ return spansY[childIndex];
+ }
+
+ /**
+ * Returns the offset for the child view with the given index for the
+ * specified axis.
+ *
+ * @param axis the axis to examine, either <code>X_AXIS</code> or
+ * <code>Y_AXIS</code>
+ * @param childIndex the index of the child for for which to return the span
+ *
+ * @return the offset for the child view with the given index for the
+ * specified axis
+ */
+ protected int getOffset(int axis, int childIndex)
+ {
+ if (axis == X_AXIS)
+ return offsetsX[childIndex];
+ else
+ return offsetsY[childIndex];
+ }
+
+ /**
+ * Returns the alignment for this box view for the specified axis. The
+ * axis that is tiled (the major axis) will be requested to be aligned
+ * centered (0.5F). The minor axis alignment depends on the child view's
+ * total alignment.
+ *
+ * @param axis the axis which is examined
+ *
+ * @return the alignment for this box view for the specified axis
+ */
+ public float getAlignment(int axis)
+ {
+ if (axis == myAxis)
+ return 0.5F;
+ else
+ return baselineRequirements(axis, null).alignment;
+ }
+
+ /**
+ * Called by a child View when its preferred span has changed.
+ *
+ * @param width indicates that the preferred width of the child changed.
+ * @param height indicates that the preferred height of the child changed.
+ * @param child the child View.
+ */
+ public void preferenceChanged (View child, boolean width, boolean height)
+ {
+ if (width)
+ xLayoutValid = false;
+ if (height)
+ yLayoutValid = false;
+ super.preferenceChanged(child, width, height);
+ }
}
diff --git a/javax/swing/text/ComponentView.java b/javax/swing/text/ComponentView.java
index e280e7c0c..366dc1c38 100644
--- a/javax/swing/text/ComponentView.java
+++ b/javax/swing/text/ComponentView.java
@@ -43,7 +43,7 @@ import java.awt.Shape;
/**
* A {@link View} implementation that is able to render arbitrary
- * {@link Components}. This uses the attribute
+ * {@link Component}s. This uses the attribute
* {@link StyleConstants#ComponentAttribute} to determine the
* <code>Component</code> that should be rendered. This <code>Component</code>
* becomes a direct child of the <code>JTextComponent</code> that contains
@@ -53,6 +53,7 @@ import java.awt.Shape;
* @author original author unknown
* @author Roman Kennke (roman@kennke.org)
*/
+// FIXME: This class is a complete stub and needs to be implemented properly.
public class ComponentView extends View
{
/**
@@ -118,38 +119,45 @@ public class ComponentView extends View
return 0;
}
- public float getMinimumSpan(int axis)
- {
- return 0;
- }
-
- public float getPreferredSpan(int axis)
- {
- return 0;
- }
-
- public Shape modelToView(int pos, Shape a, Position.Bias b)
- throws BadLocationException
- {
- return null;
- }
-
- public void paint(Graphics g, Shape a)
- {
- }
+ public float getMinimumSpan(int axis)
+ {
+ // TODO: Implement this properly.
+ return 0;
+ }
+
+ public float getPreferredSpan(int axis)
+ {
+ // TODO: Implement this properly.
+ return 0;
+ }
+
+ public Shape modelToView(int pos, Shape a, Position.Bias b)
+ throws BadLocationException
+ {
+ // TODO: Implement this properly.
+ return null;
+ }
- public void setParent(View p)
- {
- }
+ public void paint(Graphics g, Shape a)
+ {
+ // TODO: Implement this properly.
+ }
+
+ public void setParent(View p)
+ {
+ // TODO: Implement this properly.
+ }
- public void setSize(float width, float height)
- {
- }
+ public void setSize(float width, float height)
+ {
+ // TODO: Implement this properly.
+ }
- public int viewToModel(float x, float y, Shape a, Position.Bias[] bias)
- {
- return 0;
- }
+ public int viewToModel(float x, float y, Shape a, Position.Bias[] bias)
+ {
+ // TODO: Implement this properly.
+ return 0;
+ }
/**
* Maps coordinates from the <code>View</code>'s space into a position
diff --git a/javax/swing/text/CompositeView.java b/javax/swing/text/CompositeView.java
index b3dd6123e..6d8ca912f 100644
--- a/javax/swing/text/CompositeView.java
+++ b/javax/swing/text/CompositeView.java
@@ -62,7 +62,7 @@ public abstract class CompositeView
/**
* The allocation of this <code>View</code> minus its insets. This is
* initialized in {@link #getInsideAllocation} and reused and modified in
- * {@link childAllocation}.
+ * {@link #childAllocation(int, Rectangle)}.
*/
Rectangle insideAllocation;
@@ -434,10 +434,16 @@ public abstract class CompositeView
*/
protected int getViewIndexAtPosition(int pos)
{
- // We have one child view allocated for each child element in
- // loadChildren(), so this should work.
- Element el = getElement();
- int index = el.getElementIndex(pos);
+ int index = -1;
+ for (int i = 0; i < children.length; i++)
+ {
+ if (children[i].getStartOffset() <= pos
+ && children[i].getEndOffset() > pos)
+ {
+ index = i;
+ break;
+ }
+ }
return index;
}
@@ -474,8 +480,8 @@ public abstract class CompositeView
insideAllocation = inside;
}
}
- inside.x = alloc.x - insets.left;
- inside.y = alloc.y - insets.top;
+ inside.x = alloc.x + insets.left;
+ inside.y = alloc.y + insets.top;
inside.width = alloc.width - insets.left - insets.right;
inside.height = alloc.height - insets.top - insets.bottom;
return inside;
diff --git a/javax/swing/text/DefaultCaret.java b/javax/swing/text/DefaultCaret.java
index 401e2e08f..e5d28d0b8 100644
--- a/javax/swing/text/DefaultCaret.java
+++ b/javax/swing/text/DefaultCaret.java
@@ -45,10 +45,15 @@ import java.awt.event.FocusListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
import java.util.EventListener;
+import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
import javax.swing.event.EventListenerList;
/**
@@ -60,9 +65,128 @@ import javax.swing.event.EventListenerList;
public class DefaultCaret extends Rectangle
implements Caret, FocusListener, MouseListener, MouseMotionListener
{
+ /**
+ * Listens for changes in the text component's document and updates the
+ * caret accordingly.
+ *
+ * @author Roman Kennke (kennke@aicas.com)
+ */
+ private class DocumentHandler implements DocumentListener
+ {
+ /**
+ * Receives notification that some text attributes have changed. No action
+ * is taken here.
+ *
+ * @param event the document event
+ */
+ public void changedUpdate(DocumentEvent event)
+ {
+ // Nothing to do here.
+ }
+
+ /**
+ * Receives notification that some text has been inserted from the text
+ * component. The caret is moved forward accordingly.
+ *
+ * @param event the document event
+ */
+ public void insertUpdate(DocumentEvent event)
+ {
+ if (policy == ALWAYS_UPDATE ||
+ (SwingUtilities.isEventDispatchThread() &&
+ policy == UPDATE_WHEN_ON_EDT))
+ {
+ int dot = getDot();
+ setDot(dot + event.getLength());
+ }
+ }
+
+ /**
+ * Receives notification that some text has been removed into the text
+ * component. The caret is moved backwards accordingly.
+ *
+ * @param event the document event
+ */
+ public void removeUpdate(DocumentEvent event)
+ {
+ if (policy == ALWAYS_UPDATE ||
+ (SwingUtilities.isEventDispatchThread() &&
+ policy == UPDATE_WHEN_ON_EDT))
+ {
+ int dot = getDot();
+ setDot(dot - event.getLength());
+ }
+ else if (policy == NEVER_UPDATE)
+ {
+ int docLength = event.getDocument().getLength();
+ if (getDot() > docLength)
+ setDot(docLength);
+ }
+ }
+ }
+
+ /**
+ * Listens for property changes on the text document. This is used to add and
+ * remove our document listener, if the document of the text component has
+ * changed.
+ *
+ * @author Roman Kennke (kennke@aicas.com)
+ */
+ private class PropertyChangeHandler implements PropertyChangeListener
+ {
+
+ /**
+ * Receives notification when a property has changed on the text component.
+ * This adds/removes our document listener from the text component's
+ * document when the document changes.
+ *
+ * @param e the property change event
+ */
+ public void propertyChange(PropertyChangeEvent e)
+ {
+ if (e.getPropertyName().equals("document"))
+ {
+ Document oldDoc = (Document) e.getOldValue();
+ oldDoc.removeDocumentListener(documentListener);
+ Document newDoc = (Document) e.getNewValue();
+ newDoc.addDocumentListener(documentListener);
+ }
+ }
+
+ }
+
/** The serialization UID (compatible with JDK1.5). */
private static final long serialVersionUID = 4325555698756477346L;
-
+
+ /**
+ * Indicates the Caret position should always be updated after Document
+ * changes even if the updates are not performed on the Event Dispatching
+ * thread.
+ *
+ * @since 1.5
+ */
+ public static final int ALWAYS_UPDATE = 2;
+
+ /**
+ * Indicates the Caret position should not be changed unless the Document
+ * length becomes less than the Caret position, in which case the Caret
+ * is moved to the end of the Document.
+ *
+ * @since 1.5
+ */
+ public static final int NEVER_UPDATE = 1;
+
+ /**
+ * Indicates the Caret position should be updated only if Document changes
+ * are made on the Event Dispatcher thread.
+ *
+ * @since 1.5
+ */
+ public static final int UPDATE_WHEN_ON_EDT = 0;
+
+ /** Keeps track of the current update policy **/
+ int policy = UPDATE_WHEN_ON_EDT;
+
/**
* The <code>ChangeEvent</code> that is fired by {@link #fireStateChanged()}.
*/
@@ -74,6 +198,16 @@ public class DefaultCaret extends Rectangle
protected EventListenerList listenerList = new EventListenerList();
/**
+ * Our document listener.
+ */
+ DocumentListener documentListener;
+
+ /**
+ * Our property listener.
+ */
+ PropertyChangeListener propertyChangeListener;
+
+ /**
* The text component in which this caret is installed.
*/
private JTextComponent textComponent;
@@ -114,6 +248,43 @@ public class DefaultCaret extends Rectangle
private Object highlightEntry;
/**
+ * Sets the Caret update policy.
+ *
+ * @param policy the new policy. Valid values are:
+ * ALWAYS_UPDATE: always update the Caret position, even when Document
+ * updates don't occur on the Event Dispatcher thread.
+ * NEVER_UPDATE: don't update the Caret position unless the Document
+ * length becomes less than the Caret position (then update the
+ * Caret to the end of the Document).
+ * UPDATE_WHEN_ON_EDT: update the Caret position when the
+ * Document updates occur on the Event Dispatcher thread. This is the
+ * default.
+ *
+ * @since 1.5
+ * @throws IllegalArgumentException if policy is not one of the above.
+ */
+ public void setUpdatePolicy (int policy)
+ {
+ if (policy != ALWAYS_UPDATE && policy != NEVER_UPDATE
+ && policy != UPDATE_WHEN_ON_EDT)
+ throw new
+ IllegalArgumentException
+ ("policy must be ALWAYS_UPDATE, NEVER__UPDATE, or UPDATE_WHEN_ON_EDT");
+ this.policy = policy;
+ }
+
+ /**
+ * Gets the caret update policy.
+ *
+ * @return the caret update policy.
+ * @since 1.5
+ */
+ public int getUpdatePolicy ()
+ {
+ return policy;
+ }
+
+ /**
* Moves the caret position when the mouse is dragged over the text
* component, modifying the selection accordingly.
*
@@ -173,6 +344,7 @@ public class DefaultCaret extends Rectangle
*/
public void mouseExited(MouseEvent event)
{
+ // TODO: What to do here, if anything?
}
/**
@@ -186,6 +358,9 @@ public class DefaultCaret extends Rectangle
public void mousePressed(MouseEvent event)
{
// FIXME: Implement this properly.
+ if (!(event.getButton() == MouseEvent.BUTTON1))
+ return;
+ setDot(textComponent.viewToModel(event.getPoint()));
}
/**
@@ -206,6 +381,7 @@ public class DefaultCaret extends Rectangle
*/
public void focusGained(FocusEvent event)
{
+ // TODO: Implement this properly.
}
/**
@@ -215,6 +391,7 @@ public class DefaultCaret extends Rectangle
*/
public void focusLost(FocusEvent event)
{
+ // TODO: Implement this properly.
}
/**
@@ -251,6 +428,10 @@ public class DefaultCaret extends Rectangle
textComponent.removeFocusListener(this);
textComponent.removeMouseListener(this);
textComponent.removeMouseMotionListener(this);
+ textComponent.getDocument().removeDocumentListener(documentListener);
+ documentListener = null;
+ textComponent.removePropertyChangeListener(propertyChangeListener);
+ propertyChangeListener = null;
textComponent = null;
}
@@ -267,6 +448,10 @@ public class DefaultCaret extends Rectangle
textComponent.addFocusListener(this);
textComponent.addMouseListener(this);
textComponent.addMouseMotionListener(this);
+ propertyChangeListener = new PropertyChangeHandler();
+ textComponent.addPropertyChangeListener(propertyChangeListener);
+ documentListener = new DocumentHandler();
+ textComponent.getDocument().addDocumentListener(documentListener);
repaint();
}
@@ -374,10 +559,7 @@ public class DefaultCaret extends Rectangle
*/
protected final void repaint()
{
- // FIXME: Is this good? This possibly causes alot of the component
- // hierarchy to be repainted on every caret blink.
- if (textComponent != null)
- textComponent.repaint();
+ textComponent.repaint(this);
}
/**
@@ -572,8 +754,11 @@ public class DefaultCaret extends Rectangle
*/
public void setVisible(boolean v)
{
- visible = v;
- repaint();
+ if (v != visible)
+ {
+ visible = v;
+ repaint();
+ }
}
/**
diff --git a/javax/swing/text/DefaultEditorKit.java b/javax/swing/text/DefaultEditorKit.java
index 2f901947f..3b3fc1f72 100644
--- a/javax/swing/text/DefaultEditorKit.java
+++ b/javax/swing/text/DefaultEditorKit.java
@@ -222,9 +222,6 @@ public class DefaultEditorKit extends EditorKit
{
t.getDocument().insertString(t.getCaret().getDot(),
event.getActionCommand(), null);
- t.getCaret().setDot(Math.min(t.getCaret().getDot() + 1,
- t.getDocument().getEndPosition()
- .getOffset()));
}
catch (BadLocationException be)
{
@@ -286,6 +283,8 @@ public class DefaultEditorKit extends EditorKit
*/
public void actionPerformed(ActionEvent event)
{
+ // FIXME: Figure out what this Action is supposed to do. Obviously text
+ // that is entered by the user is inserted through DefaultKeyTypedAction.
}
}
@@ -692,6 +691,7 @@ public class DefaultEditorKit extends EditorKit
*/
public DefaultEditorKit()
{
+ // Nothing to do here.
}
/**
@@ -947,15 +947,23 @@ public class DefaultEditorKit extends EditorKit
* @param offset the beginning offset from where to write
* @param len the length of the fragment to write
*
- * @throws BadLocationException if <code>offset</code> or
- * <code>offset + len</code>is an invalid location inside
- * <code>document</code>
+ * @throws BadLocationException if <code>offset</code> is an
+ * invalid location inside <code>document</code>.
* @throws IOException if something goes wrong while writing to
* <code>out</code>
*/
public void write(Writer out, Document document, int offset, int len)
- throws BadLocationException, IOException
+ throws BadLocationException, IOException
{
- // TODO: Implement this properly.
+ // Throw a BLE if offset is invalid
+ if (offset < 0 || offset > document.getLength())
+ throw new BadLocationException("Tried to write to invalid location",
+ offset);
+
+ // If they gave an overly large len, just adjust it
+ if (offset + len > document.getLength())
+ len = document.getLength() - offset;
+
+ out.write(document.getText(offset, len));
}
}
diff --git a/javax/swing/text/DefaultFormatter.java b/javax/swing/text/DefaultFormatter.java
index 16d40c24b..f9e0f10e6 100644
--- a/javax/swing/text/DefaultFormatter.java
+++ b/javax/swing/text/DefaultFormatter.java
@@ -175,7 +175,10 @@ public class DefaultFormatter extends JFormattedTextField.AbstractFormatter
catch (ParseException pe)
{
// if that happens, something serious must be wrong
- throw new AssertionError("values must be parseable");
+ AssertionError ae;
+ ae = new AssertionError("values must be parseable");
+ ae.initCause(pe);
+ throw ae;
}
}
}
diff --git a/javax/swing/text/DefaultHighlighter.java b/javax/swing/text/DefaultHighlighter.java
index c8d874caa..40ea4f80a 100644
--- a/javax/swing/text/DefaultHighlighter.java
+++ b/javax/swing/text/DefaultHighlighter.java
@@ -168,6 +168,7 @@ public class DefaultHighlighter extends LayeredHighlighter
public DefaultHighlighter()
{
+ // Nothing to do here.
}
public boolean getDrawsLayeredHighlights()
@@ -238,6 +239,7 @@ public class DefaultHighlighter extends LayeredHighlighter
Shape viewBounds, JTextComponent editor,
View view)
{
+ // TODO: Implement this properly.
}
public void paint(Graphics g)
diff --git a/javax/swing/text/DefaultStyledDocument.java b/javax/swing/text/DefaultStyledDocument.java
index 765477507..648b0bd4d 100644
--- a/javax/swing/text/DefaultStyledDocument.java
+++ b/javax/swing/text/DefaultStyledDocument.java
@@ -899,6 +899,10 @@ public class DefaultStyledDocument extends AbstractDocument
/**
* Returns the paragraph element for the specified position.
+ * If the position is outside the bounds of the document's root element,
+ * then the closest element is returned. That is the last paragraph if
+ * <code>position >= endIndex</code> or the first paragraph if
+ * <code>position < startIndex</code>.
*
* @param position the position for which to query the paragraph element
*
@@ -907,7 +911,16 @@ public class DefaultStyledDocument extends AbstractDocument
public Element getParagraphElement(int position)
{
BranchElement root = (BranchElement) getDefaultRootElement();
+ int start = root.getStartOffset();
+ int end = root.getEndOffset();
+ if (position >= end)
+ position = end - 1;
+ else if (position < start)
+ position = start;
+
Element par = root.positionToElement(position);
+
+ assert par != null : "The paragraph element must not be null";
return par;
}
@@ -1060,8 +1073,9 @@ public class DefaultStyledDocument extends AbstractDocument
}
catch (BadLocationException ex)
{
- throw new AssertionError("BadLocationException must not be thrown "
- + "here.");
+ AssertionError ae = new AssertionError("Unexpected bad location");
+ ae.initCause(ex);
+ throw ae;
}
int len = 0;
diff --git a/javax/swing/text/EditorKit.java b/javax/swing/text/EditorKit.java
index bd51a866f..8719aee59 100644
--- a/javax/swing/text/EditorKit.java
+++ b/javax/swing/text/EditorKit.java
@@ -48,24 +48,24 @@ import java.io.Writer;
import javax.swing.Action;
import javax.swing.JEditorPane;
-public abstract class EditorKit
- implements Cloneable, Serializable
+public abstract class EditorKit implements Cloneable, Serializable
{
private static final long serialVersionUID = -5044124649345887822L;
public EditorKit()
{
+ // Nothing to do here.
}
public Object clone()
{
try
{
- return super.clone();
+ return super.clone();
}
catch (CloneNotSupportedException e)
{
- return null;
+ return null;
}
}
@@ -74,10 +74,12 @@ public abstract class EditorKit
*/
public void deinstall(JEditorPane c)
{
+ // This default implementation does nothing.
}
public void install(JEditorPane c)
{
+ // This default implementation does nothing.
}
public abstract Caret createCaret();
diff --git a/javax/swing/text/FieldView.java b/javax/swing/text/FieldView.java
index e2e04d7c4..d8a3568e5 100644
--- a/javax/swing/text/FieldView.java
+++ b/javax/swing/text/FieldView.java
@@ -118,7 +118,7 @@ public class FieldView extends PlainView
FontMetrics fm = getFontMetrics();
if (axis == Y_AXIS)
- return fm.getHeight();
+ return super.getPreferredSpan(axis);
String text;
Element elem = getElement();
@@ -134,7 +134,7 @@ public class FieldView extends PlainView
text = "";
}
- return fm.stringWidth(text);
+ return fm.stringWidth(text) + 30;
}
public int getResizeWeight(int axis)
@@ -159,18 +159,21 @@ public class FieldView extends PlainView
{
Shape newAlloc = adjustAllocation(shape);
super.insertUpdate(ev, newAlloc, vf);
+ getContainer().repaint();
}
public void removeUpdate(DocumentEvent ev, Shape shape, ViewFactory vf)
{
Shape newAlloc = adjustAllocation(shape);
super.removeUpdate(ev, newAlloc, vf);
+ getContainer().repaint();
}
public void changedUpdate(DocumentEvent ev, Shape shape, ViewFactory vf)
{
Shape newAlloc = adjustAllocation(shape);
super.removeUpdate(ev, newAlloc, vf);
+ getContainer().repaint();
}
public int viewToModel(float fx, float fy, Shape a, Position.Bias[] bias)
diff --git a/javax/swing/text/FlowView.java b/javax/swing/text/FlowView.java
index a6ef89efb..5f23ba987 100644
--- a/javax/swing/text/FlowView.java
+++ b/javax/swing/text/FlowView.java
@@ -42,6 +42,7 @@ import java.awt.Container;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Shape;
+import java.util.Iterator;
import java.util.Vector;
import javax.swing.event.DocumentEvent;
@@ -71,6 +72,7 @@ public abstract class FlowView extends BoxView
*/
public FlowStrategy()
{
+ // Nothing to do here.
}
/**
@@ -137,7 +139,7 @@ public abstract class FlowView extends BoxView
* Performs the layout for the whole view. By default this rebuilds
* all the physical views from the logical views of the managed FlowView.
*
- * This is called by {@link FlowLayout#layout} to update the layout of
+ * This is called by {@link FlowView#layout} to update the layout of
* the view.
*
* @param fv the flow view for which we perform the layout
@@ -183,11 +185,17 @@ public abstract class FlowView extends BoxView
{
View child = createView(fv, offset, spanLeft, rowIndex);
if (child == null)
- break;
+ {
+ offset = -1;
+ break;
+ }
int span = (int) child.getPreferredSpan(flowAxis);
if (span > spanLeft)
- break;
+ {
+ offset = -1;
+ break;
+ }
row.append(child);
spanLeft -= span;
@@ -204,7 +212,7 @@ public abstract class FlowView extends BoxView
* not fit in the available span and also cannot be broken down).
*
* @param fv the flow view
- * @param startOffset the start offset for the view to be created
+ * @param offset the start offset for the view to be created
* @param spanLeft the available span
* @param rowIndex the index of the row
*
@@ -218,13 +226,15 @@ public abstract class FlowView extends BoxView
View logicalView = getLogicalView(fv);
int viewIndex = logicalView.getViewIndex(offset, Position.Bias.Forward);
+ if (viewIndex == -1)
+ return null;
+
View child = logicalView.getView(viewIndex);
int flowAxis = fv.getFlowAxis();
int span = (int) child.getPreferredSpan(flowAxis);
if (span <= spanLeft)
return child;
-
else if (child.getBreakWeight(flowAxis, offset, spanLeft)
> BadBreakWeight)
// FIXME: What to do with the pos parameter here?
@@ -326,7 +336,19 @@ public abstract class FlowView extends BoxView
*/
public int getViewIndex(int pos, Position.Bias b)
{
- return getElement().getElementIndex(pos);
+ int index = -1;
+ int i = 0;
+ for (Iterator it = children.iterator(); it.hasNext(); i++)
+ {
+ View child = (View) it.next();
+ if (child.getStartOffset() >= pos
+ && child.getEndOffset() < pos)
+ {
+ index = i;
+ break;
+ }
+ }
+ return index;
}
/**
@@ -478,7 +500,7 @@ public abstract class FlowView extends BoxView
* The real children are created at layout time and each represent one
* row.
*
- * This method is called by {@link #setParent} in order to initialize
+ * This method is called by {@link View#setParent} in order to initialize
* the view.
*
* @param vf the view factory to use for creating the child views
@@ -502,7 +524,7 @@ public abstract class FlowView extends BoxView
/**
* Performs the layout of this view. If the span along the flow axis changed,
- * this first calls {@link FlowStrategy.layout} in order to rebuild the
+ * this first calls {@link FlowStrategy#layout} in order to rebuild the
* rows of this view. Then the superclass's behaviour is called to arrange
* the rows within the box.
*
diff --git a/javax/swing/text/GapContent.java b/javax/swing/text/GapContent.java
index 5c8f81865..439365e59 100644
--- a/javax/swing/text/GapContent.java
+++ b/javax/swing/text/GapContent.java
@@ -45,6 +45,9 @@ import java.util.Iterator;
import java.util.ListIterator;
import java.util.Vector;
+import javax.swing.undo.AbstractUndoableEdit;
+import javax.swing.undo.CannotRedoException;
+import javax.swing.undo.CannotUndoException;
import javax.swing.undo.UndoableEdit;
/**
@@ -116,7 +119,7 @@ public class GapContent
public int getOffset()
{
// Check precondition.
- assert mark <= gapStart || mark > gapEnd : "mark: " + mark
+ assert mark <= gapStart || mark >= gapEnd : "mark: " + mark
+ ", gapStart: " + gapStart
+ ", gapEnd: " + gapEnd;
@@ -127,6 +130,83 @@ public class GapContent
}
}
+ class UndoInsertString extends AbstractUndoableEdit
+ {
+ public int where, length;
+ String text;
+ public UndoInsertString(int start, int len)
+ {
+ where = start;
+ length = len;
+ }
+
+ public void undo () throws CannotUndoException
+ {
+ super.undo();
+ try
+ {
+ text = getString(where, length);
+ remove(where, length);
+ }
+ catch (BadLocationException ble)
+ {
+ throw new CannotUndoException();
+ }
+ }
+
+ public void redo () throws CannotUndoException
+ {
+ super.redo();
+ try
+ {
+ insertString(where, text);
+ }
+ catch (BadLocationException ble)
+ {
+ throw new CannotRedoException();
+ }
+ }
+
+ }
+
+ class UndoRemove extends AbstractUndoableEdit
+ {
+ public int where;
+ String text;
+ public UndoRemove(int start, String removedText)
+ {
+ where = start;
+ text = removedText;
+ }
+
+ public void undo () throws CannotUndoException
+ {
+ super.undo();
+ try
+ {
+ insertString(where, text);
+ }
+ catch (BadLocationException ble)
+ {
+ throw new CannotUndoException();
+ }
+ }
+
+ public void redo () throws CannotUndoException
+ {
+ super.redo();
+ try
+ {
+ remove(where, text.length());
+ }
+ catch (BadLocationException ble)
+ {
+ throw new CannotRedoException();
+ }
+ }
+
+ }
+
/** The serialization UID (compatible with JDK1.5). */
private static final long serialVersionUID = -6226052713477823730L;
@@ -218,8 +298,7 @@ public class GapContent
* @param where the position where the string is inserted
* @param str the string that is to be inserted
*
- * @return an UndoableEdit object (currently not supported, so
- * <code>null</code> is returned)
+ * @return an UndoableEdit object
*
* @throws BadLocationException if <code>where</code> is not a valid
* location in the buffer
@@ -235,9 +314,9 @@ public class GapContent
throw new BadLocationException("the where argument cannot be greater"
+ " than the content length", where);
- replace(where, 0, str.toCharArray(), str.length());
+ replace(where, 0, str.toCharArray(), strLen);
- return null;
+ return new UndoInsertString(where, strLen);
}
/**
@@ -246,8 +325,7 @@ public class GapContent
* @param where the position where the content is to be removed
* @param nitems number of characters to be removed
*
- * @return an UndoableEdit object (currently not supported, so
- * <code>null</code> is returned)
+ * @return an UndoableEdit object
*
* @throws BadLocationException if <code>where</code> is not a valid
* location in the buffer
@@ -264,9 +342,10 @@ public class GapContent
throw new BadLocationException("where + nitems cannot be greater"
+ " than the content length", where + nitems);
+ String removedText = getString(where, nitems);
replace(where, nitems, null, 0);
- return null;
+ return new UndoRemove(where, removedText);
}
/**
@@ -379,7 +458,6 @@ public class GapContent
if (index < 0)
index = -(index + 1);
positions.add(index, pos);
-
return pos;
}
@@ -398,12 +476,7 @@ public class GapContent
int delta = newSize - gapEnd + gapStart;
// Update the marks after the gapEnd.
- Vector v = getPositionsInRange(null, gapEnd, buffer.length - gapEnd);
- for (Iterator i = v.iterator(); i.hasNext();)
- {
- GapContentPosition p = (GapContentPosition) i.next();
- p.mark += delta;
- }
+ adjustPositionsInRange(gapEnd, buffer.length - gapEnd, delta);
// Copy the data around.
char[] newBuf = (char[]) allocateArray(length() + newSize);
@@ -426,18 +499,11 @@ public class GapContent
return;
int newGapEnd = newGapStart + gapEnd - gapStart;
-
if (newGapStart < gapStart)
{
// Update the positions between newGapStart and (old) gapStart. The marks
// must be shifted by (gapEnd - gapStart).
- Vector v = getPositionsInRange(null, newGapStart + 1,
- gapStart - newGapStart + 1);
- for (Iterator i = v.iterator(); i.hasNext();)
- {
- GapContentPosition p = (GapContentPosition) i.next();
- p.mark += gapEnd - gapStart;
- }
+ adjustPositionsInRange(newGapStart, gapStart - newGapStart, gapEnd - gapStart);
System.arraycopy(buffer, newGapStart, buffer, newGapEnd, gapStart
- newGapStart);
gapStart = newGapStart;
@@ -447,18 +513,14 @@ public class GapContent
{
// Update the positions between newGapEnd and (old) gapEnd. The marks
// must be shifted by (gapEnd - gapStart).
- Vector v = getPositionsInRange(null, gapEnd,
- newGapEnd - gapEnd);
- for (Iterator i = v.iterator(); i.hasNext();)
- {
- GapContentPosition p = (GapContentPosition) i.next();
- p.mark -= gapEnd - gapStart;
- }
+ adjustPositionsInRange(gapEnd, newGapEnd - gapEnd, -(gapEnd - gapStart));
System.arraycopy(buffer, gapEnd, buffer, gapStart, newGapStart
- gapStart);
gapStart = newGapStart;
gapEnd = newGapEnd;
}
+ if (gapStart == 0)
+ resetMarksAtZero();
}
/**
@@ -476,12 +538,7 @@ public class GapContent
assert newGapStart < gapStart : "The new gap start must be less than the "
+ "old gap start.";
- Vector v = getPositionsInRange(null, newGapStart, gapStart - newGapStart);
- for (Iterator i = v.iterator(); i.hasNext();)
- {
- GapContentPosition p = (GapContentPosition) i.next();
- p.mark = gapStart;
- }
+ setPositionsInRange(newGapStart, gapStart - newGapStart, gapStart);
gapStart = newGapStart;
}
@@ -500,12 +557,7 @@ public class GapContent
assert newGapEnd > gapEnd : "The new gap end must be greater than the "
+ "old gap end.";
- Vector v = getPositionsInRange(null, gapEnd, newGapEnd - gapEnd);
- for (Iterator i = v.iterator(); i.hasNext();)
- {
- GapContentPosition p = (GapContentPosition) i.next();
- p.mark = newGapEnd + 1;
- }
+ setPositionsInRange(gapEnd, newGapEnd - gapEnd, newGapEnd + 1);
gapEnd = newGapEnd;
}
@@ -530,9 +582,11 @@ public class GapContent
protected void replace(int position, int rmSize, Object addItems,
int addSize)
{
+ if (gapStart != position)
+ shiftGap(position);
// Remove content
- shiftGap(position);
- shiftGapEndUp(gapEnd + rmSize);
+ if (rmSize > 0)
+ shiftGapEndUp(gapEnd + rmSize);
// If gap is too small, enlarge the gap.
if ((gapEnd - gapStart) <= addSize)
@@ -588,21 +642,121 @@ public class GapContent
int index1 = Collections.binarySearch(positions,
new GapContentPosition(offset));
- int index2 = Collections.binarySearch(positions,
- new GapContentPosition(endOffset));
if (index1 < 0)
index1 = -(index1 + 1);
- if (index2 < 0)
- index2 = -(index2 + 1);
for (ListIterator i = positions.listIterator(index1); i.hasNext();)
{
- if (i.nextIndex() > index2)
- break;
-
GapContentPosition p = (GapContentPosition) i.next();
+ if (p.mark > endOffset)
+ break;
if (p.mark >= offset && p.mark <= endOffset)
res.add(p);
}
return res;
}
+
+ /**
+ * Sets the mark of all <code>Position</code>s that are in the range
+ * specified by <code>offset</code> and </code>length</code> within
+ * the buffer array to <code>value</code>
+ *
+ * @param offset the start offset of the range to search
+ * @param length the length of the range to search
+ * @param value the new value for each mark
+ */
+ void setPositionsInRange(int offset, int length, int value)
+ {
+ int endOffset = offset + length;
+
+ int index1 = Collections.binarySearch(positions,
+ new GapContentPosition(offset));
+ if (index1 < 0)
+ index1 = -(index1 + 1);
+ for (ListIterator i = positions.listIterator(index1); i.hasNext();)
+ {
+ GapContentPosition p = (GapContentPosition) i.next();
+ if (p.mark > endOffset)
+ break;
+
+ if (p.mark >= offset && p.mark <= endOffset)
+ p.mark = value;
+ }
+ }
+
+ /**
+ * Adjusts the mark of all <code>Position</code>s that are in the range
+ * specified by <code>offset</code> and </code>length</code> within
+ * the buffer array by <code>increment</code>
+ *
+ * @param offset the start offset of the range to search
+ * @param length the length of the range to search
+ * @param incr the increment
+ */
+ void adjustPositionsInRange(int offset, int length, int incr)
+ {
+ int endOffset = offset + length;
+
+ int index1 = Collections.binarySearch(positions,
+ new GapContentPosition(offset));
+ if (index1 < 0)
+ index1 = -(index1 + 1);
+ for (ListIterator i = positions.listIterator(index1); i.hasNext();)
+ {
+ GapContentPosition p = (GapContentPosition) i.next();
+ if (p.mark > endOffset)
+ break;
+
+ if (p.mark >= offset && p.mark <= endOffset)
+ p.mark += incr;
+ }
+ }
+
+ /**
+ * Resets all <code>Position</code> that have an offset of <code>0</code>,
+ * to also have an array index of <code>0</code>. This might be necessary
+ * after a call to <code>shiftGap(0)</code>, since then the marks at offset
+ * <code>0</code> get shifted to <code>gapEnd</code>.
+ */
+ protected void resetMarksAtZero()
+ {
+ if (gapStart != 0)
+ return;
+
+ setPositionsInRange(gapEnd, 0, 0);
+ }
+
+ /**
+ * Outputs debugging info to System.err. It prints out the buffer array,
+ * the gapStart is marked by a &lt; sign, the gapEnd is marked by a &gt;
+ * sign and each position is marked by a # sign.
+ */
+ private void dump()
+ {
+ System.err.println("GapContent debug information");
+ System.err.println("buffer length: " + buffer.length);
+ System.err.println("gap start: " + gapStart);
+ System.err.println("gap end: " + gapEnd);
+ for (int i = 0; i < buffer.length; i++)
+ {
+ if (i == gapStart)
+ System.err.print('<');
+ if (i == gapEnd)
+ System.err.print('>');
+
+ if (!Character.isISOControl(buffer[i]))
+ System.err.print(buffer[i]);
+ else
+ System.err.print('.');
+ }
+ System.err.println();
+ }
+
+ private void dumpPositions()
+ {
+ for (Iterator i = positions.iterator(); i.hasNext();)
+ {
+ GapContentPosition pos = (GapContentPosition) i.next();
+ System.err.println("position at: " + pos.mark);
+ }
+ }
}
diff --git a/javax/swing/text/GlyphView.java b/javax/swing/text/GlyphView.java
index 6ffab23c4..b516d20e4 100644
--- a/javax/swing/text/GlyphView.java
+++ b/javax/swing/text/GlyphView.java
@@ -44,6 +44,7 @@ import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Shape;
+import java.awt.Toolkit;
import java.text.BreakIterator;
import javax.swing.SwingConstants;
@@ -71,6 +72,7 @@ public class GlyphView extends View implements TabableView, Cloneable
*/
public GlyphPainter()
{
+ // Nothing to do here.
}
/**
@@ -258,7 +260,7 @@ public class GlyphView extends View implements TabableView, Cloneable
public float getHeight(GlyphView view)
{
Font font = view.getFont();
- FontMetrics metrics = view.getContainer().getFontMetrics(font);
+ FontMetrics metrics = Toolkit.getDefaultToolkit().getFontMetrics(font);
float height = metrics.getHeight();
return height;
}
@@ -377,7 +379,7 @@ public class GlyphView extends View implements TabableView, Cloneable
{
Element el = view.getElement();
Font font = view.getFont();
- FontMetrics fm = view.getContainer().getFontMetrics(font);
+ FontMetrics fm = Toolkit.getDefaultToolkit().getFontMetrics(font);
Segment txt = view.getText(p0, p1);
int span = Utilities.getTabbedTextWidth(txt, fm, (int) x, te, p0);
return span;
@@ -664,8 +666,11 @@ public class GlyphView extends View implements TabableView, Cloneable
}
catch (BadLocationException ex)
{
- throw new AssertionError("BadLocationException must not be thrown "
- + "here");
+ AssertionError ae;
+ ae = new AssertionError("BadLocationException must not be thrown "
+ + "here");
+ ae.initCause(ex);
+ throw ae;
}
FontMetrics fm = null; // Fetch font metrics somewhere.
return Utilities.getTabbedTextWidth(seg, fm, 0, null, p0);
@@ -712,8 +717,11 @@ public class GlyphView extends View implements TabableView, Cloneable
}
catch (BadLocationException ex)
{
- throw new AssertionError("BadLocationException should not be "
- + "thrown here. p0 = " + p0 + ", p1 = " + p1);
+ AssertionError ae;
+ ae = new AssertionError("BadLocationException should not be "
+ + "thrown here. p0 = " + p0 + ", p1 = " + p1);
+ ae.initCause(ex);
+ throw ae;
}
return txt;
diff --git a/javax/swing/text/JTextComponent.java b/javax/swing/text/JTextComponent.java
index 63dbf2a4b..be68cd5d7 100644
--- a/javax/swing/text/JTextComponent.java
+++ b/javax/swing/text/JTextComponent.java
@@ -53,6 +53,7 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputMethodListener;
import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
@@ -89,6 +90,7 @@ public abstract class JTextComponent extends JComponent
/**
* AccessibleJTextComponent
*/
+ // FIXME: This inner class is a complete stub and needs to be implemented.
public class AccessibleJTextComponent extends AccessibleJComponent
implements AccessibleText, CaretListener, DocumentListener
{
@@ -99,6 +101,7 @@ public abstract class JTextComponent extends JComponent
*/
public AccessibleJTextComponent()
{
+ // Nothing to do here.
}
/**
@@ -321,7 +324,7 @@ public abstract class JTextComponent extends JComponent
{
Caret c = caret;
if (c != null)
- c.setVisible(!c.isVisible());
+ c.setVisible(!c.isVisible());
}
/**
@@ -332,13 +335,13 @@ public abstract class JTextComponent extends JComponent
stop();
Caret c = caret;
if (c != null)
- {
- setDelay(c.getBlinkRate());
- if (editable)
- start();
- else
- c.setVisible(false);
- }
+ {
+ setDelay(c.getBlinkRate());
+ if (editable)
+ start();
+ else
+ c.setVisible(false);
+ }
}
}
@@ -628,23 +631,23 @@ public abstract class JTextComponent extends JComponent
int end = textComponent.getSelectionEnd();
if (start == end)
- return;
+ return;
try
- {
- // Copy text to clipboard.
- String data = textComponent.getDocument().getText(start, end);
- StringSelection selection = new StringSelection(data);
- clipboard.setContents(selection, null);
-
- // Delete selected text on cut action.
- if (action == MOVE)
- doc.remove(start, end - start);
- }
+ {
+ // Copy text to clipboard.
+ String data = textComponent.getDocument().getText(start, end);
+ StringSelection selection = new StringSelection(data);
+ clipboard.setContents(selection, null);
+
+ // Delete selected text on cut action.
+ if (action == MOVE)
+ doc.remove(start, end - start);
+ }
catch (BadLocationException e)
- {
- // Ignore this and do nothing.
- }
+ {
+ // Ignore this and do nothing.
+ }
}
public int getSourceActions()
@@ -658,30 +661,30 @@ public abstract class JTextComponent extends JComponent
DataFlavor[] flavors = transferable.getTransferDataFlavors();
if (flavors == null)
- return false;
+ return false;
for (int i = 0; i < flavors.length; ++i)
- if (flavors[i].equals(DataFlavor.stringFlavor))
- flavor = flavors[i];
+ if (flavors[i].equals(DataFlavor.stringFlavor))
+ flavor = flavors[i];
if (flavor == null)
- return false;
+ return false;
try
- {
- JTextComponent textComponent = (JTextComponent) component;
- String data = (String) transferable.getTransferData(flavor);
- textComponent.replaceSelection(data);
- return true;
- }
+ {
+ JTextComponent textComponent = (JTextComponent) component;
+ String data = (String) transferable.getTransferData(flavor);
+ textComponent.replaceSelection(data);
+ return true;
+ }
catch (IOException e)
- {
- // Ignored.
- }
+ {
+ // Ignored.
+ }
catch (UnsupportedFlavorException e)
- {
- // Ignored.
- }
+ {
+ // Ignored.
+ }
return false;
}
@@ -1018,12 +1021,17 @@ public abstract class JTextComponent extends JComponent
{
try
{
- doc.remove(0, doc.getLength());
- doc.insertString(0, text, null);
+ if (doc instanceof AbstractDocument)
+ ((AbstractDocument) doc).replace(0, doc.getLength(), text, null);
+ else
+ {
+ doc.remove(0, doc.getLength());
+ doc.insertString(0, text, null);
+ }
}
catch (BadLocationException e)
{
- // This can never happen.
+ // This can never happen.
}
}
@@ -1041,12 +1049,12 @@ public abstract class JTextComponent extends JComponent
try
{
- return doc.getText(0, doc.getLength());
+ return doc.getText(0, doc.getLength());
}
catch (BadLocationException e)
{
- // This should never happen.
- return "";
+ // This should never happen.
+ return "";
}
}
@@ -1077,12 +1085,12 @@ public abstract class JTextComponent extends JComponent
{
try
{
- return doc.getText(getSelectionStart(), getSelectionEnd());
+ return doc.getText(getSelectionStart(), getSelectionEnd());
}
catch (BadLocationException e)
{
- // This should never happen.
- return null;
+ // This should never happen.
+ return null;
}
}
@@ -1420,28 +1428,28 @@ public abstract class JTextComponent extends JComponent
// If content is empty delete selection.
if (content == null)
{
- caret.setDot(dot);
- return;
+ caret.setDot(dot);
+ return;
}
try
{
- int start = getSelectionStart();
- int end = getSelectionEnd();
-
- // Remove selected text.
- if (dot != mark)
- doc.remove(start, end - start);
-
- // Insert new text.
- doc.insertString(start, content, null);
-
- // Set dot to new position.
- setCaretPosition(start + content.length());
+ int start = getSelectionStart();
+ int end = getSelectionEnd();
+
+ // Remove selected text.
+ if (dot != mark)
+ doc.remove(start, end - start);
+
+ // Insert new text.
+ doc.insertString(start, content, null);
+
+ // Set dot to new position.
+ setCaretPosition(start + content.length());
}
catch (BadLocationException e)
{
- // This should never happen.
+ // This should never happen.
}
}
@@ -1575,15 +1583,15 @@ public abstract class JTextComponent extends JComponent
// Install default TransferHandler if none set.
if (getTransferHandler() == null)
{
- if (defaultTransferHandler == null)
- defaultTransferHandler = new DefaultTransferHandler();
-
- setTransferHandler(defaultTransferHandler);
+ if (defaultTransferHandler == null)
+ defaultTransferHandler = new DefaultTransferHandler();
+
+ setTransferHandler(defaultTransferHandler);
}
// Perform action.
ActionEvent event = new ActionEvent(this, ActionEvent.ACTION_PERFORMED,
- action.getValue(Action.NAME).toString());
+ action.getValue(Action.NAME).toString());
action.actionPerformed(event);
}
@@ -1667,5 +1675,20 @@ public abstract class JTextComponent extends JComponent
throws IOException
{
output.write(getText());
- }
+ }
+
+ /**
+ * Returns the tooltip text for this text component for the given mouse
+ * event. This forwards the call to
+ * {@link TextUI#getToolTipText(JTextComponent, Point)}.
+ *
+ * @param ev the mouse event
+ *
+ * @return the tooltip text for this text component for the given mouse
+ * event
+ */
+ public String getToolTipText(MouseEvent ev)
+ {
+ return getUI().getToolTipText(this, ev.getPoint());
+ }
}
diff --git a/javax/swing/text/LabelView.java b/javax/swing/text/LabelView.java
index a10391613..4890735b9 100644
--- a/javax/swing/text/LabelView.java
+++ b/javax/swing/text/LabelView.java
@@ -38,10 +38,57 @@ exception statement from your version. */
package javax.swing.text;
-// TODO: Implement this class.
-public class LabelView
- extends GlyphView
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Shape;
+
+import javax.swing.event.DocumentEvent;
+
+/**
+ * A {@link GlyphView} that caches the textattributes for most effective
+ * rendering.
+ *
+ * @author Roman Kennke (kennke@aicas.com)
+ */
+public class LabelView extends GlyphView
{
+
+ /**
+ * The background color.
+ */
+ Color background;
+
+ /**
+ * The foreground color.
+ */
+ Color foreground;
+
+ /**
+ * The background color.
+ */
+ Font font;
+
+ /**
+ * The strikethrough flag.
+ */
+ boolean strikeThrough;
+
+ /**
+ * The underline flag.
+ */
+ boolean underline;
+
+ /**
+ * The subscript flag.
+ */
+ boolean subscript;
+
+ /**
+ * The superscript flag.
+ */
+ boolean superscript;
+
/**
* Creates a new <code>GlyphView</code> for the given <code>Element</code>.
*
@@ -50,5 +97,194 @@ public class LabelView
public LabelView(Element element)
{
super(element);
+ setPropertiesFromAttributes();
+ }
+
+ /**
+ * Loads the properties of this label view from the element's text
+ * attributes. This method is called from the constructor and the
+ * {@link #changedUpdate} method
+ */
+ protected void setPropertiesFromAttributes()
+ {
+ Element el = getElement();
+ AttributeSet atts = el.getAttributes();
+ background = StyleConstants.getBackground(atts);
+ foreground = StyleConstants.getForeground(atts);
+ strikeThrough = StyleConstants.isStrikeThrough(atts);
+ subscript = StyleConstants.isSubscript(atts);
+ superscript = StyleConstants.isSuperscript(atts);
+ underline = StyleConstants.isUnderline(atts);
+
+ // Determine the font.
+ String family = StyleConstants.getFontFamily(atts);
+ int size = StyleConstants.getFontSize(atts);
+ int style = Font.PLAIN;
+ if (StyleConstants.isBold(atts))
+ style |= Font.BOLD;
+ if (StyleConstants.isItalic(atts))
+ style |= Font.ITALIC;
+ font = new Font(family, style, size);
+ }
+
+ /**
+ * Receives notification when text attributes change in the chunk of
+ * text that this view is responsible for. This simply calls
+ * {@link #setPropertiesFromAttributes()}.
+ *
+ * @param e the document event
+ * @param a the allocation of this view
+ * @param vf the view factory to use for creating new views
+ */
+ public void changedUpdate(DocumentEvent e, Shape a, ViewFactory vf)
+ {
+ setPropertiesFromAttributes();
+ }
+
+ /**
+ * Returns the background color for the glyphs.
+ *
+ * @return the background color for the glyphs
+ */
+ public Color getBackground()
+ {
+ return background;
+ }
+
+ /**
+ * Sets the background color for the glyphs. A value of <code>null</code>
+ * means the background of the parent view should shine through.
+ *
+ * @param bg the background to set or <code>null</code>
+ *
+ * @since 1.5
+ */
+ protected void setBackground(Color bg)
+ {
+ background = bg;
+ }
+
+ /**
+ * Returns the foreground color for the glyphs.
+ *
+ * @return the foreground color for the glyphs
+ */
+ public Color getForeground()
+ {
+ return foreground;
+ }
+
+ /**
+ * Returns the font for the glyphs.
+ *
+ * @return the font for the glyphs
+ */
+ public Font getFont()
+ {
+ return font;
+ }
+
+ /**
+ * Returns the font metrics of the current font.
+ *
+ * @return the font metrics of the current font
+ *
+ * @deprecated this is not used anymore
+ */
+ protected FontMetrics getFontMetrics()
+ {
+ return getContainer().getGraphics().getFontMetrics(font);
+ }
+
+ /**
+ * Returns <code>true</code> if the glyphs are rendered underlined,
+ * <code>false</code> otherwise.
+ *
+ * @return <code>true</code> if the glyphs are rendered underlined,
+ * <code>false</code> otherwise
+ */
+ public boolean isUnderline()
+ {
+ return underline;
+ }
+
+ /**
+ * Sets the underline flag.
+ *
+ * @param flag <code>true</code> if the glyphs are rendered underlined,
+ * <code>false</code> otherwise
+ */
+ protected void setUnderline(boolean flag)
+ {
+ underline = flag;
+ }
+
+ /**
+ * Returns <code>true</code> if the glyphs are rendered as subscript,
+ * <code>false</code> otherwise.
+ *
+ * @return <code>true</code> if the glyphs are rendered as subscript,
+ * <code>false</code> otherwise
+ */
+ public boolean isSubscript()
+ {
+ return subscript;
+ }
+
+ /**
+ * Sets the subscript flag.
+ *
+ * @param flag <code>true</code> if the glyphs are rendered as subscript,
+ * <code>false</code> otherwise
+ */
+ protected void setSubscript(boolean flag)
+ {
+ subscript = flag;
+ }
+
+ /**
+ * Returns <code>true</code> if the glyphs are rendered as superscript,
+ * <code>false</code> otherwise.
+ *
+ * @return <code>true</code> if the glyphs are rendered as superscript,
+ * <code>false</code> otherwise
+ */
+ public boolean isSuperscript()
+ {
+ return superscript;
+ }
+
+ /**
+ * Sets the superscript flag.
+ *
+ * @param flag <code>true</code> if the glyphs are rendered as superscript,
+ * <code>false</code> otherwise
+ */
+ protected void setSuperscript(boolean flag)
+ {
+ superscript = flag;
+ }
+
+ /**
+ * Returns <code>true</code> if the glyphs are rendered strike-through,
+ * <code>false</code> otherwise.
+ *
+ * @return <code>true</code> if the glyphs are rendered strike-through,
+ * <code>false</code> otherwise
+ */
+ public boolean isStrikeThrough()
+ {
+ return strikeThrough;
+ }
+
+ /**
+ * Sets the strike-through flag.
+ *
+ * @param flag <code>true</code> if the glyphs are rendered strike-through,
+ * <code>false</code> otherwise
+ */
+ protected void setStrikeThrough(boolean flag)
+ {
+ strikeThrough = flag;
}
}
diff --git a/javax/swing/text/LayoutQueue.java b/javax/swing/text/LayoutQueue.java
index 83433b6ee..b0c84b972 100644
--- a/javax/swing/text/LayoutQueue.java
+++ b/javax/swing/text/LayoutQueue.java
@@ -57,6 +57,7 @@ public class LayoutQueue
*/
public LayoutQueue()
{
+ // Nothing to do here.
}
/**
diff --git a/javax/swing/text/ParagraphView.java b/javax/swing/text/ParagraphView.java
index 6c6006a2a..6fb121f94 100644
--- a/javax/swing/text/ParagraphView.java
+++ b/javax/swing/text/ParagraphView.java
@@ -59,6 +59,11 @@ public class ParagraphView extends FlowView implements TabExpander
{
super(el, X_AXIS);
}
+ public float getAlignment(int axis)
+ {
+ // FIXME: This is very likely not 100% correct. Work this out.
+ return 0.0F;
+ }
}
/**
@@ -86,4 +91,29 @@ public class ParagraphView extends FlowView implements TabExpander
{
return new Row(getElement());
}
+
+ /**
+ * Returns the alignment for this paragraph view for the specified axis.
+ * For the X_AXIS the paragraph view will be aligned at it's left edge
+ * (0.0F). For the Y_AXIS the paragraph view will be aligned at the
+ * center of it's first row.
+ *
+ * @param axis the axis which is examined
+ *
+ * @return the alignment for this paragraph view for the specified axis
+ */
+ public float getAlignment(int axis)
+ {
+ if (axis == X_AXIS)
+ return 0.0F;
+ else if (getViewCount() > 0)
+ {
+
+ float prefHeight = getPreferredSpan(Y_AXIS);
+ float firstRowHeight = getView(0).getPreferredSpan(Y_AXIS);
+ return (firstRowHeight / 2.F) / prefHeight;
+ }
+ else
+ return 0.0F;
+ }
}
diff --git a/javax/swing/text/PlainDocument.java b/javax/swing/text/PlainDocument.java
index 71070e92d..9e600c4c9 100644
--- a/javax/swing/text/PlainDocument.java
+++ b/javax/swing/text/PlainDocument.java
@@ -132,8 +132,8 @@ public class PlainDocument extends AbstractDocument
// collapse elements if the removal spans more than 1 line
Element newEl = createLeafElement(rootElement,
SimpleAttributeSet.EMPTY,
- start, end - len);
- rootElement.replace(i1, i2 - i1, new Element[]{ newEl });
+ start, end);
+ rootElement.replace(i1, i2 - i1 + 1, new Element[]{ newEl });
}
}
@@ -147,4 +147,28 @@ public class PlainDocument extends AbstractDocument
Element root = getDefaultRootElement();
return root.getElement(root.getElementIndex(pos));
}
+
+ /**
+ * Inserts a string into the document. If the document property
+ * '<code>filterNewLines</code>' is set to <code>Boolean.TRUE</code>, then
+ * all newlines in the inserted string are replaced by space characters,
+ * otherwise the superclasses behaviour is executed.
+ *
+ * Inserting content causes a write lock to be acquired during this method
+ * call.
+ *
+ * @param offs the offset at which to insert the string
+ * @param str the string to be inserted
+ * @param atts the text attributes of the string to be inserted
+ *
+ * @throws BadLocationException
+ */
+ public void insertString(int offs, String str, AttributeSet atts)
+ throws BadLocationException
+ {
+ String string = str;
+ if (Boolean.TRUE.equals(getProperty("filterNewlines")))
+ string = str.replaceAll("\n", " ");
+ super.insertString(offs, string, atts);
+ }
}
diff --git a/javax/swing/text/PlainView.java b/javax/swing/text/PlainView.java
index b93d9a4f1..07351ade9 100644
--- a/javax/swing/text/PlainView.java
+++ b/javax/swing/text/PlainView.java
@@ -46,8 +46,10 @@ import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Shape;
-public class PlainView extends View
- implements TabExpander
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentEvent.ElementChange;
+
+public class PlainView extends View implements TabExpander
{
Color selectedColor;
Color unselectedColor;
@@ -59,8 +61,19 @@ public class PlainView extends View
Font font;
+ /** The length of the longest line in the Document **/
+ float maxLineLength = -1;
+
+ /** The longest line in the Document **/
+ Element longestLine = null;
+
protected FontMetrics metrics;
+ /**
+ * The instance returned by {@link #getLineBuffer()}.
+ */
+ private transient Segment lineBuffer;
+
public PlainView(Element elem)
{
super(elem);
@@ -110,7 +123,7 @@ public class PlainView extends View
// Get the rectangle for position.
Element line = getElement().getElement(lineIndex);
int lineStart = line.getStartOffset();
- Segment segment = new Segment();
+ Segment segment = getLineBuffer();
document.getText(lineStart, position - lineStart, segment);
int xoffset = Utilities.getTabbedTextWidth(segment, metrics, rect.x,
this, lineStart);
@@ -135,7 +148,9 @@ public class PlainView extends View
}
catch (BadLocationException e)
{
- // This should never happen.
+ AssertionError ae = new AssertionError("Unexpected bad location");
+ ae.initCause(e);
+ throw ae;
}
}
@@ -143,7 +158,7 @@ public class PlainView extends View
throws BadLocationException
{
g.setColor(selectedColor);
- Segment segment = new Segment();
+ Segment segment = getLineBuffer();
getDocument().getText(p0, p1 - p0, segment);
return Utilities.drawTabbedText(segment, x, y, g, this, 0);
}
@@ -157,7 +172,7 @@ public class PlainView extends View
else
g.setColor(disabledColor);
- Segment segment = new Segment();
+ Segment segment = getLineBuffer();
getDocument().getText(p0, p1 - p0, segment);
return Utilities.drawTabbedText(segment, x, y, g, this, segment.offset);
}
@@ -188,9 +203,19 @@ public class PlainView extends View
}
}
+ /**
+ * Returns the tab size of a tab. Checks the Document's
+ * properties for PlainDocument.tabSizeAttribute and returns it if it is
+ * defined, otherwise returns 8.
+ *
+ * @return the tab size.
+ */
protected int getTabSize()
{
- return 8;
+ Object tabSize = getDocument().getProperty(PlainDocument.tabSizeAttribute);
+ if (tabSize == null)
+ return 8;
+ return ((Integer)tabSize).intValue();
}
/**
@@ -203,10 +228,54 @@ public class PlainView extends View
*/
public float nextTabStop(float x, int tabStop)
{
- float tabSizePixels = getTabSize() + metrics.charWidth('m');
+ float tabSizePixels = getTabSize() * metrics.charWidth('m');
return (float) (Math.floor(x / tabSizePixels) + 1) * tabSizePixels;
}
+ /**
+ * Returns the length of the longest line, used for getting the span
+ * @return the length of the longest line
+ */
+ float determineMaxLineLength()
+ {
+ // if the longest line is cached, return the cached value
+ if (maxLineLength != -1)
+ return maxLineLength;
+
+ // otherwise we have to go through all the lines and find it
+ Element el = getElement();
+ Segment seg = getLineBuffer();
+ float span = 0;
+ for (int i = 0; i < el.getElementCount(); i++)
+ {
+ Element child = el.getElement(i);
+ int start = child.getStartOffset();
+ int end = child.getEndOffset();
+ try
+ {
+ el.getDocument().getText(start, end - start, seg);
+ }
+ catch (BadLocationException ex)
+ {
+ AssertionError ae = new AssertionError("Unexpected bad location");
+ ae.initCause(ex);
+ throw ae;
+ }
+
+ if (seg == null || seg.array == null || seg.count == 0)
+ continue;
+
+ int width = metrics.charsWidth(seg.array, seg.offset, seg.count);
+ if (width > span)
+ {
+ longestLine = child;
+ span = width;
+ }
+ }
+ maxLineLength = span;
+ return maxLineLength;
+ }
+
public float getPreferredSpan(int axis)
{
if (axis != X_AXIS && axis != Y_AXIS)
@@ -217,36 +286,16 @@ public class PlainView extends View
float span = 0;
Element el = getElement();
- Document doc = el.getDocument();
- Segment seg = new Segment();
switch (axis)
{
case X_AXIS:
- // calculate the maximum of the line's widths
- for (int i = 0; i < el.getElementCount(); i++)
- {
- Element child = el.getElement(i);
- int start = child.getStartOffset();
- int end = child.getEndOffset();
- try {
- doc.getText(start, start + end, seg);
- }
- catch (BadLocationException ex)
- {
- // throw new ClasspathAssertionError
- // ("no BadLocationException should be thrown here");
- }
- int width = metrics.charsWidth(seg.array, seg.offset, seg.count);
- span = Math.max(span, width);
- }
- break;
+ span = determineMaxLineLength();
case Y_AXIS:
default:
span = metrics.getHeight() * el.getElementCount();
break;
}
-
return span;
}
@@ -264,8 +313,221 @@ public class PlainView extends View
*/
public int viewToModel(float x, float y, Shape a, Position.Bias[] b)
{
- // FIXME: not implemented
- return 0;
+ Rectangle rec = a.getBounds();
+ Document doc = getDocument();
+ Element root = doc.getDefaultRootElement();
+
+ // PlainView doesn't support line-wrapping so we can find out which
+ // Element was clicked on just by the y-position
+ int lineClicked = (int) (y - rec.y) / metrics.getHeight();
+ if (lineClicked >= root.getElementCount())
+ return getEndOffset() - 1;
+
+ Element line = root.getElement(lineClicked);
+ Segment s = getLineBuffer();
+
+ int start = line.getStartOffset();
+ int end = line.getEndOffset();
+ try
+ {
+ doc.getText(start, end - start, s);
+ }
+ catch (BadLocationException ble)
+ {
+ AssertionError ae = new AssertionError("Unexpected bad location");
+ ae.initCause(ble);
+ throw ae;
+ }
+
+ int pos = Utilities.getTabbedTextOffset(s, metrics, rec.x, (int)x, this, start);
+ return Math.max (0, pos);
+ }
+
+ /**
+ * Since insertUpdate and removeUpdate each deal with children
+ * Elements being both added and removed, they both have to perform
+ * the same checks. So they both simply call this method.
+ * @param changes the DocumentEvent for the changes to the Document.
+ * @param a the allocation of the View.
+ * @param f the ViewFactory to use for rebuilding.
+ */
+ protected void updateDamage(DocumentEvent changes, Shape a, ViewFactory f)
+ {
+ Element el = getElement();
+ ElementChange ec = changes.getChange(el);
+
+ // If ec is null then no lines were added or removed, just
+ // repaint the changed line
+ if (ec == null)
+ {
+ int line = getElement().getElementIndex(changes.getOffset());
+ damageLineRange(line, line, a, getContainer());
+ return;
+ }
+
+ Element[] removed = ec.getChildrenRemoved();
+ Element[] newElements = ec.getChildrenAdded();
+
+ // If no Elements were added or removed, we just want to repaint
+ // the area containing the line that was modified
+ if (removed == null && newElements == null)
+ {
+ int line = getElement().getElementIndex(changes.getOffset());
+ damageLineRange(line, line, a, getContainer());
+ return;
+ }
+
+ // Check to see if we removed the longest line, if so we have to
+ // search through all lines and find the longest one again
+ if (removed != null)
+ {
+ for (int i = 0; i < removed.length; i++)
+ if (removed[i].equals(longestLine))
+ {
+ // reset maxLineLength and search through all lines for longest one
+ maxLineLength = -1;
+ determineMaxLineLength();
+ ((JTextComponent)getContainer()).repaint();
+ return;
+ }
+ }
+
+ // If we've reached here, that means we haven't removed the longest line
+ if (newElements == null)
+ {
+ // No lines were added, just repaint the container and exit
+ ((JTextComponent)getContainer()).repaint();
+ return;
+ }
+
+ // Make sure we have the metrics
+ updateMetrics();
+
+ // If we've reached here, that means we haven't removed the longest line
+ // and we have added at least one line, so we have to check if added lines
+ // are longer than the previous longest line
+ Segment seg = getLineBuffer();
+ float longestNewLength = 0;
+ Element longestNewLine = null;
+
+ // Loop through the added lines to check their length
+ for (int i = 0; i < newElements.length; i++)
+ {
+ Element child = newElements[i];
+ int start = child.getStartOffset();
+ int end = child.getEndOffset();
+ try
+ {
+ el.getDocument().getText(start, end - start, seg);
+ }
+ catch (BadLocationException ex)
+ {
+ AssertionError ae = new AssertionError("Unexpected bad location");
+ ae.initCause(ex);
+ throw ae;
+ }
+
+ if (seg == null || seg.array == null || seg.count == 0)
+ continue;
+
+ int width = metrics.charsWidth(seg.array, seg.offset, seg.count);
+ if (width > longestNewLength)
+ {
+ longestNewLine = child;
+ longestNewLength = width;
+ }
+ }
+
+ // Check if the longest of the new lines is longer than our previous
+ // longest line, and if so update our values
+ if (longestNewLength > maxLineLength)
+ {
+ maxLineLength = longestNewLength;
+ longestLine = longestNewLine;
+ }
+ // Repaint the container
+ ((JTextComponent)getContainer()).repaint();
+ }
+
+ /**
+ * This method is called when something is inserted into the Document
+ * that this View is displaying.
+ *
+ * @param changes the DocumentEvent for the changes.
+ * @param a the allocation of the View
+ * @param f the ViewFactory used to rebuild
+ */
+ public void insertUpdate(DocumentEvent changes, Shape a, ViewFactory f)
+ {
+ updateDamage(changes, a, f);
+ }
+
+ /**
+ * This method is called when something is removed from the Document
+ * that this View is displaying.
+ *
+ * @param changes the DocumentEvent for the changes.
+ * @param a the allocation of the View
+ * @param f the ViewFactory used to rebuild
+ */
+ public void removeUpdate(DocumentEvent changes, Shape a, ViewFactory f)
+ {
+ updateDamage(changes, a, f);
+ }
+
+ /**
+ * This method is called when attributes were changed in the
+ * Document in a location that this view is responsible for.
+ */
+ public void changedUpdate (DocumentEvent changes, Shape a, ViewFactory f)
+ {
+ updateDamage(changes, a, f);
+ }
+
+ /**
+ * Repaint the given line range. This is called from insertUpdate,
+ * changedUpdate, and removeUpdate when no new lines were added
+ * and no lines were removed, to repaint the line that was
+ * modified.
+ *
+ * @param line0 the start of the range
+ * @param line1 the end of the range
+ * @param a the rendering region of the host
+ * @param host the Component that uses this View (used to call repaint
+ * on that Component)
+ *
+ * @since 1.4
+ */
+ protected void damageLineRange (int line0, int line1, Shape a, Component host)
+ {
+ if (a == null)
+ return;
+
+ Rectangle rec0 = lineToRect(a, line0);
+ Rectangle rec1 = lineToRect(a, line1);
+
+ if (rec0 == null || rec1 == null)
+ // something went wrong, repaint the entire host to be safe
+ host.repaint();
+ else
+ {
+ Rectangle repaintRec = rec0.union(rec1);
+ host.repaint();
+ }
+ }
+
+ /**
+ * Provides a {@link Segment} object, that can be used to fetch text from
+ * the document.
+ *
+ * @returna {@link Segment} object, that can be used to fetch text from
+ * the document
+ */
+ protected Segment getLineBuffer()
+ {
+ if (lineBuffer == null)
+ lineBuffer = new Segment();
+ return lineBuffer;
}
}
diff --git a/javax/swing/text/Segment.java b/javax/swing/text/Segment.java
index 92d850016..84e0e700f 100644
--- a/javax/swing/text/Segment.java
+++ b/javax/swing/text/Segment.java
@@ -39,8 +39,7 @@ package javax.swing.text;
import java.text.CharacterIterator;
-public class Segment
- implements Cloneable, CharacterIterator
+public class Segment implements Cloneable, CharacterIterator
{
private boolean partialReturn;
private int current;
@@ -51,6 +50,7 @@ public class Segment
public Segment()
{
+ // Nothing to do here.
}
public Segment(char[] array, int offset, int count)
diff --git a/javax/swing/text/SimpleAttributeSet.java b/javax/swing/text/SimpleAttributeSet.java
index 61cf5e97c..0c9f607b1 100644
--- a/javax/swing/text/SimpleAttributeSet.java
+++ b/javax/swing/text/SimpleAttributeSet.java
@@ -87,8 +87,30 @@ public class SimpleAttributeSet
return s;
}
+ /**
+ * Returns true if the given name and value represent an attribute
+ * found either in this AttributeSet or in its resolve parent hierarchy.
+ * @param name the key for the attribute
+ * @param value the value for the attribute
+ * @return true if the attribute is found here or in this set's resolve
+ * parent hierarchy
+ */
public boolean containsAttribute(Object name, Object value)
{
+ return (tab.containsKey(name) && tab.get(name).equals(value)) ||
+ (getResolveParent() != null && getResolveParent().
+ containsAttribute(name, value));
+ }
+
+ /**
+ * Returns true if the given name and value are found in this AttributeSet.
+ * Does not check the resolve parent.
+ * @param name the key for the attribute
+ * @param value the value for the attribute
+ * @return true if the attribute is found in this AttributeSet
+ */
+ boolean containsAttributeLocally(Object name, Object value)
+ {
return tab.containsKey(name)
&& tab.get(name).equals(value);
}
@@ -160,11 +182,15 @@ public class SimpleAttributeSet
{
return tab.isEmpty();
}
-
+
+ /**
+ * Returns true if the given set has the same number of attributes
+ * as this set and <code>containsAttributes(attr)</code> returns
+ * true.
+ */
public boolean isEqual(AttributeSet attr)
{
- return attr != null
- && attr.containsAttributes(this)
+ return getAttributeCount() == attr.getAttributeCount()
&& this.containsAttributes(attr);
}
@@ -173,9 +199,21 @@ public class SimpleAttributeSet
tab.remove(name);
}
+ /**
+ * Removes attributes from this set if they are found in the
+ * given set. Only attributes whose key AND value are removed.
+ * Removes attributes only from this set, not from the resolving parent.
+ */
public void removeAttributes(AttributeSet attributes)
{
- removeAttributes(attributes.getAttributeNames());
+ Enumeration e = attributes.getAttributeNames();
+ while (e.hasMoreElements())
+ {
+ Object name = e.nextElement();
+ Object val = attributes.getAttribute(name);
+ if (containsAttributeLocally(name, val))
+ removeAttribute(name);
+ }
}
public void removeAttributes(Enumeration names)
diff --git a/javax/swing/text/StyleContext.java b/javax/swing/text/StyleContext.java
index fba15f6fd..d73f430b0 100644
--- a/javax/swing/text/StyleContext.java
+++ b/javax/swing/text/StyleContext.java
@@ -306,9 +306,14 @@ public class StyleContext
return attrs[i+1];
}
- Object p = getResolveParent();
- if (p != null && p instanceof AttributeSet)
- return (((AttributeSet)p).getAttribute(key));
+ // Check the resolve parent, unless we're looking for the
+ // ResolveAttribute, which would cause an infinite loop
+ if (!(key.equals(ResolveAttribute)))
+ {
+ Object p = getResolveParent();
+ if (p != null && p instanceof AttributeSet)
+ return (((AttributeSet)p).getAttribute(key));
+ }
return null;
}
diff --git a/javax/swing/text/StyledDocument.java b/javax/swing/text/StyledDocument.java
index ea277540f..168e1b116 100644
--- a/javax/swing/text/StyledDocument.java
+++ b/javax/swing/text/StyledDocument.java
@@ -45,101 +45,96 @@ import java.awt.Font;
* @author Andrew Selkirk
* @version 1.0
*/
-public interface StyledDocument extends Document {
-
- //-------------------------------------------------------------
- // Methods ----------------------------------------------------
- //-------------------------------------------------------------
-
- /**
- * addStyle
- * @param nm TODO
- * @param rent TODO
- * @returns Style
- */
- Style addStyle(String nm, Style parent);
-
- /**
- * removeStyle
- * @param nm TODO
- */
- void removeStyle(String nm);
-
- /**
- * getStyle
- * @param nm TODO
- * @returns Style
- */
- Style getStyle(String nm);
-
- /**
- * setCharacterAttributes
- * @param offset TODO
- * @param length TODO
- * @param set TODO
- * @param replace TODO
- */
- void setCharacterAttributes(int offset, int length,
- AttributeSet set, boolean replace);
-
- /**
- * setParagraphAttributes
- * @param offset TODO
- * @param length TODO
- * @param set TODO
- * @param replace TODO
- */
- void setParagraphAttributes(int offset, int length,
- AttributeSet set, boolean replace);
-
- /**
- * getLogicalStyle
- * @param position TODO
- * @returns Style
- */
- Style getLogicalStyle(int position);
-
- /**
- * setLogicalStyle
- * @param position TODO
- * @param style TODO
- */
- void setLogicalStyle(int position, Style style);
-
- /**
- * getParagraphElement
- * @param position TODO
- * @returns Element
- */
- Element getParagraphElement(int position);
-
- /**
- * getCharacterElement
- * @param position TODO
- * @returns Element
- */
- Element getCharacterElement(int position);
-
- /**
- * getForeground
- * @param set TODO
- * @returns Color
- */
- Color getForeground(AttributeSet set);
-
- /**
- * getBackground
- * @param set TODO
- * @returns Color
- */
- Color getBackground(AttributeSet set);
-
- /**
- * getFont
- * @param set TODO
- * @returns Font
- */
- Font getFont(AttributeSet set);
-
-
-} // StyledDocument
+public interface StyledDocument extends Document
+{
+ /**
+ * addStyle
+ * @param nm TODO
+ * @param parent TODO
+ * @returns Style
+ */
+ Style addStyle(String nm, Style parent);
+
+ /**
+ * removeStyle
+ * @param nm TODO
+ */
+ void removeStyle(String nm);
+
+ /**
+ * getStyle
+ * @param nm TODO
+ * @returns Style
+ */
+ Style getStyle(String nm);
+
+ /**
+ * setCharacterAttributes
+ * @param offset TODO
+ * @param length TODO
+ * @param set TODO
+ * @param replace TODO
+ */
+ void setCharacterAttributes(int offset, int length, AttributeSet set,
+ boolean replace);
+
+ /**
+ * setParagraphAttributes
+ * @param offset TODO
+ * @param length TODO
+ * @param set TODO
+ * @param replace TODO
+ */
+ void setParagraphAttributes(int offset, int length, AttributeSet set,
+ boolean replace);
+
+ /**
+ * getLogicalStyle
+ * @param position TODO
+ * @returns Style
+ */
+ Style getLogicalStyle(int position);
+
+ /**
+ * setLogicalStyle
+ * @param position TODO
+ * @param style TODO
+ */
+ void setLogicalStyle(int position, Style style);
+
+ /**
+ * getParagraphElement
+ * @param position TODO
+ * @returns Element
+ */
+ Element getParagraphElement(int position);
+
+ /**
+ * getCharacterElement
+ * @param position TODO
+ * @returns Element
+ */
+ Element getCharacterElement(int position);
+
+ /**
+ * getForeground
+ * @param set TODO
+ * @returns Color
+ */
+ Color getForeground(AttributeSet set);
+
+ /**
+ * getBackground
+ * @param set TODO
+ * @returns Color
+ */
+ Color getBackground(AttributeSet set);
+
+ /**
+ * getFont
+ * @param set TODO
+ * @returns Font
+ */
+ Font getFont(AttributeSet set);
+
+}
diff --git a/javax/swing/text/Utilities.java b/javax/swing/text/Utilities.java
index 02d98c3b2..cdbe9f98e 100644
--- a/javax/swing/text/Utilities.java
+++ b/javax/swing/text/Utilities.java
@@ -40,6 +40,7 @@ package javax.swing.text;
import java.awt.FontMetrics;
import java.awt.Graphics;
+import java.text.BreakIterator;
/**
* A set of utilities to deal with text. This is used by several other classes
@@ -231,10 +232,17 @@ public class Utilities
// At the end of the for loop, this holds the requested model location
int pos;
int currentX = x0;
- for (pos = p0; pos < s.getEndIndex(); pos++)
+
+ for (pos = p0; pos < s.count; pos++)
{
- char nextChar = s.array[pos];
- if (nextChar != '\n')
+ char nextChar = s.array[s.offset+pos];
+ if (nextChar == 0)
+ {
+ if (! round)
+ pos--;
+ break;
+ }
+ if (nextChar != '\t')
currentX += fm.charWidth(nextChar);
else
{
@@ -243,7 +251,7 @@ public class Utilities
else
currentX = (int) te.nextTabStop(currentX, pos);
}
- if (currentX >= x)
+ if (currentX > x)
{
if (! round)
pos--;
@@ -280,4 +288,238 @@ public class Utilities
{
return getTabbedTextOffset(s, fm, x0, x, te, p0, true);
}
+
+ /**
+ * Finds the start of the next word for the given offset.
+ *
+ * @param c
+ * the text component
+ * @param offs
+ * the offset in the document
+ * @return the location in the model of the start of the next word.
+ * @throws BadLocationException
+ * if the offset is invalid.
+ */
+ public static final int getNextWord(JTextComponent c, int offs)
+ throws BadLocationException
+ {
+ if (offs < 0 || offs > (c.getText().length() - 1))
+ throw new BadLocationException("invalid offset specified", offs);
+ String text = c.getText();
+ BreakIterator wb = BreakIterator.getWordInstance();
+ wb.setText(text);
+ int last = wb.following(offs);
+ int current = wb.next();
+ while (current != BreakIterator.DONE)
+ {
+ for (int i = last; i < current; i++)
+ {
+ // FIXME: Should use isLetter(int) and text.codePointAt(int)
+ // instead, but isLetter(int) isn't implemented yet
+ if (Character.isLetter(text.charAt(i)))
+ return last;
+ }
+ last = current;
+ current = wb.next();
+ }
+ return BreakIterator.DONE;
+ }
+
+ /**
+ * Finds the start of the previous word for the given offset.
+ *
+ * @param c
+ * the text component
+ * @param offs
+ * the offset in the document
+ * @return the location in the model of the start of the previous word.
+ * @throws BadLocationException
+ * if the offset is invalid.
+ */
+ public static final int getPreviousWord(JTextComponent c, int offs)
+ throws BadLocationException
+ {
+ if (offs < 0 || offs > (c.getText().length() - 1))
+ throw new BadLocationException("invalid offset specified", offs);
+ String text = c.getText();
+ BreakIterator wb = BreakIterator.getWordInstance();
+ wb.setText(text);
+ int last = wb.preceding(offs);
+ int current = wb.previous();
+
+ while (current != BreakIterator.DONE)
+ {
+ for (int i = last; i < offs; i++)
+ {
+ // FIXME: Should use isLetter(int) and text.codePointAt(int)
+ // instead, but isLetter(int) isn't implemented yet
+ if (Character.isLetter(text.charAt(i)))
+ return last;
+ }
+ last = current;
+ current = wb.previous();
+ }
+ return 0;
+ }
+
+ /**
+ * Finds the start of a word for the given location.
+ * @param c the text component
+ * @param offs the offset location
+ * @return the location of the word beginning
+ * @throws BadLocationException if the offset location is invalid
+ */
+ public static final int getWordStart(JTextComponent c, int offs)
+ throws BadLocationException
+ {
+ if (offs < 0 || offs >= c.getText().length())
+ throw new BadLocationException("invalid offset specified", offs);
+
+ String text = c.getText();
+ BreakIterator wb = BreakIterator.getWordInstance();
+ wb.setText(text);
+ if (wb.isBoundary(offs))
+ return offs;
+ return wb.preceding(offs);
+ }
+
+ /**
+ * Finds the end of a word for the given location.
+ * @param c the text component
+ * @param offs the offset location
+ * @return the location of the word end
+ * @throws BadLocationException if the offset location is invalid
+ */
+ public static final int getWordEnd(JTextComponent c, int offs)
+ throws BadLocationException
+ {
+ if (offs < 0 || offs >= c.getText().length())
+ throw new BadLocationException("invalid offset specified", offs);
+
+ String text = c.getText();
+ BreakIterator wb = BreakIterator.getWordInstance();
+ wb.setText(text);
+ return wb.following(offs);
+ }
+
+ /**
+ * Get the model position of the end of the row that contains the
+ * specified model position. Return null if the given JTextComponent
+ * does not have a size.
+ * @param c the JTextComponent
+ * @param offs the model position
+ * @return the model position of the end of the row containing the given
+ * offset
+ * @throws BadLocationException if the offset is invalid
+ */
+ public static final int getRowEnd(JTextComponent c, int offs)
+ throws BadLocationException
+ {
+ String text = c.getText();
+ if (text == null)
+ return -1;
+
+ // Do a binary search for the smallest position X > offs
+ // such that that character at positino X is not on the same
+ // line as the character at position offs
+ int high = offs + ((text.length() - 1 - offs) / 2);
+ int low = offs;
+ int oldHigh = text.length() + 1;
+ while (true)
+ {
+ if (c.modelToView(high).y != c.modelToView(offs).y)
+ {
+ oldHigh = high;
+ high = low + ((high + 1 - low) / 2);
+ if (oldHigh == high)
+ return high - 1;
+ }
+ else
+ {
+ low = high;
+ high += ((oldHigh - high) / 2);
+ if (low == high)
+ return low;
+ }
+ }
+ }
+
+ /**
+ * Get the model position of the start of the row that contains the specified
+ * model position. Return null if the given JTextComponent does not have a
+ * size.
+ *
+ * @param c the JTextComponent
+ * @param offs the model position
+ * @return the model position of the start of the row containing the given
+ * offset
+ * @throws BadLocationException if the offset is invalid
+ */
+ public static final int getRowStart(JTextComponent c, int offs)
+ throws BadLocationException
+ {
+ String text = c.getText();
+ if (text == null)
+ return -1;
+
+ // Do a binary search for the greatest position X < offs
+ // such that the character at position X is not on the same
+ // row as the character at position offs
+ int high = offs;
+ int low = 0;
+ int oldLow = 0;
+ while (true)
+ {
+ if (c.modelToView(low).y != c.modelToView(offs).y)
+ {
+ oldLow = low;
+ low = high - ((high + 1 - low) / 2);
+ if (oldLow == low)
+ return low + 1;
+ }
+ else
+ {
+ high = low;
+ low -= ((low - oldLow) / 2);
+ if (low == high)
+ return low;
+ }
+ }
+ }
+
+ /**
+ * Determine where to break the text in the given Segment, attempting to find
+ * a word boundary.
+ * @param s the Segment that holds the text
+ * @param metrics the font metrics used for calculating the break point
+ * @param x0 starting view location representing the start of the text
+ * @param x the target view location
+ * @param e the TabExpander used for expanding tabs (if this is null tabs
+ * are expanded to 1 space)
+ * @param startOffset the offset in the Document of the start of the text
+ * @return the offset at which we should break the text
+ */
+ public static final int getBreakLocation(Segment s, FontMetrics metrics,
+ int x0, int x, TabExpander e,
+ int startOffset)
+ {
+ int mark = Utilities.getTabbedTextOffset(s, metrics, x0, x, e, startOffset);
+ BreakIterator breaker = BreakIterator.getWordInstance();
+ breaker.setText(s.toString());
+
+ // If mark is equal to the end of the string, just use that position
+ if (mark == s.count)
+ return mark;
+
+ // Try to find a word boundary previous to the mark at which we
+ // can break the text
+ int preceding = breaker.preceding(mark + 1);
+
+ if (preceding != 0)
+ return preceding;
+ else
+ // If preceding is 0 we couldn't find a suitable word-boundary so
+ // just break it on the character boundary
+ return mark;
+ }
}
diff --git a/javax/swing/text/View.java b/javax/swing/text/View.java
index 9cea4ecb0..7b3039cfb 100644
--- a/javax/swing/text/View.java
+++ b/javax/swing/text/View.java
@@ -86,9 +86,9 @@ public abstract class View implements SwingConstants
{
View parent = getParent();
if (parent == null)
- throw new AssertionError("The parent of a View must not be null.");
-
- return parent.getContainer();
+ return null;
+ else
+ return parent.getContainer();
}
public Document getDocument()
@@ -507,6 +507,30 @@ public abstract class View implements SwingConstants
}
/**
+ * Maps a position in the document into the coordinate space of the View.
+ * The output rectangle usually reflects the font height but has a width
+ * of zero.
+ *
+ * This method is deprecated and calls
+ * {@link #modelToView(int, Position.Bias, int, Position.Bias, Shape)} with
+ * a bias of {@link Position.Bias#Forward}.
+ *
+ * @param pos the position of the character in the model
+ * @param a the area that is occupied by the view
+ *
+ * @return a rectangle that gives the location of the document position
+ * inside the view coordinate space
+ *
+ * @throws BadLocationException if <code>pos</code> is invalid
+ *
+ * @deprecated Use {@link #modelToView(int, Shape, Position.Bias)} instead.
+ */
+ public Shape modelToView(int pos, Shape a) throws BadLocationException
+ {
+ return modelToView(pos, a, Position.Bias.Forward);
+ }
+
+ /**
* Maps coordinates from the <code>View</code>'s space into a position
* in the document model.
*
@@ -520,6 +544,25 @@ public abstract class View implements SwingConstants
*/
public abstract int viewToModel(float x, float y, Shape a, Position.Bias[] b);
+ /**
+ * Maps coordinates from the <code>View</code>'s space into a position
+ * in the document model. This method is deprecated and only there for
+ * compatibility.
+ *
+ * @param x the x coordinate in the view space
+ * @param y the y coordinate in the view space
+ * @param a the allocation of this <code>View</code>
+ *
+ * @return the position in the document that corresponds to the screen
+ * coordinates <code>x, y</code>
+ *
+ * @deprecated Use {@link #viewToModel(float, float, Shape, Position.Bias[])}
+ * instead.
+ */
+ public int viewToModel(float x, float y, Shape a)
+ {
+ return viewToModel(x, y, a, new Position.Bias[0]);
+ }
/**
* Dumps the complete View hierarchy. This method can be used for debugging
diff --git a/javax/swing/text/WrappedPlainView.java b/javax/swing/text/WrappedPlainView.java
new file mode 100644
index 000000000..02200d254
--- /dev/null
+++ b/javax/swing/text/WrappedPlainView.java
@@ -0,0 +1,547 @@
+/* WrappedPlainView.java --
+ Copyright (C) 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.text;
+
+import java.awt.Color;
+import java.awt.Container;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Rectangle;
+import java.awt.Shape;
+
+import javax.swing.event.DocumentEvent;
+import javax.swing.text.Position.Bias;
+
+/**
+ * @author abalkiss
+ *
+ */
+public class WrappedPlainView extends BoxView implements TabExpander
+{
+ /** The color for selected text **/
+ Color selectedColor;
+
+ /** The color for unselected text **/
+ Color unselectedColor;
+
+ /** The color for disabled components **/
+ Color disabledColor;
+
+ /** Stores the font metrics **/
+ protected FontMetrics metrics;
+
+ /** Whether or not to wrap on word boundaries **/
+ boolean wordWrap;
+
+ /** A ViewFactory that creates WrappedLines **/
+ ViewFactory viewFactory = new WrappedLineCreator();
+
+ /**
+ * The instance returned by {@link #getLineBuffer()}.
+ */
+ private transient Segment lineBuffer;
+
+ public WrappedPlainView (Element elem)
+ {
+ this (elem, false);
+ }
+
+ public WrappedPlainView (Element elem, boolean wordWrap)
+ {
+ super (elem, Y_AXIS);
+ this.wordWrap = wordWrap;
+ }
+
+ /**
+ * Provides access to the Segment used for retrievals from the Document.
+ * @return the Segment.
+ */
+ protected final Segment getLineBuffer()
+ {
+ if (lineBuffer == null)
+ lineBuffer = new Segment();
+ return lineBuffer;
+ }
+
+ /**
+ * Returns the next tab stop position after a given reference position.
+ *
+ * This implementation ignores the <code>tabStop</code> argument.
+ *
+ * @param x the current x position in pixels
+ * @param tabStop the position within the text stream that the tab occured at
+ */
+ public float nextTabStop(float x, int tabStop)
+ {
+ JTextComponent host = (JTextComponent)getContainer();
+ float tabSizePixels = getTabSize()
+ * host.getFontMetrics(host.getFont()).charWidth('m');
+ return (float) (Math.floor(x / tabSizePixels) + 1) * tabSizePixels;
+ }
+
+ /**
+ * Returns the tab size for the Document based on
+ * PlainDocument.tabSizeAttribute, defaulting to 8 if this property is
+ * not defined
+ *
+ * @return the tab size.
+ */
+ protected int getTabSize()
+ {
+ Object tabSize = getDocument().getProperty(PlainDocument.tabSizeAttribute);
+ if (tabSize == null)
+ return 8;
+ return ((Integer)tabSize).intValue();
+ }
+
+ /**
+ * Draws a line of text, suppressing white space at the end and expanding
+ * tabs. Calls drawSelectedText and drawUnselectedText.
+ * @param p0 starting document position to use
+ * @param p1 ending document position to use
+ * @param g graphics context
+ * @param x starting x position
+ * @param y starting y position
+ */
+ protected void drawLine(int p0, int p1, Graphics g, int x, int y)
+ {
+ try
+ {
+ drawUnselectedText(g, x, y, p0, p1);
+ }
+ catch (BadLocationException ble)
+ {
+ // shouldn't happen
+ }
+ }
+
+ /**
+ * Renders the range of text as selected text. Just paints the text
+ * in the color specified by the host component. Assumes the highlighter
+ * will render the selected background.
+ * @param g the graphics context
+ * @param x the starting X coordinate
+ * @param y the starting Y coordinate
+ * @param p0 the starting model location
+ * @param p1 the ending model location
+ * @return the X coordinate of the end of the text
+ * @throws BadLocationException if the given range is invalid
+ */
+ protected int drawSelectedText(Graphics g, int x, int y, int p0, int p1)
+ throws BadLocationException
+ {
+ g.setColor(selectedColor);
+ Segment segment = getLineBuffer();
+ getDocument().getText(p0, p1 - p0, segment);
+ return Utilities.drawTabbedText(segment, x, y, g, this, 0);
+ }
+
+ /**
+ * Renders the range of text as normal unhighlighted text.
+ * @param g the graphics context
+ * @param x the starting X coordinate
+ * @param y the starting Y coordinate
+ * @param p0 the starting model location
+ * @param p1 the end model location
+ * @return the X location of the end off the range
+ * @throws BadLocationException if the range given is invalid
+ */
+ protected int drawUnselectedText(Graphics g, int x, int y, int p0, int p1)
+ throws BadLocationException
+ {
+ JTextComponent textComponent = (JTextComponent) getContainer();
+ if (textComponent.isEnabled())
+ g.setColor(unselectedColor);
+ else
+ g.setColor(disabledColor);
+
+ Segment segment = getLineBuffer();
+ getDocument().getText(p0, p1 - p0, segment);
+ return Utilities.drawTabbedText(segment, x, y, g, this, segment.offset);
+ }
+
+ /**
+ * Loads the children to initiate the view. Called by setParent.
+ * Creates a WrappedLine for each child Element.
+ */
+ protected void loadChildren (ViewFactory f)
+ {
+ Element root = getElement();
+ int numChildren = root.getElementCount();
+ if (numChildren == 0)
+ return;
+
+ View[] children = new View[numChildren];
+ for (int i = 0; i < numChildren; i++)
+ children[i] = new WrappedLine(root.getElement(i));
+ replace(0, 0, children);
+ }
+
+ /**
+ * Calculates the break position for the text between model positions
+ * p0 and p1. Will break on word boundaries or character boundaries
+ * depending on the break argument given in construction of this
+ * WrappedPlainView. Used by the nested WrappedLine class to determine
+ * when to start the next logical line.
+ * @param p0 the start model position
+ * @param p1 the end model position
+ * @return the model position at which to break the text
+ */
+ protected int calculateBreakPosition(int p0, int p1)
+ {
+ Container c = getContainer();
+ Rectangle alloc = c.getBounds();
+ updateMetrics();
+ try
+ {
+ getDocument().getText(p0, p1 - p0, getLineBuffer());
+ }
+ catch (BadLocationException ble)
+ {
+ // this shouldn't happen
+ }
+ // FIXME: Should we account for the insets of the container?
+ if (wordWrap)
+ return p0
+ + Utilities.getBreakLocation(lineBuffer, metrics, alloc.x,
+ alloc.x + alloc.width, this, 0);
+ else
+ {
+ return p0
+ + Utilities.getTabbedTextOffset(lineBuffer, metrics, alloc.x,
+ alloc.x + alloc.width, this, 0);
+ }
+ }
+
+ void updateMetrics()
+ {
+ Container component = getContainer();
+ metrics = component.getFontMetrics(component.getFont());
+ }
+
+ /**
+ * Determines the preferred span along the given axis. Implemented to
+ * cache the font metrics and then call the super classes method.
+ */
+ public float getPreferredSpan (int axis)
+ {
+ updateMetrics();
+ return super.getPreferredSpan(axis);
+ }
+
+ /**
+ * Called when something was inserted. Overridden so that
+ * the view factory creates WrappedLine views.
+ */
+ public void insertUpdate (DocumentEvent e, Shape a, ViewFactory f)
+ {
+ super.insertUpdate(e, a, viewFactory);
+ // FIXME: could improve performance by repainting only the necessary area
+ getContainer().repaint();
+ }
+
+ /**
+ * Called when something is removed. Overridden so that
+ * the view factory creates WrappedLine views.
+ */
+ public void removeUpdate (DocumentEvent e, Shape a, ViewFactory f)
+ {
+ super.removeUpdate(e, a, viewFactory);
+ // FIXME: could improve performance by repainting only the necessary area
+ getContainer().repaint();
+ }
+
+ /**
+ * Called when the portion of the Document that this View is responsible
+ * for changes. Overridden so that the view factory creates
+ * WrappedLine views.
+ */
+ public void changedUpdate (DocumentEvent e, Shape a, ViewFactory f)
+ {
+ super.changedUpdate(e, a, viewFactory);
+ // FIXME: could improve performance by repainting only the necessary area
+ getContainer().repaint();
+ }
+
+ class WrappedLineCreator implements ViewFactory
+ {
+ // Creates a new WrappedLine
+ public View create(Element elem)
+ {
+ return new WrappedLine(elem);
+ }
+ }
+
+ /**
+ * Renders the <code>Element</code> that is associated with this
+ * <code>View</code>. Caches the metrics and then calls
+ * super.paint to paint all the child views.
+ *
+ * @param g the <code>Graphics</code> context to render to
+ * @param a the allocated region for the <code>Element</code>
+ */
+ public void paint(Graphics g, Shape a)
+ {
+ updateMetrics();
+ super.paint(g, a);
+ }
+
+ /**
+ * Sets the size of the View. Implemented to update the metrics
+ * and then call super method.
+ */
+ public void setSize (float width, float height)
+ {
+ updateMetrics();
+ super.setSize(width, height);
+ }
+
+ class WrappedLine extends View
+ {
+ /** Used to cache the number of lines for this View **/
+ int numLines;
+
+ public WrappedLine(Element elem)
+ {
+ super(elem);
+ determineNumLines();
+ }
+
+ /**
+ * Renders this (possibly wrapped) line using the given Graphics object
+ * and on the given rendering surface.
+ */
+ public void paint(Graphics g, Shape s)
+ {
+ // Ensure metrics are up-to-date.
+ updateMetrics();
+ JTextComponent textComponent = (JTextComponent) getContainer();
+
+ g.setFont(textComponent.getFont());
+ selectedColor = textComponent.getSelectedTextColor();
+ unselectedColor = textComponent.getForeground();
+ disabledColor = textComponent.getDisabledTextColor();
+
+ Rectangle rect = s.getBounds();
+ int lineHeight = metrics.getHeight();
+
+ int end = getEndOffset();
+ int currStart = getStartOffset();
+ int currEnd;
+ while (currStart < end)
+ {
+ currEnd = calculateBreakPosition(currStart, end);
+ drawLine(currStart, currEnd, g, rect.x, rect.y);
+ rect.y += lineHeight;
+ if (currEnd == currStart)
+ currStart ++;
+ else
+ currStart = currEnd;
+ }
+ }
+
+ /**
+ * Determines the number of logical lines that the Element
+ * needs to be displayed
+ * @return the number of lines needed to display the Element
+ */
+ int determineNumLines()
+ {
+ int end = getEndOffset();
+ if (end == 0)
+ return 0;
+
+ numLines = 0;
+ int breakPoint;
+ for (int i = getStartOffset(); i < end;)
+ {
+ numLines ++;
+ // careful: check that there's no off-by-one problem here
+ // depending on which position calculateBreakPosition returns
+ breakPoint = calculateBreakPosition(i, end);
+ if (breakPoint == i)
+ i ++;
+ else
+ i = breakPoint;
+ }
+ return numLines;
+ }
+
+ /**
+ * Determines the preferred span for this view along the given axis.
+ *
+ * @param axis the axis (either X_AXIS or Y_AXIS)
+ *
+ * @return the preferred span along the given axis.
+ * @throws IllegalArgumentException if axis is not X_AXIS or Y_AXIS
+ */
+ public float getPreferredSpan(int axis)
+ {
+ if (axis == X_AXIS)
+ return getWidth();
+ else if (axis == Y_AXIS)
+ return numLines * metrics.getHeight();
+
+ throw new IllegalArgumentException("Invalid axis for getPreferredSpan: "
+ + axis);
+ }
+
+ /**
+ * Provides a mapping from model space to view space.
+ *
+ * @param pos the position in the model
+ * @param a the region into which the view is rendered
+ * @param b the position bias (forward or backward)
+ *
+ * @return a box in view space that represents the given position
+ * in model space
+ * @throws BadLocationException if the given model position is invalid
+ */
+ public Shape modelToView(int pos, Shape a, Bias b) throws BadLocationException
+ {
+ Segment s = getLineBuffer();
+ int lineHeight = metrics.getHeight();
+ Rectangle rect = a.getBounds();
+
+ // Return a rectangle with width 1 and height equal to the height
+ // of the text
+ rect.height = lineHeight;
+ rect.width = 1;
+
+ int currLineStart = getStartOffset();
+ int end = getEndOffset();
+
+ if (pos < currLineStart || pos >= end)
+ throw new BadLocationException("invalid offset", pos);
+
+ while (true)
+ {
+ int currLineEnd = calculateBreakPosition(currLineStart, end);
+ // If pos is between currLineStart and currLineEnd then just find
+ // the width of the text from currLineStart to pos and add that
+ // to rect.x
+ if (pos >= currLineStart && pos < currLineEnd || pos == end - 1)
+ {
+ try
+ {
+ getDocument().getText(currLineStart, pos - currLineStart, s);
+ }
+ catch (BadLocationException ble)
+ {
+ // Shouldn't happen
+ }
+ rect.x += Utilities.getTabbedTextWidth(s, metrics, rect.x, WrappedPlainView.this, currLineStart);
+ return rect;
+ }
+ // Increment rect.y so we're checking the next logical line
+ rect.y += lineHeight;
+
+ // Increment currLineStart to the model position of the start
+ // of the next logical line
+ if (currLineEnd == currLineStart)
+ currLineStart = end;
+ else
+ currLineStart = currLineEnd;
+ }
+
+ }
+
+ /**
+ * Provides a mapping from view space to model space.
+ *
+ * @param x the x coordinate in view space
+ * @param y the y coordinate in view space
+ * @param a the region into which the view is rendered
+ * @param b the position bias (forward or backward)
+ *
+ * @return the location in the model that best represents the
+ * given point in view space
+ */
+ public int viewToModel(float x, float y, Shape a, Bias[] b)
+ {
+ Segment s = getLineBuffer();
+ Rectangle rect = a.getBounds();
+ int currLineStart = getStartOffset();
+ int end = getEndOffset();
+ int lineHeight = metrics.getHeight();
+ if (y < rect.y)
+ return currLineStart;
+ if (y > rect.y + rect.height)
+ return end - 1;
+
+ while (true)
+ {
+ int currLineEnd = calculateBreakPosition(currLineStart, end);
+ // If we're at the right y-position that means we're on the right
+ // logical line and we should look for the character
+ if (y >= rect.y && y < rect.y + lineHeight)
+ {
+ // Check if the x position is to the left or right of the text
+ if (x < rect.x)
+ return currLineStart;
+ if (x > rect.x + rect.width)
+ return currLineEnd - 1;
+
+ try
+ {
+ getDocument().getText(currLineStart, end - currLineStart, s);
+ }
+ catch (BadLocationException ble)
+ {
+ // Shouldn't happen
+ }
+ int mark = Utilities.getTabbedTextOffset(s, metrics, rect.x,
+ (int) x,
+ WrappedPlainView.this,
+ currLineStart);
+ return currLineStart + mark;
+ }
+ // Increment rect.y so we're checking the next logical line
+ rect.y += lineHeight;
+
+ // Increment currLineStart to the model position of the start
+ // of the next logical line
+ if (currLineEnd == currLineStart)
+ currLineStart = end;
+ else
+ currLineStart = currLineEnd;
+ }
+ }
+ }
+}
diff --git a/javax/swing/text/html/CSS.java b/javax/swing/text/html/CSS.java
index f02ceb89b..029ad26f8 100644
--- a/javax/swing/text/html/CSS.java
+++ b/javax/swing/text/html/CSS.java
@@ -34,8 +34,11 @@ 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.text.html;
+import java.util.HashMap;
+
/**
* Provides CSS attributes to be used by the HTML view classes. The constants
* defined here are used as keys for text attributes for use in
@@ -45,6 +48,30 @@ package javax.swing.text.html;
*/
public class CSS
{
+ /**
+ * Returns an array of all CSS attributes.
+ *
+ * @return All available CSS.Attribute objects.
+ */
+ public static CSS.Attribute[] getAllAttributeKeys()
+ {
+ Object[] src = Attribute.attributeMap.values().toArray();
+ CSS.Attribute[] dst = new CSS.Attribute[ src.length ];
+ System.arraycopy(src, 0, dst, 0, src.length);
+ return dst;
+ }
+
+ /**
+ * Returns an a given CSS attribute.
+ *
+ * @param name - The name of the attribute.
+ * @return The CSS attribute with the given name, or <code>null</code> if
+ * no attribute with that name exists.
+ */
+ public static CSS.Attribute getAttribute(String name)
+ {
+ return (CSS.Attribute)Attribute.attributeMap.get( name );
+ }
public static final class Attribute
{
@@ -377,6 +404,11 @@ public class CSS
String defaultValue;
/**
+ * A HashMap of all attributes.
+ */
+ static HashMap attributeMap;
+
+ /**
* Creates a new Attribute instance with the specified values.
*
* @param attr the attribute string
@@ -388,6 +420,9 @@ public class CSS
attStr = attr;
isInherited = inherited;
defaultValue = def;
+ if( attributeMap == null)
+ attributeMap = new HashMap();
+ attributeMap.put( attr, this );
}
/**
diff --git a/javax/swing/text/html/HTML.java b/javax/swing/text/html/HTML.java
index fa458ef45..09bf553b5 100644
--- a/javax/swing/text/html/HTML.java
+++ b/javax/swing/text/html/HTML.java
@@ -945,22 +945,22 @@ public class HTML
* This tag is not included into the array, returned by getAllTags().
* toString() returns 'comment'. HTML reader synthesizes this tag.
*/
- public static final Tag COMMENT = new Tag("comment", SYNTETIC);
+ public static final Tag COMMENT = new Tag("comment", SYNTHETIC);
/**
* All text content is labeled with this tag.
* This tag is not included into the array, returned by getAllTags().
* toString() returns 'content'. HTML reader synthesizes this tag.
*/
- public static final Tag CONTENT = new Tag("content", SYNTETIC);
+ public static final Tag CONTENT = new Tag("content", SYNTHETIC);
/**
* All text content must be in a paragraph element.
* If a paragraph didn't exist when content was encountered,
* a paragraph is manufactured.
- * toString() returns 'implied'. HTML reader synthesizes this tag.
+ * toString() returns 'p-implied'. HTML reader synthesizes this tag.
*/
- public static final Tag IMPLIED = new Tag("implied", SYNTETIC);
+ public static final Tag IMPLIED = new Tag("p-implied", SYNTHETIC);
final String name;
final int flags;
@@ -1144,7 +1144,7 @@ public class HTML
*/
boolean isSyntetic()
{
- return (flags & SYNTETIC) != 0;
+ return (flags & SYNTHETIC) != 0;
}
private static void unexpected(Exception ex)
@@ -1185,7 +1185,7 @@ public class HTML
static final int BREAKS = 1;
static final int BLOCK = 2;
static final int PREFORMATTED = 4;
- static final int SYNTETIC = 8;
+ static final int SYNTHETIC = 8;
private static Map<String,Tag> tagMap;
private static Map<String,Attribute> attrMap;
@@ -1196,6 +1196,7 @@ public class HTML
*/
public HTML()
{
+ // Nothing to do here.
}
/**
diff --git a/javax/swing/text/html/HTMLDocument.java b/javax/swing/text/html/HTMLDocument.java
index a95e496ec..d048a04e6 100644
--- a/javax/swing/text/html/HTMLDocument.java
+++ b/javax/swing/text/html/HTMLDocument.java
@@ -38,7 +38,14 @@ exception statement from your version. */
package javax.swing.text.html;
+import java.net.URL;
+
+import javax.swing.text.AbstractDocument;
+import javax.swing.text.AttributeSet;
import javax.swing.text.DefaultStyledDocument;
+import javax.swing.text.Element;
+import javax.swing.text.ElementIterator;
+import javax.swing.text.html.HTML.Tag;
/**
* TODO: This class is not yet completetely implemented.
@@ -47,7 +54,215 @@ import javax.swing.text.DefaultStyledDocument;
*/
public class HTMLDocument extends DefaultStyledDocument
{
+ /** A key for document properies. The value for the key is
+ * a Vector of Strings of comments not found in the body.
+ */
+ public static final String AdditionalComments = "AdditionalComments";
+ URL baseURL = null;
+ boolean preservesUnknownTags = true;
+
+ /**
+ * Returns the location against which to resolve relative URLs.
+ * This is the document's URL if the document was loaded from a URL.
+ * If a <code>base</code> tag is found, it will be used.
+ * @return the base URL
+ */
+ public URL getBase()
+ {
+ return baseURL;
+ }
+
+ /**
+ * Sets the location against which to resolve relative URLs.
+ * @param u the new base URL
+ */
+ public void setBase(URL u)
+ {
+ baseURL = u;
+ //TODO: also set the base of the StyleSheet
+ }
+
+ /**
+ * Returns whether or not the parser preserves unknown HTML tags.
+ * @return true if the parser preserves unknown tags
+ */
+ public boolean getPreservesUnknownTags()
+ {
+ return preservesUnknownTags;
+ }
+
+ /**
+ * Sets the behaviour of the parser when it encounters unknown HTML tags.
+ * @param preservesTags true if the parser should preserve unknown tags.
+ */
+ public void setPreservesUnknownTags(boolean preservesTags)
+ {
+ preservesUnknownTags = preservesTags;
+ }
+
+ /**
+ * An iterator to iterate through LeafElements in the document.
+ */
+ class LeafIterator extends Iterator
+ {
+ HTML.Tag tag;
+ HTMLDocument doc;
+ ElementIterator it;
+
+ public LeafIterator (HTML.Tag t, HTMLDocument d)
+ {
+ doc = d;
+ tag = t;
+ it = new ElementIterator(doc);
+ }
+
+ /**
+ * Return the attributes for the tag associated with this iteartor
+ * @return the AttributeSet
+ */
+ public AttributeSet getAttributes()
+ {
+ if (it.current() != null)
+ return it.current().getAttributes();
+ return null;
+ }
+
+ /**
+ * Get the end of the range for the current occurrence of the tag
+ * being defined and having the same attributes.
+ * @return the end of the range
+ */
+ public int getEndOffset()
+ {
+ if (it.current() != null)
+ return it.current().getEndOffset();
+ return -1;
+ }
+
+ /**
+ * Get the start of the range for the current occurrence of the tag
+ * being defined and having the same attributes.
+ * @return the start of the range (-1 if it can't be found).
+ */
+
+ public int getStartOffset()
+ {
+ if (it.current() != null)
+ return it.current().getStartOffset();
+ return -1;
+ }
+
+ /**
+ * Advance the iterator to the next LeafElement .
+ */
+ public void next()
+ {
+ it.next();
+ while (it.current()!= null && !it.current().isLeaf())
+ it.next();
+ }
+
+ /**
+ * Indicates whether or not the iterator currently represents an occurrence
+ * of the tag.
+ * @return true if the iterator currently represents an occurrence of the
+ * tag.
+ */
+ public boolean isValid()
+ {
+ return it.current() != null;
+ }
+
+ /**
+ * Type of tag for this iterator.
+ */
+ public Tag getTag()
+ {
+ return tag;
+ }
+
+ }
+
public void processHTMLFrameHyperlinkEvent(HTMLFrameHyperlinkEvent event)
{
+ // TODO: Implement this properly.
+ }
+
+ /**
+ * Gets an iterator for the given HTML.Tag.
+ * @param t the requested HTML.Tag
+ * @return the Iterator
+ */
+ public HTMLDocument.Iterator getIterator (HTML.Tag t)
+ {
+ return new HTMLDocument.LeafIterator(t, this);
+ }
+
+ /**
+ * An iterator over a particular type of tag.
+ */
+ public abstract static class Iterator
+ {
+ /**
+ * Return the attribute set for this tag.
+ * @return the <code>AttributeSet</code> (null if none found).
+ */
+ public abstract AttributeSet getAttributes();
+
+ /**
+ * Get the end of the range for the current occurrence of the tag
+ * being defined and having the same attributes.
+ * @return the end of the range
+ */
+ public abstract int getEndOffset();
+
+ /**
+ * Get the start of the range for the current occurrence of the tag
+ * being defined and having the same attributes.
+ * @return the start of the range (-1 if it can't be found).
+ */
+ public abstract int getStartOffset();
+
+ /**
+ * Move the iterator forward.
+ */
+ public abstract void next();
+
+ /**
+ * Indicates whether or not the iterator currently represents an occurrence
+ * of the tag.
+ * @return true if the iterator currently represents an occurrence of the
+ * tag.
+ */
+ public abstract boolean isValid();
+
+ /**
+ * Type of tag this iterator represents.
+ * @return the tag.
+ */
+ public abstract HTML.Tag getTag();
+ }
+
+ public class BlockElement extends AbstractDocument.BranchElement
+ {
+ public BlockElement (Element parent, AttributeSet a)
+ {
+ super (parent, a);
+ }
+
+ /**
+ * Gets the resolving parent. Since HTML attributes are not
+ * inherited at the model level, this returns null.
+ */
+ public AttributeSet getResolveParent()
+ {
+ return null;
+ }
+
+ public String getName()
+ {
+ //FIXME: this is supposed to do something different from the super class
+ return super.getName();
+ }
}
}
diff --git a/javax/swing/text/html/HTMLEditorKit.java b/javax/swing/text/html/HTMLEditorKit.java
index c0182fe6a..a52d96c74 100644
--- a/javax/swing/text/html/HTMLEditorKit.java
+++ b/javax/swing/text/html/HTMLEditorKit.java
@@ -43,8 +43,10 @@ import java.io.Reader;
import java.io.Serializable;
import javax.swing.text.BadLocationException;
+import javax.swing.text.Document;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.StyledEditorKit;
+import javax.swing.text.html.parser.ParserDelegator;
/**
* This class is NOT implemented. This file currently holds only
@@ -96,9 +98,9 @@ public class HTMLEditorKit
/**
* The parser calls this method after it finishes parsing the document.
*/
- public void flush()
- throws BadLocationException
+ public void flush() throws BadLocationException
{
+ // TODO: What to do here, if anything?
}
/**
@@ -108,6 +110,7 @@ public class HTMLEditorKit
*/
public void handleComment(char[] comment, int position)
{
+ // TODO: What to do here, if anything?
}
/**
@@ -118,6 +121,7 @@ public class HTMLEditorKit
*/
public void handleEndOfLineString(String end_of_line)
{
+ // TODO: What to do here, if anything?
}
/**
@@ -129,6 +133,7 @@ public class HTMLEditorKit
*/
public void handleEndTag(HTML.Tag tag, int position)
{
+ // TODO: What to do here, if anything?
}
/**
@@ -139,6 +144,7 @@ public class HTMLEditorKit
*/
public void handleError(String message, int position)
{
+ // TODO: What to do here, if anything?
}
/**
@@ -149,9 +155,9 @@ public class HTMLEditorKit
* @param position The tag position in the text being parsed.
*/
public void handleSimpleTag(HTML.Tag tag, MutableAttributeSet attributes,
- int position
- )
+ int position)
{
+ // TODO: What to do here, if anything?
}
/**
@@ -165,6 +171,7 @@ public class HTMLEditorKit
int position
)
{
+ // TODO: What to do here, if anything?
}
/**
@@ -174,6 +181,7 @@ public class HTMLEditorKit
*/
public void handleText(char[] text, int position)
{
+ // TODO: What to do here, if anything?
}
}
@@ -247,4 +255,26 @@ public class HTMLEditorKit
* The "ident paragraph right" action.
*/
public static final String PARA_INDENT_RIGHT = "html-para-indent-right";
-} \ No newline at end of file
+
+ /**
+ * Create a text storage model for this type of editor.
+ *
+ * @return the model
+ */
+ public Document createDefaultDocument()
+ {
+ HTMLDocument document = new HTMLDocument();
+ return document;
+ }
+
+ /**
+ * Get the parser that this editor kit uses for reading HTML streams. This
+ * method can be overridden to use the alternative parser.
+ *
+ * @return the HTML parser (by default, {@link ParserDelegator}).
+ */
+ protected Parser getParser()
+ {
+ return new ParserDelegator();
+ }
+}
diff --git a/javax/swing/text/html/HTMLFrameHyperlinkEvent.java b/javax/swing/text/html/HTMLFrameHyperlinkEvent.java
index dc0ab10a8..e146965d7 100644
--- a/javax/swing/text/html/HTMLFrameHyperlinkEvent.java
+++ b/javax/swing/text/html/HTMLFrameHyperlinkEvent.java
@@ -41,7 +41,6 @@ package javax.swing.text.html;
import java.net.URL;
import javax.swing.event.HyperlinkEvent;
-import javax.swing.event.HyperlinkEvent.EventType;
import javax.swing.text.Element;
/**
@@ -50,8 +49,7 @@ import javax.swing.text.Element;
*
* @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
*/
-public class HTMLFrameHyperlinkEvent
- extends HyperlinkEvent
+public class HTMLFrameHyperlinkEvent extends HyperlinkEvent
{
private final String target_frame;
diff --git a/javax/swing/text/html/parser/ContentModel.java b/javax/swing/text/html/parser/ContentModel.java
index deb7b1602..70e9c2acb 100644
--- a/javax/swing/text/html/parser/ContentModel.java
+++ b/javax/swing/text/html/parser/ContentModel.java
@@ -95,9 +95,12 @@ public final class ContentModel
*/
public int type;
- /** Create a content model initializing all fields to default values. */
+ /**
+ * Create a content model initializing all fields to default values.
+ */
public ContentModel()
{
+ // Nothing to do here.
}
/**
diff --git a/javax/swing/text/html/parser/DTD.java b/javax/swing/text/html/parser/DTD.java
index 42bf2e570..6e7aeb407 100644
--- a/javax/swing/text/html/parser/DTD.java
+++ b/javax/swing/text/html/parser/DTD.java
@@ -592,8 +592,7 @@ public class DTD
* @param name the name of the entity
* @param type the type of the entity, a bitwise combination
* of GENERAL, PARAMETER, SYSTEM and PUBLIC.
- * @throws an error if the parameter is both GENERAL and PARAMETER
- * of both PUBLIC and SYSTEM.
+ *
* @return the created entity
*/
private Entity newEntity(String name, int type)
diff --git a/javax/swing/text/html/parser/DocumentParser.java b/javax/swing/text/html/parser/DocumentParser.java
index 164297f18..062606d17 100644
--- a/javax/swing/text/html/parser/DocumentParser.java
+++ b/javax/swing/text/html/parser/DocumentParser.java
@@ -168,6 +168,7 @@ public class DocumentParser
* specific packages, write your own DTD or obtain the working instance
* of parser in other way, for example, by calling
* {@link javax.swing.text.html.HTMLEditorKit#getParser()}.
+ *
* @param a_dtd a DTD to use.
*/
public DocumentParser(DTD a_dtd)
@@ -212,6 +213,7 @@ public class DocumentParser
*/
protected void handleComment(char[] comment)
{
+ // This default implementation does nothing.
}
/**
@@ -224,6 +226,7 @@ public class DocumentParser
protected void handleEmptyTag(TagElement tag)
throws javax.swing.text.ChangedCharSetException
{
+ // This default implementation does nothing.
}
/**
@@ -234,11 +237,13 @@ public class DocumentParser
*/
protected void handleEndTag(TagElement tag)
{
+ // This default implementation does nothing.
}
/* Handle error that has occured in the given line. */
protected void handleError(int line, String message)
{
+ // This default implementation does nothing.
}
/**
@@ -249,6 +254,7 @@ public class DocumentParser
*/
protected void handleStartTag(TagElement tag)
{
+ // This default implementation does nothing.
}
/**
@@ -257,5 +263,6 @@ public class DocumentParser
*/
protected void handleText(char[] text)
{
+ // This default implementation does nothing.
}
}
diff --git a/javax/swing/text/html/parser/Element.java b/javax/swing/text/html/parser/Element.java
index 098983c69..c07c07f54 100644
--- a/javax/swing/text/html/parser/Element.java
+++ b/javax/swing/text/html/parser/Element.java
@@ -148,10 +148,10 @@ public final class Element
/**
* The default constructor must have package level access in this
* class. Use DTD.defineElement(..) to create an element when required.
- * @todo MAKE THIS PACKAGE in the final version. Now the Parser needs it!
*/
Element()
{
+ // Nothing to do here.
}
/**
diff --git a/javax/swing/text/html/parser/Parser.java b/javax/swing/text/html/parser/Parser.java
index 7ff6853da..a88e9ce19 100644
--- a/javax/swing/text/html/parser/Parser.java
+++ b/javax/swing/text/html/parser/Parser.java
@@ -256,6 +256,7 @@ public class Parser
*/
protected void endTag(boolean omitted)
{
+ // This default implementation does nothing.
}
/**
@@ -310,6 +311,7 @@ public class Parser
*/
protected void handleComment(char[] comment)
{
+ // This default implementation does nothing.
}
/**
@@ -333,6 +335,7 @@ public class Parser
protected void handleEmptyTag(TagElement tag)
throws ChangedCharSetException
{
+ // This default implementation does nothing.
}
/**
@@ -343,11 +346,13 @@ public class Parser
*/
protected void handleEndTag(TagElement tag)
{
+ // This default implementation does nothing.
}
/* Handle error that has occured in the given line. */
protected void handleError(int line, String message)
{
+ // This default implementation does nothing.
}
/**
@@ -358,6 +363,7 @@ public class Parser
*/
protected void handleStartTag(TagElement tag)
{
+ // This default implementation does nothing.
}
/**
@@ -376,6 +382,7 @@ public class Parser
*/
protected void handleText(char[] text)
{
+ // This default implementation does nothing.
}
/**
@@ -387,6 +394,7 @@ public class Parser
*/
protected void handleTitle(char[] title)
{
+ // This default implementation does nothing.
}
/**
@@ -420,6 +428,7 @@ public class Parser
*/
protected void markFirstTime(Element element)
{
+ // This default implementation does nothing.
}
/**
@@ -432,5 +441,6 @@ public class Parser
protected void startTag(TagElement tag)
throws ChangedCharSetException
{
+ // This default implementation does nothing.
}
}
diff --git a/javax/swing/tree/DefaultMutableTreeNode.java b/javax/swing/tree/DefaultMutableTreeNode.java
index 4a7da7d82..d767e8b88 100644
--- a/javax/swing/tree/DefaultMutableTreeNode.java
+++ b/javax/swing/tree/DefaultMutableTreeNode.java
@@ -45,7 +45,6 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.NoSuchElementException;
diff --git a/javax/swing/tree/DefaultTreeCellEditor.java b/javax/swing/tree/DefaultTreeCellEditor.java
index 91096ad19..2891a778e 100644
--- a/javax/swing/tree/DefaultTreeCellEditor.java
+++ b/javax/swing/tree/DefaultTreeCellEditor.java
@@ -47,7 +47,6 @@ import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Rectangle;
-import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
@@ -56,12 +55,8 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.EventObject;
-import javax.swing.CellRendererPane;
import javax.swing.DefaultCellEditor;
import javax.swing.Icon;
-import javax.swing.JCheckBox;
-import javax.swing.JComboBox;
-import javax.swing.JComponent;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
@@ -354,9 +349,9 @@ public class DefaultTreeCellEditor
/**
* Configures the editing component whenever it is null.
*
- * @param tree- the tree to configure to component for.
- * @param renderer- the renderer used to set up the nodes
- * @param editor- the editor used
+ * @param tree the tree to configure to component for.
+ * @param renderer the renderer used to set up the nodes
+ * @param editor the editor used
*/
private void configureEditingComponent(JTree tree,
DefaultTreeCellRenderer renderer,
@@ -607,7 +602,7 @@ public class DefaultTreeCellEditor
/**
* Messaged when the timer fires, this will start the editing session.
*
- * @param @param e - the event that characterizes the action.
+ * @param e the event that characterizes the action.
*/
public void actionPerformed(ActionEvent e)
{
diff --git a/javax/swing/tree/DefaultTreeModel.java b/javax/swing/tree/DefaultTreeModel.java
index 609592a73..b6205c5db 100644
--- a/javax/swing/tree/DefaultTreeModel.java
+++ b/javax/swing/tree/DefaultTreeModel.java
@@ -299,6 +299,7 @@ public class DefaultTreeModel
public void insertNodeInto(MutableTreeNode newChild, MutableTreeNode parent,
int index)
{
+ newChild.setParent(parent);
parent.insert(newChild, index);
int[] childIndices = new int[1];
childIndices[0] = index;
diff --git a/javax/swing/tree/TreeCellRenderer.java b/javax/swing/tree/TreeCellRenderer.java
index ebbe3fa91..a1808c9ee 100644
--- a/javax/swing/tree/TreeCellRenderer.java
+++ b/javax/swing/tree/TreeCellRenderer.java
@@ -46,22 +46,24 @@ import javax.swing.JTree;
* TreeCellRenderer public interface
* @author Andrew Selkirk
*/
-public interface TreeCellRenderer {
+public interface TreeCellRenderer
+{
- /**
- * getTreeCellRendererComponent
- * @param tree TODO
- * @param value TODO
- * @param selected TODO
- * @param expanded TODO
- * @param leaf TODO
- * @param row TODO
- * @param us TODO
- * @returns TODO
- */
- Component getTreeCellRendererComponent(JTree tree,
- Object value, boolean selected, boolean expanded,
- boolean leaf, int row, boolean hasFocus);
+ /**
+ * getTreeCellRendererComponent
+ * @param tree TODO
+ * @param value TODO
+ * @param selected TODO
+ * @param expanded TODO
+ * @param leaf TODO
+ * @param row TODO
+ * @param hasFocus TODO
+ * @returns TODO
+ */
+ Component getTreeCellRendererComponent(JTree tree, Object value,
+ boolean selected, boolean expanded,
+ boolean leaf, int row,
+ boolean hasFocus);
-} // TreeCellRenderer
+}
diff --git a/javax/swing/tree/TreeModel.java b/javax/swing/tree/TreeModel.java
index 759aaac58..ec1884efd 100644
--- a/javax/swing/tree/TreeModel.java
+++ b/javax/swing/tree/TreeModel.java
@@ -44,66 +44,62 @@ import javax.swing.event.TreeModelListener;
* TreeModel public interface
* @author Andrew Selkirk
*/
-public interface TreeModel {
-
- //-------------------------------------------------------------
- // Methods ----------------------------------------------------
- //-------------------------------------------------------------
-
- /**
- * getRoot
- * @returns Object
- */
- Object getRoot();
-
- /**
- * getChild
- * @param parent TODO
- * @param index TODO
- * @returns Object
- */
- Object getChild(Object parent, int index);
-
- /**
- * getChildCount
- * @param parent TODO
- * @returns int
- */
- int getChildCount(Object parent);
-
- /**
- * isLeaf
- * @param node TODO
- * @returns boolean
- */
- boolean isLeaf(Object node);
-
- /**
- * valueForPathChanged
- * @param path TODO
- * @param newvalue TODO
- */
- void valueForPathChanged(TreePath path, Object newvalue);
-
- /**
- * getIndexOfChild
- * @param parent TODO
- * @param ild TODO
- * @returns int
- */
- int getIndexOfChild(Object parent, Object child);
-
- /**
- * addTreeModelListener
- * @param listener TODO
- */
- void addTreeModelListener(TreeModelListener listener);
-
- /**
- * removeTreeModelListener
- * @param listener TODO
- */
- void removeTreeModelListener(TreeModelListener listener);
-
-
-} // TreeModel
+public interface TreeModel
+{
+ /**
+ * getRoot
+ * @returns Object
+ */
+ Object getRoot();
+
+ /**
+ * getChild
+ * @param parent TODO
+ * @param index TODO
+ * @returns Object
+ */
+ Object getChild(Object parent, int index);
+
+ /**
+ * getChildCount
+ * @param parent TODO
+ * @returns int
+ */
+ int getChildCount(Object parent);
+
+ /**
+ * isLeaf
+ * @param node TODO
+ * @returns boolean
+ */
+ boolean isLeaf(Object node);
+
+ /**
+ * valueForPathChanged
+ * @param path TODO
+ * @param newvalue TODO
+ */
+ void valueForPathChanged(TreePath path, Object newvalue);
+
+ /**
+ * getIndexOfChild
+ * @param parent TODO
+ * @param child TODO
+ * @returns int
+ */
+ int getIndexOfChild(Object parent, Object child);
+
+ /**
+ * addTreeModelListener
+ * @param listener TODO
+ */
+ void addTreeModelListener(TreeModelListener listener);
+
+ /**
+ * removeTreeModelListener
+ * @param listener TODO
+ */
+ void removeTreeModelListener(TreeModelListener listener);
+
+
+}
diff --git a/javax/swing/undo/CannotRedoException.java b/javax/swing/undo/CannotRedoException.java
index 7d70a38c2..5f2264835 100644
--- a/javax/swing/undo/CannotRedoException.java
+++ b/javax/swing/undo/CannotRedoException.java
@@ -44,13 +44,13 @@ package javax.swing.undo;
* @author Andrew Selkirk (aselkirk@sympatico.ca)
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-public class CannotRedoException
- extends RuntimeException
+public class CannotRedoException extends RuntimeException
{
/**
* Constructs a new instance of a <code>CannotRedoException</code>.
*/
public CannotRedoException()
{
+ super();
}
}
diff --git a/javax/swing/undo/CannotUndoException.java b/javax/swing/undo/CannotUndoException.java
index 9fc0ec3bd..8d08cda68 100644
--- a/javax/swing/undo/CannotUndoException.java
+++ b/javax/swing/undo/CannotUndoException.java
@@ -53,5 +53,6 @@ public class CannotUndoException
*/
public CannotUndoException()
{
+ super();
}
}