001 /*
002 * Created on Apr 14, 2008
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
005 * in compliance with the License. You may obtain a copy of the License at
006 *
007 * http://www.apache.org/licenses/LICENSE-2.0
008 *
009 * Unless required by applicable law or agreed to in writing, software distributed under the License
010 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
011 * or implied. See the License for the specific language governing permissions and limitations under
012 * the License.
013 *
014 * Copyright @2008-2010 the original author or authors.
015 */
016 package org.fest.swing.driver;
017
018 import static java.lang.String.valueOf;
019 import static org.fest.swing.driver.ModelValueToString.asText;
020
021 import java.awt.*;
022
023 import javax.swing.*;
024
025 import org.fest.swing.annotation.RunsInCurrentThread;
026 import org.fest.swing.cell.JTableCellReader;
027
028 /**
029 * Understands the default implementation of <code>{@link JTableCellReader}</code>.
030 *
031 * @author Yvonne Wang
032 * @author Alex Ruiz
033 */
034 public class BasicJTableCellReader implements JTableCellReader {
035
036 private final CellRendererReader rendererReader;
037 private final BasicJComboBoxCellReader comboBoxCellReader = new BasicJComboBoxCellReader();
038
039 /**
040 * Creates a new </code>{@link BasicJTableCellReader}</code> that uses a
041 * <code>{@link BasicCellRendererReader}</code> to read the value from the cell renderer component in a
042 * <code>JTable</code>.
043 */
044 public BasicJTableCellReader() {
045 this(new BasicCellRendererReader());
046 }
047
048 /**
049 * Creates a new </code>{@link BasicJTableCellReader}</code>.
050 * @param reader knows how to read values from the cell renderer component in a
051 * <code>JTable</code>.
052 * @throws NullPointerException if <code>reader</code> is <code>null</code>.
053 */
054 public BasicJTableCellReader(CellRendererReader reader) {
055 if (reader == null)
056 throw new NullPointerException("CellRendererReader should not be null");
057 this.rendererReader = reader;
058 }
059
060 /**
061 * Returns the internal value of a cell in a <code>{@link JTable}</code> as expected in a test. This method first
062 * tries to return the value displayed in the <code>JTable</code>'s cell renderer.
063 * <ul>
064 * <li>if the renderer is a <code>{@link JLabel}</code>, this method returns its text</li>
065 * <li>if the renderer is a <code>{@link JComboBox}</code>, this method returns the value of its selection as a
066 * <code>String</code></li>
067 * <li>if the renderer is a <code>{@link JCheckBox}</code>, this method returns whether it is selected or not</li>
068 * </ul>
069 * If it fails reading the cell renderer, this method will get the value from the <code>toString</code> implementation
070 * of the object stored in the <code>JTable</code>'s model at the specified indices.
071 * <p>
072 * <b>Note:</b> This method is <b>not</b> guaranteed to be executed in the event dispatch thread (EDT.) Clients are
073 * responsible for calling this method from the EDT.
074 * </p>
075 * @param table the given <code>JTable</code>.
076 * @param row the row index of the cell.
077 * @param column the column index of the cell.
078 * @return the internal value of a cell in a <code>JTable</code> as expected in a test.
079 */
080 @RunsInCurrentThread
081 public String valueAt(JTable table, int row, int column) {
082 Component c = cellRendererIn(table, row, column);
083 String value = (c != null) ? rendererReader.valueFrom(c) : null;
084 if (value != null) return value;
085 if (c instanceof JLabel) return ((JLabel)c).getText();
086 if (c instanceof JCheckBox) return valueOf(((JCheckBox)c).isSelected());
087 if (c instanceof JComboBox) return valueAsText((JComboBox)c);
088 return asText(table.getValueAt(row, column));
089 }
090
091 private String valueAsText(JComboBox comboBox) {
092 int selectedIndex = comboBox.getSelectedIndex();
093 if (selectedIndex == -1) return null;
094 return comboBoxCellReader.valueAt(comboBox, selectedIndex);
095 }
096
097 /**
098 * Returns the font of the cell renderer for the given table cell.
099 * <p>
100 * <b>Note:</b> This method is <b>not</b> guaranteed to be executed in the event dispatch thread (EDT.) Clients are
101 * responsible for calling this method from the EDT.
102 * </p>
103 * @param table the given <code>JTable</code>.
104 * @param row the row index of the cell.
105 * @param column the column index of the cell.
106 * @return the font of the cell renderer for the given table cell.
107 */
108 @RunsInCurrentThread
109 public Font fontAt(JTable table, int row, int column) {
110 Component c = cellRendererIn(table, row, column);
111 return c != null ? c.getFont() : null;
112 }
113
114 /**
115 * Returns the background color of the cell renderer for the given table cell.
116 * <p>
117 * <b>Note:</b> This method is <b>not</b> guaranteed to be executed in the event dispatch thread (EDT.) Clients are
118 * responsible for calling this method from the EDT.
119 * </p>
120 * @param table the given <code>JTable</code>.
121 * @param row the row index of the cell.
122 * @param column the column index of the cell.
123 * @return the background color of the cell renderer for the given table cell.
124 */
125 @RunsInCurrentThread
126 public Color backgroundAt(JTable table, int row, int column) {
127 Component c = cellRendererIn(table, row, column);
128 return c != null ? c.getBackground() : null;
129 }
130
131 /**
132 * Returns the foreground color of the cell renderer for the given table cell.
133 * <p>
134 * <b>Note:</b> This method is <b>not</b> guaranteed to be executed in the event dispatch thread (EDT.) Clients are
135 * responsible for calling this method from the EDT.
136 * </p>
137 * @param table the given <code>JTable</code>.
138 * @param row the row index of the cell.
139 * @param column the column index of the cell.
140 * @return the foreground color of the cell renderer for the given table cell.
141 */
142 @RunsInCurrentThread
143 public Color foregroundAt(JTable table, int row, int column) {
144 Component c = cellRendererIn(table, row, column);
145 return c != null ? c.getForeground() : null;
146 }
147
148 @RunsInCurrentThread
149 private Component cellRendererIn(final JTable table, final int row, final int column) {
150 return table.prepareRenderer(table.getCellRenderer(row, column), row, column);
151 }
152 }