2

I made my own BottomBar with a simple gradient extending JComponent and adjusting the paintComponent() method.

Then I add it to the SOUTH of my JFrame which uses BorderLayout.

Everything looks correct at the beginning. When I resize the frame the BottomBar gets repainted and set to the new position correctly. The think is, it happens a few milliseconds to late, so that one can see the JFrame 's background for a second.

The funny thing is, that when I set the execution environment to Java-SE 1.6 it works... (instead of 1.7) Also, Im running it on a mac, if that makes a difference.

Screenshot comparing window when resized and when not


Code - JButton Example

import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JButton;
import javax.swing.JFrame;


public class Main {

    public static void main(String args[]){
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame frame = new JFrame("Resize Example");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new JButton(), BorderLayout.SOUTH);
                frame.pack();
                frame.setLocationByPlatform(true);
                frame.setVisible(true);
            }
        });
    }
}

Code - BottomBar Example

Main:

public class Main {
    public static void main(String args[]){
        Frame window = new Frame();
        window.setSize(500, 400);
        window.setVisible(true);
    }
}

Frame:

import java.awt.BorderLayout;

import javax.swing.JFrame;


public class Frame extends JFrame{
    private static final long serialVersionUID = 1L;

    public Frame() {
        setLayout( new BorderLayout() );
        getContentPane().add( BorderLayout.SOUTH, new BottomBar() );
    }
}

BottomBar

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;

import javax.swing.JComponent;

public class BottomBar extends JComponent {
    private static final long serialVersionUID = 1L;

    public BottomBar() {
        setSize(200, 30);
        setPreferredSize( new Dimension(200, 30) );
    }

    protected void paintComponent(Graphics g) {
        Graphics2D g2 = (Graphics2D)g;

        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);

        GradientPaint gradient = new GradientPaint(0, 0, new Color(185, 185, 185), 0, getHeight() , new Color(151, 151, 151) );
        g2.setPaint(gradient);
        g2.fillRect(0, 0, getWidth(), getHeight());

        g2.setColor( new Color(64, 64, 64) );
        g2.drawLine(0, 0, getWidth(), 0);
        g2.setColor( new Color(215, 215, 215) );
        g2.drawLine(0, 1, getWidth(), 1);
    }
}
Phil
  • 578
  • 2
  • 5
  • 15
  • Would care to post your code so that we can actually tell if you are doing something wrong? Otherwise, this question is just asking us to be wild-guessing gurus... – Guillaume Polet Nov 28 '12 at 14:42
  • 1
    +1 for [sscce](http://sscce.org/), although you can combine the classes, as shown [below](http://stackoverflow.com/a/13610367/230513). – trashgod Nov 28 '12 at 17:15
  • Yes I can reproduce it. I use a Mac and the problem does not appear in Java 1.6. –  Jan 29 '13 at 00:36
  • I'm able to reproduce it too (Tried JDK 5,6,7,8). If i slowly resize empty JFrame it doesn't repaint at all until i stop resizing. – FINDarkside Mar 19 '15 at 13:26

1 Answers1

3

I am unable to reproduce the effect you describe on 1.6; you might try the sscce below on 1.7. Note, several suggestions for your example:

  • Avoid setXxxxSize(), as discussed here. If you just want a 30 pixel high bar in SOUTH, override getPreferredSize() as shown below. If you later decide to add components, you'll need to add a layout manager.

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(0, 30);
    }
    
  • Use pack() to let the Window adopt the preferred sizes of the enclosed components. I've added an arbitrary size JPanel to the CENTER; resize the frame to see how the bar grows horizontally in SOUTH.

  • Swing GUI objects should be constructed and manipulated only on the event dispatch thread.

BottomBar

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;

/** @see https://stackoverflow.com/a/13610367/230513 */
public class Main {

    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame frame = new JFrame("BottomBar");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new JPanel() {

                    @Override
                    public Dimension getPreferredSize() {
                        return new Dimension(320, 240);
                    }
                }, BorderLayout.CENTER);
                frame.add(new BottomBar(), BorderLayout.SOUTH);
                frame.pack();
                frame.setLocationByPlatform(true);
                frame.setVisible(true);
            }
        });
    }

    private static class BottomBar extends JComponent {

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(0, 30);
        }

        @Override
        protected void paintComponent(Graphics g) {
            Graphics2D g2 = (Graphics2D) g;
            g2.setRenderingHint(
                RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
            GradientPaint gradient = new GradientPaint(
                0, 0, new Color(185, 185, 185),
                0, getHeight(), new Color(151, 151, 151));
            g2.setPaint(gradient);
            g2.fillRect(0, 0, getWidth(), getHeight());
            g2.setColor(new Color(64, 64, 64));
            g2.drawLine(0, 0, getWidth(), 0);
            g2.setColor(new Color(215, 215, 215));
            g2.drawLine(0, 1, getWidth(), 1);
        }
    }
}
Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • Okay, thanks for the help and the information about the event dispatch. Unfortunately it didnt solve the problem. – Phil Nov 29 '12 at 01:11
  • It has nothing to to with the bottom bar I realized. If I replace new BottomBar just with JButton the problem stays - a little bit of the button is cut off while resizing the frame upwards. Also, the problem occurs with 1.7. Not with 1.6. Would it be helpful if I post a screenshot? – Phil Nov 29 '12 at 01:21
  • It can't hurt. Each update to your question bumps it in the "active" queue. Also show the code you're testing. One goal is to see if anyone else running 1.7 can reproduce the problem. – trashgod Nov 29 '12 at 02:30