Google Tag Manager

Showing posts with label TreeCellRenderer. Show all posts
Showing posts with label TreeCellRenderer. Show all posts

2017/05/30

Use JComboBox as JTree's node cell editor

Code

class PluginCellEditor extends DefaultCellEditor {
  private final PluginPanel panel;
  private transient Node node;

  public PluginCellEditor(JComboBox<String> comboBox) {
    super(comboBox);
    panel = new PluginPanel(comboBox);
  }

  @Override public Component getTreeCellEditorComponent(
      JTree tree, Object value, boolean selected, boolean expanded,
      boolean leaf, int row) {
    Node node = panel.extractNode(value);
    panel.setContents(node);
    this.node = node;
    return panel;
  }

  @Override public Object getCellEditorValue() {
    Object o = super.getCellEditorValue();
    if (node == null) {
      return o;
    }
    DefaultComboBoxModel<String> m =
        (DefaultComboBoxModel<String>) panel.comboBox.getModel();
    Node n = new Node(panel.pluginName.getText(), node.plugins);
    n.setSelectedPluginIndex(m.getIndexOf(o));
    return n;
  }

  @Override public boolean isCellEditable(EventObject e) {
    Object source = e.getSource();
    if (!(source instanceof JTree) || !(e instanceof MouseEvent)) {
      return false;
    }
    JTree tree = (JTree) source;
    MouseEvent me = (MouseEvent) e;
    TreePath path = tree.getPathForLocation(me.getX(), me.getY());
    if (path == null) {
      return false;
    }
    Object node = path.getLastPathComponent();
    if (!(node instanceof DefaultMutableTreeNode)) {
      return false;
    }
    Rectangle r = tree.getPathBounds(path);
    if (r == null) {
      return false;
    }
    Dimension d = panel.getPreferredSize();
    r.setSize(new Dimension(d.width, r.height));
    if (r.contains(me.getX(), me.getY())) {
      showComboPopup(tree, me);
      return true;
    }
    return delegate.isCellEditable(e);
  }

  private void showComboPopup(final JTree tree, final MouseEvent me) {
    EventQueue.invokeLater(new Runnable() {
      @Override public void run() {
        Point pt = SwingUtilities.convertPoint(tree, me.getPoint(), panel);
        Component o = SwingUtilities.getDeepestComponentAt(panel, pt.x, pt.y);
        if (o instanceof JComboBox) {
          panel.comboBox.showPopup();
        } else if (o != null) {
          Container c = SwingUtilities.getAncestorOfClass(
              JComboBox.class, (Component) o);
          if (c instanceof JComboBox) {
            panel.comboBox.showPopup();
          }
        }
      }
    });
  }
}

References

2014/11/27

Make a transparent JTree and translucent selection background

Code

class TransparentTreeCellRenderer extends DefaultTreeCellRenderer {
  @Override public Component getTreeCellRendererComponent(
          JTree tree, Object value, boolean isSelected, boolean expanded,
          boolean leaf, int row, boolean hasFocus) {
    JComponent c = (JComponent) super.getTreeCellRendererComponent(
          tree, value, isSelected, expanded, leaf, row, hasFocus);
    c.setOpaque(false);
    return c;
  }
  private final Color ALPHA_OF_ZERO = new Color(0, true);
  @Override public Color getBackgroundNonSelectionColor() {
    return ALPHA_OF_ZERO;
  }
  @Override public Color getBackgroundSelectionColor() {
    return ALPHA_OF_ZERO;
  }
}

class TranslucentTreeCellRenderer extends TransparentTreeCellRenderer {
  private final Color backgroundSelectionColor = new Color(100, 100, 255, 100);

  @Override public Color getBackgroundSelectionColor() {
    return backgroundSelectionColor;
  }
}

References

2012/02/06

JCheckBox Node JTree

Code

class CheckBoxNodeEditor extends TriStateCheckBox implements TreeCellEditor {
  private DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer();
  private final JPanel panel = new JPanel(new BorderLayout());
  private String str = null;
  public CheckBoxNodeEditor() {
    super();
    this.addActionListener(new ActionListener() {
      @Override public void actionPerformed(ActionEvent e) {
        // System.out.println("actionPerformed: stopCellEditing");
        stopCellEditing();
      }
    });
    panel.setFocusable(false);
    panel.setRequestFocusEnabled(false);
    panel.setOpaque(false);
    panel.add(this, BorderLayout.WEST);
    this.setOpaque(false);
  }

