JSpinner and FocusListener

The method addFocusListener of JSpinner doesn't work. Is it a bug?

No it's not a bug. You might need to try harder to extract from the spinner something that can accept focus:
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SpinnerNumberModel;
public class JSpinFocusListener
  private JPanel mainPanel = new JPanel();
  private JSpinner spinner = new JSpinner(new SpinnerNumberModel(0, -10, 10, 1));
  private JTextField textField = new JTextField(10);
  public JSpinFocusListener()
    mainPanel.add(spinner);
    mainPanel.add(textField);
    // this doesn't work
    spinner.addFocusListener(new MyFocusListener("spinner"));
    // and this doesn't work
    spinner.getEditor().addFocusListener(new MyFocusListener("spinner's editor"));
    // but this one, works
    ((JSpinner.DefaultEditor) spinner.getEditor()).getTextField()
        .addFocusListener(new MyFocusListener("spinner's editor's textfield"));
  public JPanel getMainPanel()
    return mainPanel;
  private class MyFocusListener implements FocusListener
    private String name;
    public MyFocusListener(String name)
      this.name = name;
    public void focusGained(FocusEvent e)
      System.out.println("Focus gained on " + name);
    public void focusLost(FocusEvent e)
      System.out.println("Focus lost from " + name);
  private static void createAndShowUI()
    JFrame frame = new JFrame("JSpinFocusListener");
    frame.getContentPane().add(new JSpinFocusListener().getMainPanel());
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
  public static void main(String[] args)
    java.awt.EventQueue.invokeLater(new Runnable()
      public void run()
        createAndShowUI();
}

