The simplest way to do this (on small forms) that I have found is by taking advantage of the #prefix and #suffix elements in the render array. Here's an example:
$form['foo_fieldset'] = array(
'#type' => 'fieldset',
'#prefix' => '<table>',
'#suffix' => '</table>',
'#tree' => TRUE,
);
$form['foo_fieldset']['header'] = array(
'#markup' => '<thead>
<tr>
<th>A checkbox</th>
<th>A text input</th>
<th>A text input</th>
</tr>
</thead>',
);
for ($i=0;$i<10;$i++) {
$form['foo_fieldset']['row_' . $i] = array(
'#prefix' => '<tr>',
'#suffix' => '</tr>',
);
$form['foo_fieldset']['row_' . $i]['checkbox'] = array(
'#type' => 'checkbox',
'#prefix' => '<td>',
'#suffix' => '</td>',
);
$form['foo_fieldset']['row_' . $i]['text_1'] = array(
'#type' => 'textfield',
'#prefix' => '<td>',
'#suffix' => '</td>',
);
$form['foo_fieldset']['row_' . $i]['text_2'] = array(
'#type' => 'textfield',
'#prefix' => '<td>',
'#suffix' => '</td>',
);
}
The other way to do it (maybe known as the "right" way) involves building a theming function to render your form in a table. Take a look at this page (ignoring the tablesort options as you don't care about that) to see how it's done: http://coffeeshopped.com/2010/09/drupal-drag-and-drop-tables-in-custom-modules