Google Tag Manager

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) { //NOPMD
    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++) {
      // http://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

2016/12/27

Change the shape of JToolTip to balloon

Code

class BalloonToolTip extends JToolTip {
  private HierarchyListener listener;
  @Override public void updateUI() {
    removeHierarchyListener(listener);
    super.updateUI();
    listener = e -> {
      Component c = e.getComponent();
      if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0 && c.isShowing()) {
        Window w = SwingUtilities.getWindowAncestor(c);
        if (w instanceof JWindow) {
          ((JWindow) w).setBackground(new Color(0x0, true));
        }
      }
    };
    addHierarchyListener(listener);
    setOpaque(false);
    setBorder(BorderFactory.createEmptyBorder(8, 5, 0, 5));
  }
  @Override public Dimension getPreferredSize() {
    Dimension d = super.getPreferredSize();
    d.height = 28;
    return d;
  }
  @Override public void paintComponent(Graphics g) {
    Shape s = makeBalloonShape();
    Graphics2D g2 = (Graphics2D) g.create();
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                        RenderingHints.VALUE_ANTIALIAS_ON);
    g2.setColor(getBackground());
    g2.fill(s);
    g2.setColor(getForeground());
    g2.draw(s);
    g2.dispose();
    super.paintComponent(g);
  }
  private Shape makeBalloonShape() {
    Insets i = getInsets();
    int w = getWidth() - 1;
    int h = getHeight() - 1;
    int v = i.top / 2;
    Polygon triangle = new Polygon();
    triangle.addPoint(i.left + v + v, 0);
    triangle.addPoint(i.left + v, v);
    triangle.addPoint(i.left + v + v + v, v);
    Area area = new Area(new RoundRectangle2D.Float(
        0, v, w, h - i.bottom - v, i.top, i.top));
    area.add(new Area(triangle));
    return area;
  }
}
//...
JList list = new JList(model) {
  @Override public JToolTip createToolTip() {
    JToolTip tip = new BalloonToolTip();
    tip.setComponent(this);
    return tip;
  }
};

References

2016/11/24

Filtering JList items by Regex

Code

DefaultListModel model = new DefaultListModel<>();
JList list = new JList(model) {
  @Override public void updateUI() {
    setSelectionForeground(null);
    setSelectionBackground(null);
    setCellRenderer(null);
    super.updateUI();
    setLayoutOrientation(JList.HORIZONTAL_WRAP);
    setVisibleRowCount(0);
    setFixedCellWidth(82);
    setFixedCellHeight(64);
    setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10));
    setCellRenderer(new ListItemListCellRenderer());
    getSelectionModel().setSelectionMode(
        ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
  }
};
private Optional getPattern() {
  try {
    return Optional.ofNullable(field.getText())
                   .filter(s -> !s.isEmpty())
                   .map(Pattern::compile);
  } catch (PatternSyntaxException ex) {
    return Optional.empty();
  }
}
private void filter() {
  getPattern().ifPresent(pattern -> {
    List selected = list.getSelectedValuesList();
    model.clear();
    Stream.of(defaultModel)
          .filter(item -> pattern.matcher(item.title).find())
          .forEach(model::addElement);
    for (ListItem item : selected) {
      int i = model.indexOf(item);
      list.addSelectionInterval(i, i);
    }
  });
}

References

2016/10/25

Undo redo the selected state of the checkboxes

Code

private BigInteger status = new BigInteger("111000111", 2);
private static final int BIT_LENGTH = 50;
//...
for (int i = 0; i < BIT_LENGTH; i++) {
  BigInteger l = BigInteger.ONE.shiftLeft(i);
  JCheckBox c = new JCheckBox(Integer.toString(i + 1));
  c.addActionListener(e -> {
    JCheckBox cb = (JCheckBox) e.getSource();
    BigInteger newValue = cb.isSelected() ? status.or(l) : status.xor(l);
    undoSupport.postEdit(new StatusEdit(status, newValue));
    status = newValue;
    label.setText(print(status));
  });
  c.setSelected(!status.and(l).equals(BigInteger.ZERO));
  p.add(c);
}

References