Google Tag Manager

2013/12/09

Breadcrumb Navigation with JRadioButton

Code

private static JComponent makeBreadcrumbList(int overlap, List< String> list) {
  JPanel p = new JPanel(new FlowLayout(FlowLayout.LEADING, -overlap, 0));
  p.setBorder(BorderFactory.createEmptyBorder(4, overlap+4, 4, 4));
  p.setOpaque(false);
  ButtonGroup bg = new ButtonGroup();
  for(String title: list) {
    AbstractButton b = makeButton(title, Color.PINK);
    p.add(b);
    bg.add(b);
  }
  return p;
}

References

2013/11/25

Cut copy paste buttuns in the JMenuItem

Code

private static JMenuItem makeEditMenuItem(final JPanel edit) {
  JMenuItem item = new JMenuItem("Edit") {
    @Override public Dimension getPreferredSize() {
      Dimension d = super.getPreferredSize();
      d.width += edit.getPreferredSize().width;
      d.height = Math.max(edit.getPreferredSize().height, d.height);
      return d;
    }
    @Override protected void fireStateChanged() {
      setForeground(Color.BLACK);
      super.fireStateChanged();
    }
  };
  item.setEnabled(false);

  GridBagConstraints c = new GridBagConstraints();
  item.setLayout(new GridBagLayout());
  c.gridheight = 1;
  c.gridwidth  = 1;
  c.gridy = 0;
  c.gridx = 0;

  c.weightx = 1.0;
  c.fill = GridBagConstraints.HORIZONTAL;
  item.add(Box.createHorizontalGlue(), c);
  c.gridx = 1;
  c.fill = GridBagConstraints.NONE;
  c.weightx = 0.0;
  c.anchor = GridBagConstraints.EAST;
  item.add(edit, c);

  return item;
}
private static JPanel makeEditButtonBar(List list) {
  int size = list.size();
  JPanel p = new JPanel(new GridLayout(1, size, 0, 0)) {
    @Override public Dimension getMaximumSize() {
      return super.getPreferredSize();
    }
  };
  for(AbstractButton b: list) {
    b.setIcon(new ToggleButtonBarCellIcon());
    p.add(b);
  }
  p.setBorder(BorderFactory.createEmptyBorder(4, 10, 4, 10));
  p.setOpaque(false);
  return p;
}
private static AbstractButton makeButton(String title, Action action) {
  JButton b = new JButton(action);
  b.addActionListener(new ActionListener() {
    @Override public void actionPerformed(ActionEvent e) {
      JButton b = (JButton)e.getSource();
      Container c = SwingUtilities.getAncestorOfClass(JPopupMenu.class, b);
      if(c != null) {
        ((JPopupMenu)c).setVisible(false);
      }
    }
  });
  b.setText(title);
  b.setVerticalAlignment(SwingConstants.CENTER);
  b.setVerticalTextPosition(SwingConstants.CENTER);
  b.setHorizontalAlignment(SwingConstants.CENTER);
  b.setHorizontalTextPosition(SwingConstants.CENTER);
  b.setBorder(BorderFactory.createEmptyBorder());
  b.setContentAreaFilled(false);
  b.setFocusPainted(false);
  b.setOpaque(false);
  b.setBorder(BorderFactory.createEmptyBorder());
  return b;
}

References

2013/11/11

Using drop caps on a JLabel

Code

@Override protected void paintComponent(Graphics g) {
  Graphics2D g2 = (Graphics2D)g.create();
  g2.setPaint(getBackground());
  g2.fillRect(0, 0, getWidth(), getHeight());

  Insets i = getInsets();
  float x0 = i.left;
  float y0 = i.top;

  Font font = getFont();
  String txt = getText();

  AttributedString as = new AttributedString(txt.substring(1));
  as.addAttribute(TextAttribute.FONT, font);
  AttributedCharacterIterator aci = as.getIterator();
  FontRenderContext frc = g2.getFontRenderContext();

  Shape shape = new TextLayout(txt.substring(0, 1), font, frc).getOutline(null);

  AffineTransform at1 = AffineTransform.getScaleInstance(5d, 5d);
  Shape s1 = at1.createTransformedShape(shape);
  Rectangle r = s1.getBounds();
  r.grow(6, 2);
  int rw = r.width;
  int rh = r.height;

  AffineTransform at2 = AffineTransform.getTranslateInstance(x0, y0+rh);
  Shape s2 = at2.createTransformedShape(s1);
  g2.setPaint(getForeground());
  g2.fill(s2);

  float x = x0 + rw;
  float y = y0;
  int w0 = getWidth() - i.left - i.right;
  int w = w0 - rw;
  LineBreakMeasurer lbm = new LineBreakMeasurer(aci, frc);
  while(lbm.getPosition() < aci.getEndIndex()) {
    TextLayout tl = lbm.nextLayout(w);
    tl.draw(g2, x, y + tl.getAscent());
    y += tl.getDescent() + tl.getLeading() + tl.getAscent();
    if(y0+rh < y) {
      x = x0;
      w = w0;
    }
  }
  g2.dispose();
}

