I´m currently working on a little programm witch displays pictures from a website in a little Swing GUI. The Problem is, that every time the picture changes a new frame pops up instead of refreshing the JLable.
I have no idea how to realize this after trying a few attempts with different methods.
It would be nice if you could give me a little hint.
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);
}
}
}
}
This is my current code.
Start by taking a look at Concurrency in Swing and Worker Threads and SwingWorker
You might also like to take a look at jsoup as using String#substring
etc to parse html is a really bad idea
Swing is single threaded, meaining your can't block the Event Dispatching Thread with blocking or long running processes (like Thread.sleep
), but it is also not thread safe, meaning you shouldn't modify it from outside of EDT either.
To this end, SwingWorker
presents a reasonable solution, as it can process the html and image downloading outside of the EDT, but provides a number of ways you can resync updates to the EDT.
To start with, you need to be updating the JLabel
's icon
property and not creating new instances of PageReader
, which is one of the (many) reasons we generally discourage people from extending from JFrame
.
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;
}
}
}
}
Should also have a look at The try-with-resources Statement for better ideas on how to manage your resources
I didn't want to introduce more code into the example, but you should avoid using getScaledInstance
if you can, see The Perils of Image.getScaledInstance() for more details.
You can take a look at Java: maintaining aspect ratio of JPanel background image and Quality of Image after resize very low -- Java for alternatives