增加JSpinner箭头按钮的宽度

时间:2018-06-19 07:14:56

标签: java swing

我想增加JSpinner的宽度。我查看了互联网并找到了代码。我应用它但宽度没有增加。以下是代码

jsHR = new javax.swing.JSpinner();
Component c = jsHR.getComponent(0);
    if (c instanceof BasicArrowButton) {
        JButton b = (JButton) c;
        //b.setBounds(190, 2, 0, 0);
        b.setPreferredSize(new Dimension(100, 100));
b.setBorder(new LineBorder(Color.RED));
    }
jpTimePanel.add(jsHR);

jpTimePanel具有网格布局。

我出错了什么?如何增加JSpinner上的宽度或箭头按钮?

1 个答案:

答案 0 :(得分:0)

我为几个LookAndFeel中的每一个尝试了以下方法。

  • spinnder0
    • UIManager.put("Spinner.arrowButtonSize", new Dimension(130, 0));
  • spinner1
    • JButton#setPreferredSize(new Dimension(40, ...))
  • spinner2
    • JButton#setPreferredSize(new Dimension(50, ...))
    • JSpinner#setFont(spinner2.getFont().deriveFont(32f))
  • spinner3
    • JSpinner#setLayout(...)
    • int buttonsWidth = 100; // Math.max(nextD.width, previousD.width);
  • MetalLookAndFeel
    MetalLookAndFeel

  • NimbusLookAndFeel
    NimbusLookAndFeel

  • WindowsLookAndFeel
    WindowsLookAndFeel

import java.awt.*;
import java.util.stream.Stream;
import javax.swing.*;
import javax.swing.plaf.basic.BasicSpinnerUI;

public final class SpinnerArrowButtonSizeTest {
  private Component makeUI() {
    SpinnerModel model = new SpinnerNumberModel(5, 0, 10, 1);

    JSpinner spinner0 = new JSpinner(model);

    JSpinner spinner1 = new JSpinner(model);
    stream(spinner1)
      .filter(JButton.class::isInstance).map(JButton.class::cast)
      .forEach(b -> {
        Dimension d = b.getPreferredSize();
        d.width = 40;
        b.setPreferredSize(d);
      });

    JSpinner spinner2 = new JSpinner(model);
    spinner2.setFont(spinner2.getFont().deriveFont(32f));
    stream(spinner2)
      .filter(JButton.class::isInstance).map(JButton.class::cast)
      .forEach(b -> {
        Dimension d = b.getPreferredSize();
        d.width = 50;
        b.setPreferredSize(d);
      });

    JSpinner spinner3 = new JSpinner(model) {
      @Override public void setLayout(LayoutManager mgr) {
        super.setLayout(new SpinnerLayout());
      }
    };

    Box box = Box.createVerticalBox();
    box.add(spinner0);
    box.add(Box.createVerticalStrut(10));
    box.add(spinner1);
    box.add(Box.createVerticalStrut(10));
    box.add(spinner2);
    box.add(Box.createVerticalStrut(10));
    box.add(spinner3);

    JPanel p = new JPanel(new BorderLayout());
    p.add(box, BorderLayout.NORTH);
    p.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
    return p;
  }
  private static Stream<Component> stream(Container parent) {
    return Stream.of(parent.getComponents())
           .filter(Container.class::isInstance).map(c -> stream(Container.class.cast(c)))
           .reduce(Stream.of(parent), Stream::concat);
  }
  public static void main(String[] args) {
    EventQueue.invokeLater(() -> {
      try {
        UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
        // UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
      } catch (ClassNotFoundException | InstantiationException
                 | IllegalAccessException | UnsupportedLookAndFeelException ex) {
        ex.printStackTrace();
      }
      UIManager.put("Spinner.arrowButtonSize", new Dimension(130, 0));
      // UIManager.put("Spinner.arrowButtonInsets", new Insets(1, 1, 1, 1));
      UIManager.put("Spinner.disableOnBoundaryValues", Boolean.TRUE);
      JFrame f = new JFrame();
      f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
      f.getContentPane().add(new SpinnerArrowButtonSizeTest().makeUI());
      f.setSize(320, 240);
      f.setLocationRelativeTo(null);
      f.setVisible(true);
    });
  }
}