References

2013/10/15

Scrollable list of JCheckBoxes

Code

JList

class CheckBoxCellRenderer extends JCheckBox
    implements ListCellRenderer, MouseListener, MouseMotionListener {
  @Override public Component getListCellRendererComponent(
    JList list,
    Object value,
    int index,
    boolean isSelected,
    boolean cellHasFocus) {
    this.setOpaque(true);
    if(isSelected) {
      this.setBackground(list.getSelectionBackground());
      this.setForeground(list.getSelectionForeground());
    }else{
      this.setBackground(list.getBackground());
      this.setForeground(list.getForeground());
    }
    if(value instanceof CheckBoxNode) {
      this.setSelected(((CheckBoxNode)value).selected);
      this.getModel().setRollover(index==rollOverRowIndex);
    }
    this.setText(value.toString());
    return this;
  }
  private int rollOverRowIndex = -1;
  @Override public void mouseExited(MouseEvent e) {
    JList l = (JList)e.getSource();
    if(rollOverRowIndex>=0) {
      l.repaint(l.getCellBounds(rollOverRowIndex, rollOverRowIndex));
      rollOverRowIndex = -1;
    }
  }
  @SuppressWarnings("unchecked")
  @Override public void mouseClicked(MouseEvent e) {
    if(e.getButton()==MouseEvent.BUTTON1) {
      JList l = (JList)e.getComponent();
      DefaultListModel m = (DefaultListModel)l.getModel();
      Point p = e.getPoint();
      int index  = l.locationToIndex(p);
      if(index>=0) {
        CheckBoxNode n = (CheckBoxNode)m.get(index);
        m.set(index, new CheckBoxNode(n.text, !n.selected));
        l.repaint(l.getCellBounds(index, index));
      }
    }
  }
  @Override public void mouseMoved(MouseEvent e) {
    JList l = (JList)e.getSource();
    int index = l.locationToIndex(e.getPoint());
    if(index != rollOverRowIndex) {
      rollOverRowIndex = index;
      l.repaint();
    }
  }
  @Override public void mouseEntered(MouseEvent e) {}
  @Override public void mousePressed(MouseEvent e) {}
  @Override public void mouseReleased(MouseEvent e) {}
  @Override public void mouseDragged(MouseEvent e) {}
}

JTree

class CheckBoxNodeRenderer extends JCheckBox implements TreeCellRenderer {
  private TreeCellRenderer renderer = new DefaultTreeCellRenderer();
  @Override public Component getTreeCellRendererComponent(
      JTree tree, Object value, boolean selected, boolean expanded,
      boolean leaf, int row, boolean hasFocus) {
    if(leaf && value != null && value instanceof DefaultMutableTreeNode) {
      this.setOpaque(false);
      Object userObject = ((DefaultMutableTreeNode)value).getUserObject();
      if(userObject!=null && userObject instanceof CheckBoxNode) {
        CheckBoxNode node = (CheckBoxNode)userObject;
        this.setText(node.text);
        this.setSelected(node.selected);
      }
      return this;
    }
    return renderer.getTreeCellRendererComponent(
        tree, value, selected, expanded, leaf, row, hasFocus);
  }
}

