0

I have a JFrame that contains a JScrollPane which contains a JPanel. I upload and draw images on the JPanel. The size of the images is subject to change. Everytime I draw a new image, after an event, I call pack on the JFrame. This all works fine the JFrame and all is correctly resized, but I have problems with the scrollbars which appear and disappear erratically. If I remove the call to pack() the scrollbars are there but the containing JPanel doesn't resize. Why ? What can I do ? Here's trimmed SSCCE code for testing. Used images are at enter link description here

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import java.util.ArrayList;
    import javax.imageio.ImageIO;
    import javax.swing.BorderFactory;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JMenu;
    import javax.swing.JMenuBar;
    import javax.swing.JMenuItem;
    import javax.swing.JScrollPane;
    import javax.swing.JToolBar;
    import javax.swing.border.Border;

    @SuppressWarnings("serial")
    public class JComicFrame extends JFrame {
        private JComicPanel panel;
        private JToolBar toolbar;
        private JButton buttonZoom;
        private JButton buttonPrev;
        private JButton buttonNext;
        private JMenuBar menuBar;
        private JScrollPane scroller;
        private BufferedImage img;
        private ArrayList<BufferedImage> images;
        private int currentFile;
        public JComicFrame(){

            super("JComic");        

            images = new ArrayList<BufferedImage>();
            try {
                images.add(ImageIO.read(new File("1.jpg")));
                images.add(ImageIO.read(new File("2.jpg")));
                images.add(ImageIO.read(new File("3.jpg")));    
                images.add(ImageIO.read(new File("4.jpg")));    
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            BorderLayout layout = new BorderLayout();
            setLayout(layout);
            createToolbar();
            createPanel();
            createMenu();
            setJMenuBar(menuBar);
            add(toolbar,BorderLayout.NORTH);
            scroller = new JScrollPane(panel);
            add(scroller,BorderLayout.CENTER);
            setVisible(true);

            currentFile = -1;
            BufferedImage img = getNextFile();
            panel.setImage(img);

            pack();


        }

        private BufferedImage getNextFile(){
            currentFile = currentFile + 1;
            currentFile = (currentFile > images.size() - 1) ?    images.size() - 1 : currentFile;
            return images.get(currentFile);
        }

        private BufferedImage getPrevFile(){
            currentFile = currentFile - 1;
            currentFile = (currentFile < 0) ? 0 : currentFile;
            return images.get(currentFile);

        }



        private void createPanel(){
            Border raisedbevel, loweredbevel;
            raisedbevel = BorderFactory.createRaisedBevelBorder();
            loweredbevel = BorderFactory.createLoweredBevelBorder();
            panel = new JComicPanel(img);
            panel.setBorder(BorderFactory.createCompoundBorder(raisedbevel,loweredbevel));


        }
        private void createToolbar(){
            toolbar = new JToolBar();
            toolbar.setFloatable(false);
            buttonZoom = new JButton("+");
            toolbar.add(buttonZoom);

            buttonPrev = new JButton("<-");
            buttonPrev.addActionListener
            (
                    new ActionListener(){
                        public void actionPerformed(ActionEvent e){
                            BufferedImage img = getPrevFile();
                            panel.setImage(img);
                            pack();
                            repaint();



                        }
                    }
                    );
            toolbar.add(buttonPrev);
            buttonNext = new JButton("->");
            buttonNext.addActionListener
            (
                    new ActionListener(){
                        public void actionPerformed(ActionEvent e){
                            BufferedImage img = getNextFile();
                            panel.setImage(img);
                            pack();




                        }
                    }
                    );
            toolbar.add(buttonNext);
            toolbar.setBackground(Color.WHITE);


        }
        private void createMenu(){
            JMenu menuFile,menuJComic;
            JMenuItem fileOpen; 
            JMenuItem quitJComic,aboutJComic;


            menuBar = new JMenuBar();
            menuJComic = new JMenu("JComic");
            aboutJComic = new JMenuItem("About JComic...");
            menuJComic.add(aboutJComic);
            quitJComic = new JMenuItem("Quit");
            quitJComic.addActionListener(
                    new ActionListener(){
                        public void actionPerformed(ActionEvent e) {
                            System.exit(0);
                        }
                    }
                    );
            menuJComic.add(quitJComic);

            menuBar.add(menuJComic);

            menuFile = new JMenu("File");

            fileOpen = new JMenuItem("Open...");

            menuFile.add(fileOpen);
            menuBar.add(menuFile);


        }

        public static void main(String args[]){
            JComicFrame theFrame = new JComicFrame();



            theFrame.show();
        }

    }

/////////////////next class///////////////////

    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.RenderingHints;
    import java.awt.image.BufferedImage;

    import javax.swing.JPanel;





    public class JComicPanel extends JPanel{


        private static final long serialVersionUID = 1L;
        private BufferedImage img = null;
        private float scaling = 0.5f;
        private int newW, newH;


        public JComicPanel(BufferedImage img){
            super();

            this.img = img;

        }

        public JComicPanel(){
            super();
            this.img = null;

        }


        private Runnable scaleImage(BufferedImage img){
            int w = img.getWidth();
            int h = img.getHeight();
            newW = (int)(w * scaling);
            newH = (int)(h * scaling);
            BufferedImage dimg =  new BufferedImage(newW, newH, img.getType());  
            Graphics2D g = dimg.createGraphics();  
            g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
            g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g.setRenderingHint(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY); 
            g.drawImage(img, 0, 0, newW, newH, 0, 0, w, h, null);  
            this.img = dimg;
            revalidate();
            repaint();
            return null;

        }


        public void setImage(BufferedImage img){

            Thread t = new Thread(scaleImage(img));
            t.start();
        }


        public Dimension getPreferredSize(){
            System.out.println("PS");
            if(img==null || this.isVisible() == false)  
                return new Dimension(1,1);
            else 
                return new Dimension(img.getWidth(),img.getHeight());

        }

        public void paintComponent(Graphics g){


            Graphics2D g2d = (Graphics2D)g.create();
            super.paintComponent(g);
            g2d.drawImage(img,0,0,getSize().width,getSize().height, this); 
            g2d.dispose();
        }

    }
tagomago
  • 85
  • 1
  • 11

3 Answers3

1
  1. have to decide for max_size for JFrame on the screen

  2. after new Image is added you have to call revalidate & repaint for JPanel

  3. then JPanel returns proper PreferredSize,

  4. compare this Dimension with desired JFrames max size, if is greater then, then don't call pack(), and vice versa

  5. similair question about max size for JDialog

  6. for better help sooner post an SSCCE, because a.m. points are only about theory

Community
  • 1
  • 1
mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • I'll try, even if to be honest I've tried all possible combinations of repaint, validate, revalidate, update....As for the call to pack in the ActionEvent if I remove it the panel gets no resize, and I need to change it dynamically depending on the loaded image – tagomago Nov 02 '12 at 11:55
  • questions there is only one BuferredIamge, without any another JComponents placed in JPanel, Image fills whole JPanels area – mKorbel Nov 02 '12 at 12:18
0

My advice is: If you want to display image, don't use JPanel, use JLabel:

import javax.swing.*;

public class ScrollPane extends JFrame{
    JLabel label = new JLabel();
    JScrollPane scrollPane = new JScrollPane();

    public ScrollPane(){
        label.setIcon(new ImageIcon("C:/Documents and Settings/All Users/Documents/My Pictures/Sample Pictures/Image.jpg"));
        scrollPane.setViewportView(label);
        add(scrollPane);
    }

    public static void main(String[] args) {
        ScrollPane sp = new ScrollPane();
        sp.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        //sp.setSize(1024,800);
        sp.pack();
        sp.setVisible(true);
    }
}

Also, don't call pack(); every time after adding image on JPanel, call repaint(); method, if you want to use JPanel to display images.

Branislav Lazic
  • 14,388
  • 8
  • 60
  • 85
0

No need to declare pack() every time. Its sufficient if you declare it in the main method . That means not declare in the following part :

    public void actionPerformed(ActionEvent e){
                BufferedImage img = (BufferedImage)archiveHandler.getNextFile();
                panel.setImage(img);
                pack();
user1242347
  • 9
  • 1
  • 3