My JscrollPane isn't scrolling (vertically) the entire image,

164 views Asked by At

when I increase the preferredSize, more of the Bufferedimage(on a JPanel, on a JFrame) is found.

The size of the image is going to vary depending on the size of the file my program is reading,

where I set the scrollpane;

public Frame(String title, int theWidth, int theHeight) throws FileNotFoundException {

        super(String.format("Title", title));
        this.width = theWidth;
        this.height = theHeight;
        this.panel = new Panel(width, height);
        this.scroller = new JScrollPane(this.panel);
        this.panel.drawLinesAndTab();
        this.scroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        this.scroller.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        this.scroller.setPreferredSize(new Dimension(this.width, this.height));
        this.getContentPane().add(this.scroller);
    }

And (don't shoot me), this is my Panel class;

public class Panel extends JPanel {

    private BufferedImage image;
    private ReadTabFile tab;
    private String title;
    private String theNotes;
    private String theFlag;
    private int a, b, c, x, y, beginBarlineX, beginBarlineY, endBarX, endBarY;
    private ArrayList list;
    private Font letterFont;
    private Font flagFont;
    private int width;
    private int height;
    boolean newLine = false;

    public Panel(int theWidth, int theHeight) throws FileNotFoundException {

        this.width = theWidth;
        this.height = theHeight;
        this.tab = new ReadTabFile("tabSource.txt");
        this.image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics g = this.image.createGraphics();
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, this.image.getWidth(), this.image.getHeight());
        setBorder(BorderFactory.createLineBorder(Color.black));
        this.setFocusable(true);

    }

    public void drawLinesAndTab() {

        Graphics g = this.image.getGraphics();
        g.setColor(Color.black);
        this.list = tab.readTabCode();
        this.a = 20;
        this.b = 100;
        this.c = 60;
        this.x = 40;
        this.y = 100;
        this.beginBarlineX = 20;
        this.beginBarlineY = 100;
        this.endBarY = 980;
        this.endBarY = 100;
        this.title = tab.getTitle();
        g.drawString(this.title, 40, 20);

        for (int i = 0; i < this.list.size(); i++) {
            Bar theBar = (Bar) this.list.get(i);
            drawBarline(a, b, a, b + 125);
            ArrayList<String> stuff = theBar.getLinesInBar();

            for (int j = 0; j < stuff.size(); j++) {
                String line = stuff.get(j);
                theFlag = line.substring(0, 1);
                theNotes = line.substring(1, line.length());
                if (newLine = true){
                    //make some bar lines.
                }

                try {

                    int w = this.image.getWidth();
                    //int h = this.image.getHeight();

                    if (c <= (w - 40)) {

                        newLine = false;
                        String zero = theFlag;
                        drawFlag(zero, x + 5, y - 20);

                        String one = theNotes.substring(0, 1);
                        g.drawLine(a, b, c, b);
                        drawLetter(one, x, y);

                        String two = theNotes.substring(1, 2);
                        drawLetter(two, x, y += 25);
                        g.drawLine(a, b += 25, c, b);

                        String three = theNotes.substring(2, 3);
                        drawLetter(three, x, y += 25);
                        g.drawLine(a, b += 25, c, b);

                        String four = theNotes.substring(3, 4);
                        drawLetter(four, x, y += 25);
                        g.drawLine(a, b += 25, c, b);

                        String five = theNotes.substring(4, 5);
                        drawLetter(five, x, y += 25);
                        g.drawLine(a, b += 25, c, b);

                        String six = theNotes.substring(5, 6);
                        drawLetter(six, x, y += 25);
                        g.drawLine(a, b += 25, c, b);
                        this.repaint();

                        b -= 125;
                        y -= 125;
                        x += 40;
                        a += 40;
                        c += 40;

                    } else {
                        newLine = true;
                        a = 20;
                        x = 20;
                        b += 225;
                        c = 60;
                        y += 225;
                        beginBarlineX = 20;
                        beginBarlineY += 100;
                        endBarX += 100;
                        endBarY = 100;
                        this.repaint();
                    }

                } catch (Exception ex) {
                    System.err.println(ex + " within Panel, drawtab for loop");
                }
            }
        }
    }

    public void drawBarline(int xTop, int yTop, int xBot, int yBot) {
        Graphics g = this.image.getGraphics();
        g.setColor(Color.black);
        g.drawLine(xTop, yTop, xBot, yBot);

    }

    public Point makeBarline(int xTop, int yTop, int xBot, int yBot) {
        Graphics g = this.image.getGraphics();
        g.setColor(Color.black);
        g.drawLine(xTop, yTop, xBot, yBot);
        return (new Point());
    }

    public Point drawLetter(String letter, int x, int y) throws FontFormatException, IOException {

        Graphics g = this.image.getGraphics();
        g.setColor(Color.black);
        g.setFont(letterFont(letter).deriveFont(20.0f));
        g.drawString(letter, x, y);

        return (new Point());
    }

    public Point drawFlag(String letter, int x, int y) throws FontFormatException, IOException {

        Graphics g = this.image.getGraphics();
        g.setColor(Color.black);
        g.setFont(flagFont(letter).deriveFont(30.0f));
        g.drawString(letter, x, y);

        return (new Point());
    }

    public Font letterFont(String fontString) throws FontFormatException, IOException {

        Graphics g = this.image.getGraphics();
        g.setColor(Color.black);

        if (!Character.isDigit(fontString.charAt(0))) {
            this.letterFont = Font.createFont(Font.TRUETYPE_FONT, new File("LeRoy.ttf"));
            g.getFontMetrics(this.letterFont);
            g.setFont(this.letterFont);
            return this.letterFont;
        } else {
            return null;
        }
    }

    public Font flagFont(String fontString) throws FontFormatException, IOException {

        Graphics g = this.image.getGraphics();
        g.setColor(Color.black);

        if (!Character.isDigit(fontString.charAt(0))) {
            this.flagFont = Font.createFont(Font.TRUETYPE_FONT, new File("LeroyLuteNotes1.ttf"));
            g.getFontMetrics(this.flagFont);
            g.setFont(this.flagFont);
            return this.flagFont;
        } else {
            return null;
        }

    }

    @Override
    public Dimension getPreferredSize() {
        return (new Dimension(this.image.getWidth(), this.image.getHeight()));
    }

    public BufferedImage getImage() {
        return this.image;
    }

    @Override
    public void paintComponent(Graphics graphics) {

        Graphics g = graphics.create();
        g.drawImage(this.image, 0, 0, null);
    }
}

I think I've set it up correctly, I've not used a layout manager because all I'm doing is basically writing lines and text to the image/panel. It is working fine, but I need to be able to scroll right down to the bottom of the image.

Any help would be greatly appreciated, thanks.

1

There are 1 answers

4
Sage On BEST ANSWER
  1. JScrollPane respects component preferred size to set it's content view, not the component's content.
  2. If you wish to scroll with respect to content: image, Override getPreferreedSize(Dimension) function of the Panel class and return the image size as the component's preferred size.
  3. We should always call super.paintComponent(g) inside the overriden paintComponent(Graphics) function, which you are not doing for now.