I\'m looking for a JSpinner-like component that would provide built-in buttons that would immediately set the spinner value to the minimum or the maximum of the jspinner model.
I think it would be simple to implemt it by yourself
1) I would create a class that extend JPanel.
class MyPanel extends JPanel
2) In this class you have to define where your slider and buttons have to be placed and the actions correlated to the button.
public MyPanel(){
super();
// set the layout
JSlider slider = new Slider();
this.add(slider);
// ..
JButton button1 = new JButton();
//
}
3) You can add to your application JPanel instances of the class the you have implemented.
you have to read How to Use Spinners , and then you can be able set these value exactly for SpinnerNumberModel
JSpinner spinner = new JSpinner(new SpinnerNumberModel(0, 0, 20, 1));
for example (by StanislavL)
import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingUtilities;
import javax.swing.text.*;
public class TestDigitsOnlySpinner {
public static void main(String... args) {
SwingUtilities.invokeLater((Runnable) new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame("enter digit");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JSpinner jspinner = makeDigitsOnlySpinnerUsingDocumentFilter();
frame.getContentPane().add(jspinner, BorderLayout.CENTER);
frame.getContentPane().add(new JButton("just another widget"), BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
}
private JSpinner makeDigitsOnlySpinner_BasicAttempt() {
JSpinner spinner = new JSpinner(new SpinnerNumberModel());
return spinner;
}
private JSpinner makeDigitsOnlySpinnerUsingDocumentFilter() {
JSpinner spinner = new JSpinner(new SpinnerNumberModel(0, 0, 20, 1));
JSpinner.NumberEditor jsEditor = (JSpinner.NumberEditor) spinner.getEditor();
final Document jsDoc = jsEditor.getTextField().getDocument();
if (jsDoc instanceof PlainDocument) {
AbstractDocument doc = new PlainDocument() {
private static final long serialVersionUID = 1L;
@Override
public void setDocumentFilter(DocumentFilter filter) {
if (filter instanceof MyDocumentFilter) {
super.setDocumentFilter(filter);
}
}
};
doc.setDocumentFilter(new MyDocumentFilter());
jsEditor.getTextField().setDocument(doc);
}
return spinner;
}
});
}
private static class MyDocumentFilter extends DocumentFilter {
@Override
public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr) throws BadLocationException {
if (stringContainsOnlyDigits(string)) {
super.insertString(fb, offset, string, attr);
}
}
@Override
public void remove(FilterBypass fb, int offset, int length) throws BadLocationException {
super.remove(fb, offset, length);
}
@Override
public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
if (stringContainsOnlyDigits(text)) {
super.replace(fb, offset, length, text, attrs);
}
}
private boolean stringContainsOnlyDigits(String text) {
for (int i = 0; i < text.length(); i++) {
if (!Character.isDigit(text.charAt(i))) {
return false;
}
}
return true;
}
}
private TestDigitsOnlySpinner() {
}
}
I can't think of any component that would do it out of the box. But basically, a simple flow layout with a minus button, a spinner and a max button would do. Both buttons would have actionListeners
that will ask the spinner for min and max values and set its value.
Use a changeListener on the spinner to be notified of value changes both programatically (using your buttons) and through user interaction.
Also, you could consider using a JCombobox if your values are discrete or a JSlider if they are not, as both components present upper and lower bounds more clearly to users.
Regards, Stéphane