Google Tag Manager

2017/04/28

Disable any items in JList

Code

Set disableIndexSet = new HashSet<>();

JList 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;
  }
});

initDisableIndex(disableIndexSet);
ActionMap am = list.getActionMap();
am.put("selectNextRow", new AbstractAction() {
  @Override public void actionPerformed(ActionEvent e) {
    int index = list.getSelectedIndex();
    for (int i = index + 1; i < list.getModel().getSize(); i++) {
      if (!disableIndexSet.contains(i)) {
        list.setSelectedIndex(i);
        break;
      }
    }
  }
});
am.put("selectPreviousRow", new AbstractAction() {
  @Override public void actionPerformed(ActionEvent e) {
    int index = list.getSelectedIndex();
    for (int i = index - 1; i >= 0; i--) {
      if (!disableIndexSet.contains(i)) {
        list.setSelectedIndex(i);
        break;
      }
    }
  }
});
//...
protected final void initDisableIndex(Set set) {
  set.clear();
  try {
    set.addAll(Arrays.stream(field.getText().split(","))
      .map(String::trim).filter(s -> !s.isEmpty())
      .map(Integer::valueOf).collect(Collectors.toSet()));
  } catch (NumberFormatException ex) {
    Toolkit.getDefaultToolkit().beep();
    JOptionPane.showMessageDialog(
        field, "invalid value.\n" + ex.getMessage(),
        "Error", JOptionPane.ERROR_MESSAGE);
  }
}

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) { //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