Google Tag Manager

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

2017/04/28

Disable any items in JList

Code

JList<String> list = new JList<>(model);
list.setCellRenderer(new DefaultListCellRenderer() {
  @Override public Component getListCellRendererComponent(
      JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
    Component c;
    if (disableIndexSet.contains(index)) {
      c = super.getListCellRendererComponent(list, value, index, false, false);
      c.setEnabled(false);
    } else {
      c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
    }
    return c;
  }
});

ActionMap am = list.getActionMap();
am.put("selectNextRow", new AbstractAction() {
  @Override public void actionPerformed(ActionEvent ae) {
    for (int i = list.getSelectedIndex() + 1; i < list.getModel().getSize(); i++) {
      if (!disableIndexSet.contains(Integer.valueOf(i))) {
        list.setSelectedIndex(i);
        break;
      }
    }
  }
});

References

2017/03/30

Make a condensed Font and use it with JTextArea

Code

Font font = new Font(Font.MONOSPACED, Font.PLAIN, 18).deriveFont(
   AffineTransform.getScaleInstance(.9, 1d));
textArea.setFont(font);

References

2017/02/27

Click on the already selected JToggleButton and clear all selections in the ButtonGroup

Code

class ToggleButtonGroup extends ButtonGroup {
  private ButtonModel prevModel;
  private boolean isAdjusting;

  @Override public void setSelected(ButtonModel m, boolean b) {
    if (isAdjusting) {
      return;
    }
    if (m.equals(prevModel)) {
      isAdjusting = true;
      clearSelection();
      isAdjusting = false;
    } else {
      super.setSelected(m, b);
    }
    prevModel = getSelection();
  }
}

References

2017/01/27

Change the tab shape of JTabbedPane to trapezoid

Code

class IsoscelesTrapezoidTabbedPaneUI extends BasicTabbedPaneUI {
  private static final int ADJ2 = 3;
  private final Color selectedTabColor = UIManager.getColor("TabbedPane.selected");
  private final Color tabBackgroundColor = Color.LIGHT_GRAY;
  private final Color tabBorderColor = Color.GRAY;

  @Override protected void paintTabArea(Graphics g, int tabPlacement, int selectedIndex) {
    int tabCount = tabPane.getTabCount();

    Rectangle iconRect = new Rectangle(),
    textRect = new Rectangle();
    Rectangle clipRect = g.getClipBounds();

    for (int i = runCount - 1; i >= 0; i--) {
      int start = tabRuns[i];
      int next = tabRuns[(i == runCount - 1) ? 0 : i + 1];
      int end = next != 0 ? next - 1 : tabCount - 1; //NOPMD
      // for (int j = start; j <= end; j++) {
      // https://stackoverflow.com/questions/41566659/tabs-rendering-order-in-custom-jtabbedpane
      for (int j = end; j >= start; j--) {
        if (j != selectedIndex && rects[j].intersects(clipRect)) {
          paintTab(g, tabPlacement, rects, j, iconRect, textRect);
        }
      }
    }
    if (selectedIndex >= 0 && rects[selectedIndex].intersects(clipRect)) {
      paintTab(g, tabPlacement, rects, selectedIndex, iconRect, textRect);
    }
  }

  @Override protected void paintTabBorder(Graphics g, int tabPlacement, int tabIndex,
      int x, int y, int w, int h, boolean isSelected) {
    // Do nothing
  }

  @Override protected void paintFocusIndicator(
      Graphics g, int tabPlacement, Rectangle[] rects, int tabIndex,
      Rectangle iconRect, Rectangle textRect, boolean isSelected) {
    // Do nothing
  }

  @Override protected void paintContentBorderTopEdge(
      Graphics g, int tabPlacement, int selectedIndex, int x, int y, int w, int h) {
    super.paintContentBorderTopEdge(g, tabPlacement, selectedIndex, x, y, w, h);
    Rectangle selRect = getTabBounds(selectedIndex, calcRect);
    Graphics2D g2 = (Graphics2D) g.create();
    g2.setColor(selectedTabColor);
    g2.drawLine(selRect.x - ADJ2 + 1, y, selRect.x + selRect.width + ADJ2 - 1, y);
    g2.dispose();
  }

  @Override protected void paintTabBackground(Graphics g, int tabPlacement, int tabIndex,
        int x, int y, int w, int h, boolean isSelected) {
    Graphics2D g2 = (Graphics2D) g.create();
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
        RenderingHints.VALUE_ANTIALIAS_ON);
    int textShiftOffset = isSelected ? 0 : 1;

    Rectangle clipRect = g2.getClipBounds();
    clipRect.grow(ADJ2 + 1, 0);
    g2.setClip(clipRect);

    GeneralPath trapezoid = new GeneralPath();
    trapezoid.moveTo(x - ADJ2,     y + h);
    trapezoid.lineTo(x + ADJ2,     y + textShiftOffset);
    trapezoid.lineTo(x + w - ADJ2, y + textShiftOffset);
    trapezoid.lineTo(x + w + ADJ2, y + h);
    //trapezoid.closePath();

    g2.setColor(isSelected ? selectedTabColor : tabBackgroundColor);
    g2.fill(trapezoid);

    g2.setColor(tabBorderColor);
    g2.draw(trapezoid);

    g2.dispose();
  }
}

References