class CheckBoxNodeEditor extends JCheckBox implements TreeCellEditor {
  private final JTree tree;
  public CheckBoxNodeEditor(JTree tree) {
    super();
    this.tree = tree;
    setOpaque(false);
    setFocusable(false);
    addActionListener(new ActionListener() {
      @Override public void actionPerformed(ActionEvent e) {
        stopCellEditing();
      }
    });
  }
  @Override public Component getTreeCellEditorComponent(
      JTree tree, Object value, boolean isSelected, boolean expanded,
      boolean leaf, int row) {
    if(leaf && value != null && value instanceof DefaultMutableTreeNode) {
      Object userObject = ((DefaultMutableTreeNode)value).getUserObject();
      if(userObject!=null && userObject instanceof CheckBoxNode) {
        this.setSelected(((CheckBoxNode)userObject).selected);
      } else {
        this.setSelected(false);
      }
      this.setText(value.toString());
    }
    return this;
  }
  @Override public Object getCellEditorValue() {
    return new CheckBoxNode(getText(), isSelected());
  }
  @Override public boolean isCellEditable(EventObject e) {
    return (e != null && e instanceof MouseEvent);
  }
  //Copid from AbstractCellEditor
  //protected EventListenerList listenerList = new EventListenerList();
  //transient protected ChangeEvent changeEvent = null;
  @Override public boolean shouldSelectCell(java.util.EventObject anEvent) {
//...

References

2013/09/12

How to sort JTree nodes

Code

public static void sortTree(DefaultMutableTreeNode root) {
  Enumeration e = root.depthFirstEnumeration();
  while (e.hasMoreElements()) {
    DefaultMutableTreeNode node = (DefaultMutableTreeNode) e.nextElement();
    if (!node.isLeaf()) {
      sort2(node);   //selection sort
      //sort3(node); //JDK 1.6.0: iterative merge sort
      //sort3(node); //JDK 1.7.0: TimSort
    }
  }
}
public static Comparator< DefaultMutableTreeNode> tnc = new Comparator< DefaultMutableTreeNode>() {
  @Override public int compare(DefaultMutableTreeNode a, DefaultMutableTreeNode b) {
    //Sort the parent and child nodes separately:
    if (a.isLeaf() && !b.isLeaf()) {
      return 1;
    } else if (!a.isLeaf() && b.isLeaf()) {
      return -1;
    } else {
      String sa = a.getUserObject().toString();
      String sb = b.getUserObject().toString();
      return sa.compareToIgnoreCase(sb);
    }
  }
};
// JDK 1.8.0
// a lambda expression Comparator
//Comparator< DefaultMutableTreeNode> tnc = Comparator.comparing(DefaultMutableTreeNode::isLeaf)
//                                                    .thenComparing(n -> n.getUserObject().toString());
//selection sort
public static void sort2(DefaultMutableTreeNode parent) {
  int n = parent.getChildCount();
  for (int i = 0; i < n - 1; i++) {
    int min = i;
    for (int j = i + 1; j < n; j++) {
      if (tnc.compare((DefaultMutableTreeNode) parent.getChildAt(min),
                      (DefaultMutableTreeNode) parent.getChildAt(j)) > 0) {
        min = j;
      }
    }
    if (i != min) {
      MutableTreeNode a = (MutableTreeNode) parent.getChildAt(i);
      MutableTreeNode b = (MutableTreeNode) parent.getChildAt(min);
      parent.insert(b, i);
      parent.insert(a, min);
    }
  }
}
public static void sort3(DefaultMutableTreeNode parent) {
  int n = parent.getChildCount();
  //@SuppressWarnings("unchecked")
  //Enumeration< DefaultMutableTreeNode> e = parent.children();
  //ArrayList< DefaultMutableTreeNode> children = Collections.list(e);
  List< DefaultMutableTreeNode> children = new ArrayList< DefaultMutableTreeNode>(n);
  for (int i = 0; i < n; i++) {
    children.add((DefaultMutableTreeNode) parent.getChildAt(i));
  }
  Collections.sort(children, tnc); //iterative merge sort
  parent.removeAllChildren();
  for (MutableTreeNode node: children) {
    parent.add(node);
  }
}

References

2013/08/29

Create 9-slice scaling image JButton

Code

class NineSliceScalingIcon implements Icon {
  private final BufferedImage image;
  private final int leftw;
  private final int rightw;
  private final int toph;
  private final int bottomh;
  private int width;
  private int height;
  protected NineSliceScalingIcon(
      BufferedImage image, int leftw, int rightw, int toph, int bottomh) {
    this.image = image;
    this.leftw = leftw;
    this.rightw = rightw;
    this.toph = toph;
    this.bottomh = bottomh;
  }
  @Override public int getIconWidth() {
    return width; // Math.max(image.getWidth(null), width);
  }
  @Override public int getIconHeight() {
    return Math.max(image.getHeight(null), height);
  }
  @Override public void paintIcon(Component cmp, Graphics g, int x, int y) {
    Graphics2D g2 = (Graphics2D) g.create();
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                        RenderingHints.VALUE_ANTIALIAS_ON);
    Insets i;
    if (cmp instanceof JComponent) {
      i = ((JComponent) cmp).getBorder().getBorderInsets(cmp);
    } else {
      i = new Insets(0, 0, 0, 0);
    }

    // g2.translate(x, y); // 1.8.0: work fine?
    int iw = image.getWidth(cmp);
    int ih = image.getHeight(cmp);
    width  = cmp.getWidth() - i.left - i.right;
    height = cmp.getHeight() - i.top - i.bottom;

    g2.drawImage(
        image.getSubimage(leftw, toph, iw - leftw - rightw, ih - toph - bottomh),
        leftw, toph, width - leftw - rightw, height - toph - bottomh, cmp);
    if (leftw > 0 && rightw > 0 && toph > 0 && bottomh > 0) {
      g2.drawImage(image.getSubimage(leftw, 0, iw - leftw - rightw, toph),
                   leftw, 0, width - leftw - rightw, toph, cmp);
      g2.drawImage(image.getSubimage(leftw, ih - bottomh, iw - leftw - rightw, bottomh),
                   leftw, height - bottomh, width - leftw - rightw, bottomh, cmp);
      g2.drawImage(image.getSubimage(0, toph, leftw, ih - toph - bottomh),
                   0, toph, leftw, height - toph - bottomh, cmp);
      g2.drawImage(image.getSubimage(iw - rightw, toph, rightw, ih - toph - bottomh),
                   width - rightw, toph, rightw, height - toph - bottomh, cmp);

      g2.drawImage(image.getSubimage(0, 0, leftw, toph),
                   0, 0, cmp);
      g2.drawImage(image.getSubimage(iw - rightw, 0, rightw, toph),
                   width - rightw, 0, cmp);
      g2.drawImage(image.getSubimage(0, ih - bottomh, leftw, bottomh),
                   0, height - bottomh, cmp);
      g2.drawImage(image.getSubimage(iw - rightw, ih - bottomh, rightw, bottomh),
                   width - rightw, height - bottomh, cmp);
    }
    g2.dispose();
  }
}

References

2013/07/29

JTable highlighting and filtering with regular expression

Code

class HighlightTableCellRenderer extends JTextField implements TableCellRenderer {
  private static final Color backgroundSelectionColor = new Color(220, 240, 255);
  private static final Highlighter.HighlightPainter highlightPainter
    = new DefaultHighlighter.DefaultHighlightPainter(Color.YELLOW);
  private String pattern = "";
  private String prev = null;

