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);
}
}
por favor vea mi publicación http://stackoverflow.com/questions/8197261/jtable-how-to-change-background-color, gracias por la gran pregunta +1 – mKorbel