Google Tag Manager

Showing posts with label JTable. Show all posts
Showing posts with label JTable. Show all posts

2018/05/25

aterai

Use JTable instead of JList as a drop down list of JComboBox

Code

class DropdownTableComboBox<E extends List<Object>> extends JComboBox<E> {
  protected final transient HighlightListener highlighter = new HighlightListener();
  protected final JTable table = new JTable() {
    @Override public Component prepareRenderer(
          TableCellRenderer renderer, int row, int column) {
      Component c = super.prepareRenderer(renderer, row, column);
      c.setForeground(Color.BLACK);
      if (highlighter.isHighlightableRow(row)) {
        c.setBackground(new Color(255, 200, 200));
      } else if (isRowSelected(row)) {
        c.setBackground(Color.CYAN);
      } else {
        c.setBackground(Color.WHITE);
      }
      return c;
    }
    @Override public void updateUI() {
      removeMouseListener(highlighter);
      removeMouseMotionListener(highlighter);
      super.updateUI();
      addMouseListener(highlighter);
      addMouseMotionListener(highlighter);
      getTableHeader().setReorderingAllowed(false);
    }
  };
  protected final List<E> list;

  protected DropdownTableComboBox(List<E> list, DefaultTableModel model) {
    super();
    this.list = list;
    table.setModel(model);
    list.forEach(this::addItem);
    // list.forEach(model::addRow);
    list.forEach(v -> model.addRow(v.toArray(new Object[0])));
  }

  @Override public void updateUI() {
    super.updateUI();
    EventQueue.invokeLater(() -> {
      setUI(new MetalComboBoxUI() {
        @Override protected ComboPopup createPopup() {
          return new ComboTablePopup(comboBox, table);
        }
      });
      setEditable(false);
    });
  }
  public List<Object> getSelectedRow() {
    return list.get(getSelectedIndex());
  }
}

References

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
java -Duser.language=ar -jar example.jar

Code

