Google Tag Manager

2012/12/09

Combine five JButtons to make CompoundButton

Code

private static JComponent makeCompoundButton(final Dimension d) {
  JPanel p = new JPanel() {
    @Override public Dimension getPreferredSize() {
      return d;
    }
  };
  p.setLayout(new OverlayLayout(p));
  p.add(new CompoundButton(d, ButtonLocation.NORTH));
  p.add(new CompoundButton(d, ButtonLocation.SOUTH));
  p.add(new CompoundButton(d, ButtonLocation.EAST));
  p.add(new CompoundButton(d, ButtonLocation.WEST));
  p.add(new CompoundButton(d, ButtonLocation.CENTER));
  return p;
}

class CompoundButton extends JButton {
  protected final Color fc = new Color(100, 150, 255, 200);
  protected final Color ac = new Color(230, 230, 230);
  protected final Color rc = Color.ORANGE;
  protected Shape shape;
  protected Shape base = null;
  private final ButtonLocation bl;
  private final Dimension dim;
  public CompoundButton(Dimension d, ButtonLocation bl) {
    super();
    this.dim = d;
    this.bl = bl;
    setIcon(new Icon() {
      @Override public void paintIcon(Component c, Graphics g, int x, int y) {
        Graphics2D g2 = (Graphics2D) g.create();
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                            RenderingHints.VALUE_ANTIALIAS_ON);
        if (getModel().isArmed()) {
          g2.setColor(ac);
          g2.fill(shape);
        } else if (isRolloverEnabled() && getModel().isRollover()) {
          paintFocusAndRollover(g2, rc);
        } else if (hasFocus()) {
          paintFocusAndRollover(g2, fc);
        } else {
          g2.setColor(getBackground());
          g2.fill(shape);
        }
        g2.dispose();
      }

      @Override public int getIconWidth()  {
        return dim.width;
      }

      @Override public int getIconHeight() {
        return dim.height;
      }
    });
    setFocusPainted(false);
    setContentAreaFilled(false);
    setBackground(new Color(250, 250, 250));
    initShape();
  }

  @Override public Dimension getPreferredSize() {
    return dim;
  }

  protected void initShape() {
    if (!getBounds().equals(base)) {
      base = getBounds();
      float ww = getWidth() * .5f;
      float xx = ww * .5f;
      Shape inner = new Ellipse2D.Float(xx, xx, ww, ww);
      if (ButtonLocation.CENTER == bl) {
        shape = inner;
      } else {
        Shape outer = new Arc2D.Float(
          1, 1, getWidth() - 2, getHeight() - 2,
          bl.getStartDegree(), 90f, Arc2D.PIE);
        Area area = new Area(outer);
        area.subtract(new Area(inner));
        shape = area;
      }
    }
  }

  private void paintFocusAndRollover(Graphics2D g2, Color color) {
    g2.setPaint(new GradientPaint(
        0, 0, color, getWidth() - 1, getHeight() - 1, color.brighter(), true));
    g2.fill(shape);
    g2.setColor(getBackground());
  }

  @Override protected void paintComponent(Graphics g) {
    initShape();
    super.paintComponent(g);
  }

  @Override protected void paintBorder(Graphics g) {
    Graphics2D g2 = (Graphics2D) g.create();
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                        RenderingHints.VALUE_ANTIALIAS_ON);
    g2.setColor(getForeground());
    g2.draw(shape);
    g2.dispose();
  }

  @Override public boolean contains(int x, int y) {
    // initShape();
    return shape.contains(x, y);
  }
}

References

2012/11/20

Make a ToggleButtonBar with JRadioButtons

Code

class ToggleButtonBarCellIcon implements Icon {
  private static final Color TL = new Color(1f, 1f, 1f, .2f);
  private static final Color BR = new Color(0f, 0f, 0f, .2f);
  private static final Color ST = new Color(1f, 1f, 1f, .4f);
  private static final Color SB = new Color(1f, 1f, 1f, .1f);
  private Color ssc;
  private Color bgc;

  @Override public void paintIcon(Component c, Graphics g, int x, int y) {
    int r = 8;
    int w = c.getWidth();
    int h = c.getHeight();

    Container parent = c.getParent();
    if (parent == null) {
      return;
    }

    Graphics2D g2 = (Graphics2D) g.create();
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                        RenderingHints.VALUE_ANTIALIAS_ON);
    Path2D p = new Path2D.Float();

    if (c == parent.getComponent(0)) {
      // JButton.segmentPosition: first
      // :first-child
      p.moveTo(x, y + r);
      p.quadTo(x, y, x + r, y);
      p.lineTo(x + w, y);
      p.lineTo(x + w, y + h);
      p.lineTo(x + r, y + h);
      p.quadTo(x, y + h, x, y + h - r);
    } else if (c == parent.getComponent(parent.getComponentCount() - 1)) {
      // JButton.segmentPosition: last
      // :last-child
      p.moveTo(x, y);
      p.lineTo(x + w - r, y);
      p.quadTo(x + w, y, x + w, y + r);
      p.lineTo(x + w, y + h - r);
      p.quadTo(x + w, y + h, x + w - r, y + h);
      p.lineTo(x, y + h);
    } else {
      // JButton.segmentPosition: middle
      p.moveTo(x, y);
      p.lineTo(x + w, y);
      p.lineTo(x + w, y + h);
      p.lineTo(x, y + h);
    }
    p.closePath();
    Area area = new Area(p);

