After adding ImageIcons to JButtons, buttons no longer work

蹲街弑〆低调 提交于 2019-12-12 03:28:16

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!