2009-08-08 1 views
5

Ich kaufte vor kurzem das Buch Filthy Rich Clients und ich fand es wirklich nützlich und macht Spaß. Aufbauend auf einem Beispiel aus dem Buch habe ich versucht, ein benutzerdefiniertes ScrollPane zu implementieren, das am unteren Rand seiner Ansicht einen "Schatten" über die anzuzeigende Komponente anzeigt. Ich habe den folgenden Code erhalten. Es funktioniert aber nicht perfekt. Insbesondere, wenn ich den Fensterbereich durch Ziehen der Bildlaufleiste scrolle, funktioniert alles einwandfrei und das Bild ist wirklich glatt. Aber wenn ich mit der Maus blättern scrolle flackert der Schatten und ich habe keine Ahnung warum. Kann mir jemand helfen?So deaktivieren Sie das Standard-Malverhalten des Rad Scroll-Ereignisses auf JScrollPane

BEARBEITEN: Gleiches passiert für jede Komponente im Bildlauffenster. Bearbeitete den Code, um zwei Frames anzuzeigen, um das Problem zu sehen.

BEARBEITEN 2: Ich habe das Problem auf die Art und Weise isoliert, wie der Bildlaufbereich das Mausrad-Ereignis behandelt. Beim Scrollen kopiert der Bildlaufbereich den Inhalt des Ansichts-Ports abhängig von der Ausrichtung des Bildlaufs leicht nach oben oder unten und zeichnet dann den Bereich, der angezeigt wird. Mein Code macht die gesamte Komponente "schmutzig", aber das ist, nachdem die Komponente den Inhalt verschoben hat. Momentan siehst du den "Schatten" -Gradienten fehl am Platz, bis ein Repaint ausgegeben wird. Irgendwelche Ideen, wie man diese Funktionalität deaktiviert?

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

siehe meinen Beitrag http://Stackoverflow.com/questions/8197261/jtable-how-to-change-background-color, vielen Dank für die große Frage +1 – mKorbel

Antwort

3

Haben Sie versucht, calling setWheelScrollingEnabled (false) auf dem ScrollPane-Objekt?

Vom Javadoc-:

Ein-/Ausschalten in Reaktion auf die Bewegung der Maus Rad scrollen. Das Scrollen mit Rädern wird durch die Standardeinstellung aktiviert.

Update nach dem Kommentar von Savvas unten.

Vielleicht kann Ihnen die Methode "setScrollMode (int)" im Ansichtsfenster helfen. Diese Methode bestimmt, wie Swing das Ansichtsfenster scrollt.

Sie können das Ansichtsfenster direkt aus dem ScrollPane mit der Methode getViewPort() abrufen. Sie haben folgende Möglichkeiten:

BLIT_SCROLL_MODE 
BACKINGSTORE_SCROLL_MODE 
SIMPLE_SCROLL_MODE 

Nach dem javadoc BLIT_SCROLL_MODE Graphics.copyArea so verwenden wird vielleicht eine der anderen versuchen.

+0

Ich möchte das Scroll-Verhalten zu halten. Was ich nicht möchte, ist die Art und Weise, wie sich der Bildlaufbereich beim Scrollen selbst darstellt. Es verwendet anscheinend nicht die Repaint-Methode, sondern verwendet die Methode Graphics.copyArea (x, y, width, height, dx, dy). Danach wird das Repaint aufgerufen, um den neu eingefügten Bereich zu zeichnen und da ich die gesamte Komponente als dreckig markiert habe, setzt meine Paint-Methode ein. Aber nach dem copyArea blinkt –

+0

Thanx. Das hat wie ein Zauber funktioniert. Sowohl JViewport.BACKINGSTORE_SCROLL_MODE als auch JViewport.SIMPLE_SCROLL_MODE funktionieren wie gewünscht. –

Verwandte Themen