3

私が現在作業に苦労しているアプリケーションの部分は、一度に 1 つずつ画像のリストをスクロールして表示できることです。ユーザーからディレクトリを取得し、そのディレクトリ内のすべてのファイルをスプールしてから、jpeg と png だけの配列をロードしています。次に、最初の画像で JLabel を更新し、各画像を順番にスクロールして表示するための前と次のボタンを提供します。2番目の画像を表示しようとすると、更新されません...これまでに得たものは次のとおりです。

public class CreateGallery
{
    private JLabel swingImage;

画像を更新するために使用している方法:

protected void updateImage(String name) 
{
    BufferedImage image = null;
    Image scaledImage = null;
    JLabel tempImage;

    try
    {
        image = ImageIO.read(new File(name));
    } catch (IOException e)
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    // getScaledImage returns an Image that's been resized proportionally to my thumbnail constraints
    scaledImage = getScaledImage(image, THUMB_SIZE_X, THUMB_SIZE_Y);
    tempImage = new JLabel(new ImageIcon(scaledImage));
    swingImage = tempImage;
}

次に、swingImage を配置する createAndShowGUI メソッドで...

private void createAndShowGUI() 
{
    //Create and set up the window.
    final JFrame frame = new JFrame();

    // Miscellaneous code in here - removed for brevity

    //  Create the Image Thumbnail swingImage and start up with a default image
    swingImage = new JLabel();
    String rootPath = new java.io.File("").getAbsolutePath();
    updateImage(rootPath + "/images/default.jpg");

    // Miscellaneous code in here - removed for brevity

    rightPane.add(swingImage, BorderLayout.PAGE_START);
    frame.add(rightPane, BorderLayout.LINE_END);
public static void main(String[] args) 
{
    SwingUtilities.invokeLater(new Runnable() 
    {
        public void run() 
        {
            UIManager.put("swing.boldMetal", Boolean.FALSE);
            new CreateGalleryXML().createAndShowGUI();
        }
    });
}

ここまで来たら、最初の画像は私の default.jpg です。ディレクトリを取得してそのディレクトリ内の最初の画像を特定すると、swingImage を更新しようとすると失敗します。ここで、swingImage.setVisible() と swingImage.revalidate() を試して、強制的にリロードしようとしました。根本的な原因は私の tempImage = new JLabel だと思います。しかし、swingImage を更新するために BufferedImage または Image を JLabel に変換する方法がわかりません。

4

1 に答える 1

9

for eachNew Instanceのを作成する代わりに、のJLabel#setIcon(...)メソッドを使用して画像を変更します。JLabelImageJLabel

小さなサンプル プログラム:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class SlideShow extends JPanel
{
    private int i = 0;
    private Timer timer;
    private JLabel images = new JLabel();
    private Icon[] icons = {UIManager.getIcon("OptionPane.informationIcon"),
                            UIManager.getIcon("OptionPane.errorIcon"),
                            UIManager.getIcon("OptionPane.warningIcon")};
    private ImageIcon pictures1, pictures2, pictures3, pictures4;
    private ActionListener action = new ActionListener()
    {
        public void actionPerformed(ActionEvent ae)
        {                       
            i++;
            System.out.println(i);

            if(i == 1)
            {
                pictures1 = new ImageIcon("image/caIcon.png");
                images.setIcon(icons[i - 1]);
                System.out.println("picture 1 should be displayed here");
            }
            if(i == 2)
            {
                pictures2 = new ImageIcon("image/Keyboard.png");
                images.setIcon(icons[i - 1]);   
                System.out.println("picture 2 should be displayed here");
            }
            if(i == 3)
            {
                pictures3 = new ImageIcon("image/ukIcon.png");
                images.setIcon(icons[i - 1]);
                System.out.println("picture 3 should be displayed here");  
            }
            if(i == 4)
            {
                pictures4 = new ImageIcon("image/Mouse.png");
                images.setIcon(icons[0]);   
                System.out.println("picture 4 should be displayed here");  
            }
            if(i == 5)
            {
                timer.stop();
                System.exit(0);
            }
            revalidate();
            repaint();
        }
    };

    public SlideShow()
    {
        JFrame frame = new JFrame("SLIDE SHOW");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationByPlatform(true);

        frame.getContentPane().add(this);

        add(images);

        frame.setSize(300, 300);
        frame.setVisible(true); 
        timer = new Timer(2000, action);    
        timer.start();  
    }

    public static void main(String... args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new SlideShow();
            }
        });
    }
}

