简体   繁体   English

在JTable单元格将setDefaultRenderer设置为jTextArea之后,如何突出显示jTextArea中的所选行

[英]After JTable cell setDefaultRenderer to jTextArea how to highlight the selected row in jTextArea

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. 这是我尝试突出显示jTextArea中的行的代码。 How can i add it into jTable? 如何将其添加到jTable中? i tried add textField.addCaretListener(new ExampleCaretListener()); 我尝试添加textField.addCaretListener(new ExampleCaretListener()); But it will still select whole jTable cell. 但是它将仍然选择整个jTable单元。

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

    }

}

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. 正如eugener所说,渲染器只是基于该单元格的值将您的JTextArea绘制为该单元格内的图像。 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. 但是,您可以创建自己的自定义模型来表示单元格的状态(而不是仅使用单个String值,例如,可以使用包含String和一些其他数据的MyModel)并基于该模型渲染单元格。 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. 例如:您可以检测到鼠标单击(将鼠标侦听器附加到Jtable),然后更改该模型的状态-根据特定单元格值的鼠标位置更新选择开始和选择结束。 Inside getCellRenderer cast value to your object type (MyModel) which contains selection start and selection end data and use it to render text area. 在getCellRenderer内部,将值强制转换为对象类型(MyModel),该对象类型包含选择开始和选择结束数据,并使用它来呈现文本区域。

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: 这是示例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);
    }
}

The renderer is simply drawing your JTextArea inside the cell as an image. 渲染器只是将单元格内的JTextArea绘制为图像。 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. IMO唯一可行的方法是将JEditorPane用于具有文本样式的渲染器,以突出显示其中的适当部分。

Read more at http://java.sun.com/docs/books/tutorial/uiswing/components/editorpane.html#recap http://java.sun.com/docs/books/tutorial/uiswing/components/editorpane.html#recap中阅读更多内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM