制作幻灯片程序
Making a slideshow program
我正在尝试制作幻灯片程序。我希望在单击时显示下一张幻灯片(只有两张幻灯片没有,但一旦错误解决,我会添加更多)。
代码编译得很好。但是当我点击时,没有任何反应。
可能会出什么问题?
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();
}
}
}
因此,“主要”问题是 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
有图标...
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
添加组件是不好的...
我所做的就是在 nextSlide
被调用时,创建一个新的 JLabel
分配给它下一个 icon
并将它添加到 Frame
(它使用BorderLayout
) 然后重新调整框架的大小。因为标签是透明的,所以它们仍然可见...
这就是为什么您不应该简单地将新组件添加到 BorderLayout
,而在您的情况下,只需更新现有 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();
}
}
}
因此,“主要”问题是 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
有图标...
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
添加组件是不好的...
我所做的就是在 nextSlide
被调用时,创建一个新的 JLabel
分配给它下一个 icon
并将它添加到 Frame
(它使用BorderLayout
) 然后重新调整框架的大小。因为标签是透明的,所以它们仍然可见...
这就是为什么您不应该简单地将新组件添加到 BorderLayout
,而在您的情况下,只需更新现有 JLabel
的属性以满足不断变化的需求。