Google Tag Manager

2019/04/25

aterai

Use the GridBagLayout to layout the JButton like a keyboard

Code

private static final String[][] KEYS = {
  {"`", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "=", "BS"},
  {"Tab", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "[", "]", "\\", ""},
  {"Ctrl", "A", "S", "D", "F", "G", "H", "J", "K", "L", ";", "'", "Enter", ""},
  {"Shift", "Z", "X", "C", "V", "B", "N", "M", ",", ".", "/", "", "↑"},
  {"Fn", "Alt", "                             ", "Alt", "←", "↓", "→"}
};

private static Component makeKeyboardPanel() {
  JPanel keyboard = new JPanel(new GridBagLayout());

  GridBagConstraints c = new GridBagConstraints();
  c.fill = GridBagConstraints.BOTH;
  c.gridy = 50;
  for (int i = 0; i < KEYS[0].length * 2; i++) {
    c.gridx = i;
    keyboard.add(Box.createHorizontalStrut(KeyButton.SIZE));
  }

  for (int row = 0; row < KEYS.length; row++) {
    c.gridx = 0;
    c.gridy = row;
    for (int col = 0; col < KEYS[row].length; col++) {
      String key = KEYS[row][col];
      int len = key.length();
      c.gridwidth = len > 10 ? 14
                  : len > 4  ? 4
                  : len > 1  ? 3
                  : len == 1 ? 2 : 1;
      if (key.isEmpty()) {
        keyboard.add(Box.createHorizontalStrut(KeyButton.SIZE), c);
      } else {
        keyboard.add(new KeyButton(key, len <= 2), c);
      }
      c.gridx += c.gridwidth;
    }
  }
  EventQueue.invokeLater(() -> SwingUtilities.updateComponentTreeUI(keyboard));
  return keyboard;
}

References

2019/03/27

aterai

Perform hover effect animation using RadialGradientPaint on soft clipped JButton

Code

protected void update() {
  if (!getBounds().equals(base)) {
    base = getBounds();
    int w = getWidth();
    int h = getHeight();
    if (w > 0 && h > 0) {
      buf = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
    }
    shape = new RoundRectangle2D.Double(
      0, 0, w - 1, h - 1, ARC_WIDTH, ARC_HEIGHT);
  }
  if (buf == null) {
    return;
  }

  Graphics2D g2 = buf.createGraphics();
  g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                      RenderingHints.VALUE_ANTIALIAS_ON);
  Color c1 = new Color(0x00_F7_23_59, true);
  Color c2 = new Color(0x64_44_05_F7, true);

  g2.setComposite(AlphaComposite.Clear);
  g2.fillRect(0, 0, getWidth(), getHeight());

  g2.setComposite(AlphaComposite.Src);
  g2.setPaint(new Color(getModel().isArmed() ? 0xFF_AA_AA : 0xF7_23_59));
  g2.fill(shape);

  if (radius > 0) {
    int cx = pt.x - radius;
    int cy = pt.y - radius;
    int r2 = radius + radius;
    float[] dist = { 0f, 1f };
    Color[] colors = { c2, c1 };
    g2.setPaint(new RadialGradientPaint(pt, r2, dist, colors));
    g2.setComposite(AlphaComposite.SrcAtop);
    // g2.setClip(shape);
    g2.fill(new Ellipse2D.Double(cx, cy, r2, r2));
  }
  g2.dispose();
}

References

2019/02/27

aterai

Limit the movable range of JSlider's value

Code

public static final int MAXI = 80;
public static final int MINI = 40;

private static class MetalDragLimitedSliderUI extends MetalSliderUI {
  @Override protected TrackListener createTrackListener(JSlider slider) {
    return new TrackListener() {
      @Override public void mouseDragged(MouseEvent e) {
        // case HORIZONTAL:
        int halfThumbWidth = thumbRect.width / 2;
        int thumbLeft = e.getX() - offset;
        int maxPos = xPositionForValue(MAXI) - halfThumbWidth;
        int minPos = xPositionForValue(MINI) - halfThumbWidth;
        if (thumbLeft > maxPos) {
          e.translatePoint(maxPos + offset - e.getX(), 0);
        } else if (thumbLeft < minPos) {
          e.translatePoint(minPos + offset - e.getX(), 0);
        }
        super.mouseDragged(e);
      }
    };
  }
}

private static JSlider makeSilder(String title) {
  JSlider slider = new JSlider(0, 100, 40);
  slider.setBorder(BorderFactory.createTitledBorder(title));
  slider.setMajorTickSpacing(10);
  slider.setPaintTicks(true);
  slider.setPaintLabels(true);
  Dictionary<?, ?> dictionary = slider.getLabelTable();
  if (Objects.nonNull(dictionary)) {
    Enumeration<?> elements = dictionary.elements();
    while (elements.hasMoreElements()) {
      JLabel label = (JLabel) elements.nextElement();
      int v = Integer.parseInt(label.getText());
      if (v > MAXI || v < MINI) {
        label.setForeground(Color.RED);
      }
    }
  }
  slider.getModel().addChangeListener(e -> {
    BoundedRangeModel m = (BoundedRangeModel) e.getSource();
    if (m.getValue() > MAXI) {
      m.setValue(MAXI);
    } else if (m.getValue() < MINI) {
      m.setValue(MINI);
    }
  });
  return slider;
}

References

2019/01/30

aterai

Swap the position of the child components in the JSplitPane

Code

JSplitPane sp = new JSplitPane();
sp.setLeftComponent(new JScrollPane(new JTree()));
sp.setRightComponent(new JScrollPane(new JTable(6, 3)));
sp.setResizeWeight(.4);

JButton button = new JButton("swap");
button.setFocusable(false);
button.addActionListener(e -> {
  Component left = sp.getLeftComponent();
  Component right = sp.getRightComponent();

  // sp.removeAll(); // Divider is also removed
  sp.remove(left);
  sp.remove(right);
  // or: https://stackoverflow.com/questions/4871874/java-problem-with-jsplitpane
  // sp.setLeftComponent(null);
  // sp.setRightComponent(null);

  sp.setLeftComponent(right);
  sp.setRightComponent(left);

  sp.setResizeWeight(1d - sp.getResizeWeight());
  if (check.isSelected()) {
    sp.setDividerLocation(sp.getDividerLocation());
  }
});

References