使用Timer在JLabel中刷新图像

时间:2015-06-26 06:43:03

标签: java swing timer jlabel imageicon

我目前正在制作一个小程序女巫在一个小Swing GUI中显示来自网站的图片。问题是,每次图片更改时,弹出一个新框架而不是刷新JLable。

我不知道在用不同的方法尝试一些尝试后如何实现这一点。

如果你能给我一点提示,那就太好了。

import java.awt.BorderLayout;
import java.awt.Image;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.*;


public class PageReader extends JFrame {

    JLabel picture;
    static String[] viewable;
    int counter;
    static String urlString;
    Image image;
    URL url;

    public PageReader(int pos) throws IOException
    {
        urlString = "http:"+viewable[pos];

        url = new URL(urlString);
        image = ImageIO.read(url);

        ImageIcon icon = new ImageIcon(image); 

        picture = new JLabel();
        picture.setIcon(icon);


        int breite = icon.getImage().getWidth(this);
        int hoehe = icon.getImage().getHeight(this);


        do
        {
            if(hoehe>400)
            {
                breite *= 0.75;
                hoehe *= 0.75;
                icon.setImage(icon.getImage().getScaledInstance(breite, hoehe, image.SCALE_DEFAULT));
            }

            if(hoehe<400)
            {
                hoehe *= 1.2;
                breite *=1.2;
                icon.setImage(icon.getImage().getScaledInstance(breite, hoehe, image.SCALE_DEFAULT));
            }
        }while(hoehe>400&&hoehe<300);


        icon.setImage(icon.getImage().getScaledInstance(breite, hoehe, image.SCALE_DEFAULT));


        JPanel anzeige = new JPanel();
        anzeige.add(picture, BorderLayout.CENTER);

        setContentPane(anzeige);


        pack();
        setResizable(false);
        setVisible(true);
    }



    public static void main(String[] args) throws IOException, InterruptedException {
        // TODO Auto-generated method stub

        String meineURL = "http://www.pr0gramm.com/static/";

         URL url = new URL(meineURL);

         InputStreamReader isr = new InputStreamReader(url.openConnection().getInputStream());
         BufferedReader br = new BufferedReader(isr);

         // Kompletten Seiteninhalt auslesen
         String line ="";
         String quelltext ="";

         while((line = br.readLine()) != null)
         {
         quelltext += line + "\r\n";
         }

         // Reader Schließen
         br.close();
         isr.close();

         String test = quelltext.substring(1708);
         String[] parts = test.split("<a href=");


         for(int i=1; i<parts.length; i++)
         {
             parts[i]=parts[i].substring(1,15);
         }

         viewable = new String[parts.length];

         for(int i = 1; i<(parts.length-1); i++)
         {
             String sitePath = "http://pr0gramm.com"+parts[i];

             meineURL = sitePath;

             url = new URL(meineURL);

             isr = new InputStreamReader(url.openConnection().getInputStream());
             br = new BufferedReader(isr);

             // Kompletten Seiteninhalt auslesen
             line ="";
             quelltext ="";

             while((line = br.readLine()) != null)
             {
             quelltext += line + "\r\n";
             }

             CharSequence picPath = quelltext.subSequence(quelltext.indexOf("//img.pr0gramm.com/"), quelltext.indexOf("//img.pr0gramm.com/")+50);

             viewable[i] = picPath.toString();

             // Seiteninhalt ausgeben
             //System.out.println(quelltext);
             System.out.println(viewable[i]);
         }

         System.out.println("\nLink-Counter: "+viewable.length);
         //System.out.println("//img.pr0gramm.com/2015/06/25/87fd872bde0ab593.jpg");

         new PageReader(4);
         //System.out.println("\n \n \n Sub \n \n"+test);
         for(int i = 1; i<viewable.length; i++)
         {
             if(!(viewable[i].contains(".web")))
             {
                url = new URL("http:"+viewable[i]);

                new PageReader(i);

                System.out.println("test"+i);
                urlString = "http:"+viewable[i];
                Thread.sleep(5000);
             }
         }


    }

}

这是我目前的代码。

2 个答案:

答案 0 :(得分:2)

首先看看Concurrency in SwingWorker Threads and SwingWorker

您可能还想查看jsoup,因为使用String#substring等来解析HTML是一个非常糟糕的主意

Swing是单线程的,可以阻止事件调度线程阻塞或长时间运行(如Thread.sleep),但它也不是线程安全的,这意味着你不应该从EDT之外修改它。

为此,SwingWorker提供了一个合理的解决方案,因为它可以处理EDT之外的html和图像下载,但提供了多种方法可以重新同步EDT的更新。

首先,您需要更新JLabel的{​​{1}}属性,而不是创建icon的新实例,这是(很多)原因之一我们通常不鼓励人们从PageReader延伸。

JFrame

还应该查看The try-with-resources Statement,了解有关如何管理资源的更好建议

