JTable how to change BackGround Color
Asked Answered
S

2

9

I inspired by MeBigFatGuy interesting question, in this conection I have very specific question about Graphisc2D, how to change BackGround Color by depends if is JTables Row visible in the JViewPort,

1) if 1st. & last JTables Row will be visible in the JViewPort, then BackGround would be colored to the Color.red

2) if 1st. & last JTables Row will not be visible in the JViewPort, then BackGround would be colored to the Color.whatever

enter image description here

from SSCCE

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.RepaintManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.table.TableModel;

/*
https://stackoverflow.com/questions/1249278/
how-to-disable-the-default-painting-behaviour-of-wheel-scroll-event-on-jscrollpan
 *
and
 *
https://stackoverflow.com/questions/8195959/
swing-jtable-event-when-row-is-visible-or-when-scrolled-to-the-bottom
 */
public class ViewPortFlickering {

    private JFrame frame = new JFrame("Table");
    private JViewport viewport = new JViewport();
    private Rectangle RECT = new Rectangle();
    private Rectangle RECT1 = new Rectangle();
    private JTable table = new JTable(50, 3);
    private javax.swing.Timer timer;
    private int count = 0;

    public ViewPortFlickering() {
        GradientViewPort tableViewPort = new GradientViewPort(table);
        viewport = tableViewPort.getViewport();
        viewport.addChangeListener(new ChangeListener() {

            @Override
            public void stateChanged(ChangeEvent e) {
                RECT = table.getCellRect(0, 0, true);
                RECT1 = table.getCellRect(table.getRowCount() - 1, 0, true);
                Rectangle viewRect = viewport.getViewRect();
                if (viewRect.intersects(RECT)) {
                    System.out.println("Visible RECT -> " + RECT);
                } else if (viewRect.intersects(RECT1)) {
                    System.out.println("Visible RECT1 -> " + RECT1);
                } else {
                    //
                }
            }
        });
        frame.add(tableViewPort);
        frame.setPreferredSize(new Dimension(600, 300));
        frame.pack();
        frame.setLocation(50, 100);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        RepaintManager.setCurrentManager(new RepaintManager() {

            @Override
            public void addDirtyRegion(JComponent c, int x, int y, int w, int h) {
                Container con = c.getParent();
                while (con instanceof JComponent) {
                    if (!con.isVisible()) {
                        return;
                    }
                    if (con instanceof GradientViewPort) {
                        c = (JComponent) con;
                        x = 0;
                        y = 0;
                        w = con.getWidth();
                        h = con.getHeight();
                    }
                    con = con.getParent();
                }
                super.addDirtyRegion(c, x, y, w, h);
            }
        });
        frame.setVisible(true);
        start();
    }

    private void start() {
        timer = new javax.swing.Timer(100, updateCol());
        timer.start();
    }

    public Action updateCol() {
        return new AbstractAction("text load action") {

            private static final long serialVersionUID = 1L;

            @Override
            public void actionPerformed(ActionEvent e) {

                System.out.println("updating row " + (count + 1));
                TableModel model = table.getModel();
                int cols = model.getColumnCount();
                int row = 0;
                for (int j = 0; j < cols; j++) {
                    row = count;
                    table.changeSelection(row, 0, false, false);
                    timer.setDelay(100);
                    Object value = "row " + (count + 1) + " item " + (j + 1);
                    model.setValueAt(value, count, j);
                }
                count++;
                if (count >= table.getRowCount()) {
                    timer.stop();
                    table.changeSelection(0, 0, false, false);
                    java.awt.EventQueue.invokeLater(new Runnable() {

                        @Override
                        public void run() {
                            table.clearSelection();
                        }
                    });
                }
            }
        };
    }

    public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                ViewPortFlickering viewPortFlickering = new ViewPortFlickering();
            }
        });
    }
}

class GradientViewPort extends JScrollPane {

