FlatLaf icon indicating copy to clipboard operation
FlatLaf copied to clipboard

Need way to have a spinner without editor

Open Chrriis opened this issue 3 years ago • 3 comments

Hi,

There is a trick in our UI that is broken when using FlatLaf. We want the look of a spinner next to an existing component so that the spinner seems sort of bound to that component, but we don't want to make that component the editor of the spinner.

This is the comparison between the Windows L&F and FlatLaf: EmptySpinner

This is the corresponding test case:

	public static void main(String[] args) throws Exception {
//		UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		UIManager.setLookAndFeel(new FlatLightLaf());
		UIDefaults defaults = UIManager.getDefaults();
		defaults.put("MenuItem.selectionType","underline");
		JFrame frame = new JFrame();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		JPanel contentPane = new JPanel(new GridBagLayout());
		JPanel mainContainer = new JPanel(new BorderLayout());
		mainContainer.add(new JTextField(7), BorderLayout.CENTER);
		final JSpinner emptySpinner = new JSpinner();
		emptySpinner.setBorder(UIManager.getBorder("TextField.border"));
		emptySpinner.setEditor(new JPanel(new BorderLayout()));
		emptySpinner.getModel().addChangeListener(new ChangeListener() {
			private int startValue = ((Integer)emptySpinner.getModel().getValue()).intValue();
			@Override
			public void stateChanged(ChangeEvent e) {
				int newValue = ((Integer)emptySpinner.getModel().getValue()).intValue();
				boolean isUp = newValue > startValue;
				startValue = newValue;
				System.out.println("Spinner event: up=" + isUp);
			}
		});
		mainContainer.add(emptySpinner, BorderLayout.EAST);
		contentPane.add(mainContainer);
		frame.setContentPane(contentPane);
		frame.setSize(400, 300);
		frame.setVisible(true);
	}

What is the recommended way of achieving this using FlatLaf? Thanks in advance 😉

Chrriis avatar Apr 21 '21 12:04 Chrriis

Hi Chrriis,

I dont't think that there is a 'recommended' way of doing this except writing an own UI class or creating a custom component.

A quick & dirty hack which works for me in FlatLaf with your example program (did not test it with other LAFs):

...
final JSpinner emptySpinner = new JSpinner();
emptySpinner.setBorder(UIManager.getBorder("TextField.border"));
Dimension dimension = UIManager.getDimension("Spinner.arrowButtonSize");
dimension.height = dimension.width;
dimension.width = dimension.width - 1;
emptySpinner.setPreferredSize(dimension);
emptySpinner.setEditor(new JLabel());
...

Result:

Screenshot von 2021-04-24 09 48 23

Bigdatha avatar Apr 24 '21 07:04 Bigdatha

@Bigdatha Thanks. I will use that for the time being. That being said, I still wish there were a more elegant way 😉

Chrriis avatar Apr 27 '21 14:04 Chrriis

May I ask why you'd want this? What's the problem you are trying to solve with this? There might be a more idiomatic way, such as writing a custom Spinner Editor. While slightly more effort, it is deffo more elegant.

Bios-Marcel avatar Apr 27 '21 14:04 Bios-Marcel