0

I'm looking to try and load up a JScrollPane with the horizontal JScrollBar set all the way to the right, i.e. like in this image:

https://i.stack.imgur.com/02BKi.png

However, no matter what I do, I end up with this image:

https://i.stack.imgur.com/Eh50d.png

This is the relevant snippet of my code

    JComponent graph = new TrendsForSuccLarge(wccScores, wccScoresTimes, graphStrings, maxScore, bgColour, iPadWidth);

    JScrollPane graphScrollPane = new JScrollPane(graph, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);

    JScrollBar horizontal = graphScrollPane.getHorizontalScrollBar();
    horizontal.setValue( horizontal.getMaximum() );

    this.getContentPane().add(graphScrollPane, BorderLayout.CENTER);

Any ideas of what's going wrong?

Thanks in advance!

Kesh

SSCCE

import javax.swing.JFrame;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;

class ForStackOverflow  {

    private static JFrame main;
    //opens up a line chart on full screen

    public static void main(String args[]) {

        TempGraph tg = new TempGraph(main);
        tg.setVisible(true);

    }
}

class TempGraph extends JDialog {

    private static final long serialVersionUID = 1L;

    //opens up a line chart on full screen

    public TempGraph(JFrame parent)
    {
        // load the frame
        super(parent,true);
        configureFrame();
    }

    private void configureFrame()
    {

        int iPadHeight = 644;
        int iPadWidth = 981;

        this.getContentPane().setLayout(new BorderLayout());

        JComponent graph = new TrendsForSuccLarge2(iPadWidth);

        JScrollPane graphScrollPane = new JScrollPane(graph, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);

        this.getContentPane().add(graphScrollPane, BorderLayout.CENTER);

        JPanel buttons = new JPanel();
        buttons.setLayout(new BorderLayout());

        JButton ok = new JButton("Done");
        ok.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                next();
            }
        });
        buttons.add(ok,BorderLayout.CENTER);
        JButton exit = new JButton("Exit");
        exit.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
        buttons.add(exit,BorderLayout.WEST);

        this.getContentPane().add(buttons, BorderLayout.SOUTH);

        this.pack();        
        this.setSize(this.getWidth(), 750);
        this.setResizable(true);
        Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
        int widthFrame = iPadWidth;
        int heightFrame = iPadHeight;
        this.setSize(widthFrame, heightFrame);
        setBounds((screenSize.width - this.getWidth()) / 2,
                (screenSize.height - this.getHeight()) / 2, 
                getWidth(),
                getHeight());
    }

    private void next()
    {
        this.setVisible(false);
    }

}

class TrendsForSuccLarge2 extends JComponent {

    // basic parameters
    private static int PREF_W = 200;
    private static final int PREF_H = 200;
    private static final int BORDER_GAP = 10;
    private static final int GRAPH_GAP = BORDER_GAP + 20;

    private int graphWidth = 0;

    private static final long serialVersionUID = 1L;

    TrendsForSuccLarge2(int prefGraphWidth) {

        graphWidth = prefGraphWidth;

        paintComponent(null);
    }

    public void paint(Graphics g) { 

        int windowWidth = 2600;

        PREF_W = windowWidth;

        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        g2.drawString("Hello", graphWidth/2, getHeight() - GRAPH_GAP);

        g2.drawString("Hello1", graphWidth - GRAPH_GAP, getHeight() - GRAPH_GAP);

        g2.drawString("Hello2", windowWidth - GRAPH_GAP - GRAPH_GAP, getHeight() - GRAPH_GAP);

        // create x and y axes 
        g2.setColor(Color.black);
        g2.drawLine(GRAPH_GAP, getHeight() - GRAPH_GAP, GRAPH_GAP, GRAPH_GAP);
        g2.drawLine(GRAPH_GAP, getHeight() - GRAPH_GAP, windowWidth - GRAPH_GAP, getHeight() - GRAPH_GAP);

    }

