This discussion is archived
9 Replies Latest reply: Jul 9, 2013 5:49 AM by d67f6f8e-38d5-4b8d-9488-eb91211a8977 RSS

Vertical JButton

843806 Newbie
Currently Being Moderated
Hi!

I'm new here and I have a problem with creating vertical button with vertical text. Basically what I want to do is to rotate JButton (including text and icon) by 90 degrees. |'ve already found some solutions on this and other forums over the Internet but none of them satisfy my needs. Some of the implementations don't support differrent UI themes. I already tried overriding paintComponent from JButton and I tried to rotate it, but it only works if width and height is the same (because of the paint region). I also tried to code my custom ButtonUI, but I can't paint background gradient for Metal L&F. Can anyone post a good solution? What I would like to achieve is the same look of vertical buttons as those from NetBeans pannels (gui editor doesn't support drawing such buttons). Thanks in advance.
  • 1. Re: Vertical JButton
    DarrylBurke Guru Moderator
    Currently Being Moderated
    Search this forum for my Vertical Button (without the space) class. It's L&F independent.

    db
  • 2. Re: Vertical JButton
    843806 Newbie
    Currently Being Moderated
    Without the space it finds nothing, with - many irrelevant topics...
  • 3. Re: Vertical JButton
    DarrylBurke Guru Moderator
    Currently Being Moderated
    I suppose you used the wrong search box, the correct one for searching the forum is the one on the left labeled "Search Forums", not the one on the top right labeled "search tips".

    Anyway since I have already searched it to verify that it could be found by a forum search, here it is:
    [Changing JButton Orientation|http://forum.java.sun.com/thread.jspa?threadID=5264675].

    There's quite a bit of room for improvement.

    db
  • 4. Re: Vertical JButton
    843806 Newbie
    Currently Being Moderated
    Seems to work fine. I need to add some alternations.

    BTW: Gradient stays in the same position...
  • 5. Re: Vertical JButton
    DarrylBurke Guru Moderator
    Currently Being Moderated
    Gradient stays in the same position...
    I personally think it looke better that way, but it's by no means impossible to obtain a rotated gradient, just even more hackish.
    import java.awt.Dimension;
    import java.awt.FlowLayout;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JToggleButton;
    import javax.swing.SwingUtilities;
    
    public class TestRotatedButton {
       
       void makeUI() {
          JFrame frame = new JFrame("Test Rotated Button");
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          frame.setSize(400, 400);
          frame.setLayout(new FlowLayout());
          frame.add(new RotatedButton("Test Clockwise", true));
          frame.add(new RotatedButton("Test Anticlockwise", false));
          frame.setLocationRelativeTo(null);
          frame.setVisible(true);
       }
       
       public static void main(String[] args) {
          SwingUtilities.invokeLater(new Runnable() {
             public void run() {
                new TestRotatedButton().makeUI();
             }
          });
       }
    }
    
    class RotatedButton extends JButton {
       
       XButton template;
       boolean clockwise;
       
       RotatedButton(String text, boolean clockwise) {
          template = new XButton(text);
          this.clockwise = clockwise;
          
          Dimension d = template.getPreferredSize();
          setPreferredSize(new Dimension(d.height, d.width));
       }
       
       @Override
       protected void paintComponent(Graphics g) {
          Graphics2D g2 = (Graphics2D) g.create();
          
          Dimension d = getSize();
          template.setSize(d.height, d.width);
          
          if (clockwise) {
             g2.rotate(Math.PI / 2.0);
             g2.translate(0, -getSize().width);
          } else {
             g2.translate(0, getSize().height);
             g2.rotate(- Math.PI / 2.0);
          }
          template.setSelected(this.getModel().isPressed());
          template.paintComponent(g2);
          g2.dispose();
       }
       
       private class XButton extends JToggleButton {
          XButton(String text) {
             super(text);
          }
          
          @Override
          public void paintComponent(Graphics g) {
             super.paintComponent(g);
          }
       }
    }
    db

    edit A more complete implementation would want to override set / getText to forward to template. Also probably overrides for set / getIcon, and possibly a few more methods. All such overrides would have to invoke setPreferredSize.

    Alternatively getPreferredSize could be overridden to return the rotated preferredSize of template.

    Edited by: Darryl.Burke
  • 6. Re: Vertical JButton
    843806 Newbie
    Currently Being Moderated
    I like this solution more, but I think it's better to extend JButton than JToggleButton. The highlight for system L&F is different for JToggleButton (Windows). Thanks again for your nice hacks...
  • 7. Re: Vertical JButton
    DarrylBurke Guru Moderator
    Currently Being Moderated
    In the default L&F -- Metal -- calling setPressed on a JButton template's model does not give the blue shade of a pressed JButton but rather a gray that matches the background of the JFrame. That's why I opted for JToggleButton and setSelected.

    Inconsistencies... ;-)

    db
  • 8. Re: Vertical JButton
    d67f6f8e-38d5-4b8d-9488-eb91211a8977 Newbie
    Currently Being Moderated

    import java.awt.Dimension;

    import java.awt.Graphics;

    import java.awt.Graphics2D;

    import javax.swing.Action;

    import javax.swing.Icon;

    import javax.swing.JButton;

     

    /**

    *

    * @author Michal

    */

    public class VerticalButton extends JButton implements Cloneable {

     

        //<editor-fold defaultstate="collapsed" desc="Clockwise">

        private boolean clockwise = false;

        /** Po směru hodinových ručiček? */

        public void setClockwise(boolean clockwise) {

            this.clockwise = clockwise;

        }

        /** Po směru hodinových ručiček? */

        public boolean getClockwise() {

            return clockwise;

        }

        /** Po směru hodinových ručiček? */

        public boolean isClockwise() {

            return clockwise;

        }

        //</editor-fold>

     

        //<editor-fold defaultstate="collapsed" desc="Constructors">

        public VerticalButton() {

        }

     

        public VerticalButton(Action a) {

            super(a);

        }

     

        public VerticalButton(Icon icon) {

            super(icon);

        }

     

        public VerticalButton(String text) {

            super(text);

        }

     

        public VerticalButton(String text, Icon icon) {

            super(text, icon);

        }

     

        public VerticalButton(String text, boolean clockwise) {

            this(text);

            this.clockwise = clockwise;

        }

        //</editor-fold>

     

        @Override

        public Dimension getPreferredSize() {

            return rotate(super.getPreferredSize());

        }

     

        private Dimension rotate(Dimension d) {

            return new Dimension(d.height, d.width);

        }

     

        @Override

        public void paintComponent(Graphics g) {

            Graphics2D g2 = (Graphics2D) g.create();

            VerticalButton clone = clone();

            clone.setSize(rotate(this.getSize()));

            if (clockwise) {

                g2.rotate(Math.PI / 2.0);

                g2.translate(0, -getSize().width);

            } else {

                g2.translate(0, getSize().height);

                g2.rotate(-Math.PI / 2.0);

            }

            clone.paintSuperComponent(g2);

            g2.dispose();

        }

     

        public void paintSuperComponent(Graphics g) {

            super.paintComponent(g);

        }

     

        @Override

        protected VerticalButton clone() {

            try {

                return (VerticalButton) super.clone();

            } catch (CloneNotSupportedException cloneNotSupportedException) {

                return null;

            }

        }

     

    }

  • 9. Re: Vertical JButton
    PhHein Guru Moderator
    Currently Being Moderated

    This thread is more than five years old!

     

    Mod: locking.