ImageIOでそれを行っているので、ImageIOを使用してそのJLabelに関連する良い例を次に示します

何が起こっているかなど、あなたのケースに関連する情報:

メソッド内で(swingImage)createAndShowGUI()を初期化し、それを間接的に に追加しました。JLabelJPanelJFrame

しかし、今あなたのupdateImage()メソッド内で新しい を初期化しJLabelています。今は別のメモリの場所にあり、書き込みtempImage = new JLabel(new ImageIcon(scaledImage));後、この新しく作成された を指すようswingImage(JLabel)にしていますJLabelが、この新しく作成されJLabelた は決して追加されませんでしたJPanel。したがって、試しても表示されませんrevalidate()/repaint()/setVisible(...)updateImage(...)したがって、メソッドのコードを次のように変更します。

protected void updateImage(String name) 
{
    BufferedImage image = null;
    Image scaledImage = null;
    JLabel tempImage;

    try
    {
        image = ImageIO.read(new File(name));
    } 
    catch (IOException e)
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    // getScaledImage returns an Image that's been resized 
    // proportionally to my thumbnail constraints
    scaledImage = getScaledImage(image, THUMB_SIZE_X, THUMB_SIZE_Y);
    tempImage = new JLabel(new ImageIcon(scaledImage));
    rightPane.remove(swingImage);
    swingImage = tempImage;
    rightPane.add(swingImage, BorderLayout.PAGE_START);
    rightPane.revalidate();
    rightPane.repaint(); // required sometimes
}

またはJLabel.setIcon(...)、前述のように使用します:-)

答えを更新しました

New JLabelここで、 aが古いものの位置にどのように配置されているかを見てください。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class SlideShow extends JPanel
{
    private int i = 0;
    private Timer timer;
    private JLabel images = new JLabel();
    private Icon[] icons = {UIManager.getIcon("OptionPane.informationIcon"),
                            UIManager.getIcon("OptionPane.errorIcon"),
                            UIManager.getIcon("OptionPane.warningIcon")};
    private ActionListener action = new ActionListener()
    {
        public void actionPerformed(ActionEvent ae)
        {                       
            i++;
            System.out.println(i);          

            if(i == 4)
            {
                timer.stop();
                System.exit(0);
            }
            remove(images);
            JLabel temp = new JLabel(icons[i - 1]);
            images = temp;
            add(images);
            revalidate();
            repaint();
        }
    };

    private void createAndDisplayGUI()
    {
        JFrame frame = new JFrame("SLIDE SHOW");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationByPlatform(true);    

        this.setLayout(new FlowLayout(FlowLayout.LEFT));    

        add(images);

        frame.getContentPane().add(this, BorderLayout.CENTER);

        frame.setSize(300, 300);
        frame.setVisible(true); 
        timer = new Timer(2000, action);    
        timer.start();  
    }

    public static void main(String... args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new SlideShow().createAndDisplayGUI();
            }
        });
    }
}

そしてあなたの質問に対して:私が試した2つのオプションのうち、一方が他方より優れていますか?

setIcon(...)という意味では、 add/remove の後に revalidate()/repaint() のことを気にする必要はありませんJLabelJLabelまた、追加するたびに配置を覚える必要はありません。それはその位置にとどまり、1 つのメソッドを呼び出して画像を変更するだけです。文字列を接続する必要はなく、頭を悩ますことなく作業が完了します。

Array of Records質問 2 について: とは何かについて、少し疑問がありました。

于 2012-04-07T04:15:20.527 に答える