    private static final long serialVersionUID = 1L;
    private final int h = 50;
    private BufferedImage img = null;
    private BufferedImage shadow = new BufferedImage(1, h, BufferedImage.TYPE_INT_ARGB);
    private JViewport viewPort;

    public GradientViewPort(JComponent com) {
        super(com);
        viewPort = this.getViewport();
        viewPort.setScrollMode(JViewport.BLIT_SCROLL_MODE);
        viewPort.setScrollMode(JViewport.BACKINGSTORE_SCROLL_MODE);
        viewPort.setScrollMode(JViewport.SIMPLE_SCROLL_MODE);
        Graphics2D g2 = shadow.createGraphics();
        g2.setPaint(new Color(250, 150, 150));
        g2.fillRect(0, 0, 1, h);
        g2.setComposite(AlphaComposite.DstIn);
        g2.setPaint(new GradientPaint(0, 0, new Color(0, 0, 0, 0f), 0, h,
                new Color(0.5f, 0.8f, 0.8f, 0.5f)));
        g2.fillRect(0, 0, 1, h);
        g2.dispose();
    }

    @Override
    public void paint(Graphics g) {
        if (img == null || img.getWidth() != getWidth() || img.getHeight() != getHeight()) {
            img = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
        }
        Graphics2D g2 = img.createGraphics();
        super.paint(g2);
        Rectangle bounds = getViewport().getVisibleRect();
        g2.scale(bounds.getWidth(), -1);
        int y = (getColumnHeader() == null) ? 0 : getColumnHeader().getHeight();
        g2.drawImage(shadow, bounds.x, -bounds.y - y - h, null);
        g2.scale(1, -1);
        g2.drawImage(shadow, bounds.x, bounds.y + bounds.height - h + y, null);
        g2.dispose();
        g.drawImage(img, 0, 0, null);
    }
}
Sorrows answered 19/11, 2011 at 20:55 Comment(4)
Maybe I don't understand the question. If you only want the first/last rows to be a different color, then just use the "Table Row Renderering" approach you've seen from my blog. They will only be renderered when they are visible in the viewport.Evangelicalism
@Evangelicalism I'm not able to change GradientPaint (simple way) to the another Color, depends of that if some JTable's Row is/isn't visible in the JViewPortSorrows
RECT ? please learn java naming conventions and stick to them ;-)Kelson
curious: why? a) overriding paint b) custom repaintManager?Kelson
S
6

since I search for different suggestion I closed this question with my original knowledges about Graphics

enter image description here enter image description here enter image description here

based on code

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
//import java.awt.image.ColorModel; // I don't know how to use that
//import java.awt.image.SampleModel;// I don't know how to use that
import javax.swing.*;
import javax.swing.RepaintManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.table.TableModel;

public class ViewPortFlickeringOriginal {

    private JFrame frame = new JFrame("Table");
    private JViewport viewport = new JViewport();
    private Rectangle RECT = new Rectangle();
    private Rectangle RECT1 = new Rectangle();
    private JTable table = new JTable(50, 3);
    private javax.swing.Timer timer;
    private int count = 0;
    private boolean topOrBottom = false;
    private GradientViewPortOriginal tableViewPort;