  public boolean setPattern(String str) {
    if(str==null || str.equals(pattern)) {
      return false;
    }else{
      prev = pattern;
      pattern = str;
      return true;
    }
  }
  public HighlightTableCellRenderer() {
    super();
    setOpaque(true);
    setBorder(BorderFactory.createEmptyBorder());
    setForeground(Color.BLACK);
    setBackground(Color.WHITE);
    setEditable(false);
  }
  public void clearHighlights() {
    Highlighter highlighter = getHighlighter();
    for(Highlighter.Highlight h: highlighter.getHighlights()) {
      highlighter.removeHighlight(h);
    }
  }
  @Override public Component getTableCellRendererComponent(
    JTable table, Object value, boolean isSelected,
    boolean hasFocus, int row, int column) {
    String txt = value!=null ? value.toString() : "";
    clearHighlights();
    setText(txt);
    setBackground(isSelected ? backgroundSelectionColor : Color.WHITE);
    if(pattern!=null && !pattern.isEmpty() && !pattern.equals(prev)) {
      Matcher matcher = Pattern.compile(pattern).matcher(txt);
      if(matcher.find()) {
        int start = matcher.start();
        int end   = matcher.end();
        try{
          getHighlighter().addHighlight(start, end, highlightPainter);
        }catch(BadLocationException e) {
          e.printStackTrace();
        }
      }
    }
    return this;
  }
}

References

2013/06/28

Turn the JProgressBar red with JLayer and RGBImageFilter

Code

class BlockedColorLayerUI extends LayerUI{
  public boolean isPreventing = false;
  private BufferedImage bi;
  private int prevw = -1;
  private int prevh = -1;
  @Override public void paint(Graphics g, JComponent c) {
    if(isPreventing) {
      JLayer jlayer = (JLayer)c;
      JProgressBar progress = (JProgressBar)jlayer.getView();
      int w = progress.getSize().width;
      int h = progress.getSize().height;

      if(bi==null || w!=prevw || h!=prevh) {
        bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
      }
      prevw = w;
      prevh = h;

      Graphics2D g2 = bi.createGraphics();
      super.paint(g2, c);
      g2.dispose();

      Image image = c.createImage(
          new FilteredImageSource(
              bi.getSource(), new RedGreenChannelSwapFilter()));
      //BUG: cause an infinite repaint loop: g.drawImage(image, 0, 0, c);
      g.drawImage(image, 0, 0, null);
    }else{
      super.paint(g, c);
    }
  }
}

class RedGreenChannelSwapFilter extends RGBImageFilter{
  @Override public int filterRGB(int x, int y, int argb) {
    int r = (int)((argb >> 16) & 0xff);
    int g = (int)((argb >>  8) & 0xff);
    int b = (int)((argb    ) & 0xff);
    return (argb & 0xff000000) | (g<<16) | (r<<8) | (b);
  }
}

References

2013/05/29

Column spanning TableCellRenderer

Code

class ColumnSpanningCellRenderer extends JPanel implements TableCellRenderer {
  private static final int TARGET_COLIDX = 0;
  private final JTextArea textArea = new JTextArea(2, 999999);
  private final JLabel label = new JLabel();
  private final JLabel iconLabel = new JLabel();
  private final JScrollPane scroll = new JScrollPane(textArea);

