Полоса прокрутки не отображается после вызова пакета

У меня есть JFrame, который содержит JScrollPane, который содержит JPanel. Я загружаю и рисую изображения на JPanel. Размер изображений может быть изменен. Каждый раз, когда я рисую новое изображение, после события я вызываю пакет JFrame. Все это прекрасно работает в JFrame и все правильно изменено, но у меня есть проблемы с полосами прокрутки, которые появляются и исчезают по ошибке. Если я удаляю вызов pack(), полосы прокрутки есть, но содержащаяся JPanel не меняет размер. Зачем? Что я могу сделать? Вот урезанный код SSCCE для тестирования. Использованные изображения находятся на странице описания ссылки здесь

    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();
        }

    }

/////////////////следующий урок///////////////////

    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();
        }

    }

3 ответа

  1. должен решить для max_size за JFrame на экране

  2. после нового Image добавлено, вы должны позвонить revalidate & repaint за JPanel

  3. затем JPanel возвращается правильно PreferredSize,

  4. сравните это Dimension с желаемым JFrames max size, если больше, то не звоните pack(), и наоборот

  5. Similair вопрос о максимальном размере для JDialog

  6. для лучшей помощи, скорее отправьте SSCCE, потому что я только о теории

Не нужно объявлять pack() каждый раз. Достаточно, если вы объявите это в основном методе. Это значит не объявлять в следующей части:

    public void actionPerformed(ActionEvent e){
                BufferedImage img = (BufferedImage)archiveHandler.getNextFile();
                panel.setImage(img);
                pack();

Мой совет: если вы хотите отобразить изображение, не используйте JPanelиспользовать 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);
    }
}

Кроме того, не звоните pack(); каждый раз после добавления изображения на JPanel, вызов repaint(); метод, если вы хотите использовать JPanel для отображения изображений.

Другие вопросы по тегам