现在的位置: 首页 > 综合 > 正文

Java Thread Programming 1.9.2 – Threads and Swing

2013年04月03日 ⁄ 综合 ⁄ 共 15589字 ⁄ 字号 评论关闭
Using a Worker Thread to Relieve the Event Thread
使用工作线程来做事务操作
/*
 * Created on 2005-7-17
 *
 * Java Thread Programming - Paul Hyde
 * Copyright ? 1999 Sams Publishing
 * Jonathan Q. Bo 学习笔记
 *
 */
package org.tju.msnrl.jonathan.thread.chapter9;
 
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
 
/**
 * @author Jonathan Q. Bo from TJU MSNRL
 *
 * Email:jonathan.q.bo@gmail.com
 * Blog:blog.csdn.net/jonathan_q_bo
 *      blog.yesky.net/jonathanundersun
 *
 * Enjoy Life with Sun!
 *
 */
 
public class BalanceLookUp extends JPanel{
    private JTextField accTF;
    private JTextField pinTF;
    private JButton searchB;
    private JButton cancelB;
    private JLabel balanceL;
   
    private volatile Thread lookupThread;
   
    public BalanceLookUp(){
        buildGUI();//控制显示
        hookupEvent();//添加事件处理
    }
   
    /** 添加控件 */
    public void buildGUI(){
        JLabel accountL = new JLabel("Account Label");
        JLabel pinL = new JLabel("Pin");
        accTF = new JTextField(12);
        pinTF = new JTextField(4);
       
        JPanel dataP = new JPanel();
        dataP.setLayout(new FlowLayout(FlowLayout.CENTER));
        dataP.add(accountL);
        dataP.add(accTF);
        dataP.add(pinL);
        dataP.add(pinTF);
       
        searchB = new JButton("search");
        cancelB = new JButton("cancel");
        cancelB.setEnabled(false);
       
        JPanel buttonP = new JPanel();
        buttonP.setLayout(new GridLayout(1,-1,5,5));
        buttonP.add(searchB);
        buttonP.add(cancelB);
       
        JPanel outButtonP = new JPanel();
        outButtonP.setLayout(new FlowLayout(FlowLayout.CENTER));
        outButtonP.add(buttonP);
       
        JLabel balancePrifLb = new JLabel("account balance");
        this.balanceL = new JLabel("unknown balance");
       
        JPanel balanceP = new JPanel();
        balanceP.setLayout(new FlowLayout(FlowLayout.CENTER));
        balanceP.add(balancePrifLb);
        balanceP.add(balanceL);
       
        JPanel northP = new JPanel();
        northP.setLayout(new GridLayout(-1,1,5,5));
        northP.add(dataP);
        northP.add(outButtonP);
        northP.add(balanceP);
       
        setLayout(new BorderLayout());
        add(northP);
    }
   
    /** 添加事件响应函数 */
    public void hookupEvent(){
        searchB.addActionListener(
                new ActionListener(){
                    public void actionPerformed(ActionEvent e){
                        search();
                    }
                }
        );
       
        cancelB.addActionListener(
                new ActionListener(){
                    public void actionPerformed(ActionEvent e){
                        cancelSearch();
                    }
                }
        );
    }
   
    /** 处理查找操作 */
    private void search(){
        this.ensureEventThread();
        searchB.setEnabled(false);
        cancelB.setEnabled(true);
        balanceL.setText("searching ... ");
       
        String account = accTF.getText();
        String pin = pinTF.getText();
       
        /*新建一个线程处理,根据帐户和密码察看帐户余额*/
        lookupAsyn(account,pin);
    }
   
    /**处理取消操作*/
    private void cancelSearch(){
        this.ensureEventThread();
       
        cancelB.setEnabled(false);
        searchB.setEnabled(true);
       
        if(lookupThread != null){
            lookupThread.interrupt();
        }
    }
   
    /**新建线程处理察看操作*/
    private void lookupAsyn(String acc,String pin){
        final String accN = acc;
        final String pinN = pin;
        
        Runnable runA = new Runnable(){
            public void run(){
                String bal = lookupBalance(accN,pinN);
                setBalanceSaftly(bal);
            }
        };
       
        lookupThread = new Thread(runA);
        lookupThread.start();
    }
   
    /** 安全的显示balance */
    private void setBalanceSaftly(String bal){
        final String balN = bal;
       
        Runnable runA = new Runnable(){
            public void run(){
                try{
                    setBalance(balN);
                }catch(Exception e){
                    e.printStackTrace();
                }
            }
        };
       
        /*放到消息队列,等待处理,返回*/
        SwingUtilities.invokeLater(runA);
    }
   
