Google Tag Manager

2009/02/27

HyperLink in JTable Cell

Code

class UriRenderer extends DefaultTableCellRenderer implements MouseListener, MouseMotionListener {
  private int viewRowIndex = -1;
  private int viewColumnIndex = -1;
  private boolean isRollover;

  @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
    Component c = super.getTableCellRendererComponent(
        table, value, isSelected, false, row, column);
    if (c instanceof JLabel) {
      JLabel l = (JLabel) c;
      // @see https://ateraimemo.com/Swing/ClippedHtmlLabel.html
      // String str = SwingUtilities.layoutCompoundLabel(...);
      String str = Objects.toString(value, "");
      if (isRolloverCell(table, row, column)) {
        l.setText("<html><u><font color='blue'>" + str);
      } else if (hasFocus) {
        l.setText("<html><font color='blue'>" + str);
      } else {
        l.setText(str);
      }
    }
    return c;
  }

  protected boolean isRolloverCell(JTable table, int row, int column) {
    return !table.isEditing() && viewRowIndex == row && viewColumnIndex == column && isRollover;
  }

  private static boolean isUriColumn(JTable table, int column) {
    return column >= 0 && table.getColumnClass(column).equals(URI.class);
  }

  @Override public void mouseMoved(MouseEvent e) {
    JTable table = (JTable) e.getComponent();
    Point pt = e.getPoint();
    int prevRow = viewRowIndex;
    int prevCol = viewColumnIndex;
    viewRowIndex = table.rowAtPoint(pt);
    viewColumnIndex = table.columnAtPoint(pt);
    boolean isSameCell = viewRowIndex == prevRow && viewColumnIndex == prevCol;

    boolean prevRollover = isRollover;
    isRollover = isUriColumn(table, viewColumnIndex);
    boolean isNotRollover = isRollover == prevRollover && !isRollover; // && !prevRollover;

    if (isSameCell && isNotRollover) {
      return;
    }

    // >>>> HyperlinkCellRenderer.java
    // @see https://github.com/sjas/swingset3/blob/master/trunk/SwingSet3/src/com/sun/swingset3/demos/table/HyperlinkCellRenderer.java
    Rectangle repaintRect;
    if (isRollover) {
      Rectangle r = table.getCellRect(viewRowIndex, viewColumnIndex, false);
      repaintRect = prevRollover ? r.union(table.getCellRect(prevRow, prevCol, false)) : r;
    } else { // if (prevRollover) {
      repaintRect = table.getCellRect(prevRow, prevCol, false);
    }
    table.repaint(repaintRect);
    // <<<<
    // table.repaint();
  }

  @Override public void mouseExited(MouseEvent e) {
    JTable table = (JTable) e.getComponent();
    if (isUriColumn(table, viewColumnIndex)) {
      table.repaint(table.getCellRect(viewRowIndex, viewColumnIndex, false));
      viewRowIndex = -1;
      viewColumnIndex = -1;
      isRollover = false;
    }
  }

  @Override public void mouseClicked(MouseEvent e) {
    JTable table = (JTable) e.getComponent();
    Point pt = e.getPoint();
    int col = table.columnAtPoint(pt);
    if (isUriColumn(table, col)) {
      int crow = table.rowAtPoint(pt);
      URI uri = (URI) table.getValueAt(crow, col);
      try {
        if (Desktop.isDesktopSupported()) {
          Desktop.getDesktop().browse(uri);
        }
      } catch (IOException ex) {
        // Logger.getGlobal().severe(ex::getMessage);
        UIManager.getLookAndFeel().provideErrorFeedback(e.getComponent());
      }
    }
  }

  @Override public void mouseDragged(MouseEvent e) {
    /* not needed */
  }

  @Override public void mouseEntered(MouseEvent e) {
    /* not needed */
  }

  @Override public void mousePressed(MouseEvent e) {
    /* not needed */
  }

  @Override public void mouseReleased(MouseEvent e) {
    /* not needed */
  }
}

References

2009/02/26

Use JScrollBar as JSlider

Code

int step = 5;
int extent = 20;
int min = 0;
int max = extent * 10; // 200
int value = 50;
JScrollBar scrollbar = new JScrollBar(
  JScrollBar.HORIZONTAL, value, extent, min, max + extent);
scrollbar.setUnitIncrement(step);
scrollbar.getModel().addChangeListener(new ChangeListener() {
  @Override public void stateChanged(ChangeEvent e) {
    BoundedRangeModel m = (BoundedRangeModel) e.getSource();
    spinner.setValue(m.getValue());
  }
});
JSpinner spinner = new JSpinner(new SpinnerNumberModel(value, min, max, step));

References

2009/02/16

JTableHeader CheckBox

Code

enum Status { SELECTED, DESELECTED, INDETERMINATE }

class HeaderRenderer extends JCheckBox implements TableCellRenderer {
  private final JLabel label = new JLabel("Check All");
  private final int targetColumnIndex;

  public HeaderRenderer(JTableHeader header, int index) {
    super((String) null);
    this.targetColumnIndex = index;
    setOpaque(false);
    setFont(header.getFont());
    header.addMouseListener(new MouseAdapter() {
      @Override public void mouseClicked(MouseEvent e) {
        JTableHeader header = (JTableHeader) e.getComponent();
        JTable table = header.getTable();
        TableColumnModel columnModel = table.getColumnModel();
        int vci = columnModel.getColumnIndexAtX(e.getX());
        int mci = table.convertColumnIndexToModel(vci);
        if (mci == targetColumnIndex) {
          TableColumn column = columnModel.getColumn(vci);
          boolean b = column.getHeaderValue() == Status.DESELECTED;
          TableModel m = table.getModel();
          for (int i = 0; i < m.getRowCount(); i++) {
            m.setValueAt(b, i, mci);
          }
          column.setHeaderValue(b ? Status.SELECTED : Status.DESELECTED);
          // header.repaint();
        }
      }
    });
  }

  @Override public Component getTableCellRendererComponent(
        JTable tbl, Object val, boolean isS, boolean hasF, int row, int col) {
    TableCellRenderer r = tbl.getTableHeader().getDefaultRenderer();
    JLabel l = (JLabel) r.getTableCellRendererComponent(tbl, val, isS, hasF, row, col);
    if (targetColumnIndex == tbl.convertColumnIndexToModel(col)) {
      if (val instanceof Status) {
        switch ((Status) val) {
        case SELECTED:
          setSelected(true);
          setEnabled(true);
          break;
        case DESELECTED:
          setSelected(false);
          setEnabled(true);
          break;
        case INDETERMINATE:
          setSelected(true);
          setEnabled(false);
          break;
        default:
          throw new AssertionError("Unknown Status");
        }
      } else {
        setSelected(true);
        setEnabled(false);
      }
      label.setIcon(new ComponentIcon(this));
      l.setIcon(new ComponentIcon(label));
      l.setText(null);
    }
    return l;
  }
}

class ComponentIcon implements Icon {
  private final JComponent cmp;

  public ComponentIcon(JComponent cmp) {
    this.cmp = cmp;
  }

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

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

  @Override public void paintIcon(Component c, Graphics g, int x, int y) {
    SwingUtilities.paintComponent(
        g, cmp, c.getParent(), x, y, getIconWidth(), getIconHeight());
  }
}

References