Google Tag Manager

2008/09/16

JTable Tri-state row sorting (cycle through ascending descending unsorted)

Code

TableModel model = new DefaultTableModel();
JTable table = new JTable(model);
// sort toggles ascending descending unsorted (like TableSorter.java)
TableRowSorter< TableModel > sorter = new TableRowSorter< TableModel >(model) {
  @Override
  public void toggleSortOrder(int column) {
    if(column >= 0 && column < getModelWrapper().getColumnCount() && isSortable(column)) {
      List< SortKey > keys = new ArrayList< SortKey >(getSortKeys());
      if(!keys.isEmpty()) {
        SortKey sortKey = keys.get(0);
        if(sortKey.getColumn()==column && sortKey.getSortOrder()==SortOrder.DESCENDING) {
          setSortKeys(null);
          return;
        }
      }
    }
    super.toggleSortOrder(column);
  }
};
table.setRowSorter(sorter);

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

2008/08/13

Multi Column JComboBox

Code

class MultiColumnCellRenderer extends JPanel implements ListCellRenderer {
  private final JLabel leftLabel = new JLabel();
  private final JLabel rightLabel;

  public MultiColumnCellRenderer(int rightWidth) {
    super(new BorderLayout());
    this.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));

    leftLabel.setOpaque(false);
    leftLabel.setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 0));

    final Dimension dim = new Dimension(rightWidth, 0);
    rightLabel = new JLabel() {
      @Override public Dimension getPreferredSize() {
        return dim;
      }
    };
    rightLabel.setOpaque(false);
    rightLabel.setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 2));
    rightLabel.setForeground(Color.GRAY);
    rightLabel.setHorizontalAlignment(SwingConstants.RIGHT);

    this.add(leftLabel);
    this.add(rightLabel, BorderLayout.EAST);
  }

  @Override public Component getListCellRendererComponent(
      JList list, Object value, int index,
      boolean isSelected, boolean cellHasFocus) {
    LRItem item = (LRItem) value;
    leftLabel.setText(item.getLeftText());
    rightLabel.setText(item.getRightText());

    leftLabel.setFont(list.getFont());
    rightLabel.setFont(list.getFont());

    if (index < 0) {
      leftLabel.setForeground(list.getForeground());
      this.setOpaque(false);
    } else {
      leftLabel.setForeground(
          isSelected ? list.getSelectionForeground() : list.getForeground());
      this.setBackground(
          isSelected ? list.getSelectionBackground() : list.getBackground());
      this.setOpaque(true);
    }
    return this;
  }

  @Override public Dimension getPreferredSize() {
    Dimension d = super.getPreferredSize();
    return new Dimension(0, d.height);
  }

  @Override public void updateUI() {
    super.updateUI();
    this.setName("List.cellRenderer");
  }
}

References

2008/07/29

create round image JButton

Code

class RoundButton extends JButton {
  protected Shape base;
  protected Shape shape

  public RoundButton() {
    this(null, null);
  }

  public RoundButton(Icon icon) {
    this(null, icon);
  }

  public RoundButton(String text) {
    this(text, null);
  }

  public RoundButton(Action a) {
    this();
    setAction(a);
  }

  public RoundButton(String text, Icon icon) {
    setModel(new DefaultButtonModel());
    init(text, icon);
    if (icon == null) {
      return;
    }
    setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
    setBackground(Color.BLACK);
    setContentAreaFilled(false);
    setFocusPainted(false);
    // setVerticalAlignment(SwingConstants.TOP);
    setAlignmentY(Component.TOP_ALIGNMENT);
    initShape();
  }

  protected void initShape() {
    if (!getBounds().equals(base)) {
      Dimension s = getPreferredSize();
      base = getBounds();
      shape = new Ellipse2D.Float(0, 0, s.width - 1, s.height - 1);
    }
  }

  @Override public Dimension getPreferredSize() {
    Icon icon = getIcon();
    Insets i = getInsets();
    int iw = Math.max(icon.getIconWidth(), icon.getIconHeight());
    return new Dimension(iw + i.right + i.left, iw + i.top + i.bottom);
  }

  @Override protected void paintBorder(Graphics g) {
    initShape();
    Graphics2D g2 = (Graphics2D) g.create();
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                        RenderingHints.VALUE_ANTIALIAS_ON);
    g2.setColor(getBackground());
    // g2.setStroke(new BasicStroke(1f));
    g2.draw(shape);
    g2.dispose();
  }

  @Override public boolean contains(int x, int y) {
    initShape();
    return shape.contains(x, y);
    // Transparent color is 0, making it unclickable:
    // or return super.contains(x, y) && ((image.getRGB(x, y) >> 24) & 0xff) > 0;
  }
}

References

2008/06/25

Mouse Drag Auto Scrolling

Code

class ViewportDragScrollListener extends MouseAdapter
                                 implements HierarchyListener {
  private static final int SPEED = 4;
  private static final int DELAY = 10;
  private final Cursor dc;
  private final Cursor hc = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
  private final Timer scroller;
  private final JComponent label;
  private Point startPt = new Point();
  private Point move    = new Point();

  public ViewportDragScrollListener(JComponent comp) {
    this.label = comp;
    this.dc = comp.getCursor();
    this.scroller = new Timer(DELAY, new ActionListener() {
      @Override public void actionPerformed(ActionEvent e) {
        Container c = SwingUtilities.getAncestorOfClass(
            JViewport.class, label);
        if (c instanceof JViewport.class) {
          JViewport vport = (JViewport) c;
          Rectangle rect = vport.getViewRect();
          rect.translate(move.x, move.y);
          label.scrollRectToVisible(rect);
        }
      }
    });
  }

  @Override public void hierarchyChanged(HierarchyEvent e) {
    JComponent c = (JComponent) e.getSource();
    if ((e.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0
        && !c.isDisplayable()) {
      scroller.stop();
    }
  }

  @Override public void mouseDragged(MouseEvent e) {
    JViewport vport = (JViewport) e.getSource();
    Point pt = e.getPoint();
    int dx = startPt.x - pt.x;
    int dy = startPt.y - pt.y;
    Rectangle rect = vport.getViewRect();
    rect.translate(dx, dy);
    label.scrollRectToVisible(rect);
    move.setLocation(SPEED * dx, SPEED * dy);
    startPt.setLocation(pt);
  }

  @Override public void mousePressed(MouseEvent e) {
    e.getComponent().setCursor(hc); // label.setCursor(hc);
    startPt.setLocation(e.getPoint());
    move.setLocation(0, 0);
    scroller.stop();
  }

  @Override public void mouseReleased(MouseEvent e) {
    e.getComponent().setCursor(dc); // label.setCursor(dc);
    scroller.start();
  }

  @Override public void mouseExited(MouseEvent e) {
    e.getComponent().setCursor(dc); // label.setCursor(dc);
    move.setLocation(0, 0);
    scroller.stop();
  }
}

References