[英]After JTable cell setDefaultRenderer to jTextArea how to highlight the selected row in jTextArea
這是我的渲染器
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);
}
}
}
我猜每個單元格的內容都是日期編號,所以我不確定您要做什么或單個單元格中實際有多行。 您是要選擇表格單元格而不是整個行嗎? 如果那是您的意思,則可以通過更改表的行/列選擇模型來實現。 如果不是這種情況,請縮小您的問題范圍,並提供完整的(干凈的)源代碼。
編輯:
正如eugener所說,渲染器只是基於該單元格的值將您的JTextArea繪制為該單元格內的圖像。 但是,您可以創建自己的自定義模型來表示單元格的狀態(而不是僅使用單個String值,例如,可以使用包含String和一些其他數據的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];
}
}
這是一個主類:
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);
}
}
渲染器只是將單元格內的JTextArea繪制為圖像。 因此,突出顯示文本是行不通的。 IMO唯一可行的方法是將JEditorPane用於具有文本樣式的渲染器,以突出顯示其中的適當部分。
在http://java.sun.com/docs/books/tutorial/uiswing/components/editorpane.html#recap中閱讀更多內容。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.