2011-11-19 173 views
8

我通过MeBigFatGuy有趣question启发,在这个连接如我有非常具体的问题有关Graphisc2D,如何改变BackGround Color的依赖,如果是在JViewPortJTables Row可见,JTable中如何更改背景颜色

1)如果1st. & last JTables Row会在JViewPort是可见的,那么背景将会是彩色的Color.red

2)如果1st. & last JTables Row不会在JViewPort是可见的,那么BackGround将着色到Color.whatever

enter image description here

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

哇,非常漂亮的代码+1。 –

+0

哇,确实不错! +100。 –

+0

也许我不明白这个问题。如果您只希望第一行/最后一行是不同的颜色,那么只需使用您在我的博客中看到的“Table Row Renderering”方法即可。只有在视口中可见时才会进行渲染。 – camickr

回答

5

,因为我寻找不同的建议,我关闭了这个问题我原来的知识有关图形

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

基于代码

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

改变颜色到霓虹灯的颜色 – mKorbel

+1

不错的工作我喜欢:) – mprabhat

+0

好的工作伙伴,谢谢。 – 2014-05-20 07:56:07

2

事情是这样的......一个黑客攻击的一位。

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

编辑修正了代码,所以当第一行和最后一行在视图端口颜色是红色时,他们不是颜色是蓝色。

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

+0

+1代码,但我搜索dymanic更改,如果第一和最后一行在JViewPort中可见然后(例如)Color.red,如果不可见,则Color.red可以更改为不同的颜色 – mKorbel

+0

I一起砍了一些我认为会起作用的新代码。 – Dimitry

+0

嗯,不,这个图像是从第二。更新,看起来像扩展JTable http://stackoverflow.com/questions/6051755/java-wait-cursor-display-problem/6060678#6060678将是最简单的JScrollPane :-) – mKorbel