class CalendarViewTableModel extends DefaultTableModel {
  private final LocalDate startDate;
  private final WeekFields weekFields = WeekFields.of(Locale.getDefault());
  public CalendarViewTableModel(LocalDate 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/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/06/29

aterai

Automatically adjust the height of JTable's row

Code

class TextAreaCellRenderer extends JTextArea implements TableCellRenderer {
  private final List< List< Integer > > rowAndCellHeightList = new ArrayList<>();

  @Override public void updateUI() {
    super.updateUI();
    setLineWrap(true);
    setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
    setName("Table.cellRenderer");
  }
  @Override public Component getTableCellRendererComponent(
      JTable table, Object value, boolean isSelected, boolean hasFocus,
      int row, int column) {
    setFont(table.getFont());
    setText(Objects.toString(value, ""));
    adjustRowHeight(table, row, column);
    return this;
  }

  /**
   * Calculate the new preferred height for a given row, and sets the height on the table.
   * http://blog.botunge.dk/post/2009/10/09/JTable-multiline-cell-renderer.aspx
   */
  private void adjustRowHeight(JTable table, int row, int column) {
    // The trick to get this to work properly is to set the width of the column to the
    // textarea. The reason for this is that getPreferredSize(), without a width tries
    // to place all the text in one line. By setting the size with the with of the column,
    // getPreferredSize() returnes the proper height which the row should have in
    // order to make room for the text.
    // int cWidth = table.getTableHeader().getColumnModel().getColumn(column).getWidth();
    // int cWidth = table.getCellRect(row, column, false).width; //Ignore IntercellSpacing
    // setSize(new Dimension(cWidth, 1000));

    setBounds(table.getCellRect(row, column, false));
    // doLayout();

    int preferredHeight = getPreferredSize().height;
    while (rowAndCellHeightList.size() <= row) {
      rowAndCellHeightList.add(new ArrayList<>(column));
    }
    List cellHeightList = rowAndCellHeightList.get(row);
    while (cellHeightList.size() <= column) {
      cellHeightList.add(0);
    }
    cellHeightList.set(column, preferredHeight);
    int max = cellHeightList.stream().max(Integer::compare).get();
    if (table.getRowHeight(row) != max) {
      table.setRowHeight(row, max);
    }
  }
  // ...

References

2016/09/28

aterai

Changing JTable header text alignment of specific columns

Code

JTable table2 = makeTable();
table2.getColumnModel().getColumn(0).setHeaderRenderer(
    new HorizontalAlignmentHeaderRenderer(SwingConstants.LEFT));
table2.getColumnModel().getColumn(1).setHeaderRenderer(
    new HorizontalAlignmentHeaderRenderer(SwingConstants.CENTER));
table2.getColumnModel().getColumn(2).setHeaderRenderer(
    new HorizontalAlignmentHeaderRenderer(SwingConstants.RIGHT));

//...
class HorizontalAlignmentHeaderRenderer implements TableCellRenderer {
  private int horizontalAlignment = SwingConstants.LEFT;
  public HorizontalAlignmentHeaderRenderer(int horizontalAlignment) {
    this.horizontalAlignment = horizontalAlignment;
  }
  @Override public Component getTableCellRendererComponent(
      JTable table, Object value, boolean isSelected,
      boolean hasFocus, int row, int column) {
    TableCellRenderer r = table.getTableHeader().getDefaultRenderer();
    JLabel l = (JLabel) r.getTableCellRendererComponent(
        table, value, isSelected, hasFocus, row, column);
    l.setHorizontalAlignment(horizontalAlignment);
    return l;
  }
}

References

2016/08/26

aterai

Use an editable JComboBox as a TableCellEditor

Code

class ComboCellEditor extends AbstractCellEditor implements TableCellEditor {
  private final JComboBox combo = new JComboBox<>();
  protected ComboCellEditor() {
    super();
    combo.setEditable(true);
    combo.addActionListener(e -> {
      fireEditingStopped();
    });
  }
  @Override public Component getTableCellEditorComponent(
      JTable table, Object value, boolean isSelected, int row, int column) {
    if (value instanceof ComboBoxModel) {
      @SuppressWarnings("unchecked")
      ComboBoxModel m = (ComboBoxModel) value;
      combo.setModel(m);
    }
    return combo;
  }
  @Override public Object getCellEditorValue() {
    @SuppressWarnings("unchecked")
    DefaultComboBoxModel m = (DefaultComboBoxModel) combo.getModel();
    if (combo.isEditable()) {
      String str = Objects.toString(combo.getEditor().getItem(), "");
      if (!str.isEmpty() && m.getIndexOf(str) < 0) {
        m.insertElementAt(str, 0);
        combo.setSelectedIndex(0);
      }
    }
    return m;
  }
}

References

2016/03/31

aterai

How to hide the JTableHeader

Code

final JScrollPane scrollPane = new JScrollPane(table);
JCheckBox check = new JCheckBox("JTableHeader visible: ", true);
check.addActionListener(new ActionListener() {
  @Override public void actionPerformed(ActionEvent e) {
    JCheckBox cb = (JCheckBox) e.getSource();
    //table.getTableHeader().setVisible(cb.isSelected());
    scrollPane.getColumnHeader().setVisible(cb.isSelected());
    scrollPane.revalidate();
  }
});

References

2016/01/28

aterai

Save and load the state of a JTable and TableColumn(name, width, position and sortKey)

Code

class DefaultTableModelPersistenceDelegate extends DefaultPersistenceDelegate {
  @Override protected void initialize(
        Class type, Object oldInstance, Object newInstance, Encoder encoder) {
    super.initialize(type, oldInstance,  newInstance, encoder);
    DefaultTableModel m = (DefaultTableModel) oldInstance;
    for (int row = 0; row < m.getRowCount(); row++) {
      for (int col = 0; col < m.getColumnCount(); col++) {
        Object[] o = new Object[] {m.getValueAt(row, col), row, col};
        encoder.writeStatement(new Statement(oldInstance, "setValueAt", o));
      }
    }
  }
}

File file = File.createTempFile("output", ".xml");
try (XMLEncoder xe = new XMLEncoder(new BufferedOutputStream(new FileOutputStream(file)))) {
  xe.setPersistenceDelegate(
    RowSorter.SortKey.class,
    new DefaultPersistenceDelegate(new String[] {"column", "sortOrder"}));
  xe.writeObject(table.getRowSorter().getSortKeys());
//...

class TableColumnModelPersistenceDelegate extends DefaultPersistenceDelegate {
  @Override protected void initialize(
      Class type, Object oldInstance, Object newInstance, Encoder encoder) {
    super.initialize(type, oldInstance, newInstance, encoder);
    DefaultTableColumnModel m = (DefaultTableColumnModel) oldInstance;
    for (int col = 0; col < m.getColumnCount(); col++) {
      Object[] o = {m.getColumn(col)};
      encoder.writeStatement(new Statement(oldInstance, "addColumn", o));
    }
  }
}

References

2015/12/01

aterai

Show JToolTip for Icons placed in the cell of the JTable

Code

private final JTable table = new JTable(model) {
  @Override public String getToolTipText(MouseEvent e) {
    Point pt = e.getPoint();
    int vrow = rowAtPoint(pt);
    int vcol = columnAtPoint(pt);
    //int mrow = convertRowIndexToModel(vrow);
    int mcol = convertColumnIndexToModel(vcol);
    if (mcol == 1) {
      TableCellRenderer tcr = getCellRenderer(vrow, vcol);
      Component c = prepareRenderer(tcr, vrow, vcol);
      if (c instanceof JPanel) {
        Rectangle r = getCellRect(vrow, vcol, true);
        c.setBounds(r);
        //@see https://stackoverflow.com/questions/10854831/tool-tip-in-jpanel-in-jtable-not-working
        c.doLayout();
        pt.translate(-r.x, -r.y);
        Component l = SwingUtilities.getDeepestComponentAt(c, pt.x, pt.y);
        if (l instanceof JLabel) {
          ImageIcon icon = (ImageIcon)((JLabel) l).getIcon();
          return icon.getDescription();
        }
      }
    }
    return super.getToolTipText(e);
  }
};
class ListIconRenderer implements TableCellRenderer {
  private final JPanel p = new JPanel(new FlowLayout(FlowLayout.LEFT));
  @Override public Component getTableCellRendererComponent(
      JTable table, Object value,
      boolean isSelected, boolean hasFocus, int row, int column) {
    p.removeAll();
    if (isSelected) {
      p.setOpaque(true);
      p.setBackground(table.getSelectionBackground());
    } else {
      p.setOpaque(false);
    }
    if (value instanceof List) {
      for (Object o : (List) value) {
        if (o instanceof Icon) {
          Icon icon = (Icon) o;
          JLabel label = new JLabel(icon);
          label.setToolTipText(icon.toString());
          p.add(label);
        }
      }
    }
    return p;
  }
}

References

2015/09/30

aterai

Adjust the height of every row in the JTable to fit the JViewport

Code

JTable table = new JTable(model) {
  int prevHeight = -1;
  int prevCount = -1;
  public void updateRowsHeigth(JViewport vport) {
    int height = vport.getExtentSize().height;
    int rowCount = getModel().getRowCount();
    int defautlRowHeight = height / rowCount;
    if ((height != prevHeight || rowCount != prevCount) && defautlRowHeight > 0) {
      int over = height - rowCount * defautlRowHeight;
      for (int i = 0; i < rowCount; i++) {
        int a = over-- > 0 ? i == rowCount - 1 ? over : 1 : 0;
        setRowHeight(i, defautlRowHeight + a);
      }
    }
    prevHeight = height;
    prevCount = rowCount;
  }
  @Override public void doLayout() {
    super.doLayout();
    Container p = SwingUtilities.getAncestorOfClass(JViewport.class, this);
    if (p instanceof JViewport) {
      updateRowsHeigth((JViewport) p);
    }
  }
};

References

2014/05/01

aterai

JProgressBar in JTable cell render a progress string

Code

class Task extends SwingWorker {
  private final int lengthOfTask;
  private final int sleepDummy = new Random().nextInt(100) + 1;
  public Task(int lengthOfTask) {
    super();
    this.lengthOfTask = lengthOfTask;
  }
  @Override protected Integer doInBackground() {
    int current = 0;
    while (current < lengthOfTask && !isCancelled()) {
      current++;
      try {
        Thread.sleep(sleepDummy);
      } catch (InterruptedException ie) {
        break;
      }
      publish(new ProgressValue(lengthOfTask, current));
    }
    return sleepDummy * lengthOfTask;
  }
}

class ProgressValue {
  private final Integer progress;
  private final Integer lengthOfTask;
  public ProgressValue(Integer lengthOfTask, Integer progress) {
    this.progress = progress;
    this.lengthOfTask = lengthOfTask;
  }
  public Integer getProgress() {
    return progress;
  }
  public Integer getLengthOfTask() {
    return lengthOfTask;
  }
}

class ProgressRenderer extends DefaultTableCellRenderer {
  private final JProgressBar b = new JProgressBar();
  private final JPanel p = new JPanel(new BorderLayout());
  public ProgressRenderer() {
    super();
    setOpaque(true);
    b.setStringPainted(true);
    p.add(b);
  }
  @Override public Component getTableCellRendererComponent(
      JTable table, Object value, boolean isSelected, boolean hasFocus,
      int row, int column) {
    String text = "Done";
    if (value instanceof ProgressValue) {
      ProgressValue pv = (ProgressValue) value;
      Integer current = pv.getProgress();
      Integer lengthOfTask = pv.getLengthOfTask();
      if (current < 0) {
        text = "Canceled";
      } else if (current < lengthOfTask) {
        b.setMaximum(lengthOfTask);
        b.setValue(current);
        b.setString(String.format("%d/%d", current, lengthOfTask));
        return p;
      }
    }
    super.getTableCellRendererComponent(
        table, text, isSelected, hasFocus, row, column);
    return this;
  }
  @Override public void updateUI() {
    super.updateUI();
    if (p != null) {
      SwingUtilities.updateComponentTreeUI(p);
    }
  }
}

References

2013/07/29

aterai

JTable highlighting and filtering with regular expression

Code

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

  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);
  }
  public void clearHighlights() {
    Highlighter highlighter = getHighlighter();
    for(Highlighter.Highlight h: highlighter.getHighlights()) {
      highlighter.removeHighlight(h);
    }
  }
  @Override public Component getTableCellRendererComponent(
    JTable table, Object value, boolean isSelected,
    boolean hasFocus, int row, int column) {
    String txt = value!=null ? value.toString() : "";
    clearHighlights();
    setText(txt);
    setBackground(isSelected ? backgroundSelectionColor : Color.WHITE);
    if(pattern!=null && !pattern.isEmpty() && !pattern.equals(prev)) {
      Matcher matcher = Pattern.compile(pattern).matcher(txt);
      if(matcher.find()) {
        int start = matcher.start();
        int end   = matcher.end();
        try{
          getHighlighter().addHighlight(start, end, highlightPainter);
        }catch(BadLocationException e) {
          e.printStackTrace();
        }
      }
    }
    return this;
  }
}

References

2013/05/29

aterai

Column spanning TableCellRenderer

Code

class ColumnSpanningCellRenderer extends JPanel implements TableCellRenderer {
  private static final int TARGET_COLIDX = 0;
  private final JTextArea textArea = new JTextArea(2, 999999);
  private final JLabel label = new JLabel();
  private final JLabel iconLabel = new JLabel();
  private final JScrollPane scroll = new JScrollPane(textArea);

