akshaivk
akshaivk

Reputation: 427

Vertical and Horizontal Allignment in JTextPane

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

  1. I need to enter a value in JTable.
  2. I need to Word/Line Wrap if it exceeds the column width.
  3. 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

Answers (1)

MadProgrammer
MadProgrammer

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 ;)

Table with html

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

Related Questions