Negative Ranges, Java Scrollbars and Java2D.
Hiya all. I have a bit of an odd problem. Im working on graph animation. Graphs tend to be laid out with an initial random seed which tends to give a good smattering of negative values as well as postive ones. Now, I tend to shift all the nodes by a certain amount so that all are visible. However, once the user starts playing with the graph, there is no guarantee that all the values will still be positive. This means another shift is required which means a lot of jerky screen movements which is the last thing we need.
I was wondering. If i create a JPanel of say, size 1000 x 1000 and perform one Java2D affine translate of 500 by 500, that should center my graph on the JPanel. If i place this JPanel within a JScrollPane can I then set the scrollbars to appear halfway along their tracks, i.e, have the viewport lined up on center 500 by 500?
If anyone else has had a problem like this, i'd be most obliged if someone could post it here. Actually, probably the best thing would be some kind of canvas grow function such as the one in photoshop. When the canvas needs resizing, you can resize in one of 4 directions cant you? Yet the view remains constant. I imagine something like this isnt easy.
> then you may recalculate the bounds and adjust the
> scrollbars consquenlty? for example, minimum -7,
> maximum 10 then set the scrolbar to have a maximum of
> 17, etc. and you can always modify the scrollbars to
> have a right size so the user can scroll the graphs
Huh? Here's a demo where the component just resizes in a JScrollPane:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SampleComponent extends JPanel{
private int minX=-100, maxX=100, minY=-100, maxY=100;
public Dimension getPreferredSize() {
return new Dimension(maxX-minX, maxY-minY);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g.create();
g2.translate(-minX, -minY);
g2.drawLine(minX, 0, maxX, 0); //x axis
g2.drawLine(0, minY, 0, maxY); //y axis
g2.dispose();
}
public void rescale(float scale) {
minX=(int)(scale*minX);
maxX=(int)(scale*maxX);
minY=(int)(scale*minY);
maxY=(int)(scale*maxY);
invalidate();
revalidate();
repaint();
}
public static void main(String[] args) {
final SampleComponent app = new SampleComponent();
JScrollPane sp = new JScrollPane(app);
JPanel south = new JPanel();
JButton zoomIn = new JButton("zoom in");
south.add(zoomIn);
zoomIn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent evt) {
app.rescale(1.5f);
}
});
JButton zoomOut = new JButton("zoom out");
south.add(zoomOut);
zoomOut.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent evt) {
app.rescale(.75f);
}
});
final JFrame f = new JFrame("SampleComponent");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(sp, BorderLayout.CENTER);
f.getContentPane().add(south, BorderLayout.SOUTH);
f.pack();
SwingUtilities.invokeLater(new Runnable(){
public void run() {
f.setLocationRelativeTo(null);
f.setVisible(true);
}
});
}
}
Especially when you zoom in, you can get an unpleasant dislocation.