繁体   English   中英

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

[英]Java - Create a continuous image slide with Swing

我不确定如何在标题中正确地命名我的问题,但我希望我的形象能表达我的期望:

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

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

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

一旦幻灯片到达底部, IMAGE B将完全占据显示区域,而IMAGE A被隐藏。 反之亦然,幻灯片上升到顶部。

有什么想法如何在Swing中用Java创建这样的东西吗? 我希望我的解释足够准确,可以理解。

感谢您的帮助 :)

编辑1:这是我实现@camickr的代码,我认为它只能通过设置视图面板才能工作。 按照您的指示我有没有做错任何事情?

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);
  1. 创建两个JLabels每个JLabels都带有一个ImageIcon作为图像。
  2. 使用水平BoxLayout将每个标签添加到JPanel
  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);

使用上面的基础知识创建一个合适的程序。

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

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

为了控制图像的绘制方式,我建议为此创建一个自己的面板,并在覆盖的paintComponent方法中使用drawImage调用。 图像的“位置”应当优选地是相对值,即,在0.0(示出第一幅图像)和1.0(示出第二幅图像)之间的double值,以独立于分辨率和图像尺寸。

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

然后,一个简单的实现可能如下所示:

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

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM