Google Tag Manager

Showing posts with label ListCellRenderer. Show all posts
Showing posts with label ListCellRenderer. Show all posts

2016/11/24

aterai

Filtering JList items by Regex

Code

DefaultListModel model = new DefaultListModel<>();
JList list = new JList(model) {
  @Override public void updateUI() {
    setSelectionForeground(null);
    setSelectionBackground(null);
    setCellRenderer(null);
    super.updateUI();
    setLayoutOrientation(JList.HORIZONTAL_WRAP);
    setVisibleRowCount(0);
    setFixedCellWidth(82);
    setFixedCellHeight(64);
    setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10));
    setCellRenderer(new ListItemListCellRenderer());
    getSelectionModel().setSelectionMode(
        ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
  }
};
private Optional getPattern() {
  try {
    return Optional.ofNullable(field.getText())
                   .filter(s -> !s.isEmpty())
                   .map(Pattern::compile);
  } catch (PatternSyntaxException ex) {
    return Optional.empty();
  }
}
private void filter() {
  getPattern().ifPresent(pattern -> {
    List selected = list.getSelectedValuesList();
    model.clear();
    Stream.of(defaultModel)
          .filter(item -> pattern.matcher(item.title).find())
          .forEach(model::addElement);
    for (ListItem item : selected) {
      int i = model.indexOf(item);
      list.addSelectionInterval(i, i);
    }
  });
}

References

2013/10/15

aterai

Scrollable list of JCheckBoxes

Code

JList

class CheckBoxCellRenderer extends JCheckBox
    implements ListCellRenderer, MouseListener, MouseMotionListener {
  @Override public Component getListCellRendererComponent(
    JList list,
    Object value,
    int index,
    boolean isSelected,
    boolean cellHasFocus) {
    this.setOpaque(true);
    if(isSelected) {
      this.setBackground(list.getSelectionBackground());
      this.setForeground(list.getSelectionForeground());
    }else{
      this.setBackground(list.getBackground());
      this.setForeground(list.getForeground());
    }
    if(value instanceof CheckBoxNode) {
      this.setSelected(((CheckBoxNode)value).selected);
      this.getModel().setRollover(index==rollOverRowIndex);
    }
    this.setText(value.toString());
    return this;
  }
  private int rollOverRowIndex = -1;
  @Override public void mouseExited(MouseEvent e) {
    JList l = (JList)e.getSource();
    if(rollOverRowIndex>=0) {
      l.repaint(l.getCellBounds(rollOverRowIndex, rollOverRowIndex));
      rollOverRowIndex = -1;
    }
  }
  @SuppressWarnings("unchecked")
  @Override public void mouseClicked(MouseEvent e) {
    if(e.getButton()==MouseEvent.BUTTON1) {
      JList l = (JList)e.getComponent();
      DefaultListModel m = (DefaultListModel)l.getModel();
      Point p = e.getPoint();
      int index  = l.locationToIndex(p);
      if(index>=0) {
        CheckBoxNode n = (CheckBoxNode)m.get(index);
        m.set(index, new CheckBoxNode(n.text, !n.selected));
        l.repaint(l.getCellBounds(index, index));
      }
    }
  }
  @Override public void mouseMoved(MouseEvent e) {
    JList l = (JList)e.getSource();
    int index = l.locationToIndex(e.getPoint());
    if(index != rollOverRowIndex) {
      rollOverRowIndex = index;
      l.repaint();
    }
  }
  @Override public void mouseEntered(MouseEvent e) {}
  @Override public void mousePressed(MouseEvent e) {}
  @Override public void mouseReleased(MouseEvent e) {}
  @Override public void mouseDragged(MouseEvent e) {}
}

JTree

class CheckBoxNodeRenderer extends JCheckBox implements TreeCellRenderer {
  private TreeCellRenderer renderer = new DefaultTreeCellRenderer();
  @Override public Component getTreeCellRendererComponent(
      JTree tree, Object value, boolean selected, boolean expanded,
      boolean leaf, int row, boolean hasFocus) {
    if(leaf && value != null && value instanceof DefaultMutableTreeNode) {
      this.setOpaque(false);
      Object userObject = ((DefaultMutableTreeNode)value).getUserObject();
      if(userObject!=null && userObject instanceof CheckBoxNode) {
        CheckBoxNode node = (CheckBoxNode)userObject;
        this.setText(node.text);
        this.setSelected(node.selected);
      }
      return this;
    }
    return renderer.getTreeCellRendererComponent(
        tree, value, selected, expanded, leaf, row, hasFocus);
  }
}