  protected ColumnSpanningCellRenderer() {
    super(new BorderLayout());

    scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
    scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
    scroll.setBorder(BorderFactory.createEmptyBorder());
    scroll.setViewportBorder(BorderFactory.createEmptyBorder());
    scroll.setOpaque(false);
    scroll.getViewport().setOpaque(false);

    textArea.setBorder(BorderFactory.createEmptyBorder());
    textArea.setMargin(new Insets(0, 0, 0, 0));
    textArea.setForeground(Color.RED);
    textArea.setEditable(false);
    textArea.setFocusable(false);
    textArea.setOpaque(false);

    iconLabel.setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 4));
    iconLabel.setOpaque(false);

    Border b1 = BorderFactory.createEmptyBorder(2, 2, 2, 2);
    Border b2 = BorderFactory.createMatteBorder(0, 0, 1, 1, Color.GRAY);
    label.setBorder(BorderFactory.createCompoundBorder(b2, b1));

    setBackground(textArea.getBackground());
    setOpaque(true);
    add(label, BorderLayout.NORTH);
    add(scroll);
  }
  @Override public Component getTableCellRendererComponent(
      JTable table, Object value, boolean isSelected,
      boolean hasFocus, int row, int column) {
    OptionPaneDescription d;
    if (value instanceof OptionPaneDescription) {
      d = (OptionPaneDescription) value;
      add(iconLabel, BorderLayout.WEST);
    } else {
      String title = Objects.toString(value, "");
      int mrow = table.convertRowIndexToModel(row);
      Object o = table.getModel().getValueAt(mrow, 0);
      if (o instanceof OptionPaneDescription) {
        OptionPaneDescription t = (OptionPaneDescription) o;
        d = new OptionPaneDescription(title, t.icon, t.text);
      } else {
        d = new OptionPaneDescription(title, null, "");
      }
      remove(iconLabel);
    }
    label.setText(d.title);
    textArea.setText(d.text);
    iconLabel.setIcon(d.icon);

    Rectangle cr = table.getCellRect(row, column, false);
    if (column != TARGET_COLIDX) {
      cr.x -= iconLabel.getPreferredSize().width;
    }
    scroll.getViewport().setViewPosition(cr.getLocation());

    if (isSelected) {
      setBackground(Color.ORANGE);
    } else {
      setBackground(Color.WHITE);
    }
    return this;
  }
}

class OptionPaneDescription {
  public final String title;
  public final Icon icon;
  public final String text;
  protected OptionPaneDescription(String title, Icon icon, String text) {
    this.title = title;
    this.icon  = icon;
    this.text  = text;
  }
}

References

2013/04/25

Rearrange JToolBar icon by drag and drop

Code

