【问题标题】:Components disappear when 2 or more are added to a JPanel当 2 个或更多添加到 JPanel 时组件消失
【发布时间】:2020-11-25 21:01:19
【问题描述】:

我创建了一个类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 的 Window 类:

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

【问题讨论】:

  • 如果您可以创建并发布一个像样的minimal reproducible example,这可能会帮助您快速获得一个像样的答案。
  • 您在多个地方调用setPreferredSize(),您应该允许面板确定自己的大小。这就是让多个组件正确显示的方式。我正在附议minimal reproducible example 的请求,这里有太多可能是错误的。给我们一些重现问题的代码。
  • 谢谢。反对票替换为赞成票。
  • 您是否将slider 添加到任何面板?我看不到在哪里。
  • 使用空布局管理器的时间几乎总是从不! LayoutMangers 可以帮助程序员。当它们第一次出现在 java 中时,我接受了它们(是的,我已经那么老了)。

标签: java swing user-interface jpanel jslider


【解决方案1】:
private static JLabel[] imagesArray;

您正在为 JLabel 组件创建一个静态数组。

稍后在我看来,您尝试将数组中的 JLabel 添加到面板:

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

问题是 Swing 组件只能有一个父级。

因此,通过将 JLabel 添加到第二个面板,您可以将其从第一个面板中删除。

不要保留 JLabels 的静态数组。

改为保留ImageIcon 的静态数组。一个图标可以被多个组件共享。

然后,当您想将标签添加到面板时,您可以使用 ImageIcon 创建一个新的 JLabel。

【讨论】:

  • 这就是问题所在。谢谢。
猜你喜欢
  • 2015-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-02
  • 2011-09-13
  • 2013-12-12
  • 1970-01-01
相关资源
最近更新 更多