java swing根据jLabel调整ImageIcon大小

时间:2013-08-02 07:08:53

标签: java swing imageicon

我是这里的新程序员,我有一些要问的问题,我已将图片浏览到我的GUI(并在文本框中设置路径),该图片显示在标签上,但标签尺寸仅设置为100,100而图片要大得多,所以当我打开/显示它的标签时会被裁剪,无论如何都要自动调整大小到标签大小?下面是我在浏览按钮和打开对话框中的逻辑代码 请任何人告诉我我错在哪里..

public class ImagePath extends javax.swing.JFrame {
    private JPanel contentPane;

    JLabel jLabel1;
    String s2;
    File targetFile;
    BufferedImage targetImg;

    public ImagePath() {
        initComponents();
    }

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {

        JFileChooser jFileChooser1 = new JFileChooser();

        int state = jFileChooser1.showOpenDialog(new JFrame());

        jTextField1.setText("");
        if (state == JFileChooser.APPROVE_OPTION) {
            JOptionPane.showMessageDialog(new JFrame(), "hii");
            File file = jFileChooser1.getSelectedFile();
            s2 = file.toString();
            jTextField1.setText(s2);
            jLabel1 = new JLabel();
            jLabel1.setName(s2);
            jLabel1.setLocation(50, 50);
            jLabel1.setSize(300, 300);
            add(jLabel1);
            BufferedImage bi1;

            try {
                bi1 = ImageIO.read(file);
                ImageIcon icon1 = new ImageIcon(bi1);
                jLabel1.setIcon(icon1);

                Image img = icon1.getImage();
                ImageIcon icon = new ImageIcon(file.getPath());
                Image scaleImage = icon.getImage().getScaledInstance(28, 28, Image.SCALE_DEFAULT);

                repaint();
                pack();

            } catch (Exception e) {
                System.out.println(e);
            }
        } else if (state == JFileChooser.CANCEL_OPTION) {
            JOptionPane.showMessageDialog(new JFrame(), "Canceled");
        }

    }

}

2 个答案:

答案 0 :(得分:5)

除非你真的想要一个讨厌的头痛,否则我建议你利用布局管理系统。

不要试图设置组件的大小和位置,而是让他们决定如何在可能的情况下显示它们。

虽然我个人利用Netbeans表单设计器,但我鼓励您花时间学习如何手动构建UI,它将为表单设计人员可以做的事情提供更好的应用,以及您可以提供的想法员工制作高级用户界面 - 恕我直言

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

我已经包含了Rob Camick(潜伏在这个地方)的WrapLayout,因为坦率地说,其他布局经理都没有给我带来我想要的效果。

我还使用图像的路径设置标签的文本

查看Using layout ManagersA Visual Guide to Layout Managers

查看WrapLayout

更新了文字字段

如果您想将文字字段与图片相关联,那么我建议您将标签和文字字段添加到JPanel(使用BorderLayout之类的内容),然后将其添加到您的图片窗格......

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

更新后的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();
                }
        }
    }
});

答案 1 :(得分:0)

你应该切断对label.setSize的号召。您还应该将所有组件放在表单设计器中,而不是在单击按钮时生成它们。也许你还可以在讨价还价中添加布局管理器?这实际上将涉及对NetBeans的反抗。