summaryrefslogtreecommitdiffstats
path: root/libjava/classpath/javax/swing/plaf/metal
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/javax/swing/plaf/metal')
-rw-r--r--libjava/classpath/javax/swing/plaf/metal/MetalComboBoxUI.java36
-rw-r--r--libjava/classpath/javax/swing/plaf/metal/MetalFileChooserUI.java1699
-rw-r--r--libjava/classpath/javax/swing/plaf/metal/MetalIconFactory.java104
-rw-r--r--libjava/classpath/javax/swing/plaf/metal/MetalLookAndFeel.java235
-rw-r--r--libjava/classpath/javax/swing/plaf/metal/MetalRadioButtonUI.java2
-rw-r--r--libjava/classpath/javax/swing/plaf/metal/MetalScrollPaneUI.java88
-rw-r--r--libjava/classpath/javax/swing/plaf/metal/MetalSplitPaneDivider.java136
-rw-r--r--libjava/classpath/javax/swing/plaf/metal/MetalTabbedPaneUI.java148
-rw-r--r--libjava/classpath/javax/swing/plaf/metal/MetalTextFieldUI.java12
-rw-r--r--libjava/classpath/javax/swing/plaf/metal/MetalToolBarUI.java68
-rw-r--r--libjava/classpath/javax/swing/plaf/metal/OceanTheme.java4
11 files changed, 2450 insertions, 82 deletions
diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalComboBoxUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalComboBoxUI.java
index a43ee3cb04f..0006b78fee3 100644
--- a/libjava/classpath/javax/swing/plaf/metal/MetalComboBoxUI.java
+++ b/libjava/classpath/javax/swing/plaf/metal/MetalComboBoxUI.java
@@ -313,4 +313,40 @@ public class MetalComboBoxUI extends BasicComboBoxUI
d.height + insetsH + 1);
}
+ /**
+ * Configures the editor for this combo box.
+ */
+ public void configureEditor()
+ {
+ ComboBoxEditor cbe = comboBox.getEditor();
+ if (cbe != null)
+ {
+ cbe.getEditorComponent().setFont(comboBox.getFont());
+ cbe.setItem(comboBox.getSelectedItem());
+ cbe.addActionListener(comboBox);
+ }
+ }
+
+ /**
+ * Unconfigures the editor for this combo box.
+ */
+ public void unconfigureEditor()
+ {
+ ComboBoxEditor cbe = comboBox.getEditor();
+ if (cbe != null)
+ {
+ cbe.getEditorComponent().setFont(null);
+ cbe.setItem(null);
+ cbe.removeActionListener(comboBox);
+ }
+ }
+
+ /**
+ * Lays out the ComboBox
+ */
+ public void layoutComboBox(Container parent,
+ MetalComboBoxUI.MetalComboBoxLayoutManager manager)
+ {
+ manager.layoutContainer(parent);
+ }
}
diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalFileChooserUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalFileChooserUI.java
index 3a2e1c13508..967c40d29ad 100644
--- a/libjava/classpath/javax/swing/plaf/metal/MetalFileChooserUI.java
+++ b/libjava/classpath/javax/swing/plaf/metal/MetalFileChooserUI.java
@@ -38,39 +38,421 @@ exception statement from your version. */
package javax.swing.plaf.metal;
+import java.awt.BorderLayout;
import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.GridLayout;
+import java.awt.Insets;
+import java.awt.LayoutManager;
+import java.awt.Rectangle;
+import java.awt.Window;
import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.text.NumberFormat;
+
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.ActionMap;
+import javax.swing.BorderFactory;
+import javax.swing.ButtonGroup;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultListCellRenderer;
+import javax.swing.Icon;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
import javax.swing.JComponent;
+import javax.swing.JDialog;
import javax.swing.JFileChooser;
+import javax.swing.JLabel;
import javax.swing.JList;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.JTextField;
+import javax.swing.JToggleButton;
+import javax.swing.JViewport;
+import javax.swing.ListModel;
+import javax.swing.ListSelectionModel;
+import javax.swing.SwingUtilities;
import javax.swing.UIManager;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
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;
+import javax.swing.table.DefaultTableCellRenderer;
+import javax.swing.table.DefaultTableModel;
+
+import java.sql.Date;
+
+import java.text.DateFormat;
+
+import java.util.List;
/**
* A UI delegate for the {@link JFileChooser} component. This class is only
* partially implemented and is not usable yet.
*/
-public class MetalFileChooserUI extends BasicFileChooserUI
+public class MetalFileChooserUI
+ extends BasicFileChooserUI
{
+
+ /**
+ * A renderer for the files and directories in the file chooser table.
+ */
+ class TableFileRenderer
+ extends DefaultTableCellRenderer
+ {
+
+ /**
+ * Creates a new renderer.
+ */
+ public TableFileRenderer()
+ {
+ super();
+ }
+
+ /**
+ * Returns a component that can render the specified value.
+ *
+ * @param table the table
+ * @param value the string value of the cell
+ * @param isSelected is the item selected?
+ * @param hasFocus does the item have the focus?
+ * @param row the row
+ * @param column the column
+ *
+ * @return The renderer.
+ */
+ public Component getTableCellRendererComponent(JTable table, Object value,
+ boolean isSelected, boolean hasFocus, int row, int column)
+ {
+ if (column == 0)
+ {
+ FileView v = getFileView(getFileChooser());
+ ListModel lm = fileList.getModel();
+ if (row < lm.getSize())
+ setIcon(v.getIcon((File) lm.getElementAt(row)));
+ }
+ else
+ setIcon(null);
+
+ setText(value.toString());
+ setOpaque(true);
+ setEnabled(table.isEnabled());
+ setFont(fileList.getFont());
+
+ if (startEditing && column == 0 || !isSelected)
+ {
+ setBackground(table.getBackground());
+ setForeground(table.getForeground());
+ }
+ else
+ {
+ setBackground(table.getSelectionBackground());
+ setForeground(table.getSelectionForeground());
+ }
+
+ if (hasFocus)
+ setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
+ else
+ setBorder(noFocusBorder);
+
+ return this;
+ }
+ }
+
+ /**
+ * ActionListener for the list view.
+ */
+ class ListViewActionListener implements ActionListener
+ {
+
+ /**
+ * This method is invoked when an action occurs.
+ *
+ * @param e -
+ * the <code>ActionEvent</code> that occurred
+ */
+ public void actionPerformed(ActionEvent e)
+ {
+ if (!listView)
+ {
+ int[] index = fileTable.getSelectedRows();
+ listView = true;
+ JFileChooser fc = getFileChooser();
+ fc.remove(fileTablePanel);
+ createList(fc);
+
+ fileList.getSelectionModel().clearSelection();
+ if (index.length > 0)
+ for (int i = 0; i < index.length; i++)
+ fileList.getSelectionModel().addSelectionInterval(index[i], index[i]);
+
+ fc.add(fileListPanel, BorderLayout.CENTER);
+ fc.revalidate();
+ fc.repaint();
+ }
+ }
+ }
+
+ /**
+ * ActionListener for the details view.
+ */
+ class DetailViewActionListener implements ActionListener
+ {
+
+ /**
+ * This method is invoked when an action occurs.
+ *
+ * @param e -
+ * the <code>ActionEvent</code> that occurred
+ */
+ public void actionPerformed(ActionEvent e)
+ {
+ if (listView)
+ {
+ int[] index = fileList.getSelectedIndices();
+ JFileChooser fc = getFileChooser();
+ listView = false;
+ fc.remove(fileListPanel);
+
+ if (fileTable == null)
+ createDetailsView(fc);
+ else
+ updateTable();
+
+ fileTable.getSelectionModel().clearSelection();
+ if (index.length > 0)
+ {
+ for (int i = 0; i < index.length; i++)
+ fileTable.getSelectionModel().addSelectionInterval(index[i], index[i]);
+ }
+
+ fc.add(fileTablePanel, BorderLayout.CENTER);
+ fc.revalidate();
+ fc.repaint();
+ }
+ }
+ }
+
+ /**
+ * A property change listener.
+ */
+ class MetalFileChooserPropertyChangeListener
+ implements PropertyChangeListener
+ {
+ /**
+ * Default constructor.
+ */
+ public MetalFileChooserPropertyChangeListener()
+ {
+ }
+
+ /**
+ * Handles a property change event.
+ *
+ * @param e the event.
+ */
+ public void propertyChange(PropertyChangeEvent e)
+ {
+ JFileChooser filechooser = getFileChooser();
+
+ String n = e.getPropertyName();
+ if (n.equals(JFileChooser.MULTI_SELECTION_ENABLED_CHANGED_PROPERTY))
+ {
+ int mode = -1;
+ if (filechooser.isMultiSelectionEnabled())
+ mode = ListSelectionModel.MULTIPLE_INTERVAL_SELECTION;
+ else
+ mode = ListSelectionModel.SINGLE_SELECTION;
+
+ if (listView)
+ fileList.setSelectionMode(mode);
+ else
+ fileTable.setSelectionMode(mode);
+ }
+ else if (n.equals(JFileChooser.SELECTED_FILE_CHANGED_PROPERTY))
+ {
+ File file = filechooser.getSelectedFile();
+
+ if (file != null
+ && filechooser.getDialogType() == JFileChooser.SAVE_DIALOG)
+ {
+ if (file.isDirectory() && filechooser.isTraversable(file))
+ {
+ directoryLabel = look;
+ dirLabel.setText(directoryLabel);
+ filechooser.setApproveButtonText(openButtonText);
+ filechooser.setApproveButtonToolTipText(openButtonToolTipText);
+ }
+ else if (file.isFile())
+ {
+ directoryLabel = save;
+ dirLabel.setText(directoryLabel);
+ filechooser.setApproveButtonText(saveButtonText);
+ filechooser.setApproveButtonToolTipText(saveButtonToolTipText);
+ }
+ }
+
+ if (file == null)
+ setFileName(null);
+ else
+ setFileName(file.getName());
+ int index = -1;
+ index = getModel().indexOf(file);
+ if (index >= 0)
+ {
+ if (listView)
+ {
+ fileList.setSelectedIndex(index);
+ fileList.ensureIndexIsVisible(index);
+ fileList.revalidate();
+ fileList.repaint();
+ }
+ else
+ {
+ fileTable.getSelectionModel().addSelectionInterval(index, index);
+ fileTable.scrollRectToVisible(fileTable.getCellRect(index, 0, true));
+ fileTable.revalidate();
+ fileTable.repaint();
+ }
+ }
+ }
+
+ else if (n.equals(JFileChooser.DIRECTORY_CHANGED_PROPERTY))
+ {
+ if (listView)
+ {
+ fileList.clearSelection();
+ fileList.revalidate();
+ fileList.repaint();
+ }
+ else
+ {
+ fileTable.clearSelection();
+ fileTable.revalidate();
+ fileTable.repaint();
+ }
+
+ setDirectorySelected(false);
+ File currentDirectory = filechooser.getCurrentDirectory();
+ setDirectory(currentDirectory);
+ boolean hasParent = (currentDirectory.getParentFile() != null);
+ getChangeToParentDirectoryAction().setEnabled(hasParent);
+ }
+
+ else if (n.equals(JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY))
+ {
+ filterModel.propertyChange(e);
+ }
+ else if (n.equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY))
+ {
+ filterModel.propertyChange(e);
+ }
+ else if (n.equals(JFileChooser.DIALOG_TYPE_CHANGED_PROPERTY)
+ || n.equals(JFileChooser.DIALOG_TITLE_CHANGED_PROPERTY))
+ {
+ Window owner = SwingUtilities.windowForComponent(filechooser);
+ if (owner instanceof JDialog)
+ ((JDialog) owner).setTitle(getDialogTitle(filechooser));
+ approveButton.setText(getApproveButtonText(filechooser));
+ approveButton.setToolTipText(
+ getApproveButtonToolTipText(filechooser));
+ approveButton.setMnemonic(getApproveButtonMnemonic(filechooser));
+ }
+
+ else if (n.equals(JFileChooser.APPROVE_BUTTON_TEXT_CHANGED_PROPERTY))
+ approveButton.setText(getApproveButtonText(filechooser));
+
+ else if (n.equals(
+ JFileChooser.APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY))
+ approveButton.setToolTipText(getApproveButtonToolTipText(filechooser));
+
+ else if (n.equals(JFileChooser.APPROVE_BUTTON_MNEMONIC_CHANGED_PROPERTY))
+ approveButton.setMnemonic(getApproveButtonMnemonic(filechooser));
+
+ else if (n.equals(
+ JFileChooser.CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY))
+ {
+ if (filechooser.getControlButtonsAreShown())
+ {
+ topPanel.add(controls, BorderLayout.EAST);
+ }
+ else
+ topPanel.remove(controls);
+ topPanel.revalidate();
+ topPanel.repaint();
+ topPanel.doLayout();
+ }
+
+ else if (n.equals(
+ JFileChooser.ACCEPT_ALL_FILE_FILTER_USED_CHANGED_PROPERTY))
+ {
+ if (filechooser.isAcceptAllFileFilterUsed())
+ filechooser.addChoosableFileFilter(
+ getAcceptAllFileFilter(filechooser));
+ else
+ filechooser.removeChoosableFileFilter(
+ getAcceptAllFileFilter(filechooser));
+ }
+
+ else if (n.equals(JFileChooser.ACCESSORY_CHANGED_PROPERTY))
+ {
+ JComponent old = (JComponent) e.getOldValue();
+ if (old != null)
+ getAccessoryPanel().remove(old);
+ JComponent newval = (JComponent) e.getNewValue();
+ if (newval != null)
+ getAccessoryPanel().add(newval);
+ }
+
+ if (n.equals(JFileChooser.DIRECTORY_CHANGED_PROPERTY)
+ || n.equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY)
+ || n.equals(JFileChooser.FILE_HIDING_CHANGED_PROPERTY))
+ {
+ // Remove editing component
+ if (fileTable != null)
+ fileTable.removeAll();
+ if (fileList != null)
+ fileList.removeAll();
+ startEditing = false;
+
+ // Set text on button back to original.
+ if (filechooser.getDialogType() == JFileChooser.SAVE_DIALOG)
+ {
+ directoryLabel = save;
+ dirLabel.setText(directoryLabel);
+ filechooser.setApproveButtonText(saveButtonText);
+ filechooser.setApproveButtonToolTipText(saveButtonToolTipText);
+ }
+
+ rescanCurrentDirectory(filechooser);
+ }
+
+ filechooser.revalidate();
+ filechooser.repaint();
+ }
+ };
+
/**
* A combo box model containing the selected directory and all its parent
* directories.
*/
- protected class DirectoryComboBoxModel extends AbstractListModel
+ protected class DirectoryComboBoxModel
+ extends AbstractListModel
implements ComboBoxModel
{
/** Storage for the items in the model. */
@@ -161,7 +543,8 @@ public class MetalFileChooserUI extends BasicFileChooserUI
/**
* Handles changes to the selection in the directory combo box.
*/
- protected class DirectoryComboBoxAction extends AbstractAction
+ protected class DirectoryComboBoxAction
+ extends AbstractAction
{
/**
* Creates a new action.
@@ -184,9 +567,60 @@ public class MetalFileChooserUI extends BasicFileChooserUI
}
/**
+ * A renderer for the items in the directory combo box.
+ */
+ class DirectoryComboBoxRenderer
+ extends DefaultListCellRenderer
+ {
+ /**
+ * Creates a new renderer.
+ */
+ public DirectoryComboBoxRenderer(JFileChooser fc)
+ {
+ }
+
+ /**
+ * 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 File}).
+ * @param index the item index.
+ * @param isSelected is the item selected?
+ * @param cellHasFocus does the list cell have focus?
+ *
+ * @return The list cell renderer.
+ */
+ public Component getListCellRendererComponent(JList list, Object value,
+ int index, boolean isSelected, boolean cellHasFocus)
+ {
+ FileView fileView = getFileView(getFileChooser());
+ File file = (File) value;
+ setIcon(fileView.getIcon(file));
+ setText(fileView.getName(file));
+
+ if (isSelected)
+ {
+ setBackground(list.getSelectionBackground());
+ setForeground(list.getSelectionForeground());
+ }
+ else
+ {
+ setBackground(list.getBackground());
+ setForeground(list.getForeground());
+ }
+
+ setEnabled(list.isEnabled());
+ setFont(list.getFont());
+ return this;
+ }
+ }
+
+ /**
* A renderer for the files and directories in the file chooser.
*/
- protected class FileRenderer extends DefaultListCellRenderer
+ protected class FileRenderer
+ extends DefaultListCellRenderer
{
/**
@@ -213,8 +647,17 @@ public class MetalFileChooserUI extends BasicFileChooserUI
{
FileView v = getFileView(getFileChooser());
File f = (File) value;
- setText(v.getName(f));
- setIcon(v.getIcon(f));
+ if (f != null)
+ {
+ setText(v.getName(f));
+ setIcon(v.getIcon(f));
+ }
+ else
+ {
+ setText("");
+ setIcon(null);
+ }
+ setOpaque(true);
if (isSelected)
{
setBackground(list.getSelectionBackground());
@@ -249,7 +692,7 @@ public class MetalFileChooserUI extends BasicFileChooserUI
protected FileFilter[] filters;
/** The index of the selected file filter. */
- private int selectedIndex;
+ private Object selected;
/**
* Creates a new model.
@@ -258,7 +701,7 @@ public class MetalFileChooserUI extends BasicFileChooserUI
{
filters = new FileFilter[1];
filters[0] = getAcceptAllFileFilter(getFileChooser());
- selectedIndex = 0;
+ selected = filters[0];
}
/**
@@ -270,11 +713,11 @@ public class MetalFileChooserUI extends BasicFileChooserUI
{
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;
+ JFileChooser fc = getFileChooser();
+ FileFilter[] choosableFilters = fc.getChoosableFileFilters();
+ filters = choosableFilters;
+ fireContentsChanged(this, 0, filters.length);
+ selected = e.getNewValue();
fireContentsChanged(this, -1, -1);
}
else if (e.getPropertyName().equals(
@@ -291,13 +734,15 @@ public class MetalFileChooserUI extends BasicFileChooserUI
/**
* Sets the selected filter.
*
- * @param filter the filter.
+ * @param filter the filter (<code>null</code> ignored).
*/
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);
+ if (filter != null)
+ {
+ selected = filter;
+ fireContentsChanged(this, -1, -1);
+ }
}
/**
@@ -307,9 +752,7 @@ public class MetalFileChooserUI extends BasicFileChooserUI
*/
public Object getSelectedItem()
{
- if (selectedIndex >= 0)
- return filters[selectedIndex];
- return null;
+ return selected;
}
/**
@@ -339,7 +782,8 @@ public class MetalFileChooserUI extends BasicFileChooserUI
/**
* A renderer for the items in the file filter combo box.
*/
- public class FilterComboBoxRenderer extends DefaultListCellRenderer
+ public class FilterComboBoxRenderer
+ extends DefaultListCellRenderer
{
/**
* Creates a new renderer.
@@ -359,20 +803,488 @@ public class MetalFileChooserUI extends BasicFileChooserUI
* @param isSelected is the item selected?
* @param cellHasFocus does the list cell have focus?
*
- * @return A component.
+ * @return This component as the renderer.
*/
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus)
{
+ super.getListCellRendererComponent(list, value, index, isSelected,
+ cellHasFocus);
FileFilter filter = (FileFilter) value;
- return super.getListCellRendererComponent(list, filter.getDescription(),
- index, isSelected, cellHasFocus);
+ setText(filter.getDescription());
+ return this;
+ }
+ }
+
+ /**
+ * A listener for selection events in the file list.
+ *
+ * @see #createListSelectionListener(JFileChooser)
+ */
+ class MetalFileChooserSelectionListener
+ implements ListSelectionListener
+ {
+ /**
+ * Creates a new <code>SelectionListener</code> object.
+ */
+ protected MetalFileChooserSelectionListener()
+ {
+ // Do nothing here.
+ }
+
+ /**
+ * Makes changes to different properties when
+ * a value has changed in the filechooser's selection.
+ *
+ * @param e - the list selection event that occured.
+ */
+ public void valueChanged(ListSelectionEvent e)
+ {
+ File f = (File) fileList.getSelectedValue();
+ if (f == null)
+ return;
+ JFileChooser filechooser = getFileChooser();
+ if (! filechooser.isTraversable(f))
+ filechooser.setSelectedFile(f);
+ else
+ filechooser.setSelectedFile(null);
+ }
+ }
+
+ /**
+ * A mouse listener for the {@link JFileChooser}.
+ * This listener is used for editing filenames.
+ */
+ protected class SingleClickListener
+ extends MouseAdapter
+ {
+
+ /** Stores instance of the list */
+ JList list;
+
+ /**
+ * Stores the current file that is being edited.
+ * It is null if nothing is currently being edited.
+ */
+ File editFile;
+
+ /** The current file chooser. */
+ JFileChooser fc;
+
+ /** The last file selected. */
+ Object lastSelected;
+
+ /** The textfield used for editing. */
+ JTextField editField;
+
+ /**
+ * Creates a new listener.
+ *
+ * @param list the directory/file list.
+ */
+ public SingleClickListener(JList list)
+ {
+ this.list = list;
+ editFile = null;
+ fc = getFileChooser();
+ lastSelected = null;
+ startEditing = false;
+ }
+
+ /**
+ * Receives notification of a mouse click event.
+ *
+ * @param e the event.
+ */
+ public void mouseClicked(MouseEvent e)
+ {
+ if (e.getClickCount() == 1 && e.getButton() == MouseEvent.BUTTON1)
+ {
+ int index = list.locationToIndex(e.getPoint());
+ File[] sf = fc.getSelectedFiles();
+ if ((!fc.isMultiSelectionEnabled() || (sf != null && sf.length <= 1))
+ && index >= 0 && !startEditing && list.isSelectedIndex(index))
+ {
+ Object tmp = list.getModel().getElementAt(index);
+ if (lastSelected != null && lastSelected.equals(tmp))
+ editFile(index);
+ lastSelected = tmp;
+ }
+ else
+ completeEditing();
+ }
+ else
+ completeEditing();
+ }
+
+ /**
+ * Sets up the text editor for the current file.
+ *
+ * @param index -
+ * the current index of the item in the list to be edited.
+ */
+ void editFile(int index)
+ {
+ Rectangle bounds = list.getCellBounds(index, index);
+ list.scrollRectToVisible(bounds);
+ editFile = (File) list.getModel().getElementAt(index);
+ if (editFile.canWrite())
+ {
+ startEditing = true;
+ editField = new JTextField(editFile.getName());
+ editField.addActionListener(new EditingActionListener());
+
+ Icon icon = getFileView(fc).getIcon(editFile);
+ if (icon != null)
+ {
+ int padding = icon.getIconWidth() + 4;
+ bounds.x += padding;
+ bounds.width -= padding;
+ }
+ editField.setBounds(bounds);
+
+ list.add(editField);
+
+ editField.requestFocus();
+ editField.selectAll();
+ }
+ else
+ completeEditing();
+ list.repaint();
+ }
+
+ /**
+ * Completes the editing.
+ */
+ void completeEditing()
+ {
+ if (editField != null && editFile != null)
+ {
+ String text = editField.getText();
+ if (text != null && text != "" && !text.equals(fc.getName(editFile)))
+ if (editFile.renameTo
+ (fc.getFileSystemView().createFileObject
+ (fc.getCurrentDirectory(), text)))
+ rescanCurrentDirectory(fc);
+ list.remove(editField);
+ }
+ startEditing = false;
+ editFile = null;
+ lastSelected = null;
+ editField = null;
+ list.repaint();
+ }
+
+ /**
+ * ActionListener for the editing text field.
+ */
+ class EditingActionListener implements ActionListener
+ {
+
+ /**
+ * This method is invoked when an action occurs.
+ *
+ * @param e -
+ * the <code>ActionEvent</code> that occurred
+ */
+ public void actionPerformed(ActionEvent e)
+ {
+ if (e.getActionCommand().equals("notify-field-accept"))
+ completeEditing();
+ else if (editField != null)
+ {
+ list.remove(editField);
+ startEditing = false;
+ editFile = null;
+ lastSelected = null;
+ editField = null;
+ list.repaint();
+ }
+ }
}
}
+ /**
+ * A mouse listener for the {@link JFileChooser}.
+ * This listener is used for the table
+ */
+ private class TableClickListener extends MouseAdapter
+ {
+
+ /** Stores instance of the table */
+ JTable table;
+
+ /** Stores instance of the file chooser */
+ JFileChooser fc;
+
+ /** The last selected file. */
+ Object lastSelected = null;
+
+ /**
+ * Stores the current file that is being edited.
+ * It is null if nothing is currently being edited.
+ */
+ File editFile;
+
+ /** The textfield used for editing. */
+ JTextField editField;
+
+ /**
+ * Creates a new listener.
+ *
+ * @param table
+ * the directory/file table
+ * @param fc
+ * the JFileChooser
+ */
+ public TableClickListener(JTable table, JFileChooser fc)
+ {
+ this.table = table;
+ this.fc = fc;
+ lastSelected = fileList.getSelectedValue();
+ setDirectorySelected(false);
+ startEditing = false;
+ editFile = null;
+ editField = null;
+ }
+
+ /**
+ * Receives notification of a mouse click event.
+ *
+ * @param e
+ * the event.
+ */
+ public void mouseClicked(MouseEvent e)
+ {
+ int row = table.getSelectedRow();
+ Object selVal = fileList.getModel().getElementAt(row);
+ if (selVal == null)
+ return;
+ FileSystemView fsv = fc.getFileSystemView();
+ if (e.getClickCount() == 1 &&
+ selVal.equals(lastSelected) &&
+ e.getButton() == MouseEvent.BUTTON1)
+ {
+ File[] sf = fc.getSelectedFiles();
+ if ((!fc.isMultiSelectionEnabled() || (sf != null && sf.length <= 1))
+ && !startEditing)
+ {
+ editFile = (File) selVal;
+ editFile(row);
+ }
+ }
+ else if (e.getClickCount() >= 2 &&
+ selVal.equals(lastSelected))
+ {
+ if (startEditing)
+ completeEditing();
+ File f = fsv.createFileObject(lastSelected.toString());
+ if (fc.isTraversable(f))
+ {
+ fc.setCurrentDirectory(f);
+ fc.rescanCurrentDirectory();
+ }
+ else
+ {
+ fc.setSelectedFile(f);
+ fc.approveSelection();
+ closeDialog();
+ }
+ }
+ else
+ {
+ if (startEditing)
+ completeEditing();
+ String path = selVal.toString();
+ File f = fsv.createFileObject(path);
+ fc.setSelectedFile(f);
+ if (fc.isTraversable(f))
+ {
+ setDirectorySelected(true);
+ setDirectory(f);
+ }
+ else
+ {
+ setDirectorySelected(false);
+ setDirectory(null);
+ }
+ lastSelected = selVal;
+ if (f.isFile())
+ setFileName(path.substring(path.lastIndexOf("/") + 1));
+ else if (fc.getFileSelectionMode() == JFileChooser.DIRECTORIES_ONLY)
+ setFileName(path);
+ }
+ fileTable.repaint();
+ }
+
+ /**
+ * Sets up the text editor for the current file.
+ *
+ * @param row -
+ * the current row of the item in the list to be edited.
+ */
+ void editFile(int row)
+ {
+ Rectangle bounds = table.getCellRect(row, 0, true);
+ table.scrollRectToVisible(bounds);
+ if (editFile.canWrite())
+ {
+ startEditing = true;
+ editField = new JTextField(editFile.getName());
+ editField.addActionListener(new EditingActionListener());
+
+ // Need to adjust y pos
+ bounds.y = row * table.getRowHeight();
+ editField.setBounds(bounds);
+
+ table.add(editField);
+
+ editField.requestFocus();
+ editField.selectAll();
+ }
+ else
+ completeEditing();
+ table.repaint();
+ }
+
+ /**
+ * Completes the editing.
+ */
+ void completeEditing()
+ {
+ if (editField != null && editFile != null)
+ {
+ String text = editField.getText();
+ if (text != null && text != "" && !text.equals(fc.getName(editFile)))
+ if (editFile.renameTo
+ (fc.getFileSystemView().createFileObject
+ (fc.getCurrentDirectory(), text)))
+ rescanCurrentDirectory(fc);
+ table.remove(editField);
+ }
+ startEditing = false;
+ editFile = null;
+ editField = null;
+ table.repaint();
+ }
+
+ /**
+ * ActionListener for the editing text field.
+ */
+ class EditingActionListener implements ActionListener
+ {
+
+ /**
+ * This method is invoked when an action occurs.
+ *
+ * @param e -
+ * the <code>ActionEvent</code> that occurred
+ */
+ public void actionPerformed(ActionEvent e)
+ {
+ if (e.getActionCommand().equals("notify-field-accept"))
+ completeEditing();
+ else if (editField != null)
+ {
+ table.remove(editField);
+ startEditing = false;
+ editFile = null;
+ editField = null;
+ table.repaint();
+ }
+ }
+ }
+
+ /**
+ * Closes the dialog.
+ */
+ public void closeDialog()
+ {
+ Window owner = SwingUtilities.windowForComponent(fc);
+ if (owner instanceof JDialog)
+ ((JDialog) owner).dispose();
+ }
+ }
+
+ /** The text for a label describing the directory combo box. */
+ private String directoryLabel;
+
+ private JComboBox directoryComboBox;
+
/** The model for the directory combo box. */
DirectoryComboBoxModel directoryModel;
+ /** The text for a label describing the file text field. */
+ private String fileLabel;
+
+ /** The file name text field. */
+ private JTextField fileTextField;
+
+ /** The text for a label describing the filter combo box. */
+ private String filterLabel;
+
+ /**
+ * The top panel (contains the directory combo box and the control buttons).
+ */
+ private JPanel topPanel;
+
+ /** A panel containing the control buttons ('up', 'home' etc.). */
+ private JPanel controls;
+
+ /**
+ * The panel that contains the filename field and the filter combobox.
+ */
+ private JPanel bottomPanel;
+
+ /**
+ * The panel that contains the 'Open' (or 'Save') and 'Cancel' buttons.
+ */
+ private JPanel buttonPanel;
+
+ private JButton approveButton;
+
+ /** The file list. */
+ JList fileList;
+
+ /** The file table. */
+ JTable fileTable;
+
+ /** The panel containing the file list. */
+ JPanel fileListPanel;
+
+ /** The panel containing the file table. */
+ JPanel fileTablePanel;
+
+ /** The filter combo box model. */
+ private FilterComboBoxModel filterModel;
+
+ /** The action map. */
+ private ActionMap actionMap;
+
+ /** True if currently in list view. */
+ boolean listView;
+
+ /** True if we can or have started editing a cell. */
+ boolean startEditing;
+
+ /** The scrollpane used for the table and list. */
+ JScrollPane scrollPane;
+
+ /** The text for the label when saving. */
+ String save;
+
+ /** The text for the label when opening a directory. */
+ String look;
+
+ /** The label for the file combo box. */
+ JLabel dirLabel;
+
+ /** Listeners. */
+ ListSelectionListener listSelList;
+ MouseListener doubleClickList;
+ SingleClickListener singleClickList;
+ TableClickListener tableClickList;
+
/**
* A factory method that returns a UI delegate for the specified
* component.
@@ -393,9 +1305,439 @@ public class MetalFileChooserUI extends BasicFileChooserUI
public MetalFileChooserUI(JFileChooser filechooser)
{
super(filechooser);
+ bottomPanel = new JPanel(new GridLayout(3, 2));
+ buttonPanel = new JPanel();
+ }
+
+ public void installUI(JComponent c)
+ {
+ super.installUI(c);
+ actionMap = createActionMap();
+ }
+
+ public void uninstallUI(JComponent c)
+ {
+ super.uninstallUI(c);
+ actionMap = null;
+ }
+
+ /**
+ * Installs the sub-components of the file chooser.
+ *
+ * @param fc the file chooser component.
+ */
+ public void installComponents(JFileChooser fc)
+ {
+ fc.setLayout(new BorderLayout());
+ topPanel = new JPanel(new BorderLayout());
+ dirLabel = new JLabel(directoryLabel);
+ topPanel.add(dirLabel, BorderLayout.WEST);
+ this.controls = new JPanel();
+ addControlButtons();
+
+ JPanel dirPanel = new JPanel(new VerticalMidLayout());
+ directoryModel = createDirectoryComboBoxModel(fc);
+ directoryComboBox = new JComboBox(directoryModel);
+ directoryComboBox.setRenderer(createDirectoryComboBoxRenderer(fc));
+ dirPanel.add(directoryComboBox);
+ topPanel.add(dirPanel);
+ topPanel.add(controls, BorderLayout.EAST);
+ topPanel.setBorder(BorderFactory.createEmptyBorder(8, 8, 0, 8));
+ fc.add(topPanel, BorderLayout.NORTH);
+
+ JPanel list = createList(fc);
+ list.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
+ fc.add(list, BorderLayout.CENTER);
+
+ JPanel bottomPanel = getBottomPanel();
+ filterModel = createFilterComboBoxModel();
+ JComboBox fileFilterCombo = new JComboBox(filterModel);
+ fileFilterCombo.setRenderer(createFilterComboBoxRenderer());
+
+ fileTextField = new JTextField();
+ JPanel fileNamePanel = new JPanel(new VerticalMidLayout());
+ fileNamePanel.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 5));
+ fileNamePanel.add(fileTextField);
+ JPanel row1 = new JPanel(new BorderLayout());
+ row1.add(new JLabel(this.fileLabel), BorderLayout.WEST);
+ row1.add(fileNamePanel);
+ bottomPanel.add(row1);
+
+ JPanel row2 = new JPanel(new BorderLayout());
+ row2.add(new JLabel(this.filterLabel), BorderLayout.WEST);
+ row2.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));
+ row2.add(fileFilterCombo);
+ bottomPanel.add(row2);
+ JPanel buttonPanel = new JPanel(new ButtonLayout());
+
+ approveButton = new JButton(getApproveSelectionAction());
+ approveButton.setText(getApproveButtonText(fc));
+ approveButton.setToolTipText(getApproveButtonToolTipText(fc));
+ approveButton.setMnemonic(getApproveButtonMnemonic(fc));
+ buttonPanel.add(approveButton);
+ buttonPanel.setBorder(BorderFactory.createEmptyBorder(8, 0, 0, 0));
+
+ JButton cancelButton = new JButton(getCancelSelectionAction());
+ cancelButton.setText(cancelButtonText);
+ cancelButton.setToolTipText(cancelButtonToolTipText);
+ cancelButton.setMnemonic(cancelButtonMnemonic);
+ buttonPanel.add(cancelButton);
+ bottomPanel.add(buttonPanel, BorderLayout.SOUTH);
+ bottomPanel.setBorder(BorderFactory.createEmptyBorder(0, 8, 8, 8));
+ fc.add(bottomPanel, BorderLayout.SOUTH);
+
+ fc.add(getAccessoryPanel(), BorderLayout.EAST);
+ }
+
+ /**
+ * Uninstalls the components added by
+ * {@link #installComponents(JFileChooser)}.
+ *
+ * @param fc the file chooser.
+ */
+ public void uninstallComponents(JFileChooser fc)
+ {
+ fc.remove(bottomPanel);
+ bottomPanel = null;
+ fc.remove(fileListPanel);
+ fc.remove(fileTablePanel);
+ fileTablePanel = null;
+ fileListPanel = null;
+ fc.remove(topPanel);
+ topPanel = null;
+
+ directoryModel = null;
+ fileTextField = null;
+ directoryComboBox = null;
+ }
+
+ /**
+ * Returns the panel that contains the 'Open' (or 'Save') and 'Cancel'
+ * buttons.
+ *
+ * @return The panel.
+ */
+ protected JPanel getButtonPanel()
+ {
+ return buttonPanel;
+ }
+
+ /**
+ * Creates and returns a new panel that will be used for the controls at
+ * the bottom of the file chooser.
+ *
+ * @return A new panel.
+ */
+ protected JPanel getBottomPanel()
+ {
+ if (bottomPanel == null)
+ bottomPanel = new JPanel(new GridLayout(3, 2));
+ return bottomPanel;
+ }
+
+ /**
+ * Fetches localised strings for use by the labels and buttons on the
+ * file chooser.
+ *
+ * @param fc the file chooser.
+ */
+ protected void installStrings(JFileChooser fc)
+ {
+ super.installStrings(fc);
+ look = "Look In: ";
+ save = "Save In: ";
+ if (fc.getDialogType() == JFileChooser.SAVE_DIALOG)
+ directoryLabel = save;
+ else
+ directoryLabel = look;
+
+ fileLabel = "File Name: ";
+ filterLabel = "Files of Type: ";
+
+ this.cancelButtonMnemonic = 0;
+ this.cancelButtonText = "Cancel";
+ this.cancelButtonToolTipText = "Abort file chooser dialog";
+
+ this.directoryOpenButtonMnemonic = 0;
+ this.directoryOpenButtonText = "Open";
+ this.directoryOpenButtonToolTipText = "Open selected directory";
+
+ this.helpButtonMnemonic = 0;
+ this.helpButtonText = "Help";
+ this.helpButtonToolTipText = "Filechooser help";
+
+ this.openButtonMnemonic = 0;
+ this.openButtonText = "Open";
+ this.openButtonToolTipText = "Open selected file";
+
+ this.saveButtonMnemonic = 0;
+ this.saveButtonText = "Save";
+ this.saveButtonToolTipText = "Save selected file";
+
+ this.updateButtonMnemonic = 0;
+ this.updateButtonText = "Update";
+ this.updateButtonToolTipText = "Update directory listing";
+ }
+
+ /**
+ * Installs the listeners required.
+ *
+ * @param fc the file chooser.
+ */
+ protected void installListeners(JFileChooser fc)
+ {
+ directoryComboBox.setAction(new DirectoryComboBoxAction());
+ fc.addPropertyChangeListener(filterModel);
+ listSelList = createListSelectionListener(fc);
+ doubleClickList = this.createDoubleClickListener(fc, fileList);
+ singleClickList = new SingleClickListener(fileList);
+ fileList.addListSelectionListener(listSelList);
+ fileList.addMouseListener(doubleClickList);
+ fileList.addMouseListener(singleClickList);
+ super.installListeners(fc);
+ }
+
+ protected void uninstallListeners(JFileChooser fc)
+ {
+ super.uninstallListeners(fc);
+ fc.removePropertyChangeListener(filterModel);
+ directoryComboBox.setAction(null);
+ fileList.removeListSelectionListener(listSelList);
+ fileList.removeMouseListener(doubleClickList);
+ fileList.removeMouseListener(singleClickList);
+
+ if (fileTable != null)
+ fileTable.removeMouseListener(tableClickList);
+ }
+
+ protected ActionMap getActionMap()
+ {
+ if (actionMap == null)
+ actionMap = createActionMap();
+ return actionMap;
+ }
+
+ /**
+ * Creates and returns an action map.
+ *
+ * @return The action map.
+ */
+ protected ActionMap createActionMap()
+ {
+ ActionMap map = new ActionMap();
+ map.put("approveSelection", getApproveSelectionAction());
+ map.put("cancelSelection", getCancelSelectionAction());
+ map.put("Go Up", getChangeToParentDirectoryAction());
+ return map;
+ }
+
+ /**
+ * Creates a panel containing a list of files.
+ *
+ * @param fc the file chooser.
+ *
+ * @return A panel.
+ */
+ protected JPanel createList(JFileChooser fc)
+ {
+ if (fileList == null)
+ {
+ fileListPanel = new JPanel(new BorderLayout());
+ fileList = new JList(getModel());
+ scrollPane = new JScrollPane(fileList);
+ scrollPane.setVerticalScrollBarPolicy
+ (JScrollPane.VERTICAL_SCROLLBAR_NEVER);
+ fileList.setLayoutOrientation(JList.VERTICAL_WRAP);
+ fileList.setCellRenderer(new FileRenderer());
+ }
+ else
+ {
+ fileList.setModel(getModel());
+ fileListPanel.removeAll();
+ scrollPane.getViewport().setView(fileList);
+ }
+ fileListPanel.add(scrollPane);
+
+ return fileListPanel;
+ }
+
+ /**
+ * Creates a panel containing a table within a scroll pane.
+ *
+ * @param fc the file chooser.
+ *
+ * @return The details view.
+ */
+ protected JPanel createDetailsView(JFileChooser fc)
+ {
+ fileTablePanel = new JPanel(new BorderLayout());
+
+ Object[] cols = new Object[] {"Name", "Size", "Modified"};
+ Object[][] rows = new Object[fileList.getModel().getSize()][3];
+
+ fileTable = new JTable(new DefaultTableModel(rows, cols));
+
+ if (fc.isMultiSelectionEnabled())
+ fileTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
+ else
+ fileTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+
+ fileTable.setShowGrid(false);
+ fileTable.setColumnSelectionAllowed(false);
+ fileTable.setDefaultRenderer(Object.class, new TableFileRenderer());
+
+ tableClickList = new TableClickListener(fileTable, fc);
+ fileTable.addMouseListener(tableClickList);
+
+ return updateTable();
+ }
+
+ /**
+ * Sets the values in the table, and puts it in the panel.
+ *
+ * @return the panel containing the table.
+ */
+ JPanel updateTable()
+ {
+ DefaultTableModel mod = (DefaultTableModel) fileTable.getModel();
+ ListModel lm = fileList.getModel();
+ DateFormat dt = DateFormat.getDateTimeInstance(DateFormat.SHORT,
+ DateFormat.SHORT);
+ File curr = null;
+ int size = lm.getSize();
+ int rc = mod.getRowCount();
+
+ // If there are not enough rows
+ for (int x = rc; x < size; x++)
+ mod.addRow(new Object[3]);
+
+ for (int i = 0; i < size; i++)
+ {
+ curr = (File) lm.getElementAt(i);
+ fileTable.setValueAt(curr.getName(), i, 0);
+ fileTable.setValueAt(formatSize(curr.length()), i, 1);
+ fileTable.setValueAt(dt.format(new Date(curr.lastModified())), i, 2);
+ }
+
+ // If there are too many rows
+ while (rc > size)
+ mod.removeRow(--rc);
+
+ scrollPane.getViewport().setView(fileTable);
+ scrollPane.setColumnHeaderView(fileTable.getTableHeader());
+
+ fileTablePanel.removeAll();
+ fileTablePanel.add(scrollPane);
+
+ return fileTablePanel;
+ }
+
+ /**
+ * Formats bytes into the appropriate size.
+ *
+ * @param bytes -
+ * the number of bytes to convert
+ * @return a string representation of the size
+ */
+ private String formatSize(long bytes)
+ {
+ NumberFormat nf = NumberFormat.getNumberInstance();
+ long mb = (long) Math.pow(2, 20);
+ long kb = (long) Math.pow(2, 10);
+ long gb = (long) Math.pow(2, 30);
+ double size = 0;
+ String id = "";
+
+ if ((bytes / gb) >= 1)
+ {
+ size = (double) bytes / (double) gb;
+ id = "GB";
+ }
+ else if ((bytes / mb) >= 1)
+ {
+ size = (double) bytes / (double) mb;
+ id = "MB";
+ }
+ else if ((bytes / kb) >= 1)
+ {
+ size = (double) bytes / (double) kb;
+ id = "KB";
+ }
+ else
+ {
+ size = bytes;
+ id = "Bytes";
+ }
+
+ return nf.format(size) + " " + id;
+ }
+ /**
+ * Creates a listener that monitors selections in the directory/file list
+ * and keeps the {@link JFileChooser} component up to date.
+ *
+ * @param fc the file chooser.
+ *
+ * @return The listener.
+ *
+ * @see #installListeners(JFileChooser)
+ */
+ public ListSelectionListener createListSelectionListener(JFileChooser fc)
+ {
+ return new MetalFileChooserSelectionListener();
+ }
+
+ /**
+ * Returns the preferred size for the file chooser component.
+ *
+ * @return The preferred size.
+ */
+ public Dimension getPreferredSize(JComponent c)
+ {
+ Dimension tp = topPanel.getPreferredSize();
+ Dimension bp = bottomPanel.getPreferredSize();
+ Dimension fl = fileListPanel.getPreferredSize();
+ return new Dimension(fl.width, tp.height + bp.height + fl.height);
+ }
+
+ /**
+ * Returns the minimum size for the file chooser component.
+ *
+ * @return The minimum size.
+ */
+ public Dimension getMinimumSize(JComponent c)
+ {
+ Dimension tp = topPanel.getMinimumSize();
+ Dimension bp = bottomPanel.getMinimumSize();
+ Dimension fl = fileListPanel.getMinimumSize();
+ return new Dimension(fl.width, tp.height + bp.height + fl.height);
}
/**
+ * Returns the maximum size for the file chooser component.
+ *
+ * @return The maximum size.
+ */
+ public Dimension getMaximumSize(JComponent c)
+ {
+ return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
+ }
+
+ /**
+ * Creates a property change listener that monitors the {@link JFileChooser}
+ * for property change events and updates the component display accordingly.
+ *
+ * @param fc the file chooser.
+ *
+ * @return The property change listener.
+ *
+ * @see #installListeners(JFileChooser)
+ */
+ public PropertyChangeListener createPropertyChangeListener(JFileChooser fc)
+ {
+ return new MetalFileChooserPropertyChangeListener();
+ }
+
+ /**
* Creates and returns a new instance of {@link DirectoryComboBoxModel}.
*
* @return A new instance of {@link DirectoryComboBoxModel}.
@@ -407,6 +1749,20 @@ public class MetalFileChooserUI extends BasicFileChooserUI
}
/**
+ * Creates a new instance of the renderer used in the directory
+ * combo box.
+ *
+ * @param fc the file chooser.
+ *
+ * @return The renderer.
+ */
+ protected DirectoryComboBoxRenderer createDirectoryComboBoxRenderer(
+ JFileChooser fc)
+ {
+ return new DirectoryComboBoxRenderer(fc);
+ }
+
+ /**
* Creates and returns a new instance of {@link FilterComboBoxModel}.
*
* @return A new instance of {@link FilterComboBoxModel}.
@@ -427,4 +1783,297 @@ public class MetalFileChooserUI extends BasicFileChooserUI
return new FilterComboBoxRenderer();
}
+ /**
+ * Adds the control buttons ('up', 'home' etc.) to the panel.
+ */
+ protected void addControlButtons()
+ {
+ JButton upButton = new JButton(getChangeToParentDirectoryAction());
+ upButton.setText(null);
+ upButton.setIcon(this.upFolderIcon);
+ upButton.setMargin(new Insets(0, 0, 0, 0));
+ controls.add(upButton);
+
+ JButton homeButton = new JButton(getGoHomeAction());
+ homeButton.setText(null);
+ homeButton.setIcon(this.homeFolderIcon);
+ homeButton.setMargin(new Insets(0, 0, 0, 0));
+ controls.add(homeButton);
+
+ JButton newFolderButton = new JButton(getNewFolderAction());
+ newFolderButton.setText(null);
+ newFolderButton.setIcon(this.newFolderIcon);
+ newFolderButton.setMargin(new Insets(0, 0, 0, 0));
+ controls.add(newFolderButton);
+
+ JToggleButton listButton = new JToggleButton(this.listViewIcon);
+ listButton.setMargin(new Insets(0, 0, 0, 0));
+ listButton.addActionListener(new ListViewActionListener());
+ listButton.setSelected(true);
+ listView = true;
+ controls.add(listButton);
+
+ JToggleButton detailButton = new JToggleButton(this.detailsViewIcon);
+ detailButton.setMargin(new Insets(0, 0, 0, 0));
+ detailButton.addActionListener(new DetailViewActionListener());
+ detailButton.setSelected(false);
+ controls.add(detailButton);
+
+ ButtonGroup buttonGroup = new ButtonGroup();
+ buttonGroup.add(listButton);
+ buttonGroup.add(detailButton);
+ }
+
+ /**
+ * Removes all the buttons from the control panel.
+ */
+ protected void removeControlButtons()
+ {
+ controls.removeAll();
+ controls.revalidate();
+ controls.repaint();
+ }
+
+ /**
+ * Updates the current directory.
+ *
+ * @param the file chooser to update.
+ */
+ public void rescanCurrentDirectory(JFileChooser fc)
+ {
+ directoryModel.setSelectedItem(fc.getCurrentDirectory());
+ getModel().validateFileCache();
+ if (!listView)
+ updateTable();
+ else
+ createList(fc);
+ }
+
+ /**
+ * Returns the file name in the text field.
+ *
+ * @return The file name.
+ */
+ public String getFileName()
+ {
+ String result = null;
+ if (fileTextField != null)
+ result = fileTextField.getText();
+ return result;
+ }
+
+ /**
+ * Sets the file name in the text field.
+ *
+ * @param filename the file name.
+ */
+ public void setFileName(String filename)
+ {
+ fileTextField.setText(filename);
+ }
+
+ /**
+ * DOCUMENT ME!!
+ *
+ * @param e - DOCUMENT ME!
+ */
+ public void valueChanged(ListSelectionEvent e)
+ {
+ // FIXME: Not sure what we should be doing here, if anything.
+ }
+
+ /**
+ * Returns the approve button.
+ *
+ * @return The approve button.
+ */
+ protected JButton getApproveButton(JFileChooser fc)
+ {
+ return approveButton;
+ }
+
+ /**
+ * A layout manager that is used to arrange the subcomponents of the
+ * {@link JFileChooser}.
+ */
+ class VerticalMidLayout implements LayoutManager
+ {
+ /**
+ * Performs the layout.
+ *
+ * @param parent the container.
+ */
+ public void layoutContainer(Container parent)
+ {
+ int count = parent.getComponentCount();
+ if (count > 0)
+ {
+ Insets insets = parent.getInsets();
+ Component c = parent.getComponent(0);
+ Dimension prefSize = c.getPreferredSize();
+ int h = parent.getHeight() - insets.top - insets.bottom;
+ int adj = Math.max(0, (h - prefSize.height) / 2);
+ c.setBounds(insets.left, insets.top + adj, parent.getWidth()
+ - insets.left - insets.right,
+ (int) Math.min(prefSize.getHeight(), h));
+ }
+ }
+
+ /**
+ * Returns the minimum layout size.
+ *
+ * @param parent the container.
+ *
+ * @return The minimum layout size.
+ */
+ public Dimension minimumLayoutSize(Container parent)
+ {
+ return preferredLayoutSize(parent);
+ }
+
+ /**
+ * Returns the preferred layout size.
+ *
+ * @param parent the container.
+ *
+ * @return The preferred layout size.
+ */
+ public Dimension preferredLayoutSize(Container parent)
+ {
+ if (parent.getComponentCount() > 0)
+ {
+ return parent.getComponent(0).getPreferredSize();
+ }
+ else return null;
+ }
+
+ /**
+ * This layout manager does not need to track components, so this
+ * method does nothing.
+ *
+ * @param name the name the component is associated with.
+ * @param component the component.
+ */
+ public void addLayoutComponent(String name, Component component)
+ {
+ // do nothing
+ }
+
+ /**
+ * This layout manager does not need to track components, so this
+ * method does nothing.
+ *
+ * @param component the component.
+ */
+ public void removeLayoutComponent(Component component) {
+ // do nothing
+ }
+ }
+
+ /**
+ * A layout manager that is used to arrange buttons for the
+ * {@link JFileChooser}.
+ */
+ class ButtonLayout implements LayoutManager
+ {
+ static final int GAP = 4;
+
+ /**
+ * Performs the layout.
+ *
+ * @param parent the container.
+ */
+ public void layoutContainer(Container parent)
+ {
+ int count = parent.getComponentCount();
+ if (count > 0)
+ {
+ // first find the widest button
+ int maxW = 0;
+ for (int i = 0; i < count; i++)
+ {
+ Component c = parent.getComponent(i);
+ Dimension prefSize = c.getPreferredSize();
+ maxW = Math.max(prefSize.width, maxW);
+ }
+
+ // then position the buttons
+ Insets insets = parent.getInsets();
+ int availableH = parent.getHeight() - insets.top - insets.bottom;
+ int currentX = parent.getWidth() - insets.right;
+ for (int i = count - 1; i >= 0; i--)
+ {
+ Component c = parent.getComponent(i);
+ Dimension prefSize = c.getPreferredSize();
+ int adj = Math.max(0, (availableH - prefSize.height) / 2);
+ currentX = currentX - prefSize.width;
+ c.setBounds(currentX, insets.top + adj, prefSize.width,
+ (int) Math.min(prefSize.getHeight(), availableH));
+ currentX = currentX - GAP;
+ }
+ }
+ }
+
+ /**
+ * Returns the minimum layout size.
+ *
+ * @param parent the container.
+ *
+ * @return The minimum layout size.
+ */
+ public Dimension minimumLayoutSize(Container parent)
+ {
+ return preferredLayoutSize(parent);
+ }
+
+ /**
+ * Returns the preferred layout size.
+ *
+ * @param parent the container.
+ *
+ * @return The preferred layout size.
+ */
+ public Dimension preferredLayoutSize(Container parent)
+ {
+ Insets insets = parent.getInsets();
+ int maxW = 0;
+ int maxH = 0;
+ int count = parent.getComponentCount();
+ if (count > 0)
+ {
+ for (int i = 0; i < count; i++)
+ {
+ Component c = parent.getComponent(i);
+ Dimension d = c.getPreferredSize();
+ maxW = Math.max(d.width, maxW);
+ maxH = Math.max(d.height, maxH);
+ }
+ }
+ return new Dimension(maxW * count + GAP * (count - 1) + insets.left
+ + insets.right, maxH + insets.top + insets.bottom);
+ }
+
+ /**
+ * This layout manager does not need to track components, so this
+ * method does nothing.
+ *
+ * @param name the name the component is associated with.
+ * @param component the component.
+ */
+ public void addLayoutComponent(String name, Component component)
+ {
+ // do nothing
+ }
+
+ /**
+ * This layout manager does not need to track components, so this
+ * method does nothing.
+ *
+ * @param component the component.
+ */
+ public void removeLayoutComponent(Component component) {
+ // do nothing
+ }
+ }
+
}
diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalIconFactory.java b/libjava/classpath/javax/swing/plaf/metal/MetalIconFactory.java
index bcb86e61047..0b644f30037 100644
--- a/libjava/classpath/javax/swing/plaf/metal/MetalIconFactory.java
+++ b/libjava/classpath/javax/swing/plaf/metal/MetalIconFactory.java
@@ -68,6 +68,12 @@ public class MetalIconFactory implements Serializable
/** A constant representing "light". */
public static final boolean LIGHT = true;
+
+ /** A shared instance of the MenuArrowIcon. */
+ private static Icon menuArrow;
+
+ /** A shared instance of the MenuItemArrowIcon. */
+ private static Icon menuItemArrow;
/**
* An icon displayed for {@link JCheckBoxMenuItem} components.
@@ -2467,4 +2473,102 @@ public class MetalIconFactory implements Serializable
return treeHardDriveIcon;
}
+ /**
+ * 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()
+ {
+ if (menuArrow == null)
+ menuArrow = new Icon()
+ {
+ public int getIconHeight()
+ {
+ return 8;
+ }
+
+ public int getIconWidth()
+ {
+ return 4;
+ }
+
+ public void paintIcon(Component c, Graphics g, int x, int y)
+ {
+ Color saved = g.getColor();
+ g.setColor(Color.BLACK);
+ for (int i = 0; i < 4; i++)
+ g.drawLine(x + i, y + i, x + i, y + 7 - i);
+ g.setColor(saved);
+ }
+ };
+ return menuArrow;
+ }
+
+ /**
+ * 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 getMenuItemArrowIcon()
+ {
+ if (menuItemArrow == null)
+ menuItemArrow = new Icon()
+ {
+ public int getIconHeight()
+ {
+ return 8;
+ }
+
+ public int getIconWidth()
+ {
+ return 4;
+ }
+
+ public void paintIcon(Component c, Graphics g, int x, int y)
+ {
+ Color saved = g.getColor();
+ g.setColor(Color.BLACK);
+ for (int i = 0; i < 4; i++)
+ g.drawLine(x + i, y + i, x + i, y + 7 - i);
+ g.setColor(saved);
+ }
+ };
+ return menuItemArrow;
+ }
+
+ /**
+ * Returns a new instance of a 13 x 13 icon showing a small black check mark.
+ *
+ * @return The icon.
+ */
+ public static Icon getMenuItemCheckIcon()
+ {
+ return new Icon()
+ {
+ public int getIconHeight()
+ {
+ return 13;
+ }
+
+ public int getIconWidth()
+ {
+ return 13;
+ }
+
+ public void paintIcon(Component c, Graphics g, int x, int y)
+ {
+ Color saved = g.getColor();
+ g.setColor(Color.BLACK);
+ g.drawLine(3 + x, 5 + y, 3 + x, 9 + y);
+ g.drawLine(4 + x, 5 + y, 4 + x, 9 + y);
+ g.drawLine(5 + x, 7 + y, 9 + x, 3 + y);
+ g.drawLine(5 + x, 8 + y, 9 + x, 4 + y);
+ g.setColor(saved);
+ }
+ };
+ }
}
diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalLookAndFeel.java b/libjava/classpath/javax/swing/plaf/metal/MetalLookAndFeel.java
index da019379bf5..c60b55c9e7b 100644
--- a/libjava/classpath/javax/swing/plaf/metal/MetalLookAndFeel.java
+++ b/libjava/classpath/javax/swing/plaf/metal/MetalLookAndFeel.java
@@ -40,7 +40,6 @@ package javax.swing.plaf.metal;
import java.awt.Color;
import java.awt.Font;
-import java.awt.Insets;
import javax.swing.LookAndFeel;
import javax.swing.UIDefaults;
@@ -55,7 +54,17 @@ import javax.swing.plaf.basic.BasicLookAndFeel;
/**
* A custom look and feel that is designed to look similar across different
- * operating systems.
+ * operating systems. 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>
*/
public class MetalLookAndFeel extends BasicLookAndFeel
{
@@ -72,8 +81,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public MetalLookAndFeel()
{
- if (theme == null)
- createDefaultTheme();
+ createDefaultTheme();
}
/**
@@ -81,7 +89,8 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
protected void createDefaultTheme()
{
- setCurrentTheme(new DefaultMetalTheme());
+ if (theme == null)
+ setCurrentTheme(new DefaultMetalTheme());
}
/**
@@ -115,7 +124,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public String getDescription()
{
- return "Metal look and feel";
+ return "The Java(tm) Look and Feel";
}
/**
@@ -125,7 +134,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public String getID()
{
- return "MetalLookAndFeel";
+ return "Metal";
}
/**
@@ -135,7 +144,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public String getName()
{
- return "MetalLookAndFeel";
+ return "Metal";
}
public UIDefaults getDefaults()
@@ -145,7 +154,8 @@ public class MetalLookAndFeel extends BasicLookAndFeel
LAF_defaults = super.getDefaults();
// add custom theme entries to the table
- theme.addCustomEntriesToTable(LAF_defaults);
+ if (theme != null)
+ theme.addCustomEntriesToTable(LAF_defaults);
}
// Returns the default values for this look and feel.
@@ -159,7 +169,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static ColorUIResource getAcceleratorForeground()
{
- return theme.getAcceleratorForeground();
+ if (theme != null)
+ return theme.getAcceleratorForeground();
+ return null;
}
/**
@@ -170,7 +182,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static ColorUIResource getAcceleratorSelectedForeground()
{
- return theme.getAcceleratorSelectedForeground();
+ if (theme != null)
+ return theme.getAcceleratorSelectedForeground();
+ return null;
}
/**
@@ -180,7 +194,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static ColorUIResource getBlack()
{
- return theme.getBlack();
+ if (theme != null)
+ return theme.getBlack();
+ return null;
}
/**
@@ -190,7 +206,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static ColorUIResource getControl()
{
- return theme.getControl();
+ if (theme != null)
+ return theme.getControl();
+ return null;
}
/**
@@ -201,7 +219,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static ColorUIResource getControlDarkShadow()
{
- return theme.getControlDarkShadow();
+ if (theme != null)
+ return theme.getControlDarkShadow();
+ return null;
}
/**
@@ -211,7 +231,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static ColorUIResource getControlDisabled()
{
- return theme.getControlDisabled();
+ if (theme != null)
+ return theme.getControlDisabled();
+ return null;
}
/**
@@ -222,7 +244,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static ColorUIResource getControlHighlight()
{
- return theme.getControlHighlight();
+ if (theme != null)
+ return theme.getControlHighlight();
+ return null;
}
/**
@@ -233,7 +257,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static ColorUIResource getControlInfo()
{
- return theme.getControlInfo();
+ if (theme != null)
+ return theme.getControlInfo();
+ return null;
}
/**
@@ -244,7 +270,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static ColorUIResource getControlShadow()
{
- return theme.getControlShadow();
+ if (theme != null)
+ return theme.getControlShadow();
+ return null;
}
/**
@@ -254,7 +282,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static ColorUIResource getControlTextColor()
{
- return theme.getControlTextColor();
+ if (theme != null)
+ return theme.getControlTextColor();
+ return null;
}
/**
@@ -264,7 +294,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static FontUIResource getControlTextFont()
{
- return theme.getControlTextFont();
+ if (theme != null)
+ return theme.getControlTextFont();
+ return null;
}
/**
@@ -275,7 +307,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static ColorUIResource getDesktopColor()
{
- return theme.getDesktopColor();
+ if (theme != null)
+ return theme.getDesktopColor();
+ return null;
}
/**
@@ -286,7 +320,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static ColorUIResource getFocusColor()
{
- return theme.getFocusColor();
+ if (theme != null)
+ return theme.getFocusColor();
+ return null;
}
/**
@@ -297,7 +333,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static ColorUIResource getHighlightedTextColor()
{
- return theme.getHighlightedTextColor();
+ if (theme != null)
+ return theme.getHighlightedTextColor();
+ return null;
}
/**
@@ -308,7 +346,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static ColorUIResource getInactiveControlTextColor()
{
- return theme.getInactiveControlTextColor();
+ if (theme != null)
+ return theme.getInactiveControlTextColor();
+ return null;
}
/**
@@ -319,7 +359,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static ColorUIResource getInactiveSystemTextColor()
{
- return theme.getInactiveSystemTextColor();
+ if (theme != null)
+ return theme.getInactiveSystemTextColor();
+ return null;
}
/**
@@ -331,7 +373,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static ColorUIResource getMenuBackground()
{
- return theme.getMenuBackground();
+ if (theme != null)
+ return theme.getMenuBackground();
+ return null;
}
/**
@@ -344,7 +388,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static ColorUIResource getMenuDisabledForeground()
{
- return theme.getMenuDisabledForeground();
+ if (theme != null)
+ return theme.getMenuDisabledForeground();
+ return null;
}
/**
@@ -357,7 +403,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static ColorUIResource getMenuForeground()
{
- return theme.getMenuForeground();
+ if (theme != null)
+ return theme.getMenuForeground();
+ return null;
}
/**
@@ -370,7 +418,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static ColorUIResource getMenuSelectedBackground()
{
- return theme.getMenuSelectedBackground();
+ if (theme != null)
+ return theme.getMenuSelectedBackground();
+ return null;
}
/**
@@ -383,7 +433,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static ColorUIResource getMenuSelectedForeground()
{
- return theme.getMenuSelectedForeground();
+ if (theme != null)
+ return theme.getMenuSelectedForeground();
+ return null;
}
/**
@@ -393,7 +445,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static FontUIResource getMenuTextFont()
{
- return theme.getMenuTextFont();
+ if (theme != null)
+ return theme.getMenuTextFont();
+ return null;
}
/**
@@ -403,7 +457,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static ColorUIResource getPrimaryControl()
{
- return theme.getPrimaryControl();
+ if (theme != null)
+ return theme.getPrimaryControl();
+ return null;
}
/**
@@ -414,7 +470,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static ColorUIResource getPrimaryControlDarkShadow()
{
- return theme.getPrimaryControlDarkShadow();
+ if (theme != null)
+ return theme.getPrimaryControlDarkShadow();
+ return null;
}
/**
@@ -425,7 +483,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static ColorUIResource getPrimaryControlHighlight()
{
- return theme.getPrimaryControlHighlight();
+ if (theme != null)
+ return theme.getPrimaryControlHighlight();
+ return null;
}
/**
@@ -436,7 +496,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static ColorUIResource getPrimaryControlInfo()
{
- return theme.getPrimaryControlInfo();
+ if (theme != null)
+ return theme.getPrimaryControlInfo();
+ return null;
}
/**
@@ -447,7 +509,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static ColorUIResource getPrimaryControlShadow()
{
- return theme.getPrimaryControlShadow();
+ if (theme != null)
+ return theme.getPrimaryControlShadow();
+ return null;
}
/**
@@ -457,7 +521,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static ColorUIResource getSeparatorBackground()
{
- return theme.getSeparatorBackground();
+ if (theme != null)
+ return theme.getSeparatorBackground();
+ return null;
}
/**
@@ -467,7 +533,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static ColorUIResource getSeparatorForeground()
{
- return theme.getSeparatorForeground();
+ if (theme != null)
+ return theme.getSeparatorForeground();
+ return null;
}
/**
@@ -477,7 +545,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static FontUIResource getSubTextFont()
{
- return theme.getSubTextFont();
+ if (theme != null)
+ return theme.getSubTextFont();
+ return null;
}
/**
@@ -487,7 +557,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static ColorUIResource getSystemTextColor()
{
- return theme.getSystemTextColor();
+ if (theme != null)
+ return theme.getSystemTextColor();
+ return null;
}
/**
@@ -497,7 +569,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static FontUIResource getSystemTextFont()
{
- return theme.getSystemTextFont();
+ if (theme != null)
+ return theme.getSystemTextFont();
+ return null;
}
/**
@@ -507,7 +581,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static ColorUIResource getTextHighlightColor()
{
- return theme.getTextHighlightColor();
+ if (theme != null)
+ return theme.getTextHighlightColor();
+ return null;
}
/**
@@ -517,7 +593,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static ColorUIResource getUserTextColor()
{
- return theme.getUserTextColor();
+ if (theme != null)
+ return theme.getUserTextColor();
+ return null;
}
/**
@@ -527,7 +605,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static FontUIResource getUserTextFont()
{
- return theme.getUserTextFont();
+ if (theme != null)
+ return theme.getUserTextFont();
+ return null;
}
/**
@@ -537,7 +617,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static ColorUIResource getWhite()
{
- return theme.getWhite();
+ if (theme != null)
+ return theme.getWhite();
+ return null;
}
/**
@@ -547,7 +629,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static ColorUIResource getWindowBackground()
{
- return theme.getWindowBackground();
+ if (theme != null)
+ return theme.getWindowBackground();
+ return null;
}
/**
@@ -557,7 +641,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static ColorUIResource getWindowTitleBackground()
{
- return theme.getWindowTitleBackground();
+ if (theme != null)
+ return theme.getWindowTitleBackground();
+ return null;
}
/**
@@ -569,7 +655,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static FontUIResource getWindowTitleFont()
{
- return theme.getWindowTitleFont();
+ if (theme != null)
+ return theme.getWindowTitleFont();
+ return null;
}
/**
@@ -579,7 +667,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static ColorUIResource getWindowTitleForeground()
{
- return theme.getWindowTitleForeground();
+ if (theme != null)
+ return theme.getWindowTitleForeground();
+ return null;
}
/**
@@ -590,7 +680,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static ColorUIResource getWindowTitleInactiveBackground()
{
- return theme.getWindowTitleInactiveBackground();
+ if (theme != null)
+ return theme.getWindowTitleInactiveBackground();
+ return null;
}
/**
@@ -601,7 +693,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public static ColorUIResource getWindowTitleInactiveForeground()
{
- return theme.getWindowTitleInactiveForeground();
+ if (theme != null)
+ return theme.getWindowTitleInactiveForeground();
+ return null;
}
/**
@@ -691,6 +785,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel
"CheckBoxUI", "javax.swing.plaf.metal.MetalCheckBoxUI",
"ComboBoxUI", "javax.swing.plaf.metal.MetalComboBoxUI",
"DesktopIconUI", "javax.swing.plaf.metal.MetalDesktopIconUI",
+ "FileChooserUI", "javax.swing.plaf.metal.MetalFileChooserUI",
"InternalFrameUI", "javax.swing.plaf.metal.MetalInternalFrameUI",
"LabelUI", "javax.swing.plaf.metal.MetalLabelUI",
"MenuBarUI", "javax.swing.plaf.metal.MetalMenuBarUI",
@@ -841,7 +936,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel
"EditorPane.background", getWindowBackground(),
"EditorPane.caretForeground", getUserTextColor(),
- "EditorPane.font", new FontUIResource("Dialog", Font.PLAIN, 12),
+ "EditorPane.font", new FontUIResource("Dialog", Font.BOLD, 12),
"EditorPane.foreground", getUserTextColor(),
"EditorPane.inactiveForeground", getInactiveSystemTextColor(),
"EditorPane.selectionBackground", getTextHighlightColor(),
@@ -858,6 +953,19 @@ public class MetalLookAndFeel extends BasicLookAndFeel
"FormattedTextField.selectionBackground", getTextHighlightColor(),
"FormattedTextField.selectionForeground", getHighlightedTextColor(),
+ "FileChooser.upFolderIcon",
+ MetalIconFactory.getFileChooserUpFolderIcon(),
+ "FileChooser.listViewIcon",
+ MetalIconFactory.getFileChooserListViewIcon(),
+ "FileChooser.newFolderIcon",
+ MetalIconFactory.getFileChooserNewFolderIcon(),
+ "FileChooser.homeFolderIcon",
+ MetalIconFactory.getFileChooserHomeFolderIcon(),
+ "FileChooser.detailsViewIcon",
+ MetalIconFactory.getFileChooserDetailViewIcon(),
+ "FileChooser.fileNameLabelMnemonic", new Integer(78),
+ "FileChooser.filesOfTypeLabelMnemonic",new Integer(84),
+ "FileChooser.lookInLabelMnemonic", new Integer(73),
"FileView.computerIcon", MetalIconFactory.getTreeComputerIcon(),
"FileView.directoryIcon", MetalIconFactory.getTreeFolderIcon(),
"FileView.fileIcon", MetalIconFactory.getTreeLeafIcon(),
@@ -875,15 +983,20 @@ public class MetalLookAndFeel extends BasicLookAndFeel
"InternalFrame.icon", MetalIconFactory.getInternalFrameDefaultMenuIcon(),
"InternalFrame.closeIcon",
MetalIconFactory.getInternalFrameCloseIcon(16),
+ "InternalFrame.closeSound", "sounds/FrameClose.wav",
"InternalFrame.inactiveTitleBackground", getWindowTitleInactiveBackground(),
"InternalFrame.inactiveTitleForeground", getWindowTitleInactiveForeground(),
"InternalFrame.maximizeIcon",
MetalIconFactory.getInternalFrameMaximizeIcon(16),
+ "InternalFrame.maximizeSound", "sounds/FrameMaximize.wav",
"InternalFrame.iconifyIcon",
MetalIconFactory.getInternalFrameMinimizeIcon(16),
+ "InternalFrame.minimizeSound", "sounds/FrameMinimize.wav",
"InternalFrame.paletteBorder", new MetalBorders.PaletteBorder(),
"InternalFrame.paletteCloseIcon", new MetalIconFactory.PaletteCloseIcon(),
"InternalFrame.paletteTitleHeight", new Integer(11),
+ "InternalFrame.restoreDownSound", "sounds/FrameRestoreDown.wav",
+ "InternalFrame.restoreUpSound", "sounds/FrameRestoreUp.wav",
"Label.background", getControl(),
"Label.disabledForeground", getInactiveSystemTextColor(),
@@ -902,14 +1015,18 @@ public class MetalLookAndFeel extends BasicLookAndFeel
"Menu.acceleratorFont", new FontUIResource("Dialog", Font.PLAIN, 10),
"Menu.acceleratorForeground", getAcceleratorForeground(),
"Menu.acceleratorSelectionForeground", getAcceleratorSelectedForeground(),
+ "Menu.arrowIcon", MetalIconFactory.getMenuArrowIcon(),
"Menu.background", getMenuBackground(),
"Menu.border", new MetalBorders.MenuItemBorder(),
"Menu.borderPainted", Boolean.TRUE,
+ "MenuItem.commandSound", "sounds/MenuItemCommand.wav",
"Menu.disabledForeground", getMenuDisabledForeground(),
"Menu.font", getControlTextFont(),
"Menu.foreground", getMenuForeground(),
"Menu.selectionBackground", getMenuSelectedBackground(),
"Menu.selectionForeground", getMenuSelectedForeground(),
+ "Menu.submenuPopupOffsetX", new Integer(-4),
+ "Menu.submenuPopupOffsetY", new Integer(-3),
"MenuBar.background", getMenuBackground(),
"MenuBar.border", new MetalBorders.MenuBarBorder(),
@@ -918,11 +1035,14 @@ public class MetalLookAndFeel extends BasicLookAndFeel
"MenuBar.highlight", getControlHighlight(),
"MenuBar.shadow", getControlShadow(),
+ "MenuItem.acceleratorDelimiter", "-",
"MenuItem.acceleratorFont", new FontUIResource("Dialog", Font.PLAIN, 10),
"MenuItem.acceleratorForeground", getAcceleratorForeground(),
"MenuItem.acceleratorSelectionForeground", getAcceleratorSelectedForeground(),
+ "MenuItem.arrowIcon", MetalIconFactory.getMenuItemArrowIcon(),
"MenuItem.background", getMenuBackground(),
"MenuItem.border", new MetalBorders.MenuItemBorder(),
+ "MenuItem.borderPainted", Boolean.TRUE,
"MenuItem.disabledForeground", getMenuDisabledForeground(),
"MenuItem.font", getControlTextFont(),
"MenuItem.foreground", getMenuForeground(),
@@ -930,6 +1050,10 @@ public class MetalLookAndFeel extends BasicLookAndFeel
"MenuItem.selectionForeground", getMenuSelectedForeground(),
"OptionPane.background", getControl(),
+ "OptionPane.errorSound", "sounds/OptionPaneError.wav",
+ "OptionPane.informationSound", "sounds/OptionPaneInformation.wav",
+ "OptionPane.questionSound", "sounds/OptionPaneQuestion.wav",
+ "OptionPane.warningSound", "sounds/OptionPaneWarning.wav",
"OptionPane.errorDialog.border.background", new ColorUIResource(153, 51, 51),
"OptionPane.errorDialog.titlePane.background", new ColorUIResource(255, 153, 153),
"OptionPane.errorDialog.titlePane.foreground", new ColorUIResource(51, 0, 0),
@@ -953,6 +1077,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel
new BorderUIResource(MetalBorders.getTextFieldBorder()),
"PasswordField.caretForeground", getUserTextColor(),
"PasswordField.foreground", getUserTextColor(),
+ "PasswordField.font", new FontUIResource("Dialog", Font.PLAIN, 12),
"PasswordField.inactiveBackground", getControl(),
"PasswordField.inactiveForeground", getInactiveSystemTextColor(),
"PasswordField.selectionBackground", getTextHighlightColor(),
@@ -962,6 +1087,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel
"PopupMenu.border", new MetalBorders.PopupMenuBorder(),
"PopupMenu.font", new FontUIResource("Dialog", Font.BOLD, 12),
"PopupMenu.foreground", getMenuForeground(),
+ "PopupMenu.popupSound", "sounds/PopupMenuPopup.wav",
"ProgressBar.background", getControl(),
"ProgressBar.border", new BorderUIResource.LineBorderUIResource(getControlDarkShadow(), 1),
@@ -997,6 +1123,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel
"RadioButtonMenuItem.borderPainted", Boolean.TRUE,
"RadioButtonMenuItem.checkIcon",
MetalIconFactory.getRadioButtonMenuItemIcon(),
+ "RadioButtonMenuItem.commandSound", "sounds/MenuItemCommand.wav",
"RadioButtonMenuItem.disabledForeground", getMenuDisabledForeground(),
"RadioButtonMenuItem.font", MetalLookAndFeel.getControlTextFont(),
"RadioButtonMenuItem.foreground", getMenuForeground(),
@@ -1006,6 +1133,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel
"RadioButtonMenuItem.selectionForeground",
MetalLookAndFeel.getMenuSelectedForeground(),
+ "ScrollBar.allowsAbsolutePositioning", Boolean.TRUE,
"ScrollBar.background", getControl(),
"ScrollBar.darkShadow", getControlDarkShadow(),
"ScrollBar.foreground", getControl(),
@@ -1041,6 +1169,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel
"Slider.verticalThumbIcon",
MetalIconFactory.getVerticalSliderThumbIcon(),
+ "Spinner.arrowButtonInsets", new InsetsUIResource(0, 0, 0, 0),
"Spinner.background", getControl(),
"Spinner.font", new FontUIResource("Dialog", Font.BOLD, 12),
"Spinner.foreground", getControl(),
@@ -1048,6 +1177,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel
"SplitPane.background", getControl(),
"SplitPane.darkShadow", getControlDarkShadow(),
"SplitPane.dividerFocusColor", getPrimaryControl(),
+ "SplitPane.dividerSize", new Integer(10),
"SplitPane.highlight", getControlHighlight(),
"SplitPane.shadow", getControlShadow(),
@@ -1150,6 +1280,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel
"ToolTip.font", new FontUIResource("Dialog", Font.PLAIN, 12),
"ToolTip.foreground", getPrimaryControlInfo(),
"ToolTip.foregroundInactive", getControlDarkShadow(),
+ "ToolTip.hideAccelerator", Boolean.FALSE,
"Tree.background", getWindowBackground(),
"Tree.closedIcon", MetalIconFactory.getTreeFolderIcon(),
diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalRadioButtonUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalRadioButtonUI.java
index de71fe8e5b2..9fb960f68b9 100644
--- a/libjava/classpath/javax/swing/plaf/metal/MetalRadioButtonUI.java
+++ b/libjava/classpath/javax/swing/plaf/metal/MetalRadioButtonUI.java
@@ -176,7 +176,7 @@ public class MetalRadioButtonUI
protected void paintFocus(Graphics g, Rectangle t, Dimension d)
{
g.setColor(focusColor);
- g.drawRect(t.x - 1, t.y + 2, t.width + 2, t.height - 4);
+ g.drawRect(t.x - 1, t.y - 1, t.width + 2, t.height + 2);
}
}
diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalScrollPaneUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalScrollPaneUI.java
index d5bf175f92d..ae14af3cae9 100644
--- a/libjava/classpath/javax/swing/plaf/metal/MetalScrollPaneUI.java
+++ b/libjava/classpath/javax/swing/plaf/metal/MetalScrollPaneUI.java
@@ -38,7 +38,10 @@ exception statement from your version. */
package javax.swing.plaf.metal;
+import java.beans.PropertyChangeListener;
+
import javax.swing.JComponent;
+import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicScrollPaneUI;
@@ -68,4 +71,89 @@ public class MetalScrollPaneUI
{
return new MetalScrollPaneUI();
}
+
+ /**
+ * Configures the specified component appropriate for the look and feel.
+ * This method is invoked when the ComponentUI instance is being installed
+ * as the UI delegate on the specified component. This method should
+ * completely configure the component for the look and feel,
+ * including the following:
+ * 1. Install any default property values for color, fonts, borders,
+ * icons, opacity, etc. on the component. Whenever possible, property
+ * values initialized by the client program should not be overridden.
+ * 2. Install a LayoutManager on the component if necessary.
+ * 3. Create/add any required sub-components to the component.
+ * 4. Create/install event listeners on the component.
+ * 5. Create/install a PropertyChangeListener on the component in order
+ * to detect and respond to component property changes appropriately.
+ * 6. Install keyboard UI (mnemonics, traversal, etc.) on the component.
+ * 7. Initialize any appropriate instance data.
+ *
+ * @param c - the component to install the ui on
+ */
+ public void installUI(JComponent c)
+ {
+ super.installUI(c);
+ JScrollBar hsb = scrollpane.getHorizontalScrollBar();
+ hsb.putClientProperty(MetalScrollBarUI.FREE_STANDING_PROP, Boolean.FALSE);
+ JScrollBar vsb = scrollpane.getVerticalScrollBar();
+ vsb.putClientProperty(MetalScrollBarUI.FREE_STANDING_PROP, Boolean.FALSE);
+ }
+
+ /**
+ * Reverses configuration which was done on the specified component
+ * during installUI. This method is invoked when this UIComponent
+ * instance is being removed as the UI delegate for the specified
+ * component. This method should undo the configuration performed in
+ * installUI, being careful to leave the JComponent instance in a
+ * clean state (no extraneous listeners, look-and-feel-specific property
+ * objects, etc.). This should include the following:
+ * 1. Remove any UI-set borders from the component.
+ * 2. Remove any UI-set layout managers on the component.
+ * 3. Remove any UI-added sub-components from the component.
+ * 4. Remove any UI-added event/property listeners from the component.
+ * 5. Remove any UI-installed keyboard UI from the component.
+ * 6. Nullify any allocated instance data objects to allow for GC.
+ *
+ * @param c - the component to uninstall the ui on
+ */
+ public void uninstallUI(JComponent c)
+ {
+ JScrollBar hsb = scrollpane.getHorizontalScrollBar();
+ hsb.putClientProperty(MetalScrollBarUI.FREE_STANDING_PROP, null);
+ JScrollBar vsb = scrollpane.getVerticalScrollBar();
+ vsb.putClientProperty(MetalScrollBarUI.FREE_STANDING_PROP, null);
+ super.uninstallUI(c);
+ }
+
+ /**
+ * Installs listeners on scrollPane
+ *
+ * @param scrollPane - the component to install the listeners on
+ */
+ public void installListeners(JScrollPane scrollPane)
+ {
+ super.installListeners(scrollPane);
+ }
+
+ /**
+ * Uninstalls listeners on scrollPane
+ *
+ * @param scrollPane - the component to uninstall the listeners on
+ */
+ public void uninstallListeners(JScrollPane scrollPane)
+ {
+ super.uninstallListeners(scrollPane);
+ }
+
+ /**
+ * TODO
+ *
+ * @return TODO
+ */
+ protected PropertyChangeListener createScrollBarSwapListener()
+ {
+ // FIXME: Anything else to do here?
+ return super.createPropertyChangeListener();
+ }
}
diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalSplitPaneDivider.java b/libjava/classpath/javax/swing/plaf/metal/MetalSplitPaneDivider.java
index 016e09557d6..34a964cb339 100644
--- a/libjava/classpath/javax/swing/plaf/metal/MetalSplitPaneDivider.java
+++ b/libjava/classpath/javax/swing/plaf/metal/MetalSplitPaneDivider.java
@@ -38,9 +38,16 @@ exception statement from your version. */
package javax.swing.plaf.metal;
import java.awt.Color;
+import java.awt.Component;
+import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
+import java.awt.LayoutManager;
+import java.awt.Point;
+import javax.swing.JSplitPane;
+import javax.swing.SwingConstants;
+import javax.swing.plaf.basic.BasicArrowButton;
import javax.swing.plaf.basic.BasicSplitPaneDivider;
/**
@@ -56,7 +63,13 @@ class MetalSplitPaneDivider extends BasicSplitPaneDivider
/** The light color in the pattern. */
Color light;
+
+ /** The JSplitPane the divider is on. */
+ JSplitPane splitPane;
+ /** The split pane orientation. */
+ int orientation;
+
/**
* Creates a new instance of MetalSplitPaneDivider.
*
@@ -65,6 +78,9 @@ class MetalSplitPaneDivider extends BasicSplitPaneDivider
public MetalSplitPaneDivider(MetalSplitPaneUI ui, Color light, Color dark)
{
super(ui);
+ setLayout(new MetalDividerLayout());
+ this.splitPane = super.splitPane;
+ this.orientation = super.orientation;
this.light = light;
this.dark = dark;
}
@@ -76,9 +92,127 @@ class MetalSplitPaneDivider extends BasicSplitPaneDivider
*/
public void paint(Graphics g)
{
- //super.paint(g);
Dimension s = getSize();
MetalUtils.fillMetalPattern(splitPane, g, 2, 2, s.width - 4, s.height - 4,
light, dark);
+ if (splitPane.isOneTouchExpandable())
+ {
+ ((BasicArrowButton) rightButton).paint(g);
+ ((BasicArrowButton) leftButton).paint(g);
+ }
+ }
+
+ /**
+ * This helper class acts as the Layout Manager for the divider.
+ */
+ public class MetalDividerLayout implements LayoutManager
+ {
+ /** The right button. */
+ BasicArrowButton rb;
+
+ /** The left button. */
+ BasicArrowButton lb;
+
+ /**
+ * Creates a new DividerLayout object.
+ */
+ public MetalDividerLayout()
+ {
+ // Nothing to do here
+ }
+
+ /**
+ * This method is called when a Component is added.
+ *
+ * @param string The constraints string.
+ * @param c The Component to add.
+ */
+ public void addLayoutComponent(String string, Component c)
+ {
+ // Nothing to do here, constraints are set depending on
+ // orientation in layoutContainer
+ }
+
+ /**
+ * This method is called to lay out the container.
+ *
+ * @param c The container to lay out.
+ */
+ public void layoutContainer(Container c)
+ {
+ // The only components we care about setting up are the
+ // one touch buttons.
+ if (splitPane.isOneTouchExpandable())
+ {
+ if (c.getComponentCount() == 2)
+ {
+ Component c1 = c.getComponent(0);
+ Component c2 = c.getComponent(1);
+ if ((c1 instanceof BasicArrowButton)
+ && (c2 instanceof BasicArrowButton))
+ {
+ lb = ((BasicArrowButton) c1);
+ rb = ((BasicArrowButton) c2);
+ }
+ }
+ if (rb != null && lb != null)
+ {
+ Point p = getLocation();
+ lb.setSize(lb.getPreferredSize());
+ rb.setSize(rb.getPreferredSize());
+ lb.setLocation(p.x, p.y);
+
+ if (orientation == JSplitPane.HORIZONTAL_SPLIT)
+ {
+ rb.setDirection(SwingConstants.EAST);
+ lb.setDirection(SwingConstants.WEST);
+ rb.setLocation(p.x, p.y + lb.getHeight());
+ }
+ else
+ {
+ rb.setDirection(SwingConstants.SOUTH);
+ lb.setDirection(SwingConstants.NORTH);
+ rb.setLocation(p.x + lb.getWidth(), p.y);
+ }
+ }
+ }
+ }
+
+ /**
+ * This method returns the minimum layout size.
+ *
+ * @param c The container to calculate for.
+ *
+ * @return The minimum layout size.
+ */
+ public Dimension minimumLayoutSize(Container c)
+ {
+ return preferredLayoutSize(c);
+ }
+
+ /**
+ * This method returns the preferred layout size.
+ *
+ * @param c The container to calculate for.
+ *
+ * @return The preferred layout size.
+ */
+ public Dimension preferredLayoutSize(Container c)
+ {
+ int dividerSize = getDividerSize();
+ return new Dimension(dividerSize, dividerSize);
+ }
+
+ /**
+ * This method is called when a component is removed.
+ *
+ * @param c The component to remove.
+ */
+ public void removeLayoutComponent(Component c)
+ {
+ // Nothing to do here. If buttons are removed
+ // they will not be layed out when layoutContainer is
+ // called.
+ }
}
}
diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalTabbedPaneUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalTabbedPaneUI.java
index b1e02c7a6b0..c6c46ffe614 100644
--- a/libjava/classpath/javax/swing/plaf/metal/MetalTabbedPaneUI.java
+++ b/libjava/classpath/javax/swing/plaf/metal/MetalTabbedPaneUI.java
@@ -38,11 +38,14 @@ exception statement from your version. */
package javax.swing.plaf.metal;
+import java.awt.Color;
import java.awt.Graphics;
import java.awt.LayoutManager;
+import java.awt.Rectangle;
import javax.swing.JComponent;
import javax.swing.JTabbedPane;
+import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicTabbedPaneUI;
@@ -101,6 +104,29 @@ public class MetalTabbedPaneUI extends BasicTabbedPaneUI
}
/**
+ * The minimum tab width.
+ */
+ protected int minTabWidth;
+
+ /**
+ * The color for the selected tab.
+ */
+ protected Color selectColor;
+
+ /**
+ * The color for a highlighted selected tab.
+ */
+ protected Color selectHighlight;
+
+ /**
+ * The background color used for the tab area.
+ */
+ protected Color tabAreaBackground;
+
+ /** The graphics to draw the highlight below the tab. */
+ private Graphics hg;
+
+ /**
* Constructs a new instance of MetalTabbedPaneUI.
*/
public MetalTabbedPaneUI()
@@ -175,6 +201,16 @@ public class MetalTabbedPaneUI extends BasicTabbedPaneUI
protected void paintTopTabBorder(int tabIndex, Graphics g, int x, int y,
int w, int h, int btm, int rght, boolean isSelected)
{
+ int currentRun = getRunForTab(tabPane.getTabCount(), tabIndex);
+ if (shouldFillGap(currentRun, tabIndex, x, y))
+ {
+ g.translate(x, y);
+ g.setColor(getColorForGap(currentRun, x, y));
+ g.fillRect(1, 0, 5, 3);
+ g.fillRect(1, 3, 2, 2);
+ g.translate(-x, -y);
+ }
+
if (isSelected)
{
g.setColor(MetalLookAndFeel.getControlHighlight());
@@ -267,6 +303,16 @@ public class MetalTabbedPaneUI extends BasicTabbedPaneUI
protected void paintBottomTabBorder(int tabIndex, Graphics g, int x, int y,
int w, int h, int btm, int rght, boolean isSelected)
{
+ int currentRun = getRunForTab(tabPane.getTabCount(), tabIndex);
+ if (shouldFillGap(currentRun, tabIndex, x, y))
+ {
+ g.translate(x, y);
+ g.setColor(getColorForGap(currentRun, x, y));
+ g.fillRect(1, h - 5, 3, 5);
+ g.fillRect(4, h - 2, 2, 2);
+ g.translate(-x, -y);
+ }
+
if (isSelected)
{
g.setColor(MetalLookAndFeel.getControlHighlight());
@@ -297,9 +343,16 @@ public class MetalTabbedPaneUI extends BasicTabbedPaneUI
int tabIndex, int x, int y, int w, int h, boolean isSelected)
{
if (isSelected)
- g.setColor(MetalLookAndFeel.getControl());
+ g.setColor(UIManager.getColor("TabbedPane.selected"));
else
- g.setColor(MetalLookAndFeel.getControlShadow());
+ {
+ // This is only present in the OceanTheme, so we must check if it
+ // is actually there
+ Color background = UIManager.getColor("TabbedPane.unselectedBackground");
+ if (background == null)
+ background = UIManager.getColor("TabbedPane.background");
+ g.setColor(background);
+ }
int[] px, py;
if (tabPlacement == TOP)
{
@@ -324,6 +377,8 @@ public class MetalTabbedPaneUI extends BasicTabbedPaneUI
else
throw new AssertionError("Unrecognised 'tabPlacement' argument.");
g.fillPolygon(px, py, 5);
+ hg = g;
+ paintHighlightBelowTab();
}
/**
@@ -342,5 +397,94 @@ public class MetalTabbedPaneUI extends BasicTabbedPaneUI
// (which is drawn at the very top for tabPlacement == TOP)
return run < this.runCount - 1;
}
+
+ /**
+ * Installs the defaults for this UI. This method calls super.installDefaults
+ * and then loads the Metal specific defaults for TabbedPane.
+ */
+ protected void installDefaults()
+ {
+ super.installDefaults();
+ selectColor = UIManager.getColor("TabbedPane.selected");
+ selectHighlight = UIManager.getColor("TabbedPane.selectHighlight");
+ tabAreaBackground = UIManager.getColor("TabbedPane.tabAreaBackground");
+ minTabWidth = 0;
+ }
+ /**
+ * Returns the color for the gap.
+ *
+ * @param currentRun - The current run to return the color for
+ * @param x - The x position of the current run
+ * @param y - The y position of the current run
+ *
+ * @return the color for the gap in the current run.
+ */
+ protected Color getColorForGap(int currentRun, int x, int y)
+ {
+ int index = tabForCoordinate(tabPane, x, y);
+ int selected = tabPane.getSelectedIndex();
+ if (selected == index)
+ return selectColor;
+ return tabAreaBackground;
+ }
+
+ /**
+ * Returns true if the gap should be filled in.
+ *
+ * @param currentRun - The current run
+ * @param tabIndex - The current tab
+ * @param x - The x position of the tab
+ * @param y - The y position of the tab
+ *
+ * @return true if the gap at the current run should be filled
+ */
+ protected boolean shouldFillGap(int currentRun, int tabIndex, int x, int y)
+ {
+ // As far as I can tell, the gap is never filled in.
+ return false;
+ }
+
+ /**
+ * Paints the highlight below the tab, if there is one.
+ */
+ protected void paintHighlightBelowTab()
+ {
+ int selected = tabPane.getSelectedIndex();
+ int tabPlacement = tabPane.getTabPlacement();
+ Rectangle bounds = getTabBounds(tabPane, selected);
+
+ hg.setColor(selectColor);
+ int x = bounds.x;
+ int y = bounds.y;
+ int w = bounds.width;
+ int h = bounds.height;
+
+ if (tabPlacement == TOP)
+ hg.fillRect(x, y + h - 2, w, 30);
+ else if (tabPlacement == LEFT)
+ hg.fillRect(x + w - 1, y, 20, h);
+ else if (tabPlacement == BOTTOM)
+ hg.fillRect(x, y - h + 2, w, 30);
+ else if (tabPlacement == RIGHT)
+ hg.fillRect(x - 18, y, 20, h);
+ else
+ throw new AssertionError("Unrecognised 'tabPlacement' argument.");
+ hg = null;
+ }
+
+ /**
+ * Returns true if we should rotate the tab runs.
+ *
+ * @param tabPlacement - The current tab placement.
+ * @param selectedRun - The selected run.
+ *
+ * @return true if the tab runs should be rotated.
+ */
+ protected boolean shouldRotateTabRuns(int tabPlacement,
+ int selectedRun)
+ {
+ // false because tab runs are not rotated in the MetalLookAndFeel
+ return false;
+ }
}
diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalTextFieldUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalTextFieldUI.java
index 6984daeccbe..30738b37c72 100644
--- a/libjava/classpath/javax/swing/plaf/metal/MetalTextFieldUI.java
+++ b/libjava/classpath/javax/swing/plaf/metal/MetalTextFieldUI.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing.plaf.metal;
+import java.beans.PropertyChangeEvent;
+
import javax.swing.JComponent;
import javax.swing.JTextField;
import javax.swing.plaf.ComponentUI;
@@ -67,4 +69,14 @@ public class MetalTextFieldUI extends BasicTextFieldUI
{
return new MetalTextFieldUI();
}
+
+ /**
+ * This method gets called when a bound property is changed on the associated
+ * JTextComponent. This is a hook which UI implementations may change to
+ * reflect how the UI displays bound properties of JTextComponent subclasses.
+ */
+ public void propertyChange(PropertyChangeEvent evt)
+ {
+ super.propertyChange(evt);
+ }
}
diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalToolBarUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalToolBarUI.java
index c5ca91399ab..16e22ac5286 100644
--- a/libjava/classpath/javax/swing/plaf/metal/MetalToolBarUI.java
+++ b/libjava/classpath/javax/swing/plaf/metal/MetalToolBarUI.java
@@ -38,12 +38,16 @@ exception statement from your version. */
package javax.swing.plaf.metal;
+import java.awt.Point;
import java.awt.event.ContainerListener;
+import java.awt.event.MouseEvent;
+
import java.beans.PropertyChangeListener;
import javax.swing.JComponent;
import javax.swing.JToolBar;
import javax.swing.border.Border;
+import javax.swing.event.MouseInputListener;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicToolBarUI;
@@ -158,5 +162,67 @@ public class MetalToolBarUI extends BasicToolBarUI
{
return MetalBorders.getToolbarButtonBorder();
}
-
+
+ /**
+ * Sets the offset for the window used for dragging the toolbar.
+ * It is set as long as the window is not null (it has been installed).
+ */
+ protected void setDragOffset(Point p)
+ {
+ if (dragWindow != null)
+ dragWindow.setOffset(p);
+ }
+
+ /**
+ * Creates and returns an instance of MetalDockingListener.
+ *
+ * @return an instance of MetalDockingListener.
+ */
+ protected MouseInputListener createDockingListener()
+ {
+ return new MetalDockingListener(toolBar);
+ }
+
+ /**
+ * This is the MouseHandler class that allows the user to drag the JToolBar
+ * in and out of the parent and dock it if it can.
+ */
+ protected class MetalDockingListener extends BasicToolBarUI.DockingListener
+ {
+ /**
+ * Creates a new DockingListener object.
+ *
+ * @param t The JToolBar this DockingListener is being used for.
+ */
+ public MetalDockingListener(JToolBar t)
+ {
+ super(t);
+ }
+
+ /**
+ * This method is called when the mouse is pressed in the JToolBar. If the
+ * press doesn't occur in a place where it causes the JToolBar to be
+ * dragged, it returns. Otherwise, it starts a drag session.
+ *
+ * @param e The MouseEvent.
+ */
+ public void mousePressed(MouseEvent e)
+ {
+ super.mousePressed(e);
+ setDragOffset(new Point(e.getX(), e.getY()));
+ }
+
+ /**
+ * This method is called when the mouse is dragged. It delegates the drag
+ * painting to the dragTo method.
+ *
+ * @param e The MouseEvent.
+ */
+ public void mouseDragged(MouseEvent e)
+ {
+ // Does not do anything differently than dragging
+ // BasicToolBarUI.DockingListener
+ super.mouseDragged(e);
+ }
+ }
}
diff --git a/libjava/classpath/javax/swing/plaf/metal/OceanTheme.java b/libjava/classpath/javax/swing/plaf/metal/OceanTheme.java
index f1886b167cf..d1fc4cfecde 100644
--- a/libjava/classpath/javax/swing/plaf/metal/OceanTheme.java
+++ b/libjava/classpath/javax/swing/plaf/metal/OceanTheme.java
@@ -238,6 +238,10 @@ public class OceanTheme extends DefaultMetalTheme
{new Double(0.3), new Double(0.0), new ColorUIResource(221, 232, 243),
new ColorUIResource(Color.WHITE), new ColorUIResource(184, 207, 229)}));
+
defaults.put("Button.rollover", Boolean.TRUE);
+
+ defaults.put("TabbedPane.selected", new ColorUIResource(200, 221, 242));
+ defaults.put("TabbedPane.unselectedBackground", SECONDARY3);
}
}
OpenPOWER on IntegriCloud