Ofek Ron
Ofek Ron

Reputation: 8580

Having multi-line text on a ListCell using JList and ListCellRenderer

This class instance is returned by my ListCellRenderer:

    public class SessionQALine extends JPanel {
    private JTextArea question;
    private JLabel answer;
    public SessionQALine() {
        setLayout(new BoxLayout(this,BoxLayout.X_AXIS));
        setOpaque(false);
        question = new JTextArea();
        question.setLineWrap(true);
        question.setWrapStyleWord(true);
        question.setFont(new Font(Font.SERIF, Font.ITALIC|Font.BOLD, 14));
        question.setOpaque(false);
        answer = new JLabel();
        answer.setFont(new Font(Font.SERIF, Font.BOLD, 10));
        answer.setOpaque(false);
            add(question);
        add(Box.createHorizontalGlue());
        add(answer);
    }

    public void setQuestion(String q) {
        question.setText(q);
    }
    public void setAnswer(String q) {
        answer.setText(q);
    }
    @Override
    public void paint(Graphics g) {
        super.paint(g);
        g.drawLine(0, getHeight()-1, getWidth(), getHeight()-1);
    }
}

This is part of my ListCellRenderer:

private SessionQALine qaLine = new SessionQALine();
@Override
public Component getListCellRendererComponent(JList list, Object value,
        int index, boolean isSelected, boolean cellHasFocus) {
    qaLine.setQuestion(questions.get(index));
    qaLine.setAnswer(answers.get(index));
    return qaLine;
}

everything works fine when the strings fit in one line, though if it needs more then one line, the second line and on seems not to be taken under consideration, the JList paints the cells and these line just never show, do you know how i can fix that?

Upvotes: 0

Views: 1149

Answers (1)

mKorbel
mKorbel

Reputation: 109813

  • for JList or JTable is easiest to use doLayout(), rather than getPreferredSize from java.swing.text.FieldView

  • most comfortable will be to put JTextArea to the JScrollPane, for quite nicer output to the GUI,

  • notice then have to redirect MouseScrollEvents from parent JScrollPane to the JScrollPane under Mouse Cursor, (five-six code_lines moreover a few times solved here)

  • use Borders or JSeparator instead of drawLine()

do you meaning

import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.text.*;
//http://tips4java.wordpress.com/2008/10/26/text-utilities/
public class AutoWrapTest {

    public JComponent makeUI() {
        String[] columnNames = {" Text Area Cell Renderer "};
        Object[][] data = {
            {"123456789012345678901234567890"},
            {"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddx"},
            {"----------------------------------------------0"},
            {">>>>>>>>>>>>>dddddddddddddddddddddddddddddddddddddddddddddddddd"
                + "dddddddxdddddddddddddddddddddddddddddddddddddddddddddd"
                + "dddddddddddx>>>>>>>>>>>>>>>>>>>>>>>>>|"},
            {">>>>>>>>>>>>ddddddddddddddddddddddddddddddddddddddddddddddddddd"
                + "ddddddx>>>>>>>>>>>>>>>>>>>>>>>>>>|"},
            {"a|"},
            {">>>>>>>>bbbb>>>>>>>>>>>>>>>>>>>|"},
            {">>>>>>>>>>>>>>>>>>|"},
            {">>>>>>>>>>>>>dddddddddddddddddddddddddddddddddddddddddddddddddd"
                + "dddddddxdddddddddddddd123456789012345678901234567890dddddd"
                + "dddddddddddddddddddddddddddddddddddddx>>>>>>>>>>>>>>>>>>>>"
                + ">>>>>|"},
            {">>>>>>>>>>>>>dddddddddddddd123456789012345678901234567890dddddd"
                + "dddddddddddddddddddddddddddddddddddddxdddddddddddddd123456"
                + "789012345678901234567890dddddddddddddddddddddddddddddddddd"
                + "ddddd123456789012345678901234567890ddddx>>>>>>>>>>>>>>>>>>"
                + ">>>>>>>|"},};
        TableModel model = new DefaultTableModel(data, columnNames) {

            private static final long serialVersionUID = 1L;

            @Override
            public boolean isCellEditable(int row, int column) {
                return false;
            }
        };
        JTable table = new JTable(model) {

            private static final long serialVersionUID = 1L;

            @Override
            public void doLayout() {
                TableColumn col = getColumnModel().getColumn(0);
                for (int row = 0; row < getRowCount(); row++) {
                    Component c = prepareRenderer(col.getCellRenderer(), row, 0);
                    if (c instanceof JTextArea) {
                        JTextArea a = (JTextArea) c;
                        int h = getPreferredHeight(a) + getIntercellSpacing().height;
                        if (getRowHeight(row) != h) {
                            setRowHeight(row, h);
                        }
                    }
                }
                super.doLayout();
            }

            private int getPreferredHeight(JTextComponent c) {
                Insets insets = c.getInsets();
                View view = c.getUI().getRootView(c).getView(0);
                int preferredHeight = (int) view.getPreferredSpan(View.Y_AXIS);
                return preferredHeight + insets.top + insets.bottom;
            }
        };
        table.setEnabled(false);
        table.setShowGrid(false);
        table.setTableHeader(null);
        table.getColumnModel().getColumn(0).setCellRenderer(new TextAreaCellRenderer());
        //table.setPreferredScrollableViewportSize(table.getPreferredSize());
        JScrollPane sp = new JScrollPane(table);
        sp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        sp.setPreferredSize(new Dimension(250, 533));
        JPanel p = new JPanel(new BorderLayout());
        p.add(sp);
        return p;
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                createAndShowGUI();
            }
        });
    }

    public static void createAndShowGUI() {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        f.getContentPane().add(new AutoWrapTest().makeUI());
        f.setLocation(100, 100);
        f.pack();
        f.setVisible(true);
    }
}

class TextAreaCellRenderer extends JTextArea implements TableCellRenderer {

    private static final long serialVersionUID = 1L;
    private final Color evenColor = new Color(230, 240, 255);

    public TextAreaCellRenderer() {
        super();
        setLineWrap(true);
        setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
    }

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
        if (isSelected) {
            setForeground(table.getSelectionForeground());
            setBackground(table.getSelectionBackground());
        } else {
            setForeground(table.getForeground());
            setBackground(table.getBackground());
            setBackground((row % 2 == 0) ? evenColor : getBackground());
        }
        setFont(table.getFont());
        setText((value == null) ? "" : value.toString());
        return this;
    }
}

Upvotes: 2

Related Questions