Google Tag Manager

Showing posts with label JTextField. Show all posts
Showing posts with label JTextField. Show all posts

2021/01/31

Draw the upper right, left, and right borders sequentially when JTextField gets focus

Code

class AnimatedBorder extends EmptyBorder {
  private static final int BOTTOM_SPACE = 20;
  private static final double PLAY_TIME = 300d;
  private static final int BORDER = 4;
  private final Timer animator = new Timer(10, null);
  private final transient Stroke stroke = new BasicStroke(BORDER);
  private final transient Stroke bottomStroke = new BasicStroke(BORDER / 2f);
  private long startTime = -1L;
  private final transient List points = new ArrayList<>();
  private transient Shape shape;

  public AnimatedBorder(JComponent c) {
    super(BORDER, BORDER, BORDER + BOTTOM_SPACE, BORDER);
    animator.addActionListener(e -> {
      if (startTime < 0) {
        startTime = System.currentTimeMillis();
      }
      long playTime = System.currentTimeMillis() - startTime;
      double progress = playTime / PLAY_TIME;
      boolean stop = progress > 1d || points.isEmpty();
      if (stop) {
        startTime = -1L;
        ((Timer) e.getSource()).stop();
        c.repaint();
        return;
      }
      Point2D pos = new Point2D.Double();
      pos.setLocation(points.get(0));
      Path2D border = new Path2D.Double();
      border.moveTo(pos.getX(), pos.getY());
      int idx = Math.min(Math.max(0, (int) (points.size() * progress)), points.size() - 1);
      for (int i = 0; i <= idx; i++) {
        pos.setLocation(points.get(i));
        border.lineTo(pos.getX(), pos.getY());
        border.moveTo(pos.getX(), pos.getY());
      }
      border.closePath();
      shape = border;
      c.repaint();
    });
    c.addFocusListener(new FocusListener() {
      @Override public void focusGained(FocusEvent e) {
        Rectangle r = c.getBounds();
        r.height -= BOTTOM_SPACE + 1;
        Path2D p = new Path2D.Double();
        p.moveTo(r.getWidth(), r.getHeight());
        p.lineTo(r.getWidth(), 0d);
        p.lineTo(0d, 0d);
        p.lineTo(0d, r.getHeight());
        p.closePath();
        makePointList(p, points);
        animator.start();
      }

      @Override public void focusLost(FocusEvent e) {
        points.clear();
        shape = null;
        c.repaint();
      }
    });
  }

  @Override public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
    super.paintBorder(c, g, x, y, w, h);
    Graphics2D g2 = (Graphics2D) g.create();
    g2.setPaint(c.isEnabled() ? Color.ORANGE : Color.GRAY);
    g2.translate(x, y);
    g2.setStroke(bottomStroke);
    g2.drawLine(0, h - BOTTOM_SPACE, w - 1, h - BOTTOM_SPACE);
    g2.setStroke(stroke);
    if (shape != null) {
      g2.draw(shape);
    }
    g2.dispose();
  }

  private static void makePointList(Shape shape, List points) {
    points.clear();
    PathIterator pi = shape.getPathIterator(null, .01);
    Point2D prev = new Point2D.Double();
    double delta = .02;
    double threshold = 2d;
    double[] coords = new double[6];
    while (!pi.isDone()) {
      int segment = pi.currentSegment(coords);
      Point2D current = createPoint(coords[0], coords[1]);
      if (segment == PathIterator.SEG_MOVETO) {
        points.add(current);
        prev.setLocation(current);
      } else if (segment == PathIterator.SEG_LINETO) {
        double distance = prev.distance(current);
        double fraction = delta;
        if (distance > threshold) {
          Point2D p = interpolate(prev, current, fraction);
          while (distance > prev.distance(p)) {
            points.add(p);
            fraction += delta;
            p = interpolate(prev, current, fraction);
          }
        } else {
          points.add(current);
        }
        prev.setLocation(current);
      }
      pi.next();
    }
  }

  private static Point2D createPoint(double x, double y) {
    return new Point2D.Double(x, y);
  }

  private static Point2D interpolate(Point2D start, Point2D end, double fraction) {
    double dx = end.getX() - start.getX();
    double dy = end.getY() - start.getY();
    double nx = start.getX() + dx * fraction;
    double ny = start.getY() + dy * fraction;
    return new Point2D.Double(nx, ny);
  }
}

