Google Tag Manager

2018/01/29

aterai

Apply LocalDate considering Locale to JTable and display calendar

java -Duser.language=en -jar example.jar
java -Duser.language=fr -jar example.jar

Code

class CalendarViewTableModel< T extends LocalDate> extends DefaultTableModel {
  private final LocalDate startDate;
  private final WeekFields weekFields = WeekFields.of(Locale.getDefault());
  public CalendarViewTableModel(T date) {
    super();
    LocalDate firstDayOfMonth = YearMonth.from(date).atDay(1);
    int dowv = firstDayOfMonth.get(weekFields.dayOfWeek()) - 1;
    startDate = firstDayOfMonth.minusDays(dowv);
  }
  @Override public Class getColumnClass(int column) {
    return LocalDate.class;
  }
  @Override public String getColumnName(int column) {
    return weekFields.getFirstDayOfWeek().plus(column)
      .getDisplayName(TextStyle.SHORT_STANDALONE, Locale.getDefault());
  }
  @Override public int getRowCount() {
    return 6;
  }
  @Override public int getColumnCount() {
    return 7;
  }
  @Override public Object getValueAt(int row, int column) {
    return startDate.plusDays(row * getColumnCount() + column);
  }
  @Override public boolean isCellEditable(int row, int column) {
    return false;
  }
}

References

2017/12/26

aterai

Automatically extend its height when JTextArea gains focus

Code

textArea.addFocusListener(new FocusAdapter() {
  @Override public void focusLost(FocusEvent e) {
    String text = textArea.getText();
    label.setText(text.isEmpty() ? " " : text);
    cardLayout.show(cp, "TextField");
  }
});
label.addFocusListener(new FocusAdapter() {
  @Override public void focusGained(FocusEvent e) {
    cardLayout.show(cp, "TextArea");
    textArea.requestFocusInWindow();
  }
});

References

2017/11/24

aterai

When JTree's node is expanded, collapse all other sibling nodes

Code

JTree tree = new JTree(makeModel());
tree.setRootVisible(false);
tree.addTreeWillExpandListener(new TreeWillExpandListener() {
  private boolean isAdjusting;
  @Override public void treeWillExpand(TreeExpansionEvent e) throws ExpandVetoException {
    if (isAdjusting) {
      return;
    }
    isAdjusting = true;
    collapseFirstHierarchy(tree);
    tree.setSelectionPath(e.getPath());
    isAdjusting = false;
  }
  @Override public void treeWillCollapse(TreeExpansionEvent e) throws ExpandVetoException {
    //throw new ExpandVetoException(e, "Tree collapse cancelled");
  }
});
//...
public static void collapseFirstHierarchy(JTree tree) {
  TreeModel model = tree.getModel();
  DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot();
  Enumeration e = root.breadthFirstEnumeration();
  while (e.hasMoreElements()) {
    DefaultMutableTreeNode node = (DefaultMutableTreeNode) e.nextElement();
    boolean isOverFirstLevel = node.getLevel() > 1;
    if (isOverFirstLevel) { // Collapse only nodes in the first hierarchy
      return;
    } else if (node.isLeaf() || node.isRoot()) {
      continue;
    }
    tree.collapsePath(new TreePath(node.getPath()));
  }
}

References

2017/10/27

aterai

Set Sudoku style border lines created by MatteBorder as cell ruled lines of JTable

Code

static class SudokuCellRenderer extends DefaultTableCellRenderer {
  private final Font font;
  private final Font bold;
  private final Border b0 = BorderFactory.createMatteBorder(
      0, 0, BORDERWIDTH1, BORDERWIDTH1, Color.GRAY);
  private final Border b1 = BorderFactory.createMatteBorder(
      0, 0, BORDERWIDTH2, BORDERWIDTH2, Color.BLACK);
  private final Border b2 = BorderFactory.createCompoundBorder(
      BorderFactory.createMatteBorder(0, 0, BORDERWIDTH2, 0, Color.BLACK),
      BorderFactory.createMatteBorder(0, 0, 0, BORDERWIDTH1, Color.GRAY));
  private final Border b3 = BorderFactory.createCompoundBorder(
      BorderFactory.createMatteBorder(0, 0, 0, BORDERWIDTH2, Color.BLACK),
      BorderFactory.createMatteBorder(0, 0, BORDERWIDTH1, 0, Color.GRAY));
  private final Integer[][] data;
  protected SudokuCellRenderer(Integer[][] src, Font font) {
    super();
    this.font = font;
    this.bold = font.deriveFont(Font.BOLD);
    Integer[][] dest = new Integer[src.length][src[0].length];
    for (int i = 0; i < src.length; i++) {
      System.arraycopy(src[i], 0, dest[i], 0, src[0].length);
    }
    this.data = dest;
  }
  @Override public Component getTableCellRendererComponent(
      JTable table, Object value, boolean isSelected, boolean hasFocus,
      int row, int column) {
    boolean isEditable = data[row][column] == 0;
    super.getTableCellRendererComponent(
        table, value, isEditable && isSelected, hasFocus, row, column);
    if (isEditable && Objects.equals(value, 0)) {
      this.setText(" ");
    }
    setFont(isEditable ? font : bold);
    setHorizontalAlignment(CENTER);
    boolean rf = (row + 1) % 3 == 0;
    boolean cf = (column + 1) % 3 == 0;
    if (rf && cf) {
      setBorder(b1);
    } else if (rf) {
      setBorder(b2);
    } else if (cf) {
      setBorder(b3);
    } else {
      setBorder(b0);
    }
    return this;
  }
}

References

2017/09/28

aterai

Add a JComboBox that selects the encoding at the bottom of JFileChooser

Code

class EncodingFileChooserUI extends MetalFileChooserUI {
  public final JComboBox< String> combo = new JComboBox<>(
      new String[] {"UTF-8", "UTF-16", "Shift_JIS", "EUC-JP"});
  protected EncodingFileChooserUI(JFileChooser filechooser) {
    super(filechooser);
  }
  @Override public void installComponents(JFileChooser fc) {
    super.installComponents(fc);
    JPanel bottomPanel = getBottomPanel();

    JLabel label = new JLabel("Encoding:") {
      @Override public Dimension getPreferredSize() {
        return SwingUtils.stream(bottomPanel)
          .filter(JLabel.class::isInstance).map(JLabel.class::cast)
          .findFirst()
          .map(JLabel::getPreferredSize)
          .orElse(super.getPreferredSize());
      }
    };
    label.setDisplayedMnemonic('E');
    label.setLabelFor(combo);

    JPanel panel = new JPanel();
    panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
    panel.add(label);
    panel.add(combo);

    // 0: fileNamePanel
    // 1: RigidArea
    // 2: filesOfTypePanel
    bottomPanel.add(Box.createRigidArea(new Dimension(1, 5)), 3);
    bottomPanel.add(panel, 4);

    SwingUtils.stream(bottomPanel)
      .filter(JLabel.class::isInstance).map(JLabel.class::cast)
      .forEach(l -> {
        l.setHorizontalAlignment(SwingConstants.RIGHT);
        l.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));
      });
  }
}

References