制作幻灯片节目

时间:2015-07-10 02:22:12

标签: java swing slideshow jlabel

我正在尝试制作幻灯片程序。我希望在我点击时显示下一张幻灯片(只有两张幻灯片没有,但我会在错误整理后添加更多)。 代码编译得很好。但是当我点击时,没有任何反应。 什么可能出错?

package project;

import java.awt.BorderLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class Frame extends JFrame{

Frame() {
    setLayout(new BorderLayout());
    ImageIcon slide = new ImageIcon("E:\\Books\\Computer\\Java\\Introduction to Java Programming\\exercise9e\\image\\slide0.jpg");
    JLabel slidesLabel = new JLabel(slide);
    add(slidesLabel,BorderLayout.CENTER);
    slidesLabel.addMouseListener(new ClickListener());
}

public void nextSlide() {
    ImageIcon slide = new ImageIcon("E:\\Books\\Computer\\Java\\Introduction to Java Programming\\exercise9e\\image\\slide1.jpg");
    JLabel slidesLabel = new JLabel(slide);
    add(slidesLabel,BorderLayout.CENTER);
    System.out.println("x");
}

public static void main(String args[]) {
    Frame frame = new Frame();
    frame.setSize(800,600);
    frame.setLocationRelativeTo(null);
    frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
    frame.setVisible(true);
}

public class ClickListener extends MouseAdapter {
    @Override
    public void mouseClicked(MouseEvent e) {
        nextSlide();
    }
}

}

1 个答案:

答案 0 :(得分:4)

所以,"主要"问题是BorderLayout只管理其管理的五个可用位置中的任何一个组件。

在该位置添加另一个组件往往会导致问题,即首次添加的组件不会显示,或者在您的情况下,将保留并可能干扰新组件

" A"解决方案是为每张幻灯片重复使用相同的JLabel,只需为icon属性(或在此示例中为text属性)提供新值

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Frame extends JFrame {

    private JLabel slidesLabel = new JLabel("Apple");
    public Frame() {
        setLayout(new BorderLayout());
        add(slidesLabel, BorderLayout.CENTER);
        slidesLabel.addMouseListener(new ClickListener());
    }

    public void nextSlide() {
        slidesLabel.setText("Banana");
    }

    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                Frame frame = new Frame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class ClickListener extends MouseAdapter {

        @Override
        public void mouseClicked(MouseEvent e) {
            nextSlide();
        }
    }

}

这种方法允许您将每个icon放入array,并且只需要一个计数器来确定哪个幻灯片是最新的,所以当您点击下一张幻灯片时,您只需递增计数器,从数组中获取下一个值并将其应用于标签

更好(更合适)的解决方案是实际使用CardLayout,有关详细信息,请参阅How to Use CardLayout

带图标......

SlideShow

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Frame extends JFrame {

    private JLabel slidesLabel = new JLabel();
    private Icon[] icons;
    private int currentSlide = -1;

    public Frame() {
        try {
            // Personally, I'd use File#listFiles to list all the
            // images in a directory, but that might be consider
            // using our initiative...
            icons = new Icon[]{
                new ImageIcon(ImageIO.read(new File("..."))),
                new ImageIcon(ImageIO.read(new File("..."))),
                new ImageIcon(ImageIO.read(new File("...")))
            };
            slidesLabel.setVerticalAlignment(JLabel.CENTER);
            slidesLabel.setHorizontalAlignment(JLabel.CENTER);
            setLayout(new BorderLayout());
            add(slidesLabel, BorderLayout.CENTER);
            slidesLabel.addMouseListener(new ClickListener());
            nextSlide();
        } catch (IOException exp) {
            exp.printStackTrace();
        }
    }

    public void nextSlide() {
        if (currentSlide < icons.length - 1) {
            currentSlide++;
            slidesLabel.setIcon(icons[currentSlide]);
        }
    }

    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                Frame frame = new Frame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class ClickListener extends MouseAdapter {

        @Override
        public void mouseClicked(MouseEvent e) {
            nextSlide();
        }
    }

}

为什么简单地向BorderLayout添加组件是错误的......

BadLayout

我所做的只是在调用nextSlide时,创建一个新的JLabel将其分配给下一个icon并将其添加到Frame(使用BorderLayout 1}})然后重新调整框架的大小。因为标签是透明的,所以它们仍然可见......

这就是为什么您不应该只为BorderLayout添加新组件的原因,但在您的情况下,只需更新现有JLabel的属性即可满足不断变化的需求。