    /** 显示balance */
    private void setBalance(String bal){
        this.ensureEventThread();
       
        balanceL.setText(bal);
        cancelB.setEnabled(false);
        searchB.setEnabled(true);
    }
   
    /** 其实这两个参数没有用的啦 */   
    private String lookupBalance(String acc,String pin){
        try{
            Thread.sleep(5000);
            return "1,234.5";
        }catch(InterruptedException e){
            return "search canceled";
        }
    }
   
    /** 保证在消息线程中执行 */
    private void ensureEventThread(){
        if(SwingUtilities.isEventDispatchThread() == false)
            throw new RuntimeException("only event thread can do this");
        return;
    }
 
    public static void main(String[] args) {
        BalanceLookUp blp = new BalanceLookUp();
       
        JFrame f = new JFrame("Balance Lookup");
        f.addWindowListener(
                new WindowAdapter(){
                    public void windowClosing(WindowEvent e){
                        System.exit(0);
                    }
                }
        );
        f.setContentPane(blp);
        f.setSize(400,150);
        f.setVisible(true);
    }
}
 
Scrolling Text in a Custom Component
动画效果:滚动字幕
/*
 * Created on 2005-7-18
 *
 * Java Thread Programming - Paul Hyde
 * Copyright ? 1999 Sams Publishing
 * Jonathan Q. Bo 学习笔记
 *
 */
package org.tju.msnrl.jonathan.thread.chapter9;
 
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.font.*;
import java.awt.image.*
;
/*
 * Provides the Java 2D classes
 * for defining and performing operations
 * on objects
 * related to two-dimensional geometry.
 */
/*提供二维几何操作*/
import java.awt.geom.*;
 
/**
 * @author Jonathan Q. Bo from TJU MSNRL
 *
 * Email:jonathan.q.bo@gmail.com
 * Blog:blog.csdn.net/jonathan_q_bo
 *      blog.yesky.net/jonathanundersun
 *
 * Enjoy Life with Sun!
 *
 */
public class ScrollText extends JComponent {
   
    private BufferedImage image;
    private Dimension imageSize;
    public volatile int currOffset;
   
    private Thread localThread;
    private volatile boolean noStopRequest;
   
    public ScrollText(String text){
        currOffset = 0;
        buildImage(text);
       
        this.setMaximumSize(this.imageSize);
        this.setMinimumSize(this.imageSize);
        this.setPreferredSize(this.imageSize);
        this.setSize(this.imageSize);
       
        this.noStopRequest = true;
       
        Runnable runA = new Runnable(){
          public void run(){
              try{
                  runWork();
              }catch(Exception e){
                  e.printStackTrace();
              }
          }
        };
        
        localThread = new Thread(runA,"ScrollText");
        localThread.start();
    }
   
    public void paint(Graphics g){
        g.setClip(0,0,this.imageSize.width,imageSize.height);
        int localOffset = currOffset;
        g.drawImage(this.image,-localOffset,0,this);
        g.drawImage(this.image,imageSize.width - localOffset,0,this);
        g.setColor(Color.BLACK);
        g.drawRect(0,0,imageSize.width - 1,imageSize.height - 1);
    }
   
    public void stopThread(){
        this.noStopRequest = false;
        localThread.interrupt();
    }
   
    public boolean isAlive(){
        return localThread.isAlive();
    }
   