Similar Messages

  • Default background color and Focuslistener disapair on table?

    When I imp. TableCellRenderer on my table the default background color and Focuslistener disapair. What can I do to get it back and still keep TableCellRenderer on my table? This is how my TableCellRenderer looks:
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
            JFormattedTextField beloeb = new JFormattedTextField();
            beloeb.setFormatterFactory(new DefaultFormatterFactory(new NumberFormatter()));
            beloeb.setBorder(null);
            beloeb.setHorizontalAlignment(JTextField.RIGHT);
            if (value != null) {
                if (value instanceof Double) {
                    Double val = (Double) value;
                    beloeb.setValue(val);
                    if (val.doubleValue() < 0) {
                        beloeb.setForeground(Color.RED);
            beloeb.setFont(new Font("Verdana",Font.PLAIN, 11));
            beloeb.setOpaque(true);
            return beloeb;
        }

    I'm sorry to say this is a terrible example of a renderer. The point of using a renderer is to reuse the same object over and over. You don't keep creating Objects every time a cell is renderered. In your example your are creating:
    a) JFormattedTextField
    b) NumberFormatter
    c) DefaultFormatterFactory
    d) Font.
    So you start by extending the DefaultTableCellRenderer. A JLabel is used to display the text. There is no need to use a JFormattedTextField. All you want to do is format the data. So in your constructor for the class you would create a NumberFormatter that can be reused to format your data. Then your code in the renderer would look something like:
    if (value instanceof Double)
        Double val = (Double)value;
        setText( formatter.format(val) );
        if (negative)
          setForeground(Color.RED)
        else
            setForeground(table.getForeground());
    }Here is a really simple [url http://forum.java.sun.com/thread.jsp?forum=57&thread=419688]example to get you started

  • JDK1.4 JSPinner and DateFormatSymbols

    Hi,
    I have a problem with DateFormatSymbols().getWeekdays(); use in JSPinner and JCOmboBox
    The getWeekdays() method returns a STring[] containing the nameof the days (sunday, ...) in a localized way. I want to use these names inside a JSPinner or a JCombobox. The names are properly inserted, but there is a 'empty' value containing no string, even after calling the setEditable(false)
    any idea on how to remove that empty 'day'??
    thanks,
    vincent

    Store the String[] in a local copy and remove from that local copy manually the "empty day". Then use the manipulated local copy in the JComboBox ...

  • JSpinner and very small values

    I Have a JSpinner and i wrote this code
    Double v = new Double(3.111110001111111111111111111111111111111111111);
    double min = 0;
    double max = 10;
    double step = 0.0001;
    SpinnerModel spinnerModel = new SpinnerNumberModel(v.doubleValue(),min,max,step);The are two problems
    1. The variable v is represented as '3,111'
    2. The step is incorrect... When i click on the up arrow, the number don't change. If I set the step to '0.001' all works correctly.
    There is a solution?

    If step = 0.0001 or step < 0.0001, the increment andthe decrement don't work
    correctly. The number displayed in the JSpinnerdon't change.
    If step = 0.001 all works correctly.
    Why if step = 0,001 it works, and if step = 0.0001it don't works correctly?
    It probly does work correctly, its just you are
    incrementing the 4th decimal place and the spinner
    only shows 3 decimal places.
    So you ARE incrementing, you just wont see it until
    after you increment 10 times and the 3rd decimal
    rounds up.If I increment 10 times the 4th decimal value, the 3rd decimal value don't change.
    Anyone can solve this problem?

  • MaskFormatter with JSpinner and DateEditor?

    Hi,
    I'm trying to apply a MaskFormatter to the DateEditor on a JSpinner. We want the ability to both manually edit the fields by hand AND/OR click the up/down arrows.
    The one gotcha is that when manually entering the values, we want to set a mask on the field so the user doesn't have to type in the ":" when separating the time fields. Right now, when they can delete all the text in the spinner textfield.
    I've dug through the source code of JSpinner and it appears that I should be able to get the editors JFormattedTextField and set the MaskFormatter as part of the AbstractFormatFactory. But all I end up with is a blank JSpinner and I can't type in the textfield.
    Below is my code:
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    import java.util.Calendar;
    import java.util.Date;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JSpinner;
    import javax.swing.SpinnerDateModel;
    import javax.swing.SpinnerModel;
    import javax.swing.text.DefaultFormatterFactory;
    import javax.swing.text.MaskFormatter;
    public class MaskedFieldTest {
         public static void main(String[] args) {
              final JFrame f = new JFrame("Textfield demo");
              f.setDefaultCloseOperation(f.DISPOSE_ON_CLOSE);
              f.addWindowListener(new WindowAdapter() {
                   public void windowClosed(WindowEvent e) {
                        System.exit(0);
              f.setSize(250, 70);
              try {
                   // Create a spinner
                   JSpinner spinner = new JSpinner();
                   // Set up a dummy calendar for the model
                   Calendar calendar = Calendar.getInstance();
                   Date initDate = calendar.getTime();
                   calendar.add(Calendar.YEAR, -100);
                   Date earliestDate = calendar.getTime();
                   calendar.add(Calendar.YEAR, 200);
                   Date latestDate = calendar.getTime();
                   // Set the model
                   SpinnerModel dateModel = new SpinnerDateModel(initDate, earliestDate, latestDate, Calendar.YEAR);
                   spinner.setModel(dateModel);
                   // Create the dateeditor using the time format we want displayed in the spinner
                   JSpinner.DateEditor dateEditor = new JSpinner.DateEditor(spinner, "hh:mm:ss a");
                   // Create a mask for editing so we don't have to manually add the :
                   MaskFormatter fmt = new MaskFormatter("##:##:## UU");
                   // Get the factory from the editor and set the maskformatter for the editing portion
                   DefaultFormatterFactory form = (DefaultFormatterFactory)dateEditor.getTextField().getFormatterFactory();
                   form.setEditFormatter(fmt);
                   // Finally, assign the editor to the spinner
                   spinner.setEditor(dateEditor);
                   // Display the panel
                   JPanel panel = new JPanel();
                   panel.add(spinner);
                   f.getContentPane().add(panel);
                   f.setVisible(true);
              } catch (java.text.ParseException e) {
                   e.printStackTrace();
    }If you run the code, you'll just get an empty JSpinner and you can't do anything in the textfield even though it is enabled.
    I'm running JDK.1.4.2_09 on Windows XP SP2
    Has anyone used a MaskFormatter with a DateEditor on a JSpinner before?
    Thanks,
    - Tim

    see weebib's post here
    http://forum.java.sun.com/thread.jspa?forumID=57&threadID=581804

  • Colors of JSpinner and JComboBox

    hello
    I like to change the fore- and backgroundcolors of JSpinner and JComboBox. how can I do this?
    thanks in advance! nix

    this is much easyer code I will use it.
    but the button is anyway gray and black!?You want to change the color of the arrowButton and arrow color?
    there's probably an easier way, but this worked OK for me
    import javax.swing.*;
    import java.awt.*;
    import javax.swing.plaf.basic.BasicSpinnerUI;
    import javax.swing.plaf.basic.BasicArrowButton;
    class Testing extends JFrame
      public Testing()
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLocation(400,300);
        JSpinner spinner = new JSpinner(new SpinnerNumberModel(50, 0, 100, 5));
        spinner.setUI(new MyUI());
        ((JSpinner.DefaultEditor)spinner.getEditor()).getTextField().setBackground(Color.GREEN);
        JPanel jp = new JPanel();
        jp.add(spinner);
        getContentPane().add(jp);
        pack();
      public static void main(String[] args) {new Testing().setVisible(true);}
    class MyUI extends BasicSpinnerUI
      protected Component createNextButton()
        JButton btn = (JButton)super.createNextButton();
        JButton btnNext = new MyBasicArrowButton(SwingConstants.NORTH);
        btnNext.addActionListener(btn.getActionListeners()[0]);
        btnNext.setBackground(Color.BLACK);
        return btnNext;
      protected Component createPreviousButton()
        JButton btn = (JButton)super.createPreviousButton();
        JButton btnPrevious = new MyBasicArrowButton(SwingConstants.SOUTH);
        btnPrevious.addActionListener(btn.getActionListeners()[0]);
        btnPrevious.setBackground(Color.BLACK);
        return btnPrevious;
    class MyBasicArrowButton extends BasicArrowButton
      public MyBasicArrowButton(int direction)
        super(direction);
      public MyBasicArrowButton(int direction,Color background,Color shadow,Color darkShadow,Color highlight)
        super(direction,background,shadow,darkShadow,highlight);
      public void paintTriangle(Graphics g,int x,int y,int size,int direction,boolean isEnabled)
        Color oldColor = g.getColor();//Note 1: all if(!isEnabled) code removed, for brevity
        int mid, i, j;                //Note 2: all EAST / WEST code removed, for brevity
        j = 0;
        size = Math.max(size, 2);
        mid = (size / 2) - 1;
        g.translate(x, y);
        g.setColor(Color.GREEN);//<-------------------set arrow colors here
        switch(direction)
          case NORTH:
            for(i = 0; i < size; i++)
              g.drawLine(mid-i, i, mid+i, i);
            break;
          case SOUTH:
            j = 0;
            for(i = size-1; i >= 0; i--)
              g.drawLine(mid-i, j, mid+i, j);
              j++;
            break;
        g.translate(-x, -y);
        g.setColor(oldColor);
    }

  • JSpinner and finding which item was selected...

    With a JComboBox, I can load up my list with an array and use "getSelectedIndex()" to grab the index number of the item the user selects.
    With a JSpinner (SpinnerListModel), I can load up my list with an array but there doesn't appear to be any way to retrieve an index number. Am I missing something? The best thing I can come up with is to use "getValue()" and search my array for that value and then I'd have the correct index. Seems the long way around to me.
    I have other elements in the array I need to get to based on the users selection.
    -Duane

    If you're creating your own object class to use in the list of possible values, you could make the array index be an instance variable in this class. I just had to do something like this recently. As in:
    class MySpinnerValue
      public int index;
      public String name;
      //  ... other useful stuff
      public String toString()
        return name;
    // ... and somewhere we create the list, like ...
    MySpinnerValue[] list=new MySpinnerValue[10];
    for (int x=0;x<10;++x)
      MySpinnerValue v=new MySpinnerValue();
      v.index=x;
      list[x]=v;
    }Then when you retrieve a value you just check index to see where it is in the array.
    Clumsy, yes, because it relies on setting an index value equal to the array subscript, which is redundant data in a sense. (Ah, there were advantages to pointers in C, you could just say "pEntry-entry[0]" to get the index ...)

  • JSPinner and floating point quirk

    Please test these spinners only with their down arrow buttons to reach minimum value of each. When the number of fraction columns are 5,10 and 12, spinner stops at one step before the real minimum. They don't go to the real minimum. Why could this happen?
    import javax.swing.*;
    import java.text.*;
    public class SpinnerQuirk{
      public static void main(String[] args){
        Box panel = new Box(BoxLayout.X_AXIS);
        double fraction = 0.01;
        double base = 1.0;
        String fmt = "#0.00";
        for (int i = 2; i < 14; ++i){
          DecimalFormat df = new DecimalFormat(fmt);
          Box box = new Box(BoxLayout.Y_AXIS);
          JSpinner spinner = new JSpinner();
          SpinnerNumberModel spinnerModel
            = new SpinnerNumberModel(base + fraction,
                                     base + fraction - fraction * 101,
                                     base + fraction + fraction * 99,
                                     fraction);
          spinner.setModel(spinnerModel);
          spinner.setEditor(new JSpinner.NumberEditor(spinner, fmt));
          JLabel label = new JLabel("min = "
              + df.format((base + fraction - fraction * 101)));
          box.add(spinner);
          box.add(label);
          panel.add(box);
          fraction = fraction / 10.0;
          fmt += "0";
        JOptionPane.showMessageDialog(null, panel);
        System.exit(0);
    }

    Thanks. I think I have found the root cause of the problem. That is, there's no effective communications between java.text formatting and javax.swing.text one(*). A bad example of a bureaucratic sectionalism at Sun?
    (*: Because DecimalFormat does the right job given the same format string and same value.)
    Japanese: tate wari
    Englisn: divided vertically
    Edited by: hiwa on Oct 5, 2007 11:18 AM

  • JSpinner and invalid values

    Hi guys !
    I have a JSpinner using the SpinnerNumberModel. I want to do the following:
    1- When the user enters an integer lower then the min value, it would automatically be set to the min value.
    2- When the user enters an integer higher then the max value, it would be set to the max value.
    3- When the user enters other characters (not integers), it would be set to the previous value (before the user typed).
    The default behavior of the SpinnerNumberModel is to just let it lay there when an invalid value is entered (until the focus leaves the spinner).
    I need to catch these invalid values (integer outside the range or non-integer characters) in other to respond correctly and change the value in the text field. Since these invalid values do not trigger the ChangeEvent event (thats the idea of the model I guess), I have tried catching them with an ActionEvent on the JFormattedTextField in the spinner but with no result.
    Or do I need to subclass the SpinnerNumberModel class ? And then how ?
    Or does it have to do with the JformattedTextField class ?
    Any idea someone ?

    I just realized if the user types in something that is not a number... it won't get committed... the spinner just reverts back to the last valid number. This is a good configuration (in case anyone ever reads this in the future):
        NumberEditor editor = (NumberEditor) spinner.getEditor();
        JFormattedTextField editorField = editor.getTextField();
        NumberFormatter formatter = (NumberFormatter) editorField.getFormatter();
        formatter.setOverwriteMode(true);
        formatter.setAllowsInvalid(true);
        formatter.setCommitsOnValidEdit(true);

  • JSpinner and addKeyListener (again)

    Hello
    I have already read in the forum (and in other places) that in order to get the key event, it is enough to grab the Model, apply getTextField() and then get the JFormattedTextField.
    The problem that is that, this works only if the focus is on the JTextField.
    If the focus is on the up/down arrows, I can't get the key event.
    What I am trying to do is this: if the user presses a button (e.g. the ALT button) to make the spinner go faster, when the user clicks on the arrow buttons.
    I have tried to grab the jey event in various positions, but with no luck.
    Any ideas / help?

    There is no direct API method to get at the buttons unless you start playing with the UI, but JSpinner is a container for the text field and the two buttons, so as a hack you should be able to use the Container.getComponent(...) method to get the button and add the listener to it.

  • JSpinner and BigDecimal , what am i doing wrong?

    hi,
    i'm trying to use a JSpinner to let the user input currencies.
    all my currencies are represented by BigDecimals.
    SpinnerNumberModel provides the following methodn which let's me think i can use BigDecimals in the spinner component:
    setStepSize(Number stepSize)
    The following code fails though :
    JSpinner spinner = new JSpinner();
    SpinnerNumberModel model = new SpinnerNumberModel();
    model.setStepSize(new BigDecimal("0.01");
    model.setValue(new BigDecimal("0.00");
    spinner.setModel(model);the spinner arrows don't work , and any value i enter is rejected
    what could be the problem ?

    From the SpinnerNumberModel API documentation:
    Internally, there's only support for values whose type is one of the primitive Number types: Double, Float, Long, Integer, Short, or Byte.

  • JSpinner and ChangeListener... HELP!

    In order to seperate components and not have everything mashed together into one giant program (I'm trying to use the MVC paradigm). I'm trying to seperate the controller from the view so that the values will be passed to the model (eventually)
    class StatSpinner extends JPanel           // this will be part of the view
    {   JTextField statistic;
        SpinnerNumberModel stat;
        JSpinner Stat;
        JLabel StatLabel;
        int STAT;
        StatSpinnerListener SSL;
        ChangeEvent event;
        public StatSpinner (String statis, int x)           // called from other classes to create individual spinners
        {   stat = new SpinnerNumberModel(10,0,x,1);
            Stat = new JSpinner(stat);
            statistic = new JTextField(4);
            statistic.setEditable(false);
            StatLabel = new JLabel(statis);
            JSpinner Dx = new JSpinner(stat);
            add(StatLabel);
            add(Stat);
            add(statistic);
            SSL = new StatSpinnerListener();
            stat.addChangeListener(SSL);
            //stat.addActionListener(this);
        public int getSTAT()                
        {   return (STAT=stat.getNumber().intValue());
        public void ChangeStat (int x)      // partial legacy that didn't work from ActionListener
        {   SSL.OutStat(this);
            stText(x);
            //statistic.setText(""+(x-10) * 10);
        public void stText (int x)
        {   statistic.setText(""+x);
      //  public void actionPerformed(java.awt.event.ActionEvent actionEvent)
      //  {  // setChanged();
      //      int x = getSTAT();
      //      ChangeStat(x);              
       // }    //////////////////   ignore the Action listner portions
    class StatSpinnerListener implements ChangeListener
    {   public StatSpinnerListener()
        public int OutStat(StatSpinner x)
        {   int y = x.getSTAT();
            return y;
        public void stateChanged (ChangeEvent e)
        {   SpinnerNumberModel source = (SpinnerNumberModel)e.getSource();
            int x =source.getNumber().intValue();
    //       StatSpinner srce = (StatSpinner)e.getSource();  // need to do something
    //       srce.stText(x);         // like this to change the Textfield      // thew an exception
    }

    What have you got so far - and what doesn't work?
    Adding a ChangeListener to a JSpinner works for me: When the field is modified (hit return to commit the change), the added ChangeListener is notified of the change.

  • JSpinner and changeListener

    Hi. How can I detect in a JSpinner a change made by the user editing the numeric value in the JFormattedTextField of the JSpinner itself? It seems to me that the method StateChanged does not detect it..
    Thanks very much

    What have you got so far - and what doesn't work?
    Adding a ChangeListener to a JSpinner works for me: When the field is modified (hit return to commit the change), the added ChangeListener is notified of the change.

  • JSpinner and small values

    This code don't works properly
    spinner.setModel(new SpinnerNumberModel(3.0,null,null,0.1));This is the JSpinner but the number displayed in the included JTextField don't represent the correct value.
    For example, in some case the number displayed is 3.3 but the number that returns spinner.getValue() is 3.30000000003.
    I want that spinner.getValue returns 3.3
    There is a solution to this problem?

    Ayrton_4 wrote:
    This code don't works properly
    spinner.setModel(new SpinnerNumberModel(3.0,null,null,0.1));This is the JSpinner but the number displayed in the included JTextField don't represent the correct value.
    For example, in some case the number displayed is 3.3 but the number that returns spinner.getValue() is 3.30000000003.
    I want that spinner.getValue returns 3.3
    There is a solution to this problem?Yes, you need desperately to learn about how all computers treat floating point numbers and work your programs accordingly. 3.30000000003 is a reasonable representation of 3.3 when working with floating point numbers. The key here is how to display this number correctly, and for this I often use the String.format( ) method which is similar to c's printf.
    Please read in the tutorial section the parts about floating point math and you will understand.

  • Strange Problem about KeyListener, and FocusListener

    Hi,Please help me with this problem.
    I create a JTable and setCellEditor by using my customerized TextField
    The problem is: when I edit JTable Cell, the value can not be changed and I can not get Key Event and Focus Event.
    here is my source:
    //create normal JTable instance,and then initlize it
    private void initTable(Vector folders)
    TableColumn tempcol = getColumnModel().getColumn(0);
    tempcol.setCellEditor(new DefaultCellEditor(new MyTextField()));
    for(int i=0;i<folders.size();i++)
    mddDataSource ds=(mddDataSource) folders.get(i);
    String name = ds.getDataSourceName();
    layers.add(name);
    for(int i=0;i<layers.size();i++){
    Vector temp = new Vector();
    temp.add(layers.get(i));
    temp.add(layers.get(i));
    dtm.addRow(temp);
    // My Text Field cell
    class MyTextField extends JTextField implements FocusListener, KeyListener
    MyTextField()
    setOpaque (false);
    addKeyListener(this);
    addFocusListener(this);
    MyTextField(String text)
    setOpaque (false);
    addKeyListener(this);
    addFocusListener(this);
    public void focusGained(FocusEvent e) {
    System.out.println("get Focus");
    public void focusLost(FocusEvent e) {
    instance.setValue(getText());
    public void keyTyped(KeyEvent e){
    instance.setValue(getText());
    public void keyPressed(KeyEvent e){
    System.out.println("get Key ");
    public void keyReleased(KeyEvent e){
    instance.setValue(getText());
    If there are some good sample, please tell me the link or give me some suggestion.
    Thanks in advanced

    Thanks for your help.
    The problem still exist. It does not commit the value that I input.
    Maybe I should say it clearly.
    I have create JPanel include three JPanel:
    Left Panel and right upper-panel and right borrom panel.
    The JTable instance is on right-upper Panel.
    If I edit one of row at JTable and then click JTable other row,the value can be commited. if I edit one of row and then push one Button on
    the right-bottom button to see the editting cell value.It does not commit value.
    when I use debug style, and set breakpoint the
    foucsGained or KeyTyped,
    It never stopes at there,So I assume that the Editing cell never get focus.
    Is there a bug at Java if we move focus on other Panel, that JTable can not detect the Focus lost or focus gained event?
    Thanks

Maybe you are looking for