I have a java JPanel with 16 JCheckBoxes and I am wanting to ensure that the user selects at least one before submitting the form. The only way I know to do this is a huge if statement that looks at the Boolean value of the "isSelected()" method, but this seems inefficient.
So I was wondering if there was a faster to way to check if all of the boxes are unchecked.
You don't need an if statement. You can do it with a big logical expression using ||:
boolean somethingChecked = box1.isSelected()
|| box2.isSelected()
|| ...;
or, if the boxes are in an array (much preferred), a loop:
boolean somethingSelected = false;
for (JCheckBox box : boxes) {
if (box.isSelected()) {
somethingSelected = true;
break;
}
}
Alternatively, you can use an ItemListener attached to each JCheckBox to track the count of checked boxes:
int selectionCount;
ItemListener boxListener = new ItemListener() {
#Override public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
selectionCount++;
} else {
selectionCount--;
}
}
};
(Note that if this is all that the ItemListener is doing, a single instance can be attached to all the boxes.) The selectionCount should be initialized to the number of boxes initially checked. Then at the appropriate point(s) in your code, you can simply test whether selectionCount is greater than zero.
This will do the trick I believe:
public boolean validatePanel(JPanel panel) {
for (Component component : panel.getComponents()) {
if(component instanceof JCheckBox){
JCheckBox c = (JCheckBox) component;
if(c.isSelected()){
return true;
}
}
}
return false;
}
That method receives a JPanel and get all the components on it. Then check all of then, if it's a checkbox will cast the Component to CheckBox to have access to isSelected method. If any checkbox is selected it will return true, if it finish the foreach without returning any true it means that no checkbox were selected.
Related
I am using following code to set shortcut keys for my JFrame.
KeyboardFocusManager keyManager;
keyManager=KeyboardFocusManager.getCurrentKeyboardFocusManager();
keyManager.addKeyEventDispatcher(new KeyEventDispatcher() {
#Override
public boolean dispatchKeyEvent(KeyEvent e){
if(e.getID()==KeyEvent.KEY_PRESSED && e.getKeyCode()==KeyEvent.VK_C && e.isShiftDown()){
//shift+c
openCalculator();
}
return false;
}});
And it works fine! but the problem is that when user is writing something in some textfield or table cells etc. and wants to write any capital letter let's say Compose and presses Shift+C to capitalise then my code accepts this as a shortcut key and instead of writing the capital letter that event is fired.
What I want to do is disable this event for all editable cells, fields etc through out the program And enable it back again when the editable component loses focus.
I want my shortcut keys to only work when user is not editing any field or writing something in the program.
I resolved this with a check on KeyDispatchEvent by identifying specific instances of the components on which I don't want my event to work when focused.
boolean check = true;
try
{
Component comp = FocusManager.getCurrentManager().getFocusOwner();
if(comp instanceof JTextField || comp instanceof JTextArea || comp instanceof JComboBox || comp instanceof JTable){
check = false;
}
} catch (Exception ee) { ee.printStackTrace();
check = true;
}
}
if (check)
{
//do something
}
So I have a question. I use code which checks if I am dragging a button unto a JLabel and I control it by asking for label.getBounds().contains(pointWhereDraggingStopped) which returns false whereas new Rectangle(label.getBounds()).contains(pointWhereDraggingStopped) is true. Any idea as of why it could be?
I would post code but its a mess. I mean I will just put rectangle to make it work just curious as of why would it consider it not contained like that. They are all added as components into a panel both the label and all buttons by the way.
public void endOfDragging(Point pointOfEndOfDragging, Card draggedCard) {
for (Component c : this.panel.getComponents()) {
if (c.contains(pointOfEndOfDragging) && c.getName().equals("Button")) {
return;
}
if (c.getName().equals("Brazier")) {
System.out.println(pointOfEndOfDragging+ "///" + c.getBounds());
System.out.println(new Rectangle(c.getBounds()).contains(pointOfEndOfDragging));
System.out.println(c.contains(pointOfEndOfDragging));
}
if (c.getName().equals("Brazier") && new Rectangle(c.getBounds()).contains(pointOfEndOfDragging) && DraggedCard.getTyp() == TypeOfCard.SUMMONING) {
DraggedCard.use((IFighter) DraggedCard);
return;
}
}
}
I have JComboBox where I apply ListCellRenderer as following:
colorList = new JComboBox<>(COLORS_NAMES);
ColorComboBoxRenderer renderer = new ColorComboBoxRenderer(colorList);
renderer.setColors(COLORS);
renderer.setColorNames(COLORS_NAMES);
colorList.setRenderer(renderer);
it has result in modyfing cells, but I can't find reason why selected value is remembered but not pictured. Like following:
Here is my code for renderer ( omitting setColors, getColors etc..)
class ColorComboBoxRenderer extends JPanel implements ListCellRenderer{
JPanel textPanel;
JLabel text;
public ColorComboBoxRenderer(JComboBox combo){
textPanel = new JPanel();
textPanel.add(this);
text = new JLabel();
text.setOpaque(true);
text.setFont(combo.getFont());
textPanel.add(text);
}
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,
boolean cellHasFocus) {
if (isSelected){
list.setSelectionBackground(colors[list.getSelectedIndex()]);
}
else{}
if(colors.length != colorNames.length){
System.out.println("colors.length doesn't match colorNames.length");
return this;
}
else if(colors == null){
System.out.println("Set colors by setColors first.");
return this;
}
else if(colorNames == null){
System.out.println("Set colorNames by setColorNames first.");
return this;
}
text.setText(" ");
if(index > -1){
text.setBackground(colors[index]);
text.setText(" ");
}
return text;
}
}
What also confuses me is that if(isSelected) block is done everytime I point cursor on specified cell, but my intuition would rather expect that happen when cellHasFocus param is true.
Thanks in advance, as I am struggling with it since 2 days ;/
EDIT 1
Added JComboBox field to ColorComboBoxRenderer class, and initializes it in constructor:
private JComboBox comboBox;
public ColorComboBoxRenderer(JComboBox combo) {
this.comboBox = combo;
//rest of code as it was
}
Changed that:
if(isSelected){
list.setSelectionBackground(colors[list.getSelectedIndex()]);
}
To:
if (isSelected){
list.setSelectionBackground(colors[list.getSelectedIndex()]);
comboBox.setBackground(colors[list.getSelectedIndex()]);
}
Results in:
Now the effect is better, so maybe u have an idea how to change JComboBox background but do not affect dropdown arrow?
In EDIT 1 it is important that we did edit ComboBox, it is necessary, because ListRenderer just generates dropDown list and its cells, but wouldn't affect ComboBox fields. So what was necessary and I finally found it, was quite brute force approach. I changed whole ComboBox background when selected as in EDIT 1 but then returned Arrow State, which is at Index (0) of JComboBox. Finally that section of code should be like this:
if (isSelected){
list.setSelectionBackground(colors[list.getSelectedIndex()]);
comboBox.setBackground(colors[list.getSelectedIndex()]);
comboBox.getComponent(0).setBackground(new JButton().getBackground());
}
Now everything works as designed:
I am trying to validate user input into text boxes. I am checking whether the text box is populated or not and if it's not I need to alert the user to which text box isn't populated. My problem is that I need a way of returning which text box / variable is empty. I am aware I will need to pass 2 values in, one being the content of the text box and the other, an identifier of the text box.
Currently I have this (found on StackOverflow) which checks if each variable in the array is populated.
public boolean areAllNotEmpty(String... text){
for(String s : text) {
if(s == null || "".equals(s)) {
return false;
}
}
return true;
}
I would like it to also return something like this (commented):
public boolean areAllNotEmpty(String... text){
for(String s : text) {
if(s == null || "".equals(s)) {
// return textbox name / value OR show alert box with "Forename missing" etc
return false;
}
}
return true;
}
I implemented this method before on a C# project but it requires passing in one text box at a time with multiple method calls which I'm guessing isn't great.
public static bool IsFieldNull(TextBox currentText, string type)
{
bool allOk = false;
if (currentText.Text == "")
{
MessageBox.Show("Error - '" + type + "' field cannot be left blank, please enter some data in this field");
currentText.Focus();
return allOk;
}
else
{
allOk = true;
return allOk;
}
This is how it is called in C#.
Validation.IsFieldNull(txtBoxFixtureDate, "Fixture Date") && Validation.IsFieldNull(txtBoxTime, "Time")
If any of that doesn't make sense, let me know.
Thanks for any help.
You could pass the components to the method and return ones that are empty like this:
public List<JTextField> getEmptyFields(JTextField... textFields) {
List<JTextField> emptyFields = new ArrayList<JTextField>();
for (JTextField field : textFields) {
if (field.getText().isEmpty()) {
emptyFields.add(field);
}
}
return emptyFields;
}
Then you can just check the size() of the returned list to determine if there was an empty field and deal with them accordingly.
It's not pretty useful to validate when a submit button is pressed, it's better to validate when the error is happening. You may consider using InputVerifier . Then you know when it's in valid state or not. Apart from that if you are using java7 or above you could take a look to JLayer to decorate components which are not in valid state. See here for more examples Decorate components with JLayer.
I would like for my ComboBoxCellEditor to be able to have 3 selections possible. Right now it only has Yes or No. I would like for it to have Yes, No, Both.
Also the combobox selection values does not show up in the table unless the cell is clicked. It is hard to tell if the table cell has a selection possible unless they click in the empty cell. I would like it to at least show the down arrow.
I have read some where that the only way you can get around this is to set a default value.
I am not sure how to add the 3rd value. I will add my code trying to add the 3rd value
How can a get the combobox show up in the table without the cell having to be clicked first?
.
public class OptionEditingSupport extends EditingSupport {
private ComboBoxCellEditor cellEditor;
public OptionEditingSupport(ColumnViewer viewer) {
super(viewer);
cellEditor = new ComboBoxCellEditor(((TableViewer)viewer).getTable(), new String[]{"Yes", "No", "Both"}, SWT.READ_ONLY);
}
protected CellEditor getCellEditor(Object element) {
return cellEditor;
}
protected boolean canEdit(Object element) {
return true;
}
protected Object getValue(Object element) {
return 0;
}
protected void setValue(Object element, Object value)
{
if((element instanceof AplotDatasetData) && (value instanceof Integer)) {
Integer choice = (Integer)value;
String option = (choice == 0? "Yes":"No":"Both"); **<- Error Here
((AplotDatasetData)element).setMarkupValue(option);
getViewer().update(element, null);
}
}
}
The conditional operator
x ? y : z
is a ternary operator, which internally does:
if(x)
y;
else
z;
Thus, you can only use it with three components. Use an if else if else instead:
Integer choice = (Integer)value;
String option = "";
if(choice == 0)
option = "Yes";
else if(choice == 1)
option = "No";
else
option = "Both";
TableEditor can be used to show any Widget on top of Table Cell. It should solve your problem with showing Combobox to let user know there is selection possible for that row and column.
I am not sure I understand your question about 3 selections.