2

I'm using a simple "Calculator" project as an example of rounded-rectangular buttons. The entire project consists of one small class file. Here it is:

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.KeyEvent;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.JTextField;

/**
 * Swing layout management tutorial
 *
 * This program shows how to use the
 * GridLayout manager to create a
 * calculator skeleton.
 *
 * @author jan bodnar
 * website zetcode.com
 * last modified February 2009
 */
public class Calculator extends JFrame {

    public Calculator() {
        setTitle("Calculator");
        initUI();
        setSize(320, 290);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        setVisible(true);
    }

    public void initUI() {
        JMenuBar menubar = new JMenuBar();
        JMenu file = new JMenu("File");
        file.setMnemonic(KeyEvent.VK_F);
        menubar.add(file);
        setJMenuBar(menubar);

        String[] labels = {
            "Cls", "Bck", "", "Close",
            "7", "8", "9", "/",
            "4", "5", "6", "*",
            "1", "2", "3", "-",
            "0", ".", "=", "+"
        };
        JTextField field = new JTextField();
        add(field, BorderLayout.NORTH);
        JPanel buttonPanel = new JPanel(new GridLayout(5, 4, 3, 3));
        buttonPanel.setBorder(BorderFactory.createEmptyBorder(8, 0, 0, 0));

        for (String label: labels) {
            if (label.isEmpty()) {
                JLabel lbl = new JLabel();
                buttonPanel.add(lbl);
            } else {
                JButton button = new JButton(label);
                buttonPanel.add(button);
            }
        }
        add(buttonPanel, BorderLayout.CENTER);
    }

    public static void main(String[] args) {
        new Calculator();
    }
}

When this runs, it produces nice rectangular labelled buttons with a flat, slightly 3D appearance. I attempted to get the same effect as follows:

    FlowLayout flowLayoutManager = new FlowLayout(FlowLayout.RIGHT);
    JPanel lowerPanel = new JPanel(flowLayoutManager);
    lowerPanel.setBorder(
            BorderFactory.createEtchedBorder(
            EtchedBorder.RAISED));
    lowerPanel.setBackground(Color.ORANGE);
    lowerPanel.setPreferredSize(new Dimension(700, 100));
    lowerPanel.setMaximumSize(lowerPanel.getPreferredSize());
    lowerPanel.setMinimumSize(lowerPanel.getPreferredSize());

    /*
     * cardReaderButtonPanel holds three card reader control buttons
     */
    JPanel cardReaderButtonPanel = new JPanel(new GridLayout(1, 3, 10, 0));
    cardReaderButtonPanel.setBorder(BorderFactory.createEmptyBorder(8, 0, 0, 0));
    cardReaderButtonPanel.setOpaque(false); // transparent background

    String[] labels = {"Load", "Stop", "Start"};
    for (String label : labels) {
        JButton button = new JButton(label);
        cardReaderButtonPanel.add(button);
    }
    lowerPanel.add(cardReaderButtonPanel);

... but my buttons look like Mac OS X Aqua lozenges! Unlike in the Calculator example, I'm adding the panel of buttons to an enclosing panel that itself is enclosed by the center of a BorderLayout - but I don't see how that could influence the way a button is drawn.

Chap
  • 3,649
  • 2
  • 46
  • 84
  • This is a question that gets asked a lot, and in fact many of these threads are linked to yours in the list of links on the right. Your task will involve a bit of work, but those links will help show you how to get started. – Hovercraft Full Of Eels Jul 13 '11 at 04:09
  • possible duplicate of [How to create a JButton extension with rounded corners?](http://stackoverflow.com/questions/1007116/how-to-create-a-jbutton-extension-with-rounded-corners) – Stephen C Jul 13 '11 at 05:49
  • I did see those links, but my real question is, how did the Calculator code that I was studying manage to produce rounded-rectangular buttons without seemingly doing anything special? I don't seem to be able to edit my original question, so I will post the Calculator code in its entirety (it's not long) via "Answer Your Question". When I compile & run it, I get square buttons, but I'm not able to figure out why. – Chap Jul 13 '11 at 06:11
  • Fantastic. I can't "answer my question" in order to post the entire code. – Chap Jul 13 '11 at 06:16
  • Anyway - point is, I am looking at a one-file program that's 89 lines long and only imports java.awt and javax.swing, yet manages to render round-rect buttons, but I can't see how, nor can I duplicate its behavior. And tomorrow, when SO lets me, I'll post the code in its entirety. – Chap Jul 13 '11 at 06:26
  • 1
    http://stackoverflow.com/questions/5751311/creating-custom-button-in-java/5755124#5755124 – mKorbel Jul 13 '11 at 06:37
  • @Chap: you don't have to "answer" your question but instead simply edit your original question adding any necessary code there. – Hovercraft Full Of Eels Jul 13 '11 at 21:23
  • @Hovercraft - yesterday, when I clicked Edit, I was instead presented with a blackish overlay whose purpose was unclear, and which didn't offer me any way to edit my post (I think it may have been related to someone's perception that this was a duplicate question, but I had no idea what action, if any, was required). That overlay doesn't appear this evening. – Chap Jul 14 '11 at 03:59
  • Original question edited to contain _entire_ Calculator class. – Chap Jul 14 '11 at 04:09

1 Answers1

4

On Mac OS X, a button's appearance is provided by an instance of com.apple.laf.AquaButtonUI. When the button's preferred size it within a particular range, it is displayed as shown here; otherwise, it is displayed as shown here. Note that both programs use a GridLayout; but the former uses the button's preferred size, while the latter stretches the buttons to fill the enclosing panel's preferred size. Resize the frames to see the effect.

Your example uses FlowLayout, which relies on the button's preferred size.

Addendum: The center of BorderLayout behaves similarly to GridLayout in this regard. Try adding a button to each of the five BorderLayout regions, and resize the frame to see the effect.

trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • @Trashgod: I was able to watch the buttons transform from Mac OS Aqua style to simple squares as I resized the frame. I don't yet understand all the variables that contribute to this behavior, but you've helped me to narrow it down. – Chap Jul 14 '11 at 04:21
  • 1
    @Chap: The result is determined by the layout manager of the container to which the buttons are added. – trashgod Jul 14 '11 at 04:32