How to extends JViewport correctly? - java

I am trying to design a class of endless coordinate board with a grid. I have extended a JViewport and it draws at initial position ok (inside JScrollPane). How to tell scroll pane that there are some space to scroll in any direction?
The following does not help
JCoordinateViewport coordinate = new JCoordinateViewport();
coordinate.setBackground(Color.WHITE);
//coordinate.setPreferredSize(new Dimension(10000, 10000));
JScrollPane scroll = new JScrollPane();
//scroll.setViewportView(coordinate);
scroll.setViewport(coordinate);
scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
scroll.getVerticalScrollBar().setMinimum(-10000);
scroll.getVerticalScrollBar().setMaximum(+10000);
scroll.getHorizontalScrollBar().setMinimum(-10000);
scroll.getHorizontalScrollBar().setMaximum(+10000);
UPDATE
Does anybody knows how JScrollPane determines scroll ranges from it's viewport?
UPDATE2
I found, that scrollbars appear t work if maximums and minimums are set after setVisible called.
But unfortunately, paintConponent does not called upon scroll.
Why?
UPDATE3
Although scroll bars work, they don't change viewport position.
Why?

As shown here, painting on a JViewport appears to "stick" to the viewport, while painting on the underlying scrollable component slides beneath. Sizes are integral multiples of TILE: for demonstration purposes, the preferred size of the viewport is made smaller than the underlying panel; in practice, it's better to override getPreferredSize(). See also ScrollAction, which auto-scrolls as the mouse hovers near any border.

CoordinateViewport coordinate = new JCoordinateViewport(); coordinate.setBackground(Color.WHITE); //coordinate.setPreferredSize(new Dimension(10000, 10000));
JScrollPane scroll = new JScrollPane(); //scroll.setViewportView(coordinate);
scroll.setViewport(coordinate);
scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
scroll.getVerticalScrollBar().setMinimum(-10000);
scroll.getVerticalScrollBar().setMaximum(+10000);
scroll.getHorizontalScrollBar().setMinimum(-10000);
scroll.getHorizontalScrollBar().setMaximum(+10000);
.
The following does not help
then issue should be only in the class with name CoordinateViewport
for better help sooner post an SSCCE, short, runnable, compilable, just about JFrame, JScrollPane and JViewport
for reducing of flickering in the JViewport is required to set
own RepaintManager
and by using/with built_in methods in JViewport
JViewport.setScrollMode(JViewport.BLIT_SCROLL_MODE);
JViewport.setScrollMode(JViewport.BACKINGSTORE_SCROLL_MODE);
JViewport.setScrollMode(JViewport.SIMPLE_SCROLL_MODE);
please see Passing current Date and JTable how to change BackGround Color as potential source for SSCCE

Related

JScrollPane does not scroll properly: scrollRectToVisible acting up?

I have got the following basic setup on a Part of my GUI:
A JScrollPane
On it, a JPanel with a BoxLayout (new BoxLayout(tablePanel, BoxLayout.PAGE_AXIS))
And on this Panel, a Bunch ob Panels.
I am trying to scroll to the Panel that has been highlighted... this works ALMOST.
Currenly, if a Panel is only half-visible on the bottom Part, the ScrollPane scrolls to make it fully visible.. great.
If it is half-visible on the TOP part, it does not... I could live with that.
But if a totally invisible Panel at the very bottom is highlighted, the system does not comment, but neither does it scroll there!
if(selectedPanel!=null){
Rectangle targetRectangle = new Rectangle(selectedPanel.getX(), selectedPanel.getY(), selectedPanel.getWidth(), selectedPanel.getHeight());
Rectangle r = scrollPane.getVisibleRect();
if (!r.contains(targetRectangle)) {
tablePanel.scrollRectToVisible(targetRectangle);
}
}
I am unfortunately not 100% sure how it behaves when the second-to-last panel is selected while not visible, because I cannot make that happen without some code-gymnastics; perhaps someone can help with the information I can give at this point.
you have to compare Rectangle from/returns JViewport(visible rectangle from JScrollPane), not from JScrollPane
use selectedPanel.getBounds instead of (selectedPanel.getX(), selectedPanel.getY(), selectedPanel.getWidth(), selectedPanel.getHeight());
still isn't centerred, have to divide JVievports and selectedPanel with 2
the same result as to use single code line JComponentPlacedIntoJScrollPane.scrollRectToVisible(selectedPanel.getBounds())
for better help sooner post an SSCCE/MCVE, short, runnable, compilable