我不想在示例中引入更多代码,但如果可以,请避免使用import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Image; import java.awt.image.BufferedImage; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.URL; import java.util.List; import javax.imageio.ImageIO; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.SwingWorker; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; public class Test { public static void main(String[] args) { new Test(); } public Test() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { ex.printStackTrace(); } JFrame frame = new JFrame("Testing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(new TestPane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class TestPane extends JPanel { private JLabel label; public TestPane() { setLayout(new BorderLayout()); label = new JLabel("Loading..."); label.setHorizontalAlignment(JLabel.CENTER); label.setVerticalAlignment(JLabel.CENTER); add(label); ImageWorker worker = new ImageWorker(label); worker.execute(); } @Override public Dimension getPreferredSize() { return new Dimension(400, 400); } public class ImageWorker extends SwingWorker<Object, Image> { private JLabel output; public ImageWorker(JLabel output) { this.output = output; } @Override protected void process(List<Image> chunks) { output.setText(null); output.setIcon(new ImageIcon(chunks.get(chunks.size() - 1))); } @Override protected Object doInBackground() throws Exception { String meineURL = "http://www.pr0gramm.com/static/"; URL url = new URL(meineURL); String quelltext = ""; try (InputStreamReader isr = new InputStreamReader(url.openConnection().getInputStream()); BufferedReader br = new BufferedReader(isr)) { // Kompletten Seiteninhalt auslesen String line = ""; while ((line = br.readLine()) != null) { quelltext += line + "\r\n"; } } String test = quelltext.substring(1708); String[] parts = test.split("<a href="); for (int i = 1; i < parts.length; i++) { parts[i] = parts[i].substring(1, 15); } String[] viewable = new String[parts.length]; for (int i = 1; i < (parts.length - 1); i++) { String sitePath = "http://pr0gramm.com" + parts[i]; meineURL = sitePath; url = new URL(meineURL); try (InputStreamReader isr = new InputStreamReader(url.openConnection().getInputStream()); BufferedReader br = new BufferedReader(isr)) { // Kompletten Seiteninhalt auslesen String line = ""; quelltext = ""; while ((line = br.readLine()) != null) { quelltext += line + "\r\n"; } CharSequence picPath = quelltext.subSequence(quelltext.indexOf("//img.pr0gramm.com/"), quelltext.indexOf("//img.pr0gramm.com/") + 50); viewable[i] = picPath.toString(); } } System.out.println("\nLink-Counter: " + viewable.length); for (int i = 1; i < viewable.length; i++) { if (!(viewable[i].contains(".web"))) { url = new URL("http:" + viewable[i]); System.out.println("Reading " + url); BufferedImage original = ImageIO.read(url); Image image = original; if (original.getWidth() > original.getHeight()) { image = original.getScaledInstance(400, -1, Image.SCALE_SMOOTH); } else { image = original.getScaledInstance(-1, 400, Image.SCALE_SMOOTH); } publish(image); System.out.println("test" + i); Thread.sleep(5000); } } return null; } } } } ,有关详细信息,请参阅The Perils of Image.getScaledInstance()

您可以查看Java: maintaining aspect ratio of JPanel background imageQuality of Image after resize very low -- Java了解替代方案

答案 1 :(得分:0)

由于语言不同,我无法理解变量命名约定。但是,根据我的理解,我认为你不应该在每次更新时调用new PageReader()

相反,您应该调用类似update(int pos)

的内容
public void update(int pos)
{
    //The Code that went into your constructor
}

这将确保重用相同的JFrame,而不是创建新的JLabel

此外,我不认为你应该每次都初始化一个新的JPanelJLabel,而应该将JPanel添加到构造函数中的update,在picture.setIcon(icon);函数中,在不创建新JLabel的情况下调用public PageReader() { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); picture=new JLabel(); JPanel anzeige = new JPanel(); anzeige.add(picture, BorderLayout.CENTER); setContentPane(anzeige); pack(); setResizable(false); setVisible(true); }

你的构造函数应该是这样的:

update

构造函数中的其余部分代码应转到public void update(int pos) throws IOException { urlString = "http:"+viewable[pos]; url = new URL(urlString); image = ImageIO.read(url); ImageIcon icon = new ImageIcon(image); picture.setIcon(icon); int breite = icon.getImage().getWidth(this); int hoehe = icon.getImage().getHeight(this); do { if(hoehe>400) { breite *= 0.75; hoehe *= 0.75; icon.setImage(icon.getImage().getScaledInstance(breite, hoehe, image.SCALE_DEFAULT)); } if(hoehe<400) { hoehe *= 1.2; breite *=1.2; icon.setImage(icon.getImage().getScaledInstance(breite, hoehe, image.SCALE_DEFAULT)); } }while(hoehe>400&&hoehe<300); icon.setImage(icon.getImage().getScaledInstance(breite, hoehe, image.SCALE_DEFAULT)); }

编辑:

PageReader pr=new PageReader

现在在主类中,U应该声明像

这样的东西
new PageReader(4)

如果您使用pr.update(4)的任何地方,则应使用getScaledInstance

@MegaCleptomaniac,我不是形象专家,所以我认为你应该听听@MadProgrammer关于不使用public class aaa { int i=1; // instance variable /* To print this you have to write in the main() as aaa a = new aaa(); System.out.println(a.i); */ public static void main(String Args[]) { int i=0; // local variable System.out.println(i); } } 的说法