独自の Swing コンポーネントの作成に関するアドバイスを歓迎します
-
22-09-2019 - |
質問
最近 私は尋ねた これは、(いくつかの特定の編集プロパティを備えた) BigDecimal 変数にバインドするのに最適な Swing コンポーネントでした。標準の Swing コンポーネントはどれも私に完全に合わないことがわかりました。また、そこで見つけたサードパーティの Swing コンポーネント ライブラリも同様ではありませんでした。そこで、独自の Swing コンポーネントを作成することにしました。
コンポーネントの説明:
延長したい Jテキストフィールド または JFormattedTextField, なので、新しいコンポーネントを簡単にバインドできます。 BigDecimal 変数。
コンポーネントはカスタマイズ可能になります 規模 そして 長さ プロパティ。
行動:
コンポーネントが描画されると、小数点とスペースのみが表示されます。 規模 その右側に数字。
コンポーネントがフォーカスを受け取ると、キャレットは小数点の左側に配置される必要があります。ユーザーが数字を入力すると (他の文字は無視されます)、数字はキャレットの左側にのみ表示されます。 長さ – 規模 数値は受け入れられますが、入力された他の数値は整数部分がいっぱいであるため無視されます。ユーザーが小数点を入力するたびに、キャレットは小数点の右側に移動します。次の数値を入力すると、小数部分のみが表示されます。 規模 数値は、入力された他の数値とみなされ、小数部分がいっぱいであるため無視されます。さらに、ユーザーが小数点以下の数値を入力すると、千の位の区切り文字が表示されます。
また、コンポーネントを セルエディター で Jテーブル (二度コーディングする必要はありません)。
コンポーネントで getValue() メソッドを呼び出すと、入力したばかりの数値を表す BigDecimal が返されるはずです。
私は独自の Swing コンポーネントを作成したことがありません。標準のものはほとんど使っていません。したがって、説明されているコンポーネントの作成に関する優れたチュートリアル/情報/ヒントがあれば幸いです。 これ 私がこれまでに得た唯一のものです。
前もって感謝します。
解決
私は好き グルーチニコフ あなたが引用した記事ですが、UI デリゲートを変更したいかどうかわかりません。これは不変オブジェクトのビューになるため、継承よりも合成を好みます。私はあなたが説明するコンポーネントを次のように考える傾向があります。 レンダラー, 、これに見られるように 例. 。を追加できます InputVerifier
または DocumwntListener
必要な検証を取得するには。
補遺:以下は使用例です JFormattedTextField
そして MaskFormatter
. 。スケールと長さに合わせて書式マスクを調整する必要があります。
public class TableGrid extends JPanel {
private DecimalFormat df;
private MaskFormatter mf;
private JFormattedTextField tf;
public TableGrid() {
df = new DecimalFormat("0.00");
try {
mf = new MaskFormatter("#.##");
} catch (ParseException ex) {
ex.printStackTrace();
}
tf = new JFormattedTextField(mf);
TableModel dataModel = new TableModel();
JTable table = new JTable(dataModel);
table.setCellSelectionEnabled(true);
table.setRowHeight(32);
table.setDefaultRenderer(BigDecimal.class, new DecRenderer(df));
table.setDefaultEditor(BigDecimal.class, new DecEditor(tf, df));
this.add(table);
}
private static class TableModel extends AbstractTableModel {
private static final int SIZE = 4;
private BigDecimal[][] matrix = new BigDecimal[SIZE][SIZE];
public TableModel() {
for (Object[] row : matrix) {
Arrays.fill(row, BigDecimal.valueOf(0));
}
}
@Override
public int getRowCount() {
return SIZE;
}
@Override
public int getColumnCount() {
return SIZE;
}
@Override
public Object getValueAt(int row, int col) {
return matrix[row][col];
}
@Override
public void setValueAt(Object value, int row, int col) {
matrix[row][col] = (BigDecimal) value;
}
@Override
public Class<?> getColumnClass(int col) {
return BigDecimal.class;
}
@Override
public boolean isCellEditable(int row, int col) {
return true;
}
}
private static class DecRenderer extends DefaultTableCellRenderer {
DecimalFormat df;
public DecRenderer(DecimalFormat df) {
this.df = df;
this.setHorizontalAlignment(JLabel.CENTER);
this.setBackground(Color.lightGray);
this.df.setParseBigDecimal(true);
}
@Override
protected void setValue(Object value) {
setText((value == null) ? "" : df.format(value));
}
}
private static class DecEditor extends DefaultCellEditor {
private JFormattedTextField tf;
private DecimalFormat df;
public DecEditor(JFormattedTextField tf, DecimalFormat df) {
super(tf);
this.tf = tf;
this.df = df;
tf.setHorizontalAlignment(JFormattedTextField.CENTER);
}
@Override
public Object getCellEditorValue() {
try {
return new BigDecimal(tf.getText());
} catch (NumberFormatException e) {
return BigDecimal.valueOf(0);
}
}
@Override
public Component getTableCellEditorComponent(JTable table,
Object value, boolean isSelected, int row, int column) {
tf.setText((value == null) ? "" : df.format((BigDecimal) value));
if (isSelected) tf.selectAll();
return tf;
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame f = new JFrame("TableGrid");
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.add(new TableGrid());
f.pack();
f.setVisible(true);
}
});
}
}
他のヒント
を使用するものは何でもあなたのような構成要素とあなたのbehaviour.AddのgetValueを(一致する文字を拒絶するようにのKeyListenerを登録)&setValueのは/ BiDecimalや他のいくつかの方法を簡単に設定を取得するには、すべての絵はどのJTextComponentのによって提供されます。