In my application i have put listfield on the screen. Now my problem is that when i am clicking the list item (while list item has the focus on it) it does activities asopen the menu.
I want to disable the menu while clicking list. I want that if i click the list item it should perform only the necessary task defined in the item click event, Not shown the menu with it.
Any body has some idea about about that?
Override the navigationClick() for your ListField to consume the click event (should return true) without calling super.navigationClick():
protected boolean navigationClick(int status, int time) {
Status.show("Clicked on item: " + myList.getSelectedIndex());
return true;
}
Related
Creating a really basic Memory game using Java Swing. I created my GUI with a list of blank buttons where I set the icon property to none.
My code for some of the buttons is:
private void tbtnCard3ActionPerformed(java.awt.event.ActionEvent evt) {
tbtnCard3.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Card3Logo.png")));
if(tbtnCard5.isSelected()){
score++;
lblScore.setText(""+score);
}
}
private void tbtnCard4ActionPerformed(java.awt.event.ActionEvent evt) {
tbtnCard4.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Card7EWaste.png")));
if(tbtnCard7.isSelected()){
score++;
lblScore.setText(""+score);
}
}
private void tbtnCard5ActionPerformed(java.awt.event.ActionEvent evt) {
tbtnCard5.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Card3Logo.png")));
if(tbtnCard3.isSelected()){
score++;
lblScore.setText(""+score);
}
}
I have about 20 toggle buttons and for example the code above works and the scores go up by 1 when a match is found. So for tbtnCard3, if tbtnCard5 is selected the score goes up by 1. Now my question is how would I make it so that if tbtnCard3 is selected but tbtnCard 5 is not selected, display "Wrong Match". Since im using if Selected I'm not too sure how to display "wrong match" when the case is false. It doesn't make sense to say else ifSelected as no parameters can be put either....
In my opinion, the OPs suggestion is not a good approach. You do not want the listener of one button to be "aware" of some other component unnecessarily. Suppose you have an 8-by-8 grid with toggle buttons. You don't want each toggle button listener to be aware of the other 63 toggle buttons.
I believe there is a much simpler (and cleaner) approach. What you want is for the toggle button listener to register and deregister the toggle when the state of the button changes. Let say, you add the toggle button to or remove from a list (most likely a custom class) where you can trigger some logic when the list size reaches two. Then, depending on the outcome of the comparison, it will count a match (and disable these two toggle buttons in the current state), or will display some message like "Try again" and then toggle the buttons to hide the image.
In pseudocode, this will look something like this:
public class ToggleListener implements ItemListener {
public void actionPerformed (ItemEvent event) {
JToggleButton button = (JToggleButton) event.getSource();
if (event.getStateChange()==ItemEvent.SELECTED) {
// TODO Add the button to your list..
} else {
// remove button
}
}
}
In your Swing application, you can create a single instance of the above listener and add it to every single toggle button. And, as you can see, this listener is only responsible to register and unregister the component associated with the triggered event.
The "List Listener" on the other hand, is responsible to trigger the comparison logic when the size of the list reaches two. So, if you click on the same toggle button over and over again, the only thing the button listener will do is add or remove the button from the list depending on the button's current state. However, once a second button is toggled to reveal its image, the list listener will trigger the comparison logic. I am not 100% sure, but I think you could use JavaFX ObservableList interface or one of its implementing classes to do this. If the ListChangeListener.Change class is not suitable to figure out the size of the list to trigger the logic, you will have to implement this on your own. Regardless, in pseudocode, you need to do something like this:
public void onListChange(Event event) {
if (list.size() == 2 && btn1.getIconName().equals(btn2.getIconName())) {
displayMatchMessage();
btn1.setEnabled(false);
btn2.setEnabled(false);
list.clear(); // you should remove matched items from list manually
} else {
displayMismatchMessage();
btn1.setSelected(false); // flip the card
btn2.setSelected(false); // flip the card
// list.clear(); // you should not need this because the setSelected should trigger the Item Listener which should remove item from list.
}
}
Doing something like this is a much cleaner implementation where the button listener have a single job to do and the "list listener" has another job to do. Neither one encroaches on the other's job.
I've a recycler view on my app. I'd like to prevent multi selections on my recyclerView, because I'm getting unexpected output while trying to delete items.
holder.mView.setOnClickListener(v -> {
if (null != mListener) {
mListener.onPreviewItemClicked(position);
if (holder.isSelected) {
holder.mView.setBackgroundColor(Color.TRANSPARENT);
Log.d("positionClicked adapter",position+"");
holder.isSelected = false;
isSelected = holder.isSelected;
} else {
holder.mView.setBackgroundColor(ContextCompat.getColor(mContext, (R.color.accent_light)));
holder.isSelected = true;
positionClicked = position;
isSelected = holder.isSelected;
}
}
});
On my code, I use is Selected boolean to catch if something is clicked. When I click on an item, background of its changes. The thing is :
If I click on item1, then on item2, both items have backgrounds changed, and I'd like to have only one. And when I click on item, code below is done. But then, If i click again on item2, it goes transparent, which is good ! But the position of my item selected is wrong ( should be 1, but it's 2 because last item selected was 2). So when I delete, it will delete 2nd item and not first one...
I delete using positionClicked variable.
Any idea on how to fix this ?
You should keep if item is selected in your model, and use it in the onBindViewHolder to setup background for the ViewHolder. In OnClickListener just set true for the specific data item, false for all others and then call notifyDataSetChanged() to rebinf all items.
Let 'x' be an item in the JList. When I click it for the first time, the event fires, when I click it again, the event does not fire. I have to click some other item and then come back to 'x'.
How can I fire the event repeatedly from 'x' without having to deal with other items.
This is my code:
public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting() == false) {
if (list.getSelectedIndex() == -1) {} else {
String clicked = (String)list.getSelectedValue();
//method to fire is here
}
}
updateDisplays();
}
The ListSelectionListener reflects changes to the lists selection, you could use a MouseListener instead...
For example...
MouseListener ml = new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent evt) {
if (SwingUtilities.isLeftMouseButton(evt) && evt.getClickCount() == 1) {
if (list.getSelectedIndex() != -1) {
int index = list.locationToIndex(evt.getPoint());
System.out.println("You clicked item # " + index);
}
}
}
}
list.addMouseListener(ml);
You can add a MouseListener and watch for clicks. Note that a click that changes the selection will fire both the MouseListener and your ListSelectionListener.
Another option is to immediately clear the selection from your ListSelectionListener; that way the next click will reselect and retrigger, although you will lose the ability to navigate through items with the keyboard.
It seems like sort of an unusual UX decision, though, to assign significance to a click on an already selected item in a list.
Adding based on your question comments: If you go the MouseListener route, I recommend looking for double-clicks instead of single-clicks if the click is going to execute an action (especially if the action changes data and is not undoable). Also note that your ListSelectionListener will execute actions as you navigate through the list with the keyboard, which may not be what you intend.
If your commands in your history list are typed, you could also consider using a drop-down combo box for both command entry and the history list, where a selection from history fills in the command text but does not execute. You'd also have an opportunity to add auto-complete from command history.
I am looking for a method to prevent a user from hiding certain columns in my grids. I was trying to override Menu createContextMenu(final int colIndex) method of GridView where I find the submenu items that are related to my not-hidable columns and call disable() on them:
...
for (Component menuItem : menu.getItems()) {
String text = ((MenuItem) menuItem).getText();
if (((MenuItem) menuItem).getSubMenu() != null && (text.equals("Columns"))) {
for (Component subMenuItem : ((MenuItem) menuItem).getSubMenu().getItems()) {
String subMenuItemText = ((MenuItem) subMenuItem).getText();
if (<i want this column to be not hidable>) {
subMenuItem.disable();
}
}
}
}
...
It almost works - when the grid is just rendered the menu items that I disabled are greyed out and they don't accept user's input. However it all breaks after some other, not disabled columns are toggled. All of a sudden the disabled menu items become enabled.
I am using GXT 2.2.6.
Thank you!
The reason of the problem is found. Any changes in columns call GXT listeners and eventually restrictMenu method of GridView is called. This overrides all my disable settings. The solution is to add custom listener let GXT' listener do its job and then overwrite the enable/disable settings.
I am working on a project where I have many radio buttons in several radio groups. What I would like to do is save the configuration of all the radio groups in accordance to a specific button in the first radio group. For example the first radio group is called select and I have 4 different select radio buttons. When I switch from the 4 buttons inside that group I would like the other radio group buttons to be filled in automatically to that of what they were previously, I would also like to save the configuration of the current button when it is switched through out the radio group. So for example if a radio button in the first radio group is switched it remembers the configuration of the previous one and will automatically load itself again when it comes back to that view.
Create a model that models all of this. Use a property change listener (or many other listeners) to allow you to listen for update in state. The state will be updated whenever you call a setter on the model.
For example, when you set the outer radio button group to the 2nd button, then the model can throw property change events for all of the buttons which depend on that state. The getters for the state of the inner radio buttons can depend on the state of the outer button.
You will probably need to add listeners in the view that listen for user actions on the buttons. The actions in these listeners will call the setters on the model. Be careful to not cause recursive events this way.
Example:
This is an example of the model you could build. Say you have an outer radio button group with 2 buttons and single inner button group with 3 buttons. The inner group options are always the same regardless of the selected outer button.
public class Model {
private int outerSelected = 0; // 0 or 1
private InnerModel[] innerModels = new InnerModel[2];
private class InnerModel {
private int selected = 0; // 0, 1, or 2
public void setSelected(int selected) {
this.selected = selected;
// Send event
}
public int getSelected() {
return selected;
}
}
public int getSelectedInnerModel() {
return innerModels[outerSelected];
}
public int setOuterSelected(int outerSelected) {
this.outerSelected = outerSelected;
// send event for selectedInnerModel change
// If you use beans binding, this should cause the view to re-query the
// getSelected on the InnerModel as well
}
}
I wouldn't suggest you actually use integers. The enum is a better idea, but I didn't write it out. Optionally, you can make this Model class be private inside your view.