1 Attachment(s)
Scroll position from the past (SSCCE)
Hello! [Please go to second post in this thread first]
First of all, in attachments is SSCCE program which shows main problem.
You should complie it with (after going to folder javatest_SSCCE):
Code :
javac -d \javatest *.java
and run it from the same folder with:
Instruction: You should now have a window with nice picture. Program is set to scroll always to 50% of width of the image.
When you press zoom in or zoom out it looks ok. But if you use slider and slide it about 100% you will see it is not in the center.
The best is to do this after starting the application.
It is happeining because all parameters of scrollBar are taken from previous state of application window and not from the current one:
[class ScrolledPictureViewer]
Code Java:
/*
* Gets vertical scroll position in percentage
*/
public final int getVerticalScrollPosition()
{
//This is calculated from the previous state
int maxPositionV = this.getVerticalScrollBar().getMaximum () - this.getVerticalScrollBar().getVisibleAmount();
int scrollPos = this.getVerticalScrollBar().getValue();
int percentage = 0;
if(maxPositionV > 0)
{
//percentage = java.lang.Math.round(((float)scrollPos / (float)maxPositionV)*100);
percentage = (int)(((float)scrollPos / (float)maxPositionV)*100);
}
return percentage;
}
Here is code which directly makes zoom:
Code Java:
public void setZoom(float zoom)
{
this.picViewer1.setZoom(zoom);
//Resizing picture and setting its new parameters
this.picViewer1.refreshImage();
this.setScrollPosition(50,50);
}
For me it's ok. First I'm resizing picture, so scrollbars should have correct sizes... but repaint is happening in other thread. How can i synchronize everything.
Target is to set always the same focus on picture during zooming, if I set scroll to 20% it should be always in position of 20% of the picture, but it's not.
I think answer on this simple question will solve most of my problems now.
PS. I don't want to post here all the code not to make mess. Everything should me in attachment.
Re: Scroll position from the past (SSCCE)
OK. I simplify the problem.
Please compile program below and tell me why program is setting correct position of JPanel and JScrollPanel scrollbars after 3 clicks of button. It should take one click.
Code java:
import java.awt.*;
import java.awt.event.ActionEvent;
import javax.swing.*;
import javax.swing.border.Border;
/**
*
* @author blazejp
*/
class JPanelCircle extends JPanel
{
public JPanelCircle()
{
super();
this.setLayout(new FlowLayout());
this.setBackground(Color.red);
this.setBounds(50, 50, 500, 300);
this.setPreferredSize(new Dimension(500, 300));
}
@Override
protected void paintComponent(Graphics g)
{
int h = getHeight();
int w = getWidth();
super.paintComponent(g);
g.setColor(Color.CYAN);
g.fillOval(w/2, h/2, w, h);
}
}
class Scroll2 extends JPanel
{
private JPanelCircle panel;
private JScrollPane sPane;
public Scroll2()
{
super(new BorderLayout());
panel = new JPanelCircle();
panel.repaint();
sPane = new JScrollPane(panel);
sPane.getViewport().setBackground(Color.black);
sPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
sPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
sPane.setBorder(BorderFactory.createBevelBorder(0, Color.lightGray, Color.yellow));
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(sPane.getViewport());
sPane.getViewport().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 594, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 508, Short.MAX_VALUE)
);
this.add(sPane, BorderLayout.NORTH);
JButton scroll = new JButton("scroll");
scroll.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
scrollActionPerformed(evt);
}
});
JButton resizeScroll = new JButton("resize&scroll");
resizeScroll.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
resizeScrollActionPerformed(evt);
}
});
this.add(scroll);
this.add(resizeScroll);
}
private void scrollActionPerformed(ActionEvent evt)
{
this.setScrollPosition(50, 50);
}
private void resizeScrollActionPerformed(ActionEvent evt)
{
this.panel.setPreferredSize(new Dimension(1000, 300));
this.panel.setBounds(50, 50, 1000, 300);
this.panel.repaint();
this.setScrollPosition(50, 50);
this.sPane.repaint();
}
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("Scroll");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
Scroll2 newContentPane = new Scroll2();
newContentPane.setOpaque(true); //content panes must be opaque
frame.setContentPane(newContentPane);
//Display the window.
frame.pack();
frame.setVisible(true);
}
public final int getHorizontalScrollPosition()
{
int maxPositionH = sPane.getHorizontalScrollBar().getMaximum () - sPane.getHorizontalScrollBar().getVisibleAmount();
int scrollPos = sPane.getHorizontalScrollBar().getValue();
int percentage = 0;
if(maxPositionH > 0)
{
percentage = (int)(((float)scrollPos / (float)maxPositionH)*100);
}
return percentage;
}
public final void setHorizontalScrollPosition(int posPercentage)
{
int maxPositionH = sPane.getHorizontalScrollBar().getMaximum () - sPane.getHorizontalScrollBar().getVisibleAmount();
int scrollPos = maxPositionH;//this.getHorizontalScrollBar().getValue();
if(maxPositionH > 0 && posPercentage >= 0 && posPercentage <= 100)
{
//scrollPos = java.lang.Math.round(((float)maxPositionH * (float)posPercentage)/100);
scrollPos = (int)(((float)maxPositionH * (float)posPercentage)/100);
}
else if(posPercentage > 100)
{
scrollPos = maxPositionH;
}
sPane.getHorizontalScrollBar().setValue(scrollPos);
}
/*
* Gets vertical scroll position in percentage
*/
public final int getVerticalScrollPosition()
{
int maxPositionV = sPane.getVerticalScrollBar().getMaximum () - sPane.getVerticalScrollBar().getVisibleAmount();
int scrollPos = sPane.getVerticalScrollBar().getValue();
int percentage = 0;
if(maxPositionV > 0)
{
percentage = (int)(((float)scrollPos / (float)maxPositionV)*100);
}
return percentage;
}
public final void setVerticalScrollPosition(int posPercentage)
{
int maxPositionV = sPane.getVerticalScrollBar().getMaximum () - sPane.getVerticalScrollBar().getVisibleAmount();
int scrollPos = maxPositionV;//this.getVerticalScrollBar().getValue();
if(maxPositionV > 0 && posPercentage >= 0 && posPercentage <= 100)
{
scrollPos = (int)(((float)maxPositionV * (float)posPercentage)/100);
}
else if(posPercentage > 100)
{
scrollPos = maxPositionV;
}
sPane.getVerticalScrollBar().setValue(scrollPos);
}
public final void setScrollPosition(int hPercentage, int vPercentage)
{
this.setHorizontalScrollPosition(hPercentage);
this.setVerticalScrollPosition(vPercentage);
}
public static void main(String[] args) {
// TODO code application logic here
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run()
{
createAndShowGUI();
}
});
}
}
Re: Scroll position from the past (SSCCE)
Can you explain what you see and what position is the correct position?
When I click the button once the display changes. What is wrong with the change that I see?
Re: Scroll position from the past (SSCCE)
Quote:
Originally Posted by
Norm
Can you explain what you see and what position is the correct position?
When I click the button once the display changes. What is wrong with the change that I see?
First click:
Red JPanel i moving down by 50 and resizes to (1000, 300)
Second click:
Horizontal scrollbar moves to 50% of scrollbar length
Third click:
Red JPanel i moving down by 50 to the right
This is what i see on m screen
And I want it happen in one button click.
Re: Scroll position from the past (SSCCE)
How do I change the height (make shorter) of the window?
Re: Scroll position from the past (SSCCE)
Quote:
Originally Posted by
Norm
How do I change the height (make shorter) of the window?
I don't understand what You want to do...?
The goal is to make all three steps in one button click - somehow force to repaint once or wait when full repaint is finished.
Re: Scroll position from the past (SSCCE)
The window is too tall and covers up what I want to see behind it. How can I make its height be 400 pixels?
Is the code using a layout manager and also calling setBounds()? Which should control the location? Are they competing to control the locations of the components?
Re: Scroll position from the past (SSCCE)
Here is repaired code. Now JScrollPane should be (400,400) - variable mainSize. Also I changed LayoutManager of JScrollPane to SpringLayout which is, I think, most suitable for me.
Now calling function below, JPanel is moved and resized. Is this resizing algorithm ok? For me this is strange that I have to change parameters by setBounds, setPreferredSize and layout.putConstraints (!?)... 3 operations to make a new position and resize of JPanel? Is there better way to do this?
And still there is a problem with setting horizontal scrollbar.
Code java:
private void resizeScrollActionPerformed(ActionEvent evt)
{
SpringLayout layout = (SpringLayout)sPane.getViewport().getLayout();
layout.putConstraint(SpringLayout.WEST, panel, 50, SpringLayout.WEST, sPane);
layout.putConstraint(SpringLayout.NORTH, panel, 50, SpringLayout.NORTH, sPane);
this.panel.setPreferredSize(new Dimension(1000, 100));
this.panel.setBounds(0, 0, 1000, 100);
this.setScrollPosition(50, 50);
}
Full Program:
Code java:
import java.awt.*;
import java.awt.event.ActionEvent;
import javax.swing.*;
/**
*
* @author blazejp
*/
class JPanelCircle extends JPanel
{
public JPanelCircle()
{
super();
this.setLayout(new FlowLayout());
this.setBackground(Color.red);
this.setBounds(0, 0, 200, 50);
this.setPreferredSize(new Dimension(200, 50));
}
@Override
protected void paintComponent(Graphics g)
{
int h = getHeight();
int w = getWidth();
super.paintComponent(g);
g.setColor(Color.CYAN);
g.fillOval(w/2, h/2, w, h);
}
}
class Scroll2 extends JPanel
{
private JPanelCircle panel;
private JScrollPane sPane;
private Dimension mainSize = new Dimension(400, 400);
public Scroll2()
{
super(new BorderLayout());
panel = new JPanelCircle();
panel.repaint();
sPane = new JScrollPane(panel);
sPane.setBounds(0,0,mainSize.width,mainSize.height);
sPane.setPreferredSize(mainSize);
sPane.getViewport().setBackground(Color.black);
sPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
sPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
sPane.setBorder(BorderFactory.createBevelBorder(0, Color.lightGray, Color.yellow));
sPane.getViewport().setLayout(new SpringLayout());
this.add(sPane, BorderLayout.NORTH);
JButton resizeScroll = new JButton("resize&scroll");
resizeScroll.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
resizeScrollActionPerformed(evt);
}
});
this.add(resizeScroll);
}
private void scrollActionPerformed(ActionEvent evt)
{
this.setScrollPosition(50, 50);
}
private void resizeScrollActionPerformed(ActionEvent evt)
{
SpringLayout layout = (SpringLayout)sPane.getViewport().getLayout();
layout.putConstraint(SpringLayout.WEST, panel, 50, SpringLayout.WEST, sPane);
layout.putConstraint(SpringLayout.NORTH, panel, 50, SpringLayout.NORTH, sPane);
this.panel.setPreferredSize(new Dimension(1000, 100));
this.panel.setBounds(0, 0, 1000, 100);
this.setScrollPosition(50, 50);
}
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("Scroll");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
Scroll2 newContentPane = new Scroll2();
newContentPane.setOpaque(true); //content panes must be opaque
frame.setContentPane(newContentPane);
//Display the window.
frame.pack();
frame.setVisible(true);
}
public final int getHorizontalScrollPosition()
{
int maxPositionH = sPane.getHorizontalScrollBar().getMaximum () - sPane.getHorizontalScrollBar().getVisibleAmount();
int scrollPos = sPane.getHorizontalScrollBar().getValue();
int percentage = 0;
if(maxPositionH > 0)
{
percentage = (int)(((float)scrollPos / (float)maxPositionH)*100);
}
return percentage;
}
public final void setHorizontalScrollPosition(int posPercentage)
{
int maxPositionH = sPane.getHorizontalScrollBar().getMaximum () - sPane.getHorizontalScrollBar().getVisibleAmount();
int scrollPos = maxPositionH;
if(maxPositionH > 0 && posPercentage >= 0 && posPercentage <= 100)
{
scrollPos = (int)(((float)maxPositionH * (float)posPercentage)/100);
}
else if(posPercentage > 100)
{
scrollPos = maxPositionH;
}
sPane.getHorizontalScrollBar().setValue(scrollPos);
}
/*
* Gets vertical scroll position in percentage
*/
public final int getVerticalScrollPosition()
{
int maxPositionV = sPane.getVerticalScrollBar().getMaximum () - sPane.getVerticalScrollBar().getVisibleAmount();
int scrollPos = sPane.getVerticalScrollBar().getValue();
int percentage = 0;
if(maxPositionV > 0)
{
percentage = (int)(((float)scrollPos / (float)maxPositionV)*100);
}
return percentage;
}
public final void setVerticalScrollPosition(int posPercentage)
{
int maxPositionV = sPane.getVerticalScrollBar().getMaximum () - sPane.getVerticalScrollBar().getVisibleAmount();
int scrollPos = maxPositionV;
if(maxPositionV > 0 && posPercentage >= 0 && posPercentage <= 100)
{
scrollPos = (int)(((float)maxPositionV * (float)posPercentage)/100);
}
else if(posPercentage > 100)
{
scrollPos = maxPositionV;
}
sPane.getVerticalScrollBar().setValue(scrollPos);
}
public final void setScrollPosition(int hPercentage, int vPercentage)
{
this.setHorizontalScrollPosition(hPercentage);
this.setVerticalScrollPosition(vPercentage);
}
public static void main(String[] args) {
// TODO code application logic here
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run()
{
createAndShowGUI();
}
});
}
}