How to make JLabel with image fill BorderLayout.CENTER

前端 未结 2 1184
眼角桃花
眼角桃花 2021-01-13 03:23

Ive got a JFrame and set the LayoutManager to BorderLayout and then proceeded to add my JLabel with an image. However when i resize the frame the JLabel doesnt resize. I hav

相关标签:
2条回答
  • 2021-01-13 03:51

    Forgive me if this seems arrogant, but I have nothing else to go on.

    I did a quick sample

    BorderLayout wide BorderLayout narrow

    See the red line around the image, that's the JLabel's border. As you can see, the label is been re-sized to fill the entire area.

    This is the code I used to produce the sample

    public class LayoutFrame extends JFrame {
    
        public LayoutFrame() throws HeadlessException {
    
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            Image image = null;
            URL url = getClass().getResource("/layout/issue78.jpg");
            try {
                image = ImageIO.read(url);
            } catch (IOException ex) {
    
                ex.printStackTrace();
    
            }
    
            JLabel label = new JLabel(new ImageIcon(image));
            label.setHorizontalAlignment(JLabel.CENTER);
            label.setVerticalAlignment(JLabel.CENTER);
            label.setBorder(new LineBorder(Color.RED, 4));
    
            setLayout(new BorderLayout());
    
            add(label);
    
        }
    
        public static void main(String[] args) {
    
            EventQueue.invokeLater(new Runnable() {
    
                @Override
                public void run() {
    
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException ex) {
                    } catch (InstantiationException ex) {
                    } catch (IllegalAccessException ex) {
                    } catch (UnsupportedLookAndFeelException ex) {
                    }
    
                    LayoutFrame frame = new LayoutFrame();
                    frame.setSize(200, 200);
                    frame.setLocationByPlatform(true);
                    frame.setVisible(true);
    
                }
            });
    
        }
    
    }
    

    Obviously, you'll need to supply your own image ;).

    Don't forget, the label WON'T scale the content for you, if that's your goal, you'll need to implement your own component to achieve this.

    If you're still having problems, I would suggest (in the absence of further evidence) that your label may not be in the container you think it is or the containers layout manager is not what you think it is.

    UPDATE

    I don't know why you're having issues with components going missing or issues with you menu. Are mixing heavy and light weight components??

    Sample with menu bar

    With menu bar

    After reading your question a little closer, I've devised a simple resizing image pane sample. For speed, I've relied on my libraries, but it should be reasonably easy to implementation your own code in place of my calls

    public class ImagePane extends JPanel {
    
        protected static final Object RESIZE_LOCK = new Object();
    
        private BufferedImage image;
        private BufferedImage scaledImage;
        private Timer resizeTimer;
    
        public ImagePane() {
    
            URL url = getClass().getResource("/layout/issue78.jpg");
            try {
                image = ImageIO.read(url);
            } catch (IOException ex) {
    
                ex.printStackTrace();
    
            }
    
            resizeTimer = new Timer(250, new ActionListener() {
    
                @Override
                public void actionPerformed(ActionEvent e) {
    
                    // Simple thread factory to start a slightly lower 
                    // priority thread.
                    CoreThreadFactory.getUIInstance().execute(new ResizeTask());
    
                }
    
            });
    
            resizeTimer.setCoalesce(true);
            resizeTimer.setRepeats(false);
    
        }
    
        @Override
        public void setBounds(int x, int y, int width, int height) {
    
            super.setBounds(x, y, width, height);
    
            resizeTimer.restart();
    
        }
    
        @Override
        protected void paintComponent(Graphics g) {
    
            super.paintComponent(g);
    
            Graphics2D g2d = (Graphics2D) g;
            if (scaledImage != null) {
    
                // This simply returns a rectangle that takes into consideration
                //the containers insets
                Rectangle safeBounds = UIUtilities.getSafeBounds(this);
    
                System.out.println("scaledImage = " + scaledImage.getWidth() + "x" + scaledImage.getWidth());
    
                int x = ((safeBounds.width - scaledImage.getWidth()) / 2) + safeBounds.x;
                int y = ((safeBounds.height - scaledImage.getHeight()) / 2) + safeBounds.y;
    
                g2d.drawImage(scaledImage, x, y, this);
    
            }
    
        }
    
        protected class ResizeTask implements Runnable {
    
            @Override
            public void run() {
    
                synchronized (RESIZE_LOCK) {
    
                    if (image != null) {
    
                        int width = getWidth();
                        int height = getHeight();
    
                        System.out.println("width = " + width);
                        System.out.println("height = " + height);
    
                        // A simple divide and conquer resize implementation
                        // this will scale the image so that it will fit within
                        // the supplied bounds
                        scaledImage = ImageUtilities.getScaledInstanceToFit(image, new Dimension(width, height), ImageUtilities.RenderQuality.High);
    
                        System.out.println("scaledImage = " + scaledImage.getWidth() + "x" + scaledImage.getWidth());
    
                        repaint(); // this is one of the few thread safe calls
    
                    }
    
                }
    
            }
    
        }
    
    }
    
    0 讨论(0)
  • 2021-01-13 03:52

    Best option is to sub class ImageIcon and override its paintIcon method to simply paint the image using the Graphics.paint( x, y, width, height ...).

    0 讨论(0)
提交回复
热议问题