2012-09-07 87 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; 
    } 
} 

}