Yuriah
Yuriah

Reputation: 27

JScrollPane holding a JPanel is buggy

Recently I started making a Map Editor for my game and I came across a couple of issues that I've kind of have fixed. My current problem right now is that I have a JFrame (main interface). Within that JFrame I have a JScrollPane which holds my Client(a JPanel). Since I can't post picture I will post a link of the image. Image of GUI: https://i.sstatic.net/Cd1Pu.png

This is where I add my client(JPanel) to the JScrollPane.

//======== mainScrollPane ========
        {
            client.setPreferredSize(client.getSize());
            mainScrollPane.setPreferredSize(client.getSize());
            mainScrollPane.setViewportView(client);
            mainScrollPane.add(client);

This is my Client.java|The MapEditor class is a little large to post here but feel free to ask for snippets or anymore information.

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JPanel;

public class Client extends JPanel implements Runnable, MouseListener, MouseMotionListener {

    private static final long serialVersionUID = 1L;
    private Thread animationThread;
    protected Map map;
    private Tile tile;
    public int mX, mY;

    public Client() {
        init();
        setVisible(true);
        setFocusable(true);
        animationThread = new Thread(this);
        animationThread.start();
    }

    public void init() {
        addMouseListener(this);
        addMouseMotionListener(this);
        ImageHandler.loadImages();
        map = new Map();
        setSize(1000, 500);
    }

    public void run() {
        while (animationThread != null) {
            repaint();
            try {
                Thread.sleep(4);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public void paint(Graphics g) {
        Graphics2D gg = (Graphics2D) g;
        map.drawCurrentMap(gg);

    }

    @Override
    public void mouseClicked(final MouseEvent e) {
        //final Point p = e.getPoint();
        //final int x = p.x / 25;
        //final int y = p.y / 25;
        //map.getTileAt(x, y).setGraphicId(MapEditor.id);
        //map.getTileAt(x, y).setBlocked(true);
        map.getTiles().set(map.getTileIndex(mX, mY), new Tile(mX, mY, true, MapEditor.id));
        System.out.println(map.getTiles().get(map.getTileIndex(mX, mY)).toString());

    }

    @Override
    public void mouseEntered(MouseEvent arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void mouseExited(MouseEvent arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void mousePressed(MouseEvent e) {;

    }

    @Override
    public void mouseReleased(MouseEvent arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void mouseDragged(MouseEvent e) {

    }

    @Override
    public void mouseMoved(MouseEvent e) {
        mX = e.getX()/25;
        mY = e.getY()/25;
    }
}

Upvotes: 0

Views: 91

Answers (1)

MadProgrammer
MadProgrammer

Reputation: 347314

This has nothing to do with scroll pane, but with how you've done your custom painting...

Basically, this...

public void paint(Graphics g) {
    Graphics2D gg = (Graphics2D) g;
    map.drawCurrentMap(gg);
}

Is breaking the paint chain requirements. A Graphics context is a shared resource, meaning that everything painting within a given paint cycle shares the same Graphics contents.

Painting is also a complex chain of methods which is, as you've discovered, really easy to break.

Instead, you should override paintComponent and perform your custom painting there, making sure you call super.paintComponent first

Take a look at Performing Custom Painting and Painting in AWT and Swing for more details

Upvotes: 3

Related Questions