2

I would like to add a scrollable Canvas to a JFrame, some research on the web led me to a solution with a scrollable Canvas as a Java Applet. I tried to apply this onto a JFrame, which resulted in:

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.FlowLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Panel;
import java.awt.Scrollbar;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class Frame extends JFrame {
private JPanel contentPane;

class ScrollCanvas extends Panel {
     int vw,vh;
     int rw,rh;
     Color b,f;
     myCanvas c;
     Scrollbar sv, sh;

     // constructor
     //   visible h w
     //   real    h w
     //   background foreground
     ScrollCanvas
        (int vw1, int vh1,  int rw1, int rh1, Color b1, Color f1) {
      super();
      vw = vw1; vh = vh1;
      rh = rh1; rw = rw1;
      b  = b1;  f  = f1;
      int ScrollIncrement = 10;
      setLayout(new BorderLayout());
      c = new myCanvas(vw, vh, rw, rh, b ,f);
      add("West", c);
      sv = new Scrollbar
        (Scrollbar.VERTICAL,0, ScrollIncrement, 0, rh);
      add("East", sv);
      sh = new Scrollbar
        (Scrollbar.HORIZONTAL, 0, ScrollIncrement, 0, rw);
      add("South", sh);
      }

     public void redraw() {
      int y = sv.getValue();
      int x = sh.getValue();
      c.draw(x,y);
      }

     public Dimension minimumSize() {
      return new Dimension(vw,vh);
      }

     public Dimension preferredSize() {
      return new Dimension(vw,vh);
      }
    }

   class myCanvas extends Canvas {
     int vw, vh;
     int rw, rh;
     Color b, f;
     int x, y;
     Image buffImage;
     Graphics offscreen;
     boolean initDone;

     myCanvas
        (int vw1, int vh1, int rw1, int rh1, Color b1, Color f1) {
      super();
      vw = vw1; vh = vh1;
      rh = rh1; rw = rw1;
      b  = b1;  f  = f1;
      initDone = false;
      repaint();
      }

     public void paint(Graphics g) {
      if (!initDone)
       initpaint(g);
      else
       g.drawImage(buffImage, x, y,  this);
      }

     public void update(Graphics g) {
      g.drawImage(buffImage, x, y,  this);
      }

     public void initpaint(Graphics g) {
      try {
       buffImage = this.createImage(rw, rh);
       offscreen = buffImage.getGraphics();
       offscreen.setColor(b);
       offscreen.fillRect(0, 0, rw, rh);
       offscreen.setColor(f);
       offscreen.setFont(new Font("Courier", Font.ITALIC, 42));
       offscreen.drawString("Hello World!", 0, 50);
       initDone = true;
       g.drawImage(buffImage,0,0, this);
       }
      catch (Exception e) {
       System.out.println("oups...");
       }
      }

     public void draw (int x1, int y1)  {
      x = -x1;
      y = -y1;
      update(getGraphics());
      }

     public Dimension minimumSize() {
      return new Dimension(vw,vh);
      }

     public Dimension preferredSize() {
      return new Dimension(vw,vh);
      }
   }
   /**
 * Launch the application.
 */
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                Frame frame = new Frame();
                frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the frame.
 */
public Frame() {

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(267, 267, 1000, 900);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    contentPane.setLayout(new BorderLayout(0, 0));
    setContentPane(contentPane);

    ScrollCanvas myCV = new ScrollCanvas(500, 500, 1000, 1000, Color.BLACK, Color.RED);
    contentPane.add(myCV);
    }
}

Works fine, the canvas shows on the Frame perfectly fine, but its not SCROLLABLE and I cant repaint it (e.g. change the background color by pressing a button on the GUI of the JFrame). Either this is not an appropriate approach on adding a scrollable canvas to a JFrame, or im missing something you may know better and may share with me.

Thankfully

gobernador
  • 5,659
  • 3
  • 32
  • 51
Zi1mann
  • 334
  • 1
  • 2
  • 15
  • Note: The canvas itself should be scrollable – Zi1mann Dec 18 '15 at 12:53
  • Don't mix AWT and Swing components. Use only Swing components unless you have a strange restriction. – user1803551 Dec 18 '15 at 13:49
  • `some research on the web led me to a solution with a scrollable Canvas` - that is old code and should be avoided. That is not how you add components to a container. That is not how you do custom painting when using Swing. You override the paintComponent() method of a JPanel. Start with a simple example from the Swing tutorial on [How to Use Scroll Panes](http://docs.oracle.com/javase/tutorial/uiswing/components/scrollpane.html). The tutorial also has a section on `Custom Painting` that contains working examples. – camickr Dec 18 '15 at 16:07

0 Answers0