I'm making a To-Do List application and I have a PrimaryList frame and a SubList frame. When a user selects something from the PrimaryList (Grocery...or something like that) and then hits a forward arrow JButton, it is supposed to launch up the SubList frame. Now here is what I have for the actionPerformed method of the forward arrow button called btnArrow.
private void btnArrowActionPerformed(java.awt.event.ActionEvent evt) {
lstToDoLists.addListSelectionListener(new ListSelectionListener(){
public void valueChanged(ListSelectionEvent e){
if (lstToDoLists.getSelectedIndex() > 0){
btnArrow.addActionListener(new ActionListener(){
public void actionPerformed (ActionEvent ae){
if (btnArrow==ae.getSource()){
SubList sublist = new SubList();
sublist.setVisible(true);
}
}
});
}
}
});
}
Now, when I run the PrimaryList file and click on an item in my JList and then select the forward arrow button, I get nothing. But then when I click another element from the list and press the forward arrow button again, my SubList pops up twice.
Something isn't write with what I've written and I am hoping someone else will know how to fix this problem.
You're adding listeners inside of listeners -- something that you don't want to do, since this means that new listeners will be added, each time an event occurs.
Solution: don't add listeners inside of other event listeners but rather add the listeners once and in your code's constructor or initialization method.
Note that I would not use a ListSelectionListener at all. Instead I'd just use a single ActionListener on the button. Then in that listener, get the list's selection and use it.
e.g.,
private void btnArrowActionPerformed(java.awt.event.ActionEvent evt) {
// if list contains String:
String selectedItem = (String) lstToDoLists.getSelectedItem();
// check that selectedItem isn't null, i.e,
if (selectedItem != null) {
// TODO: do something with selection here
}
}
As a side recommendation, please look at The Use of Multiple JFrames, Good/Bad Practice?.
Related
I am designing Reversi game in java, and the structure is as follows:
a. A JFrame with 64 buttons in it. The buttons are stored in an array.
b. The JButtons will have black circles or white circles.
So whenever a move is to be made, the program will highlight those boxes where a move can be made, but how can I know which button (I want to know the index of that button) has been clicked when all are highlighted the same way?
From my understanding, you are attempting to detect when a specific JButton is pressed.
The simplest way to do this is by implementing an ActionListener.
public class ExampleClass implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == buttonNameOne)
System.out.println("Button One was pressed");
else if (e.getSource() == buttonNameTwo)
System.out.pringln("Button Two was pressed);
}
}
Detecting an action
The actionPerformed(ActionEvent e) method will activate whenever any button is pressed.
Recording source of action
When it is pressed, it automatically detects the source of this action (the button) and stores it in parameter "e".
Using recorded source of action
By simply doing e.getSource() you are able to get the component which invoked this method and compare it to pre-existing components in your program.
Customized arguments
With each if statement, you are able to customize and personalize the result of the condition (which is if the button being pressed is equal to a specific button). Do this by putting arguments within the body of each conditional statement:
if (e.getSource == sayHiButton)
System.out.println("Hi");
You probably have one ActionListener added to all buttons. Then the ActionEvent getSource passed to performAction has info. That is ugly, like testing the button text.
What is more normal is to use Action (take a look) and setting different actions bearing the 64 states.
public BoardAction extends AbstractAction {
public BoardAction(int x, int y) { ... }
#Override
public void actionPerformed(ActionEvent e) {
...
}
}
JButton button = new JButton(new BoardAction(x, y));
In an Action you can also specify the button caption, and an Action can also be (re)used in a JMenuItem and such.
Because of the extra indirection needed, most examples use an ActionListener,
but swing interna use Action quite often. For instance having an edit menu with cut/copy/pase and a toolbar with cut/copy/paste icons, context menus.
Background Information: I am currently working in a Dialog class I have extended for my game. Inside of this dialog's content table I have both an Image and a Table (lets call it ioTable). Inside of ioTable I have a combination of both Labels and TextFields. The idea is that the dialog becomes a sort of form for the use to fill out.
Next, inside of the Dialog's button table, I want to include a "Clear" TextButton (clearButton). The idea that clearButton will clear any values written to the TextFields of ioTable.
My Question: Is is possible to add a listener to each of the TextFields of ioTable that will trigger when clearButton is pressed. As always, any other creative solution is more than welcome.
You could just give the EventListener a reference to the table you want to clear:
// Assuming getSkin() and ioTable are defined elsewhere and ioTable is final
TextButton clearButton = new TextButton("Clear", getSkin());
clearButton.addListener(new EventListener() {
#Override
public boolean handle(Event event) {
for(Actor potentialField : table.getChildren()) {
if(potentialField instanceof TextField) {
((TextField)potentialField).setText("");
}
}
return true;
}
});
// Add clearButton to your dialog
If you see yourself creating multiple clearButtons, you could easily wrap this in a helper method or extend TextButton.
I'm making a simple GUI where the user can select an item from a list of Strings using the JList<String> component, and I want my program to update a JTextField with some data describing the selected item. I know I need an event listener, but I'm confused as to what I should use to detect a change in selection in my list.
You need to add it to the JList object:
myJList.addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent e) {
System.out.println("Hello you selected me! "
+ dataList.getSelectedValue().toString());
}
});
I have a JList which runs code each time the value in the list is double-clicked. The value is populated when a button is pressed. My problem is each time I click the button and then double-click the JList value it will repeat the code by however many times the button is pressed.
For example, the first time everything looks great, but if I press the button again to change the JList value, it will execute the code for a double-click twice. If I press it a third time, it will execute the code three times and so on. I am new to this so apologies if this is an easy one. Thanks for any info. Code is below let me know if more is necessary.
public DefaultListModel results(StringBuilder message)
{
DefaultListModel model = new DefaultListModel();
model.addElement(message);
showOption.setModel(model);
MouseListener mouseListener = new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2)
{
int index = showOption.locationToIndex(e.getPoint());
Object o = showOption.getModel().getElementAt(index);
System.out.println("Double-clicked on: " + o.toString());
}
}
};
showOption.addMouseListener(mouseListener);
return model;
}
You are adding a new MouseListener each time results is called...
This...
DefaultListModel model = new DefaultListModel();
model.addElement(message);
showOption.setModel(model);
Shows that showOption is an existing instance of JList (which is good), but then you do...
MouseListener mouseListener = new MouseAdapter() {
//...
};
showOption.addMouseListener(mouseListener);
Which adds ANOTHER MouseListener to the JList, so the each time this method is called, there will another MouseListener added to the JList.
Add a single MouseListener to the JList when you first create it.
I'm quite new to Java Swing. And I'm stuck on trying to add a ListSelectionListener on a JComboBox instance. It seems only the ListSelectionModel interface has addListSelectionListener method. I kind of cannot figure it out...
Why I want to do add it is that I want program do something even the item in the combo box is not changes after selecting.
POTENTIAL ANSWER
I was simply thinking of attaching an actionListener on combobox not working. and i think it's bug of openjdk. I've reported it here
Thanks in advance.
Take a look at JComboBox#addItemListener:
JComboBox combo = createCombo();
combo.addItemListener(new ItemListener()
{
#Override
public void itemStateChanged(ItemEvent e)
{
if (e.getStateChange() == ItemEvent.SELECTED)
{
Object selectedItem = e.getItem();
// Do something with the selected item...
}
}
});
This event is fired for both mouse and keyboard interaction.
For JComboBox, you'll have to use ActionListener.
JComboBox jComboBox = new JComboBox();
jComboBox.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("combobox event");
}
});
AFAIK, actionPerformed is raised whenever the user makes a selection for the JComboBox even if it's the same item that was already selected.
It depends on your requirement. The ActionEvent is only fired when the keyboard is used, not when the selection changes as the mouse is moved over the items.
If you want to do some action when the item selection changes even if the mouse is moved then yes you will probably need access to the JList. You can access the JList used by the popup with the following code:
JComboBox comboBox = new JComboBox(...);
BasicComboPopup popup = (BasicComboPopup)comboBox.getAccessibleContext().getAccessibleChild(0);
JList list = popup.getList();
list.addListSelectionListener(...);
Use a PopupMenuListener. When the popup menu closes get the selected index and do your processing.