2014-09-18 238 views
4

我试图保持我的JTable的紧密和安全,只能通过isCellEditable()编辑可编辑列。但是,我的客户坚持要双击一个单元格,以便他们可以复制它的内容,即使它是只读的。我可以让这个单元格可编辑,并且不会对setValueAt()中的任何编辑进行任何操作(因此,当编辑器退出时,它将恢复为原始值)。但我不希望这个应用程序感觉如此自由。是否有一种简单有效的方法可以使JTextField用作单元编辑器,以允许在编辑器中选择文本,但不可编辑?使JTable单元格编辑器值可选,但不可编辑?

我在下面的JTable上试过这个覆盖,但我不认为我在寻找正确的“instanceof”对象。

@Override 
public TableCellEditor getDefaultEditor(Class<?> columnClass) { 
    if (super.getDefaultEditor(columnClass) instanceof JTextField) { 
     JTextField jTextField = new JTextField(); 
     jTextField.setEditable(false); 
     return (TableCellEditor) jTextField; 
    } 
    if (columnClass == null) { 
     return null; 
    } 
    else { 
     Object editor = defaultEditorsByColumnClass.get(columnClass); 
     if (editor != null) { 
      return (TableCellEditor)editor; 
     } 
     else { 
      return getDefaultEditor(columnClass.getSuperclass()); 
     } 
    } 
} 
+0

也许你应该检查[CellEditor的#stopCellEditing(http://docs.oracle.com/javase/7/docs/api/javax/swing/CellEditor.html#stopCellEditing%28%29) – Frakcool 2014-09-18 16:19:21

+0

没有使用它们,但你也可以检查[CellEditor#cancelCellEditing()](http://docs.oracle.com/javase/7/docs/api/javax/swing/CellEditor.html#cancelCellEditing()) – Frakcool 2014-09-18 16:24:25

回答

8

然而,我的客户都坚持认为他们想双击一个细胞,使他们可以复制它的内容,即使它是只读的。

创建一个使用只读文本字段的自定义编辑:

JTextField tf = new JTextField(); 
tf.setEditable(false); 
DefaultCellEditor editor = new DefaultCellEditor(tf); 
table.setDefaultEditor(Object.class, editor); 

使用键盘或鼠标选择要复制的文本。然后,您将使用Ctrl + C复制选定的文本。或者你甚至可以添加一个弹出菜单到文本字段并添加一个Copy菜单项。

+0

希望我能接受答案。虽然下面的答案是一个非常原始的解决方案,但这在技术上是我所要求的,尽管我会尝试双击解决方案。 – tmn 2014-09-19 16:08:25

+0

*希望我可以接受这两个答案** – tmn 2014-09-19 17:13:50

6

“不过,我的客户都坚持认为他们想双击一个细胞,使他们能够复制它的内容,哪怕是只读”

你可以只使用一个MouseListener,并双击,以编程方式将单元格的内容复制到剪贴板。喜欢的东西:

table.addMouseListener(new MouseAdapter() { 
    @Override 
    public void mouseClicked(MouseEvent e) { 
     if (e.getClickCount() == 2) { 
      System.out.println("double click"); 
      Point p = e.getPoint(); 
      int row = table.rowAtPoint(p); 
      int col = table.columnAtPoint(p); 
      Object value = table.getValueAt(row, col); 
      StringSelection stringSelection = new StringSelection(value.toString()); 
      Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); 
      clipboard.setContents(stringSelection, ProgrammaticCopyDemo.this); 
     } 
    } 
}); 

这里有一个完整的例子:

enter image description here

import java.awt.*; 
import java.awt.datatransfer.*; 
import java.awt.event.*; 
import java.io.IOException; 
import javax.swing.*; 
import javax.swing.table.DefaultTableModel; 
import javax.swing.text.JTextComponent; 

public class ProgrammaticCopyDemo implements ClipboardOwner { 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       new ProgrammaticCopyDemo(); 
      } 
     }); 
    } 

    public ProgrammaticCopyDemo() { 
     JTable table = getTable(); 
     addCopylistenerToTable(table); 

     JTextArea area = new JTextArea(3, 20); 
     addPasteListenerToArea(area); 

     JFrame frame = new JFrame(); 
     frame.add(new JScrollPane(table)); 
     frame.add(area, BorderLayout.PAGE_END); 
     frame.pack(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    private void addPasteListenerToArea(final JTextComponent component) { 
     JPopupMenu menu = new JPopupMenu(); 
     menu.add(new AbstractAction("Paste") { 
      public void actionPerformed(ActionEvent e) { 
       String copiedContent = getClipboardContents(); 
       int caretPosition = component.getCaretPosition(); 
       try { 
        component.getDocument().insertString(caretPosition, copiedContent, null); 
       } catch (Exception ex) { 
        ex.printStackTrace(); 
       } 

      } 

      private String getClipboardContents() { 
       String result = ""; 
       Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); 
       Transferable contents = clipboard.getContents(null); 
       boolean hasTransferableText 
         = (contents != null) 
         && contents.isDataFlavorSupported(DataFlavor.stringFlavor); 
       if (hasTransferableText) { 
        try { 
         result = (String) contents.getTransferData(DataFlavor.stringFlavor); 
        } catch (UnsupportedFlavorException | IOException ex) { 
         System.out.println(ex); 
         ex.printStackTrace(); 
        } 
       } 
       return result; 
      } 
     }); 
     component.setComponentPopupMenu(menu); 
    } 

    private void addCopylistenerToTable(final JTable table) { 
     table.addMouseListener(new MouseAdapter() { 
      @Override 
      public void mouseClicked(MouseEvent e) { 
       if (e.getClickCount() == 2) { 
        System.out.println("double click"); 
        Point p = e.getPoint(); 
        int row = table.rowAtPoint(p); 
        int col = table.columnAtPoint(p); 
        Object value = table.getValueAt(row, col); 
        StringSelection stringSelection = new StringSelection(value.toString()); 
        Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); 
        clipboard.setContents(stringSelection, ProgrammaticCopyDemo.this); 
       } 
      } 
     }); 
    } 

    private JTable getTable() { 
     String[][] data = { 
      {"Hello", "World"}, 
      {"Stack", "Overflow"}, 
      {"Foo", "Bar"} 
     }; 
     String[] cols = {"Col", "Col"}; 
     DefaultTableModel model = new DefaultTableModel(data, cols) { 
      @Override 
      public boolean isCellEditable(int row, int col) { 
       return false; 
      } 
     }; 
     return new JTable(model) { 
      @Override 
      public Dimension getPreferredScrollableViewportSize() { 
       return getPreferredSize(); 
      } 
     }; 
    } 

    @Override 
    public void lostOwnership(Clipboard clipboard, Transferable contents) { 
    } 
} 
+0

我只是在寻找为“预制”功能,但从来没有想过这个。其实我也从这个答案中了解到复制到剪贴板的事情。 :) +1 – Frakcool 2014-09-18 17:20:14

+0

@Frakcool有时候魔法功能会躲过我。没有真正去寻找一个。谁知道也许有_is_一个:-) – 2014-09-18 17:26:36

+0

我在学校,现在不能编程,所以我只是尽我所能寻找这个神奇的功能。我将学习更多关于swing的知识,以便我可以创建类似于你的函数:-) – Frakcool 2014-09-18 17:30:01

相关问题