Java-使用Swing创建连续的图像幻灯片

时间:2019-06-10 18:07:20

标签: java swing

我不确定如何在标题中正确地指出我的问题,但我希望我的图像能表达出我想要的内容:

https://i.stack.imgur.com/fIhP8.png

所以我要完成的工作是,例如,您有两张图片(如上图所示),以及旁边有一张幻灯片的对象[图片中名为(1)]

根据幻灯片的进度/值(1),会弹出 IMAGE A幻灯片 IMAGE B

一旦幻灯片到达底部,图像B 将完全占据显示区域,并且图像A 被隐藏。 反之亦然,幻灯片向上滑动。

是否知道如何在Swing中使用Java创建这样的东西? 我希望我的解释足够准确,可以理解。

谢谢您的帮助:)

编辑1: 这是我实现的代码@camickr 我认为它应该仅通过设置viewpanel才能起作用。按照您的指示,我有没有做错任何事情?

JPanel bigPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 20));
JPanel displayPanel = new JPanel();
JScrollPane scrollPane = new JScrollPane();
[...] 
displayPanel.setLayout(new BoxLayout(displayPanel, BoxLayout.X_AXIS));
JLabel label1 = new JLabel(new ImageIcon("R:\\imgA.jpg"));
JLabel label2 = new JLabel(new ImageIcon("R:\\imgB.jpg"));
displayPanel.add(label1);
displayPanel.add(label2);
scrollPane.setViewportView(displayPanel);
bigPanel.add(scrollPane);

2 个答案:

答案 0 :(得分:2)

  1. 为图像创建两个JLabels,每个ImageIcon
  2. 使用水平JPanel将每个标签添加到BoxLayout
  3. 将面板添加到JScrollPane
  4. 将滚动窗格添加到框架。

如果面板没有完全填满滚动窗格的可用空间,则滚动窗格将自动显示滚动条。

编辑:

您发布的代码不是“ MRE”:

  1. 我们无法编译该代码,因此我们不知道代码使用方式的确切上下文。

  2. 文本字段的意义是什么?您的问题是关于滚动两个图像。因此,文本字段与所陈述的问题无关。

  3. 我们无权访问您的图片,因此也不应包含在“ MRE”中。

您问题的基础是滚动两个标签的能力。因此,要对此进行测试,您需要像以下这样:

JLabel red = new JLabel("Image 1");
red.setOpaque(true);
red.setBackground( Color.RED );
red.setPreferredSize( new Dimension(200, 200) ); // for testing only

JLabel blue = new JLabel("Image 2");
...

JPanel displayPanel = new JPanel();
displayPanel.setLayout(new BoxLayout(displayPanel, BoxLayout.X_AXIS));
JScrollPane scrollPane = new JScrollPane(displayPanel);
frame.add(scrollPane);
frame.pack();
frame.setVisible(true);

使用以上内容作为基础来创建合适的程序。

显示边框时,图像将以原尺寸显示。缩小边框,将出现滚动条。

解决方案并不完全是您想要的,但是它向您展示了如何使用默认组件来实现滚动效果。我个人觉得使用水平滚动条而不是垂直滑块将图像从右向左滚动更为直观。

答案 1 :(得分:2)

为了控制图像的绘制方式,我建议为此创建一个自己的面板,并在覆盖的drawImage方法中使用paintComponent调用。图像的“位置”最好是一个 relative 值-即double值在0.0(显示第一个图像)和1.0(显示第二个图像)之间是独立的分辨率和图像尺寸。

有一个关于图像大小的警告,但是:必须假定两个图像的大小相同。否则,您将打开一罐蠕虫,其中涉及应如何处理不同图像大小的问题。此外,当包含的成分大于或小于图像时,应该发生一些自由度。但为简单起见,可以假定它始终具有正确的大小。

一个简单的实现可能看起来像这样:

ImageSlide

这是对应的代码:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;

public class ImageSlideTest
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }

    private static void createAndShowGui()
    {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        BufferedImage image0 = createImage("Image 0", Color.RED);
        BufferedImage image1 = createImage("Image 1", Color.GREEN);

        ImageSlidePanel imageSlidePanel = new ImageSlidePanel(image0, image1);
        JPanel panel = new JPanel(new BorderLayout());

        panel.add(imageSlidePanel, BorderLayout.CENTER);

        JSlider slider = new JSlider(SwingConstants.VERTICAL, 0, 100, 0);
        slider.addChangeListener(e -> 
        {
            double location = slider.getValue() / 100.0;
            imageSlidePanel.setLocation(location);
        });
        panel.add(slider, BorderLayout.EAST);

        f.getContentPane().add(panel);

        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    private static BufferedImage createImage(String text, Color color)
    {
        int w = 300;
        int h = 200;
        BufferedImage image =
            new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = image.createGraphics();
        g.setColor(color);
        g.fillRect(0, 0, w, h);
        g.setColor(Color.BLACK);
        g.setFont(new Font("Dialog", Font.PLAIN, 30));
        g.drawString(text, 50, 50);
        g.dispose();
        return image;
    }
}

class ImageSlidePanel extends JPanel
{
    private final BufferedImage image0;
    private final BufferedImage image1;
    private double location;

    // Note: The images should have the same size...
    public ImageSlidePanel(BufferedImage image0, BufferedImage image1)
    {
        this.image0 = image0;
        this.image1 = image1;
        this.location = 0.0;
    }

    public void setLocation(double location)
    {
        this.location = Math.min(1.0, Math.max(0.0, location));
        repaint();
    }

    @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        int dx = (int) (image0.getWidth() * location);
        g.drawImage(image0, -dx, 0, null);
        g.drawImage(image1, -dx + image0.getWidth(), 0, null);
    }

    @Override
    public Dimension getPreferredSize()
    {
        if (isPreferredSizeSet())
        {
            return super.getPreferredSize();
        }
        int w = image0.getWidth();
        int h = image0.getHeight();
        return new Dimension(w, h);
    }

}