2009-08-08 3 views
5

Недавно я приобрел книгу Filthy Rich Clients, и я нашел ее очень полезной и забавной. Основываясь на одном примере из книги, я попытался реализовать пользовательскую ScrollPane, которая отображает «тень» в нижней части своего представления над компонентом, который будет отображаться. Я закончил с кодом ниже. Он работает, но не идеально. В частности, когда я просматриваю панель, перетаскивая полосу прокрутки, все работает нормально, и картина действительно гладкая. Но когда я прокручиваю прокрутку мыши, тень мерцает, и я понятия не имею, почему. Может кто-нибудь мне помочь?Как отключить поведение рисования колес по умолчанию на JScrollPane

EDIT: То же самое происходит для любого компонента в панели прокрутки. Отредактировал код для отображения двух кадров, чтобы увидеть проблему.

EDIT 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

ответ

3

Вы пытались дозвониться setWheelScrollingEnabled (ложь) на объекте ScrollPane?

Из Javadoc:

Включает/отключает прокрутку в ответ на перемещение мыши колеса. Прокрутка колеса включена по умолчанию .

Обновление, следующее за комментарием Savvas.

Возможно, метод setScrollMode (int) в окне просмотра может вам помочь. Этот метод определит, как свинг прокручивает область просмотра.

Вы можете получить окно просмотра непосредственно из ScrollPane с помощью метода getViewPort(). У вас есть следующие варианты:

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). После этого перерисовывается, чтобы нарисовать недавно введенную область и потому, что я отметил весь компонент как грязный, мой метод краски срабатывает. Но после copyArea так происходит мигание –

+0

Thanx. Это работало как шарм. И JViewport.BACKINGSTORE_SCROLL_MODE, и JViewport.SIMPLE_SCROLL_MODE работают так, как я хочу. –

Смежные вопросы