References

2020/05/02

Disable the JOptionPane OK button until text is entered in the JTextField

Code

JPanel panel2 = new JPanel(new GridLayout(2, 1));
JTextField field2 = new JTextField();
Border enabledBorder = field2.getBorder();
Insets i = enabledBorder.getBorderInsets(field2);
Border disabledBorder = BorderFactory.createCompoundBorder(
    BorderFactory.createLineBorder(Color.RED),
    BorderFactory.createEmptyBorder(i.top - 1, i.left - 1, i.bottom - 1, i.right - 1));
String disabledMessage = "Text is required to create ...";
JLabel label2 = new JLabel(" ");
label2.setForeground(Color.RED);
panel2.add(field2);
panel2.add(label2);
if (field2.getText().isEmpty()) {
  field2.setBorder(disabledBorder);
  label2.setText(disabledMessage);
}
field2.addHierarchyListener(e -> {
  Component c = e.getComponent();
  if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0 && c.isShowing()) {
    EventQueue.invokeLater(c::requestFocusInWindow);
  }
});
field2.getDocument().addDocumentListener(new DocumentListener() {
  private void update() {
    boolean verified = !field2.getText().isEmpty();
    JButton b = field2.getRootPane().getDefaultButton();
    if (verified) {
      b.setEnabled(true);
      field2.setBorder(enabledBorder);
      label2.setText(" ");
    } else {
      b.setEnabled(false);
      field2.setBorder(disabledBorder);
      label2.setText(disabledMessage);
    }
  }

  @Override public void insertUpdate(DocumentEvent e) {
    update();
  }

  @Override public void removeUpdate(DocumentEvent e) {
    update();
  }

  @Override public void changedUpdate(DocumentEvent e) {
    update();
  }
});
JButton button2 = new JButton("show");
button2.addActionListener(e -> {
  Component p2 = log.getRootPane();
  EventQueue.invokeLater(() -> {
    JButton b = field2.getRootPane().getDefaultButton();
    if (b != null && field2.getText().isEmpty()) {
      b.setEnabled(false);
    }
  });
  int ret = JOptionPane.showConfirmDialog(
      p2, panel2, "Input text", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
  if (ret == JOptionPane.OK_OPTION) {
    log.setText(field2.getText());
  }
});

References

2015/04/28

ScrollBar for JTextField

Code

scroller.setModel(textField.getHorizontalVisibility());
//...
class EmptyThumbHandler extends ComponentAdapter implements DocumentListener {
  private final BoundedRangeModel emptyThumbModel
    = new DefaultBoundedRangeModel(0, 1, 0, 1);
  private final JTextField textField;
  private final JScrollBar scroller;
  public EmptyThumbHandler(JTextField textField, JScrollBar scroller) {
    super();
    this.textField = textField;
    this.scroller = scroller;
  }

  private void changeThumbModel() {
    EventQueue.invokeLater(new Runnable() {
      @Override public void run() {
        BoundedRangeModel m = textField.getHorizontalVisibility();
        int iv = m.getMaximum() - m.getMinimum() - m.getExtent() - 1;
        if (iv <= 0) {
          scroller.setModel(emptyThumbModel);
        } else {
          scroller.setModel(textField.getHorizontalVisibility());
        }
      }
    });
  }

  @Override public void componentResized(ComponentEvent e) {
    changeThumbModel();
  }

  @Override public void insertUpdate(DocumentEvent e) {
    changeThumbModel();
  }

  @Override public void removeUpdate(DocumentEvent e) {
    changeThumbModel();
  }

  @Override public void changedUpdate(DocumentEvent e) {
    changeThumbModel();
  }
}

References

2014/07/23

Highlight all search pattern matches in the JTextArea

Code

private Pattern getPattern() {
  String text = field.getText();
  if (text == null || text.isEmpty()) {
    return null;
  }
  try {
    String cw = checkWord.isSelected() ? "\\b" : "";
    String pattern = String.format("%s%s%s", cw, text, cw);
    int flags = checkCase.isSelected()
      ? 0
      : Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE;
    return Pattern.compile(pattern, flags);
  } catch (PatternSyntaxException ex) {
    field.setBackground(WARNING_COLOR);
    return null;
  }
}

private void changeHighlight() {
  field.setBackground(Color.WHITE);
  Highlighter highlighter = textArea.getHighlighter();
  highlighter.removeAllHighlights();
  Document doc = textArea.getDocument();
  try {
    Pattern pattern = getPattern();
    if (pattern != null) {
      Matcher matcher = pattern.matcher(doc.getText(0, doc.getLength()));
      int pos = 0;
      while (matcher.find(pos)) {
        int start = matcher.start();
        int end   = matcher.end();
        highlighter.addHighlight(start, end, highlightPainter);
        pos = end;
      }
    }
    JLabel label = layerUI.hint;
    Highlighter.Highlight[] array = highlighter.getHighlights();
    int hits = array.length;
    if (hits == 0) {
      current = -1;
      label.setOpaque(true);
    } else {
      current = (current + hits) % hits;
      label.setOpaque(false);
      Highlighter.Highlight hh = highlighter.getHighlights()[current];
      highlighter.removeHighlight(hh);
      highlighter.addHighlight(
          hh.getStartOffset(), hh.getEndOffset(), currentPainter);
      scrollToCenter(textArea, hh.getStartOffset());
    }
    label.setText(String.format("%02d / %02d%n", current + 1, hits));
  } catch (BadLocationException e) {
    e.printStackTrace();
  }
  field.repaint();
}

References

2013/07/29

JTable highlighting and filtering with regular expression

Code

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

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

  @Override public Component getTableCellRendererComponent(
      JTable table, Object value, boolean isSelected,
      boolean hasFocus, int row, int column) {
    String txt = Objects.toString(value, "");
    Highlighter highlighter = getHighlighter();
    highlighter.removeAllHighlights();
    setText(txt);
    setBackground(isSelected ? BGC : Color.WHITE);
    if (pattern != null && !pattern.isEmpty() && !pattern.equals(prev)) {
      Matcher matcher = Pattern.compile(pattern).matcher(txt);
      int pos = 0;
      while (matcher.find(pos) && !matcher.group().isEmpty()) {
        int start = matcher.start();
        int end   = matcher.end();
        try {
          highlighter.addHighlight(start, end, highlightPainter);
        } catch (BadLocationException | PatternSyntaxException e) {
          e.printStackTrace();
        }
        pos = end;
      }
    }
    return this;
  }
}