    g2.setPaint(c.getBackground());
    g2.fill(area);

    ssc = TL;
    bgc = BR;
    if (c instanceof AbstractButton) {
      ButtonModel m = ((AbstractButton) c).getModel();
      if (m.isSelected() || 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();
  }

  @Override public int getIconWidth()  {
    return 80;
  }

  @Override public int getIconHeight() {
    return 20;
  }
}

References

2012/10/29

Delete button in a JComboBox popup menu items

Code

class CellButtonsMouseListener extends MouseAdapter {
  @Override public void mouseMoved(MouseEvent e) {
    JList<?> list = (JList<?>) e.getComponent();
    Point pt = e.getPoint();
    int index = list.locationToIndex(pt);
    ButtonsRenderer<?> renderer = (ButtonsRenderer<?>) list.getCellRenderer();
    renderer.rolloverIndex = Objects.nonNull(getButton(list, pt, index)) ? index : -1;
    list.repaint();
  }

  @Override public void mousePressed(MouseEvent e) {
    e.getComponent().repaint();
  }

  @Override public void mouseReleased(MouseEvent e) {
    JList<?> list = (JList<?>) e.getComponent();
    Point pt = e.getPoint();
    int index = list.locationToIndex(pt);
    if (index >= 0) {
      JButton button = getButton(list, pt, index);
      if (Objects.nonNull(button)) {
        button.doClick();
      }
    }
    ((ButtonsRenderer<?>) list.getCellRenderer()).rolloverIndex = -1;
    list.repaint();
  }

  @Override public void mouseExited(MouseEvent e) {
    JList<?> list = (JList<?>) e.getComponent();
    ((ButtonsRenderer<?>) list.getCellRenderer()).rolloverIndex = -1;
  }

  private static <E> JButton getButton(JList<E> list, Point pt, int index) {
    E proto = list.getPrototypeCellValue();
    Component c = list.getCellRenderer().getListCellRendererComponent(
        list, proto, index, false, false);
    Rectangle r = list.getCellBounds(index, index);
    c.setBounds(r);
    // c.doLayout(); // may be needed for other layout managers (eg. FlowLayout)
    pt.translate(-r.x, -r.y);
    return Optional.ofNullable(SwingUtilities.getDeepestComponentAt(c, pt.x, pt.y))
        .filter(JButton.class::isInstance).map(JButton.class::cast).orElse(null);
  }
}

References

2012/09/24

create a gradient titled separator

Code

class TitledSeparator extends JLabel {
  private final String title;
  private final Color target;
  private final int height;
  private final int titlePosition;

  public TitledSeparator(String title, int height, int titlePosition) {
    this(title, null, height, titlePosition);
  }

  public TitledSeparator(
      String title, Color target, int height, int titlePosition) {
    super();
    this.title = title;
    this.target = target;
    this.height = height;
    this.titlePosition = titlePosition;
    updateBorder();
  }

  private void updateBorder() {
    Icon icon = new TitledSeparatorIcon();
    setBorder(BorderFactory.createTitledBorder(
        BorderFactory.createMatteBorder(height, 0, 0, 0, icon), title,
        TitledBorder.DEFAULT_JUSTIFICATION, titlePosition));
  }

  @Override public Dimension getMaximumSize() {
    Dimension d = super.getPreferredSize();
    d.width = Short.MAX_VALUE;
    return d;
  }

  @Override public void updateUI() {
    super.updateUI();
    EventQueue.invokeLater(this::updateBorder);
  }

  private class TitledSeparatorIcon implements Icon {
    private int width = -1;
    private Paint painter1;
    private Paint painter2;

    @Override public void paintIcon(Component c, Graphics g, int x, int y) {
      int w = c.getWidth();
      if (w != width || painter1 == null || painter2 == null) {
        width = w;
        Point2D start = new Point2D.Float();
        Point2D end = new Point2D.Float(width, 0);
        float[] dist = {0f, 1f};
        Color ec = Optional.ofNullable(getBackground())
            .orElse(UIManager.getColor("Panel.background"));
        Color sc = Optional.ofNullable(target).orElse(ec);
        painter1 = new LinearGradientPaint(
            start, end, dist, new Color[] {sc.darker(), ec});
        painter2 = new LinearGradientPaint(
            start, end, dist, new Color[] {sc.brighter(), ec});
      }
      int h = getIconHeight() / 2;
      Graphics2D g2  = (Graphics2D) g.create();
      g2.setPaint(painter1);
      g2.fillRect(x, y, width, getIconHeight());
      g2.setPaint(painter2);
      g2.fillRect(x, y + h, width, getIconHeight() - h);
      g2.dispose();
    }

    @Override public int getIconWidth() {
      return 200; // sample width
    }

    @Override public int getIconHeight() {
      return height;
    }
  }
}

References

2012/08/17

JFileChooser with file already exists Dialog

Code

JFileChooser fileChooser = new JFileChooser() {
  @Override public void approveSelection() {
    File f = getSelectedFile();
    if (f.exists() && getDialogType() == SAVE_DIALOG) {
      String m = String.format(
          "<html>%s already exists.<br>Do you want to replace it?",
          f.getAbsolutePath());
      int rv = JOptionPane.showConfirmDialog(
          this, m, "Save As", JOptionPane.YES_NO_OPTION);
      if (rv != JOptionPane.YES_OPTION) {
        return;
      }
    }
    super.approveSelection();
  }
};

References