  @Override public Component getTreeCellEditorComponent(
      JTree tree, Object value, boolean isSelected,
      boolean expanded, boolean leaf, int row) {
    JLabel l = (JLabel) renderer.getTreeCellRendererComponent(
      tree, value, true, expanded, leaf, row, true);
    l.setFont(tree.getFont());
    if (value instanceof DefaultMutableTreeNode) {
      this.setEnabled(tree.isEnabled());
      this.setFont(tree.getFont());
      Object userObject = ((DefaultMutableTreeNode) value).getUserObject();
      if (userObject instanceof CheckBoxNode) {
        CheckBoxNode node = (CheckBoxNode) userObject;
        if (node.status == Status.INDETERMINATE) {
          setIcon(new IndeterminateIcon());
        } else {
          setIcon(null);
        }
        l.setText(node.label);
        setSelected(node.status == Status.SELECTED);
        str = node.label;
      }
      // panel.add(this, BorderLayout.WEST);
      panel.add(l);
      return panel;
    }
    return l;
  }

  @Override public Object getCellEditorValue() {
    return new CheckBoxNode(str, isSelected() ? Status.SELECTED : Status.DESELECTED);
  }

  @Override public boolean isCellEditable(EventObject e) {
    if (e instanceof MouseEvent && e.getSource() instanceof JTree) {
      MouseEvent me = (MouseEvent) e;
      JTree tree = (JTree) e.getSource();
      TreePath path = tree.getPathForLocation(me.getX(), me.getY());
      Rectangle r = tree.getPathBounds(path);
      if (r == null) {
        return false;
      }
      Dimension d = getPreferredSize();
      r.setSize(new Dimension(d.width, r.height));
      if (r.contains(me.getPoint())) {
        return true;
      }
    }
    return false;
  }

  @Override public void updateUI() {
    super.updateUI();
    setName("Tree.cellEditor");
    if (panel != null) {
      //panel.removeAll(); // ??? Change to Nimbus LnF, JDK 1.6.0
      panel.updateUI();
      //panel.add(this, BorderLayout.WEST);
    }
    // ???#1: JDK 1.6.0 bug??? @see 1.7.0 DefaultTreeCellRenderer#updateUI()
    // if (System.getProperty("java.version").startsWith("1.6.0")) {
    //   renderer = new DefaultTreeCellRenderer();
    // }
  }
// ...

References

2011/08/29

FileSystemTree with JCheckBox

Code

class CheckBoxNodeEditor extends TriStateCheckBox implements TreeCellEditor {
  private final FileSystemView fileSystemView;
  private final JPanel panel = new JPanel(new BorderLayout());
  private DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer();
  private File file;

  public CheckBoxNodeEditor(FileSystemView fileSystemView) {
    super();
    this.fileSystemView = fileSystemView;
    this.addActionListener(new ActionListener() {
      @Override public void actionPerformed(ActionEvent e) {
        stopCellEditing();
      }
    });
    panel.setFocusable(false);
    panel.setRequestFocusEnabled(false);
    panel.setOpaque(false);
    panel.add(this, BorderLayout.WEST);
    this.setOpaque(false);
  }

  @Override public Component getTreeCellEditorComponent(
      JTree tree, Object value, boolean isSelected, boolean expanded,
      boolean leaf, int row) {
    JLabel l = (JLabel) renderer.getTreeCellRendererComponent(
      tree, value, true, expanded, leaf, row, true);
    l.setFont(tree.getFont());
    setOpaque(false);
    if (value instanceof DefaultMutableTreeNode) {
      this.setEnabled(tree.isEnabled());
      this.setFont(tree.getFont());
      Object userObject = ((DefaultMutableTreeNode) value).getUserObject();
      if (userObject instanceof CheckBoxNode) {
        CheckBoxNode node = (CheckBoxNode) userObject;
        if (node.status == Status.INDETERMINATE) {
          setIcon(new IndeterminateIcon());
        } else {
          setIcon(null);
        }
        file = node.file;
        l.setIcon(fileSystemView.getSystemIcon(file));
        l.setText(fileSystemView.getSystemDisplayName(file));
        setSelected(node.status == Status.SELECTED);
      }
      // panel.add(this, BorderLayout.WEST);
      panel.add(l);
      return panel;
    }
    return l;
  }

  @Override public Object getCellEditorValue() {
    return new CheckBoxNode(file, isSelected() ? Status.SELECTED : Status.DESELECTED);
  }

