2009-08-08 4 views
5

최근에 책 Filthy Rich Clients을 구입했으며 정말 유용하고 재미있었습니다. 이 책에서 한 예제를 기반으로 표시 할 구성 요소 위에 뷰의 아래쪽에 "그림자"를 표시하는 사용자 정의 ScrollPane 구현을 시도했습니다. 나는 아래의 코드로 끝났다. 그것은 효과가 있지만 완벽하지는 않습니다. 특히 스크롤 막대를 드래그하여 창을 스크롤하면 모든 것이 정상적으로 작동하고 그림은 정말 매끄 럽습니다. 그러나 마우스 스크롤을 사용하여 스크롤 할 때 그림자가 깜박이고 그 이유를 알 수 없습니다. 누구든지 나를 도울 수 있습니까?JScrollPane에서 휠 스크롤 이벤트의 기본 페인팅 동작을 비활성화하는 방법

편집 : 스크롤 창에있는 구성 요소와 동일한 문제가 발생합니다. 문제를보기 위해 두 개의 프레임을 표시하도록 코드를 편집했습니다.

편집 2 : 스크롤 휠이 마우스 휠 이벤트를 처리하는 방식으로 문제가 발생했습니다. 스크롤 창을 스크롤하면 스크롤 방향에 따라보기 포트의 내용이 약간 위나 아래로 복사 된 다음 볼 수있는 영역이 그려집니다. 내 코드는 전체 구성 요소를 "더티 (dirty)"로 만들지 만, 구성 요소가 내용을 이동시킨 이후입니다. 이렇게 순간에 당신은 repaint가 발행 될 때까지 제자리에서 "그림자"그라데이션을 보게됩니다. 이 기능을 사용 중지하는 방법에 대한 아이디어가 있습니까?

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

답변

3

는 당신이 ScrollPane 구성 객체 (false)를 setWheelScrollingEnabled로 부르심 봤어? javadoc 내에서

:

는/마우스 휠의 움직임에 응답 해 스크롤을 유효 또는 무효로 수 있습니다. 휠 스크롤은 기본값에 의해 활성화됩니다.

아래 Savvas의 의견에 따라 업데이트.

아마도 뷰포트의 "setScrollMode (int)"메서드가 도움이 될 수 있습니다. 이 메서드는 스윙이 뷰포트를 스크롤하는 방법을 결정합니다.

getViewPort() 메소드를 사용하여 ScrollPane에서 직접 뷰포트를 가져올 수 있습니다. 다음과 같은 옵션이 있습니다 BLIT_SCROLL_MODE 그래서 아마 다른 사람의 일을하려고 Graphics.copyArea 호출을 사용하는 javadoc에 따르면

BLIT_SCROLL_MODE 
BACKINGSTORE_SCROLL_MODE 
SIMPLE_SCROLL_MODE 

합니다.

+0

저는 스크롤 동작을 유지하고 싶습니다. 내가 원하지 않는 것은 스크롤 할 때 스크롤 패널이 스스로 그려주는 방식을 유지하는 것입니다. 그것은 분명히 repaint 메서드를 사용하고 있지 않지만 Graphics.copyArea (x, y, width, height, dx, dy) 메서드를 사용합니다. 그 후 페인트가 새롭게 도입 된 영역을 페인트하기 위해 호출되고, 전체 컴포넌트를 더티로 표시했기 때문에 내 페인트 메소드가 실행됩니다. 그러나 복사 영역 이후에는 깜박임 –

+0

고맙습니다. 그것은 매력처럼 작용했습니다. JViewport.BACKINGSTORE_SCROLL_MODE와 JViewport.SIMPLE_SCROLL_MODE는 모두 내가 원하는 것처럼 작동합니다. –

관련 문제