knorberg
knorberg

Reputation: 462

Why is my JPanel messing with other components on my JFrame?

So I have a JFrame which contains a JPanel that holds a JList component.

Then I have another JPanel for my paintComponent() which also returns a dimension.

But when I set the size for the dimension, it tries to relocate my other JPanel.

Here is my code for the paintComponent():

class drawOnPanel extends JPanel {
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setColor(Color.BLUE);
    }
    @Override
  public Dimension getPreferredSize(){
    return new Dimension(250, 250);
  }
}

Then I have my JFrame which calls the drawOnPanel class:

public static void mainFrame() {
    JFrame f = new MTGSAMPServerReference();
    f.setTitle("MTG SAMP Server Reference Guide");
    f.pack();
    f.setVisible(true);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.add(new drawOnPanel());
    f.setSize(330, 300);
    f.setLocationRelativeTo(null);
}

And then I have my JList which is on my JPanel:

public void MainMenu() {
    JPanel controls = new JPanel(new BorderLayout(5,5));
    final CardLayout cl = new CardLayout();
    final JPanel panel = new JPanel(cl);
    controls.add(panel);
    this.getContentPane().setLayout(new FlowLayout(FlowLayout.LEADING));
        list = new JList<Object>(mainMenu);
        list.setVisibleRowCount(7);
        select = new JButton("Select");
        exit = new JButton("Exit");
        select.addActionListener(this);
        exit.addActionListener(this);
        controls.add(new JScrollPane(list));
        JPanel basePanel = new JPanel(new GridLayout(0, 1));
        basePanel.add(select);
        basePanel.add(exit);
        controls.add(basePanel, BorderLayout.PAGE_END);
        add(controls);
        refreshFrame();
}

When I try to draw on my paintComponent() JPanel, it draws, but the coordinates that I indicate are not correctly drawn.

Does anyone know why this is happening?

Thanks in advance!

EDIT: Here are some screenshots of my program.

This one is what my program looks like when I don't include drawOnPanel: No drawOnPanel

And this one is what my program looks like when I include drawOnPanel: With drawOnPanel

I just want it to draw on the right side of the JList, without moving the JList. As you can see, it adjusts the other JPanel.

Any and all help is appreciated!

EDIT: Here is my SSCCE.

EDIT: Here is my SSCCE code:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public final class SSCCE1 extends JFrame implements ActionListener {
    private static final long serialVersionUID = 1L;
    JList list;
    JButton select;
    JButton exit;
    Object[]mainMenu = {"Value 1", "Value 2", "Value 3", "Value 4"};

    public SSCCE1() {
        MainMenu();
    }

    public void MainMenu() {
        JPanel controls = new JPanel(new BorderLayout(5,5));
        final CardLayout cl = new CardLayout();
        final JPanel panel = new JPanel(cl);
        controls.add(panel);
        this.getContentPane().setLayout(new FlowLayout(FlowLayout.LEADING));
            list = new JList<Object>(mainMenu);
            list.setVisibleRowCount(7);
            select = new JButton("Select");
            exit = new JButton("Exit");
            controls.add(new JScrollPane(list));
            JPanel basePanel = new JPanel(new GridLayout(0, 1));
            basePanel.add(select);
            basePanel.add(exit);
            controls.add(basePanel, BorderLayout.PAGE_END);
            add(controls);
            revalidate();
            repaint();
            SSCCE1.this.repaint();
    }

    public void createAndShowGUI() {
        mainFrame();
        SSCCE1.this.repaint();
    }

    public static void mainFrame() {
        JFrame f = new SSCCE1();
        f.setTitle("My SSCCE");
        f.pack();
        f.setVisible(true);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(new drawOnPanel()); // When this is uncommented, it messes with the other JPanel, but when commented, it works fine, but does not allow drawing on the other JFrame.
        f.setExtendedState(JFrame.MAXIMIZED_BOTH);
        f.setLocationRelativeTo(null);
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
            SSCCE1 gui = new SSCCE1();
            gui.createAndShowGUI();
            }
        });
    }
    @Override
    public void actionPerformed(ActionEvent ae) {
    }
}

class drawOnPanel extends JPanel {
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setColor(Color.BLUE);
    }
  @Override
  public Dimension getPreferredSize(){
    return new Dimension(250, 250);
  }
}

Upvotes: 3

Views: 482

Answers (1)

trashgod
trashgod

Reputation: 205775

Make setVisible() last, after a adding, packing and locating. Complete examples are seen here and here.

f.add(…);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);

Addendum: Here's a variation on your example, without the invisible panel. Absent a compelling reason to extend JFrame, just create one and add your components.

image

import java.awt.*;
import javax.swing.*;

/** @see https://stackoverflow.com/a/18038765/230513 */
public class SSCCE2 {

    private JList list;
    private JButton select;
    private JButton exit;
    private Object[] mainMenu = {"Value 1", "Value 2", "Value 3", "Value 4"};

    public JPanel mainMenu() {
        JPanel controls = new JPanel(new BorderLayout(5, 5));
        list = new JList(mainMenu);
        list.setVisibleRowCount(7);
        select = new JButton("Select");
        exit = new JButton("Exit");
        controls.add(new JScrollPane(list));
        JPanel basePanel = new JPanel(new GridLayout(0, 1));
        basePanel.add(select);
        basePanel.add(exit);
        controls.add(basePanel, BorderLayout.PAGE_END);
        return controls;
    }

    public void createAndShowGUI() {
        JFrame f = new JFrame("My SSCCE");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(new DrawOnPanel());
        f.add(mainMenu(), BorderLayout.WEST);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                SSCCE2 gui = new SSCCE2();
                gui.createAndShowGUI();
            }
        });
    }

    private static class DrawOnPanel extends JPanel {

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.BLUE);
            g.fillRect(0, 0, getWidth(), getHeight());
        }

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

Upvotes: 3

Related Questions