我需要为JTree使用自定义单元格渲染器,以便在每个单元格上添加一些JLabel。然后允许用户单击这些标签,而无需先选择单元格。
因此,我创建了一个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;
}
}
在mouseEnter上开始编辑是有效的解决方案:-)
另一方面,您的编辑器不是有效的实现:如果编辑由于内部事件而终止(例如,点击任意按钮),则无法通知其监听器。以下是如何实现两者的示例目标并有效实施
一些评论:
在代码中:
static class TreeNodeEditor extends AbstractCellEditor implements TreeCellEditor {
private static final long serialVersionUID = 1L;
private JButton button1;
private JButton button2;
private JPanel panel1;
// JW: do not modify the node inside the editor
// private DefaultMutableTreeNode node = null;
private DefaultTreeCellRenderer defaultRenderer;
private Object editorValue;
public TreeNodeEditor() {
super();
panel1 = new JPanel();
defaultRenderer = new DefaultTreeCellRenderer();
button1 = new JButton("DELETE");
button1.setOpaque(true);
button1.setIcon(new ImageIcon("trash.png"));
button1.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
button2 = new JButton("UPLOAD");
button2.setOpaque(true);
button2.setIcon(new ImageIcon("app_up.png"));
button2.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
button2.setAction(createAction("upload", "UPLOAD"));
button1.setAction(createAction("delete", "DELETE"));
panel1.add(defaultRenderer);
panel1.add(button1);
panel1.add(button2);
}
private Action createAction(final String actionCommand, String display) {
Action action = new AbstractAction(display) {
@Override
public void actionPerformed(ActionEvent e) {
stopEditing(actionCommand);
}
};
return action;
}
/**
* @param actionCommand
*/
protected void stopEditing(String actionCommand) {
editorValue = actionCommand;
stopCellEditing();
}
@Override
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);
return panel1;
}
/**
*
*/
private void reset() {
editorValue = null;
}
/**
* At this point in time the component is added to the tree (not documented!) but
* tree's internal cleanup might not yet be ready
*/
@Override
public boolean shouldSelectCell(EventObject anEvent) {
reset();
if (anEvent instanceof MouseEvent) {
redirect((MouseEvent) anEvent);
}
return false;
}
private void redirect(final MouseEvent anEvent) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
MouseEvent ev = SwingUtilities.convertMouseEvent(anEvent.getComponent(), anEvent, panel1);
panel1.dispatchEvent(ev);
}
});
}
@Override
public Object getCellEditorValue() {
return editorValue;
}
}
问题内容: 我当前正在编写一个脚本,该脚本必须检查所有指定的文件夹是否实际存在。我发现我必须将os.path.isdir()与绝对路径一起使用。 我有以下目录结构: 当我打开op我的python命令行并尝试文件夹是否确实存在时,我得到以下信息: 这很奇怪,因为当我将这些路径复制并粘贴到Windows资源管理器中时,我可以毫无问题地访问它们。我检查了权限,所有文件夹都具有相同的权限。有人知道我在做什
http://prntscr.com/9jhrwa“GUI看起来怎么样” 公共类Okno1扩展javax.swing.jFrame{ 在这里,我显示了按下这个按钮时的jScrollPanel,我还显示了如果我想在显示的JList中获得选定元素的索引时必须按下的按钮 在这里,我按下一个按钮,它应该为我提供所选项的索引,但它一直给我-1,无论JList上的项是否被选中都无关紧要
这是我的代码: 因为我使用POM设计模式,所以我为此创建了一种方法: 这是超文本标记语言标签: 我的问题是,即使存在WebElement,isDisplayed()也返回false。
问题内容: 我正在尝试使用getElementById()获取元素,但是即使元素存在,它也会返回null。我究竟做错了什么? 问题答案: 您必须将其放在一个 事件中。脚本执行时尚未到达DOM 。
问题内容: 我有以下代码: 注释行无法编译。 为什么即使协议要求,我也必须强制将协议类型对象强制转换为符合该对象类型的对象? 问题答案: 采用该协议告诉编译器此特定响应,至少不会更多。 在相反的结论,并 没有 成为必然。 如果受影响的类不是,约束只是编译器 在编译时 抱怨的另一信息。 在您的情况下,对编译器进行批注仅知道对作出响应。它不知道类型实际上是的子类。 因此,如果要访问具体类的属性,请不要