2009-08-08 31 views
5

Gần đây tôi đã mua sách Filthy Rich Clients và tôi thấy nó thực sự hữu ích và thú vị. Xây dựng trên một ví dụ từ cuốn sách tôi đã thử triển khai một ScrollPane tùy chỉnh hiển thị một "bóng tối" ở dưới cùng của chế độ xem của nó trên thành phần sẽ được hiển thị. Tôi đã kết thúc với mã dưới đây. Nó hoạt động nhưng không hoàn hảo. Cụ thể khi tôi di chuyển khung bằng cách kéo thanh cuộn, mọi thứ hoạt động tốt và bức tranh thực sự mượt mà. Nhưng khi tôi di chuyển bằng chuột di chuyển các bóng mờ và tôi không có ý tưởng tại sao. Ai giúp tôi với?Cách tắt hành vi sơn mặc định của sự kiện cuộn bánh xe trên JScrollPane

CHỈNH SỬA: Điều tương tự cũng xảy ra với bất kỳ thành phần nào trong ngăn cuộn. Đã chỉnh sửa mã để hiển thị hai khung hình để xem sự cố.

EDIT 2: Tôi đã tách biệt vấn đề với cách khung cuộn xử lý sự kiện bánh xe chuột. Khi cuộn ô cuộn, sao chép nội dung của cổng xem hơi lên hoặc xuống tùy thuộc vào hướng cuộn và sau đó vẽ vùng được xem. Mã của tôi làm cho toàn bộ thành phần "bẩn" nhưng đó là sau khi thành phần đã chuyển nội dung. Vì vậy, trong giây lát bạn nhìn thấy "bóng" gradient ra khỏi vị trí cho đến khi một repaint được ban hành. Bất kỳ ý tưởng nào về cách tắt chức năng này?

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

vui lòng xem bài đăng của tôi http://stackoverflow.com/questions/8197261/jtable-how-to-change-background-color, cảm ơn câu hỏi tuyệt vời +1 – mKorbel

Trả lời

3

Bạn đã thử gọi setWheelScrollingEnabled (false) trên đối tượng ScrollPane chưa?

Từ javadoc:

Cho phép/vô hiệu hóa di chuyển trong đáp ứng với chuyển động của chuột bánh xe. Tính năng cuộn bánh xe được bật theo mặc định .

Cập nhật sau nhận xét của Savvas bên dưới.

Có lẽ phương thức "setScrollMode (int)" trên chế độ xem có thể giúp bạn. Phương pháp này sẽ xác định cách xoay cuộn chế độ xem.

Bạn có thể lấy khung nhìn trực tiếp từ ScrollPane bằng phương thức getViewPort(). Bạn có các tùy chọn sau:

BLIT_SCROLL_MODE 
BACKINGSTORE_SCROLL_MODE 
SIMPLE_SCROLL_MODE 

Theo javadoc BLIT_SCROLL_MODE sẽ sử dụng Graphics.copyArea vì vậy có lẽ thử một trong những người khác.

+0

tôi muốn giữ hành vi cuộn. Những gì tôi không muốn là giữ cho cách cửa sổ cuộn tự vẽ khi cuộn. Nó không sử dụng phương pháp repaint rõ ràng nhưng sử dụng phương thức Graphics.copyArea (x, y, width, height, dx, dy). Sau đó repaint được gọi là sơn khu vực mới được giới thiệu và bởi vì tôi đã đánh dấu toàn bộ thành phần là bẩn, phương pháp sơn của tôi đá. Nhưng sau khi copyArea để có nhấp nháy –

+0

Thanx. Tiếng Anh> Tiếng Việt. Cả JViewport.BACKINGSTORE_SCROLL_MODE và JViewport.SIMPLE_SCROLL_MODE đều hoạt động như tôi muốn. –

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