I have a Problem with JTree and JButton It seems like when entering the Edit modus and hovering over the Buttons on the TreeCells, it Renderes some Part of the Tree inside the Button. Even when Dragging from one Button to another in the Same Row it Renderes the one Button over the other one.
Here a Short Selfexplaining Sample that you can copy paste to See what i mean.
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.util.EventObject;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.UIManager;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellEditor;
import javax.swing.tree.DefaultTreeCellRenderer;
public class MyProblemWithTree {
public static void main(String...args) {
JFrame frame = new JFrame("Panel");
JScrollPane scroll = new JScrollPane();
DefaultMutableTreeNode node = new DefaultMutableTreeNode("Root");
DefaultMutableTreeNode nodeChild = new DefaultMutableTreeNode("childcaretaker1");
nodeChild.add(new DefaultMutableTreeNode("child1"));
nodeChild.add(new DefaultMutableTreeNode("child2"));
node.add(nodeChild);
final JTree tree = new JTree(node);
tree.setCellRenderer(new MyTreeCellRenderer());
tree.setEditable(true);
tree.setCellEditor(new MyTreeCellEditor(tree));
tree.addMouseMotionListener(new MouseMotionListener() {
@Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
if (tree.getRowForLocation(e.getX(), e.getY()) != -1)
{
tree.startEditingAtPath(tree.getPathForLocation(e.getX(), e.getY()));
}
}
@Override
public void mouseDragged(MouseEvent arg0) {
// TODO Auto-generated method stub
}
});
scroll.setViewportView(tree);
frame.add(scroll);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
class MyTreeCellEditor extends DefaultTreeCellEditor {
JPanel leafPanel;
JLabel colorIcon;
PlayButton play;
PauseButton pause;
JLabel name;
public MyTreeCellEditor(JTree tree) {
super(tree, (MyTreeCellRenderer)tree.getCellRenderer());
leafPanel = new JPanel(new FlowLayout());
colorIcon = new JLabel(UIManager.getIcon("OptionPane.informationIcon"));
play = new PlayButton();
pause = new PauseButton();
name = new JLabel();
play.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
System.out.println("Playbutton klickt");
}
});
leafPanel.add(colorIcon);
leafPanel.add(name);
leafPanel.add(pause);
leafPanel.add(play);
}
@Override
public Component getTreeCellEditorComponent(JTree tree, Object value,
boolean selected, boolean expanded, boolean leaf, int row) {
name.setText((String)((DefaultMutableTreeNode)value).getUserObject());
pause.setVisible(!leaf);
return leafPanel;
}
@Override
public boolean isCellEditable(EventObject arg0) {
return true;
}
}
class MyTreeCellRenderer extends DefaultTreeCellRenderer {
private static final long serialVersionUID = 3691823996133806942L;
JPanel leafPanel;
JLabel colorIcon;
PlayButton play;
PauseButton pause;
JLabel name;
DefaultTreeCellRenderer defaultRenderer = new DefaultTreeCellRenderer();
Color backgroundSelectionColor;
Color backgroundNonSelectionColor;
public MyTreeCellRenderer() {
leafPanel = new JPanel(new FlowLayout());
colorIcon = new JLabel(UIManager.getIcon("OptionPane.informationIcon"));
play = new PlayButton();
pause = new PauseButton();
name = new JLabel();
leafPanel.add(colorIcon);
leafPanel.add(name);
leafPanel.add(pause);
leafPanel.add(play);
backgroundSelectionColor = new Color(200,200,255,50);
backgroundNonSelectionColor = new Color(0,0,0,0);
}
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
name.setText((String)((DefaultMutableTreeNode) value).getUserObject());
if (selected) {
leafPanel.setBackground(backgroundSelectionColor);
} else {
leafPanel.setBackground(backgroundNonSelectionColor);
}
leafPanel.setEnabled(tree.isEnabled());
pause.setVisible(!leaf);
return leafPanel;
}
}
class PlayButton extends JButton{
private static final long serialVersionUID = 550654173835539853L;
Dimension size = new Dimension(140,28);
public PlayButton() {
setIcon(UIManager.getIcon("OptionPane.informationIcon"));
setPressedIcon(UIManager.getIcon("OptionPane.errorIcon"));
setBackground(new Color(0,0,0,0));
setBorderPainted(false);
setPreferredSize(size);
setMaximumSize(size);
setMinimumSize(size);
}
}
class PauseButton extends JButton{
private static final long serialVersionUID = -5877843953696256070L;
Dimension size = new Dimension(140,28);
public PauseButton() {
setIcon(UIManager.getIcon("OptionPane.warningIcon"));
setPressedIcon(UIManager.getIcon("OptionPane.questionIcon"));
setBackground(new Color(0,0,0,0));
setBorderPainted(false);
setPreferredSize(size);
setMaximumSize(size);
setMinimumSize(size);
}
}
Even when i erase this Part. and i must click a Cell to enter the Edit Modus i still can get the Effect by leaving the Cell witzh the mouse and go back.
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
if (tree.getRowForLocation(e.getX(), e.getY()) != -1)
{
tree.startEditingAtPath(tree.getPathForLocation(e.getX(), e.getY()));
}
}
I spend already 4 days into this JTree Customizing. But it really confuses me, how i could stop the rendering by entering the Button.