  protected ColumnSpanningCellRenderer() {
    super(new BorderLayout());

    scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
    scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
    scroll.setBorder(BorderFactory.createEmptyBorder());
    scroll.setViewportBorder(BorderFactory.createEmptyBorder());
    scroll.setOpaque(false);
    scroll.getViewport().setOpaque(false);

    textArea.setBorder(BorderFactory.createEmptyBorder());
    textArea.setMargin(new Insets(0, 0, 0, 0));
    textArea.setForeground(Color.RED);
    textArea.setEditable(false);
    textArea.setFocusable(false);
    textArea.setOpaque(false);

    iconLabel.setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 4));
    iconLabel.setOpaque(false);

    Border b1 = BorderFactory.createEmptyBorder(2, 2, 2, 2);
    Border b2 = BorderFactory.createMatteBorder(0, 0, 1, 1, Color.GRAY);
    label.setBorder(BorderFactory.createCompoundBorder(b2, b1));

    setBackground(textArea.getBackground());
    setOpaque(true);
    add(label, BorderLayout.NORTH);
    add(scroll);
  }
  @Override public Component getTableCellRendererComponent(
      JTable table, Object value, boolean isSelected,
      boolean hasFocus, int row, int column) {
    OptionPaneDescription d;
    if (value instanceof OptionPaneDescription) {
      d = (OptionPaneDescription) value;
      add(iconLabel, BorderLayout.WEST);
    } else {
      String title = Objects.toString(value, "");
      int mrow = table.convertRowIndexToModel(row);
      Object o = table.getModel().getValueAt(mrow, 0);
      if (o instanceof OptionPaneDescription) {
        OptionPaneDescription t = (OptionPaneDescription) o;
        d = new OptionPaneDescription(title, t.icon, t.text);
      } else {
        d = new OptionPaneDescription(title, null, "");
      }
      remove(iconLabel);
    }
    label.setText(d.title);
    textArea.setText(d.text);
    iconLabel.setIcon(d.icon);

    Rectangle cr = table.getCellRect(row, column, false);
    if (column != TARGET_COLIDX) {
      cr.x -= iconLabel.getPreferredSize().width;
    }
    scroll.getViewport().setViewPosition(cr.getLocation());

    if (isSelected) {
      setBackground(Color.ORANGE);
    } else {
      setBackground(Color.WHITE);
    }
    return this;
  }
}

