java组件在向jpanel添加2个或更多组件时消失

lstz6jyr  于 2021-07-06  发布在  Java
关注(0)|答案(1)|浏览(430)

我创建了一个类 SliderPanel 允许用户使用 JSlider 旋转图片并返回 int 表示滑块上的选定值。此对象继承自 JPanel ,所以当我加上两个或更多 SliderPanels 到主要 JPanel (creationpanel),看起来这些图片从gui中消失了。有没有解决这个问题的办法,我尝试过改变到一个绝对的布局,嵌套面板,并调整大小。
这是密码 SliderPanel :

public class SliderPanel extends JPanel
{
    private JSlider slider;
    private JLabel[] labelsArray;
    private static final GridBagConstraints gbc = new GridBagConstraints();
    private int selectedValue = 5;
    private boolean isImgVisible;

    /**
     * Constructor which creates the JPanel and manages the changing of the 
     * JSlider.
     * 
     * @param headerTitle The title of the Panel.
     * @param window The Window object to retrieve the images from.
     */
    public SliderPanel(String headerTitle, Window window)
    {
        setSize(new Dimension(300, 300));

        labelsArray = window.getImages();

        setLayout(new GridBagLayout());

        // Create a header for the label slider and add it to the panel.
        JLabel headerLabel = new JLabel("<HTML><U>" + headerTitle + 
                "</U></HTML>");
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.anchor = GridBagConstraints.CENTER;
        add(headerLabel, gbc);

        Hashtable labels = new Hashtable();
        for (int i = 0; i < 12; i++)
            labels.put(i, new JLabel(String.valueOf(i)));

        JPanel sliderAndImgPanel = new JPanel(new GridBagLayout());
        JPanel imgPanel = new JPanel();
        sliderAndImgPanel.setSize(new Dimension(200, 200));

        slider = new JSlider(0, 10, 5);
        slider.setLabelTable(labels);
        slider.setPaintLabels(true);
        slider.setPaintTicks(true);
        slider.addChangeListener((ChangeEvent e) -> {
            selectedValue = ((JSlider) e.getSource()).getValue();
            System.out.println(selectedValue);

            if (isImgVisible)
            {
                System.out.println("in");
                sliderAndImgPanel.remove(imgPanel);
                imgPanel.removeAll();
            }

            validate();
            repaint();

            JLabel pic = labelsArray[selectedValue];
            pic.setPreferredSize(new Dimension(150, 150));
            imgPanel.add(pic);
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.anchor = GridBagConstraints.CENTER;
            sliderAndImgPanel.add(imgPanel, gbc);
            isImgVisible = true;
            validate();
            window.validate();
        });

        JLabel pic = labelsArray[5];
        pic.setPreferredSize(new Dimension(150, 150));
        imgPanel.add(pic);
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.anchor = GridBagConstraints.CENTER;
        sliderAndImgPanel.add(imgPanel, gbc);
        sliderAndImgPanel.validate();

        gbc.gridx = 0;
        gbc.gridy = 1;
        gbc.anchor = GridBagConstraints.CENTER;
        sliderAndImgPanel.add(slider, gbc);

        gbc.gridx = 0;
        gbc.gridy = 1;
        gbc.anchor = GridBagConstraints.CENTER;
        add(sliderAndImgPanel, gbc);
    }

    /**
     * This method returns the value selected on the JSlider.
     * 
     * @return The selected value. [0, 10] 
     */
    public int getSelectedValue()
    {
        return selectedValue;
    }
}

下面是将面板添加到jframe的窗口类:

import java.awt.GridLayout;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class Window extends JFrame
{
    private static JLabel[] imagesArray;

    public static void main(String[] args)
    {
        new Window();
    }

    public Window()
    {
        super("Testing");

        setLayout(new GridLayout(2,1,5,5));
        setSize(1000, 700);
        setVisible(true);

        imagesArray = loadImages();

        add(new SliderPanel("test 1", this));
        add(new SliderPanel("test 2", this));

    }

    //  Accessor method.
    public static JLabel[] getImages()
    {
        return imagesArray;
    }

    // Loads images from project directory.
    private static JLabel[] loadImages()
    {
        JLabel[] array = new JLabel[11];

        // Load each image into the array.
        for (int i = 0; i < 11; i++)
        {
            try
            {
                BufferedImage newImg = ImageIO.read(new File(i + ".png"));
                array[i] = new JLabel(new ImageIcon(newImg));
            } catch (IOException ex)
            {
                System.out.println("Exception: " + i);
            }
        }

        return array;
    }
}

提前谢谢!
ps:以下是我上传的图片链接:

https://i.imgur.com/BvIehj5.png, 
https://i.imgur.com/f527RdK.png,
https://i.imgur.com/98mgTHr.png,
https://i.imgur.com/Jsqm08U.png,
https://i.imgur.com/0pHTDgE.png,
https://i.imgur.com/TvtEiFm.png,
https://i.imgur.com/VeEDFfn.png,
https://i.imgur.com/3rp59Oz.png,
https://i.imgur.com/AjVf9pU.png,
https://i.imgur.com/sqEO7GL.png,
https://i.imgur.com/dXlush6.png
nkhmeac6

nkhmeac61#

private static JLabel[] imagesArray;

您正在为jlabel组件创建静态数组。
稍后,在我看来,您尝试将数组中的jlabel添加到面板中:

JLabel pic = labelsArray[selectedValue];
pic.setPreferredSize(new Dimension(150, 150));
imgPanel.add(pic);

问题是swing组件只能有一个父级。
因此,通过将jlabel添加到第二个面板,可以将其从第一个面板中移除。
不要保持jlabel的静态数组。
而是保留一个 ImageIcon . 一个图标可以由多个组件共享。
然后,当您要将标签添加到面板时,可以使用imageicon创建一个新的jlabel。

相关问题