Creating Custom JButton in Java

Is there a way to create a JButton with your own button graphics, not just with the image inside the button?

If not, is there another way to create a custom JButton in java?

+82
java swing jbutton
Aug 05 '08 at 12:15
source share
5 answers

When I first studied Java, we had to make Yahtzee, and I thought it would be great to create custom Swing components and containers instead of just drawing everything on one JPanel . Of course, the advantage of expanding Swing components is that you can add support for keyboard shortcuts and other accessibility features that cannot be done simply by using the paint() method to print a beautiful image. However, this may not be done in the best way, but it may be a good starting point for you.

Edit 8/6 - If this was not visible from the images, each Die is a button that you can click. This will move it to the DiceContainer below. If you look at the source code, you will see that each Die button is drawn dynamically based on its value.

alt text
alt text
alt text

Here are the basic steps:

  • Create a class that extends JComponent
  • Calling parent constructor super() in your constructors
  • Make sure the class implements MouseListener
  • Put this in the constructor:

     enableInputMethods(true); addMouseListener(this); 
  • Cancel the following methods:

     public Dimension getPreferredSize() public Dimension getMinimumSize() public Dimension getMaximumSize() 
  • Cancel this method:

     public void paintComponent(Graphics g) 

The amount of space you should work with when drawing your button is determined by getPreferredSize() , assuming that getMinimumSize() and getMaximumSize() return the same value. I have not experimented too much with this, but depending on the layout you use for your GUI, your button may look completely different.

And finally, the source code . In case I missed something.

+83
Aug 05 '08 at 13:03
source share

Yes it is possible. One of the main benefits of using Swing is the ease with which abstract controls can be created and manipulated.

Here's a quick and dirty way to extend an existing JButton class to draw a circle to the right of the text.

 package test; import java.awt.Color; import java.awt.Container; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Graphics; import javax.swing.JButton; import javax.swing.JFrame; public class MyButton extends JButton { private static final long serialVersionUID = 1L; private Color circleColor = Color.BLACK; public MyButton(String label) { super(label); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Dimension originalSize = super.getPreferredSize(); int gap = (int) (originalSize.height * 0.2); int x = originalSize.width + gap; int y = gap; int diameter = originalSize.height - (gap * 2); g.setColor(circleColor); g.fillOval(x, y, diameter, diameter); } @Override public Dimension getPreferredSize() { Dimension size = super.getPreferredSize(); size.width += size.height; return size; } /*Test the button*/ public static void main(String[] args) { MyButton button = new MyButton("Hello, World!"); JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(400, 400); Container contentPane = frame.getContentPane(); contentPane.setLayout(new FlowLayout()); contentPane.add(button); frame.setVisible(true); } } 

Note that by overriding paintComponent that the contents of the button can be changed, but so that the border is painted using the paintBorder method. The getPreferredSize method also needs to be managed to dynamically support content changes. Care must be taken when measuring metrics and image sizes.

To create a control you can rely on, the above code is not correct. Dimensions and colors are dynamic in Swing and depend on the look and feel. Even the standard look of Metal has changed in JRE versions. It would be better to implement AbstractButton and comply with the recommendations of the Swing API. A good starting point is to look at the javax.swing.LookAndFeel and javax.swing.UIManager classes.

http://docs.oracle.com/javase/8/docs/api/javax/swing/LookAndFeel.html

http://docs.oracle.com/javase/8/docs/api/javax/swing/UIManager.html

Understanding Anatomy LookAndFeel is useful for writing controls: Creating a custom look and feel

+32
Aug 05 '08 at 12:53
source share

You can always try the look of Synth. You provide an xml file that acts as a kind of style sheet, as well as any images you want to use. The code might look like this:

 try { SynthLookAndFeel synth = new SynthLookAndFeel(); Class aClass = MainFrame.class; InputStream stream = aClass.getResourceAsStream("\\default.xml"); if (stream == null) { System.err.println("Missing configuration file"); System.exit(-1); } synth.load(stream, aClass); UIManager.setLookAndFeel(synth); } catch (ParseException pe) { System.err.println("Bad configuration file"); pe.printStackTrace(); System.exit(-2); } catch (UnsupportedLookAndFeelException ulfe) { System.err.println("Old JRE in use. Get a new one"); System.exit(-3); } 

From there, continue and add your JButton, as usual. The only change is that you use the setName (string) method to determine what the button should be displayed in the XML file.

An xml file might look like this:

 <synth> <style id="button"> <font name="DIALOG" size="12" style="BOLD"/> <state value="MOUSE_OVER"> <imagePainter method="buttonBackground" path="dirt.png" sourceInsets="2 2 2 2"/> <insets top="2" botton="2" right="2" left="2"/> </state> <state value="ENABLED"> <imagePainter method="buttonBackground" path="dirt.png" sourceInsets="2 2 2 2"/> <insets top="2" botton="2" right="2" left="2"/> </state> </style> <bind style="button" type="name" key="dirt"/> </synth> 

The binding element indicates what needs to be matched (in this example, it will apply this style to any buttons whose name has the value "dirt").

And some useful links:

http://javadesktop.org/articles/synth/

http://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/synth.html

+12
Aug 05 '08 at 12:47
source share

I'm probably going a million miles in the wrong direct (but I'm just young: P). but you could not add graphics to the panel, and then a mousetrap to the graphic object, so that the user on the chart performs your action.

+8
Aug 20 '08 at 15:48
source share

I did not develop SWING from the early CS classes, but if it hadn't been built, you could just inherit javax.swing.AbstractButton and create your own. It should be pretty easy to connect something along with your existing infrastructure.

+6
Aug 05 '08 at 12:30
source share



All Articles