    public ViewPortFlickeringOriginal() {
        tableViewPort = new GradientViewPortOriginal(table);
        viewport = tableViewPort.getViewport();
        viewport.addChangeListener(new ChangeListener() {

            @Override
            public void stateChanged(ChangeEvent e) {
                if (tableViewPort.bolStart) {
                    RECT = table.getCellRect(0, 0, true);
                    RECT1 = table.getCellRect(table.getRowCount() - 1, 0, true);
                    Rectangle viewRect = viewport.getViewRect();
                    if (viewRect.intersects(RECT)) {
                        System.out.println("Visible RECT -> " + RECT);
                        tableViewPort.paintBackGround(new Color(250, 150, 150));
                    } else if (viewRect.intersects(RECT1)) {
                        System.out.println("Visible RECT1 -> " + RECT1);
                        tableViewPort.paintBackGround(new Color(150, 250, 150));
                    } else {
                        System.out.println("Visible RECT1 -> ???? ");
                        tableViewPort.paintBackGround(new Color(150, 150, 250));
                    }
                }
            }
        });
        frame.add(tableViewPort);
        frame.setPreferredSize(new Dimension(600, 300));
        frame.pack();
        frame.setLocation(50, 100);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        RepaintManager.setCurrentManager(new RepaintManager() {

            @Override
            public void addDirtyRegion(JComponent c, int x, int y, int w, int h) {
                Container con = c.getParent();
                while (con instanceof JComponent) {
                    if (!con.isVisible()) {
                        return;
                    }
                    if (con instanceof GradientViewPortOriginal) {
                        c = (JComponent) con;
                        x = 0;
                        y = 0;
                        w = con.getWidth();
                        h = con.getHeight();
                    }
                    con = con.getParent();
                }
                super.addDirtyRegion(c, x, y, w, h);
            }
        });
        frame.setVisible(true);
        start();
    }

    private void start() {
        timer = new javax.swing.Timer(100, updateCol());
        timer.start();
    }

    public Action updateCol() {
        return new AbstractAction("text load action") {

            private static final long serialVersionUID = 1L;

            @Override
            public void actionPerformed(ActionEvent e) {

                System.out.println("updating row " + (count + 1));
                TableModel model = table.getModel();
                int cols = model.getColumnCount();
                int row = 0;
                for (int j = 0; j < cols; j++) {
                    row = count;
                    table.changeSelection(row, 0, false, false);
                    timer.setDelay(100);
                    Object value = "row " + (count + 1) + " item " + (j + 1);
                    model.setValueAt(value, count, j);
                }
                count++;
                if (count >= table.getRowCount()) {
                    timer.stop();
                    table.changeSelection(0, 0, false, false);
                    java.awt.EventQueue.invokeLater(new Runnable() {

                        @Override
                        public void run() {
                            table.clearSelection();
                            tableViewPort.bolStart = true;
                        }
                    });
                }
            }
        };
    }

    public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                ViewPortFlickeringOriginal viewPortFlickering = new ViewPortFlickeringOriginal();
            }
        });
    }
}

class GradientViewPortOriginal extends JScrollPane {

    private static final long serialVersionUID = 1L;
    private final int h = 50;
    private BufferedImage img = null;
    private BufferedImage shadow = new BufferedImage(1, h, BufferedImage.TYPE_INT_ARGB);
    private JViewport viewPort;
    public boolean bolStart = false;

    public GradientViewPortOriginal(JComponent com) {
        super(com);
        viewPort = this.getViewport();
        viewPort.setScrollMode(JViewport.BLIT_SCROLL_MODE);
        viewPort.setScrollMode(JViewport.BACKINGSTORE_SCROLL_MODE);
        viewPort.setScrollMode(JViewport.SIMPLE_SCROLL_MODE);
        paintBackGround(new Color(250, 150, 150));
    }

    public void paintBackGround(Color g) {
        Graphics2D g2 = shadow.createGraphics();
        g2.setPaint(g);
        g2.fillRect(0, 0, 1, h);
        g2.setComposite(AlphaComposite.DstIn);
        g2.setPaint(new GradientPaint(0, 0, new Color(0, 0, 0, 0f), 0, h,
                new Color(0.1f, 0.8f, 0.8f, 0.5f)));
        g2.fillRect(0, 0, 1, h);
        g2.dispose();
    }

