2009-11-20 60 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; 
}