Read-only JSpinner?
This may seem a little weird, but bear with me; I think the use case is valid.
I am writing an abstract java.beans.Customizer that makes use of the JGoodies Binding framework, specifically the PresentationModel class. You need not know any details about this class except that it makes working with Java Beans properties very simple and allows many views to reflect changes in a common underlying model (the bean itself).
Users of this Customizer who subclass it typically need to create some kind of Swing widget and bind it to a bean property, like so:
this.bind(this.ageSpinner,"age");
As I hope is clear this means bind the Customizer's bean property "age" to the ageSpinner component, which, for the sake of this question, let's assume is a JSpinner.
Now, it just so happens that getAge() happens to be a computed property (that is, there is no setter).
I would like it to be the case that if someone decides to bind a JSpinner to a read-only property that the spinner would not permit edits of any kind.
I would also like it to be the case, however, that the user could, if they so desired, select text in the JSpinner's editor. This means that jSpinner.setEnabled(false) doesn't cut it.
JSpinner does not support an "editable" property, and its editor already has a read-only JFormatted text field. What I need to do is disable any effect the spinner's buttons may have on its associated JFormattedTextField. What's the best way of doing this?
Thanks,
Laird
[1563 byte] By [
ljnelsona] at [2007-11-26 17:50:35]

# 4
Hi, Michael; try your solution. The buttons still work, and the value still gets set. Thanks anyhow for your time.
What's really needed is a way to disable the buttons, but the buttons are UI-delegate specific. I'm inclined to go with a previous poster's suggestion of a custom model whose setValue() does nothing. This seems kind of icky to me, but should accomplish what I want.
# 5
not sure what you're trying to do - seems like you don't want to disable the
spinner, just the buttons
if so, this seems to work OK (1.4.0_01)
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class Testing
{
public void buildGUI()
{
JPanel p = new JPanel();
JSpinner spinner = new JSpinner(new SpinnerNumberModel(50, 0, 100, 5));
spinner.setUI(new MyUI());
p.add(spinner);
JFrame f = new JFrame();
f.getContentPane().add(p);
f.pack();
f.setLocationRelativeTo(null);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable(){
public void run(){
new Testing().buildGUI();
}
});
}
}
class MyUI extends javax.swing.plaf.basic.BasicSpinnerUI
{
protected Component createNextButton()
{
return new javax.swing.plaf.basic.BasicArrowButton(SwingConstants.NORTH);
}
protected Component createPreviousButton()
{
return new javax.swing.plaf.basic.BasicArrowButton(SwingConstants.SOUTH);
}
}
# 6
i guess if you're going to have to make assumptions about the UI, you could just use a custom JSpinner:
JSpinner s = new JSpinner() {
public void updateUI() {
super.updateUI();
for (Component c : getComponents()) {
if (c instanceof AbstractButton) {
c.setEnabled(false);
}
}
}
};
# 7
> i guess if you're going to have to make assumptions
> about the UI, you could just use a custom JSpinner:
> > JSpinner s = new JSpinner() {
> public void updateUI() {
> super.updateUI();
> for (Component c : getComponents()) {
> if (c instanceof AbstractButton) {
> c.setEnabled(false);
> }
> }
> }
> };
>
Hi, Jaspre; I like this. Thanks.