[英]JAVA JCheckBox takes 2 clicks to check and 1 click to uncheck
[英]JTable dynamic JCheckBox needs 1 click to uncheck, but 2 clicks to check
我對java很新,所以請原諒我犯的任何愚蠢的錯誤......
我有一個2列的JTable,其中第2列可以有4種類型:
列類型是動態的,因為它們取決於接收的數據。
除JCheckBox外,所有類型都可以正常工作。 當我用帶有2個選項的JComboBox替換JCheckBox時,它工作正常。 所以我猜JCheckBox的代碼存在問題。
問題是 :
一個示例項目(盡可能小):
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);
}
}
我用來查看Applet的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
之后,當我再次單擊該復選框(因此第二次)時,復選框仍然未選中,然后控制台顯示:
isSelected = false
Sent 1
復選框閃爍檢查短時間,然后當我再次單擊復選框(因此第三次)時再次取消選中,然后它的行為就像是第一次點擊
我希望復選框: - 取消選中后單擊發送1 - 選中並單擊時發送0
真正的項目有點復雜:通過檢查JCheckBox,我向設備發送一條消息,該設備以其當前狀態進行回答,該狀態被處理並顯示為已檢查的JCheckBox。 處理工作正常,因為我通過另一個通道更改設備中的狀態,然后JCheckBox完美地顯示當前狀態
我希望JCheckBox響應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,點擊一下后得到結果:
isSelected = true
Sent : REG SCH 4 = 0
Sent 0
在此之后,JCheckBox未被選中
未選中JCheckBox,單擊一次后得到結果:
isSelected = true
Sent : REG SCH 4 = 0
Sent 0
在此之后,JCheckBox仍然未經檢查
JCheckBox未經選中但已經點擊一次,第二次點擊后結果:
isSelected = false
Sent : REG SCH 4 = 1
Sent 1
在此之后,檢查JCheckBox
我搜索並找到解決方案,當你總是需要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"
不是Dropbox的值而不是checkbutton的值嗎?
還有,你每次都在創建一個新的JCheckBox。
也許SSCCE可能有用。
代碼的問題在於getTableCellRendererComponent
方法。 在這里,您始終使用JCheckBox
創建新組件。 所以每次它都采用新的JCheckBox
並渲染列。
除此之外,不需要將列呈現為Boolean
。 JTable
它會自我渲染。 您只需將列類型指定為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:我刪除了未使用的代碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.