class CheckBoxNodeEditor extends JCheckBox implements TreeCellEditor {
  private final JTree tree;
  public CheckBoxNodeEditor(JTree tree) {
    super();
    this.tree = tree;
    setOpaque(false);
    setFocusable(false);
    addActionListener(new ActionListener() {
      @Override public void actionPerformed(ActionEvent e) {
        stopCellEditing();
      }
    });
  }
  @Override public Component getTreeCellEditorComponent(
      JTree tree, Object value, boolean isSelected, boolean expanded,
      boolean leaf, int row) {
    if(leaf && value != null && value instanceof DefaultMutableTreeNode) {
      Object userObject = ((DefaultMutableTreeNode)value).getUserObject();
      if(userObject!=null && userObject instanceof CheckBoxNode) {
        this.setSelected(((CheckBoxNode)userObject).selected);
      } else {
        this.setSelected(false);
      }
      this.setText(value.toString());
    }
    return this;
  }
  @Override public Object getCellEditorValue() {
    return new CheckBoxNode(getText(), isSelected());
  }
  @Override public boolean isCellEditable(EventObject e) {
    return (e != null && e instanceof MouseEvent);
  }
  //Copid from AbstractCellEditor
  //protected EventListenerList listenerList = new EventListenerList();
  //transient protected ChangeEvent changeEvent = null;
  @Override public boolean shouldSelectCell(java.util.EventObject anEvent) {
//...

References

2012/10/29

aterai

Delete button in a JComboBox popup menu items

Code

class CellButtonsMouseListener extends MouseAdapter {
  private int prevIndex = -1;
  private JButton prevButton;
  private static void listRepaint(JList list, Rectangle rect) {
    if (Objects.nonNull(rect)) {
      list.repaint(rect);
    }
  }
  @Override public void mouseMoved(MouseEvent e) {
    JList list = (JList) e.getComponent();
    Point pt = e.getPoint();
    int index = list.locationToIndex(pt);
    if (!list.getCellBounds(index, index).contains(pt)) {
      if (prevIndex >= 0) {
        Rectangle r = list.getCellBounds(prevIndex, prevIndex);
        listRepaint(list, r);
      }
      index = -1;
      prevButton = null;
      return;
    }
    if (index >= 0) {
      JButton button = getButton(list, pt, index);
      ButtonsRenderer renderer = (ButtonsRenderer) list.getCellRenderer();
      if (Objects.nonNull(button)) {
        renderer.rolloverIndex = index;
        if (!button.equals(prevButton)) {
          Rectangle r = list.getCellBounds(prevIndex, index);
          listRepaint(list, r);
        }
      } else {
        renderer.rolloverIndex = -1;
        Rectangle r = null;
        if (prevIndex == index) {
          if (prevIndex >= 0 && Objects.nonNull(prevButton)) {
            r = list.getCellBounds(prevIndex, prevIndex);
          }
        } else {
          r = list.getCellBounds(index, index);
        }
        listRepaint(list, r);
        prevIndex = -1;
      }
      prevButton = button;
    }
    prevIndex = index;
  }
  @Override public void mousePressed(MouseEvent e) {
    JList list = (JList) e.getComponent();
    Point pt = e.getPoint();
    int index = list.locationToIndex(pt);
    if (index >= 0) {
      JButton button = getButton(list, pt, index);
      if (Objects.nonNull(button)) {
        listRepaint(list, list.getCellBounds(index, index));
      }
    }
  }
  @Override public void mouseReleased(MouseEvent e) {
    JList list = (JList) e.getComponent();
    Point pt = e.getPoint();
    int index = list.locationToIndex(pt);
    if (index >= 0) {
      JButton button = getButton(list, pt, index);
      if (Objects.nonNull(button)) {
        button.doClick();
        Rectangle r = list.getCellBounds(index, index);
        listRepaint(list, r);
      }
    }
  }
  @Override public void mouseExited(MouseEvent e) {
    JList list = (JList) e.getComponent();
    ButtonsRenderer renderer = (ButtonsRenderer) list.getCellRenderer();
    renderer.rolloverIndex = -1;
  }
  @SuppressWarnings("unchecked")
  private static JButton getButton(JList list, Point pt, int index) {
    Container c = (Container) list.getCellRenderer().getListCellRendererComponent(
        list, "", index, false, false);
    Rectangle r = list.getCellBounds(index, index);
    c.setBounds(r);
    // c.doLayout(); // may be needed for other layout managers (eg. FlowLayout)
    pt.translate(-r.x, -r.y);
    Component b = SwingUtilities.getDeepestComponentAt(c, pt.x, pt.y);
    if (b instanceof JButton) {
      return (JButton) b;
    } else {
      return null;
    }
  }
}

References

2011/09/29

aterai

JProgressBar in JComboBox

Code

class ProgressCellRenderer extends DefaultListCellRenderer {
  private final JProgressBar bar = new JProgressBar() {
    @Override public Dimension getPreferredSize() {
      return ProgressCellRenderer.this.getPreferredSize();
    }
  };
  @Override public Component getListCellRendererComponent(
      JList list, Object value, int index,
      boolean isSelected, boolean cellHasFocus) {
    if(index < 0 && worker!=null && !worker.isDone()) {
      bar.setFont(list.getFont());
      bar.setBorder(BorderFactory.createEmptyBorder(0,0,0,0));
      bar.setValue(count);
      return bar;
    }else{
      return super.getListCellRendererComponent(
          list,value,index,isSelected,cellHasFocus);
    }
  }
  @Override public void updateUI() {
    super.updateUI();
    if(bar!=null) SwingUtilities.updateComponentTreeUI(bar);
  }
}

//........
button = new JButton(new AbstractAction("load") {
  @Override public void actionPerformed(ActionEvent e) {
    button.setEnabled(false);
    combo.setEnabled(false);
    combo.removeAllItems();
    worker = new SwingWorker<String, String>() {
      private int max = 30;
      @Override public String doInBackground() {
        int current = 0;
        while(current <= max && !isCancelled()) {
          try {
            Thread.sleep(50);
            //setProgress(100 * current / max);
            count = 100 * current / max;
            publish("test: "+current);
          }catch(Exception ie) {
            return "Exception";
          }
          current++;
        }
        return "Done";
      }
      @Override protected void process(java.util.List< String > chunks) {
        DefaultComboBoxModel m = (DefaultComboBoxModel)combo.getModel();
        for(String s: chunks) {
          m.addElement(s);
        }
        combo.setSelectedIndex(-1);
        combo.repaint();
      }
      @Override public void done() {
        String text = null;
        if(!isCancelled()) {
          combo.setSelectedIndex(0);
        }
        combo.setEnabled(true);
        button.setEnabled(true);
        count = 0;
      }
    };
    worker.execute();
  }
});

References

2010/03/11

aterai

Non Selectable JComboBox Items

Code

class DisableItemComboBox< E> extends JComboBox< E> {
  private final Set< Integer> disableIndexSet = new HashSet<>();
  private boolean isDisableIndex;
  private final Action up = new AbstractAction() {
    @Override public void actionPerformed(ActionEvent e) {
      int si = getSelectedIndex();
      for (int i = si - 1; i >= 0; i--) {
        if (!disableIndexSet.contains(i)) {
          setSelectedIndex(i);
          break;
        }
      }
    }
  };
  private final Action down = new AbstractAction() {
    @Override public void actionPerformed(ActionEvent e) {
      int si = getSelectedIndex();
      for (int i = si + 1; i < getModel().getSize(); i++) {
        if (!disableIndexSet.contains(i)) {
          setSelectedIndex(i);
          break;
        }
      }
    }
  };
  public DisableItemComboBox() {
    super();
  }
  public DisableItemComboBox(ComboBoxModel< E> aModel) {
    super(aModel);
  }
  public DisableItemComboBox(E[] items) {
    super(items);
  }
  @Override public void updateUI() {
    super.updateUI();
    setRenderer(new DefaultListCellRenderer() {
      @Override public Component getListCellRendererComponent(
          JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
        Component c;
        if (disableIndexSet.contains(index)) {
          c = super.getListCellRendererComponent(list, value, index, false, false);
          c.setEnabled(false);
        } else {
          c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
          c.setEnabled(true);
        }
        return c;
      }
    });
    ActionMap am = getActionMap();
    am.put("selectPrevious3", up);
    am.put("selectNext3", down);
    InputMap im = getInputMap();
    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0),      "selectPrevious3");
    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_KP_UP, 0),   "selectPrevious3");
    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0),    "selectNext3");
    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_KP_DOWN, 0), "selectNext3");
  }
  public void setDisableIndex(Set< Integer> set) {
    disableIndexSet.clear();
    for (Integer i : set) {
      disableIndexSet.add(i);
    }
  }
  @Override public void setPopupVisible(boolean v) {
    if (!v && isDisableIndex) {
      isDisableIndex = false;
    } else {
      super.setPopupVisible(v);
    }
  }
  @Override public void setSelectedIndex(int index) {
    if (disableIndexSet.contains(index)) {
      isDisableIndex = true;
    } else {
      //isDisableIndex = false;
      super.setSelectedIndex(index);
    }
  }
}