class OptionPaneDescription {
  public final String title;
  public final Icon icon;
  public final String text;
  protected OptionPaneDescription(String title, Icon icon, String text) {
    this.title = title;
    this.icon  = icon;
    this.text  = text;
  }
}

References

2012/06/21

aterai

Height of JTableHeader

Code

JScrollPane scroll = new JScrollPane(table);
scroll.setColumnHeader(new JViewport() {
  @Override public Dimension getPreferredSize() {
    Dimension d = super.getPreferredSize();
    d.height = 32;
    return d;
  }
});
//or
table.setTableHeader(new JTableHeader(table.getColumnModel()) {
  @Override public Dimension getPreferredSize() {
    Dimension d = super.getPreferredSize();
    d.height = 32;
    return d;
  }
});

References

2011/12/22

aterai

Dropdown menu button in the JTableHeader

Code

@Override public void mouseClicked(MouseEvent e) {
  JTableHeader header = (JTableHeader)e.getSource();
  JTable table = header.getTable();
  TableColumnModel columnModel = table.getColumnModel();
  int vci = columnModel.getColumnIndexAtX(e.getX());
  int mci = table.convertColumnIndexToModel(vci);
  TableColumn column = table.getColumnModel().getColumn(mci);
  Rectangle r = header.getHeaderRect(vci);
  Container c = (Container)getTableCellRendererComponent(table, "", true, true, -1, vci);
  r.translate(r.width-BUTTON_WIDTH, 0);
  r.setSize(BUTTON_WIDTH, r.height);
  Point pt = e.getPoint();
  if(c.getComponentCount() > 0 && r.contains(pt) && pop!=null) {
    pop.show(header, r.x, r.height);
    JButton b = (JButton)c.getComponent(0);
    b.doClick();
    e.consume();
  }
}
@Override public void mouseExited(MouseEvent e) {
  rolloverIndex = -1;
}
@Override public void mouseMoved(MouseEvent e) {
  JTableHeader header = (JTableHeader)e.getSource();
  JTable table = header.getTable();
  TableColumnModel columnModel = table.getColumnModel();
  int vci = columnModel.getColumnIndexAtX(e.getX());
  int mci = table.convertColumnIndexToModel(vci);
  rolloverIndex = mci;
}

