Im trying to create a small client where I can paint coordinates onto a map. I want to start by loading a map image on to a JPanel and then add that panel to a frame. The image is very large hence you need to be able to scroll to see all of it.
But for some reason my scroll bar wont show up. I tried most guides but it wont work.
here is my panel class:
public class MapPanel extends JPanel implements Pointable {
private static final long serialVersionUID = 1L;
private List<Shape> shapes = new LinkedList<>();
public MapPanel() {
Commander.getInstance().addShapeContainer(this);
shapeContainerState = NoState.getInstance();
MouseHandler mouseHandler = new MouseHandler(this);
KeyListener keyListener = new KeyListener();
this.addMouseListener(mouseHandler);
this.addMouseMotionListener(mouseHandler);
this.addKeyListener(keyListener);
this.setBackground(Color.white);
this.setFocusable(true);
this.requestFocusInWindow();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
BufferedImage image;
try {
image = ImageIO.read(new File("earthmap1.jpg"));
} catch (IOException e) {
throw new RuntimeException(e);
}
g.drawImage(image, 0, 0, null);
}
And here is my JFrame class:
public class MapFrame extends JFrame {
public MapFrame() {
buildTheUI();
setUpEventHandling();
mapPanel = new MapPanel();
JScrollPane scrollPane = new JScrollPane(mapPanel);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(900, 800);
this.add(scrollPane);
this.setVisible(true);
}
}
The image is displayed fine and if i enlarge the window u can see more of it (as all of it is not displayed) but there are no scroll bars so i can see the rest of the image by scrolling.
CodePudding user response:
Your problem is due to the JPanel's preferred size -- it needs to match the size of the image. I recommend overriding the public Dimension getPreferredSize()
method and return a dimension that matches the size of the image.
Side issue: Do not read in an image in a painting method such as paintComponent. These methods help determine the perceived responsiveness of your program and need to be as fast as possible. What is more, there is no reason to re-read the image in each time the JPanel gets a repaint, and instead read the image in once, say in the class's constructor.
e.g.,
public class MapPanel extends JPanel implements Pointable {
private static final long serialVersionUID = 1L;
private List<Shape> shapes = new LinkedList<>();
private BufferedImage image = null;
public MapPanel() throws IOException {
Commander.getInstance().addShapeContainer(this);
shapeContainerState = NoState.getInstance();
MouseHandler mouseHandler = new MouseHandler(this);
KeyListener keyListener = new KeyListener();
this.addMouseListener(mouseHandler);
this.addMouseMotionListener(mouseHandler);
this.addKeyListener(keyListener);
this.setBackground(Color.white);
this.setFocusable(true);
this.requestFocusInWindow();
image = ImageIO.read(new File("earthmap1.jpg"));
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (image != null) {
g.drawImage(image, 0, 0, null);
}
}
@Override
public Dimension getPreferredSize() {
if (image == null) {
return super.getPreferredSize();
} else {
int w = image.getWidth();
int h = image.getHeight();
return new Dimension(w, h);
}
}
}
Note: code has not been tested