java swing根据jLabel调整ImageIcon大小

我是一个新的程序员,我有一些问题,我已经浏览了一个图片到我的GUI(并在文本框中也设置了路径),它显示在一个标签上,但标签尺寸设置只有100,100而图片很多更大,所以当我打开/显示它到标签它被裁剪,无论如何,它是否自动resize到标签大小? 下面是我在浏览按钮和打开对话框上的逻辑代码,请任何人告诉我我哪里错了..

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

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

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

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

在此处输入图像描述

 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 * WrapLayout with a left alignment and a default 5-unit * horizontal and vertical gap. */ public WrapLayout() { super(); } /** * Constructs a new * FlowLayout with the specified alignment and a default 5-unit * horizontal and vertical gap. The value of the alignment argument must be * one of * WrapLayout, * WrapLayout, or * WrapLayout. * * @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. * 

* The value of the alignment argument must be one of * WrapLayout, * WrapLayout, or * WrapLayout. * * @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 * visible 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 visible * 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(他潜伏着这个地方),因为坦率地说,没有其他布局经理给我带来我想要的效果。

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

看一下使用布局管理器和布局管理器 的可视指南

看看WrapLayout

更新了文本字段

如果你想将文本字段与图像相关联,那么我建议你将标签和文本字段都添加到JPanel (使用类似BorderLayout类的东西),然后将其添加到图像窗格……

在此处输入图像描述

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

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