Reputation: 427
I am trying to insert a value in a JTable. But I come across some issues(Design). When I tried to add a value normally word/Line wrapping is not working, so I tried inserting the value embedded with HTML tag
<html>Value</html>
but the issue with this is there occurs some extra space on top(the first line comes exactly middle). So I tried with adding JTextpane to the JTable using renderer but it only makes horizontal center and not vertical center(Word/Line wrapping is working correctly).
In short my needs are
I need the value to be displayed exactly in middle of cell(Horizontally and vertically centered)
class TableCellLongTextRenderer extends JTextPane implements TableCellRenderer {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
this.setText((String) value);
StyledDocument doc = this.getStyledDocument();
SimpleAttributeSet center = new SimpleAttributeSet();
StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER);
StyleConstants.setSpaceAbove(center, StyleConstants.getSpaceBelow(center) / 2);
StyleConstants.setSpaceBelow(center, StyleConstants.getSpaceAbove(center));
doc.setParagraphAttributes(0, doc.getLength(), center, false);
return this;
}}
What is wrong in my code can someone help me to rectify it? Thanks in advance.
Upvotes: 0
Views: 1947
Reputation: 347244
You can just use plain HTML
and the default TableCellRenderer
, which is based on a JLabel
to achieve this basic principles.
The following example uses a html
table
, which further aligns the text (broken of lines) to the center of the label. It uses the horizontalAlignment
and verticalAlignment
properties of the JLabel
to get the contents aligned within the label.
It also does a little trickery with the row height ;)
import java.awt.Component;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableModel;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
String text
= "<html><div align=center>"
+ "And Caesar's spirit, raging for revenge,<br>"
+ "With Ate by his side come hot from hell,<br>"
+ "Shall in these confines with a monarch's voice<br>"
+ "Cry \"Havoc!\" and let slip the dogs of war,<br>"
+ "That this foul deed shall smell above the earth<br>"
+ "With carrion men, groaning for burial.";
DefaultTableModel model = new DefaultTableModel(0, 1);
model.addRow(new String[]{text});
JTable table = new JTable(model) {
@Override
public int getRowHeight(int row) {
Component comp = prepareRenderer(getCellRenderer(row, 0), row, 0);
return comp.getPreferredSize().height;
}
};
((JLabel)table.getDefaultRenderer(Object.class)).setHorizontalAlignment(JLabel.CENTER);
((JLabel)table.getDefaultRenderer(Object.class)).setVerticalAlignment(JLabel.CENTER);
table.setRowHeight(100);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JScrollPane(table));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
Now, I pre-wrapped my text and applied it to the model. You could create a custom TableCellRenderer
(using a DefaultTableCellRenderer
) and post-wrap the text, depending on your needs
Upvotes: 4