HeadFirst设计模式第11章代理模式设计谜题>>ImageProxy类似乎有两个有条件语句控制的状态

问题来自HeadFirst设计模式第11章代理模式468页的设计谜题:
ImageProxy类似乎有两个有条件语句控制的状态,你能否用另一个设计模式清理这样的代码?你要如何重新设计ImageProxy?

思路:
我们可以使用状态模式实现两个状态,分别是ImageLoaded和ImageUnloaded。然后把if语句内的代码放进去各自的状态中。一开始的状态是ImageLoaded,当ImageIcon取回后就转换道ImageLoaded状态。

下面是自己写的一段参考代码

State类
扩展Icon接口,只是单纯的改个接口名字方便理解
Icon是JavaAPI的内置接口,负责处理图片。

1

2

3

4

5

package com.julian.delegatePattern.virtualProxy;

 

import javax.swing.*;

 

public interface State extends Icon {}

ImageUnloaded类
如果图片未加载,调用该类。
先打印一行字“Loading CD Cover, please wait...”提醒用户等待。
接着开启新线程加载图片,并修改ImageProxyState的状态为ImageLoaded。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

package com.julian.delegatePattern.virtualProxy;

 

import javax.swing.*;

import java.awt.*;

import java.net.URL;

 

public class ImageUnloaded implements State {

 

    ImageProxyState imageProxyState;

 

    public ImageUnloaded(ImageProxyState imageProxyState) {

        this.imageProxyState = imageProxyState;

    }

 

 

    @Override

    public void paintIcon(Component c, Graphics g, int x, int y) {

        g.drawString("Loading CD Cover, please wait...",x+ 300, y + 190);

        if (!imageProxyState.isRetrieving()){

            imageProxyState.setRetrieving(true);

            //open a sub-Thread to load photo

            Thread retrievalThread = new Thread(new Runnable() {

                @Override

                public void run() {

                    try{

                        ImageIcon imageIcon = new ImageIcon(imageProxyState.getImageURL(),"CD Cover");

                        imageProxyState.setImageIcon(imageIcon);

                        c.repaint();//repaint(0, 0, 0, width, height);

                    }catch (Exception e){

                        e.printStackTrace();

                    }

                }

            });

            imageProxyState.setRetrievalThread(retrievalThread);

            imageProxyState.startThread();

        }

        imageProxyState.setCurrentState(imageProxyState.imageLoaded);

    }

 

    @Override

    public int getIconWidth() {

        return 800;

    }

 

    @Override

    public int getIconHeight() {

        return 600;

    }

}

ImageLoaded类
如果图片已经加载了,那么调用该类加载图片

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

package com.julian.delegatePattern.virtualProxy;

 

import javax.swing.*;

import java.awt.*;

 

public class ImageLoaded implements State {

    ImageProxyState imageProxyState;

 

    public ImageLoaded(ImageProxyState imageProxyState) {

        this.imageProxyState = imageProxyState;

    }

 

    @Override

    public void paintIcon(Component c, Graphics g, int x, int y) {

        imageProxyState.paintIconByImageIcon(c,g,x,y);

    }

 

    @Override

    public int getIconWidth() {

        return imageProxyState.getIconWidthByImageIcon();

    }

 

    @Override

    public int getIconHeight() {

        return imageProxyState.getIconHeightByImageIcon();

    }

 

    public void setImageIcon(ImageIcon imageIcon) {

        this.imageProxyState.setImageIcon(imageIcon);

    }

}

ImageProxyState
Icon的代理类。有两个State状态 imageLoaded和 imageUnloaded。
当调用它的方法时,会委托给它当前状态处理。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

package com.julian.delegatePattern.virtualProxy;

 

import javax.swing.*;

import java.awt.*;

import java.net.URL;

 

public class ImageProxyState implements Icon {

    State imageLoaded;

    State imageUnloaded;

    State currentState;

 

    ImageIcon imageIcon;

    URL imageURL;

    Thread retrievalThread;

    boolean retrieving = false;

 

    public ImageProxyState(URL imageURL) {

        this.imageURL = imageURL;

        imageLoaded = new ImageLoaded(this);

        imageUnloaded = new ImageUnloaded(this);

        currentState = imageUnloaded;

    }

 

