Selection background color in a custom TreeCellRenderer

I'm trying to write a custom TreeCellRender and I'm not having any luck getting the selection to work. When I click on a node (leaf or not) the color of the node does not change. If I use the default renderer instead of my custom renderer selection works fine. I've tried everything I can find on the web, setOpaque(true) setTextSelectionColor() etc but I'm not getting anywhere. I've also tried setting the background color in getTreeCellRendererComponent() based on the selected boolean. Still nothing.
Here's my code:
class PackageTreeRenderer extends DefaultTreeCellRenderer {
     public PackageTreeRenderer() {
          setOpaque(true);
          setTextSelectionColor(getBackgroundSelectionColor());
     public Component getTreeCellRendererComponent(JTree t,Object value,boolean sel,boolean expanded,boolean leaf,int row,boolean hasFocus) {
          DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
          Object obj = node.getUserObject();
          if(obj instanceof String) {
               String name = (String) obj;
               setText(name);
          if(obj instanceof ResultPackageInterface) {
               ResultPackageInterface rpi = (ResultPackageInterface) obj;
               String name = "Name";
               try {
                    name = rpi.getDescription();
               catch(RemoteException ex) {
                    errorMessage(ex);
               setText(name);
          if(leaf) {
               setIcon(getLeafIcon());
          else {
               if(expanded) {
                    setIcon(getOpenIcon());
               else {
                    setIcon(getClosedIcon());
          return this;
}Hope someone can help.

Thanks for the suggestions everyone but I got it working. Instead of extending DefaultTreeCellRenderer it works if I extend JLabel and implement TreeCellRenderer. Here's my code for future reference:
class PackageTreeRenderer extends JLabel implements TreeCellRenderer {
     public PackageTreeRenderer() {
          setOpaque(true);
     public Component getTreeCellRendererComponent(JTree t,Object value,boolean sel,boolean expanded,boolean leaf,int row,boolean hasFocus) {
          DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
          Object obj = node.getUserObject();
          setText(obj.toString());
          if(obj instanceof String) {
               String name = (String) obj;
               setText(name);
          if(obj instanceof ResultPackageInterface) {
               ResultPackageInterface rpi = (ResultPackageInterface) obj;
               String name = "Name";
               try {
                    name = rpi.getDescription();
               catch(RemoteException ex) {
                    errorMessage(ex);
               setText(name);
          if(leaf) {
               setIcon(UIManager.getIcon("Tree.leafIcon"));
          else {
          if(expanded) {
               setIcon(UIManager.getIcon("Tree.openIcon"));
          else {
               setIcon(UIManager.getIcon("Tree.closedIcon"));
          if(sel) {
               setForeground(UIManager.getColor("Tree.selectionForeground"));
               setBackground(UIManager.getColor("Tree.selectionBackground"));
          else {
               setForeground(UIManager.getColor("Tree.textForeground"));
               setBackground(UIManager.getColor("Tree.textBackground"));
          return this;
}

Similar Messages

  • Selection background color in 452 vs 447

    I am using a TextFlow with a SelectionManager.  I have not been able to track this down, but since switching from build 447 to 460 today, my selection background color does not change during a selection.  The selection works fine and it copies fine, but i do not see any visual indication that it is selecting.  I moved back to build 452, and that also has this issue.  Build 447 did not.  Looking at the changes from 447 to 452 (http://labs.adobe.com/technologies/textlayout/builds/changelog.html?452) doesn't give me any hints as to what I am doing wrong.  I tried out the SelectText sample in 460 and it works fine, so its not an inherit flaw in the selectionmanager, just something I am doing incorrectly or differently. 
    The code I am using is too interweaved with other code to post here, but does anyone know off hand of a change between 447 to 452 that could cause this issue?  I am going to try to take my code out and get it to break in a testbed and then slowly move back towards the most basic (ie: the example SelectText.as) and see if I can figure something out.
    Any help would be appreciated,
    -Kevin

    I am using a TextFlow with a SelectionManager.  I have not been able to track this down, but since switching from build 447 to 460 today, my selection background color does not change during a selection.  The selection works fine and it copies fine, but i do not see any visual indication that it is selecting.  I moved back to build 452, and that also has this issue.  Build 447 did not.  Looking at the changes from 447 to 452 (http://labs.adobe.com/technologies/textlayout/builds/changelog.html?452) doesn't give me any hints as to what I am doing wrong.  I tried out the SelectText sample in 460 and it works fine, so its not an inherit flaw in the selectionmanager, just something I am doing incorrectly or differently. 
    The code I am using is too interweaved with other code to post here, but does anyone know off hand of a change between 447 to 452 that could cause this issue?  I am going to try to take my code out and get it to break in a testbed and then slowly move back towards the most basic (ie: the example SelectText.as) and see if I can figure something out.
    Any help would be appreciated,
    -Kevin

  • How to change the selection background color of the selected item in the popup menu of the choice box ?

    How to change the selection background color of the selected item in the popup menu of the choice box ?
    By defaut, the selection background color likes "blue", but if I want it to be "yellow" for example, how should I do ?
    Thanks

    The id is applied by (I think) the skin class of the ChoiceBox. You don't need to define it.
    You have to apply the css in an external style sheet. You can apply the external style sheet to any parent of your choice box, or to the scene (the most usual way to do it).
    Example:
    import java.util.ArrayList;
    import java.util.List;
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.control.ChoiceBox;
    import javafx.scene.layout.VBox;
    import javafx.stage.Stage;
    public class ChoiceBoxTest extends Application {
      @Override
      public void start(Stage primaryStage) throws Exception {
        primaryStage.setTitle("Example 2");
        final ChoiceBox<String> choiceBox = new ChoiceBox<>();
        List<String> tempResult = new ArrayList<String>();
        for (int i = 0; i < 10; i++) {
          tempResult.add("Item " + i);
        choiceBox.getItems().setAll(tempResult);
        VBox root = new VBox();
        root.getChildren().add(choiceBox);
        final Scene scene = new Scene(root, 300, 250);
        scene.getStylesheets().add("choiceBox.css");
        primaryStage.setScene(scene);
        primaryStage.show();   
      public static void main(String[] args) {
        launch(args);
    choiceBox.css:
    @CHARSET "UTF-8";
    #choice-box-menu-item:focused  {
    -fx-background-color: yellow ;
    #choice-box-menu-item .label {
    -fx-text-fill: black ;
    Message was edited by: James_D

  • JTree custom renderer setting selection background color problem

    Hi,
    I have a JTree with a custom icon renderer that displays an icon. The JTree is part of a TreeTable component. Iam having a problem setting the selection background uniformly for the entire row. There is no problem when there is no row selected in the JTable.
    My present code looks like this:
    Iam overriding paint in my renderer which extends DefaultCellRenderer.
           super.paint(g);
            Color bColor = null;
            if(!m_selected) {
                 if(currRow % 2 == 0) {
                      bColor = Color.WHITE;
                 } else {
                                                    bColor = backColor;
            } else {
                 bColor = table.getSelectionBackground();                  bColor = getRowSelectionColor();
         if(bColor != null) {
                           g.setColor(bColor);
             if(!m_selected) {
                   g.setXORMode(new Color(0xFF, 0xFF, 0xFF));
             } else {
                 g.setXORMode(new Color(0x00, 0x00, 0x00));
                  I have a color I arrive at using some algorithm that I want using method getRowSelectionColor(). The other cells in the row have this color. But the cell containing the tree node shows different color. Iam not able to arrive at the right combination of the color to set and the xor color so my tree node also looks like the other cells in the row.
    It is not a problem really as the table still looks good. Its just that the tree node looks like it has been highlighted and this might cause a problem when a table cell is highlighed later on in the application ( two cells in the row would be highlighted causing confusion).
    Any help would be appreciated.
    Regards,
    vidyut

    Hi Camickr,
    Thanks for the reply. Iam sorry I didn't include the sources the first time around. There were too many of them. I have created a small, self-contained, compilable program that demonstrates the problem and including it herewith. Still there's quite many files but they are all needed Iam afraid. The only one you will have to concern yourself fior this problem is the file IconRenderer.java. The treenode background and the other cells background are not in sync when table row is not selected in this example though. But they are in my real program. I just need them to be in sync i.e have the same background color when the row is selected.
    Your help would be very much appreciated.
    These are the files that are included below:
    1. AbstractTreeTableModel.java
    2. Bookmarks.java
    3. BookmarksModel.java
    4. DynamicTreeTableModel.java
    5. IconRenderer.java
    6. IndicatorRenderer.java
    7. JTreeTable.java
    8. TreeTableExample3.java (contains main)
    9. TreeTableModel.java
    10. TreeTableModelAdapter.java
    The copyright and javadocs information has been stripped for clarity.
    cheers,
    vidyut
    // AbstractTreeTableModel.java BEGIN
    import javax.swing.tree.*;
    import javax.swing.event.*;
    public abstract class AbstractTreeTableModel implements TreeTableModel {
        protected Object root;    
        protected EventListenerList listenerList = new EventListenerList();
        public AbstractTreeTableModel(Object root) {
            this.root = root;
        // Default implementations for methods in the TreeModel interface.
        public Object getRoot() {
            return root;
        public boolean isLeaf(Object node) {
            return getChildCount(node) == 0;
        public void valueForPathChanged(TreePath path, Object newValue) {}
        // This is not called in the JTree's default mode:
        // use a naive implementation.
        public int getIndexOfChild(Object parent, Object child) {
            for (int i = 0; i < getChildCount(parent); i++) {
             if (getChild(parent, i).equals(child)) {
                 return i;
         return -1;
        public void addTreeModelListener(TreeModelListener l) {
            listenerList.add(TreeModelListener.class, l);
        public void removeTreeModelListener(TreeModelListener l) {
            listenerList.remove(TreeModelListener.class, l);
        protected void fireTreeNodesChanged(Object source, Object[] path,
                                            int[] childIndices,
                                            Object[] children) {
            // Guaranteed to return a non-null array
            Object[] listeners = listenerList.getListenerList();
            TreeModelEvent e = null;
            // Process the listeners last to first, notifying
            // those that are interested in this event
            for (int i = listeners.length-2; i>=0; i-=2) {
                if (listeners==TreeModelListener.class) {
    // Lazily create the event:
    if (e == null)
    e = new TreeModelEvent(source, path,
    childIndices, children);
    ((TreeModelListener)listeners[i+1]).treeNodesChanged(e);
    protected void fireTreeNodesInserted(Object source, Object[] path,
    int[] childIndices,
    Object[] children) {
    // Guaranteed to return a non-null array
    Object[] listeners = listenerList.getListenerList();
    TreeModelEvent e = null;
    // Process the listeners last to first, notifying
    // those that are interested in this event
    for (int i = listeners.length-2; i>=0; i-=2) {
    if (listeners[i]==TreeModelListener.class) {
    // Lazily create the event:
    if (e == null)
    e = new TreeModelEvent(source, path,
    childIndices, children);
    ((TreeModelListener)listeners[i+1]).treeNodesInserted(e);
    protected void fireTreeNodesRemoved(Object source, Object[] path,
    int[] childIndices,
    Object[] children) {
    // Guaranteed to return a non-null array
    Object[] listeners = listenerList.getListenerList();
    TreeModelEvent e = null;
    // Process the listeners last to first, notifying
    // those that are interested in this event
    for (int i = listeners.length-2; i>=0; i-=2) {
    if (listeners[i]==TreeModelListener.class) {
    // Lazily create the event:
    if (e == null)
    e = new TreeModelEvent(source, path,
    childIndices, children);
    ((TreeModelListener)listeners[i+1]).treeNodesRemoved(e);
    protected void fireTreeStructureChanged(Object source, Object[] path,
    int[] childIndices,
    Object[] children) {
    // Guaranteed to return a non-null array
    Object[] listeners = listenerList.getListenerList();
    TreeModelEvent e = null;
    // Process the listeners last to first, notifying
    // those that are interested in this event
    for (int i = listeners.length-2; i>=0; i-=2) {
    if (listeners[i]==TreeModelListener.class) {
    // Lazily create the event:
    if (e == null)
    e = new TreeModelEvent(source, path,
    childIndices, children);
    ((TreeModelListener)listeners[i+1]).treeStructureChanged(e);
    // Default impelmentations for methods in the TreeTableModel interface.
    public Class getColumnClass(int column) { return Object.class; }
    public boolean isCellEditable(Object node, int column) {
    return getColumnClass(column) == TreeTableModel.class;
    public void setValueAt(Object aValue, Object node, int column) {}
    // Left to be implemented in the subclass:
    * public Object getChild(Object parent, int index)
    * public int getChildCount(Object parent)
    * public int getColumnCount()
    * public String getColumnName(Object node, int column)
    * public Object getValueAt(Object node, int column)
    // AbstractTreeTableModel.java END
    // Bookmarks.java BEGIN
    import java.io.*;
    import java.net.*;
    import java.util.*;
    import javax.swing.*;
    import javax.swing.tree.*;
    import javax.swing.text.*;
    import javax.swing.text.html.*;
    import javax.swing.text.html.parser.*;
    public class Bookmarks {
    /** The root node the bookmarks are added to. */
    private BookmarkDirectory root;
    * Creates a new Bookmarks object, with the entries coming from
    * <code>path</code>.
    public Bookmarks(String path) {
         root = new BookmarkDirectory("Bookmarks");
         if (path != null) {
         parse(path);
    * Returns the root of the bookmarks.
    public BookmarkDirectory getRoot() {
         return root;
    protected void parse(String path) {
         try {
         BufferedReader reader = new BufferedReader(new FileReader
                                       (path));
         new ParserDelegator().parse(reader, new CallbackHandler(), true);
         catch (IOException ioe) {
         System.out.println("IOE: " + ioe);
         JOptionPane.showMessageDialog(null, "Load Bookmarks",
                             "Unable to load bookmarks",
                             JOptionPane.ERROR_MESSAGE);
    private static final short NO_ENTRY = 0;
    private static final short BOOKMARK_ENTRY = 2;
    private static final short DIRECTORY_ENTRY = 3;
    private class CallbackHandler extends HTMLEditorKit.ParserCallback {
         /** Parent node that new entries are added to. */
         private BookmarkDirectory parent;
         /** The most recently parsed tag. */
         private HTML.Tag tag;
         /** The last tag encountered. */
         private HTML.Tag lastTag;
         * The state, will be one of NO_ENTRY, DIRECTORY_ENTRY,
    * or BOOKMARK_ENTRY.
         private short state;
         * Date for the next BookmarkDirectory node.
         private Date parentDate;
         * The values from the attributes are placed in here. When the
         * text is encountered this is added to the node hierarchy and a
    * new instance is created.
         private BookmarkEntry lastBookmark;
         * Creates the CallbackHandler.
         public CallbackHandler() {
         parent = root;
         lastBookmark = new BookmarkEntry();
         // HTMLEditorKit.ParserCallback methods
         * Invoked when text in the html document is encountered. Based on
         * the current state, this will either: do nothing
    * (state == NO_ENTRY),
         * create a new BookmarkEntry (state == BOOKMARK_ENTRY) or
    * create a new
         * BookmarkDirectory (state == DIRECTORY_ENTRY). If state is
    * != NO_ENTRY, it is reset to NO_ENTRY after this is
    * invoked.
    public void handleText(char[] data, int pos) {
         switch (state) {
         case NO_ENTRY:
              break;
         case BOOKMARK_ENTRY:
              // URL.
              lastBookmark.setName(new String(data));
    parent.add(lastBookmark);
    lastBookmark = new BookmarkEntry();
              break;
         case DIRECTORY_ENTRY:
              // directory.
              BookmarkDirectory newParent = new
                   BookmarkDirectory(new String(data));
              newParent.setCreated(parentDate);
              parent.add(newParent);
              parent = newParent;
              break;
         default:
              break;
    state = NO_ENTRY;
         * Invoked when a start tag is encountered. Based on the tag
         * this may update the BookmarkEntry and state, or update the
         * parentDate.
         public void handleStartTag(HTML.Tag t, MutableAttributeSet a,
                        int pos) {
         lastTag = tag;
         tag = t;
         if (t == HTML.Tag.A && lastTag == HTML.Tag.DT) {
    long lDate;
              // URL
              URL url;
              try {
              url = new URL((String)a.getAttribute(HTML.Attribute.HREF));
              } catch (MalformedURLException murle) {
              url = null;
              lastBookmark.setLocation(url);
              // created
              Date date;
              try {
    lDate = Long.parseLong((String)a.getAttribute("add_date"));
    if (lDate != 0l) {
    date = new Date(1000l * lDate);
    else {
    date = null;
              } catch (Exception ex) {
              date = null;
              lastBookmark.setCreated(date);
              // last visited
              try {
    lDate = Long.parseLong((String)a.
    getAttribute("last_visit"));
    if (lDate != 0l) {
    date = new Date(1000l * lDate);
    else {
    date = null;
              } catch (Exception ex) {
              date = null;
              lastBookmark.setLastVisited(date);
              state = BOOKMARK_ENTRY;
         else if (t == HTML.Tag.H3 && lastTag == HTML.Tag.DT) {
              // new node.
              try {
              parentDate = new Date(1000l * Long.parseLong((String)a.
                                  getAttribute("add_date")));
              } catch (Exception ex) {
              parentDate = null;
              state = DIRECTORY_ENTRY;
         * Invoked when the end of a tag is encountered. If the tag is
         * a DL, this will set the node that parents are added to the current
         * nodes parent.
         public void handleEndTag(HTML.Tag t, int pos) {
         if (t == HTML.Tag.DL && parent != null) {
              parent = (BookmarkDirectory)parent.getParent();
    public static class BookmarkDirectory extends DefaultMutableTreeNode {
         /** Dates created. */
         private Date created;
         public BookmarkDirectory(String name) {
         super(name);
         public void setName(String name) {
         setUserObject(name);
         public String getName() {
         return (String)getUserObject();
         public void setCreated(Date date) {
         this.created = date;
         public Date getCreated() {
         return created;
    public static class BookmarkEntry extends DefaultMutableTreeNode {
         /** User description of the string. */
         private String name;
         /** The URL the bookmark represents. */
         private URL location;
         /** Dates the URL was last visited. */
         private Date lastVisited;
         /** Date the URL was created. */
         private Date created;
         public void setName(String name) {
         this.name = name;
         public String getName() {
         return name;
         public void setLocation(URL location) {
         this.location = location;
         public URL getLocation() {
         return location;
         public void setLastVisited(Date date) {
         lastVisited = date;
         public Date getLastVisited() {
         return lastVisited;
         public void setCreated(Date date) {
         this.created = date;
         public Date getCreated() {
         return created;
         public String toString() {
         return getName();
    // Bookmarks.java END
    // BookmarksModel.java BEGIN
    import java.util.Date;
    public class BookmarksModel extends DynamicTreeTableModel {
    * Names of the columns.
    private static final String[] columnNames =
    { "Name", "Location", "Last Visited", "Created" };
    * Method names used to access the data to display.
    private static final String[] methodNames =
    { "getName", "getLocation", "getLastVisited","getCreated" };
    * Method names used to set the data.
    private static final String[] setterMethodNames =
    { "setName", "setLocation", "setLastVisited","setCreated" };
    private static final Class[] classes =
    { TreeTableModel.class, String.class, Date.class, Date.class };
    public BookmarksModel(Bookmarks.BookmarkDirectory root) {
         super(root, columnNames, methodNames, setterMethodNames, classes);
    public boolean isCellEditable(Object node, int column) {
         switch (column) {
         case 0:
         // Allow editing of the name, as long as not the root.
         return (node != getRoot());
         case 1:
         // Allow editing of the location, as long as not a
         // directory
         return (node instanceof Bookmarks.BookmarkEntry);
         default:
         // Don't allow editing of the date fields.
         return false;
    // BookmarksModel.java END
    // DynamicTreeTableModel.java BEGIN
    import java.lang.reflect.*;
    import javax.swing.tree.*;
    public class DynamicTreeTableModel extends AbstractTreeTableModel {
    /** Names of the columns, used for the TableModel getColumnName method. */
    private String[] columnNames;
    private String[] methodNames;
    private String[] setterMethodNames;
    /** Column classes, used for the TableModel method getColumnClass. */
    private Class[] cTypes;
    public DynamicTreeTableModel(TreeNode root, String[] columnNames,
                        String[] getterMethodNames,
                        String[] setterMethodNames,
                        Class[] cTypes) {
         super(root);
         this.columnNames = columnNames;
         this.methodNames = getterMethodNames;
         this.setterMethodNames = setterMethodNames;
         this.cTypes = cTypes;
    public int getChildCount(Object node) {
         return ((TreeNode)node).getChildCount();
    public Object getChild(Object node, int i) {
         return ((TreeNode)node).getChildAt(i);
    public boolean isLeaf(Object node) {
         return ((TreeNode)node).isLeaf();
    public int getColumnCount() {
         return columnNames.length;
    public String getColumnName(int column) {
         if (cTypes == null || column < 0 || column >= cTypes.length) {
         return null;
         return columnNames[column];
    public Class getColumnClass(int column) {
         if (cTypes == null || column < 0 || column >= cTypes.length) {
         return null;
         return cTypes[column];
    public Object getValueAt(Object node, int column) {
         try {
         Method method = node.getClass().getMethod(methodNames[column],
                                  null);
         if (method != null) {
              return method.invoke(node, null);
         catch (Throwable th) {}
         return null;
    * Returns true if there is a setter method name for column
    * <code>column</code>. This is set in the constructor.
    public boolean isCellEditable(Object node, int column) {
    return (setterMethodNames != null &&
         setterMethodNames[column] != null);
    // Note: This looks up the methods each time! This is rather inefficient;
    // it should really be changed to cache matching
    // methods/constructors
    // based on <code>node</code>'s class, and code>aValue</code>'s
    //class.
    public void setValueAt(Object aValue, Object node, int column) {
         boolean found = false;
         try {
         // We have to search through all the methods since the
         // types may not match up.
         Method[] methods = node.getClass().getMethods();
         for (int counter = methods.length - 1; counter >= 0; counter--) {
              if (methods[counter].getName().equals
              (setterMethodNames[column]) && methods[counter].
              getParameterTypes() != null && methods[counter].
              getParameterTypes().length == 1) {
              // We found a matching method
              Class param = methods[counter].getParameterTypes()[0];
              if (!param.isInstance(aValue)) {
                   // Yes, we can use the value passed in directly,
                   // no coercision is necessary!
                   if (aValue instanceof String &&
                   ((String)aValue).length() == 0) {
                   // Assume an empty string is null, this is
                   // probably bogus for here.
                   aValue = null;
                   else {
                   // Have to attempt some sort of coercision.
                   // See if the expected parameter type has
                   // a constructor that takes a String.
                   Constructor cs = param.getConstructor
                   (new Class[] { String.class });
                   if (cs != null) {
                        aValue = cs.newInstance(new Object[]
                                       { aValue });
                   else {
                        aValue = null;
              // null either means it was an empty string, or there
              // was no translation. Could potentially deal with these
              // differently.
              methods[counter].invoke(node, new Object[] { aValue });
              found = true;
              break;
         } catch (Throwable th) {
         System.out.println("exception: " + th);
         if (found) {
         // The value changed, fire an event to notify listeners.
         TreeNode parent = ((TreeNode)node).getParent();
         fireTreeNodesChanged(this, getPathToRoot(parent),
                        new int[] { getIndexOfChild(parent, node) },
                        new Object[] { node });
    public TreeNode[] getPathToRoot(TreeNode aNode) {
    return getPathToRoot(aNode, 0);
    private TreeNode[] getPathToRoot(TreeNode aNode, int depth) {
    TreeNode[] retNodes;
         // This method recurses, traversing towards the root in order
         // size the array. On the way back, it fills in the nodes,
         // starting from the root and working back to the original node.
    /* Check for null, in case someone passed in a null node, or
    they passed in an element that isn't rooted at root. */
    if(aNode == null) {
    if(depth == 0)
    return null;
    else
    retNodes = new TreeNode[depth];
    else {
    depth++;
    if(aNode == root)
    retNodes = new TreeNode[depth];
    else
    retNodes = getPathToRoot(aNode.getParent(), depth);
    retNodes[retNodes.length - depth] = aNode;
    return retNodes;
    // DynamicTreeTableModel.java END
    // IconRenderer.java BEGIN
    import java.awt.*;
    import javax.swing.*;
    import javax.swing.tree.*;
    import javax.swing.plaf.basic.BasicTreeUI;
    class IconRenderer extends DefaultTreeCellRenderer
    // Color backColor = new Color(0xD0, 0xCC, 0xFF);
    Color backColor = new Color(0xF0, 0xF0, 0xE0);
    String tipText = "";
    JTree tree;
    int currRow = 0;
    boolean m_selected;
    JTable table;
    public IconRenderer(JTree tree, JTable table) {
    this.table = table;
    // setBackground(backColor);
    setBackground(Color.GREEN);
    setForeground(Color.black);
         this.tree = tree;
    public Component getTreeCellRendererComponent(JTree tree, Object value,
    boolean selected,
    boolean expanded, boolean leaf,
    int row, boolean hasFocus) {
         Object node = null;
         super.getTreeCellRendererComponent(
    tree, value, selected,
    expanded, leaf, row,
    hasFocus);
         TreePath treePath = tree.getPathForRow(row);
    if(treePath != null)
              node = treePath.getLastPathComponent();
    currRow = row;
    m_selected = selected;
    DefaultMutableTreeNode itc = null;
    if (node instanceof DefaultMutableTreeNode) {
    itc = (DefaultMutableTreeNode)node;
         setClosedIcon(closedIcon);
    setOpenIcon(openIcon);
    return this;
    /* Override the default to send back different strings for folders and leaves. */
    public String getToolTipText() {
    return tipText;
    * Paints the value. The background is filled based on selected.
    public void paint(Graphics g) {
         super.paint(g);
         Color bColor = null;
         if(!m_selected) {
              System.out.println(" iconren not sel currRow " + currRow);
              if(currRow % 2 == 0) {
                   bColor = Color.WHITE;
              } else {
              bColor = backColor;
         } else {
              bColor = table.getSelectionBackground();
              System.out.println("in else selbg = " + bColor);           
              bColor = new Color(0xF0, 0xCC, 0x92);
              System.out.println(" bColor aft = " + bColor);           
         int imageOffset = -1;
         if(bColor != null) {
         imageOffset = getLabelStart();
         g.setColor(bColor);
         if(!m_selected) {
              System.out.println(" not sel setting white ");
              g.setXORMode(new Color(0xFF, 0xFF, 0xFF));
         } else {
    //          g.setXORMode(new Color(0xCC, 0xCC, 0x9F));
              g.setXORMode(new Color(0x00, 0x00, 0x00));
              System.out.println(" using color = " + g.getColor());           
         if(getComponentOrientation().isLeftToRight()) {
         g.fillRect(imageOffset, 0, getWidth() - 1 - imageOffset,
                   getHeight());
         } else {
         g.fillRect(0, 0, getWidth() - 1 - imageOffset,
                   getHeight());
    private int getLabelStart() {
         Icon currentI = getIcon();
         if(currentI != null && getText() != null) {
         return currentI.getIconWidth() + Math.max(0, getIconTextGap() - 1);
         return 0;
    // IconRenderer.java END
    // IndicatorRenderer.java BEGIN
    // import java.awt.*;
    import javax.swing.*;
    import javax.swing.border.*;
    import javax.swing.event.*;
    import javax.swing.tree.*;
    import javax.swing.table.*;
    import javax.swing.table.*;
    import javax.swing.plaf.basic.*;
    import java.awt.event.*;
    import java.util.EventObject;
    import java.text.NumberFormat;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.StringTokenizer;
    import java.util.Arrays;
    class IndicatorRenderer extends DefaultTableCellRenderer {
    /** Makes sure the number of displayed in an internationalized
    * manner. */
    protected NumberFormat formatter;
    /** Row that is currently being painted. */
    protected int lastRow;
    protected int reloadRow;
    protected int reloadCounter;
    protected TreeTableModel treeTableModel;
    protected TreeTableModelAdapter treeTblAdapter;
    protected JTable table;
    Component renderer = null;
    Color backColor = new Color(0xF0, 0xF0, 0xE0);
    IndicatorRenderer(TreeTableModelAdapter treeTblAdapter, TreeTableModel treeTableModel) {
         setHorizontalAlignment(JLabel.RIGHT);
         setFont(new Font("serif", Font.BOLD, 12));
         this.treeTableModel = treeTableModel;
         this.treeTblAdapter = treeTblAdapter;
    * Invoked as part of DefaultTableCellRenderers implemention. Sets
    * the text of the label.
    public void setValue(Object value) {
    /* setText((value == null) ? "---" : formatter.format(value)); */
         setText((value == null) ? "---" : (String) value.toString());
    * Returns this.
    public Component getTableCellRendererComponent(JTable table,
    Object value, boolean isSelected, boolean hasFocus,
    int row, int column) {
         renderer = super.getTableCellRendererComponent(table, value, isSelected,
    hasFocus, row, column);
         lastRow = row;
         this.table = table;
              if(isSelected) {
                   doMask(hasFocus, isSelected);
              } else
              setBackground(table.getBackground());
    return renderer;
    * If the row being painted is also being reloaded this will draw
    * a little indicator.
    public void paint(Graphics g) {
         super.paint(g);
    private void doMask(boolean hasFocus, boolean selected) {
              maskBackground(hasFocus, selected);
    private void maskBackground(boolean hasFocus, boolean selected) {
              Color seed = null;
              seed = table.getSelectionBackground();
              Color color = seed;
              if (color != null) {
                   setBackground(
    new Color(0xF0, 0xCC, 0x92));
    // IndicatorRenderer.java END
    // JTreeTable.java BEGIN
    import java.awt.*;
    import javax.swing.*;
    import javax.swing.border.*;
    import javax.swing.event.*;
    import javax.swing.tree.*;
    import javax.swing.table.*;
    import java.awt.event.*;
    import java.util.EventObject;
    public class JTreeTable extends JTable {
    /** A subclass of JTree. */
    protected TreeTableCellRenderer tree;
    protected IndicatorRenderer indicatorRenderer = null;
    public JTreeTable(TreeTableModel treeTableModel) {
         super();
         // Creates the tree. It will be used as a renderer and editor.
         tree = new TreeTableCellRenderer(treeTableModel);
         TreeTableModelAdapter tdap = new TreeTableModelAdapter(treeTableModel, tree);
         // Installs a tableModel representing the visible rows in the tree.
         super.setModel(tdap);
         // Forces the JTable and JTree to share their row selection models.
         ListToTreeSelectionModelWrapper selectionWrapper = new
         ListToTreeSelectionModelWrapper();
         tree.setSelectionModel(selectionWrapper);
         setSelectionModel(selectionWrapper.getListSelectionModel());
         // Installs the tree editor renderer and editor.
         setDefaultRenderer(TreeTableModel.class, tree);
         setDefaultEditor(TreeTableModel.class, new TreeTableCellEditor());
         indicatorRenderer = new IndicatorRenderer(tdap, treeTableModel);     
         // No grid.
         setShowGrid(false);
         // No intercell spacing
         setIntercellSpacing(new Dimension(0, 0));     
         // And update the height of the trees row to match that of
         // the table.
         //if (tree.getRowHeight() < 1) {
         // Metal looks better like this.
         setRowHeight(20);
    public TableCellRenderer getCellRenderer(int row, int col) {
              if(col == 0)
              return tree;
              else
              return indicatorRenderer;     
    public void updateUI() {
         super.updateUI();
         if(tree != null) {
         tree.updateUI();
         // Do this so that the editor is referencing the current renderer
         // from the tree. The renderer can potentially change each time
         // laf changes.
         setDefaultEditor(TreeTableModel.class, new TreeTableCellEditor());
         // Use the tree's default foreground and background colors in the
         // table.
    LookAndFeel.installColorsAndFont(this, "Tree.background",
    "Tree.foreground", "Tree.font");
    public int getEditingRow() {
    return (getColumnClass(editingColumn) == TreeTableModel.class) ? -1 :
         editingRow;
    private int realEditingRow() {
         return editingRow;
    public void sizeColumnsToFit(int resizingColumn) {
         super.sizeColumnsToFit(resizingColumn);
         if (getEditingColumn() != -1 && getColumnClass(editingColumn) ==
         TreeTableModel.class) {
         Rectangle cellRect = getCellRect(realEditingRow(),
                             getEditingColumn(), false);
    Component component = getEditorComponent();
         component.setBounds(cellRect);
    component.validate();
    public void setRowHeight(int rowHeight) {
    super.setRowHeight(rowHeight);
         if (tree != null && tree.getRowHeight() != rowHeight) {
    tree.setRowHeight(getRowHeight());
    public JTree getTree() {
         return tree;
    public boolean editCellAt(int row, int column, EventObject e){
         boolean retValue = super.editCellAt(row, column, e);
         if (retValue && getColumnClass(column) == TreeTableModel.class) {
         repaint(getCellRect(row, column, false));
         return retValue;
    public class TreeTableCellRenderer extends JTree implements
         TableCellRenderer {
         /** Last table/tree row asked to renderer. */
         protected int visibleRow;
         /** Border to draw around the tree, if this is non-null, it will
         * be painted. */
         protected Border highlightBorder;
         public TreeTableCellRenderer(Tr

  • Chance Xfce desktop icon color and folder select background color

    Hi there,
    I'm using Xfce as my DE and I have installed this theme.
    The problem is, because I have a black desktop background I can't see the icon's labels very well. I already tried to change the color with the file .gtkrc-2.0 in many ways, including the one in Arch Wiki, but the problem continues.
    The other problem is, when I select a folder/file in Thunar the background is white, and again it's very difficult to distinguish between selected and not select folders/files. How can I change the background color? (This one I have no idea of how to make).
    Thanks in advance.

    Hello,
    Try here: http://support.apple.com/kb/HT2493?viewlocale=en_US and here:
    http://www.apple.com/downloads/macosx/icons_screensavers/
    Carolyn

  • Incorrect list item background color in Nimbus custom ListCellRenderer

    Hi there,
    I've been doing lots of web searches trying to come up with what's going on here. It seems other people have had the same problem I've had, but in the one place that seems to nail the question directly, it doesn't seem to be resolved. The issue is that I'm using a JPanel as a ListCellRenderer for a JList. I'm using the Nimbus LAF, and my problem is that the background of the panel doesn't seem to have its background color set properly. I call setBackground on it, and it should be setting it to a DerivedColor that's pure white, but it seems to have no effect. Manually calling setBackground to white works, but it also means I've now hardcoded the color into it, which I'm trying to refrain from doing. Here's some code to reproduce the issue:
    import java.awt.Component;
    import java.awt.EventQueue;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JList;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.ListCellRenderer;
    import javax.swing.UIManager;
    import javax.swing.UIManager.LookAndFeelInfo;
    import javax.swing.border.Border;
    public class ListTest extends JFrame {
      private JScrollPane scrollPane = new JScrollPane();
      private JList list = new JList(new String[] {"TEST 1", "TEST 2"});
      private class Renderer extends JPanel implements ListCellRenderer {
        private JLabel text = new JLabel();
        public Renderer() {
          add(text);
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
          setEnabled(list.isEnabled());
          Border border = null;
          if (cellHasFocus) {
            if (isSelected) {
              border = UIManager.getBorder("List.focusSelectedCellHighlightBorder");
            if (border == null) {
              border = UIManager.getBorder("List.focusCellHighlightBorder");
          } else {
            border = UIManager.getBorder("List.cellNoFocusBorder");
          setBorder(border);
          // set renderer values
          text.setText((String)value);
          text.setFont(list.getFont());
          if (isSelected) {
            setBackground(list.getSelectionBackground());
            text.setForeground(list.getSelectionForeground());
          } else {
            // the color returned from list.getBackground() is pure white
            // but the list items appear with a grey background!
            setBackground(list.getBackground());
            // THIS works -- but is obviously hardcoded
            // setBackground(Color.WHITE);
            text.setForeground(list.getForeground());
          return this;
      public ListTest() {
        list.setCellRenderer(new Renderer());
        scrollPane.setViewportView(list);
        add(scrollPane);
        pack();
      public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
          public void run() {
            for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
              if ("Nimbus".equals(info.getName())) {
                try {
                  UIManager.setLookAndFeel(info.getClassName());
                } catch (Exception ex) { }
            new ListTest().setVisible(true);
    }Here's a StackOverflow question that is exactly what I'm experiencing, but doesn't seem to be exactly resolved: http://stackoverflow.com/questions/2787781
    Any ideas would be greatly appreciated!
    Thanks!

    // the color returned from list.getBackground() is pure white
    // but the list items appear with a grey background!
    setBackground(list.getBackground());
    // THIS works -- but is obviously hardcoded
    // setBackground(Color.WHITE);So when you hardcode the background you are using a Color object.
    Have you added any debug info to see what kind of class list.getBackground() returns?
    If it is some fancy class that extend Color, you can always create your Color object by using:
    Color background = new Color(....)
    Then all you have to do is get the RGB values from the list Color object.

  • Setting the background color of the selection when text selected (input TextField)

    My input TextField has a black background. The problem is,
    when some text is enter and then selected, the selection background
    color remains black and the selected text remains white. Because of
    this it's imposible to tell that the text has been selected. Is
    there a way to change the selection background color, or do I
    really have to write a custom textfield? :(

    Yes, I do have an additional attribute called "identity" which is set to the original table where it came from. The problem is that I do not know how to check for it in my renderer. I will post my renderer code here
    public class myTableRenderer extends DefaultTableCellRenderer{
    public Component getTableCellRendererComponent( JTable table,Object value,boolean isSelected,boolean hasFocus,int row,int column) {
    final Component component = super.getTableCellRendererComponent(table, value,isSelected,hasFocus, row, column);
    if ( value != null ) {
    if ( value instanceof String ) {
    String val = value.toString();
    if ( val.compareTo("DisplayKnown") == 0 ) {
    component.setBackground(Color.CYAN);
    else
    component.setBackground(Color.LIGHT_GRAY);
    } // end if value not null
    return component;
    } // end mytablerenderer
    What happens here, is that only the column with the identity value "DisplayKnown" gets the color blue. I would like to color the whole row with that column value to be Blue.
    Does this make sense??
    Thanks,
    npatel

  • WorkOrderList TileView Row & Selected Row Background Color Change

    Hi,
         can we change the background color of WorkorderList TileView Row & Selected Row Background color ?. Actually i am trying to change the color of both in WorkOrderList but it not reflecting any color on my Agentry client. I used a style on Tile List View Data/Style.
    but these applied style on Rows & Selected Rows are not working in Agentry client.
    if any other alternate solution exist in Agentry, please guide me.
    i am using following...
      sap mobile platform-2.3.3
    Thanks & Regard
    Manish Kumar
    Tags edited by: Michael Appleby

    Hi Jason
          Yes using Image we can achieve that goal but i want to use a background color instead of Image background. Finally I used a background color on label and set the that label field on Screen. And It's showing the background color on WorkOrderList Row & Selected Row that what i wanted. But on both Row & Selected TileView Screen showing white outline that i don't want and also i could not remove the default Selected Blue Background Color.
         Please guide me how to remove white outline and default Blue Selected Background color.
    Thanks & Regard
    Manish Kumar

  • Dynamically Set Subreport Background Color to the Same Value as Main Report Background Color

    I have a report that contains a subreport.  The main report has groupings in it.  I am dynamically setting the background color of the group rows based on an expression.  That part is working fine.  The problem that I am having is that
    I don't know how to get the subreport to "inherit" the background color of the grouping that holds it.
    Basically, I have different row shadings on my report differentiating the groupings except for the rows where the subreport shows.
    How do I go about setting the subreport background color to equal it's contaiing grouping's background color?  Thanks in advance for any and all assistance provided.

    The parameter method given by gpshukla will send the info to the subreport, but you don't need the color parameter in the main report, only the subreport. The trick is in setting the value of that parameter.
    Right-click the cell with the embedded subreport, you can select subreport properties.
    Select Parameters and add a parameter.
    The name column is the name of the parameter in the subreport (color) and value is the value to set it to.
    Set name to "color" (no quotes).
    Set Value to the same expression used to set the background color for the row.
    In the subreport, click the design surface to select the report (not header or footer).
    In the properties pane, select background color and choose expression from the dropdown.
    Type =Parameters!color.Value into the expression builder.
    This will work assuming that background color in the main report row will not change without also refreshing the subreport.
    "You will find a fortune, though it will not be the one you seek." -
    Blind Seer, O Brother Where Art Thou
    Please Mark posts as answers or helpful so that others may find the fortune they seek.

  • How to set selected text color in Spark TextInput

    I'm trying to make Spark TextInputs and MXFTETextInputs look like Halo/MX TextInputs as much as possible, since I have a mix of both Spark and MX TextInputs in my application. I know I can set the
    selection background color to black using focusedTextSelectionColor. How can I set the selected text color to white so it matches the MX white-on-black look?

    This works, if you set the enabled property directly on the s:TextInput:
    <?xml version="1.0" encoding="utf-8"?>
    <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
                   xmlns:s="library://ns.adobe.com/flex/spark"
                   xmlns:mx="library://ns.adobe.com/flex/mx">
        <s:layout>
            <s:VerticalLayout horizontalAlign="center" verticalAlign="middle" />
        </s:layout>
        <s:controlBarContent>
            <s:CheckBox id="ch" label="enabled" selected="true" />
        </s:controlBarContent>
        <fx:Style>
            @namespace s "library://ns.adobe.com/flex/spark";
            @namespace mx "library://ns.adobe.com/flex/mx";
            s|TextInput:disabled {
                color: red;
        </fx:Style>
        <s:Group>
            <s:TextInput id="ti" text="The quick brown fox jumps over the lazy dog" enabled="{ch.selected}" />
        </s:Group>
    </s:Application>
    It can get a bit trickier when you're setting the enabled property on a parent container, since (I believe) that the child control's enabled properties are still set to true and just the container is disabled. One possible workaround would be to bind the child TextInput control's enabled property to the container's enabled property. That way the s:TextInput should still go to it's disabled state and you can customize the disabled state's styles to have darker text, or whatever else you want.
    <s:Group id="gr" enabled="{ch.selected}">
        <s:TextInput id="ti" text="The quick brown fox jumps over the lazy dog" enabled="{gr.enabled}" />
    </s:Group>
    Peter

  • JPopupMenu-item selection backbround color

    Hi !
    I want to change item selection background color of JPopupMenu from its default color. How can I do this?
    Pawan

    UIManager.put("MenuItem.selectionBackground", new javax.swing.plaf.ColorUIResource(Color.YELLOW));

  • Solid background color... creating

    How do I make a background color for the entire page? I thought I just went to "Fill" (top left) and clicked on it. Then chose my color... and that's that. But... it's creating an area of the color... that doesn't go to the very edge of the web page. What am I doing wrong? Thanks.
    julie

    Hi Julie
    Make sure you are using fill option for browser not page , if you will select page fill then it would show you the same but with browser fill you can select background color for page as well browser area.
    Thanks,
    Sanjit

  • Custom Action to change selected column's Background color for a table in CEWP

    I have a OOTB CEWP. When I insert a table to this, I would like to see a context menu that would give me an option to change the selected cell's/row's/table's properties like cell padding/cell spacing/background color etc.
    How can this be achieved using SP2013 ribbon's custom actions. It would be great if we could add all these properties on a separate contextual tab when row/cell/table is selected.
    Rajasekar A.C

    Hi,
    If the table in Content Editor Web Part, we don’t need to use SharePoint Ribbon to achieve it.
    We can insert some input button and use jQuery to change the table tr/td background color.
    The code like this:
    <style type="text/css">
    .highlight {
    background-color: red;
    </style>
    <script src="http://code.jquery.com/jquery-1.11.1.min.js" type="text/javascript"></script>
    <script type="text/javascript">
    $(function () {
    $("#TableID tr").click(function () {
    $(this).toggleClass("highlight");
    </script>
    Thanks,
    Dennis Guo
    TechNet Community Support
    Please remember to mark the replies as answers if they help and unmark them if they provide no help. If you have feedback for TechNet Subscriber Support, contact
    [email protected]
    Dennis Guo
    TechNet Community Support

  • Changing the background color of the row of the selected cell in table view

    How can I change the background color of the table row when user clicks on table cell in table view?
    Edited by: a_brar on May 5, 2012 11:12 PM

    You could apply the following css style (by defining a custom stylsheet with the following lines and loading it into your app).
    The last color sets the background color of the selected row while the table-view has focus (in this case to orange).
    .table-view:focused .table-row-cell:filled:focused:selected {
        -fx-background-color: -fx-focus-color, -fx-cell-focus-inner-border, orange;
    }There are quite a lot of subtleties in the css styling for the tableview (e.g. different colors for the selected row when the control has focus vs when it doesn't or when the user hovers over a selected row in an unfocussed tableview), which you may want to cater for when chaning the background color of the selected row in a table view. There is also alternate styling for when the tableview is in row selection vs cell selection mode. So you may want to look at customizing further based on the css styles in caspian.css in sdk/rt/lib/jfxrt.jar if you can understand the complex css there.

  • How to set background color for selected days in DateChooser

    How to set background color for selected days. I created
    checkbox for each day [Son,Mon,Tue,Wed,Thu,Fri,Sat] and a
    DateChooser, I want to change the background color for the selected
    day when i click on a button after selecting the desired checkboxs
    [ monthly wise/yearly wise]
    Thanks in advance

    There is no button involved in the following code, but it may
    be of use to you:
    <?xml version="1.0"?>
    <mx:Application xmlns:mx="
    http://www.adobe.com/2006/mxml"
    creationComplete="init()">
    <mx:Script>
    <![CDATA[
    private var origColor:uint;
    private function init():void {
    origColor = dc.getStyle("selectionColor");
    public function setBackGrdColors(newColor:uint):void {
    dc.setStyle("selectionColor", origColor);
    if(dc.selectedDate){
    var dayOfWeek:Number = dc.selectedDate.day;
    else{
    return;
    switch(dayOfWeek) {
    case 0:
    if(sun.selected)
    dc.setStyle("selectionColor", newColor);
    break;
    case 1:
    if(mon.selected)
    dc.setStyle("selectionColor", newColor);
    break;
    case 2:
    if(tue.selected)
    dc.setStyle("selectionColor", newColor);
    break;
    case 3:
    if(wed.selected)
    dc.setStyle("selectionColor", newColor);
    break;
    case 4:
    if(thu.selected)
    dc.setStyle("selectionColor", newColor);
    break;
    case 5:
    if(fri.selected)
    dc.setStyle("selectionColor", newColor);
    break;
    case 6:
    if(sat.selected)
    dc.setStyle("selectionColor", newColor);
    break;
    default:
    break;
    ]]>
    </mx:Script>
    <mx:VBox horizontalAlign="center" verticalGap="20">
    <mx:DateChooser id="dc" textAlign="left"
    change="setBackGrdColors(cellColor.selectedColor)"/>
    <mx:HBox width="100%" horizontalAlign="center">
    <mx:CheckBox id="sun" label="Sun"/>
    <mx:CheckBox id="mon" label="Mon"/>
    <mx:CheckBox id="tue" label="Tue"/>
    <mx:CheckBox id="wed" label="Wed"/>
    </mx:HBox>
    <mx:HBox width="100%" horizontalAlign="center">
    <mx:CheckBox id="thu" label="Thu"/>
    <mx:CheckBox id="fri" label="Fri"/>
    <mx:CheckBox id="sat" label="Sat"/>
    </mx:HBox>
    <mx:HBox width="300" horizontalAlign="center">
    <mx:Label text="Background Color" />
    <mx:ColorPicker id="cellColor"
    selectedColor="#FF00FF"/>
    </mx:HBox>
    </mx:VBox>
    </mx:Application>

Maybe you are looking for

  • Need to install Snow Leopard--seems complicated.  Can I pay Apple store to do it?

    While I'm mostly a right brain  type (writer), I can still do a lot of semi-geeky on my Mac Book Pro and even recently figured out how to rescue my mother's iMac from the "death screen" by using some keyboard shortcuts after unplugging all her cords.

  • Handling Messages in EOIO as QOS

    Hi All   For <b>EOIO</b> as <b>QOS</b> scenarios ( in case of <b>O/B</b> ), how can we make separate queues for messages that pass through the Integration server and adapter engine based on certain criteria ( sender/receiver etc..) in XI System? We a

  • How to setup Time stamp for CO-PA.

    Hello Friends, I have created CO-PA datasource in KEB0. Defaultly, the delta method has been selected as 'Generic delta'. But, I need time stamp for delta process. Where can I setup time stamp for CO-PA data source? Thanks Sumanth

  • Which is better one

    can any one tell me is it nice develop the portal on oracle instant portal or by customizing the portal.Which is the better one to develop an intranet portal.pls tell me advanatage and disadvantage of oracle instant portal and customizing the portal

  • Multiplexing/Mirroring a datafile

    Is there any way to multiplexing or mirroring a datafile in a database? Explain in detail with an example. DB: Oracle 10g OS: Redhat 5 ASM: No ASM is used