gengencera
gengencera

Reputation: 426

Set margin and custom border of a specific row for a JTable

How can I set the margin of a specific row in a JTable by its row number?

Please refer to the illustration below I made using excel.

enter image description here


Also, I want a thick border and an invisible border

Upvotes: 1

Views: 1588

Answers (2)

prasad_
prasad_

Reputation: 14317

This is an example of a JTable with custom row borders - for specific rows. These specific rows are determined by the data in the table rows.

The example uses a JTable with a custom renderer - CustomBorderRenderer class which extends javax.swing.table.DefaultTableCellRenderer. There are two classes in this example application: TableCellRendererTester.java and CustomBorderRenderer.java.

The following is the image of the table with custom border for a specific row - where the Year value is "2012". The source code for the two classes follow.

enter image description here


The Example Code:

import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

public class TableCellRendererTester {

    private static final Object[] TABLE_COLUMNS = {"Book", "Author", "Year"};
    private static final Object [][] TABLE_DATA = {
        {"Book 1", "author 1", "1972"}, {"Book 2", "author 1", "1945"},
        {"Book 3", "author 2", "2012"}, {"Book 4", "author 3", "1999"}
    };

    public static void main(String [] args) {
        new TableCellRendererTester().createAndShowGUI();
    }

    public void createAndShowGUI() {
        JFrame frame = new JFrame("Table Custom Row Border Tester");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(getTablePanel());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private JPanel getTablePanel() {
        DefaultTableModel model = new DefaultTableModel(TABLE_DATA, TABLE_COLUMNS);
        JTable table = new JTable(model);
        table.setRowHeight(30);
        CustomBorderRenderer renderer = new CustomBorderRenderer();
        table.setDefaultRenderer(Object.class, renderer);
        JScrollPane scrollpane = new JScrollPane(table);
        scrollpane.setPreferredSize(new Dimension(400, 150));
        scrollpane.setViewportView(table);
        JPanel panel = new JPanel();
        panel.add(scrollpane);
        return panel;
    }
}


The Renderer Class:

import java.awt.Color;
import java.awt.Component;
import javax.swing.JTable;
import javax.swing.JComponent;
import javax.swing.BorderFactory;
import javax.swing.border.Border;
import javax.swing.table.TableModel;
import javax.swing.table.DefaultTableCellRenderer;

public class CustomBorderRenderer extends DefaultTableCellRenderer {

    private int prevRow;
    private boolean customBorderFlag;

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value,
            boolean isSelected, boolean hasFocus, int row, int column) {

        JComponent c = (JComponent) super.getTableCellRendererComponent(table,
                value, isSelected, hasFocus, row, column);

        if (row != prevRow) {
            // Row has changed.
            // Store it so that all the columns can be rendered 
            // with the custom border - if condition is met.
            customBorderFlag = false;
            prevRow = row;
            TableModel m = table.getModel();
            String s = (String) m.getValueAt(row, 2);
            // Check if the row needs to be rendered with a custom border.
            if (s.equals("2012")) {
                customBorderFlag = true;
            }
        }

        if (customBorderFlag) {
            // Set custom border for all column cells - for a row.
            c.setBorder(getCustomBorder());
        }

        return c;
    }

    /*
     * Returns a custom border with:
     * 1. Thick border
     * 2. A margin between cell content (text) and the border.
     */
    private Border getCustomBorder() {
            Border insideMargin = BorderFactory.createEmptyBorder(10, 10, 10, 10);
            Border thickBorder = BorderFactory.createLineBorder(Color.BLACK, 3);
            Border borderWithMargin = 
                BorderFactory.createCompoundBorder(thickBorder, insideMargin);

            return borderWithMargin;
    }
}


EDIT: Updated the image and the CustomBorderRenderer.java class to show the custom border with margin.

Upvotes: 1

camickr
camickr

Reputation: 324207

JTable has a method setRowHeight(...) which will allow you to increase the height of specific rows.

Regarding the border you can check out Table Row Rendering. It demonstrates how to override the prepareRenderer(...) method of the JTable to use a custom Border.

Upvotes: 1

Related Questions