JTable单元格setDefaultRenderer到jTextArea后如何突出显示jTextArea中的选定行

发布于 2024-09-08 05:44:11 字数 2699 浏览 7 评论 0原文

这是我的渲染器

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

这是我尝试突出显示 jTextArea 中的行的代码。我怎样才能将它添加到jTable中?我尝试添加 textField.addCaretListener(new ExampleCaretListener());但它仍然会选择整个 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);
        }

    }

}

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

    }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

拥醉 2024-09-15 05:44:11

我猜想每个单元格的内容都是日期数字,所以我不确定您要做什么,或者单个单元格中实际上有多行。
您的意思是选择表格单元格而不是整行吗?
如果这就是您的意思,您可以通过更改表的行/列选择模型来实现。
如果不是这种情况,请缩小您的问题范围并提供完整的(经过清理的)源代码。

编辑:

正如 eugener 所说,渲染器只是根据该单元格的值将您的 JTextArea 在单元格内绘制为图像。但是,您可以创建自己的自定义模型来表示单元格的状态(您可以使用例如包含字符串和一些附加数据的 MyModel,而不是仅使用单个字符串值)并基于该模型渲染单元格。例如:您可以检测鼠标单击(将鼠标侦听器附加到 Jtable),然后更改该模型的状态 - 根据特定单元格值的鼠标位置更新选择开始和选择结束。在 getCellRenderer 内部将值转换为包含选择开始和选择结束数据的对象类型 (MyModel),并使用它来渲染文本区域。

这是示例代码,当您单击单元格时会增加选择(您应该修改它以根据单击的鼠标位置设置正确的插入符位置),代码很脏(您应该稍微清理一下)但可以工作:

将其插入到您的单元格渲染器:

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

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

这是一个 Main 类:

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

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);
    }
}
满天都是小星星 2024-09-15 05:44:11

渲染器只是将单元格内的 JTextArea 绘制为图像。所以突出显示文本是行不通的。 IMO 唯一可行的方法是使用 JEditorPane 为渲染器使用文本样式来突出显示其中的适当部分。

欲了解更多信息,请访问 http://java.sun.com /docs/books/tutorial/uiswing/components/editorpane.html#recap

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文