shanec
shanec

Reputation: 15

JButton not working for me?

I am making a program where you choose a selection sort or a merge sort using JButtons and it sorts an int array in the form of a bar graph using Graphics where each element in the array is a bar.

but for some reason the compiler isn't receiving my button presses, i have tried to use (selection.equals(e.getSource()) in the if statement but it isnt working, am i missing something obvious or what?

public class Animation extends Canvas implements ActionListener{
JPanel panel;
JButton Selection;
JButton Merge;
boolean selection, merge;


int[] random = new int[25];
Sorter sort = new Sorter();
public Animation(){
    Selection = new JButton("Selection sort");
    Selection.addActionListener(this);
    Selection.setActionCommand("select");
    Merge = new JButton("Merge sort");
    Merge.addActionListener(this);
    Merge.setActionCommand("merge");
    panel = new JPanel();
    panel.add(Selection);
    panel.add(Merge);
    setBackground(Color.WHITE);
    selection=false;
    merge=false;

}
public void actionPerformed(ActionEvent e) {
    if("select".equals(e.getActionCommand())){
        selection = true;
        repaint();

    }
    else if("merge".equals(e.getActionCommand())){
        merge = true;
        repaint();
    }
}

public void paint (Graphics window){

    Random r = new Random();
    for(int i=0; i<random.length; i++){
        int randomInt = r.nextInt(100) + 1;
        random[i] = randomInt;
    }
    window.setColor(Color.MAGENTA);
    if(selection==true){
        for(int i=0; i< random.length-1; i++){
            int smallest = i;
            for(int j = i+1; j< random.length; j++){
                if(random[j] < random[smallest])
               smallest = j;        
                }
            if( smallest != i) {
                int least = random[smallest];
                random[smallest] = random[i];
                random[i] = least; 
                drawIt(random, window);
                window.setColor(Color.WHITE);
                drawIt(random, window);
                window.setColor(Color.MAGENTA);
            }
    }
    }

    drawIt(random, window);
    }
public void drawIt (int[] a, Graphics window1){
    int x=128;
    int height = 200;
    for(int i=0; i<a.length; i++){
        window1.drawLine(x, 200, x, height-a[i]);
        window1.drawLine(x+1, 200, x+1, height-a[i]);
        window1.drawLine(x+2, 200, x+2, height-a[i]);
        x+=20;
    }
    try {
        Thread.currentThread().sleep(100);
    } catch(Exception ex) {

    }

    }

   }

heres the main class to run it:

public class AnimationRunner extends JFrame{
private static final int WIDTH = 800;
private static final int HEIGHT = 250;
JButton Selection;
JButton Merge;

public AnimationRunner()
{
    super("Sorting Animation");
    setSize(WIDTH,HEIGHT);
    Animation a = new Animation();
    Merge = new JButton("Merge sort");
    Selection = new JButton("Selection sort");
    Merge.setSize(120, 30);
    Selection.setSize(120,30);
    Merge.setLocation(200, 30);
    Selection.setLocation(400, 30);
    this.add(Merge);
    this.add(Selection);
    ((Component)a).setFocusable(true);
    getContentPane().add(new Animation());
    setVisible(true);
}

public static void main( String args[] )
{

    AnimationRunner run = new AnimationRunner();
}
   }

Upvotes: 0

Views: 136

Answers (2)

MadProgrammer
MadProgrammer

Reputation: 347332

There are a series of cascading problems...

In the AnimationRunner class you create two JButtons called Merge sort and Selection sort and add these to the main frame. This is what's actually on the screen. This buttons have no listeners attached, therefore never notify any body when they are clicked...

In the Animation class you create two JBttonss called Merge sort and Selection sort and add these to panel (and instance of JPanel), which is never added to anything. This means you can never possibly click them...

You don't seem to have an understanding of how painting works in Swing and seem to be assuming that you control the paint process in some way.

Painting is controlled by the paint sub system in Swing, which schedules and performs paint cycles when and where it sees fit. This means that your paint method may be called for any number of reasons, many of which you don't control.

Remove the logic of the sort out of the paint process and place into some kind of model, whose state you can control. Then use the custom painting capabilities to render the state of the model.

paint is an inappropriate method to be using for custom painting and you should be using paintComponent. You have broken the paint chain which may prevent the component from rendering child components and/or introduce series paint artifacts into your program

Take a look at Performing Custom Painting and Painting in AWT and Swing for more details

Swing is a single threaded framework work. That means that anything that blocks the Event Dispatching Thread will prevent it from process new repaint requests or events into the system. This will cause your program to look like it's "hung". In your case, you will most likely only ever see the end result of the painting process...after a short delay.

Instead, consider using a javax.swing.Timer to introduce a safe delty and update the model each time it ticks.

Take a look at Concurrency in Swing and How to use Swing Timers for more details

Swing programs are expected to run on a variety of hardware and software platforms, all with there own notions of DPI and font rendering approaches. This makes it very difficult to accommodate your design to all the possible needs of these systems.

Swing makes this easier by providing a layout management API, which takes the fiddle work out of making these decisions. Take a look at Laying Out Components Within a Container for more details

You should also take a look at Code Conventions for the Java Programming Language, it will make it eaiser for people to read your code.

You might find this example of some benifit

Upvotes: 2

Java Devil
Java Devil

Reputation: 10969

You create a button for each action in your main class and add these to your JFrame. You also create a two instances of your Animation class. One which you create, setfocusable then do nothing with. Then another which you create and add to the contentPane of the JFrame.

In your Animation constructor you again create a button for each action, this time setting the action commands. You then add these to a panel. This panel is never added to anything and so these buttons will never be seen.

The buttons you see are not the buttons that you have defined the action commands for.

Also you should avoid using setSize() and Use Layout Managers to defines the sizes of your components.

Upvotes: 3

Related Questions