我需要爲我的JTree使用自定義單元格渲染器來在每個單元格上添加一些JLabel。然後允許用戶點擊這些標籤,而無需先選擇單元格。TreeCellEditor:即使ShouldSelectCell返回false,也必須選擇要編輯的單元格
所以,我創建了一個Renderer,它返回一個包含DefaultTreeCellRenderer和2個JLabel的JPanel。
public class TreeNodeRenderer extends DefaultTreeCellRenderer implements TreeCellRenderer
{
private JPanel panel1 = new JPanel();
private JLabel delete = new JLabel("");
private JLabel upload = new JLabel("");
public Component getTreeCellRendererComponent(JTree tree,
Object value,
boolean selected, boolean expanded, boolean leaf, int row,
boolean hasFocus)
{
//
// DELETE label
//
delete.setName("delete");
delete.setIcon(new ImageIcon("Data/trash.png"));
//
// UPLOAD label
//
upload.setName("upload");
upload.setIcon(new ImageIcon("Data/app_up.png"));
DefaultTreeCellRenderer defaultRenderer = new DefaultTreeCellRenderer();
Color backgroundSelectionColor = defaultRenderer.getBackgroundSelectionColor();
Color backgroundNonSelectionColor = defaultRenderer.getBackgroundNonSelectionColor();
if(selected)
panel1.setBackground(backgroundSelectionColor);
else
panel1.setBackground(backgroundNonSelectionColor);
component = (DefaultTreeCellRenderer) super.getTreeCellRendererComponent(tree,
value, selected, expanded, leaf, row, hasFocus);
panel1.add(component);
panel1.add(delete);
panel1.add(upload);
return panel1;
}
}
然後,我創建了編輯器,允許用戶點擊這些標籤感謝MouseListener。除了用戶必須在點擊標籤之前選擇單元格之外,一切運行良好。 我試圖用「ShouldSelectCell」方法返回「false」,但它不起作用。
有人知道爲什麼嗎?
這裏編輯:
public class TreeNodeEditor extends AbstractCellEditor implements TreeCellEditor
{
private TreeNodeRenderer renderer;
public TreeNodeEditor(TreeNodeRenderer treeRenderer)
{
this.renderer = treeRenderer;
//change the cursor when it's over a label renderer.getDeleteButton().setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
renderer.getUploadButton().setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); renderer.getDownloadButton().setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
//add labels' mouse listeners
addLabelMouseListener(renderer.getDeleteButton());
addLabelMouseListener(renderer.getUploadButton());
}
public Component getTreeCellEditorComponent(JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row)
{
...
return renderer.getTreeCellRendererComponent(
tree, value, isSelected,
expanded, leaf, row, true);
}
public boolean isCellEditable(EventObject anEvent)
{
return true;
}
public boolean shouldSelectCell(EventObject anEvent)
{
return false;
}
public boolean stopCellEditing()
{
return super.stopCellEditing();
}
public void cancelCellEditing()
{
super.cancelCellEditing();
}
public void addCellEditorListener(CellEditorListener l)
{
super.addCellEditorListener(l);
}
public void removeCellEditorListener(CellEditorListener l)
{
super.removeCellEditorListener(l);
}
public Object getCellEditorValue()
{
return null;
}
}
編輯 - 在這裏一個SSCCE:
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.EventObject;
import javax.swing.AbstractCellEditor;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTree;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.CellEditorListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeCellEditor;
import javax.swing.tree.TreeCellRenderer;
public class EditJTreeCell extends JFrame
{
/**
*
*/
private static final long serialVersionUID = 4745146614430249610L;
private JTree tree;
private DefaultTreeModel treeModel;
private DefaultMutableTreeNode root;
public EditJTreeCell()
{
super("Sample");
root = new DefaultMutableTreeNode("Root folder");
treeModel = new DefaultTreeModel(root);
tree = new JTree(treeModel);
TreeNodeRenderer renderer = new TreeNodeRenderer();
tree.setCellRenderer(renderer);
tree.setCellEditor(new TreeNodeEditor());
tree.setEditable(true);
//tree creation
DefaultMutableTreeNode folder = new DefaultMutableTreeNode("folder1");
DefaultMutableTreeNode file = new DefaultMutableTreeNode("file1");
folder.add(file);
file = new DefaultMutableTreeNode("file2");
folder.add(file);
root.add(folder);
folder = new DefaultMutableTreeNode("folder2");
file = new DefaultMutableTreeNode("file1");
folder.add(file);
file = new DefaultMutableTreeNode("file2");
folder.add(file);
file = new DefaultMutableTreeNode("file3");
folder.add(file);
root.add(folder);
this.setSize(400, 800);
this.add(tree);
this.setVisible(true);
}
public static void main(String[] args)
{
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
new EditJTreeCell();
}
}
class TreeNodeRenderer extends DefaultTreeCellRenderer implements TreeCellRenderer
{
/**
*
*/
private static final long serialVersionUID = 1L;
private JPanel panel1 = new JPanel();
private JLabel delete = new JLabel("DELETE");
private JLabel upload = new JLabel("UPLOAD");
public Component getTreeCellRendererComponent(JTree tree, Object value,
boolean selected, boolean expanded, boolean leaf, int row,
boolean hasFocus)
{
//
// DELETE label
//
delete.setName("delete");
delete.setIcon(new ImageIcon("trash.png"));
//addLabelMouseListener(delete);
//
// UPLOAD label
//
upload.setName("upload");
upload.setIcon(new ImageIcon("app_up.png"));
//addLabelMouseListener(upload);
DefaultTreeCellRenderer defaultRenderer = new DefaultTreeCellRenderer();
Color backgroundSelectionColor = defaultRenderer.getBackgroundSelectionColor();
Color backgroundNonSelectionColor = defaultRenderer.getBackgroundNonSelectionColor();
DefaultTreeCellRenderer component = (DefaultTreeCellRenderer) super.getTreeCellRendererComponent(tree,
value, selected, expanded, leaf, row, hasFocus);
if(selected)
{
panel1.setBackground(backgroundSelectionColor);
}
else
{
panel1.setBackground(backgroundNonSelectionColor);
}
panel1.add(component);
panel1.add(delete);
panel1.add(upload);
return panel1;
}
}
class TreeNodeEditor extends AbstractCellEditor implements TreeCellEditor
{
/**
*
*/
private static final long serialVersionUID = 1L;
private JLabel button1;
private JLabel button2;
private JPanel panel1;
private DefaultMutableTreeNode node = null;
private DefaultTreeCellRenderer defaultRenderer;
public TreeNodeEditor()
{
super();
panel1 = new JPanel();
defaultRenderer = new DefaultTreeCellRenderer();
button1 = new JLabel("DELETE");
button1.setOpaque(true);
button1.setIcon(new ImageIcon("trash.png"));
button1.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
button1.addMouseListener(new MouseListener()
{
public void mouseClicked(MouseEvent arg0) {
System.out.println("Delete clicked");
}
public void mouseEntered(MouseEvent arg0) {}
public void mouseExited(MouseEvent arg0) {}
public void mousePressed(MouseEvent arg0) {}
public void mouseReleased(MouseEvent arg0) {}
});
button2 = new JLabel("UPLOAD");
button2.setOpaque(true);
button2.setIcon(new ImageIcon("app_up.png"));
button2.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
button2.addMouseListener(new MouseListener()
{
public void mouseClicked(MouseEvent arg0) {
System.out.println("Upload clicked");
}
public void mouseEntered(MouseEvent arg0) {}
public void mouseExited(MouseEvent arg0) {}
public void mousePressed(MouseEvent arg0) {}
public void mouseReleased(MouseEvent arg0) {}
});
}
public Component getTreeCellEditorComponent(JTree tree, Object value,
boolean isSelected, boolean expanded, boolean leaf, int row)
{
//in order to do some actions on a node
if(value instanceof DefaultMutableTreeNode)
{
node = (DefaultMutableTreeNode) value;
}
defaultRenderer.getTreeCellRendererComponent(tree,
value, isSelected, expanded, leaf, row, true);
panel1.add(defaultRenderer);
panel1.add(button1);
panel1.add(button2);
return panel1;
}
public boolean isCellEditable(EventObject anEvent)
{
return true;
}
public boolean shouldSelectCell(EventObject anEvent)
{
return false;
}
public boolean stopCellEditing()
{
return super.stopCellEditing();
}
public void cancelCellEditing()
{
super.cancelCellEditing();
}
public void addCellEditorListener(CellEditorListener l)
{
super.addCellEditorListener(l);
}
public void removeCellEditorListener(CellEditorListener l)
{
super.removeCellEditorListener(l);
}
public Object getCellEditorValue()
{
return null;
}
}
不回答你的問題(或者它是,沒有檢查),只是要小心:你不能使用同一個組件實例來渲染和編輯 – kleopatra
時間sscce來演示究竟是什麼問題 – kleopatra
謝謝你的建議。現在,我不使用同一個組件的實例進行渲染和編輯。但問題仍然存在。我編輯了我的帖子以添加sscce。 我正在考慮在光標位於節點(使用myTree.getRowAtPoint(x,y))時模擬鍵F2(版本鍵)。但是,如果我可以,我寧願避免它。 – bldcoco