References

2012/03/21

Rounded Border for JTextField

Code

JTextField textField02 = new JTextField(20) {
  @Override protected void paintComponent(Graphics g) {
    if (!isOpaque() && getBorder() instanceof RoundedCornerBorder) {
      Graphics2D g2 = (Graphics2D) g.create();
      g2.setPaint(getBackground());
      g2.fill(((RoundedCornerBorder) getBorder()).getBorderShape(
          0, 0, getWidth() - 1, getHeight() - 1));
      g2.dispose();
    }
    super.paintComponent(g);
  }

  @Override public void updateUI() {
    super.updateUI();
    setOpaque(false);
    setBorder(new RoundedCornerBorder());
  }
};
class RoundedCornerBorder extends AbstractBorder {
  private static final Color ALPHA_ZERO = new Color(0x0, true);

  @Override public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
    Graphics2D g2 = (Graphics2D) g.create();
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    Shape border = getBorderShape(x, y, width - 1, height - 1);
    g2.setPaint(ALPHA_ZERO);
    Area corner = new Area(new Rectangle2D.Double(x, y, width, height));
    corner.subtract(new Area(border));
    g2.fill(corner);
    g2.setPaint(Color.GRAY);
    g2.draw(border);
    g2.dispose();
  }

  public Shape getBorderShape(int x, int y, int w, int h) {
    int r = h; //h / 2;
    return new RoundRectangle2D.Double(x, y, w, h, r, r);
  }

  @Override public Insets getBorderInsets(Component c) {
    return new Insets(4, 8, 4, 8);
  }

  @Override public Insets getBorderInsets(Component c, Insets insets) {
    insets.set(4, 8, 4, 8);
    return insets;
  }
}

References

2010/09/21

SearchBar JComboBox

Code

public class BasicSearchBarComboBoxUI extends SearchBarComboBoxUI {
  protected boolean isEditable = true;
  public static javax.swing.plaf.ComponentUI createUI(JComponent c) {
    return new BasicSearchBarComboBoxUI();
  }

  @Override protected void installDefaults() {
    super.installDefaults();
    // comboBox.setEditable(true);
    comboBox.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
    // comboBox.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
  }