class DragHandler extends MouseAdapter{
  private final JWindow window = new JWindow();
  private Component draggingComonent = null;
  private int index = -1;
  private Component gap = Box.createHorizontalStrut(24);
  private Point startPt = null;
  private int gestureMotionThreshold = DragSource.getDragThreshold();
  public DragHandler() {
    window.setBackground(new Color(0, true));
  }
  @Override public void mousePressed(MouseEvent e) {
    JComponent parent = (JComponent)e.getComponent();
    if(parent.getComponentCount()<=1) {
      startPt = null;
      return;
    }
    startPt = e.getPoint();
  }
  @Override
  public void mouseDragged(MouseEvent e) {
    Point pt = e.getPoint();
    JComponent parent = (JComponent)e.getComponent();
    int t = Math.sqrt(Math.pow(pt.x-startPt.x, 2)+Math.pow(pt.y-startPt.y, 2))
    if(startPt != null && t>gestureMotionThreshold) {
      startPt = null;
      Component c = parent.getComponentAt(pt);
      index = parent.getComponentZOrder(c);
      if(c == parent || index < 0) {
        return;
      }
      draggingComonent = c;

      parent.remove(draggingComonent);
      parent.add(gap, index);
      parent.revalidate();
      parent.repaint();

      window.add(draggingComonent);
      window.pack();

      Dimension d = draggingComonent.getPreferredSize();
      Point p = new Point(pt.x - d.width/2, pt.y - d.height/2);
      SwingUtilities.convertPointToScreen(p, parent);
      window.setLocation(p);
      window.setVisible(true);

      return;
    }
    if(!window.isVisible() || draggingComonent==null) {
      return;
    }

    Dimension d = draggingComonent.getPreferredSize();
    Point p = new Point(pt.x - d.width/2, pt.y - d.height/2);
    SwingUtilities.convertPointToScreen(p, parent);
    window.setLocation(p);

    for(int i=0; i=0 ? i : 0;
        parent.remove(gap);
        parent.add(gap, n);
        parent.revalidate();
        parent.repaint();
        return;
      }else if(r2.contains(pt)) {
        if(c==gap) {
          return;
        }
        parent.remove(gap);
        parent.add(gap, i);
        parent.revalidate();
        parent.repaint();
        return;
      }
    }
    parent.remove(gap);
    parent.revalidate();
    parent.repaint();
  }

  @Override
  public void mouseReleased(MouseEvent e) {
    startPt = null;
    if(!window.isVisible() || draggingComonent==null) {
      return;
    }
    Point pt = e.getPoint();
    JComponent parent = (JComponent)e.getComponent();

    Component cmp = draggingComonent;
    draggingComonent = null;
    window.setVisible(false);

    for(int i=0; i=0 ? i : 0;
        parent.remove(gap);
        parent.add(cmp, n);
        parent.revalidate();
        parent.repaint();
        return;
      }else if(r2.contains(pt)) {
        parent.remove(gap);
        parent.add(cmp, i);
        parent.revalidate();
        parent.repaint();
        return;
      }
    }
    if(parent.getBounds().contains(pt)) {
      parent.remove(gap);
      parent.add(cmp);
    }else{
      parent.remove(gap);
      parent.add(cmp, index);
    }
    parent.revalidate();
    parent.repaint();
  }
}

References

2013/03/30

JTree node edit only from JPopupMenu

Code

tree.setCellEditor(new DefaultTreeCellEditor(
    tree, (DefaultTreeCellRenderer)tree.getCellRenderer()) {
  @Override public boolean isCellEditable(java.util.EventObject e) {
    return (e instanceof MouseEvent)?false:super.isCellEditable(e);
  }
});
tree.setEditable(true);
tree.setComponentPopupMenu(new TreePopupMenu());

References

2013/02/26

Get SVG from PathIterator

Code

