Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
47 views
in Technique[技术] by (71.8m points)

java - To display an image

I want to display an image from the web to a panel in another JFrame at the click of a button. Whenever I click the button, first the image loads; and during this time, the current form potentially freezes. Once the image has loaded, the form is displayed with the image. How can I avoid the situation where my form freezes since it is very irritating. Among my codes:

My current class:

private void btn_TrackbusActionPerformed(java.awt.event.ActionEvent evt) {                                             
        try {
            sendMessage("Query,map,$,start,211,Arsenal,!");
            System.out.println(receiveMessage());
        } catch (UnknownHostException ex) {
            Logger.getLogger(client_Trackbus.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(client_Trackbus.class.getName()).log(Level.SEVERE, null, ex);
        }
        catch (Exception ex) {
            Logger.getLogger(client_Trackbus.class.getName()).log(Level.SEVERE, null, ex);
        }
        client_trackedbus nextform=new client_trackedbus(planform,connection,packet_receive,packet_send);
        this.setVisible(false);
        this.dispose();
        nextform.setVisible(true);
        // TODO add your handling code here:
    }                                            

My next class that displays the image:

public class client_trackedbus extends javax.swing.JFrame {
    client_planform planform=null;
    DatagramSocket connection=null;
    DatagramPacket packet_receive=null;
    DatagramPacket packet_send=null;
    JLabel label=null;
    /** Creates new form client_trackedbus */
    public client_trackedbus(client_planform planform,DatagramSocket connection,DatagramPacket packet_receive,DatagramPacket packet_send) {
        initComponents();
        this.planform=planform;
        this.connection=connection;
        this.packet_receive=packet_receive;
        this.packet_send=packet_send;
        try {
            displayMap("http://www.huddletogether.com/projects/lightbox2/images/image-2.jpg", jPanel1, new JLabel());
        } catch (MalformedURLException ex) {
            Logger.getLogger(client_trackedbus.class.getName()).log(Level.SEVERE, null, ex);
        }

    }


    private void displayMap(String url,JPanel panel,JLabel label) throws MalformedURLException{
        URL imageurl=new URL(url);
        Image image=(Toolkit.getDefaultToolkit().createImage(imageurl));
        ImageIcon icon = new ImageIcon(image);
        label.setIcon(icon);
        panel.add(label);
       // System.out.println(panel.getSize().width);
        this.getContentPane().add(panel);
    }


    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        btn_Exit = new javax.swing.JButton();
        btn_Plan = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Public Transport Journey Planner");

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 368, Short.MAX_VALUE)
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 172, Short.MAX_VALUE)
        );

        jLabel1.setFont(new java.awt.Font("Arial", 1, 18));
        jLabel1.setText("Your tracked bus");

        btn_Exit.setText("Exit");
        btn_Exit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btn_ExitActionPerformed(evt);
            }
        });

        btn_Plan.setText("Plan journey");
        btn_Plan.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btn_PlanActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(104, 104, 104)
                        .addComponent(jLabel1))
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(65, 65, 65)
                        .addComponent(btn_Plan)
                        .addGap(65, 65, 65)
                        .addComponent(btn_Exit, javax.swing.GroupLayout.PREFERRED_SIZE, 87, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap(20, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(35, 35, 35)
                .addComponent(jLabel1)
                .addGap(18, 18, 18)
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(btn_Exit)
                    .addComponent(btn_Plan))
                .addContainerGap(12, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>                        

    private void btn_ExitActionPerformed(java.awt.event.ActionEvent evt) {                                         
        // TODO add your handling code here:
        Exitform();
    }                                        

    private void btn_PlanActionPerformed(java.awt.event.ActionEvent evt) {                                         
        // TODO add your handling code here:
        this.setVisible(false);
        this.dispose();
         this.planform.setVisible(true);
    }                                        


    private void Exitform(){
        this.setVisible(false);
        this.dispose();

    }
    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
               // new client_trackedbus().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify                     
    private javax.swing.JButton btn_Exit;
    private javax.swing.JButton btn_Plan;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JPanel jPanel1;
    // End of variables declaration                   

}
Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

As suggested in the article Concurrency in Swing, your button handler's query may be blocking the event dispatch thread. Using javax.swing.SwingWorker is one approach to loading images in the background, while displaying progress and keeping the GUI thread alive.

Addendum: Here's a sscce that loads the SO logo; it's been updated to handle exceptions and resize the enclosing container to fit the loaded image:

SO Logo

import java.awt.*;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.*;

/**
 * @see http://stackoverflow.com/questions/4530659
 */
public final class WorkerTest extends JFrame {

    private final JLabel label = new JLabel("Loading...");

    public WorkerTest() {
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        label.setHorizontalTextPosition(JLabel.CENTER);
        label.setVerticalTextPosition(JLabel.BOTTOM);
        this.add(label);
        this.pack();
        this.setLocationRelativeTo(null);
    }

    private void start() {
        new ImageWorker().execute();
    }

    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                WorkerTest wt = new WorkerTest();
                wt.setVisible(true);
                wt.start();
            }
        });
    }

    class ImageWorker extends SwingWorker<Image, Void> {

        private static final String TEST
            = "http://cdn.sstatic.net/stackexchange/img/logos/so/so-logo.png";

        @Override
        protected Image doInBackground() throws IOException {
            Image image = ImageIO.read(new URL(TEST));
            return image.getScaledInstance(640, -1, Image.SCALE_SMOOTH);
        }

        @Override
        protected void done() {
            try {
                ImageIcon icon = new ImageIcon(get());
                label.setIcon(icon);
                label.setText("Done");
                WorkerTest.this.pack();
                WorkerTest.this.setLocationRelativeTo(null);
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        }
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...