Search code examples
javaswinggraphicsjbutton

Custom JButton with Graphics for a Calculator Implementation


I'm trying to program a Calculator as close to the Windows 7/8 model as possible, and I'm currently trying to give the Jbuttons a custom look, but it's not going as planned.My button is called CalculatorButton which extends JButton. I'm currently using Graphics to draw borders and make it rounder than the standard JButton borders, but it only seems to work for one CalculatorButton instance, and not subsequently created ones.

Also please excuse the bad formatting, it's my first post.

below is the calculatorbutton class

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Insets;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.border.Border;

public class CalculatorButton extends JButton {

    CalculatorButton() {
        super();
        this.setFont(new Font("Segoe UI",Font.PLAIN,12));
        this.setOpaque(false);
        this.setFocusPainted(false);
    }

    CalculatorButton(String text) {
        super(text);
        this.setFont(new Font("Segoe UI",Font.PLAIN,12));
        this.setOpaque(false);
        this.setFocusPainted(false);
        this.setContentAreaFilled(false);
    }

    protected void paintBorder(Graphics g) {
        g.setColor(new Color(144,158,171));
        g.drawLine(getX()+1,getY(),getX()+getWidth()-2,getY());
        g.drawLine(getX()+1,getY()+getHeight()-1,getX()+getWidth()-2,getY()+getHeight()-1);
        g.drawLine(getX(),getY()+1,getX(),getY()+getHeight()-2);
        g.drawLine(getX()+getWidth()-1,getY()+1,getX()+getWidth()-1,getY()+getHeight()-2);
    }   
}

below is the calculator class

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Calculator extends JFrame {
    /***************************************/ //aesthetics like font,color,icons,etc
    private Color backgroundColor = new Color(218,229,240);

    /**************************************/ //menubar
    /*************************************///textfield
    private JPanel textPanel = new JPanel();
    /*************************************/
    private JPanel mainPanel = new JPanel();
    /*************************************/
    /*************************************/

    Calculator() {
        super("Calculator");
        setSize(400,320);
        setResizable(false);
        this.add(mainPanel,BorderLayout.CENTER);
        mainPanel.setBackground(backgroundColor);
        mainPanel.setLayout(new BoxLayout(mainPanel,BoxLayout.Y_AXIS));
        mainPanel.add(textPanel);
        textPanel.setLayout(new BoxLayout(textPanel,BoxLayout.X_AXIS));
        CalculatorButton c = new CalculatorButton("1");
        CalculatorButton cb = new CalculatorButton("w");
        textPanel.add(c);
        textPanel.add(cb);
        setVisible(true);
    }

    public static void main(String[]args)throws Exception {
        //UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        Calculator calc = new Calculator();
        calc.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }   
}

Solution

  • First of all, all painting is done within a local context. That is, the Graphics context is translated to the components location (x/y).

    This means that the top/left corner is actually 0x0 and the bottom/right corner is width - 1 x height - 1

    Second of all, instead of overriding paintBorder, you should consider making your own Border which meets your needs. Borders don't just paint, they also provide important information about the additional space they need