Swing/CheckBoxCellList のバックアップ差分(No.7)
- バックアップ一覧
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- バックアップ を表示
- Swing/CheckBoxCellList へ行く。
- 1 (2012-05-29 (火) 14:32:45)
- 2 (2012-06-22 (金) 01:52:01)
- 3 (2012-12-22 (土) 16:09:37)
- 4 (2013-09-03 (火) 13:06:56)
- 5 (2013-09-03 (火) 14:11:14)
- 6 (2013-10-01 (火) 00:20:57)
- 7 (2013-10-01 (火) 05:15:35)
- 8 (2013-10-09 (水) 04:48:10)
- 9 (2013-10-15 (火) 00:01:11)
- 10 (2013-10-15 (火) 08:23:58)
- 11 (2013-10-15 (火) 11:52:31)
- 12 (2013-10-21 (月) 10:23:25)
- 13 (2013-10-21 (月) 15:03:31)
- 14 (2013-10-28 (月) 10:11:18)
- 15 (2013-10-28 (月) 15:00:16)
- 16 (2014-02-18 (火) 15:20:20)
- 17 (2014-02-19 (水) 02:29:31)
- 18 (2014-06-26 (木) 16:19:19)
- 19 (2014-09-04 (木) 14:20:47)
- 20 (2014-10-07 (火) 17:55:53)
- 21 (2014-11-22 (土) 03:57:24)
- 22 (2015-08-24 (月) 02:47:47)
- 23 (2015-08-25 (火) 19:37:30)
- 24 (2017-04-06 (木) 20:42:32)
- 25 (2018-02-24 (土) 19:51:30)
- 26 (2018-03-22 (木) 14:13:29)
- 27 (2019-05-22 (水) 19:35:38)
- 28 (2020-03-22 (日) 01:45:30)
- 29 (2021-09-28 (火) 13:11:02)
- 30 (2021-11-25 (木) 05:36:48)
- 追加された行はこの色です。
- 削除された行はこの色です。
TITLE:JListのセルにJCheckBoxを使用する
#navi(../)
#tags(JList, JCheckBox, ListCellRenderer, MouseListener, JTree)
RIGHT:Posted by &author(aterai); at 2011-03-28
* JListのセルにJCheckBoxを使用する [#z6df133e]
``JList``のセルに``JCheckBox``を使用して、チェックボックスの一覧を作成します。
- &jnlp;
- &jar;
- &zip;
#ref(https://lh6.googleusercontent.com/_9Z4BYR88imo/TZAiQ_MSc_I/AAAAAAAAA4k/FiVk_o38jyY/s800/CheckBoxCellList.png)
** サンプルコード [#hbcc9907]
#code(link){{
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) {}
}
}}
** 解説 [#u07c22e4]
- 左: ``JCheckBox Cell in JList``
-- ``JCheckBox``を継承する``ListCellRenderer``を設定
-- チェックボックスのロールオーバーなどは、``JList``にマウスリスナーを設定して表示
-- ``JList#processMouseEvent``、``JList#processMouseMotionEvent``のオーバーライドと、``JList#putClientProperty("List.isFileList", Boolean.TRUE);``で、クリックが有効になる領域をチェックボックスの幅に制限
#code{{
JList list1 = new JList(model) {
private CheckBoxCellRenderer renderer;
@Override public void updateUI() {
setForeground(null);
setBackground(null);
setSelectionForeground(null);
setSelectionBackground(null);
if(renderer!=null) {
removeMouseListener(renderer);
removeMouseMotionListener(renderer);
}
super.updateUI();
renderer = new CheckBoxCellRenderer();
setCellRenderer(renderer);
addMouseListener(renderer);
addMouseMotionListener(renderer);
}
//@see SwingUtilities2.pointOutsidePrefSize(...)
private boolean pointOutsidePrefSize(Point p) {
int index = locationToIndex(p);
DefaultListModel m = (DefaultListModel)getModel();
CheckBoxNode n = (CheckBoxNode)m.get(index);
Component c = getCellRenderer().getListCellRendererComponent(
this, n, index, false, false);
//c.doLayout();
Dimension d = c.getPreferredSize();
Rectangle rect = getCellBounds(index, index);
rect.width = d.width;
return index < 0 || !rect.contains(p);
}
@Override protected void processMouseEvent(MouseEvent e) {
if(!pointOutsidePrefSize(e.getPoint())) {
super.processMouseEvent(e);
}
}
@Override protected void processMouseMotionEvent(MouseEvent e) {
if(!pointOutsidePrefSize(e.getPoint())) {
super.processMouseMotionEvent(e);
}else{
e = new MouseEvent(
(Component)e.getSource(), MouseEvent.MOUSE_EXITED, e.getWhen(),
e.getModifiers(), e.getX(), e.getY(),
e.getXOnScreen(), e.getYOnScreen(),
e.getClickCount(), e.isPopupTrigger(), MouseEvent.NOBUTTON);
super.processMouseEvent(e);
}
}
};
}}
- 右: ``JCheckBox in Box``
-- ``Box.createVerticalBox()``に``JCheckBox``を追加
-- ``JCheckBox#setAlignmentX(Component.LEFT_ALIGNMENT);``で左揃えに設定
----
[[JTreeの葉ノードをJCheckBoxにする>Swing/CheckBoxNodeTree]]のセルレンダラーを使った``JTree``に、``JTree#setRootVisible(false)``を設定しても、ほぼ同様のチェックボックスの一覧を作成することができます。
#code{{
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.tree.*;
public class TreeCheckBoxListTest {
public JComponent makeUI() {
DefaultMutableTreeNode root = new DefaultMutableTreeNode("JTree");
for(int i=0; i<16; i++) {
root.add(new DefaultMutableTreeNode(new CheckBoxNode("No."+i, i%2==0)));
}
JTree tree = new JTree(new DefaultTreeModel(root));
tree.setEditable(true);
tree.setRootVisible(false);
tree.setCellRenderer(new CheckBoxNodeRenderer());
tree.setCellEditor(new CheckBoxNodeEditor(tree));
return new JScrollPane(tree);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new TreeCheckBoxListTest().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
class CheckBoxNode {
public final String text;
public final boolean selected;
public CheckBoxNode(String text, boolean selected) {
this.text = text;
this.selected = selected;
}
@Override public String toString() {
return text;
}
}
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) {
return true;
}
@Override public boolean stopCellEditing() {
fireEditingStopped();
return true;
}
@Override public void cancelCellEditing() {
fireEditingCanceled();
}
@Override public void addCellEditorListener(CellEditorListener l) {
listenerList.add(CellEditorListener.class, l);
}
@Override public void removeCellEditorListener(CellEditorListener l) {
listenerList.remove(CellEditorListener.class, l);
}
public CellEditorListener[] getCellEditorListeners() {
return listenerList.getListeners(CellEditorListener.class);
}
protected void fireEditingStopped() {
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for(int i = listeners.length-2; i>=0; i-=2) {
if(listeners[i]==CellEditorListener.class) {
// Lazily create the event:
if(changeEvent == null) changeEvent = new ChangeEvent(this);
((CellEditorListener)listeners[i+1]).editingStopped(changeEvent);
}
}
}
protected void fireEditingCanceled() {
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for(int i = listeners.length-2; i>=0; i-=2) {
if(listeners[i]==CellEditorListener.class) {
// Lazily create the event:
if(changeEvent == null) changeEvent = new ChangeEvent(this);
((CellEditorListener)listeners[i+1]).editingCanceled(changeEvent);
}
}
}
}
}}
//**参考リンク
** コメント [#d0ea5ae4]
- No, I'm not particularly sporty <a href=" http://www.runningonclimate.com/about ">cost of voltaren</a> up, and the white balance is fixed. (ONE-PUSH <a href=" http://www.blackberry-france.com/a-propos/ ">buy zithromax cheap</a> member first. The complexity of rotation assignments is the reason why the PEP does not allow <a href=" http://www.geexmedia.com/mikes-cart-free-e-commerce-websites/ ">abilify copay discount</a> FS AM 3 variable R x1CAM <a href=" http://pizzagalleryandgrill.com/instagram/ ">generic acyclovir online</a> these instances pharmacists will be eligible to endorse the prescription as close control and -- [[Logan]] &new{2013-10-01 (火) 00:20:57};
#comment