1

私はJavaにかなり慣れていないので、私が犯した愚かな間違いを許してください...

2 列目に 4 つの型を持つことができる 2 列の JTable があります。

  • 値を変更できない列
  • 任意のテキスト文字列を含むことができる列
  • JComboBoxes を含む列
  • JCheckBoxes を含む列

受信するデータに依存するため、列の型は動的です。

JCheckBox を除くすべてのタイプが正常に機能します。JCheckBox を 2 つの選択肢を持つ JComboBox に置き換えると、正常に動作します。したがって、JCheckBox のコードに問題があると思います。

問題は :

  • JCheckBox がチェックされている場合は、1 クリックするだけでチェックを外すことができます
  • ただし、JCheckBox がチェックされていない場合は、チェックするために (ダブルクリックではなく) 2 回クリックする必要があります。

編集

サンプルプロジェクト(私ができる限り小さい):

    import java.awt.Component;
    import javax.swing.*;
    import javax.swing.event.*;
    import javax.swing.table.*;

    public class frmCheck extends JApplet
    {
        JTable mgrdData;
        DefaultTableModel mtableModel;

        public void init()
        {
            mtableModel = new DefaultTableModel();
            mtableModel.setColumnCount(2);
            mtableModel.setRowCount(4);
            mgrdData = new JTable(mtableModel);
            mgrdData.getSelectionModel().addListSelectionListener(new RowListener());
            add(mgrdData);
            for (int i=1;i<mtableModel.getRowCount();i++)
            {
                addCheck(1);
            }
        }

        private class RowListener implements ListSelectionListener
        {
            public void valueChanged(ListSelectionEvent event)
            {
                if (event.getValueIsAdjusting()) return;
            }
        }

        private void addCheck(int intCol)
        {
            mgrdData.getColumnModel().getColumn(intCol).setCellRenderer(new TableCellRenderer()
            {
                public Component getTableCellRendererComponent(JTable table,Object value,boolean isSelected,boolean isFocused,int row,int col)
                {
                    JCheckBox rendererComponent = new JCheckBox();
                    String strVal="";
                    if (value!=null) strVal = value.toString();
                    if (strVal.equals("1"))
                    {
                        rendererComponent.setSelected(true);
                    } else
                    {
                        rendererComponent.setSelected(false);
                    }
                    return rendererComponent;
                }
            });
            DefaultCellEditor cellEditor = new DefaultCellEditor(new JCheckBox());
            cellEditor.setClickCountToStart(1);
            cellEditor.addCellEditorListener(new CellEditorListener()
            {
                public void editingCanceled(ChangeEvent e) {}
                public void editingStopped(ChangeEvent e)
                {
                    JCheckBox checkBox = (JCheckBox)((DefaultCellEditor)e.getSource()).getComponent();
                    System.out.println("isSelected = " + checkBox.isSelected());
                    if (checkBox.isSelected())
                    {
                        System.out.println("Sent 0");
                    } else
                    {
                        System.out.println("Sent 1");
                    }
                }
            });
            mgrdData.getColumnModel().getColumn(intCol).setCellEditor(cellEditor);
        }
    }

アプレットを表示するために使用する html ページは次のとおりです。

<html>
  <body>
    <applet code="frmCheck.class" width="1016" height="822"></applet>
  </body>
</html>

実行可能 (アプリケーション) にするには、次の main() 関数を追加します (init() 関数の上、mtableModel の宣言の下)。

        public static void main(String[] args) {
        frmCheck myApplet = new frmCheck(); // define applet of interest
        Frame myFrame = new Frame("Applet Holder"); // create frame with title

        // Call applet's init method (since Java App does not
        // call it as a browser automatically does)
        myApplet.init();    

        // add applet to the frame
        myFrame.add(myApplet, BorderLayout.CENTER);
        myFrame.pack(); // set window to appropriate size (for its elements)
        myFrame.setVisible(true); // usual step to make frame visible

      } 

チェックされていないチェックボックスをクリックすると、コンソールに次のように表示されます。

isSelected = true
Sent 0

その後、チェックボックスをもう一度クリックすると(したがって2回目)、チェックボックスがオフのままになり、コンソールに次のように表示されます:

isSelected = false
Sent 1

チェックボックスが短時間チェックされたように点滅し、チェックボックスをもう一度クリックすると(したがって3回目)、再びチェックが外れて、初めてクリックされたように動作します