private StringBuilder makeStarburstSvg(PathIterator pi, int sz, String style, String desc) {
  StringBuilder sb = new StringBuilder();
  sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
  //...
  sb.append(String.format("<svg width=\"%d\" height=\"%d\" xmlns=\"%s\">%n", sz, sz, w3));
  sb.append(String.format("  <desc>%s</desc>%n", desc));
  sb.append("  <path d=\"");
  double[] c = new double[6];
  while(!pi.isDone()) {
    switch(pi.currentSegment(c)) {
      case PathIterator.SEG_MOVETO:
        sb.append(String.format("M%.2f,%.2f ", c[0], c[1])); break;
      case PathIterator.SEG_LINETO:
        sb.append(String.format("L%.2f,%.2f ", c[0], c[1])); break;
      case PathIterator.SEG_QUADTO:
        sb.append(String.format("Q%.2f,%.2f,%.2f,%.2f ",c[0],c[1],c[2],c[3]));
        break;
      case PathIterator.SEG_CUBICTO:
        sb.append(String.format("C%.2f,%.2f,%.2f,%.2f,%.2f,%.2f ",c[0],c[1],c[2],c[3],c[4],c[5]));
        break;
      case PathIterator.SEG_CLOSE:
        sb.append("Z"); break;
    }
    pi.next();
  }
  sb.append(String.format("\" style=\"%s\" />%n</svg>%n", style));
  return sb;
}

References

2013/01/28

JScrollBar search highlighter

Code

Override WindowsScrollBarUI#paintTrack(...)

scrollbar.setUI(new WindowsScrollBarUI() {
  @Override protected void paintTrack(
      Graphics g, JComponent c, Rectangle trackBounds) {
    super.paintTrack(g, c, trackBounds);

    Rectangle rect = textArea.getBounds();
    double sy = trackBounds.getHeight() / rect.getHeight();
    AffineTransform at = AffineTransform.getScaleInstance(1.0, sy);
    Highlighter highlighter = textArea.getHighlighter();
    g.setColor(Color.YELLOW);
    try{
      for(Highlighter.Highlight hh: highlighter.getHighlights()) {
        Rectangle r = textArea.modelToView(hh.getStartOffset());
        Rectangle s = at.createTransformedShape(r).getBounds();
        int h = 2; //Math.max(2, s.height-2);
        g.fillRect(trackBounds.x, trackBounds.y+s.y, trackBounds.width, h);
      }
    }catch(BadLocationException e) {
      e.printStackTrace();
    }
  }
});

JLabel + Icon + RowHeader

final JScrollPane scroll = new JScrollPane(textArea);
JLabel label = new JLabel(new Icon() {
  private final Color THUMB_COLOR = new Color(0,0,255,50);
  private final Rectangle thumbRect = new Rectangle();
  private final JTextComponent textArea;
  private final JScrollBar scrollbar;
  public HighlightIcon(JTextComponent textArea, JScrollBar scrollbar) {
    this.textArea  = textArea;
    this.scrollbar = scrollbar;
  }
  @Override public void paintIcon(Component c, Graphics g, int x, int y) {
    //Rectangle rect   = textArea.getBounds();
    //Dimension sbSize = scrollbar.getSize();
    //Insets sbInsets  = scrollbar.getInsets();
    //double sy = (sbSize.height-sbInsets.top-sbInsets.bottom)/rect.getHeight();
    int itop = scrollbar.getInsets().top;
    BoundedRangeModel range = scrollbar.getModel();
    double sy = range.getExtent()/(double)(range.getMaximum()-range.getMinimum());
    AffineTransform at = AffineTransform.getScaleInstance(1.0, sy);
    Highlighter highlighter = textArea.getHighlighter();

    //paint Highlight
    g.setColor(Color.RED);
    try{
      for(Highlighter.Highlight hh: highlighter.getHighlights()) {
        Rectangle r = textArea.modelToView(hh.getStartOffset());
        Rectangle s = at.createTransformedShape(r).getBounds();
        int h = 2; //Math.max(2, s.height-2);
        g.fillRect(x, y+itop+s.y, getIconWidth(), h);
      }
    }catch(BadLocationException e) {
      e.printStackTrace();
    }

    //paint Thumb
    if(scrollbar.isVisible()) {
      //JViewport vport = Objects.requireNonNull(
      //  (JViewport)SwingUtilities.getAncestorOfClass(JViewport.class, textArea));
      //Rectangle thumbRect = vport.getBounds();
      thumbRect.height = range.getExtent();
      thumbRect.y = range.getValue(); //vport.getViewPosition().y;
      g.setColor(THUMB_COLOR);
      Rectangle s = at.createTransformedShape(thumbRect).getBounds();
      g.fillRect(x, y+itop+s.y, getIconWidth(), s.height);
    }
  }
  @Override public int getIconWidth() {
    return 8;
  }
  @Override public int getIconHeight() {
    JViewport vport = Objects.requireNonNull(
        (JViewport)SwingUtilities.getAncestorOfClass(JViewport.class, textArea));
    return vport.getHeight();
  }
});