    private void buildImage(String text){
        RenderingHints renderHints = new RenderingHints(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        renderHints.put(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY);
       
        BufferedImage scratchImage = new BufferedImage(1,1,BufferedImage.TYPE_INT_RGB);
        Graphics2D scratchG2 = scratchImage.createGraphics();
        scratchG2.setRenderingHints(renderHints);
       
        Font font = new Font("Serif",Font.BOLD | Font.ITALIC,24);
        FontRenderContext frc = scratchG2.getFontRenderContext();
       
        TextLayout tl = new TextLayout(text,font,frc);
        Rectangle2D textBounds = tl.getBounds();
        int textWidth = (int)Math.ceil(textBounds.getWidth());
        int textHeight = (int)Math.ceil(textBounds.getHeight());
       
        int horizPad = 10;
        int verticPad = 6;
       
        this.imageSize = new Dimension(textWidth + horizPad,textHeight + verticPad);
        this.image = new BufferedImage(imageSize.width,imageSize.height,BufferedImage.TYPE_INT_RGB);
       
        Graphics2D g2 = image.createGraphics();
        g2.setRenderingHints(renderHints);
       
        int baselineOffset = (verticPad / 2) - (int)(textBounds.getY());
        g2.setColor(Color.WHITE);
        g2.fillRect(0,0,imageSize.width,imageSize.height);
        g2.setColor(Color.BLUE);
        tl.draw(g2,0,baselineOffset);
       
        scratchG2.dispose();
        scratchImage.flush();
        g2.dispose();
    }
   
    private void runWork(){
        while(noStopRequest){
            try{
                Thread.sleep(100);               
                currOffset = (currOffset + 1)%this.imageSize.width;               
                repaint();
            }catch(InterruptedException e){
                Thread.currentThread().interrupt();
                System.out.println("interruptedException " + e.getMessage());
            }
        }
    }
 
    public static void main(String[] args) {
        ScrollText st = new ScrollText("Java can do animation");
       
        JPanel p = new JPanel(new FlowLayout());
        p.add(st);
       
        JFrame f = new JFrame("Scroll Text Demo");
        f.setContentPane(p);
        f.setSize(400,200);
        f.setVisible(true);
    }
}
 
Animating a Set of Images
动画效果:一个椭圆的动态缩放
/*
 * Created on 2005-7-19
 *
 * Java Thread Programming - Paul Hyde
 * Copyright ? 1999 Sams Publishing
 * Jonathan Q. Bo 学习笔记
 *
 */
package org.tju.msnrl.jonathan.thread.chapter9;
 
import java.awt.*;
import java.awt.image.*;
import javax.swing.*;
 
/**
 * @author Jonathan Q. Bo from TJU MSNRL
 *
 * Email:jonathan.q.bo@gmail.com
 * Blog:blog.csdn.net/jonathan_q_bo
 *      blog.yesky.net/jonathanundersun
 *
 * Enjoy Life with Sun!
 *
 */
public class SlideShow extends JComponent {
    private BufferedImage[] slide;//轮显的图形
    private Dimension slideSize;//切片大小
    private volatile int currSlide;//当前要显示的切片
   
    private Thread internalThread;//新线程执行更新
    private volatile boolean noStopRequested;//标识线程停止
   
    public SlideShow(){
        currSlide = 0;
       
        /*设置控件大小*/
        slideSize = new Dimension(50,50);
       
        /*在缓存中作图*/
        buildSlides();
       
        /*设置为固定大小*/
        setMinimumSize(slideSize);
        setPreferredSize(slideSize);
        setMaximumSize(slideSize);
        setSize(slideSize);
       
        noStopRequested = true;
        Runnable r = new Runnable(){
            public void run(){
                try{
                    runWork();
                }catch(Exception e){
                    e.printStackTrace();
                }
            }
        };
       
        /*自运行object*/
        internalThread = new Thread(r,"SlidwShow");
        internalThread.start();
    }
   
    public void paint(Graphics g){
        /*绘制当前slide*/
        g.drawImage(slide[currSlide],0,0,this);
    }
   