チェックボックスを次のようにします: - チェックを外してクリックすると 1 を送信します - チェックを入れてクリックすると 0 を送信します

実際のプロジェクトはもう少し複雑です。JCheckBox をチェックすることで、デバイスにメッセージを送信します。デバイスは現在の状態で応答し、処理されてチェック済みの JCheckBox として表示されます。別のチャネルを介してデバイスの状態を変更すると、JCheckBoxは現在の状態を完全に表示するため、処理は正常に機能します

JCheckBox が 1 回のクリックに応答するようにします。

  • チェックしてクリックすると、「REG SCH 4 = 0」が送信されます
  • チェックを外してクリックすると、「REG SCH 4 = 1」が送信されます

ここに私がこれまでに持っているコードがあります:

JTable は次のように作成されます。

JTable mgrdData;
DefaultTableModel mtableModel;
mtableModel = new DefaultTableModel(null,new String[0]);
mgrdData = new JTable(mtableModel);
mgrdData.getSelectionModel().addListSelectionListener(new RowListener());
mgrdData.setFillsViewportHeight(true);
String[] strHeader = {"Naam","Waarde"};
mtableModel.setColumnIdentifiers(strHeader);

列は次のように構成されます。

        addReadOnly(0);
//          addCombo(1,new String[]{"UIT","AAN"}); //this works fine
        addCheck(1);

列 0 は読み取り専用で、列 1 には 2 つの可能な値があります。addCombo(1,new String[]{"UIT","AAN"}); 完全に動作します

関数 addReadOnly と addCombo と addCheck は次のとおりです。

private void addReadOnly(int intCol)
{
    JTextField txtField = new JTextField();
    txtField.setEditable(false);
    DefaultCellEditor cellEditor = new DefaultCellEditor(txtField);
    mgrdData.getColumnModel().getColumn(intCol).setCellEditor(cellEditor);
}

private void addCombo(int intCol,final String[] strItems)
{
    //add combobox
    mgrdData.getColumnModel().getColumn(intCol).setCellRenderer(new TableCellRenderer()
    {
        public Component getTableCellRendererComponent(JTable table,Object value,boolean isSelected,boolean isFocused,int row,int col)
        {
            JComboBox rendererComponent = new JComboBox(strItems);
            if (value!=null) rendererComponent.setSelectedItem(value.toString());
            return rendererComponent;
        }
    });
    DefaultCellEditor cellEditor = new DefaultCellEditor(new JComboBox(strItems));
    cellEditor.setClickCountToStart(1);
    cellEditor.addCellEditorListener(new CellEditorListener()
    {
        private boolean blnChanged=false;
        public void editingCanceled(ChangeEvent e) {}
        public void editingStopped(ChangeEvent e)
        {
            if (blnChanged==true)
            {
                JComboBox comboBox = (JComboBox)((DefaultCellEditor)e.getSource()).getComponent(); 
                sendVal(String.valueOf(comboBox.getSelectedIndex()));
                blnChanged = false;
            } else
            {
                blnChanged = true; 
            } 
        }
    });
    mgrdData.getColumnModel().getColumn(intCol).setCellEditor(cellEditor);
}

private void addCheck(int intCol)
{
    //add checkbox
    mgrdData.getColumnModel().getColumn(intCol).setCellRenderer(new TableCellRenderer()
    {
        public Component getTableCellRendererComponent(JTable table,Object value,boolean isSelected,boolean isFocused,int row,int col)
        {
            JCheckBox rendererComponent = new JCheckBox();
            String strVal="";
            if (value!=null) strVal = value.toString();
//              if (strVal.equals("AAN"))
            if (strVal.equals("1"))
            {
                rendererComponent.setSelected(true);
            } else
            {
                rendererComponent.setSelected(false);
            }
            return rendererComponent;
        }
    });
    DefaultCellEditor cellEditor = new DefaultCellEditor(new JCheckBox());
    cellEditor.setClickCountToStart(1);
    cellEditor.addCellEditorListener(new CellEditorListener()
    {
        public void editingCanceled(ChangeEvent e) {}
        public void editingStopped(ChangeEvent e)
        {
            JCheckBox checkBox = (JCheckBox)((DefaultCellEditor)e.getSource()).getComponent();
            System.out.println("isSelected = " + checkBox.isSelected());
            if (checkBox.isSelected())
            {
                sendVal("0");
                System.out.println("Sent 0");
            } else
            {
                sendVal("1");
                System.out.println("Sent 1");
            }
        }
    });
    mgrdData.getColumnModel().getColumn(intCol).setCellEditor(cellEditor);
}