    @Override
    public void paint(Graphics g) {
        if (img == null || img.getWidth() != getWidth() || img.getHeight() != getHeight()) {
            img = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
        }
        Graphics2D g2 = img.createGraphics();
        super.paint(g2);
        Rectangle bounds = getViewport().getVisibleRect();
        g2.scale(bounds.getWidth(), -1);
        int y = (getColumnHeader() == null) ? 0 : getColumnHeader().getHeight();
        g2.drawImage(shadow, bounds.x, -bounds.y - y - h, null);
        g2.scale(1, -1);
        g2.drawImage(shadow, bounds.x, bounds.y + bounds.height - h + y, null);
        g2.dispose();
        g.drawImage(img, 0, 0, null);
    }
}
Sorrows answered 23/11, 2011 at 21:31 Comment(1)
changed Colors to the Neon's based colorsSorrows
M
2

Something like this... a bit of a hack.

class GradientViewPort extends JScrollPane {

    private static final long serialVersionUID = 1L;
    private final int h = 50;
    private BufferedImage img = null;
    private BufferedImage imgBottom = null;
    private BufferedImage shadow = new BufferedImage(1, h,
            BufferedImage.TYPE_INT_ARGB);
    private BufferedImage shadowBottom = new BufferedImage(1, h,
            BufferedImage.TYPE_INT_ARGB);
    private JViewport viewPort;

    public GradientViewPort(JComponent com) {
        super(com);
        viewPort = this.getViewport();
        viewPort.setScrollMode(JViewport.BLIT_SCROLL_MODE);
        viewPort.setScrollMode(JViewport.BACKINGSTORE_SCROLL_MODE);
        viewPort.setScrollMode(JViewport.SIMPLE_SCROLL_MODE);
        createShadow(new Color(250, 150, 150),shadow);
        createShadow(Color.BLUE,shadowBottom);

    }

    private void createShadow(Color color, BufferedImage shadow) {
        Graphics2D g2 = shadow.createGraphics();
        g2.setPaint(color);
        g2.fillRect(0, 0, 1, h);
        g2.setComposite(AlphaComposite.DstIn);
        g2.setPaint(new GradientPaint(0, 0, new Color(0, 0, 0, 0f), 0, h,
                new Color(0.5f, 0.8f, 0.8f, 0.5f)));
        g2.fillRect(0, 0, 1, h);
        g2.dispose();
    }

    @Override
    public void paint(Graphics g) {
        paintTop(g,img);
        paintBottom(g,imgBottom);
    }

    private void paintBottom(Graphics g,BufferedImage img) {
        if (img == null || img.getWidth() != getWidth()
                || img.getHeight() != getHeight()) {
            img = new BufferedImage(getWidth(), getHeight(),
                    BufferedImage.TYPE_INT_ARGB);
        }
        Graphics2D g2 = img.createGraphics();
        //super.paint(g2);
        Rectangle bounds = getViewport().getVisibleRect();
        g2.scale(bounds.getWidth(), -1);
        int y = (getColumnHeader() == null) ? 0 : getColumnHeader().getHeight();
        //g2.drawImage(shadowBottom, bounds.x, -bounds.y - y - h, null);
        g2.scale(1, -1);
        g2.drawImage(shadowBottom, bounds.x, bounds.y + bounds.height - h + y, null);
        g2.dispose();
        g.drawImage(img, 0, 0, null);
    }

    private void paintTop(Graphics g,BufferedImage img) {
        if (img == null || img.getWidth() != getWidth()
                || img.getHeight() != getHeight()) {
            img = new BufferedImage(getWidth(), getHeight(),
                    BufferedImage.TYPE_INT_ARGB);
        }
        Graphics2D g2 = img.createGraphics();
        super.paint(g2);
        Rectangle bounds = getViewport().getVisibleRect();
        g2.scale(bounds.getWidth(), -1);
        int y = (getColumnHeader() == null) ? 0 : getColumnHeader().getHeight();
        g2.drawImage(shadow, bounds.x, -bounds.y - y - h, null);
        g2.scale(1, -1);
        //g2.drawImage(shadow, bounds.x, bounds.y + bounds.height - h + y, null);
        g2.dispose();
        g.drawImage(img, 0, 0, null);
    }

EDIT fixed the code so when first and last row are in the view port the color is red when they are not the color is blue.

