-2

I am creating a program in Java, and would like to make my own button class as opposed to using a JButton. I've got all the aesthetics sorted out but I'm not sure how to get the mouse pressed event in Java. This is my code:

// Button.java
package cella;

import java.awt.Color;
import java.awt.Point;
import java.awt.Graphics;

import java.awt.event.MouseEvent;

public class Button extends MouseAdapter {
    int x, y, w, h;
    String ph, val;
    boolean mouseDown;
    Color LIGHTGRAY = new Color(200, 200, 200);
    public Button(int xt, int yt, int wt, int ht, String pht, String valt) {
        x = xt;
        y = yt;
        w = wt;
        h = ht;
        ph = pht;
        val = valt;
        mouseDown = false;
    }

    public void draw(Graphics g, Point mouse) {
        if (contains(mouse)) {
            g.setColor(Color.GRAY);
        } else {
            g.setColor(LIGHTGRAY);
        }
        g.fillRect(x, y, w, h);
        g.setColor(Color.BLACK);
        g.drawRect(x, y, w, h);
        g.drawString(ph, x + 5, y + h - 5);
    }   

    private boolean contains(Point pos) {
        if (pos.x > x && pos.x < x + w && pos.y > y && pos.y < y + h) {
            return true;
        } else {
            return false;
        }
    }
    public boolean pressed(Point pos) {
        if (contains(pos) && mouseDown) {
            System.out.println("Pressed");
            return true; 
        }
        else return false;
    }
}

The boolean mouseDown will be set to true when the mouse is pressed and then false when released however i can't find a way to catch these events, mouseListener gives errors about needing abstract classes when i try to implement it. Thanks for any help you can give me.