References

2011/11/28

aterai

JTable group directories first sorting

Code

// > dir /O:GN
// > ls --group-directories-first
class FileGroupComparator extends DefaultFileComparator{
  private final JTable table;
  public FileGroupComparator(JTable table, int column) {
    super(column);
    this.table = table;
  }
  public int compare(File a, File b) {
    int flag = 1;
    java.util.List < ? extends TableRowSorter.SortKey > keys
        = table.getRowSorter().getSortKeys();
    if(!keys.isEmpty()) {
      TableRowSorter.SortKey sortKey = keys.get(0);
      if(sortKey.getColumn()==column &&
         sortKey.getSortOrder()==SortOrder.DESCENDING) {
        flag = -1;
      }
    }
    if(a.isDirectory() && !b.isDirectory()) {
      return -1*flag;
    }else if(!a.isDirectory() && b.isDirectory()) {
      return  1*flag;
    }else{
      return super.compare(a, b);
    }
  }
}

References

2011/05/24

aterai

Change border of focused row in JTable

Code

class DotBorder extends EmptyBorder {
  public enum Type { START, END; }
  private static final BasicStroke dashed = new BasicStroke(
    1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER,
    10.0f, (new float[] {1.0f}), 0.0f);
  private static final Color dotColor = new Color(200,150,150);
  public DotBorder(int top, int left, int bottom, int right) {
    super(top, left, bottom, right);
  }
  public EnumSet type = EnumSet.noneOf(Type.class);
  @Override public boolean isBorderOpaque() {
    return true;
  }
  @Override public void paintBorder(
        Component c, Graphics g, int x, int y, int w, int h) {
    Graphics2D g2 = (Graphics2D)g;
    g2.translate(x,y);
    g2.setPaint(dotColor);
    g2.setStroke(dashed);
    if(type.contains(Type.START)) {
      g2.drawLine(0,0,0,h);
    }
    if(type.contains(Type.END)) {
      g2.drawLine(w-1,0,w-1,h);
    }
    if(c.getBounds().x%2==0) {
      g2.drawLine(0,0,w,0);
      g2.drawLine(0,h-1,w,h-1);
    }else{
      g2.drawLine(1,0,w,0);
      g2.drawLine(1,h-1,w,h-1);
    }
    g2.translate(-x,-y);
  }
}

