2009-08-08 19 views
5

Compré recientemente el libro Filthy Rich Clients y lo encontré realmente útil y divertido. Sobre la base de un ejemplo del libro intenté implementar un ScrollPane personalizado que muestra una "sombra" en la parte inferior de su vista sobre el componente que se mostrará. Terminé con el código a continuación. Funciona pero no perfectamente. Específicamente, cuando desplazo el panel arrastrando la barra de desplazamiento, todo funciona bien y la pintura es realmente fluida. Pero cuando me desplazo con el mouse, la sombra parpadea y no tengo idea de por qué. ¿Alguien puede ayudarme?Cómo deshabilitar el comportamiento de pintura predeterminado del evento de desplazamiento de rueda en JScrollPane

EDITAR: Lo mismo sucede con cualquier componente en el panel de desplazamiento. Editó el código para mostrar dos cuadros para ver el problema.

EDIT 2: He aislado el problema de la forma en que el panel de desplazamiento maneja el evento de la rueda del mouse. Al desplazarse por el panel de desplazamiento, copia los contenidos del puerto de visualización ligeramente hacia arriba o hacia abajo según la orientación del desplazamiento y luego dibuja la región que aparece. Mi código hace que todo el componente esté "sucio", pero eso es después de que el componente haya cambiado el contenido. Así que, momentáneamente, ve el gradiente de "sombra" fuera de lugar hasta que se emite una nueva pintura. ¿Alguna idea sobre cómo deshabilitar esta funcionalidad?

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

por favor vea mi publicación http://stackoverflow.com/questions/8197261/jtable-how-to-change-background-color, gracias por la gran pregunta +1 – mKorbel

Respuesta

3

¿Ha intentado llamar setWheelScrollingEnabled (falso) en el objeto ScrollPane?

Desde el javadoc:

Activa/desactiva el desplazamiento en respuesta al movimiento de la rueda del ratón. El desplazamiento de rueda está habilitado por por defecto.

Actualiza el siguiente comentario de Savvas a continuación.

Quizás el método "setScrollMode (int)" en la ventana gráfica puede ayudarlo. Este método determinará cómo el desplazamiento se desplaza por la ventana gráfica.

Puede obtener la ventana gráfica directamente desde el ScrollPane con el método getViewPort(). Dispone de las siguientes opciones:

BLIT_SCROLL_MODE 
BACKINGSTORE_SCROLL_MODE 
SIMPLE_SCROLL_MODE 

Según el javadoc BLIT_SCROLL_MODE utilizará Graphics.copyArea así que tal vez probar uno de los otros.

+0

quiero mantener el comportamiento de desplazamiento. Lo que no quiero es mantener la forma en que el panel de desplazamiento se dibuja al deslizar. No está utilizando el método de repintado aparentemente, pero usa el método Graphics.copyArea (x, y, ancho, alto, dx, dy). Después de que se llama el repintado para pintar el área recién introducida y porque he marcado todo el componente como sucio, mi método de pintura entra en acción. Pero después de copyArea entonces hay un flash intermitente –

+0

Thanx. Eso funcionó como un encanto. Tanto JViewport.BACKINGSTORE_SCROLL_MODE como JViewport.SIMPLE_SCROLL_MODE funcionan como yo quiero. –

Cuestiones relacionadas