[SOLVED][JAVA] Niedziałający JScrollPane

Witam, mam za zadanie napisać prostą przeglądarkę obrazków wraz z opcją skalowania. Do tego jeśli rozmiar załadowanego obrazka przekracza rozmiar okna ma być możliwość przewijania i tutaj już sobie nie dałem rady… Próbowałem zrobić to na kilka różnych sposobów lecz jakbym tego nie rozwiązał cały czas po załadowniu obrazka o większej rozdzielczości okno nie mam możliwości przewijania (paski natomiast się pojawiają). Proszę o pomoc/poradę/wskazówkę. Dodam, że jestem początkującym “programistą” więc proszę o wyrozumiałość.

import java.awt.BorderLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.io.File;

import javax.swing.*;

import javax.swing.filechooser.FileNameExtensionFilter;


/**

 * Klasa zarządzająca ramką z obrazkiem.

 */

public class ImageViewer extends JFrame

{

    public static final int DEFAULT_WIDTH = 800; //domyślna szerokość okna

    public static final int DEFAULT_HEIGHT = 600; //domyślna wysokość okna

    private ScaleData scale = new ScaleData(); //obiekt zawierający dane potrzebne do skalowania

    private ImageComponent comp = new ImageComponent(); //component zawierający obrazek

    private JFileChooser chooser; //okno dialogowe wyboru plików

    private JScrollPane scroll; //panel dodający paski przewijania

    private ScaleChooser dialog; //ramka pobierająca info potrzebne do skalowania


    /**

     * Konstruktor

     */

    public ImageViewer()

    {

        setTitle("aaaaaaa");

        setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);

        setResizable(false);

        setLocation(20, 20);


        // pasek przewijania

        scroll = new JScrollPane(comp, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);

        add(scroll, BorderLayout.CENTER); 


        // pasek menu

        JMenuBar menuBar = new JMenuBar();

        setJMenuBar(menuBar);


        JMenu menu = new JMenu("Plik");

        menuBar.add(menu);


        //opcja otworzenia pliku

        JMenuItem openItem = new JMenuItem("Otwórz");

        menu.add(openItem);

        openItem.addActionListener(new ImageViewer.FileOpenListener());


        //skalowanie zdjęcia

        JMenuItem scaleItem = new JMenuItem("Skaluj");

        menu.add(scaleItem);

        scaleItem.addActionListener(new ActionListener()

        {

            public void actionPerformed(ActionEvent event)

            {

                dialog = new ScaleChooser(); 

                scale = dialog.showDialog(ImageViewer.this);

                comp.scaleImage(scale.getWidth(), scale.getHeight());

            }

        });


        //zamknięcie programu

        JMenuItem exitItem = new JMenuItem("Zamknij");

        menu.add(exitItem);

        exitItem.addActionListener(new ActionListener()

        {

            public void actionPerformed(ActionEvent event)

            {

                System.exit(0);

            }

        });


        // okno wyboru plików - dodany filtr domyślny akceptujący tylko pliki obrazów

        chooser = new JFileChooser();

        FileNameExtensionFilter filter = new FileNameExtensionFilter("Pliki obrazów", "jpg", "jpeg", "gif");

        chooser.setFileFilter(filter);


    }



    /**

     * Słuchacz elementu menu Plik->Otwórz.

     */

    private class FileOpenListener implements ActionListener

    {

        public void actionPerformed(ActionEvent event)

        {

            /*

            * Domyślnym katalogiem, w któym będą szukane obrazki jest katalog projektu. 

            * Umieściłem tam kilka obrazów o różnej rozdzielczości

            */

            chooser.setCurrentDirectory(new File("."));


            // Wyświetlanie okna dialogowego wyboru plików.

            int result = chooser.showOpenDialog(ImageViewer.this);


            // Jeśli plik obrazu jest zaakceptowany, przekazuję jego ścieżkę do komponentu rysującego

            if (result == JFileChooser.APPROVE_OPTION)

            {

                String name = chooser.getSelectedFile().getPath();

                comp.setImage(name);

                comp.repaint();

            }

        }

    }

}

Dodaj komponent prezentujący obrazek do viewportu.

nie wiem czy dobrze zrozumiałem ale chcesz żebym zamieścił kod komponentu?? Jeśli tak to jest poniżej. Jeśli nie o to chodziło to proszę o prostsze opisanie co zrobić bo nie rozumiem.

package lab_9;


import java.awt.Graphics;

import java.awt.Image;

import java.io.File;

import java.io.IOException;

import javax.imageio.ImageIO;

import javax.swing.JComponent;


/**

 * Klasa odpowiadająca za wyświetlenie obrazka na ekranie.

 */

public class ImageComponent extends JComponent

{

    private Image image = null; //obrazek do wyświetlenia


    /**

     * Metoda ładująca obrazek

     * @param name scieżka do pliku

     */

    public void setImage(String name)

    {

        try 

        {

            image = ImageIO.read(new File(name));

        } 

        catch (IOException ee) 

        {

            ee.printStackTrace();

        }

    }


    /**

     * Metoda skalująca obrazek. 

     * @param width szerokość nowego obrazka

     * @param height wysokość nowego obrazka

     */

    public void scaleImage(int width, int height)

    {

        if(image != null && width>0 && height>0)

            image = image.getScaledInstance(width, height, image.SCALE_DEFAULT);

    }


    /**

     * Przeciążenie metody paint z klasy JComponent/

     */

    public void paintComponent(Graphics g)

    {

        if(image == null)

            return;

        g.drawImage(image, 0, 0, this);

    }

}

Niepotrzebne mi to, czytaj uważniej. JScrollPane ma coś takiego jak viewport (przeczytaj o tym w dokumentacji), żeby działo tak jak chcesz, musisz dodać komponent który ma być “scrollowalny” do viewportu, a nie do JScrollPane jako takiego.

EDIT olej wyżej co pisałem, domyślnie konstruktor dodaje do viewportu, myślałem, że do viewportBorder, nie wiem czemu. Dodałem do kodu

comp.setPreferredSize(new Dimension(2000, 2000));

comp.setSize(new Dimension(2000, 2000));

po wczytaniu obrazka 2000 na 2000 (kod dodany do części słuchacza FileOpenListener w actionPerformed przed odmalowaniem) i są paski. Ustawiasz po prostu b. duży obrazek, ale component jako taki się nie rozszerza sam z tego powodu, jego musisz rozszerzyć “ręcznie”.

http://www.roseindia.net/java/example/j … Size.shtml

Tu masz przykład jak pobrać wymiary obrazka. I na takie wymiary ustawiasz component.

ok, działa. Dziękuję.