  @Override protected LayoutManager createLayoutManager() {
    return new LayoutManager() {
      @Override public void addLayoutComponent(String name, Component comp) {
        /* not needed */
      }

      @Override public void removeLayoutComponent(Component comp) {
        /* not needed */
      }

      @Override public Dimension preferredLayoutSize(Container parent) {
        return parent.getPreferredSize();
      }

      @Override public Dimension minimumLayoutSize(Container parent) {
        return parent.getMinimumSize();
      }

      @Override public void layoutContainer(Container parent) {
        if (!(parent instanceof JComboBox)) {
          return;
        }
        JComboBox<?> cb = (JComboBox<?>) parent;
        Rectangle r = SwingUtilities.calculateInnerArea(cb, null);

        int arrowSize = 0;
        JButton arrowButton = (JButton) cb.getComponent(0);
        if (Objects.nonNull(arrowButton)) {
          Insets arrowInsets = arrowButton.getInsets();
          int bw = arrowButton.getPreferredSize().width + arrowInsets.left + arrowInsets.right;
          arrowButton.setBounds(r.x, r.y, bw, r.height);
          arrowSize = bw;
        }
        JButton loupeButton = null;
        for (Component c : cb.getComponents()) {
          if ("ComboBox.loupeButton".equals(c.getName())) {
            loupeButton = (JButton) c;
            break;
          }
        }
        int loupeSize = 0;
        if (Objects.nonNull(loupeButton)) {
          loupeSize = r.height;
          loupeButton.setBounds(r.x + r.width - loupeSize, r.y, loupeSize, r.height);
        }
        JTextField editor = (JTextField) cb.getEditor().getEditorComponent();
        if (Objects.nonNull(editor)) {
          editor.setBounds(r.x + arrowSize, r.y, r.width - arrowSize - loupeSize, r.height);
        }
      }
    };
  }
  // ...

References

2009/06/03

Color JComboBox

Code

combo01.setModel(makeModel());
combo01.setRenderer(new MyListCellRenderer(combo01.getRenderer()));
combo01.addItemListener(new ItemListener() {
  public void itemStateChanged(ItemEvent e) {
    if(e.getStateChange()!=ItemEvent.SELECTED) return;
    combo01.setBackground(getOEColor(combo01.getSelectedIndex()));
  }
});
combo01.setSelectedIndex(0);
combo01.setBackground(evenBGColor);

final JTextField field = (JTextField) combo02.getEditor().getEditorComponent();
field.setOpaque(true);
field.setBackground(evenBGColor);
combo02.setEditable(true);
combo02.setModel(makeModel());
combo02.setRenderer(new MyListCellRenderer(combo02.getRenderer()));
combo02.addItemListener(new ItemListener() {
  public void itemStateChanged(ItemEvent e) {
    if(e.getStateChange()!=ItemEvent.SELECTED) return;
    field.setBackground(getOEColor(combo02.getSelectedIndex()));
  }
});
combo02.setSelectedIndex(0);

References

2008/09/11

Double-click on each tab and change its name like Excel

Code

private Component tabComponent = null;
private int editing_idx = -1;
private int len = -1;
private Dimension dim;

private void startEditing() {
  // System.out.println("start");
  editing_idx  = tabbedPane.getSelectedIndex();
  tabComponent = tabbedPane.getTabComponentAt(editing_idx);
  tabbedPane.setTabComponentAt(editing_idx, editor);
  editor.setVisible(true);
  editor.setText(tabbedPane.getTitleAt(editing_idx));
  editor.selectAll();
  editor.requestFocusInWindow();
  len = editor.getText().length();
  dim = editor.getPreferredSize();
  editor.setMinimumSize(dim);
}

private void cancelEditing() {
  // System.out.println("cancel");
  if (editing_idx >= 0) {
    tabbedPane.setTabComponentAt(editing_idx, tabComponent);
    editor.setVisible(false);
    editing_idx = -1;
    len = -1;
    tabComponent = null;
    editor.setPreferredSize(null);
  }
}

private void renameTabTitle() {
  // System.out.println("rename");
  String title = editor.getText().trim();
  if (editing_idx >= 0 && !title.isEmpty()) {
    tabbedPane.setTitleAt(editing_idx, title);
  }
  cancelEditing();
}

References