views:

468

answers:

2

This is my renderer

class tblCalendarRenderer extends JTextArea implements TableCellRenderer {

    JTextArea textField;

    public tblCalendarRenderer() {
        textField = new JTextArea();
    }

    public Component getTableCellRendererComponent(JTable table,
            Object value, boolean selected, boolean focused, int row,
            int column) {
        textField.setText(value == null ? "" : value.toString());
        textField.setLineWrap(true);
        textField.setWrapStyleWord(true);

        if (column == 0 || column == 6) { // Week-end
            textField.setBackground(new Color(255, 220, 220));
        } else { // Week
            textField.setBackground(new Color(255, 255, 255));
        }
        if (row % 2 == 0) {
            if (value != null) {
                if (Integer.parseInt(value.toString()) == realDay
                        && currentMonth == realMonth
                        && currentYear == realYear) { // Today
                    textField.setBackground(new Color(220, 220, 255));
                }
            }
            textField.setFont(new java.awt.Font("Dialog",
                    java.awt.Font.BOLD, 11));
        } else {
            textField.setFont(new java.awt.Font("Dialog",
                    java.awt.Font.BOLD, 12));
        }
        if (selected && row % 2 != 0) {
            textField.setBackground(Color.LIGHT_GRAY);
            textField.setForeground(Color.black);
        }

        textField.setBorder(null);
        return textField;
    }
}

This is the code I tried out to highlight the row in jTextArea. How can i add it into jTable? i tried add textField.addCaretListener(new ExampleCaretListener()); But it will still select whole jTable cell.

    class ExampleCaretListener implements CaretListener {

    public void caretUpdate(CaretEvent e) {
        Color HILIT_COLOR = Color.LIGHT_GRAY;
        final Highlighter.HighlightPainter painter;
        painter = new DefaultHighlighter.DefaultHighlightPainter(
                HILIT_COLOR);
        JTextArea textField = (JTextArea) e.getSource();
        String lineText = "";
        try {
            int dot = e.getDot();
            int rowStart = Utilities.getRowStart(textField, dot);
            int rowEnd = Utilities.getRowEnd(textField, dot);
            System.out.println(dot + " " + rowStart + " " + rowEnd);
            lineText = textField.getText(rowStart, (rowEnd - rowStart));
            textField.getHighlighter().removeAllHighlights();
            textField.getHighlighter().addHighlight(rowStart, rowEnd,
                    painter);
        } catch (BadLocationException ex) {
            System.out.println(ex);
        }

    }

}
A: 

I guess that the content of each cell is date number so I am not sure what are you trying to do or where do you actually have multiple lines in single cell. Did you mean on selecting the table cell instead of entire row? If that is what you meant you could do it by changing the row/column selection models for your table. If this is not the case please narrow down your problem and provide a complete (cleaned) source code.

Edit:

As eugener said, renderer is simply drawing your JTextArea inside the cell as an image based on value for that cell. You can however create your own custom model to represent the state of the cell (instead of just having a single String value you can use for example MyModel which contains String and some additional data) and render cell based on that model. For example: you can detect mouse clicks (attach mouse listener to Jtable) and then change the state of that model - update selection start and selection end based on mouse position for the specific cell value. Inside getCellRenderer cast value to your object type (MyModel) which contains selection start and selection end data and use it to render text area.

Here is the sample code which increases selection as you click on a cell (you should modify it to set proper caret positions based on clicked mouse position), code is dirty (you should clean it up a little) but works:

insert this in your cell renderer:

CellValue myValue = (CellValue)value;
HighlightPainter painter = new DefaultHighlighter.DefaultHighlightPainter(
        Color.green);
textField.getHighlighter().removeAllHighlights();
try {
    textField.getHighlighter().addHighlight(myValue.highlightStart, myValue.highlightEnd, painter);
} catch (BadLocationException e) {
    System.out.println("Miss");
}

And here is the sample MyModel:

public class MyModel extends AbstractTableModel {
    class CellValue {
        String value;
        int highlightStart;
        int highlightEnd;

        CellValue(String val) {
            this.value = val;
        }

        @Override
        public String toString() {
            return value;
        }
    }

    CellValue[][] values = new CellValue[2][7];

    public MyModel() {
        for(int i = 0; i < 2; i++) {
            for(int j=0; j < 7; j++) {
                values[i][j] = new CellValue(i + ":" + j);
            }
        }
    }

    @Override
    public int getColumnCount() {
        return 7;
    }

    @Override
    public int getRowCount() {
        return 2;
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        return values[rowIndex][columnIndex];
    }
}

Here is a Main class:

public class Main {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(new Dimension(500,500));

        final JTable table = new JTable(new MyModel());
        for(int i =0; i < 7; i++) {
            table.getColumnModel().getColumn(i).setCellRenderer(new tblCalendarRenderer());
        }

        table.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                int row = table.rowAtPoint(e.getPoint());
                int column = table.columnAtPoint(e.getPoint());

                Object obj = table.getValueAt(row, column);
                System.out.println("value " + obj);
                CellValue cellValue = (CellValue)obj;
                cellValue.highlightEnd++;
                table.repaint();
            }
        });
        table.setRowHeight(50);
        JScrollPane scp = new JScrollPane(table);
        frame.add(scp);
        frame.setVisible(true);
    }
}
draganstankovic
each table cell consider one date so if one date incude multiple event, i want the user can select each event in order to edit them.
Hi i tried using your code but I got this error, java.lang.Integer cannot be cast to ui.EventFrame$MyModel$CellValue.
you should check the instance of value before casting it to CellValue. You have the line: "if (Integer.parseInt(value.toString()) == realDay" in renderer. Please remove it in order to test the code and when all works you should get the idea of how to use to solve your problem.(please, don't forget the line: final JTable table = new JTable(new MyModel()); )
draganstankovic
A: 

The renderer is simply drawing your JTextArea inside the cell as an image. So highlighting the text is not going to work. The only thing which may work IMO is using JEditorPane for your renderer with text styling to highlight appropriate part of it.

Read more at http://java.sun.com/docs/books/tutorial/uiswing/components/editorpane.html#recap

eugener