2009-11-20 63 views
1

我有一個Jtable,我想通過向該行添加邊框來突出顯示一行。我擴大了DefaultTableCellRenderer,我認爲這項工作需要在getTableCellRendererComponent方法中完成。如何將邊框添加到Jtable中的某一行?

我猜測,因爲似乎沒有一行的概念,我需要爲行中的單個單元格創建自定義邊框。類似於第一個單元格的左側,頂部和底部,所有內部單元格的頂部和底部以及該行中最後一個單元格的頂部,底部和右側。我在發現如何去實際執行思考過程時遇到問題。我不知道如何使用setBorder()方法,或者如果這是我需要採取的方向。

回答

2

您有正確的想法,您需要根據表格中的位置(即邊緣,中心等)設置cellrenderer標籤上的邊框。

看看matteborder。您可以指定沿w /寬度和顏色繪製邊框的區域。

+0

+1,但我走:) – 2009-11-20 20:14:43

+0

謝謝,我指出了正確的方向票。我將用更完整的答案編輯我的問題以供將來參考。 – 2009-11-21 00:06:02

8

我不會爲此創建自定義渲染器。是的,如果你所有的數據都是同一類型的,那麼它就可以工作。但是當你開始混合Strings,日期和整數以及所有使用不同渲染器的布爾值時會發生什麼?然後,您需要創建4個自定義渲染器。

更好的方法是覆蓋prepareRenderer(...)方法JTable,以便您可以將代碼添加到一個位置。這是一個讓你開始的例子。實際上,您希望使用一個包含頂部/底部的MatteBorder和包含左側/右側的EmptyBorder的CompoundBorder,並且您將創建邊界的單個實例。

import java.awt.*; 
import java.util.*; 
import javax.swing.*; 
import javax.swing.table.*; 
import javax.swing.text.*; 
import javax.swing.border.*; 

public class TablePrepareRenderer extends JFrame 
{ 
    JTable table; 

    public TablePrepareRenderer() 
    { 
     Object[] columnNames = {"Type", "Company", "Shares", "Price", "Boolean"}; 
     Object[][] data = 
     { 
      {"Buy", "IBM", new Double(1000), new Double(80.5), Boolean.TRUE}, 
      {"Sell", "MicroSoft", new Double(2000), new Double(6.25), Boolean.TRUE}, 
      {"RSell", "Apple", new Double(3000), new Double(7.35), Boolean.TRUE}, 
      {"Buy", "Nortel", new Double(4000), new Double(20), Boolean.TRUE} 
     }; 

     DefaultTableModel model = new DefaultTableModel(data, columnNames); 
     table = new JTable(model) 
     { 
      // Returning the Class of each column will allow different 
      // renderers to be used based on Class 

      public Class getColumnClass(int column) 
      { 
       return getValueAt(0, column).getClass(); 
      } 

      public Component prepareRenderer(
       TableCellRenderer renderer, int row, int column) 
      { 
       Component c = super.prepareRenderer(renderer, row, column); 
       JComponent jc = (JComponent)c; 

       // Color row based on a cell value 
       // Alternate row color 

       if (!isRowSelected(row)) 
        c.setBackground(row % 2 == 0 ? getBackground() : Color.LIGHT_GRAY); 
       else 
        jc.setBorder(new MatteBorder(1, 0, 1, 0, Color.RED)); 


       // Use bold font on selected row 

       return c; 
      } 
     }; 

     table.setPreferredScrollableViewportSize(table.getPreferredSize()); 
     table.changeSelection(0, 0, false, false); 
     JScrollPane scrollPane = new JScrollPane(table); 
     getContentPane().add(scrollPane); 
    } 

    public static void main(String[] args) 
    { 
     TablePrepareRenderer frame = new TablePrepareRenderer(); 
     frame.setDefaultCloseOperation(EXIT_ON_CLOSE); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 
} 
+0

我已經有了一些其他需求的自定義cellrenderer,但不同的數據類型不會導致任何問題。 – 2009-11-21 00:05:00

+1

沒關係。這種方法不關心你使用的是什麼單元格渲染器。這是解決方案的關鍵。它將運行默認渲染器或您的自定義渲染器。 – camickr 2009-11-21 00:54:53

+1

順便說一句,如果你有一個渲染器,在一個渲染器中呈現Date,Integers,String和Booleans,那是一個糟糕的設計。 – camickr 2009-11-21 02:43:53

0

我>同意camickr 去最好的辦法是重寫prepareRendere方法。下面的代碼將創建一個邊界與所選單元格的行:

@Override 
public Component prepareRenderer(TableCellRenderer renderer, int row, int column) { 

Component c = super.prepareRenderer(renderer, row, column);  
JComponent jc = (JComponent)c; 

if (isRowSelected(row)){ 
    int top = (row > 0 && isRowSelected(row-1))?1:2; 
    int left = column == 0?2:0; 
    int bottom = (row < getRowCount()-1 && isRowSelected(row + 1))?1:2; 
    int right = column == getColumnCount()-1?2:0; 

    jc.setBorder(BorderFactory.createMatteBorder(top, left, bottom, right, this.getSelectionBackground())); 
} 
else 
    jc.setBorder(null); 

return c; 
}