java swing resize ImageIcon according to jLabel

前端 未结 2 1136
忘了有多久
忘了有多久 2020-12-11 08:23

i am a new programmer here and i have something to ask, i have browse a picture into my GUI (and set the path in text box also)which displays on a Label, but the label dimen

相关标签:
2条回答
  • 2020-12-11 08:37

    Unless you really want a nasty head ache, I would suggest taking advantage of the layout management system.

    Instead of trying to set the size and location of components, let them decide how they wan to be displayed where possible.

    While I personally take advantage of Netbeans form designer, I would encourage you to take the time to learn how to build your UI's by hand, it will give a greater apprication for what the form designers can do, as well ideas you can employee to make advanced UIs - IMHO

    enter image description here

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Component;
    import java.awt.Container;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.FlowLayout;
    import java.awt.Insets;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import javax.imageio.ImageIO;
    import javax.swing.ImageIcon;
    import javax.swing.JButton;
    import javax.swing.JFileChooser;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.SwingUtilities;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    import javax.swing.border.LineBorder;
    
    public class SimpleImageBrowser {
    
        public static void main(String[] args) {
            new SimpleImageBrowser();
        }
    
        public SimpleImageBrowser() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    }
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new BorderLayout());
                    frame.add(new SimpleImageBrowser.ImageBrowserPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class ImageBrowserPane extends JPanel {
    
            private JFileChooser fcImage = new JFileChooser();
            private SimpleImageBrowser.ImagePane imagePane;
    
            public ImageBrowserPane() {
                setLayout(new BorderLayout());
    
                imagePane = new SimpleImageBrowser.ImagePane();
                add(new JScrollPane(imagePane));
    
                JButton add = new JButton("Add");
                add.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
    
                        int state = fcImage.showOpenDialog(SimpleImageBrowser.ImageBrowserPane.this);
                        switch (state) {
    
                            case JFileChooser.APPROVE_OPTION:
                                File file = fcImage.getSelectedFile();
    
                                try {
                                    BufferedImage bi1 = ImageIO.read(file);
                                    ImageIcon icon1 = new ImageIcon(bi1);
                                    JLabel label = new JLabel(icon1);
                                    label.setText(file.getPath());
                                    label.setHorizontalTextPosition(JLabel.CENTER);
                                    label.setVerticalTextPosition(JLabel.BOTTOM);
                                    label.setForeground(Color.WHITE);
                                    label.setBorder(new LineBorder(Color.WHITE));
                                    imagePane.add(label);
                                    imagePane.revalidate();
                                } catch (Exception exp) {
                                    exp.printStackTrace();
                                }
                        }
                    }
                });
    
                JPanel buttons = new JPanel();
                buttons.add(add);
                add(buttons, BorderLayout.NORTH);
    
            }
        }
    
        public class ImagePane extends JPanel {
    
            public ImagePane() {
                setLayout(new SimpleImageBrowser.WrapLayout());
                setBackground(Color.BLACK);
            }
    
            @Override
            public Dimension getPreferredSize() {
                return getComponentCount() == 0 ? new Dimension(200, 200) : super.getPreferredSize();
            }
        }
    
        /**
         * FlowLayout subclass that fully supports wrapping of components.
         */
        public class WrapLayout extends FlowLayout {
    
            private Dimension preferredLayoutSize;
    
            /**
             * Constructs a new
             * <code>WrapLayout</code> with a left alignment and a default 5-unit
             * horizontal and vertical gap.
             */
            public WrapLayout() {
                super();
            }
    
            /**
             * Constructs a new
             * <code>FlowLayout</code> with the specified alignment and a default 5-unit
             * horizontal and vertical gap. The value of the alignment argument must be
             * one of
             * <code>WrapLayout</code>,
             * <code>WrapLayout</code>, or
             * <code>WrapLayout</code>.
             *
             * @param align the alignment value
             */
            public WrapLayout(int align) {
                super(align);
            }
    
            /**
             * Creates a new flow layout manager with the indicated alignment and the
             * indicated horizontal and vertical gaps.
             * <p>
             * The value of the alignment argument must be one of
             * <code>WrapLayout</code>,
             * <code>WrapLayout</code>, or
             * <code>WrapLayout</code>.
             *
             * @param align the alignment value
             * @param hgap the horizontal gap between components
             * @param vgap the vertical gap between components
             */
            public WrapLayout(int align, int hgap, int vgap) {
                super(align, hgap, vgap);
            }
    
            /**
             * Returns the preferred dimensions for this layout given the
             * <i>visible</i> components in the specified target container.
             *
             * @param target the component which needs to be laid out 
             * @return the preferred dimensions to lay out the subcomponents of the
             * specified container
             */
            @Override
            public Dimension preferredLayoutSize(Container target) {
                return layoutSize(target, true);
            }
    
            /**
             * Returns the minimum dimensions needed to layout the <i>visible</i>
             * components contained in the specified target container.
             *
             * @param target the component which needs to be laid out
             * @return the minimum dimensions to lay out the subcomponents of the
             * specified container
             */
            @Override
            public Dimension minimumLayoutSize(Container target) {
                Dimension minimum = layoutSize(target, false);
                minimum.width -= (getHgap() + 1);
                return minimum;
            }
    
            /**
             * Returns the minimum or preferred dimension needed to layout the target
             * container.
             *
             * @param target target to get layout size for
             * @param preferred should preferred size be calculated
             * @return the dimension to layout the target container
             */
            private Dimension layoutSize(Container target, boolean preferred) {
                synchronized (target.getTreeLock()) {
                    //  Each row must fit with the width allocated to the containter.
                    //  When the container width = 0, the preferred width of the container
                    //  has not yet been calculated so lets ask for the maximum.
    
                    int targetWidth = target.getSize().width;
    
                    if (targetWidth == 0) {
                        targetWidth = Integer.MAX_VALUE;
                    }
    
                    int hgap = getHgap();
                    int vgap = getVgap();
                    Insets insets = target.getInsets();
                    int horizontalInsetsAndGap = insets.left + insets.right + (hgap * 2);
                    int maxWidth = targetWidth - horizontalInsetsAndGap;
    
                    //  Fit components into the allowed width
    
                    Dimension dim = new Dimension(0, 0);
                    int rowWidth = 0;
                    int rowHeight = 0;
    
                    int nmembers = target.getComponentCount();
    
                    for (int i = 0; i < nmembers; i++) {
                        Component m = target.getComponent(i);
    
                        if (m.isVisible()) {
                            Dimension d = preferred ? m.getPreferredSize() : m.getMinimumSize();
    
                            //  Can't add the component to current row. Start a new row.
    
                            if (rowWidth + d.width > maxWidth) {
                                addRow(dim, rowWidth, rowHeight);
                                rowWidth = 0;
                                rowHeight = 0;
                            }
    
                            //  Add a horizontal gap for all components after the first
    
                            if (rowWidth != 0) {
                                rowWidth += hgap;
                            }
    
                            rowWidth += d.width;
                            rowHeight = Math.max(rowHeight, d.height);
                        }
                    }
    
                    addRow(dim, rowWidth, rowHeight);
    
                    dim.width += horizontalInsetsAndGap;
                    dim.height += insets.top + insets.bottom + vgap * 2;
    
                    //    When using a scroll pane or the DecoratedLookAndFeel we need to
                    //  make sure the preferred size is less than the size of the
                    //  target containter so shrinking the container size works
                    //  correctly. Removing the horizontal gap is an easy way to do this.
    
                    Container scrollPane = SwingUtilities.getAncestorOfClass(JScrollPane.class, target);
    
                    if (scrollPane != null && target.isValid()) {
                        dim.width -= (hgap + 1);
                    }
    
                    return dim;
                }
            }
    
            /*
             *  A new row has been completed. Use the dimensions of this row
             *  to update the preferred size for the container.
             *
             *  @param dim update the width and height when appropriate
             *  @param rowWidth the width of the row to add
             *  @param rowHeight the height of the row to add
             */
            private void addRow(Dimension dim, int rowWidth, int rowHeight) {
                dim.width = Math.max(dim.width, rowWidth);
    
                if (dim.height > 0) {
                    dim.height += getVgap();
                }
    
                dim.height += rowHeight;
            }
        }
    }       
    

    I've included WrapLayout by Rob Camick (who lurks about the place) because, to be quite frank, none of the other layout managers gave me the effect I wanted.

    I also set the label's text with the path of the image

    Take a look at Using layout Managers and A Visual Guide to Layout Managers

    Take a look at WrapLayout

    Updated with text fields

    If you want to associate a text field with the image, then I suggest you add both the label and text field to a JPanel (using something like a BorderLayout) and then add that to your image pane...

    enter image description here

    public class ImagePane extends JPanel {
    
        public ImagePane() {
            setLayout(new SimpleImageBrowser.WrapLayout());
            setBackground(Color.BLACK);
        }
    
        public void addImage(File file) throws IOException {
            BufferedImage bi1 = ImageIO.read(file);
            ImageIcon icon1 = new ImageIcon(bi1);
            JPanel imgPane = new JPanel(new BorderLayout());
            imgPane.setOpaque(false);
            JLabel label = new JLabel(icon1);
            imgPane.add(label);
            JTextField field = new JTextField(file.getPath(), 20);
            field.setEditable(false);
            imgPane.add(field, BorderLayout.SOUTH);
            add(imgPane);
            revalidate();
        }
    
        @Override
        public Dimension getPreferredSize() {
            return getComponentCount() == 0 ? new Dimension(200, 200) : super.getPreferredSize();
        }
    }
    

    And the updated ActionListener...

    add.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
    
            int state = fcImage.showOpenDialog(SimpleImageBrowser.ImageBrowserPane.this);
            switch (state) {
    
                case JFileChooser.APPROVE_OPTION:
                    File file = fcImage.getSelectedFile();
                    try {
                        imagePane.addImage(file);
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
            }
        }
    });
    
    0 讨论(0)
  • 2020-12-11 08:47

    You should cut out the call to label.setSize. You should also place all your components in in the form designer instead of producing them when you click the button. Maybe you could also add a layout manager in the bargain? This will really involve a revolt against NetBeans.

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