JScrollPane does not update scrollbar

I am trying to create a JScrollPane that contains a JPanel that will be increasing and decreasing in height. When it becomes larger than the size of the JScrollPane, it should create a vertical scroll bar which will allow me to scroll through the entire JPanel. However, I am having difficulty achieving this. Yes, I know I am not using LayoutManagers. No, I will not be using them, and I need a solution that does not involve their usage.
Here are the two button's AbstractActions that add and subtract from the JPanel:
class AddACT extends AbstractAction
{
public void actionPerformed(ActionEvent e)
{
info.setSize(420,info.getHeight() + 40);
info.add(new SubPanel); // Adds another JPanel into the main JPanel (for content input)
gui.repaint();
infoS.validate();
}
}
class RemoveACT extends AbstractAction
{
public void actionPerformed(ActionEvent e)
{
info.remove(subPanel()); // This would remove the last JPanel added to the main JPanel
info.setSize(420,info.getHeight() - 40);
gui.repaint();
infoS.validate();
}
And here is the code for the main JPanel and the JScrollPane:
final JPanel info = new JPanel();
final JScrollPane infoS = new JScrollPane(info, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
info.setLayout(null);
info.setSize(420,600);
infoS.setLocation(10,80);
infoS.setSize(420,490);
gui.add(infoS); // gui is the frame's content pane (the overall JPanel)
This is the second project I've been trying to learn GUI by doing. I am a complete novice in Swing and am only intermediate in Java. Sorry if I am making a blindingly obvious mistake.
1) Use LayoutManagers (+1 to #kleopatra and #GagandeepBali comments)
The absence of LayoutManagers only guarantees your GUI's will look very trashy (especially when run on other OSes/builds) and being a Novice you should rather learn the correct way than learn the wrong way and get into bad habits like calling setSize() etc.
Have a read on these links to get you started:
A Visual Guide to Layout Managers
Concurrency in Swing
2) See this example for how to use a JScrollPane, it simply adds a JPanel with buttons to a JScrollPane which in-turn is added to the JFrame.
3) Also see this example for how to make the JScrollPane vertically scroll-able only.
4) For more on JScrollPanes have a look here: How to Use Scroll Panes.
5) As for how it interacts with LayoutManager, if you do not explicitly set its size via setPreferredSize(Dimension d) the scroll pane computes it based on the preferred size of its nine components (the viewport, and, if present, the two scroll bars, the row and column headers, and the four corners)
6) On your usage of validate():
validate() is used when new JComponents are added to a visible component
revalidate() is used when JComponent is removed/added from a visible component
revalidate() covers validate() too
Thus always use this:
//add or remove component(s)
revalidate();
repaint();
References:
http://www.daniweb.com/software-development/java/threads/405568/validate-vs-revalidate
LayoutManager is not required to solve the problem. The problem in Thrfoot's example is in these lines:
final JScrollPane infoS = new JScrollPane(info, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
info.setLayout(null);
info.setSize(420,600);
The program appears to recognize there is a need for scroll bars (it would show the scroll bar if your setting was VERTICAL_SCROLLBAR_AS_NEEDED), but the actual scrolling does not work (the scroll bar slider is not there).
To fix this, first set the preferred size of info, then construct the infoS.
Example:
info.setPreferredSize(420,600);
final JScrollPane infoS = new JScrollPane(info, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
The idea is to set the preferred size of the info panel before it is used for the scroll pane. This is the same reason to set the size and location of infoS before adding to the gui:
infoS.setLocation(10,80);
infoS.setSize(420,490);
gui.add(infoS); // gui is the frame's content pane (the overall JPanel)

Resize JPanel within JScrollPane - never smaller than viewport

I've created a JPanel and JScrollPane like so:
JPanel panel = new JPanel();
panel.setPreferredSize(5000, 5000);
JScrollPane scrollPane = new JScrollPane(panel, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
scrollPanel.getViewport().setBackground(Color.GRAY); //panel is white
I will be using event handlers to dynamically resize the panel. The problem is, sometimes the panel is smaller than the viewport. I'd set the panel's size like this:
panel.setPreferredSize(10, 10); //Just an example
but the panel will never be smaller than the viewport. I tried using
panel.setSize(10, 10);
and i saw a gray flicker (the viewport's background showing through), which indicated that the panel was being sized to what i wanted it to be, but then grew to the viewport's size. How can i stop this?
To control the sizing the view inside a JViewport, let it implement the Scrollable interface. Without, it's always forced to the size of the viewport.

Resizing a JPanel inside of a JScrollPane clears the things I've drawn on the JPanel

I've got a JPanel inside a JScrollPane. I draw things in the JPanel, and at some point I might draw past the width of the JScrollPane. In this case, I'd like the horizontal scroll bar to appear, and I'd like to be able to scroll around to view different parts of the JPanel. However, I end up clearing the JScrollPane.
frame = new JFrame();
frame.setBounds(100, 100, 1000, 800);
localScrollPane = new JScrollPane();
localScrollPane.setBounds(768, 6, 226, 350);
frame.getContentPane().add(localScrollPane);
localView = new JPanel();
localScrollPane.setViewportView(localView);
drawSomeThings(localView.getGraphics());
// wait for user input
int newWidth = drawThingsPastTheWidth(localView.getGraphics());
// these next two lines clear it
localView.setPreferredSize(new Dimension(newWidth, localView.getHeight()));
localView.revalidate();
What am I doing wrong? Thanks!
drawSomeThings(localView.getGraphics());
Don't use the getGraphics() method to do painting. The painting will be lost the next time Swing determines the components needs to be repainted.
Instead custom painting is done by overriding the paintComponent() method of your component.
Do not use setPreferredSize method, here's a related thread.
Do not specify explicetly the size of the JScrollPane with setBounds. Let the LayoutManager of it's parent take care of this.
JScrollPane should use a
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED by default. So
the scrollbar should appear automatically when the preferred size of
the child component is higher than the displayed area. Try to
revalidate the JScrollPane instead of the JPanel.
It would appear that redraw is being called at some point, I've not used swing for a while so I'm not entirely sure what the problem is but try debugging and running through the code step by step to see where redraw is being called would be a good starting place.
you should certainly use repaint instead of revalidate. revalidate only marks all the container upto the top level as invalid.

Java : jscrollpane disable horizontal scrolling

I want to add a Jpanel on a jscrollpane; also I want to have only vertical scrolling. I want to set layout of my jPanel "flowLaout" and add several components to my jPanel in my code by jpanel.add(component) method. The result is that all components are placed in just one row that excide width of jpanel and are not shown. I have used this tricks and both failed:
jScrollPane1.setHorizontalScrollBar(null);
jScrollPane1.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
Wrap Layout should work for you.
I am unsure of the particulars for your current project, but i would recommend MigLayout. It has never served me wrong.
I am currently writing a touchscreen interface with nested MigLayout panels up to 4 or five layers deep, and have not had a single problem.
Please use the below policy to turn on vertical scrolling and turn off horizontal scrolling(Works with Java SE 7):
Panel graphicPanel = new Panel();
JScrollPane scrollbar = new JScrollPane(graphicPanel);
scrollbar.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
scrollbar.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scrollbar.setPreferredSize(new Dimension(1300, 600));
scrollbar.setVisible(true);
add(scrollbar, BorderLayout.CENTER);

Categories

Resources