2011-11-19 85 views
8

Tôi lấy cảm hứng từ MeBigFatGuy thú question, trong conection này tôi có câu hỏi rất cụ thể về Graphisc2D, làm thế nào để thay đổi BackGround Color bởi phụ thuộc nếu là JTables Row nhìn thấy trong JViewPort,JTable làm thế nào để thay đổi màu nền

1) nếu 1st. & last JTables Row sẽ được hiển thị trong JViewPort, sau đó nền sẽ được tô màu để các Color.red

2) nếu 1st. & last JTables Row sẽ không được hiển thị trong JViewPort, sau đó BackGround sẽ được tô màu để các Color.whatever

enter image description here

từ 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

wow, mã rất hay +1. –

+0

Chà, thật tuyệt! +100. –

+0

Có lẽ tôi không hiểu câu hỏi. Nếu bạn chỉ muốn các hàng đầu tiên/cuối cùng là một màu khác nhau, thì chỉ cần sử dụng cách tiếp cận "Bảng hàng Renderering" mà bạn đã nhìn thấy từ blog của tôi. Chúng sẽ chỉ được hiển thị khi chúng hiển thị trong khung nhìn. – camickr

Trả lời

5

kể từ khi tôi tìm kiếm gợi ý khác nhau Tôi nhắm câu hỏi này với kiến ​​thức ban đầu của tôi về Graphics

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

dựa trên mã

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

đã thay đổi Màu sắc thành màu sắc của Neon – mKorbel

+1

công việc đẹp mắt Tôi thích nó :) – mprabhat

+0

Bạn thân làm việc tốt, cảm ơn. –

2

Something như thế này ... một chút của một 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 cố định mã để khi hàng đầu tiên và cuối cùng nằm trong cổng xem màu đỏ khi không có màu xanh lam.

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 cho mã, nhưng tôi tìm kiếm thay đổi dymanic, nếu 1st & last Row có thể nhìn thấy trong JViewPort thì (ví dụ) Color.red, nếu không nhìn thấy được thì Color.red có thể được đổi thành màu khác – mKorbel

+0

I đã tấn công một số mã mới mà tôi nghĩ sẽ hoạt động. – Dimitry

+0

hmmmm không, hình ảnh này là từ thứ 2. cập nhật, có vẻ như mở rộng JTable http://stackoverflow.com/questions/6051755/java-wait-cursor-display-problem/6060678#6060678 sẽ dễ nhất là JScrollPane :-) – mKorbel

Các vấn đề liên quan