    private void buildSlides(){
        RenderingHints renderHints = new RenderingHints(
                RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
       
        renderHints.put(
                RenderingHints.KEY_RENDERING,
                RenderingHints.VALUE_RENDER_QUALITY);
       
        slide = new BufferedImage[20];
       
        Color rectColor = new Color(100,160,250);
        Color circleColor = new Color(250,250,150);
 
        /*画出每一个slide*/
        for(int i = 0; i < slide.length; i++){
            slide[i] = new BufferedImage(
                    slideSize.width,
                    slideSize.height,
                    BufferedImage.TYPE_INT_RGB);
           
            /*获得Graphics控制*/
            Graphics2D g2 = slide[i].createGraphics();
           
            /*设置renderhint*/
            g2.setRenderingHints(renderHints);
           
            /*填充矩形*/
            g2.setColor(rectColor);
            g2.fillRect(0,0,slideSize.width,slideSize.height);
           
            /*画椭圆,5到45之间*/
            g2.setColor(circleColor);
            int diameter = 0;
            if(i < (slide.length/2)){
                diameter = 5 + (8*i);
            }else{
                diameter = 5 + (8*(slide.length - i));
            }
            int inset = (slideSize.width - diameter)/2;
            g2.fillOval(inset,inset,diameter,diameter);
           
            /*画矩形外框*/
            g2.setColor(Color.BLACK);
            g2.drawRect(0,0,slideSize.width - 1, slideSize.height - 1);
           
            /*释放资源*/
            g2.dispose();
        }
    }
   
    private void runWork(){
        while(noStopRequested){
            try{
                Thread.sleep(100);
                /*轮换图片*/
                currSlide = (currSlide + 1)%slide.length;
                /*更新显示*/
                repaint();
            }catch(InterruptedException e){
                Thread.currentThread().interrupt();
                e.printStackTrace();
            }
        }
    }
   
    public void stopRequest(){
        noStopRequested = false;
        internalThread.interrupt();
    }
   
    public static void main(String[] args){
        SlideShow ss = new SlideShow();
       
        JPanel p = new JPanel(new FlowLayout());
        p.add(ss);
       
        JFrame f = new JFrame("SlideShow Demo");
        f.setContentPane(p);
        f.setSize(250,150);
        f.setVisible(true);
    }
}
 
Displaying Elapsed Time on a JLabel
 
动画效果:在一个JLabel中显示逝去的时间
/*
 * Created on 2005-7-19
 *
 * Java Thread Programming - Paul Hyde
 * Copyright ? 1999 Sams Publishing
 * Jonathan Q. Bo 学习笔记
 *
 */
package org.tju.msnrl.jonathan.thread.chapter9;
 
import javax.swing.*;
import java.awt.*;
import java.text.*;
import java.lang.reflect.*;
 
/**
 * @author Jonathan Q. Bo from TJU MSNRL
 *
 * Email:jonathan.q.bo@gmail.com
 * Blog:blog.csdn.net/jonathan_q_bo
 *      blog.yesky.net/jonathanundersun
 *
 * Enjoy Life with Sun!
 *
 */
public class DigitalTimer extends JLabel {
    private volatile String timeText;
   
    private Thread internalThread;
    private volatile boolean noStopRequested;
   
    public DigitalTimer(){
        this.setBorder(BorderFactory.createLineBorder(Color.BLACK));
        this.setHorizontalAlignment(SwingConstants.RIGHT);
        this.setFont(new Font("SansSerif",Font.BOLD,16));
       
        /*用来确定控件大小*/
        this.setText("00000.0");
        this.setMinimumSize(getPreferredSize());
        this.setPreferredSize(this.getPreferredSize());
        this.setSize(this.getPreferredSize());
       
        timeText = "0.0";
        this.setText(timeText);
       
        noStopRequested = true;
        Runnable r = new Runnable(){
          public void run(){
              try{
                  runWork();
              }catch(Exception e){
                  e.printStackTrace();
              }
          }
        };
       
        /*自运行object*/
        internalThread = new Thread(r,"DigitalTimer");
        internalThread.start();
    }
   
    private void runWork(){
        long startTime = System.currentTimeMillis();//开始时间
        int tenths = 0;//线程执行的次数
        long normalSleepTime = 100;//正常时间间隔
        long nextSleepTime = 100;//下一次时间间隔
        DecimalFormat fmt = new DecimalFormat("0.0");
       
        /*更新label显示*/
        Runnable updateText = new Runnable(){
                public void run(){
                    setText(timeText);
                }
        };
       
        while(noStopRequested){
            try{
                /*对实时性要求高*/
                Thread.sleep(nextSleepTime);
               
                /*while执行次数加*/
                tenths++;
                long currTime = System.currentTimeMillis();//当前时间
                long elapsedTime = currTime - startTime;//实际已经过去的时间
               
                /*下一次线程休息时间在应该间隔时间上调整,实际逝去时间和应该逝去时间的查值*/
                nextSleepTime = normalSleepTime + ((tenths * 100) - elapsedTime);
                /*如果为负,则设为0*/
                if(nextSleepTime < 0)
                    nextSleepTime = 0;
               
                /*通知显示*/
                timeText = fmt.format(elapsedTime/1000.0);
                SwingUtilities.invokeAndWait(updateText);
            }catch(InterruptedException e1){
                e1.printStackTrace();
                /*停止运行*/
                return;
            }catch(InvocationTargetException e2){
                e2.printStackTrace();
            }
        }
       
    }
   
    public static void main(String[] args){
        DigitalTimer dt = new DigitalTimer();
       
        JPanel p = new JPanel(new FlowLayout());
        p.add(dt);
       
        JFrame f = new JFrame("DigitalTimer Demo");
        f.setContentPane(p);
        f.setSize(250,100);
        f.setVisible(true);
    }
   
}

抱歉!评论已关闭.