简体   繁体   English

如何在Jtable中的行中添加边框?

[英]How do you add a border to a row in a Jtable?

I have a Jtable and I want to highlight a row by adding a border to the row. 我有一个Jtable,我想通过在行中添加边框来突出显示一行。 I have extended a DefaultTableCellRenderer and I figure the work needs to be done in the getTableCellRendererComponent method. 我扩展了一个DefaultTableCellRenderer ,我认为需要在getTableCellRendererComponent方法中完成工作。

I'm guessing that since there doesn't seem to be a concept of a row that I need to create a custom border for the individual cells in the row. 我猜测,因为似乎没有一行的概念,我需要为行中的单个单元格创建自定义边框。 Something like a left side, top, and bottom for the first cell, a top and bottom for all the inner cells, and a top, bottom, and right side for the last cell in the row. 类似于第一个单元格的左侧,顶部和底部,所有内部单元格的顶部和底部,以及行中最后一个单元格的顶部,底部和右侧。 I'm having problems finding out how to go about actually executing the thought process. 我在查找如何实际执行思考过程时遇到了问题。 I'm not sure how to use the setBorder() method or if that's even the direction I need to take. 我不知道如何使用setBorder()方法,或者甚至是我需要采取的方向。

I would not create a custom renderer for this. 我不会为此创建自定义渲染器。 Yes it will work if all your data is of the same type. 是的,如果您的所有数据属于同一类型,它将起作用。 But what happens when you start to mix Strings, with Dates and Integers and Booleans which all use different renderers? 但是当你开始混合使用字符串,日期和整数以及布尔都使用不同的渲染器时会发生什么? Then you would need to create 4 custom renderers. 然后,您需要创建4个自定义渲染器。

The better approach is to override the prepareRenderer(...) method JTable so you can add the code in one place. 更好的方法是覆盖prepareRenderer(...)方法JTable,以便您可以在一个地方添加代码。 Here is an example to get you started. 这是一个让你入门的例子。 In reality you would want to use a CompoundBorder that contains a MatteBorder for the top/bottom and and EmptyBorder for the left/right and you would create a single instance of the Border. 实际上,您可能希望使用包含顶部/底部的MatteBorder和左/右的EmptyBorder的CompoundBorder,您将创建一个Border的单个实例。

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

You have the correct idea in mind, you will need to set the border on the label in the cellrenderer depending on where it is in the table(ie edge, center etc). 您有正确的想法,您需要在cellrenderer中的标签上设置边框,具体取决于它在表格中的位置(即边缘,中心等)。

Take a look at matteborder . 看看matteborder You can specify which areas to draw a border along w/ width and color. 您可以指定沿宽度和颜色绘制边框的区域。

I agree with > camickr the best way to go is to override the prepareRendere method. 我同意> camickr最好的方法是覆盖prepareRendere方法。 The following code will create a border for a row with a selected cell: 以下代码将为具有所选单元格的行创建边框:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM