Swing JScrollPane-Inhalt: Grösse anpassen

Pepe Rohny

Aktives Mitglied
Hi,

ich bin gerade dabei, einen ImageViewer zu bauen. Dabei habe ich folgendes Problem: wie kann ich erreichen, dass das Bild nach einer Grössenänderung derJScrollPane immer den gesamten Bereich (viewport) ohne Rollbalken ausfüllt?

Das mit den Rollbalken funnktioniert bereits - nur die Grössenanpassung ist das Problem.

Ein bisschen code gefällig? Voilá:
Java:
class ImageScrollablePane extends JScrollPane {

    private Image image = null;
    private final ImagePane imagePane;

    ImageScrollablePane() {

        imagePane = new ImagePane();

        imagePane.setHorizontalScrollBarPolicy(HORIZONTAL_SCROLLBAR_NEVER);
        imagePane.setVerticalScrollBarPolicy(VERTICAL_SCROLLBAR_NEVER);

        setViewportView(imagePane);

    }

    public void setImage(Image image) {
        this.image = image;
        imagePane.revalidate();
    }

    class ImagePane extends JComponent {

        int height = 0;
        int width = 0;

        public void paintComponent() {
            graphics.drawImage(image, 0, 0, width, height);
        }

    }

}

Ich muss also width und height berechnen bzw. die entsprechenden Werte in Erfahrung bringen. Nur: wie? Hat jemand ne' Idee?

Pepe
 
Du wirst da diese Methode benötigen:
drawImage

public abstract boolean drawImage(Image img,
int dx1,
int dy1,
int dx2,
int dy2,
int sx1,
int sy1,
int sx2,
int sy2,
ImageObserver observer)

Draws as much of the specified area of the specified image as is currently available, scaling it on the fly to fit inside the specified area of the destination drawable surface. Transparent pixels do not affect whatever pixels are already there.

This method returns immediately in all cases, even if the image area to be drawn has not yet been scaled, dithered, and converted for the current output device. If the current output representation is not yet complete then drawImage returns false. As more of the image becomes available, the process that draws the image notifies the specified image observer.

This method always uses the unscaled version of the image to render the scaled rectangle and performs the required scaling on the fly. It does not use a cached, scaled version of the image for this operation. Scaling of the image from source to destination is performed such that the first coordinate of the source rectangle is mapped to the first coordinate of the destination rectangle, and the second source coordinate is mapped to the second destination coordinate. The subimage is scaled and flipped as needed to preserve those mappings.

Parameters:
img - the specified image to be drawn
dx1 - the x coordinate of the first corner of the destination rectangle.
dy1 - the y coordinate of the first corner of the destination rectangle.
dx2 - the x coordinate of the second corner of the destination rectangle.
dy2 - the y coordinate of the second corner of the destination rectangle.
sx1 - the x coordinate of the first corner of the source rectangle.
sy1 - the y coordinate of the first corner of the source rectangle.
sx2 - the x coordinate of the second corner of the source rectangle.
sy2 - the y coordinate of the second corner of the source rectangle.
observer - object to be notified as more of the image is scaled and converted.
Returns:
true if the current output representation is complete; false otherwise.

Deine drawImage Methode zeichnet nur einen Ausschnitt. Einfacher kannst du mit Image.getScaledInstance ein neues Bild in bestimmter Größe errechnen.
Dann brauchst du noch einen Listener der dir bei größenänderungen des Scrollpanes das Bild neu berechnet. Ich schätz mal einen ChangeListener.
 
Du wirst da diese Methode benötigen:


Deine drawImage Methode zeichnet nur einen Ausschnitt.
??? neeeehhh!
Einfacher kannst du mit Image.getScaledInstance ein neues Bild in bestimmter Größe errechnen.
die von mir verwendete Methode skaliert bereits. Die Darstellung funktioniert problemlos. Das Problem ist, die Grösse { des viewwports (?) } zu bekommen und dann der ImagePane zuübergeben.
Dann brauchst du noch einen Listener der dir bei größenänderungen des Scrollpanes das Bild neu berechnet. Ich schätz mal einen ChangeListener.
interessanter Ansatz - weisst du was genaueres?
ich probiere gerade einen anderen Ansatz: die Methode setBounds überschreiben

Pepe
 
🙂 JScollPane.getViewPort().getSize() ?

hat was für sich - allerdings meinte ich einen passenden Listener.

Sooo: das mit setBounds überschreiben funktioniert - und zwar folgendermassen:
Java:
public void setBounds(int x, int y, int width, int height) {
    super.setBounds(x, y, width, height);
    imageCarrier.setBounds(getViewport().getBounds());
}
 

Neue Themen


Zurück
Oben