//......
UIManager.put("Table.focusCellHighlightBorder", new DotBorder(2,2,2,2));
JTable table = new JTable(model) {
  private final DotBorder dotBorder = new DotBorder(2,2,2,2);
  private final Border emptyBorder  = BorderFactory.createEmptyBorder(2,2,2,2);
  private void updateBorderType(DotBorder border, int column) {
    border.type = EnumSet.noneOf(DotBorder.Type.class);
    if(column==0) border.type.add(DotBorder.Type.START);
    if(column==getColumnCount()-1) border.type.add(DotBorder.Type.END);
  }
  @Override public Component prepareRenderer(
      TableCellRenderer tcr, int row, int column) {
    Component c = super.prepareRenderer(tcr, row, column);
    if(row==getSelectionModel().getLeadSelectionIndex()) {
      ((JComponent)c).setBorder(dotBorder);
      updateBorderType(dotBorder, column);
    }else{
      ((JComponent)c).setBorder(emptyBorder);
    }
    return c;
  }
  @Override public Component prepareEditor(
      TableCellEditor editor, int row, int column) {
    Component c = super.prepareEditor(editor, row, column);
    if(c instanceof JCheckBox) {
      JCheckBox b = (JCheckBox)c;
      //System.out.println(b.getBorder());
      //b.setBorder(dotBorder);
      updateBorderType((DotBorder)b.getBorder(), column);
      b.setBorderPainted(true);
      b.setBackground(getSelectionBackground());
    }
    return c;
  }
};

References

2011/04/19

aterai

Transparent JTableHeader

Code

class TransparentHeader extends JLabel implements TableCellRenderer {
  private final Border b = BorderFactory.createCompoundBorder(
      BorderFactory.createMatteBorder(0,0,1,0,Color.BLACK),
      BorderFactory.createEmptyBorder(2,2,1,2));
  private final Color alphaZero = new Color(0, true);
  @Override public Component getTableCellRendererComponent(
        JTable table, Object value, boolean isSelected,
        boolean hasFocus, int row, int column) {
    this.setText(value!=null?value.toString():"");
    this.setHorizontalAlignment(JLabel.CENTER);
    this.setOpaque(false);
    this.setBackground(alphaZero);
    this.setForeground(Color.BLACK);
    this.setBorder(b);
    return this;
  }
}

References

2011/03/10

aterai

CheckBoxes in JTable Cell

Code

