2009-08-08 38 views
5

我最近購買了書Filthy Rich Clients,我發現它非常有用和有趣。基於本書的一個例子,我嘗試實現一個自定義的ScrollPane,在其視圖底部顯示一個「影子」,以顯示要顯示的組件。我結束了下面的代碼。它的工作原理並不完美。具體來說,當我通過拖動滾動條滾動窗格時,一切正常,繪畫非常平滑。但是,當我滾動鼠標滾動陰影閃爍,我不知道爲什麼。誰能幫我?如何在JScrollPane上禁用滾輪滾動事件的默認繪製行爲

編輯:同樣的事情發生在滾動窗格中的任何組件。編輯代碼以顯示兩幀來查看問題。

編輯2:我已經將問題隔離爲滾動窗格處理鼠標滾輪事件的方式。當滾動滾動窗格時,根據滾動的方向稍微向上或向下複製視圖端口的內容,然後繪製進入視圖的區域。我的代碼使整個組件「髒」,但是在組件轉移了內容之後。所以暫時你會看到「陰影」漸變,直到發出重繪。關於如何禁用此功能的任何想法?

import java.awt.AlphaComposite; 
import java.awt.Color; 
import java.awt.Container; 
import java.awt.GradientPaint; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Rectangle; 
import java.awt.image.BufferedImage; 

import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.JTextArea; 
import javax.swing.RepaintManager; 

public class Test { 

    public static void main(String[] args) { 
     JFrame f = new JFrame("Table"); 
     JFrame f1 = new JFrame("Text Area"); 
     Object[] names = new Object[] { "Title", "Artist", "Album" }; 
     String[][] data = new String[][] { 
       { "Los Angeles", "Sugarcult", "Lights Out" }, 
       { "Do It Alone", "Sugarcult", "Lights Out" }, 
       { "Made a Mistake", "Sugarcult", "Lights Out" }, 
       { "Kiss You Better", "Maximo Park", "A Certain Trigger" }, 
       { "All Over the Shop", "Maximo Park", "A Certain Trigger" }, 
       { "Los Angeles", "Sugarcult", "Lights Out" }, 
       { "Do It Alone", "Sugarcult", "Lights Out" }, 
       { "Made a Mistake", "Sugarcult", "Lights Out" }, 
       { "Kiss You Better", "Maximo Park", "A Certain Trigger" }, 
       { "All Over the Shop", "Maximo Park", "A Certain Trigger" }, 
       { "Los Angeles", "Sugarcult", "Lights Out" }, 
       { "Do It Alone", "Sugarcult", "Lights Out" }, 
       { "Made a Mistake", "Sugarcult", "Lights Out" }, 
       { "Kiss You Better", "Maximo Park", "A Certain Trigger" }, 
       { "All Over the Shop", "Maximo Park", "A Certain Trigger" }, 
       { "Los Angeles", "Sugarcult", "Lights Out" }, 
       { "Do It Alone", "Sugarcult", "Lights Out" }, 
       { "Made a Mistake", "Sugarcult", "Lights Out" }, 
       { "Kiss You Better", "Maximo Park", "A Certain Trigger" }, 
       { "All Over the Shop", "Maximo Park", "A Certain Trigger" }, 
       { "Los Angeles", "Sugarcult", "Lights Out" }, 
       { "Do It Alone", "Sugarcult", "Lights Out" }, 
       { "Made a Mistake", "Sugarcult", "Lights Out" }, 
       { "Kiss You Better", "Maximo Park", "A Certain Trigger" }, 
       { "All Over the Shop", "Maximo Park", "A Certain Trigger" }, 
       { "Going Missing", "Maximo Park", "A Certain Trigger" } }; 
     JTable table = new JTable(data, names); 
     f.getContentPane().add(new ShadowScrollPane(table)); 
     f1.getContentPane().add(new ShadowScrollPane(new JTextArea(20, 50))); 
     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 ShadowScrollPane) { 
         c = (JComponent)con; 
         x = 0; 
         y = 0; 
         w = con.getWidth(); 
         h = con.getHeight(); 
        } 
        con = con.getParent(); 
       } 
       super.addDirtyRegion(c, x, y, w, h); 
      } 
     }); 
     f.pack(); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.setVisible(true); 
     f1.pack(); 
     f1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f1.setVisible(true); 
    } 

} 

@SuppressWarnings("serial") 
class ShadowScrollPane extends JScrollPane { 

    private final int h = 50; 
    private BufferedImage img = null; 
    private BufferedImage shadow = new BufferedImage(1, h, BufferedImage.TYPE_INT_ARGB); 

    public ShadowScrollPane(JComponent com) { 
     super(com); 
     Graphics2D g2 = shadow.createGraphics(); 
     g2.setPaint(new Color(50, 50, 50)); 
     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(1, 1, 1, 0.6f))); 
     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); 
    } 
} 
+0

請看我的帖子http://stackoverflow.com/questions/8197261/jtable-how-to-change-background-color,謝謝你的好問題+1 – mKorbel 2011-11-19 21:05:52

回答

3

你有沒有打過電話setWheelScrollingEnabled(假)將ScrollPane對象?

根據JavaDoc:

啓用/禁用在 響應鼠標 滾輪滾動的移動。輪盤滾動默認爲 。

更新下面的評論Savvas下面。

也許視口上的「setScrollMode(int)」方法可以幫助你。這個方法將決定如何擺動視口。

您可以使用getViewPort()方法直接從ScrollPane獲取視口。 您有以下選擇:

BLIT_SCROLL_MODE 
BACKINGSTORE_SCROLL_MODE 
SIMPLE_SCROLL_MODE 

根據javadoc的BLIT_SCROLL_MODE將使用Graphics.copyArea所以也許嘗試其他的一個。

+0

我想保持滾動的行爲。我不想要的是在滾動時保持滾動窗格的自我繪製方式。它顯然不使用repaint方法,而是使用Graphics.copyArea(x,y,width,height,dx,dy)方法。之後,調用repaint來繪製新引入的區域,並且因爲我已將整個組件標記爲髒,我的繪畫方法會踢入。但是在copyArea之後,存在閃爍的 – 2009-08-08 20:46:10

+0

Thanx。這就像一個魅力。 JViewport.BACKINGSTORE_SCROLL_MODE和JViewport.SIMPLE_SCROLL_MODE都像我想要的那樣工作。 – 2009-08-08 21:38:05

相關問題