3 回クリックした後のテスト結果:

JCheckBox がチェックされ、1 回クリックした後の結果:

isSelected = true
Sent : REG SCH 4 = 0
Sent 0

この後、JCheckBox のチェックが外されます

JCheckBox はチェックされていません。1 回クリックした後の結果:

isSelected = true
Sent : REG SCH 4 = 0
Sent 0

この後、JCheckBoxはまだチェックされていません

JCheckBox はチェックされていませんが、すでに 1 回クリックされています。2 回目のクリック後の結果:

isSelected = false
Sent : REG SCH 4 = 1
Sent 1

この後、JCheckBox がチェックされます

常に2回のクリックが必要な場合の解決策、または動的ではなく固定チェックボックスを使用した解決策を検索して見つけましたが、私のようなケースではありません....

誰でも光を当てることができますか?

4

2 に答える 2

2

答え

問題は、ブール値の場合にチェックボックスの値を文字列として扱っていたことです。

作業コードは次のとおりです。

Boolean val = new Boolean(false);
if (value != null){
    val = (Boolean) value;
}
if (val.booleanValue()) {
    rendererComponent.setSelected(true);
}else{
     rendererComponent.setSelected(false);
}
return rendererComponent;

古い答え

私はまだそれを見ていますが、問題は、が選択されてJCheckBoxいるかどうかに応じて選択されていることが原因である可能性があると思います。

if (strVal.equals("AAN"))
        {
            rendererComponent.setSelected(true);
        } else
        {
            rendererComponent.setSelected(false);
        }

"AAN"チェックボタンではなく、ドロップボックスの値ではありませんか?

また、毎回新しい JCheckBox を作成しています。

多分SSCCEが役に立つかもしれません。

于 2013-01-23T15:23:22.847 に答える
1

コードの問題はgetTableCellRendererComponentメソッドにあります。ここでは、常に。を使用して新しいコンポーネントを作成していJCheckBoxます。JCheckBoxしたがって、新しいものを取得して列をレンダリングするたびに。

それに加えて、列をにレンダリングする必要はありませんBooleanJTableそれ自体がそれをレンダリングします。列タイプをモデルBoolean.class.のメソッドの上書きgetColumnClass(私が示したようにDefaultTableModel)として指定し、column-1がブール値であると言う必要があります。

アプレットの例

import javax.swing.DefaultCellEditor;
import javax.swing.JApplet;
import javax.swing.JCheckBox;
import javax.swing.JTable;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;

    public class frmCheck extends JApplet
    {
        JTable mgrdData;
        DefaultTableModel mtableModel;

        public void init()
        {
            mtableModel = new DefaultTableModel() {
                @Override
                public Class<?> getColumnClass(int arg0) {
                    if(arg0 == 1) {
                        return Boolean.class; 
                    } else {
                        return super.getColumnClass(arg0);
                    }
                }
            };
            mtableModel.setColumnCount(2);
            mtableModel.setRowCount(4);
            mgrdData = new JTable(mtableModel);
//            mgrdData.getSelectionModel().addListSelectionListener(new RowListener());
            add(mgrdData);

            for (int i=1;i<mtableModel.getRowCount();i++)
            {
                addCheck(1);
            }
        }

        private class RowListener implements ListSelectionListener
        {
            public void valueChanged(ListSelectionEvent event)
            {
                if (event.getValueIsAdjusting()) return;
            }
        }

        private void addCheck(int intCol)
        {

            DefaultCellEditor cellEditor = new DefaultCellEditor(new JCheckBox());
             mgrdData.getColumnModel().getColumn(1).getCellEditor();
            cellEditor.setClickCountToStart(1);
            cellEditor.addCellEditorListener(new CellEditorListener()
            {
                public void editingCanceled(ChangeEvent e) {}
                public void editingStopped(ChangeEvent e)
                {
                    JCheckBox checkBox = (JCheckBox)((DefaultCellEditor)e.getSource()).getComponent();
                    System.out.println("isSelected = " + checkBox.isSelected());
                    if (checkBox.isSelected())
                    {
                        System.out.println("Sent 0");
                    } else
                    {
                        System.out.println("Sent 1");
                    }
                }
            });
            mgrdData.getColumnModel().getColumn(intCol).setCellEditor(cellEditor);
        }
    }

PS:未使用のコードを削除しました。

于 2013-01-24T11:48:26.393 に答える