栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

自定义Java Swing组件模型,UIDelegate,组件格式

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

自定义Java Swing组件模型,UIDelegate,组件格式

好的,那是对我不使用的API部分的一次有趣的冒险:首先,通读如何编写自定义Swing组件及其相关链接,这将为您提供基础知识,以了解什么是即将发生…

模型

介面

就个人而言,我总是从界面开始,界面使生活变得更好,并且它为您提供了更大的灵活性。现在,您应该从哪个模型扩展(根据您的要求)…?

好吧,我能找到的最佳选择是

BoundedRangeModel
,它也被
JSlider

使用…实际上,这意味着我不仅可以将此模型传递给视图,而且还可以传递给,而
JSlider
无需任何额外的工作,就可以让滑块更改图像!! 双赢

import java.awt.Dimension;import java.awt.Image;import javax.swing.BoundedRangeModel;public interface ZoomModel extends BoundedRangeModel {    public Image getImage();    public Dimension getScaledSize();}

摘要

接下来,我想制作一个抽象版本,这是我放置“通用”功能的地方,对于大多数实现来说,它可能是相同的,在这种情况下,可能不需要,但是我有点像这样。 。

import java.awt.Dimension;import java.awt.Image;import javax.swing.DefaultBoundedRangeModel;public abstract class AbstractZoomModel extends DefaultBoundedRangeModel implements ZoomModel {    public AbstractZoomModel() {        super(100, 0, 0, 200);    }    @Override    public Dimension getScaledSize() {        Dimension size = new Dimension(0, 0);        Image image = getImage();        if (image != null) { double scale = getValue() / 100d; size.width = (int) Math.round(image.getWidth(null) * scale); size.height = (int) Math.round(image.getHeight(null) * scale);        }        return size;    }}

因此,您可以在这里看到,我定义了一些基本属性,初始缩放级别为

100
,最大级别为
200
,最小级别为
0
,此外,我还实现了
getScaledSize
,使用了一点,使生活更轻松…

默认…

现在,因为我们喜欢,所以我们提供了该模型的“默认”实现。这是非常基本的,因为它所做的全部工作都是引用图像…

import java.awt.Image;public class DefaultZoomModel extends AbstractZoomModel {    Image image;    public DefaultZoomModel(Image image) {        this.image = image;    }    @Override    public Image getImage() {        return image;    }}

您可以创建从

URL
例如下载图像的实现…

风景

好的,这是实际的组件本身,已添加到您的UI中。它包含构造和准备UI委托以及管理模型所需的基本功能。这里感兴趣的关键是使用属性更改支持来提供对模型更改的通知,这很重要,如您所见…

import java.awt.Color;import java.awt.Dimension;import javax.swing.JComponent;import javax.swing.UIManager;public class ZoomComponent extends JComponent {    private static final String uiClassID = "ZoomComponentUI";    private ZoomModel model;    public ZoomComponent() {        setBackground(Color.black);        setFocusable(true);        updateUI();    }    public void setModel(ZoomModel newModel) {        if (model != newModel) { ZoomModel old = model; this.model = newModel; firePropertyChange("model", old, newModel);        }    }    public ZoomModel getModel() {        return model;    }    @Override    public Dimension getPreferredSize() {        ZoomModel model = getModel();        Dimension size = new Dimension(100, 100);        if (model != null) { size = model.getScaledSize();        }        return size;    }    public void setUI(BasicZoomUI ui) {        super.setUI(ui);    }    @Override    public void updateUI() {        if (UIManager.get(getUIClassID()) != null) { ZoomUI ui = (ZoomUI) UIManager.getUI(this); setUI(ui);        } else { setUI(new BasicZoomUI());        }    }    public BasicZoomUI getUI() {        return (BasicZoomUI) ui;    }    @Override    public String getUIClassID() {        return uiClassID;    }}

UI委托

现在还有其他有趣的东西…如果遵循标准约定,通常您会提供

abstract
UI委托的概念,例如…

import javax.swing.plaf.ComponentUI;public abstract class ZoomUI extends ComponentUI {       }

由此,其他代表将会增长。

基本UI委托

常规通常会建议您提供一个“基本”实施,完成许多繁重的工作,但允许其他实施有机会跳到那里进行更改

