2

I am trying to create a triangle button.

I don't know how to do it so i'm gonna need for help in creating and please explane to me how to create it!

Here's what I'm trying to achieve:

enter image description here

Any ideas?

user1118321
  • 25,567
  • 4
  • 55
  • 86

5 Answers5

6

According to this, It looks like you just have to subclass JButton and override the paintBorder() and contains() methods

I create this not so quick and dirty example. I thought it would be faster but it took me about 15 minutes to come with this.

a triangular jbutton

Visually looks flat, because I use the same border and paint the same always, but you might want to provide different representations for onmouse over, click, enable, disable, etc. etc.

If you run this code, you may see only "Click" text is executed when you actually click inside the triangle:

import java.awt.Polygon;
import java.awt.Shape;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JPanel;
import java.awt.Dimension;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

class TriangleButton extends JButton {
    private Shape triangle = createTriangle();

    public void paintBorder( Graphics g ) {
        ((Graphics2D)g).draw(triangle);
    }
    public void paintComponent( Graphics g ) {
        ((Graphics2D)g).fill(triangle);
    }
    public Dimension getPreferredSize() {
        return new Dimension(200,100);
    }
    public boolean contains(int x, int y) {
        return triangle.contains(x, y);
    }

    private Shape createTriangle() {
        Polygon p = new Polygon();
        p.addPoint( 0   , 100 );
        p.addPoint( 100 , 0   );
        p.addPoint( 200 ,100  );
        return p;
    }
}

public class A {

    public static void main( String ... args ) {
        JFrame frame = new JFrame();
        final JButton b =  new TriangleButton();
        b.addActionListener( new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.out.println("Click!");
            }
        });
        frame.add( new JPanel(){{add(b);}} );
        frame.setVisible(true);

    }
}
Community
  • 1
  • 1
OscarRyz
  • 196,001
  • 113
  • 385
  • 569
  • A problem is positioning text or icons, would need fontmetrics. – arynaq Jun 04 '13 at 20:27
  • Yeah, it is not trivial. You may delegate to an existing component to paint it for you. Might be worth reading this: http://stackoverflow.com/a/370284/20654 – OscarRyz Jun 04 '13 at 21:10
4

You probably just want to extend the JButton and override the .paint(Graphics g) method (extending JComponent is semantically incorrect and may cause trouble with other frameworks since this is a button). paint is where the code that "paints" the button onto the screen goes. If you add custom code to draw the button they way you want it, it will appear differently on the screen. You'll probably want to implement java.awt.event.MouseListener for your button so that you can have different effects for your button when the user hovers over it or clicks on it.

From another answer, you'll want to override contains(int x, int y) so that the clickable area reflects the actual shape of your button.

But this isn't a quick thing you want to do and you can just grab something readymade from Java, you'll have to make it yourself and it's quite involved but very doable.

Sled
  • 18,541
  • 27
  • 119
  • 168
3

It is harder to create a custom made GUI button using swingGUI. So be it simple and making a triangle on a button in netbeans IDE

public class TriangleButton extends javax.swing.JFrame {


public TriangleButton() {
    initComponents();
}

private void initComponents() {

    jPanel1 = new javax.swing.JPanel();
    jButton1 = new javax.swing.JButton();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

    jButton1.setIcon(new javax.swing.ImageIcon("triangle.png")); 
    jButton1.setText("text1");
    jButton1.setActionCommand("hii");
    jButton1.setBorder(null);
    jButton1.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR));
    jButton1.setMargin(new java.awt.Insets(0, 0, 0, 0));
    jButton1.setPressedIcon(new javax.swing.ImageIcon("triangle.png")); 
    jButton1.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            jButton1ActionPerformed(evt);
        }
    });

    javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
    jPanel1.setLayout(jPanel1Layout);
    jPanel1Layout.setHorizontalGroup(
        jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(jPanel1Layout.createSequentialGroup()
            .addGap(104, 104, 104)
            .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 196, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addContainerGap(90, Short.MAX_VALUE))
    );
    jPanel1Layout.setVerticalGroup(
        jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(jPanel1Layout.createSequentialGroup()
            .addGap(52, 52, 52)
            .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 177, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addContainerGap(93, Short.MAX_VALUE))
    );

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addContainerGap()
            .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addContainerGap()
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addContainerGap())
    );

    pack();
}

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
    System.out.println("Hiiiiii");
}                                        


public static void main(String args[]) {
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new TriangleButton().setVisible(true);
        }
    });
}


private javax.swing.JButton jButton1;
private javax.swing.JPanel jPanel1;


![https://i.stack.imgur.com/KUPWQ.jpg][1]}
Murali
  • 774
  • 6
  • 12
2

There is no standard component that i know of that does this, You will need to create your own.

Extend one that is similar or just extend a jpanel.

http://www.programmersheaven.com/mb/java/247058/247058/draw-a-triangle/ gives some code for drawing a triangle.

To make it more "button" like you will need a listener.

exussum
  • 18,275
  • 8
  • 32
  • 65
0

Assuming we're talking about Swing, your best bet would be to take the source code for JComponent, and modify the _paintImmediately method to draw a triangle instead of a rectangle.

It would probably be easier to create your own Java GUI library.

Gilbert Le Blanc
  • 50,182
  • 6
  • 67
  • 111
  • how can i do that?I see the source code,but i'm trying to understand.You mean i should create a new class and rewrite my "own" source code? – Manolis Karagiannis Jun 04 '13 at 18:27
  • @Manolis Karagiannis: Yes, that's what I mean. Copy JComponent into your project, give it a more project specific name, and modify the _paintImmediately method. Of course, you'll have to copy the source code for every Swing component extended from JComponent into your project, so that you can modify them all to use your project specific JComponent. – Gilbert Le Blanc Jun 04 '13 at 18:30
  • Hmm..I'll try that.Thank you for your answer.Well this was one theme on exams and the studends had only 1 hour to deliver that button.I think there is a fastest way.I don't djudje your answer,thanks again for your interest!;) – Manolis Karagiannis Jun 04 '13 at 18:35