    class GradientViewPort extends JScrollPane {

    private static final long serialVersionUID = 1L;
    private final int h = 50;
    private BufferedImage imgRed = null;
    private BufferedImage imgBlue = null;
    private BufferedImage shadowRed = new BufferedImage(1, h,
            BufferedImage.TYPE_INT_ARGB);
    private BufferedImage shadowBlue = new BufferedImage(1, h,
            BufferedImage.TYPE_INT_ARGB);
    private JViewport viewPort;
    private boolean recVisible = true;

    public GradientViewPort(JComponent com) {
        super(com);
        viewPort = this.getViewport();
        viewPort.setScrollMode(JViewport.BLIT_SCROLL_MODE);
        viewPort.setScrollMode(JViewport.BACKINGSTORE_SCROLL_MODE);
        viewPort.setScrollMode(JViewport.SIMPLE_SCROLL_MODE);
        createShadow(new Color(250, 150, 150),shadowRed);
        createShadow(Color.BLUE,shadowBlue);

        final JTable table = (JTable) com;
        viewport.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                Rectangle RECT = table.getCellRect(0, 0, true);

                Rectangle viewRect = viewport.getViewRect();
                if (viewRect.intersects(RECT)) {
                    System.out.println("Visible RECT -> " + RECT);
                    recVisible = true;

                } else {
                    recVisible = false;
                }
            }
        });

    }

    private void createShadow(Color color, BufferedImage shadow) {
        Graphics2D g2 = shadow.createGraphics();
        g2.setPaint(color);
        g2.fillRect(0, 0, 1, h);
        g2.setComposite(AlphaComposite.DstIn);
        g2.setPaint(new GradientPaint(0, 0, new Color(0, 0, 0, 0f), 0, h,
                new Color(0.5f, 0.8f, 0.8f, 0.5f)));
        g2.fillRect(0, 0, 1, h);
        g2.dispose();
    }

    @Override
    public void paint(Graphics g) {
        if(recVisible){
        paintShadow(g,imgRed,shadowRed);
        } else {
        paintShadow(g,imgBlue,shadowBlue);
        }
    }

    private void paintShadow(Graphics g,BufferedImage img, BufferedImage shadow) {
        if (img == null || img.getWidth() != getWidth()
                || img.getHeight() != getHeight()) {
            img = new BufferedImage(getWidth(), getHeight(),
                    BufferedImage.TYPE_INT_ARGB);
        }
        Graphics2D g2 = img.createGraphics();
        super.paint(g2);
        Rectangle bounds = getViewport().getVisibleRect();
        g2.scale(bounds.getWidth(), -1);
        int y = (getColumnHeader() == null) ? 0 : getColumnHeader().getHeight();
        g2.drawImage(shadow, bounds.x, -bounds.y - y - h, null);
        g2.scale(1, -1);
        g2.drawImage(shadow, bounds.x, bounds.y + bounds.height - h + y, null);
        g2.dispose();
        g.drawImage(img, 0, 0, null);
    }
}

enter image description here

Moxley answered 20/11, 2011 at 0:2 Comment(5)
+1 for code, but I search for dymanic changes, if 1st & last Row is visible in the JViewPort then (e.g.) Color.red, if isn't in visible then Color.red could be changed to the different colorSorrows
hmmmm not, this image was from 2nd. update, looks like as extends JTable #6052255 would be easiest as JScrollPane :-)Sorrows
Hmm. I just ran it again and looks like what you are asking for. Please check to make sure you are running the right code.Moxley
yes I'm sure, because these methods never listening ChangeEventsSorrows
Take a look at the construtor of GradientViewPort in the 2nd version.Moxley

© 2022 - 2024 — McMap. All rights reserved.