scroll.setVerticalScrollBar(scrollbar);
/*
// Fixed Versions: 7 (b134)
scroll.setRowHeaderView(label);
/*/
// [JDK-6826074] JScrollPane does not revalidate the component hierarchy after scrolling - Java Bug System
// https://bugs.openjdk.java.net/browse/JDK-6826074
// Affected Versions: 6u12,6u16,7
JViewport vp = new JViewport() {
  @Override public void setViewPosition(Point p) {
    super.setViewPosition(p);
    revalidate();
  }
};
vp.setView(label);
scroll.setRowHeader(vp);

MatteBorder + Icon + RowHeader

JScrollBar scrollBar = new JScrollBar(JScrollBar.VERTICAL) {
  @Override public Dimension getPreferredSize() {
    Dimension d = super.getPreferredSize();
    d.width += getInsets().left;
    return d;
  }
  @Override public void updateUI() {
    super.updateUI();
    setBorder(BorderFactory.createMatteBorder(0, 4, 0, 0, new Icon() {
      @Override public void paintIcon(Component c, Graphics g, int x, int y) {
        //...
      }
      @Override public int getIconWidth() {
        return getInsets().left;
      }
      @Override public int getIconHeight() {
        return getHeight();
      }
    }));
  }
};
scroll.setVerticalScrollBar(scrollBar);

References

2013/01/08

make a translucent JButton

Code

class TranslucentButton extends JButton{
  private static final Color TL = new Color(1f,1f,1f,.2f);
  private static final Color BR = new Color(0f,0f,0f,.4f);
  private static final Color ST = new Color(1f,1f,1f,.2f);
  private static final Color SB = new Color(1f,1f,1f,.1f);
  private Color ssc;
  private Color bgc;
  private int r = 8;
  public TranslucentButton(String text) {
    super(text);
  }
  public TranslucentButton(String text, Icon icon) {
    super(text, icon);
  }
  @Override public void updateUI() {
    super.updateUI();
    setContentAreaFilled(false);
    setFocusPainted(false);
    setOpaque(false);
    setForeground(Color.WHITE);
  }
  @Override protected void paintComponent(Graphics g) {
    int x = 0;
    int y = 0;
    int w = getWidth();
    int h = getHeight();
    Graphics2D g2 = (Graphics2D)g.create();
    g2.setRenderingHint(
      RenderingHints.KEY_ANTIALIASING,
      RenderingHints.VALUE_ANTIALIAS_ON);
    Shape area = new RoundRectangle2D.Float(x, y, w-1, h-1, r, r);
    ssc = TL;
    bgc = BR;
    ButtonModel m = getModel();
    if(m.isPressed()) {
      ssc = SB;
      bgc = ST;
    }else if(m.isRollover()) {
      ssc = ST;
      bgc = SB;
    }
    g2.setPaint(new GradientPaint(x, y, ssc, x, y+h, bgc, true));
    g2.fill(area);
    g2.setPaint(BR);
    g2.draw(area);
    g2.dispose();
    super.paintComponent(g);
  }
}
private static String makeTitleWithIcon(URL u, String t, String a) {
  return String.format(
    "<html><p align='%s'><img src='%s' align='%s' />&nbsp;%s", a, u, a, t);
}
private static AbstractButton makeButton(String title) {
  return new JButton(title) {
    @Override public void updateUI() {
      super.updateUI();
      setVerticalAlignment(SwingConstants.CENTER);
      setVerticalTextPosition(SwingConstants.CENTER);
      setHorizontalAlignment(SwingConstants.CENTER);
      setHorizontalTextPosition(SwingConstants.CENTER);
      setBorder(BorderFactory.createEmptyBorder());
      //setBorderPainted(false);
      setContentAreaFilled(false);
      setFocusPainted(false);
      setOpaque(false);
      setForeground(Color.WHITE);
      setIcon(new TranslucentButtonIcon());
    }
  };
}
JLabel label = new JLabel("JLabel", icon, SwingConstants.CENTER);
label.setForeground(Color.WHITE);
label.setAlignmentX(.5f);
b = makeButton("");
b.setAlignmentX(.5f);
JPanel p = new JPanel();
p.setLayout(new OverlayLayout(p));
p.setOpaque(false);
p.add(label);
p.add(b);
add(p);

References