// @see javax/swing/plaf/basic/BasicSpinnerUI.java
class SpinnerLayout implements LayoutManager {
  private Component nextButton = null;
  private Component previousButton = null;
  private Component editor = null;

  @Override public void addLayoutComponent(String name, Component c) {
    if ("Next".equals(name)) {
      nextButton = c;
    } else if ("Previous".equals(name)) {
      previousButton = c;
    } else if ("Editor".equals(name)) {
      editor = c;
    }
  }

  @Override public void removeLayoutComponent(Component c) {
    if (c == nextButton) {
      nextButton = null;
    } else if (c == previousButton) {
      previousButton = null;
    } else if (c == editor) {
      editor = null;
    }
  }

  private Dimension preferredSize(Component c) {
    return (c == null) ? new Dimension() : c.getPreferredSize();
  }

  @Override public Dimension preferredLayoutSize(Container parent) {
    Dimension nextD = preferredSize(nextButton);
    Dimension previousD = preferredSize(previousButton);
    Dimension editorD = preferredSize(editor);

    /* Force the editors height to be a multiple of 2
     */
    editorD.height = ((editorD.height + 1) / 2) * 2;

    Dimension size = new Dimension(editorD.width, editorD.height);
    size.width += Math.max(nextD.width, previousD.width);
    Insets insets = parent.getInsets();
    size.width += insets.left + insets.right;
    size.height += insets.top + insets.bottom;
    return size;
  }

  @Override public Dimension minimumLayoutSize(Container parent) {
    return preferredLayoutSize(parent);
  }

  private void setBounds(Component c, int x, int y, int width, int height) {
    if (c != null) {
      c.setBounds(x, y, width, height);
    }
  }

  @Override public void layoutContainer(Container parent) {
    int width  = parent.getWidth();
    int height = parent.getHeight();

    Insets insets = parent.getInsets();

    if (nextButton == null && previousButton == null) {
      setBounds(editor, insets.left,  insets.top, width - insets.left - insets.right,
                height - insets.top - insets.bottom);

      return;
    }

    Dimension nextD = preferredSize(nextButton);
    Dimension previousD = preferredSize(previousButton);
    int buttonsWidth = 100; // Math.max(nextD.width, previousD.width);
    int editorHeight = height - (insets.top + insets.bottom);

    // The arrowButtonInsets value is used instead of the JSpinner's
    // insets if not null. Defining this to be (0, 0, 0, 0) causes the
    // buttons to be aligned with the outer edge of the spinner's
    // border, and leaving it as "null" places the buttons completely
    // inside the spinner's border.
    Insets buttonInsets = UIManager.getInsets("Spinner.arrowButtonInsets");
    if (buttonInsets == null) {
      buttonInsets = insets;
    }

    /* Deal with the spinner's componentOrientation property.
     */
    int editorX, editorWidth, buttonsX;
    if (parent.getComponentOrientation().isLeftToRight()) {
      editorX = insets.left;
      editorWidth = width - insets.left - buttonsWidth - buttonInsets.right;
      buttonsX = width - buttonsWidth - buttonInsets.right;
    } else {
      buttonsX = buttonInsets.left;
      editorX = buttonsX + buttonsWidth;
      editorWidth = width - buttonInsets.left - buttonsWidth - insets.right;
    }

    int nextY = buttonInsets.top;
    int nextHeight = (height / 2) + (height % 2) - nextY;
    int previousY = buttonInsets.top + nextHeight;
    int previousHeight = height - previousY - buttonInsets.bottom;

    setBounds(editor,         editorX,  insets.top, editorWidth, editorHeight);
    setBounds(nextButton,     buttonsX, nextY,      buttonsWidth, nextHeight);
    setBounds(previousButton, buttonsX, previousY,  buttonsWidth, previousHeight);
  }
}