Java 可调整大小的 JLabel 图标不断变大

标签 java swing user-interface jlabel image-resizing

(编辑2)嘿伙计们,我没有很多时间,所以我会快速发布这个,我在一个较小的程序中发生了问题:

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.imageio.ImageIO;
import javax.swing.DefaultListModel;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JScrollPane;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.JTextField;
import javax.swing.JList;
import javax.swing.JToolBar;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.ListSelectionEvent;
import java.awt.Color;
import javax.swing.border.LineBorder;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;

public class Main extends JFrame {

private JPanel contentPane;
private JTextField txtWhatTheHell;

private static ArrayList<ImageIcon> thumbslist = new ArrayList<ImageIcon>();
public static DefaultListModel model = new DefaultListModel();


private static void initialize_pix() throws IOException
{
    File filefolder = new File("pix");
    File[] pictures = filefolder.listFiles();


    for(File a: pictures)
    {
        Image tempimage = ImageIO.read(a);
        ImageIcon perimage = new ImageIcon(tempimage);

        thumbslist.add(perimage);
    }
    model.addElement(filefolder.toString());
}

public static ImageIcon resize(ImageIcon source, JLabel label)
{

    int height = label.getHeight();
    int width = label.getWidth();

    Image original = source.getImage();

    BufferedImage resized = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
    Graphics2D graphics = resized.createGraphics();

    graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
    graphics.drawImage(original, 0, 0, width, height, null);
    graphics.dispose();

    ImageIcon result = new ImageIcon(resized);

    return result;
}







public static void main(String[] args) {
    try {
        initialize_pix();
    } catch (IOException e1) {
        e1.printStackTrace();
    }
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                Main frame = new Main();
                frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

public Main() {

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 731, 563);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    setContentPane(contentPane);

    JScrollPane scrollPane = new JScrollPane();

    txtWhatTheHell = new JTextField();
    txtWhatTheHell.setText("Text");
    txtWhatTheHell.setEditable(false);
    txtWhatTheHell.setColumns(10);

    JToolBar toolBar = new JToolBar();
    toolBar.setFloatable(false);

    JLabel label = new JLabel("");
    label.addComponentListener(new ComponentAdapter() {
        @Override
        public void componentResized(ComponentEvent a) {


            label.setIcon(resize(thumbslist.get(0), label));
        }
    });
    label.setBorder(new LineBorder(new Color(0, 0, 0)));
    label.setBackground(Color.GRAY);
    GroupLayout gl_contentPane = new GroupLayout(contentPane);
    gl_contentPane.setHorizontalGroup(
        gl_contentPane.createParallelGroup(Alignment.LEADING)
            .addGroup(gl_contentPane.createSequentialGroup()
                .addContainerGap()
                .addGroup(gl_contentPane.createParallelGroup(Alignment.LEADING)
                    .addComponent(toolBar, GroupLayout.DEFAULT_SIZE, 685, Short.MAX_VALUE)
                    .addGroup(gl_contentPane.createSequentialGroup()
                        .addComponent(scrollPane, GroupLayout.PREFERRED_SIZE, 491, GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(ComponentPlacement.RELATED)
                        .addGroup(gl_contentPane.createParallelGroup(Alignment.LEADING)
                            .addComponent(label, GroupLayout.DEFAULT_SIZE, 188, Short.MAX_VALUE)
                            .addComponent(txtWhatTheHell, GroupLayout.DEFAULT_SIZE, 188, Short.MAX_VALUE))))
                .addContainerGap())
    );
    gl_contentPane.setVerticalGroup(
        gl_contentPane.createParallelGroup(Alignment.TRAILING)
            .addGroup(gl_contentPane.createSequentialGroup()
                .addComponent(toolBar, GroupLayout.PREFERRED_SIZE, 85, GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(ComponentPlacement.UNRELATED)
                .addGroup(gl_contentPane.createParallelGroup(Alignment.TRAILING)
                    .addGroup(gl_contentPane.createSequentialGroup()
                        .addComponent(txtWhatTheHell, GroupLayout.DEFAULT_SIZE, 162, Short.MAX_VALUE)
                        .addPreferredGap(ComponentPlacement.RELATED)
                        .addComponent(label, GroupLayout.PREFERRED_SIZE, 239, GroupLayout.PREFERRED_SIZE))
                    .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 407, Short.MAX_VALUE))
                .addContainerGap())
    );

    JList list = new JList(model);
    list.addListSelectionListener(new ListSelectionListener() {
        public void valueChanged(ListSelectionEvent a) {

            if(list.isSelectionEmpty() == true)
            {
                return;
            }
            else
            {
                label.setIcon(thumbslist.get(0));
            }


        }
    });
    scrollPane.setViewportView(list);
    contentPane.setLayout(gl_contentPane);
}
}

开头的文件是图片文件 我真的不知道出了什么问题

(编辑3)在调用调整大小监听器的每个实例后,我都会延迟一段时间,并且第一次,它会正确调整大小,然后似乎之后它开始失去控制

我认为@HovercraftFullOfEels 是这么想的,但我只是不知道到底该怎么做才能使其在每次调整框架大小时只调整一次大小

最佳答案

您的组件监听器内部正在进行某种递归。由于您在 JLabel 自己的 ComponentListener 中增加了 JLabel 图标的大小,因此监听器会收到大小更改的通知,这会增加图标的大小,从而通知监听器大小的更改......

一个可能的解决方案:考虑关闭监听器本身,以便不会发生这种递归,然后再次将其重新打开。一种方法是简单地删除监听器,然后在其内部重新添加监听器。

例如,

Label thumbchanger = new JLabel();
thumbchanger.addComponentListener(new ComponentAdapter() {
    @Override
    public void componentResized(ComponentEvent a) {
        // remove the *this* component listener before resizing
        thumbchanger.removeComponentListener(this);
        Mod current_mod = Globals.modList.get(list.getSelectedIndex());
        ImageIcon new_icon = Globals.resize(current_mod.get_current(), thumbchanger);
        thumbchanger.setIcon(new_icon);
        // re-add the component listener after done resizing
        thumbchanger.addComponentListener(this);
    }
});

另一种方法是使用您在其中设置的监听器本地的 boolean 字段。

thumbchanger.addComponentListener(new ComponentAdapter() {
    private boolean resizing = false;

    @Override
    public void componentResized(ComponentEvent a) {
        if (resizing) {
            return;
        }

        resizing = true;

        Mod current_mod = Globals.modList.get(list.getSelectedIndex());
        ImageIcon new_icon = Globals.resize(current_mod.get_current(), thumbchanger);
        thumbchanger.setIcon(new_icon);

        resizing = false;
    }
});

关于Java 可调整大小的 JLabel 图标不断变大,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41420985/

相关文章:

java - 如何使主 GUI 线程 'wait' 直到一个单独的弹出窗口消失

java - 测试浮点相等性。 (FE_FLOATING_POINT_EQUALITY)

java - 声明另一个类方法的类是什么

ios - 将值传递给下一个 viewController

jquery - Ie7/Ie8 中的 Jquery UI 对话框出现错误

Java TextField 问题

java - 网络代理背后的 Spring-Boot

java - 谁来帮帮我。用API重新编译后出现这个问题

java - GridBagLayout 中的组件放在中心,不占用所有可用空间

java - 将图像绘制为按钮的背景或使用 Java2D 绘制它更好/更快吗