2012-09-07 207 views
1

我有一个使用第三方包的应用程序,该应用程序具有返回给我的工厂的JTextField对象,然后将这些对象添加到GUI中。这占用了大约10%的JTextFields。如何将JTextField组件转换为扩展类型的对象

我无法更改第三方软件包,但需要在所有字段中添加右键单击(剪切,复制和粘贴)选项。

现在我有一个扩展了JTextField的RightClickTextField,并具有内置的所有功能,这可以解决90%的应用程序中的问题。

但是,对于使用第三方包获取JTextFields的10%,我想不出一个解决方案,该解决方案将允许我将字段声明为RightClickTextFields,但仍然使用工厂,我必须取回Boxes。我知道我不能转换结果,因为返回的对象不是在层次结构中高的类型,并且复制构造函数不起作用,因为我无法复制工厂设置的每个属性,但我不知道一种将JTextField转换为我的类型的方法。有一个吗?

+3

我不知道我完全搞定你的问题,但不能使用组成,而不是继承?我不想让RightClickTextField扩展JTextfield,而是尝试将RightClickTextField与JTextField成员一起使用。 –

+0

听起来就像你真的明白这一点,我曾想过这样做,但我并不想拥有所有各种属性和设置的复合材料,增加了我的内存占用空间。我想要一种将JTextField对象转换为RightClickTextFields的方法,并且想知道是否有一些巧妙的技巧可以用来做到这一点。如果没有,我可能只需添加一个Util类,它将右键单击添加到JTextField。但我不想这样做。 – Link19

+0

正如@GuillaumePolet所建议的那样,Swing在几个地方使用[delegation](http://en.wikipedia.org/wiki/Delegation_pattern),例如, 'DefaultCellEditor'。 – trashgod

回答

2

而不是子类,或者试图施放它,你可以把你的右键功能集成到自己的类,它实现MouseInputListener interface,并简单地添加右键单击处理程序的实例所讨论的JTextField中的对象?

+0

我知道还有其他的解决方案,但我希望通过这种方式来保持整个代码库的一致性,如果这是不可能的,那么我将不得不重新考虑。但我想知道是否有人首先有任何真正聪明的想法。 – Link19

+0

我想这是一个问题,你是否可以更改应用程序布局。如果你可以从第三方包得到一个'JTextField'并且创建一个'RightClickTextFields'的构造函数来接受一个'JTextField'(来自第三方包)并且给你一个'RightClickTextField',那么这会工作,但是你还必须用新的'RightClickTextField'替换应用布局中的'JTextField'。我不知道如何将一个对象从一种类型转换为另一种类型,除非它们共享适当的类别血统。 – jefflunt

+0

换句话说,除非它实际上是该子类型的一个实例,否则不能将一种类型的对象转换为其子类型。我所知道的唯一方法是创建一个工厂或构造函数,它接受父类型的一个实例并使用它来创建子类型的实例,并将属性复制过来。 – jefflunt

1

也许使用Decorator Pattern。通过这种方式,您可以完全停止使用RightClickTextField - 开始使用RightClickTextFieldDecorator并将其提供给您自己的JTextField或您从第三方提供的东西。

+0

我不认为装饰者模式可以在这种情况下工作。如果我正确理解模式,装饰器将需要扩展JTextField,但是用存根调用传入对象中的等效方法的所有方法? 我认为最好的方式是通过静态方法将新的JTextFields传递给某个地方,从而为其添加功能。只是这种方法不会那么干净。我的RightClickTextField实现了所需的监听器,因此可以轻松地调用剪切/复制/粘贴功能。它很好,很干净。 – Link19

0

感谢您的所有意见。我认为我的问题的实际答案是:

你不能。

虽然所有的建议都是有效的,但我知道可以做所有这些事情,我只是想知道我是否可以先按照自己的方式行事。

我的解决方案(基于这里的反馈和我自己的喜好)是在下面创建这个类,并管理和公开它的单个实例。

我很欣赏这个解决方案的想法?

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; 
    } 
} 

}

相关问题