2010-07-03 59 views
1

這是我的渲染後的JTable細胞setDefaultRenderer到JTextArea中如何突出所選行中的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(新的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); 
     } 

    } 

} 

回答

0

我想,每一個單元格的內容是日期數,所以我不知道什麼是你想幹什麼或者你在哪裏實際上有單細胞多行。 你的意思是選擇表格單元而不是整行? 如果這就是你的意思,你可以通過更改表格的行/列選擇模型來完成。 如果情況並非如此,請縮小您的問題範圍,並提供完整的(已清理的)源代碼。

編輯:

正如eugener說,渲染器簡單地繪製你的JTextArea細胞作爲基於該單元格值的圖像中。但是,您可以創建自己的自定義模型來表示單元格的狀態(而不是僅包含可用於包含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); 
    } 
} 
+0

每個表格單元的考慮,所以如果一個日期incude多個事件,我希望用戶能夠以編輯選擇的每個事件一個日期。 – user236501 2010-07-04 03:07:05

+0

嗨,我試着用你的代碼,但我得到了這個錯誤,java.lang.Integer不能轉換爲ui.EventFrame $ MyModel $ CellValue。 – user236501 2010-07-04 12:17:53

+0

您應該在將其轉換爲CellValue之前檢查值的實例。你在渲染器中有這樣一行:「if(Integer.parseInt(value.toString())== realDay」。請刪除它以測試代碼,並且在所有工作中你應該知道如何使用它來解決你的問題問題。 (請不要忘記這行:最終的JTable表=新的JTable(new MyModel());) – draganstankovic 2010-07-05 06:07:03