    public Dimension getPreferredSize() {
        return new Dimension(PREF_W, PREF_H);
    }

}
Keshava Murthy
  • 119
  • 1
  • 2
  • 12

4 Answers4

2

the full code is here:

The code you posted doesn't compile since we don't have access to all your custom classes. Post a proper SSCCE when you have a question.

horizontal.setValue( horizontal.getMaximum() ); 

You need to invoke that code AFTER the dialog is visible.

camickr
  • 321,443
  • 19
  • 166
  • 288
  • OK, I'll post an SSCCE, will reword my code. Thanks for the heads up. – Keshava Murthy Aug 29 '13 at 15:14
  • Edited to include an SSCCE. Thanks. – Keshava Murthy Aug 29 '13 at 16:19
  • @KeshavaMurthy: the first "S" in "SSCCE" == "short". Your code should have only enough code to compile, run, and show the problem, and nothing else. Your current posted code has a lot of code completely unrelated to your problem and thus distracting to us, making it hard for us to easily hone down to the essence of your problem. Sure doing this will mean more work for you, but it is work that is well spent both for you and for us. – Hovercraft Full Of Eels Aug 29 '13 at 16:59
  • Your question is about scrolling a component to the right when it is a scrollpane. We don't care about your real application. All you need to do is create a component, maybe a JPanel and then invoke setPreferredSize(...), with a large width. Then you add the component to a scrollpane and you have a simple test case. Now the goal is to scroll to the right. Anyway I already gave you the solution. So create you 10 line SSCCE to test my suggestion. If you can't get it to work, then you have you simple 10 line SSCCE to post. – camickr Aug 29 '13 at 19:13
1

From the Javadoc :

javax.​swing.​JScrollBar
public void setValue(int i)
Sets the current value of the adjustable object. If the value supplied is less than minimum or greater than maximum - visibleAmount, then one of those values is substituted, as appropriate. Calling this method does not fire an AdjustmentEvent.
Parameters:
v - the current value, between minimum and maximum - visibleAmount

And I don't really know why it seems that the maximum value, using getMaximum() returns 100.
and the visible amount value, using getVisibleAmount() returns 10.
So, the scroll's value when you call setValue(9999) won't be greater than 90.

And my solution is, set the maximum with some high value first, then set the value :

myScrollPane.getHorizontalScrollBar().setMaximum(1500);
myScrollPane.getHorizontalScrollBar().setValue(1500);

topher
  • 1,357
  • 4
  • 17
  • 36
1

In answer to your question of whether I know what's going on, I'd have to say "only partially".

The problem appears to be that the scrollbar value is getting set before the UI is fully realized (or something similar -- I do not understand Swing internals enough to know just what all the various levels and terms are).

I got it to work by inserting the following code:

SwingUtilities.invokeLater
(
  new Runnable()
  {
    public void run()
    {
      graphScrollPane.getHorizontalScrollBar().setValue(1000);
    }
  }
);

just before the end of the configureFrame() method in TempGraph.

arcy
  • 12,845
  • 12
  • 58
  • 103
  • Hi, turns out this only works when my window is smaller than a certain size. My window got much bigger and suddenly the bar only goes halfway. I've changed the question to include a proper SSCCE. – Keshava Murthy Sep 02 '13 at 10:17
  • I did not keep the original code with which I set the value, but I don't remember the graph being in a dialog, I thought it was in the frame. Once you make the dialog visible, it halts execution of things like "invokeLater" that appear after the "setVisible". There's a way to do it with a dialog, but I'm no longer sure what you want, or even that you're still asking a question. But I think the bar "only going halfway" is likely that we're setting the value to 1000 and the window is now wider than that, and I'm disinclined to try to debug the current code without knowing more what is wanted. – arcy Sep 02 '13 at 14:01
0

I solved this, apparently the issue was that my component had a preferred size that was too small. I rammed the preferred size up and everything sorted itself.

Keshava Murthy
  • 119
  • 1
  • 2
  • 12