class CheckBoxesPanel extends JPanel {
  protected final String[] title = {"r", "w", "x"};
  public JCheckBox[] buttons;
  public CheckBoxesPanel() {
    super();
    setOpaque(false);
    setBackground(new Color(0,0,0,0));
    setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
    initButtons();
  }
  protected void initButtons() {
    buttons = new JCheckBox[title.length];
    for(int i=0; i < buttons.length; i++) {
      JCheckBox b = new JCheckBox(title[i]);
      b.setOpaque(false);
      b.setFocusable(false);
      b.setRolloverEnabled(false);
      b.setBackground(new Color(0,0,0,0));
      buttons[i] = b;
      add(b);
      add(Box.createHorizontalStrut(5));
    }
  }
  protected void updateButtons(Object v) {
    if("Windows 7".equals(OSNAME)) { //Windows aero?
      removeAll();
      initButtons();
    }
    Integer i = (Integer)(v==null?0:v);
    buttons[0].setSelected((i&(1<<2))!=0);
    buttons[1].setSelected((i&(1<<1))!=0);
    buttons[2].setSelected((i&(1<<0))!=0);
  }
}
class CheckBoxesRenderer extends CheckBoxesPanel
                         implements TableCellRenderer, Serializable {
  public CheckBoxesRenderer() {
    super();
    setName("Table.cellRenderer");
  }
  @Override public Component getTableCellRendererComponent(JTable table,
      Object value, boolean isSelected, boolean hasFocus, int row, int column) {
    updateButtons(value);
    return this;
  }
  public static class UIResource extends CheckBoxesRenderer
                                 implements UIResource{}
}
class CheckBoxesEditor extends CheckBoxesPanel
                       implements TableCellEditor, Serializable {
  public CheckBoxesEditor() {
    ActionListener al = new ActionListener() {
      @Override public void actionPerformed(ActionEvent e) {
        fireEditingStopped();
      }
    };
    ActionMap am = getActionMap();
    for(int i=0; i < buttons.length; i++) {
      final JCheckBox b = buttons[i];
      b.addActionListener(al);
      am.put(title[i], new AbstractAction(title[i]) {
        public void actionPerformed(ActionEvent e) {
          b.setSelected(!b.isSelected());
          fireEditingStopped();
        }
      });
    }
    InputMap im = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_R, 0), title[0]);
    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0), title[1]);
    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_X, 0), title[2]);
  }
  @Override public Component getTableCellEditorComponent(JTable table,
        Object value, boolean isSelected, int row, int column) {
    updateButtons(value);
    return this;
  }
  @Override public Object getCellEditorValue() {
    int i = 0;
    if(buttons[0].isSelected()) i|=1<<2;
    if(buttons[1].isSelected()) i|=1<<1;
    if(buttons[2].isSelected()) i|=1<<0;
    return i;
  }

  //Copid from AbstractCellEditor
  protected EventListenerList listenerList = new EventListenerList();
  transient protected ChangeEvent changeEvent = null;
  //......

References

2011/01/20

aterai

JTable RowHeader

Code

class RowHeaderList extends JList {
  private final JTable table;
  private final ListSelectionModel tableSelection;
  private final ListSelectionModel rListSelection;
  public RowHeaderList(ListModel model, JTable table) {
    super(model);
    this.table = table;
    setFixedCellHeight(table.getRowHeight());
    setCellRenderer(new RowHeaderRenderer(table.getTableHeader()));
    RollOverListener rol = new RollOverListener();
    addMouseListener(rol);
    addMouseMotionListener(rol);
    tableSelection = table.getSelectionModel();
    rListSelection = getSelectionModel();
  }
  class RowHeaderRenderer extends JLabel implements ListCellRenderer {
    private final JTableHeader header;
    public RowHeaderRenderer(JTableHeader header) {
      this.header = header;
      this.setOpaque(true);
      this.setBorder(BorderFactory.createMatteBorder(0,0,1,2,Color.GRAY));
      this.setHorizontalAlignment(CENTER);
      this.setForeground(header.getForeground());
      this.setBackground(header.getBackground());
      this.setFont(header.getFont());
    }
    public Component getListCellRendererComponent(JList list, Object value,
               int index, boolean isSelected, boolean cellHasFocus) {
      if(index==pressedRowIndex) {
        setBackground(Color.GRAY);
      }else if(index==rollOverRowIndex) {
        setBackground(Color.WHITE);
      }else if(isSelected) {
        setBackground(Color.GRAY.brighter());
      }else{
        setForeground(header.getForeground());
        setBackground(header.getBackground());
      }
      setText((value==null)?"":value.toString());
      return this;
    }
  }
}

References