References

2009/06/03

aterai

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

2009/05/19

aterai

Left Clipped JComboBox

Code

final JButton arrowButton = getArrowButton(combo02);
combo02.setRenderer(new DefaultListCellRenderer() {
  public Component getListCellRendererComponent(JList list, Object value, int index,
                          boolean isSelected, boolean cellHasFocus) {
    super.getListCellRendererComponent(list,value,index,isSelected,cellHasFocus);
    int itb=0, ilr=0;
    Insets insets = getInsets();
    itb+=insets.top+insets.bottom; ilr+=insets.left+insets.right;
    insets = combo02.getInsets();
    itb+=insets.top+insets.bottom; ilr+=insets.left+insets.right;
    int availableWidth = combo02.getWidth()-ilr;
    if(index < 0) {
      //@see BasicComboBoxUI#rectangleForCurrentValue
      int buttonSize = combo02.getHeight()-itb;
      if(arrowButton!=null) {
        buttonSize = arrowButton.getWidth();
      }
      availableWidth -= buttonSize;
      JTextField tf = (JTextField)combo02.getEditor().getEditorComponent();
      insets = tf.getMargin();
      availableWidth -= (insets.left + insets.right);
    }
    String cellText = (value!=null)?value.toString():"";
    //blockquote
    //@cite http://tips4java.wordpress.com/2008/11/12/left-dot-renderer/
    //@title Left Dot Renderer
    //@auther Rob Camick
    //FontMetrics fm = getFontMetrics(getFont());
    //if(fm.stringWidth(cellText) > availableWidth) {
    //  String dots = "...";
    //  int textWidth = fm.stringWidth(dots);
    //  int nChars = cellText.length() - 1;
    //  while(nChars > 0) {
    //    textWidth += fm.charWidth(cellText.charAt(nChars));
    //    if(textWidth > availableWidth) break;
    //    nChars--;
    //  }
    //  setText(dots+cellText.substring(nChars+1));
    //}
    //blockquote

    // Unicode surrogate programming with the Java language
    // http://www.ibm.com/developerworks/library/j-unicode/index.html
    FontMetrics fm = getFontMetrics(getFont());
    if (fm.stringWidth(cellText) > availableWidth) {
      String dots = "...";
      int textWidth = fm.stringWidth(dots);
      int len = cellText.length();
      int[] acp = new int[cellText.codePointCount(0, len)];
      int j = acp.length;
      for (int i = len; i > 0; i = cellText.offsetByCodePoints(i, -1)) {
        int cp = cellText.codePointBefore(i);
        textWidth += fm.charWidth(cp);
        if (textWidth > availableWidth) {
          break;
        }
        acp[--j] = cp;
      }
      setText(dots + new String(acp, j, acp.length - j));
    }
    return this;
  }
});

References

2008/08/13

aterai

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