Swing/BitSetCheckBoxes のバックアップの現在との差分(No.1)
- category: swing folder: BitSetCheckBoxes title: JCheckBoxの選択状態をBitSetで管理する tags: [JCheckBox, BitSet, UndoManager, UndoableEditSupport] author: aterai pubdate: 2018-03-26T16:22:10+09:00 description: 複数のJCheckBoxの選択状態をBitSetを使用して管理します。 image: https://drive.google.com/uc?id=1u_RLXjvLSINB0mb0ar_COqlBq5jbVhPByg
概要
複数のJCheckBox
の選択状態をBitSet
を使用して管理します。
Screenshot
Advertisement
サンプルコード
// Long.MAX_VALUE
// 0b111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111
// protected static final int BIT_LENGTH = 63;
protected static final int BIT_LENGTH = 72;
BitSet status = BitSet.valueOf(new long[] {Long.valueOf("111000111", 2)});
// ...
IntStream.range(0, BIT_LENGTH).forEach(i -> {
JCheckBox c = new JCheckBox(Integer.toString(i), status.get(i));
c.addActionListener(e -> {
JCheckBox cb = (JCheckBox) e.getSource();
BitSet newValue = status.get(0, BIT_LENGTH);
newValue.set(i, cb.isSelected());
undoSupport.postEdit(new StatusEdit(status, newValue));
status = newValue;
label.setText(print(status));
});
#spandel
panel.add(c);
#spanend
panel.add(c);
});
View in GitHub: Java, Kotlin解説
JCheckBox
の選択状態をBitSet
で管理-
UndoManager
を使用したアンドゥ・リドゥは、JCheckBoxの選択状態をBigIntegerで記憶し、UndoManagerを使用して元に戻したりやり直したりすると同じ -
JCheckBox
がクリックされて値が変化した場合、BitSet
内のビットを2
進数の形で表示-
BitSet#toLongArray()
を使用しているので、Long.MAX_VALUE
より2
進数での桁数が大きくなる場合は注意が必要 -
BitSet#toLongArray()
が返すlong
配列は、0
から63
ビットがインデックス0
、64
から127
ビットがインデックス1
と続く
-
-
UndoManager
を使用したUndo
、Redo
はJCheckBoxの選択状態をBigIntegerで記憶し、UndoManagerを使用して元に戻したりやり直したりすると同じ -
JCheckBox
がクリックされて値が変化した場合BitSet
内のビットを2
進数の形でJLabel
に表示-
BitSet#toLongArray()
を使用しているのでLong.MAX_VALUE
より2
進数での桁数が大きくなる場合は注意が必要 -
BitSet#toLongArray()
が返すlong
配列は0
から63
ビットが存在すればインデックス0
、64
から127
ビットが存在すればインデックス1
と続く -
BitSet
内のビットが空の場合、bitSet.toLongArray().length
は0
となり、bitSet.toLongArray()[0]
はArrayIndexOutOfBoundsException
になる -
0
から63
ビットのすべてにフラグがある場合(0b1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111
)、Long.toString(..., 2)
は-1
になるので、Long.toUnsignedString(..., 2)
を使用する必要がある -
BitSet
内のビットが全て空の場合、bitSet.toLongArray().length
は0
となり、bitSet.toLongArray()[0]
はArrayIndexOutOfBoundsException
になる -
bitSet.toLongArray()[0]
に0
から63
ビットのすべてにフラグが立ったlong
値lv
が入っている場合、符号ビットにもフラグが立った状態なのでLong.toString(lv, 2)
は-1L
になる- 符号なし整数として扱うよう
Long.toUnsignedString(lv, 2)
を使用する必要がある
- 符号なし整数として扱うよう
-
#spandel
private static String print(BitSet l) {
#spanend
long[] la = l.toLongArray();
#spanadd
// 0 から 63 ビットのすべてにフラグがある場合、bitSet.toLongArray()[0] には、
#spanend
#spanadd
// -1L: (イメージ的?には大きすぎるが 0b1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111)
#spanend
#spanadd
// が入っている
#spanend
#spanadd
private static String print(BitSet bitSet) {
#spanend
StringBuilder buf = new StringBuilder();
for (int i = la.length - 1; i >= 0; i--) {
buf.append(Long.toUnsignedString(la[i], 2));
for (long lv: bitSet.toLongArray()) {
buf.insert(0, Long.toUnsignedString(lv, 2));
}
String b = buf.toString();
int count = l.cardinality();
int count = bitSet.cardinality();
return "<html>0b" + ZEROPAD.substring(b.length()) + b + "<br/> count: " + count;
}
参考リンク
- BitSet (Java Platform SE 8)
- JCheckBoxの選択状態をBigIntegerで記憶し、UndoManagerを使用して元に戻したりやり直したりする
BigInteger
を使用する場合のサンプル
- java - BitSet toString() and valueOf() are difficult to understand - Stack Overflow
- Long#toUnsignedString(...) (Java Platform SE 8)
-
JDK 1.8.0
で符号なし整数として扱うために追加された
-