How to invert JSpinner layout

116 Views Asked by At

I have a JSpinner:

Spinner

I want the up/down buttons to be on the left side, and also the text to align on the left.

Is there a simple way I can achieve this? Thank you

JSpinner spinner = new JSpinner();
1

There are 1 best solutions below

0
happy songs On BEST ANSWER

You can override the methods found in BasicSpinnerUI for creating the next and previous buttons:

Custom Spinner UI:

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.border.CompoundBorder;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.UIResource;
import javax.swing.plaf.basic.BasicArrowButton;
import javax.swing.plaf.basic.BasicSpinnerUI;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.BorderLayout;

public class MyJSpinnerUI extends BasicSpinnerUI{
    public static ComponentUI createUI(JComponent c) {
        return new MyJSpinnerUI();
    }

    @Override 
    protected Component createNextButton(){
        // change arrow direction: up becomes right
        Component c = createArrowButton(SwingConstants.EAST);
        c.setName("Spinner.nextButton");
        c.setSize(new Dimension(5, 5));
        installNextButtonListeners(c);
        return c;
    }

    @Override
    protected Component createPreviousButton() {
        // change arrow direction: down becomes left
        Component c = createArrowButton(SwingConstants.WEST);
        c.setName("Spinner.previousButton");
        c.setSize(new Dimension(5, 5));
        installPreviousButtonListeners(c);
        return c;
    }

    @Override
    public void installUI(JComponent c) {
      super.installUI(c);
      c.removeAll();
      c.setLayout(new BorderLayout());

      // here you can play with their positioning
      c.add(createPreviousButton(), BorderLayout.WEST);
      c.add(createEditor(), BorderLayout.CENTER);
      c.add(createNextButton(), BorderLayout.EAST);
    }

    // private method inside BasicSpinnerUI
    private Component createArrowButton(int direction) {
        JButton b = new BasicArrowButton(direction);
        Border buttonBorder = UIManager.getBorder("Spinner.arrowButtonBorder");
        if (buttonBorder instanceof UIResource) {
            // Wrap the border to avoid having the UIResource be replaced by
            // the ButtonUI. This is the opposite of using BorderUIResource.
            b.setBorder(new CompoundBorder(buttonBorder, null));
        } else {
            b.setBorder(buttonBorder);
        }
        b.setInheritsPopupMenu(true);
        return b;
    }
}

Demo:

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import java.awt.Dimension;
import java.awt.FlowLayout;  

public class JSpinnerTest{

    public static void main(String[] args) {
        JFrame frame = new JFrame("JSpinner changed arrows");  
        JPanel panel = new JPanel();  
        JSpinner jSpinner = new JSpinner();

        // apply your custom Spinner UI
        jSpinner.setUI(new MyJSpinnerUI());

        jSpinner.setPreferredSize(new Dimension(100, 40));
        panel.setLayout(new FlowLayout());  
        panel.add(jSpinner);  
        frame.add(panel);
        frame.setVisible(true);  
        frame.setSize(1000, 400);  
        frame.setLocationRelativeTo(null);  
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  

    }
}