  @Override public boolean isCellEditable(EventObject e) {
    if (e instanceof MouseEvent && e.getSource() instanceof JTree) {
      MouseEvent me = (MouseEvent) e;
      JTree tree = (JTree) e.getSource();
      TreePath path = tree.getPathForLocation(me.getX(), me.getY());
      Rectangle r = tree.getPathBounds(path);
      if (r == null) {
        return false;
      }
      Dimension d = getPreferredSize();
      r.setSize(new Dimension(d.width, r.height));
      if (r.contains(me.getX(), me.getY())) {
        // if (file == null && System.getProperty("java.version").startsWith("1.7.0")) {
        //   System.out.println("XXX: Java 7, only on first run\n" + getBounds());
        //   setBounds(new Rectangle(0, 0, d.width, r.height));
        // }
        return true;
      }
    }
    return false;
  }

  @Override public void updateUI() {
    super.updateUI();
    if (panel != null) {
      panel.updateUI();
    }
    // 1.6.0_24 bug??? @see 1.7.0 DefaultTreeCellRenderer#updateUI()
    renderer = new DefaultTreeCellRenderer();
  }
// ...

References

2011/02/28

Highlight entire JTree row on selection

Code

class RowSelectionTree extends JTree {
  private static final Color SELC = new Color(100, 150, 200);
  private Handler handler;

  @Override protected void paintComponent(Graphics g) {
    g.setColor(getBackground());
    g.fillRect(0, 0, getWidth(), getHeight());
    if (getSelectionCount() > 0) {
      g.setColor(SELC);
      for (int i : getSelectionRows()) {
        Rectangle r = getRowBounds(i);
        g.fillRect(0, r.y, getWidth(), r.height);
      }
    }
    super.paintComponent(g);
    if (getLeadSelectionPath() != null) {
      Rectangle r = getRowBounds(getRowForPath(getLeadSelectionPath()));
      g.setColor(hasFocus() ? SELC.darker() : SELC);
      g.drawRect(0, r.y, getWidth() - 1, r.height - 1);
    }
  }

  @Override public void updateUI() {
    removeFocusListener(handler);
    super.updateUI();
    setUI(new BasicTreeUI() {
      @Override public Rectangle getPathBounds(JTree tree, TreePath path) {
        if (tree != null && treeState != null) {
          return getPathBounds(path, tree.getInsets(), new Rectangle());
        }
        return null;
      }

      private Rectangle getPathBounds(
          TreePath path, Insets insets, Rectangle bounds) {
        Rectangle rect = treeState.getBounds(path, bounds);
        if (rect != null) {
          rect.width = tree.getWidth();
          rect.y += insets.top;
        }
        return rect;
      }
    });
    handler = new Handler();
    addFocusListener(handler);
    setCellRenderer(handler);
    setOpaque(false);
  }

  static class Handler extends DefaultTreeCellRenderer implements FocusListener {
    @Override public Component getTreeCellRendererComponent(
        JTree tree, Object value, boolean selected, boolean expanded,
        boolean leaf, int row, boolean hasFocus) {
      JLabel l = (JLabel) super.getTreeCellRendererComponent(
          tree, value, selected, expanded, leaf, row, hasFocus);
      l.setBackground(selected ? SELC : tree.getBackground());
      l.setOpaque(true);
      return l;
    }

    @Override public void focusGained(FocusEvent e) {
      e.getComponent().repaint();
    }

    @Override public void focusLost(FocusEvent e) {
      e.getComponent().repaint();
    }
  }
}

References

2010/10/26

JTree node highlight search

Code

class HighlightTreeCellRenderer extends DefaultTreeCellRenderer {
  private static final Color rollOverRowColor = new Color(220, 240, 255);
  private final TreeCellRenderer renderer;
  public String q;
  public HighlightTreeCellRenderer(TreeCellRenderer renderer) {
    this.renderer = renderer;
  }

  @Override public Component getTreeCellRendererComponent(JTree tree, Object value,
        boolean isSelected, boolean expanded,
        boolean leaf, int row, boolean hasFocus) {
    JComponent c = (JComponent) renderer.getTreeCellRendererComponent(
        tree, value, isSelected, expanded, leaf, row, hasFocus);
    if (isSelected) {
      c.setOpaque(false);
      c.setForeground(getTextSelectionColor());
      // c.setBackground(Color.BLUE); // getBackgroundSelectionColor());
    } else {
      c.setOpaque(true);
      if (q != null && !q.isEmpty() && value.toString().startsWith(q)) {
        c.setForeground(getTextNonSelectionColor());
        c.setBackground(rollOverRowColor);
      } else {
        c.setForeground(getTextNonSelectionColor());
        c.setBackground(getBackgroundNonSelectionColor());
      }
    }
    return c;
  }
}

References