Full code

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Thomas Ayling
  • 95
  • 2
  • 10
  • 1
    When making a custom component, you rather want `JComponent` as base class – Gyro Gearless Jun 11 '18 at 11:17
  • @GyroGearless So i should make the `button` class extend `JComponenent`? – Thomas Ayling Jun 11 '18 at 11:25
  • 1
    You say you want to create a custom component with jbutton functionality. Ok it makes sense. But why dont you simply extend JButton class and override everything you want to re-work? It would be the safest option here. – George Z. Jun 11 '18 at 11:31
  • @GeorgeZougianos i was trying to do something like that earlier but looking into the source code for a `JButton` makes no sense as to what i should be overriding – Thomas Ayling Jun 11 '18 at 11:34
  • @Thomas Ayling The way i see it, according to the given class an override in paintComponent () would be enough. – George Z. Jun 11 '18 at 11:36
  • 1
    *"..would like to make my own button class as opposed to using a JButton."* Why? – Andrew Thompson Jun 11 '18 at 13:32
  • 1
    @AndrewThompson: do you suspect that this question is in fact an [XY Problem](http://xyproblem.info/) type question? To the original poster, please check out this link to understand what I'm talking about. You're currently asking "how do I fix this code problem" when the best solution may in fact be to use a different approach entirely. Consider telling us the overall problem that you're trying to solve rather than how you're currently trying to solve it. – Hovercraft Full Of Eels Jun 11 '18 at 23:52
  • 1
    @HovercraftFullOfEels In short, yes. – Andrew Thompson Jun 12 '18 at 03:21

3 Answers3

0

Try this.

JButton button = new JButton("Click!");

button.addMouseListener(new MouseAdapter() {
  public void mouseClicked(MouseEvent e) {
    if (e.getButton() == MouseEvent.NOBUTTON) {
      textArea.setText("No button clicked...");
    } else if (e.getButton() == MouseEvent.BUTTON1) {
      textArea.setText("Button 1 clicked...");
    } 

  }
});

See available methods

Hope this help!

Vinit Mehta
  • 449
  • 4
  • 13
  • I knwo about the `JButton`, I wanted to make my own button class to have my own graphics etc – Thomas Ayling Jun 11 '18 at 11:27
  • Thanks anyway though – Thomas Ayling Jun 11 '18 at 11:28
  • @ThomasAyling Please check this https://stackoverflow.com/questions/2158/creating-a-custom-jbutton-in-java – Vinit Mehta Jun 11 '18 at 11:29
  • You can create your own custom class by extending JButton class. Thanks – Vinit Mehta Jun 11 '18 at 11:30
  • Are you sure? The JButton class provides options to set its variables to make it customized. Furthermore you could extend the class if you really wanted to add more functionality. However if its just for aesthetic reasons, JButton allows for good customization already, its not advised to reinvent the wheel – Zeeno Jun 11 '18 at 11:30
0

You can add a listener to your button that handles the event.

JButton button = new JButton("Click for Stuff");

button.addMouseListener(new MouseAdapter() {
  public void mouseClicked(MouseEvent e) {
    switch(e.getButton())
     { 
      case MouseEvent.NOBUTTON : // do stuff on button release
           break;
      case MouseEvent.BUTTON1 : // do stuff on click
           break;

     }
  }
});
Zeeno
  • 2,671
  • 9
  • 37
  • 60
0

I know this question is a few years old, but I thought my input might be useful to someone down the road trying to accomplish the same task, considering I have some experience in custom UIs.

If you want a fully non-JComponent button, then you're going to need to also program your mouselistener and a UI Object Registry and a render/update function all operating on their required threads. I've done that, complete with NumberInputFields, Buttons, PasswordFields, TextFields, TextAreas, Graphics, and a variety of other UI objects. You don't want to unless you're going for a radically different look and feel than what is already supplied with very different functionality (for instance, my TextArea and TextField took in BitLines made up of TextBits rather than Strings, which allowed for each character to individually be formatted or colored or sized, complete with customized hover and click events). If such a different result is desired, you would do well to look into everything that goes into making a full UI within a Canvas object. If not, you have a couple other options.

Option 1: Extend the JButton class like has already been suggested. This is the easiest and likely the best option for you. It's fairly simple, and you can make that button be whatever you want it to be (within reason, of course).

Option 2: Create your own custom look and feel by extending the BasicLookAndFeel class. This is more complex and may take a bit of time and research, but in the end you can format all of your program to have a consistent L&F throughout, giving a satisfying and unique look to your software.

Here's an example of what it can take to make a button with basic functionality, completely separate from the JComponent class. Please note that this does NOT include the many background classes required to make this operate, such as the registry, the renderer, the animation and image loaders, the listeners, etc.

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;

import dev.blue.neuron.storage.Animation;

public class Button extends UIObject {
    private Animation whileDown;

    private Animation whileUp;

    private int tooltipTimer = 0;

    private boolean showTooltip = false;

    private boolean useTooltip = false;

    protected boolean showingClicked = false;

    protected boolean isSelected;

    private boolean showID;

    private int fontSize;

    private Color color = Color.BLACK;

    public Button(String id, boolean showID, boolean useTooltip, int fontSize, int x, int y, int width, int height,
            int animationSpeed, Animation whileDown, Animation whileUp) {
        this.id = id;
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
        this.whileDown = whileDown;
        this.whileUp = whileUp;
        this.bounds = new Rectangle(x, y, width, height);
        this.showID = showID;
        this.fontSize = fontSize;
        this.useTooltip = useTooltip;
    }

    public void render(Graphics g) {
        animate();
        this.whileUp.render(g);
        this.whileDown.render(g);
        if (this.showID) {
            g.setFont(new Font("Helvetica", 1, this.fontSize));
            g.setColor(this.color);
            g.drawString(this.id, this.x + this.width / 2 - g.getFontMetrics().stringWidth(this.id) / 2,
                    (int) ((this.y + this.height / 2) + g.getFontMetrics().getHeight() / 3.5D));
        }
        if (this.showTooltip && this.useTooltip) {
            g.setFont(new Font("Helvetica", 0, 12));
            g.setColor(Color.GRAY);
            g.drawString(this.id, this.x, (int) (this.y + g.getFontMetrics().getHeight() * 1.5D));
        }
    }

    public void setColor(Color color) {
        this.color = color;
    }

    public void update() {
        if (this.hovering) {
            this.tooltipTimer++;
        } else if (this.showingClicked) {
            this.showingClicked = false;
        }
        if (this.tooltipTimer >= 50)
            this.showTooltip = true;
        runOnUpdate();
    }

    public void runOnUpdate() {
    }

    public void onMouseMove(Point p) {
        if (this.bounds.contains(p)) {
            if (!this.hovering) {
                this.hovering = true;
                runOnHover();
            }
        } else if (this.hovering) {
            this.hovering = false;
            this.showTooltip = false;
            this.tooltipTimer = 0;
            runOnStopHover();
        }
    }

    private void animate() {
        if (this.showingClicked) {
            if (!this.whileDown.isRunning()) {
                this.whileUp.end();
                this.whileDown.run();
            }
        } else if (!this.whileUp.isRunning()) {
            this.whileDown.end();
            this.whileUp.run();
        }
    }

    public boolean onClick(int button, Point p) {
        if (this.bounds.contains(p)) {
            runClick();
            return true;
        }
        return false;
    }

    public void runOnMissedClick() {
    }

    public boolean onMouseDown(int button, Point p) {
        if (this.bounds.contains(p)) {
            (App.getInstance().getMouseManager()).clickedObject = this;
            runMouseDown();
            this.showingClicked = true;
            return true;
        }
        return false;
    }

    public boolean onMouseUp(int button, Point p) {
        if ((App.getInstance().getMouseManager()).clickedObject == this)
            (App.getInstance().getMouseManager()).clickedObject = null;
        if (!this.bounds.contains(p))
            runOnMissedClick();
        if (this.showingClicked) {
            this.showingClicked = false;
            if (this.bounds.contains(p)) {
                runMouseUp();
                onClick(button, p);
                return true;
            }
            return false;
        }
        return false;
    }

    public void onType(KeyEvent e) {
    }

    public void onKeyPressed(KeyEvent e) {
    }

    public Animation getWhileUpAnim() {
        return this.whileUp;
    }

    public Animation getWhileDownAnim() {
        return this.whileDown;
    }

    public void setWhileUpAnim(Animation whileUp) {
        this.whileUp = whileUp;
    }

    public void setWhileDownAnim(Animation whileDown) {
        this.whileDown = whileDown;
    }

    public String getId() {
        return this.id;
    }

    public void setId(String id) {
        this.id = id;
    }
}
Blue Dev
  • 142
  • 8