I have a JTable in which the final column displays a custom cell renderer (a JButton). Is it possible to reduce the width of the JButton within it's column so that it is only large enough to display it's text? I would rather not reduce the size of the column itself unless that is the only solution. Methods which I have tried and have failed were to:
Code for the custom renderer can be seen below:
import java.awt.Component;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;
public class ButtonColumnRenderer extends JButton implements TableCellRenderer {
public ButtonColumnRenderer(){
// this.setBorder(BorderFactory.createEmptyBorder(50, 50, 50, 50));
// this.setPreferredSize(new Dimension(10,10));
// this.setMargin(new Insets(20,20,20,20));
}
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column){
return this;
}
}
The custom render component can be used as follows:
import javax.swing.*;
import javax.swing.table.*;
public static void main(String[] args){
//setup data + column headers
String[] columns = {"Text Column", "Button Column"};
Object[][] data = new Object[3][2];
for(int i = 0; i < 3; i++){
Object[] rowOfData = {"text" + i, "button" + i};
data[i] = rowOfData;
}
//Setup table
DefaultTableModel model = new DefaultTableModel(data, columns);
JTable table = new JTable(model);
TableColumn column = table.getColumnModel().getColumn(table.getModel().getColumnCount() - 1);
column.setCellRenderer(new ButtonColumnRenderer(table.getModel().getRowCount()));
//Display table on frame
JFrame frame = new JFrame();
frame.add(table);
frame.pack();
frame.setVisible(true);
}
UPDATE: I have managed to reduce the size of component using a matteborder
the same color as the background, however the issue with this is that there is no 'one size fits all' for the border (i.e. the component still stretches with the Table it is within). Any help setting a constant size for the render component would be much appreciated.
IIUC, your problem is that the button fills up the column. Because of the resize mode you are using is giving the column more space, when the table is resized - your button gets more space to fill.
If you use a container (in this case, a JComponent
), you may treat the problem as a "standard" layout problem, without dealing with renderers nor tables:
public class ButtonColumnRenderer extends JComponent implements TableCellRenderer {
private final JButton button;
public ButtonColumnRenderer(){
setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
button = new JButton();
add(Box.createHorizontalGlue());
add(button);
add(Box.createHorizontalGlue());
}
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column){
button.setText(String.valueOf(value));
return this;
}
}
My choice here was to use a BoxLayout
. Feel free to use you favorite substance.