0

我有一个 JFrame,其中包含一个 JScrollPane,其中包含一个 JPanel。我在 JPanel 上上传和绘制图像。图像的大小可能会发生变化。每次我绘制一个新图像时,在一个事件之后,我都会在 JFrame 上调用 pack。这一切都可以正常工作,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();
        }

    }
4

3 回答 3

1
  1. 必须在屏幕上max_size决定JFrame

  2. 添加新Image内容后,您必须调用revalidate& repaintforJPanel

  3. 然后JPanel返回正确的PreferredSize

  4. 将此Dimension与 desired进行比较JFrames max size,如果大于 then,则不要调用pack(),反之亦然

  5. 关于 JDialog 的最大大小的类似问题

  6. 尽快发布SSCCE以获得更好的帮助,因为 am 点仅与理论有关

于 2012-11-02T11:07:36.207 回答
0

我的建议是:如果你想显示图像,不要使用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

于 2012-11-02T11:00:04.093 回答
0

无需每次都声明 pack()。如果您在 main 方法中声明它就足够了。这意味着不在以下部分声明:

    public void actionPerformed(ActionEvent e){
                BufferedImage img = (BufferedImage)archiveHandler.getNextFile();
                panel.setImage(img);
                pack();
于 2012-11-02T11:00:30.443 回答