import java.awt.Dimension;import java.awt.Graphics;import java.awt.Image;import java.awt.event.ActionEvent;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;import java.awt.event.MouseWheelEvent;import java.beans.PropertyChangeEvent;import java.beans.PropertyChangeListener;import javax.swing.AbstractAction;import javax.swing.Action;import javax.swing.ActionMap;import javax.swing.InputMap;import javax.swing.JComponent;import javax.swing.KeyStroke;import javax.swing.event.ChangeEvent;import javax.swing.event.ChangeListener;import javax.swing.plaf.ComponentUI;public class BasicZoomUI extends ZoomUI {    private ZoomComponent zoomComponent;    private MouseAdapter mouseHandler;    private ChangeListener changeHandler;    private Action zoomIn;    private Action zoomOut;    private PropertyChangeListener propertyChangeHandler;    protected ChangeListener getChangeHandler() {        if (changeHandler == null) { changeHandler = new ChangeHandler();        }        return changeHandler;    }    protected void installMouseListener() {        mouseHandler = new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) {     zoomComponent.requestFocusInWindow(); } @Override public void mouseWheelMoved(MouseWheelEvent e) {     int amount = e.getWheelRotation();     ZoomModel model = zoomComponent.getModel();     if (model != null) {         int value = model.getValue();         model.setValue(value + amount);     } }        };        zoomComponent.addMouseListener(mouseHandler);        zoomComponent.addMouseWheelListener(mouseHandler);    }    protected void installModelPropertyChangeListener() {        propertyChangeHandler = new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) {     ZoomModel old = (ZoomModel) evt.getOldValue();     if (old != null) {         old.removeChangeListener(getChangeHandler());     }     ZoomModel newValue = (ZoomModel) evt.getNewValue();     if (newValue != null) {         newValue.addChangeListener(getChangeHandler());     } }        };        zoomComponent.addPropertyChangeListener("model", propertyChangeHandler);    }    protected void installKeyBindings() {        zoomIn = new ZoomInAction();        zoomOut = new ZoomOutAction();        InputMap inputMap = zoomComponent.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ADD, 0), "zoomIn");        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_SUBTRACT, 0), "zoomOut");        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_PLUS, 0), "zoomIn");        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, 0), "zoomOut");        ActionMap actionMap = zoomComponent.getActionMap();        actionMap.put("zoomIn", zoomIn);        actionMap.put("zoomOut", zoomOut);    }    protected void installModelChangeListener() {        ZoomModel model = getModel();        if (model != null) { model.addChangeListener(getChangeHandler());        }    }    @Override    public void installUI(JComponent c) {        zoomComponent = (ZoomComponent) c;        installMouseListener();        installModelPropertyChangeListener();        installKeyBindings();        installModelChangeListener();    }    protected void uninstallModelChangeListener() {        getModel().removeChangeListener(getChangeHandler());    }    protected void uninstallKeyBindings() {        InputMap inputMap = zoomComponent.getInputMap(JComponent.WHEN_FOCUSED);        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ADD, 0), "donothing");        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_SUBTRACT, 0), "donothing");        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_PLUS, 0), "donothing");        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, 0), "donothing");        AbstractAction blank = new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { }        };        ActionMap actionMap = zoomComponent.getActionMap();        actionMap.put("zoomIn", blank);        actionMap.put("zoomOut", blank);    }    protected void uninstallModelPropertyChangeListener() {        zoomComponent.removePropertyChangeListener(propertyChangeHandler);        propertyChangeHandler = null;    }    protected void uninstallMouseListener() {        zoomComponent.removeMouseWheelListener(mouseHandler);        mouseHandler = null;    }    @Override    public void uninstallUI(JComponent c) {        uninstallModelChangeListener();        uninstallModelPropertyChangeListener();        uninstallKeyBindings();        uninstallMouseListener();        mouseHandler = null;        zoomComponent = null;    }    @Override    public void paint(Graphics g, JComponent c) {        super.paint(g, c);        paintImage(g);    }    protected void paintImage(Graphics g) {        if (zoomComponent != null) { ZoomModel model = zoomComponent.getModel(); Image image = model.getImage(); Dimension size = model.getScaledSize(); int x = (zoomComponent.getWidth() - size.width) / 2; int y = (zoomComponent.getHeight() - size.height) / 2; g.drawImage(image, x, y, size.width, size.height, zoomComponent);        }    }    public static ComponentUI createUI(JComponent c) {        return new BasicZoomUI();    }    protected ZoomModel getModel() {        return zoomComponent == null ? null : zoomComponent.getModel();    }    protected class ChangeHandler implements ChangeListener {        @Override        public void stateChanged(ChangeEvent e) { zoomComponent.revalidate(); zoomComponent.repaint();        }    }    protected class ZoomAction extends AbstractAction {        private int delta;        public ZoomAction(int delta) { this.delta = delta;        }        @Override        public void actionPerformed(ActionEvent e) { ZoomModel model = getModel(); if (model != null) {     model.setValue(model.getValue() + delta); }        }    }    protected class ZoomOutAction extends ZoomAction {        public ZoomOutAction() { super(-5);        }    }    protected class ZoomInAction extends ZoomAction {        public ZoomInAction() { super(5);        }    }}

From here you could go and devise platform specific implementations, but I’ve
decided to stick with the basic delegate…

Putting it all together

If that wasn’t enough, before you can use any of it, you must install the
delegate…

UIManager.getDefaults().put("ZoomComponentUI", "your.awesome.package.name.BasicZoomUI");

nb: Change

your.awesome.package.name
to reflect your actual package name…

Runnable Example

 import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.Graphics2D; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.Jframe; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSlider; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; public class TestZoom100 {      public static void main(String[] args) {new TestZoom100();      }      public TestZoom100() {EventQueue.invokeLater(new Runnable() {     @Override     public void run() {          try {    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());          } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {    ex.printStackTrace();          }          UIManager.getDefaults().put("ZoomComponentUI", "your.awesome.package.name.BasicZoomUI");          try {    DefaultZoomModel model = new DefaultZoomModel(ImageIO.read(new File("/your/awesome/image.jpg")));    model.setValue(50);    ZoomComponent zoomComp = new ZoomComponent();    zoomComp.setModel(model);    JSlider slider = new JSlider(model);    Jframe frame = new Jframe("Testing");    frame.setDefaultCloseOperation(Jframe.EXIT_ON_CLOSE);    frame.add(new JScrollPane(zoomComp));    frame.add(slider, BorderLayout.SOUTH);    frame.pack();    frame.setLocationRelativeTo(null);    frame.setVisible(true);          } catch (IOException exp) {    exp.printStackTrace();          }     }});      } }

Don’t forget to change the package name for the

BasicZoomUI
to the package
name you have it stored in and actually specify a image file ;)



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/569522.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号