问题
I finished a project early, so with the remaining time I had before submitting it, I wanted to experiment. The entire program works great, and the JButtons did exactly as they were programmed to do.
Something went awry after adding ImageIcon(s) to my JButtons. I'll show a few of the JButton initializations and show the original in a single comment above each block:
/**
* create child components
*/
private void initComponents() {
//normalSetupButton = new JButton("Normal Setup");
ImageIcon normalButtonImage = new ImageIcon("src/Images/normalIcon.png");
normalSetupButton = new JButton();
normalSetupButton.setIcon(normalButtonImage);
normalSetupButton.addActionListener(buttonHandler);
normalSetupButton.setToolTipText("Set up simulation for normal execution");
// queen test button
//queenTestButton = new JButton("Queen Test");
ImageIcon queenButtonImage = new ImageIcon("src/Images/yellowIcon.jpg");
queenTestButton = new JButton();
queenTestButton.setIcon(queenButtonImage);
queenTestButton.addActionListener(buttonHandler);
queenTestButton.setToolTipText("Set up to test Queen Lifespan or Food Levels");
// scout test button
//scoutTestButton = new JButton("Scout Test");
ImageIcon scoutButtonImage = new ImageIcon("src/Images/blueIcon.png");
scoutTestButton = new JButton();
scoutTestButton.setIcon(scoutButtonImage);
scoutTestButton.addActionListener(buttonHandler);
scoutTestButton.setToolTipText("Set up simulation for testing the Scout ant");
}
The only difference with the buttons is that there are now ImageIcons rather than text.
My problem lies in the following code. This is the first time I've ever used ImageIcons on Buttons, so I've always been accustomed to "button.getText().equals("Button String");"
public void actionPerformed(ActionEvent e) {
// get the button that was pressed
JButton b = (JButton) e.getSource();
// fire appropriate event
if (b.getText().equals("Normal Setup")) {
// set up for normal simulation
fireSimulationEvent(SimulationEvent.NORMAL_SETUP_EVENT);
} else if (b.getText().equals("Queen Test")) {
// set for testing the queen ant
fireSimulationEvent(SimulationEvent.QUEEN_TEST_EVENT);
} else if (b.getText().equals("Scout Test")) {
// set for testing the scout ant
fireSimulationEvent(SimulationEvent.SCOUT_TEST_EVENT);
} else if (b.getText().equals("Forager Test")) {
// set for testing the forager ant
fireSimulationEvent(SimulationEvent.FORAGER_TEST_EVENT);
} else if (b.getText().equals("Soldier Test")) {
// set for testing the soldier ant
fireSimulationEvent(SimulationEvent.SOLDIER_TEST_EVENT);
} else if (b.getText().equals("Run")) {
// run the simulation continuously
fireSimulationEvent(SimulationEvent.RUN_EVENT);
} else if (b.getText().equals("Step")) {
// run the simulation one turn at a time
fireSimulationEvent(SimulationEvent.STEP_EVENT);
} else if (b.getText().equals("Stop")) {
//stop everything
fireSimulationEvent(SimulationEvent.STOP_EVENT);
}
}
So, Swing gurus, how does one fire an event based on the ImageIcon of a JButton? Thanks for any help offered. If this doesn't work, I'll happily change it back to the old version with just plain text.
NOTE Yes, I know the images are not all in the same format. They aren't going to be the final images. I'm just testing and grabbed whatever format I could find for now.
回答1:
You are not set any text to JButton so it's not working, If you set text Text, then it will appear on the image, So you can do one thing
1. Set the setName
Method and add text to that.
2. in actionPerformed
, use getName
rather than getText
.
For Example:
ImageIcon normalButtonImage = new ImageIcon("src/Images/normalIcon.png");
normalSetupButton = new JButton();
normalSetupButton.setIcon(normalButtonImage);
normalSetupButton.setName("Normal Setup");
normalSetupButton.addActionListener(buttonHandler);
normalSetupButton.setToolTipText("Set up simulation for normal execution");
In Action performed :
public void actionPerformed(ActionEvent e) {
// get the button that was pressed
JButton b = (JButton) e.getSource();
// fire appropriate event
if (b.getName().equals("Normal Setup")) {
// set up for normal simulation
fireSimulationEvent(SimulationEvent.NORMAL_SETUP_EVENT);
}
......
回答2:
I think the best way to rework your code is to use client properties of a button.
private static final String EVENT_TYPE = "event_type";
// button creation
normalSetupButton = new JButton();
// set appropriate event for this button
normalSetupButton.putClientProperty(EVENT_TYPE, SimulationEvent.NORMAL_SETUP_EVENT);
// other init button routine
//next button
queenTestButton = new JButton();
queenTestButton.putClientProperty(EVENT_TYPE, SimulationEvent.QUEEN_TEST_EVENT);
// other init button routine
// same way for other buttons
public void actionPerformed(ActionEvent e) {
// get the button that was pressed
JButton b = (JButton) e.getSource();
SimulationEvent evt = (SimulationEvent) b.getClientProperty(EVENT_TYPE);
fireSimulationEvent(evt);
}
This looks better than "if-else if" cascade ;)
回答3:
There are multiple ways you might achieve this
You could...
Simply use the source
of the ActionEvent
Action voting = new AbstractAction(){
@Override
public void actionPerformed(ActionEvent e){
if (e.getSource() == vote_up) {
//...
} else if (...) {
//...
}
}
};
This might be okay if you have a reference to the original buttons
You could...
Assign a actionCommand
to each button
JButton vote_up = new JButton(upvote);
vote_up.setActionCommand("vote.up");
JButton vote_down = new JButton(downvote);
vote_down .setActionCommand("vote.down");
//...
Action voting = new AbstractAction(){
@Override
public void actionPerformed(ActionEvent e){
if ("vote.up".equals(e.getActionCommand())) {
//...
} else if (...) {
//...
}
}
};
You could...
Take full advantage of the Action
API and make indiviual, self contained actions for each button...
public class VoteUpAction extends AbstractAction {
public VoteUpAction() {
putValue(SMALL_ICON, new ImageIcon(getClass().getResource("vote_up.png")));
}
@Override
public void actionPerformed(ActionEvent e) {
// Specific action for up vote
}
}
Then you could simply use
JButton vote_up = new JButton(new VoteUpAction());
//...
Which will configure the button according to the properties of the Action
and will trigger it's actionPerformed
method when the button is triggered. This way, you know 100% what you should/need to do when the actionPerformed
method is called, without any doubts.
Have a closer look at How to Use Actions for more details
回答4:
@Sandeep.K
I'm still going to accept your answer, because I like the shorter call to "Normal Setup". I went the long way around before I saw your answer. Both work, but yours is better.
public void actionPerformed(ActionEvent e) {
// get the button that was pressed
JButton b = (JButton) e.getSource();
// fire appropriate event
if(b.getToolTipText().equals("Set up simulation for normal execution")) {
fireSimulationEvent(SimulationEvent.NORMAL_SETUP_EVENT);
}
else if(b.getToolTipText().equals("Set up to test Queen Lifespan or Food Levels")) {
fireSimulationEvent(SimulationEvent.QUEEN_TEST_EVENT);
}
else if (b.getToolTipText().equals("Set up simulation for testing the Forager ant (Scouts are included)")) {
// set for testing the forager ant
fireSimulationEvent(SimulationEvent.FORAGER_TEST_EVENT);
} else if (b.getToolTipText().equals("Set up simulation for testing the Soldier ant (Scouts are included")) {
// set for testing the soldier ant
fireSimulationEvent(SimulationEvent.SOLDIER_TEST_EVENT);
} else if (b.getToolTipText().equals("Run the simulation continuously")) {
// run the simulation continuously
fireSimulationEvent(SimulationEvent.RUN_EVENT);
} else if (b.getToolTipText().equals("Step through the simulation one turn at a time")) {
// run the simulation one turn at a time
fireSimulationEvent(SimulationEvent.STEP_EVENT);
} else if (b.getToolTipText().equals("Stop or Pause the simulation")) {
//stop everything
fireSimulationEvent(SimulationEvent.STOP_EVENT);
}
来源:https://stackoverflow.com/questions/37065186/after-adding-imageicons-to-jbuttons-buttons-no-longer-work