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 }