Я довольно новичок в Java, поэтому, пожалуйста, извините меня за любые глупые ошибки, которые я делаю...
У меня есть JTable из 2 столбцов, в которых 2-й столбец может иметь 4 типа:
- столбец, в котором значения не могут быть изменены
- столбец, который может содержать любую текстовую строку
- столбец, содержащий JComboBoxes
- столбец, содержащий JCheckBoxes
Типы столбцов являются динамическими, поскольку они зависят от получаемых данных.
Все типы работают нормально, кроме JCheckBox. Когда я заменяю JCheckBox на JComboBox с двумя вариантами выбора, все работает нормально. Так что я предполагаю, что есть проблема в коде для JCheckBox.
Проблема в :
- когда JCheckBox отмечен, мне нужно всего 1 щелчок, чтобы снять его
- однако, когда 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);
}
}
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 клик:
- когда он отмечен, и я нажимаю на него, он должен отправить «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 не отмечен, но уже нажат один раз, результат после второго щелчка:
isSelected = false
Sent : REG SCH 4 = 1
Sent 1
После этого проверяется JCheckBox
Я искал и нашел решение, когда вам всегда нужно было 2 клика, или решения с фиксированными флажками вместо динамических, но не такой случай, как мой ....
может ли кто-нибудь пролить свет?