I made a game "Who Wants To Be A Millionaire" with jList filed. In the jList I listed the prises see this picture below
The game is started with the prise number 1 and increase the number if the answer was OK. If I move the mouse over the prises I can modify the prise position with the mouse click as well. This is what I want to disable. The jList need to have only for show the prises without modify with the mouse click.
I also try to use disable of the jList but than all the colors are changed and I don't find where can I adjust the disabled colors.
What is the best solution for my need ?
The simplest way to achieve that is to add a ListSelectionListener to restore the proper index into your JList.
Take a look at an example:
list.addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent e) {
list.setSelectedIndex(myIndex);
}
});
list.setSelectedIndex(0); //0 plays no role, since listener will select myIndex
The selected index will always remain my index, no matter what.
Note: If you want to change the index later, you must change the value of myIndex variable without forgetting firing the selection listener as well. More accurately:
myIndex = 15;
list.setSelectedIndex(0); //0 plays no role, since the selection listener uses myIndex
Another way (more complex in my opinion) is to read and follow Disable JList Cell Selection Property.
Related
Here's some example code, using Groovy's swingbuilder to create the code for the valueChanged event of a JList:
mainList.valueChanged = { event ->
if (event.isAdjusting) {
index = mainList.selectedIndex
otherList.clearSelection()
otherIndex = otherList.selectedIndex
} else {
mainListSelected = true
clearJList(otherList)
}
}
I have two JList's, and this function kind of controls which list is allowed to be selected via the mainListSelected variable. We also then have to change int eindex we want to use from the selection based on whether or not it's an index from mainList or otherList
I've read about event.isAdjusting, and it only fires twice like this on a mouse click event. With this knowledge, you would think I would just move everything out of there, but I need certain things to happen differently if the mouse is what causes the event as opposed to using arrows. However, with this code, using arrow key navigation prevents the index from ever changing.
I Have an odd problem - not sure if there's a coding mistake or a bug in CN1.
Basically I create a row of CheckBox objects and put them in a container that is X-Scrollable. If i click on one un-selected item and drag until the "elastic" effect pulls it back, it appears to be selected, but the code does not record it as selected.
Please see the following video of the issue:
https://youtu.be/EtputE1kjyo
Note that in the Console output, the word 'selected' is capitalized when the field has been selected and lowercase when it is unselected. Same for focus (I added focus to the output to determine if setFocusable() was working as desired so that focus was not to blame for the selection error).
here's the Checkbox creation code:
cb = new CheckBox(getCacheableImageMaxHeight(mod.getIconFile(),moduleImageHeight));
cb.setName(mod.getModuleID());
cb.setToggle(true);
cb.setUIID("ModuleButton");
cb.setFocusable(false);
cb.setScrollVisible(false);
cb.setTextPosition(Component.BOTTOM);
cb.setCloudDestinationProperty(cb.getName());
//actionlistener added for debugging only
final CheckBox cbFinal = cb;
final String modName = mod.getDisplayName();
cb.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
System.out.println(modName+", "+(cbFinal.isSelected()?"SELECTED":"selected") + ", " + (cbFinal.hasFocus()?"FOCUS":"focus"));
}
});
c.addComponent(cb);
UPDATE: I've realized there are two "states" at war here:
The toggleButtons (I now realize they're not just CheckBoxes since I set "setToggle(true)) are getting stuck in the "pressed" state as they are dragged and released with the "elastic" effect. Unfortunately, the "pressed" and "selected" states have the same appearance so that means my users think they have selected something when it's just stuck being "pressed" during a drag operation.
Here's some more debugging I did.
The first button is Pressed, but not selected (the bug).
the second button is Selected normally and not showing the bug.
The Third button is interesting because I selected it, then dragged and released it to get it to be SELECTED and PRESSED!
So the question changes to: Is there an open bug for this situation already (Pressed state gets stuck on after button is released) and if so, is there a fix coming or a workaround for now?
Just style the selected state to look different from the pressed state and it should work fine.
In a touch device selected state isn't rendered when the finger is up. This is almost always true unless you changed a flag in Display or set some arcane theme constant.
So I figured out a more effective workaround that doesn't involve adding a separate pressed style (since there could be buttons selected, pressed, and selected+pressed with the bug)
I needed to capture the event that scrolling stopped and then check the state of the buttons to make sure none were still pressed. To do this, I used addPointerReleasedListener on the scrolling container to detect when the pointer came off (so its components are definitely no longer pressed), and then in its Runnable, I make sure each one is released.
scrollingContainer.addPointerReleasedListener(evt -> {
Container cont = (Container) evt.getComponent();
Iterator<Component> buttons = cont.iterator();
while (buttons.hasNext()){
Button button = (Button) buttons.next();
if (button.getState() == Button.STATE_PRESSED) {
button.released();
}
}
});
So far seems to solve the problem. Now we just need a permanent fix, or a note in the documentation of ToggleButtons that when they are in a scrolling container, they could get stuck in a pressed state and need to be released.
I try to do an image creator program in java (with squares/circles/etc)
I have a few JRadioButtons in a ButtonGroup that symbolizes my program's "mode" (if I draw a circle, something else/if I move the objects).
When I click on different modes, the "mode" changes and I'm able to do what I want.
My problem is when I try to change the mode by double-clicking on an object. I do it in a MouseListener. I'm able to select the object, to change the "mode", but I can't change the selected JRadio Button on my ButtonGroup.
I searched for a while (since the setSelected() is not working). I know that ButtonGroup can have only a button selected at once. How could I deselect the curent one and select the one I need (the first one).
Thank you for any advices.
From the docs:
public void setSelected(boolean b)
Sets the state of the button. Note that this method does not trigger
an actionEvent. Call doClick to perform a programatic action change.
As mentioned here use:
radioBtn.doClick();
I created a small method that allow me to set any radio group button. Very convenient if you don't want to use if for any radio button.
public void setButtonGroup(int rdValue, Enumeration elements ){
while (elements.hasMoreElements()){
AbstractButton button = (AbstractButton)elements.nextElement();
if(Integer.parseInt(button.getActionCommand())==rdValue){
button.setSelected(true);
}
}
}
then
setButtonGroup(yourValue, yourButtonGroup.getElements());
i do have a JList and want to check if any Index is selected or not.
I thought it will work with a loop. I tried everything but everytime my whole frame is blank.
The JButton must stay disabled until any Index is selected.
do {
JButton.setEnabled(false);
} while (JList.getSelectedIndex() == -1);
You can do this by adding a ListSelectionListener to your JList. This is done via the addListSelectionListener method.
From the javadoc:
Adds a listener to the list, to be notified each time a change to the
selection occurs; the preferred way of listening for selection state
changes. JList takes care of listening for selection state changes in
the selection model, and notifies the given listener of each change.
ListSelectionEvents sent to the listener have a source property set to
this list.
I have a JPanel which contains two JLists - both can have an item in them selected - as expected.
What I'd love to be able to do is have it so that only one item in either to be selected
Can anyone help me with either
a) "marrying" them so this can be the case
b) giving me some tips for the best practice to write listeners which can preside over them both and unselect all the elements of one when the other is selected - I'd rather avoid this if possible as I can see it getting ugly!!
Thanks :)
I think the best solution, also for the user, is putting a radio button next with a category label to each list, so you clearly disable the other each time you select one.
I can imagine the user clicking values on the first list, then clicking on the next one and seeing all the values he clicked are gone, with logical frustration...
Then when you are taking the values from the form, just take the enabled ones
The listener is not that difficult nor ugly to write. I would
make sure the lists only support single selection
add the same selection listener to both lists' selection model
This listener can be implemented as
public void valueChanged(ListSelectionEvent e){
if ( e.isAdjusting()) return;
ListSelectionModel sourceSelectionModel = (ListSelectionModel) e.getSource();
if ( !sourceSelectionModel.isSelectionEmpty() ){
//still need to implement the findOtherSelectionModel method
ListSelectionModel other = findOtherSelectionModel( sourceSelectionModel );
other.clearSelection();
}
}
Note that clearing the selection will trigger the listener again, but due to the isSelectionEmpty check you will not end up with a loop. Another approach would be to disable the listener (e.g. with a boolean flag) right before you call clearSelection on the other list.