Domanda

Recentemente ho acquistato il libro client Filthy Rich e ho trovato davvero utile e divertente. Sulla un esempio dal libro ho provato attuazione ScrollPane personalizzato che visualizza una "ombra" sul fondo della sua vista sul componente da visualizzare. Ho finito con il codice qui sotto. Funziona, ma non perfettamente. In particolare quando ho scorrere il pannello trascinando la barra di scorrimento tutto funziona ok e la pittura è davvero liscia. Ma quando ho scorrere con la rotellina del mouse lampeggia l'ombra e non ho idea del perché. Qualcuno mi può aiutare?

EDIT: Stessa cosa succede per qualsiasi componente nel pannello di scorrimento. A cura il codice per visualizzare due fotogrammi di vedere il problema.

EDIT 2: ho isolato il problema al modo in cui il riquadro di scorrimento gestisce l'evento rotellina del mouse. Durante lo scorrimento delle copie riquadro di scorrimento del contenuto del porto vista leggermente verso l'alto o verso il basso a seconda dell'orientamento del rotolo e quindi richiama la regione che entra in vista. Il mio codice rende l'intero componente "sporco", ma che è dopo che il componente si è spostato il contenuto. Quindi, momentaneamente si vede il gradiente "ombra" fuori luogo fino a quando viene emesso un ridisegno. Tutte le idee su come disattivare questa funzionalità?

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);
    }
}
È stato utile?

Soluzione

Hai provato a chiamare setWheelScrollingEnabled (false) sull'oggetto ScrollPane?

Dal javadoc:

  

Abilita / disabilita lo scorrimento in   risposta al movimento del mouse   ruota. rotella di scorrimento è abilitata per   di default.

Aggiornamento a seguito del commento di Savvas di seguito.

Forse il "setScrollMode (int)" metodo sul viewport può aiutare. Questo metodo determinare come scorre a battente della finestra.

È possibile ottenere la finestra direttamente dal ScrollPane con il metodo getViewPort (). Sono disponibili le seguenti opzioni:

BLIT_SCROLL_MODE
BACKINGSTORE_SCROLL_MODE
SIMPLE_SCROLL_MODE

Secondo il BLIT_SCROLL_MODE javadoc utilizzerà Graphics.copyArea quindi forse provare uno degli altri.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top