Weird shadowing while changing JLabel text

143 views Asked by At

I am working on a little menu program with clickable buttons and an image that changes based on button clicks. If I click a button I get a shadow of the button at the bottom where I change the JLabel text. I cannot figure it out for the life of me. Any advice would be greatly appreciated. Visuals below...thanks

public class SampleGUI
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                createAndShowGUI();
            }
        });
    }

    private static void createAndShowGUI()
    {
        System.out.println("Created GUI on EDT? " +
                            SwingUtilities.isEventDispatchThread());
        JFrame f = new JFrame("Robert's VICI Prototype");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(new MyPanel());
        f.pack();
        f.setVisible(true);
    }
}

class MyPanel extends JPanel
{
    // Fields
    Image imageDisplayed;
    JLabel status;

    // Methods
    public MyPanel()
    {
        setBorder(BorderFactory.createLineBorder(Color.BLACK));
        setLayout(null);

        JLabel title = new JLabel("CS380 TEAM 5 VICI Prototype");
        title.setFont(new Font("Tahoma", Font.BOLD, 20));
        title.setBounds(425, 10, 400, 40);
        add(title);

        status = new JLabel("Please click an option above.");
        status.setFont(new Font("Tahoma", Font.BOLD, 14));
        status.setBounds(425, 740, 400, 40);
        add(status);

        JButton choice1 = new JButton("Search Class");
        choice1.setBounds(50, 50, 150, 40);
        add(choice1);

        JButton choice2 = new JButton("Add Class");
        choice2.setBounds(225, 50, 150, 40);
        add(choice2);

        JButton choice3 = new JButton("Drop Class");
        choice3.setBounds(400, 50, 150, 40);
        add(choice3);

        JButton choice4 = new JButton("Verify Reg Hold");
        choice4.setBounds(575, 50, 150, 40);
        add(choice4);

        JButton choice5 = new JButton("Verify Reg Date");
        choice5.setBounds(750, 50, 150, 40);
        add(choice5);

        JButton choice6 = new JButton("Schedule Advisor");
        choice6.setBounds(925, 50, 150, 40);
        add(choice6);
        choice6.addActionListener(
            new ActionListener()
            {
                @Override
                public void actionPerformed(ActionEvent e)
                {
                    System.out.println("Schedule Advisor button pressed.");
                    status.setText("Choose a date.");
                    imageDisplayed = new ImageIcon("C:\\Temp\\sa01.jpg").getImage();
                }
            });

        JButton exit = new JButton("EXIT");
        exit.setBounds(940, 750, 150, 40);
        add(exit);
        exit.addActionListener(
            new ActionListener()
            {
                @Override
                public void actionPerformed(ActionEvent e)
                {
                    System.exit(0);
                }
            });

        imageDisplayed = new ImageIcon("C:\\Temp\\main.jpg").getImage();  

    }

    @Override
    public Dimension getPreferredSize()
    {
        return new Dimension(1100, 800);
    }

    @Override
    public void paintComponent(Graphics g)
    {
        g.drawImage(imageDisplayed, 100, 120, 900, 600, this);
    }


}

Visual Aid 1

Visual Aid 2

1

There are 1 answers

1
MadProgrammer On BEST ANSWER

You've broken the paint chain...

@Override
public void paintComponent(Graphics g)
{
    g.drawImage(imageDisplayed, 100, 120, 900, 600, this);
}

The first thing you should be calling is super.paintComponent(g)

@Override
public void paintComponent(Graphics g)
{
    super.paintComponent(g);
    g.drawImage(imageDisplayed, 100, 120, 900, 600, this);
}

The Graphics context is shared resource, meaning that the Graphics context you get has also been used to paint the other components that have also been painted. One of the jobs of paintComponent is to clear the Graphics context ready for the component to be painted (fill the background)

See Painting in AWT and Swing and Performing Custom Painting for more details

You should, also, avoid using null layouts, pixel perfect layouts are an illusion within modern ui design. There are too many factors which affect the individual size of components, none of which you can control. Swing was designed to work with layout managers at the core, discarding these will lead to no end of issues and problems that you will spend more and more time trying to rectify. See Why is it frowned upon to use a null layout in SWING? for more details...

Before you go all defensive over getting your screen laid out just nicely, you shouldn't be doing it this way. You controls should be laid out on separate containers (using appropriate layout managers) and you "drawing surface" should be it's own component. See Laying Out Components Within a Container for more details...

If you're still not convicned, take a look at Why setting setPreferredSize() on JFrame is bad? and java expandable JDialog for examples of differences between Mac and Windows