    @Override

    public void paintIcon(Component c, Graphics g, int x, int y) {

        currentState.paintIcon(c,g,x,y);

    }

 

    @Override

    public int getIconWidth() {

        return currentState.getIconWidth();

    }

 

    @Override

    public int getIconHeight() {

        return currentState.getIconHeight();

    }

 

    public boolean isRetrieving() {

        return retrieving;

    }

 

    public void setCurrentState(State currentState) {

        this.currentState = currentState;

    }

 

    public void setImageIcon(ImageIcon imageIcon) {

        this.imageIcon = imageIcon;

    }

 

    public URL getImageURL() {

        return imageURL;

    }

 

    public void setRetrievalThread(Thread retrievalThread) {

        this.retrievalThread = retrievalThread;

    }

 

    public void setRetrieving(boolean retrieving) {

        this.retrieving = retrieving;

    }

 

    public void startThread(){

        retrievalThread.start();

    }

 

    public int getIconWidthByImageIcon(){

        return imageIcon.getIconWidth();

    }

 

    public int getIconHeightByImageIcon(){

        return imageIcon.getIconHeight();

    }

 

    public void paintIconByImageIcon(Component c, Graphics g, int x, int y){

        imageIcon.paintIcon(c,g,x,y);

    }

}

ImageProxyStateTestDrive
建立框架和菜单并测试代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

package com.julian.delegatePattern.virtualProxy;

 

import javax.swing.*;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.net.MalformedURLException;

import java.net.URL;

import java.util.Enumeration;

import java.util.Hashtable;

 

public class ImageProxyStateTestDrive {

    ImageComponent imageComponent;

    JFrame jFrame = new JFrame("CD Cover Viewer");//set the title for the frame

    JMenuBar jMenuBar;

    JMenu jMenu;

    Hashtable cds = new Hashtable();

 

    public static void main(String[] args) throws Exception {

        ImageProxyStateTestDrive imageProxyTestDrive = new ImageProxyStateTestDrive();

    }

 

    public ImageProxyStateTestDrive() throws Exception {

        cds.put("Ballet Pose","https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=1736727202,1355489933&fm=26&gp=0.jpg");

        cds.put("Naruto","https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1062924988,1223376387&fm=26&gp=0.jpg");

        cds.put("Selected Ambient Works, Vol. 2","https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1265870196,2883097596&fm=26&gp=0.jpg");

        cds.put("kimonoBaiDu","https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1598667455000&di=c90ebc533f1a4e1109a18d52ee353ee7&imgtype=0&src=http%3A%2F%2Fhbimg.b0.upaiyun.com%2F454d60b63dbc3858331bbc4bc8757aef329e5b59231b6-bcV3m4_fw658");

 

        URL initialURL = new URL((String)cds.get("Selected Ambient Works, Vol. 2"));

        jMenuBar = new JMenuBar();

        jMenu = new JMenu("fAVORITE cds");//set the title of the menu

        jMenuBar.add(jMenu);

        jFrame.setJMenuBar(jMenuBar);

        for (Enumeration e = cds.keys();e.hasMoreElements();){

            String name = (String)e.nextElement();

            JMenuItem jMenuItem = new JMenuItem(name);

            jMenu.add(jMenuItem);

            jMenuItem.addActionListener(new ActionListener() {

                @Override

                public void actionPerformed(ActionEvent e) {

                    imageComponent.setIcon(new ImageProxyState(getCDUrl(e.getActionCommand())));

                    jFrame.repaint();

                }

            });

        }

 

        //建立框架和菜单build frame and menu

        Icon icon = new ImageProxyState(initialURL);

        imageComponent = new ImageComponent(icon);

        jFrame.getContentPane().add(imageComponent);

        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        jFrame.setSize(1000,800);

        jFrame.setVisible(true);

        jFrame.setLocation(450,100);

    }

 

    URL getCDUrl(String name){

        try {

            return new URL((String)cds.get(name));

        catch (MalformedURLException e) {

            e.printStackTrace();

            return null;

        }

    }

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值