简体   繁体   中英

How can I convert a swing JTextField component in to an object of a type that extends it

I have an application using a third party package that has a factory that returns to me JTextField objects that are then added to a GUI. This makes up about 10% of the JTextFields used.

I can't change the third party package but have a requirement to add right click (cut, copy and paste) options in to all ofthe fields.

Now I have a RightClickTextField that extends JTextField and has all the functionality built in to it, this serves to solve my issue for 90% of the application.

However for the 10% that's using the third party package to get JTextFields I cannot think of a solution that will allow me to declare the fields as RightClickTextFields yet use the factory I have to get back the Boxes. I know I cannot cast the result as the objects returned are not of a type that high up in the hierarchy, and a copy constructor won't work since I cannot copy every property being set by the factory, but I don't know of a way to upcast the JTextField in to my type. Is there one?

您可以将右键单击功能放入其自己的实现MouseInputListener接口的类中,而只是将右键单击处理程序的实例添加到相关的JTextField对象中,而不是子类化或尝试转换它吗?

Maybe use the Decorator Pattern . This way you can stop using RightClickTextField at all - start using RightClickTextFieldDecorator and supply it either with your own JTextField s or the ones you get from 3rd party thingy.

Thanks for all the comments. I think the actual answer to my question is:

You can't.

Whilst all of the suggestions are valid, I knew it was possible to do all those things, I just wanted to know if I could do it my way first.

My solution (based on feedback here and my own preference) was to create this class below, and manage and expose a single instance of it from a singleton.

I'd appreciate thoughts on this solution?

import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.HashMap;
import java.util.Map;

import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.text.JTextComponent;

public class CopyPasteTextComponentPopoupMenu extends JPopupMenu implements
    ActionListener {


private JTextComponent lastInvoker;
private JMenuItem cutMenuItem;
private JMenuItem copyMenuItem;
private JMenuItem pasteMenuItem;

private Map<JTextComponent, JTCProperties> managedComponents;

private MouseListener heyListen;

public CopyPasteTextComponentPopoupMenu() {
    super();
    init();
}

public CopyPasteTextComponentPopoupMenu(String label) {
    super(label);
    init();
}

@Override
public void show(Component invoker, int x, int y) {

    JTCProperties props = managedComponents.get(invoker);
    if(props!=null) {
        this.lastInvoker = (JTextComponent) invoker;
        setEnabled(props);
        super.show(invoker, x, y);
    } else {
        this.lastInvoker = null;
    }
}

public void manageTextComponent(JTextComponent jtc, boolean canCut,
        boolean canCopy, boolean canPaste) {

    jtc.addMouseListener(heyListen);

    JTCProperties props = new JTCProperties(canCut,canCopy,canPaste);
    managedComponents.put(jtc,props);

}

public void dispose() {
    for (JTextComponent component : managedComponents.keySet()) {
        component.removeMouseListener(heyListen);
        managedComponents.remove(component);
    }
}

@Override
public void actionPerformed(ActionEvent e) {
    if (lastInvoker != null) {
        if (e.getSource() == cutMenuItem) {
            lastInvoker.cut();
        } else if (e.getSource() == copyMenuItem) {
            lastInvoker.copy();
        } else if (e.getSource() == pasteMenuItem) {
            lastInvoker.paste();
        }
    }
}

private void setEnabled(JTCProperties props) {
    cutMenuItem.setEnabled(props.canCut);
    copyMenuItem.setEnabled(props.canCopy);
    pasteMenuItem.setEnabled(props.canPaste);
}

private void init() {
    this.managedComponents = new HashMap<JTextComponent, JTCProperties>();
    this.setPreferredSize(new Dimension(100, 70));
    cutMenuItem = new JMenuItem("Cut");
    copyMenuItem = new JMenuItem("Copy");
    pasteMenuItem = new JMenuItem("Paste");

    cutMenuItem.addActionListener(this);
    copyMenuItem.addActionListener(this);
    pasteMenuItem.addActionListener(this);

    this.add(cutMenuItem);
    this.add(copyMenuItem);
    this.add(pasteMenuItem);

    heyListen = new MouseAdapter() {
        public void mousePressed(MouseEvent e) {
            if (e.isPopupTrigger()) {
                show(e.getComponent(), e.getX(), e.getY());
            }
        }

        public void mouseReleased(MouseEvent e) {
            if (e.isPopupTrigger()) {
                show(e.getComponent(), e.getX(), e.getY());
            }
        }
    };
}

private class JTCProperties {
    public boolean canCut, canCopy, canPaste;

    public JTCProperties(boolean canCut, boolean canCopy, boolean canPaste) {
        this.canCut = canCut;
        this.canCopy = canCopy;
        this.canPaste = canPaste;
    }
}

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM