0

Quick picture to show what is happening

The JSpinner is appearing twice as seen in the picture above. The first appearance at point (0,0) that should not be there is not selectable, editable or useable with no spinner buttons.

The odd thing here is that every other component has no problem. Only the jspinner. I am using Java 7 and developing in Netbeans (not gui developer kit). Is this a bug with java 7? If not what can I try to make my JSpinner paint only 1 time in the area i specified?

Code to illustrate the problem:

I am adding it to a subclass of JPanel as seen here:

public class MyCustomGUI extends JPanel {
private JSpinner entrySpinner;
public MyCustomGUI () {
 super(null);
 this.setDoubleBuffered(true);

 entrySpinner = new JSpinner(new SpinnerNumberModel(0, 0, Integer.MAX_VALUE, 1));
 add(entrySpinner);
....

I have a method to give it a location:

public void resize() {
     entrySpinner.setBounds((int) (this.getWidth() * .2), (int) (this.getHeight() * 0.38), (int) (this.getWidth() * 0.3), (int) (this.getHeight() * 0.1));
}

And I override the paint method here:

public void paint(Graphics g) {
    super.paint(g);
    Graphics2D g2d = (Graphics2D) g;
    g2d.setRenderingHint(
            RenderingHints.KEY_TEXT_ANTIALIASING,
            RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
    .. draw shapes..
    super.paintComponents(g);
    super.validate();
    Toolkit.getDefaultToolkit.sync();
    g.dispose();
}
Quinma
  • 1,436
  • 2
  • 17
  • 39

1 Answers1

2
  1. You're calling paintComponent twice, once when you call super.paint and once manually
  2. You're calling validate from within a paint method which is only going to result in the component begin repainted, over and over and over again...say good bye to your CPU...
  3. You're disposing of the graphics context you did not create, this is like closing a file your did not open. If you didn't create it, you shouldn't close it.
  4. I'm not convinced that you have a need to call Toolkit.getDefaultToolkit.sync();, but I'm reasonably confident that you shouldn't be doing it from within the paint method
  5. Unless you have a very good reason to do it otherwise, you should not be overriding the paint method. The recommended method to perform custom painting in is the paintComponent method (which is called by paint)

You might like to have a read through

Update with example

Fixed it for me...

enter image description hereenter image description here

Left is your code, right is mine

public class TestPaintSpinner {

    public static void main(String[] args) {
        new TestPaintSpinner();
    }

    public TestPaintSpinner() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setDoubleBuffered(true);
            setLayout(new GridBagLayout());
            add(new JSpinner(new SpinnerNumberModel(0, 0, Integer.MAX_VALUE, 1)));

            JPanel panel = new JPanel();
            panel.add(new JLabel("Subpanel"));
            add(panel);
        }

//        public void paint(Graphics g) {
//            super.paint(g);
//
//            Graphics2D g2d = (Graphics2D) g;
//            Point2D sPoint = new Point2D.Float(0, 0);
//            Point2D ePoint = new Point2D.Float(this.getWidth(), this.getHeight());
//
//            g2d.setRenderingHint(
//                    RenderingHints.KEY_TEXT_ANTIALIASING,
//                    RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
//            super.paintComponents(g);
//            super.validate();
//            Toolkit.getDefaultToolkit().sync();
//            g.dispose();
//        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g); //To change body of generated methods, choose Tools | Templates.

            Graphics2D g2d = (Graphics2D) g;
            Point2D sPoint = new Point2D.Float(0, 0);
            Point2D ePoint = new Point2D.Float(this.getWidth(), this.getHeight());

            // Note, this will effect every component painted after this one!!
            g2d.setRenderingHint(
                    RenderingHints.KEY_TEXT_ANTIALIASING,
                    RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        }
    }
}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • Very interesting, thank you. I have implemented 1-4. It didnt solve the problem but it did save me some significant CPU cycles. I am now reading up on the links you gave me. Again, I appreciate the input. – Quinma Nov 21 '12 at 00:26
  • Updated with example. I have no issue with the fixes – MadProgrammer Nov 21 '12 at 00:36
  • Your answer is correct, I am just not using the correct methods of painting my components. Thank you again. – Quinma Nov 21 '12 at 00:46
  • Isn't painting fun :D (ps- I just like clarification in case I've screwed up, not badgering you ;)) – MadProgrammer Nov 21 '12 at 00:52
  • Found it! Thanks to your insight and those tutorials i found that calling super.paintComponents(g); should only be called at the first line of the paintComponents method. Calling it twice like that causes some wierd graphical problems. I actually enjoy painting now that I am getting the hang of how it was designed to be used with java. – Quinma Nov 21 '12 at 17:23