In my application I want to show generated graph, using JUNG. It produces JPanel object as output. So, i though it would be just a matter of adding a component to panel. But the graph is drawn outside of its parent panel. Screenshot:
How do I restrict the graph to be only inside the visible area?
The code I use to add graph to panel is this (the border was for me to see panel borders, though it doesnt show for some reason):
Layout<Object, String> layout = new CircleLayout<Object, String> (graphProvider.getGraph());
layout.setSize(panel.getMarketGraphPane().getPreferredSize());
BasicVisualizationServer<Object,String> graphPanel = new BasicVisualizationServer<Object,String>(layout);
graphPanel.setBorder(new EtchedBorder());
graphPanel.setSize(panel.getMarketGraphPane().getPreferredSize());
panel.getMarketGraphPane().add(graphPanel, BorderLayout.CENTER);
panel.getMarketGraphPane().revalidate();
too little informations for the actual image
1 depends
what Size returns (generated graph, by using JUNG), are you set there setSize(int, int) too,
if is graph resiziable,
2) remove
layout.setSize(panel.getMarketGraphPane().getPreferredSize());
and
graphPanel.setSize(panel.getMarketGraphPane().getPreferredSize());
you can't to setSize for Object placed to the BorderLayout.CENTER, and I think that is possible directly put (generated graph, using JUNG. It produces JPanel object) to the BorderLayout.CENTER area, try that maybe your twice setSize generated some mess
and then you can call only
panel.add(graphPanel, BorderLayout.CENTER);
panel.revalidate();
panel.repaint();
3) another two choises (without clean-up setSize)
call pack(); to the Top-Level Container, notice carefully with LCD/LED monitors bounds
put that to the JScrollPane
use GraphZoomScrollPane to add zoom-able graph scrollpane container for VisualizationViewer object as follows:
GraphZoomScrollPane pane = new GraphZoomScrollPane(visualizationViewer);
JPanel panel = new JPanel();
BorderLayout panelMapLayout = new BorderLayout();
panel.setLayout(panelMapLayout);
panel.add(pane, BorderLayout.CENTER);
Related
I have been researching for 30 minutes on how to automatically resize a JFrame when the elements are too large. I am trying to fit line segments inside the JFrame but it always exceeds the space but does not automatically generate more space.
What should I do?
DrivePanel panel = new DrivePanel(aCar, coordinates);
JFrame application = new JFrame();
application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
application.add(panel);
application.setSize(600,600);
application.setVisible(true);
Example of output:
Some things to consider :
if you are doing custom painting on your panel, remember that the panel's size it's not changed by what you are drawing.
For example, if the "last" point (i mean the point with the biggest values of x and y) is drawn at (1000,1000) coordinates, you should set the preferred size of your panel in order to contain it.
To let your application using the preferred size of your components, you should call application.pack() (where application is your JFrame object) instead of setting size manually.
If your panel is too big to be displayed enterily on your screen, you might add it to a JScrollPane, and then add the scrollpane to your jframe (not the panel itself).
The scrollpane will automatically use scroll bars if your panel can't be fully displayed on your screen.
So consider this small example, based on your code :
DrivePanel panel = new DrivePanel(aCar, coordinates);
JFrame application = new JFrame();
application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel.setPreferredSize(new Dimension(1000,1000)); // change 1000,1000 with the coordinates you need ...
JScrollPane scrollPane = new JScrollPane(panel);
application.add(scrollPane);
application.pack();
application.setVisible(true);
Hope this helps :)
I am attempting to create panel, PluginListPanel (extending JPanel), which will show a list of plugin panels which will respect the preferred height of the plugin's panel, but will force the width. I have a solution, but it is slow and has a weird bug. In the screenshot, there are two such panels, one to the left and one to the right:
I don't know different layout manager systems very well, but I know that the TOP field in the BorderLayout does what I want. So, I came up with this 'recursive' solution:
public PluginListPanel(List<PanelContainer> items) {
JPanel body = this;
for (PanelContainer item : items) {
body.setLayout(new BorderLayout(0, 0));
JPanel panel = new PluginOnePanel(item);
body.add(panel, BorderLayout.NORTH);
JPanel newBody = new JPanel();
body.add(newBody, BorderLayout.CENTER);
body = newBody;
}
}
The problem I encounter is when I scroll, the system responds somewhat slowly, and the colour of the SamplePluginPanels is different (see picture below), even if the number of SamplePluginPanels is as low as 8.
The question is, how can I make this more elegant, not slow down the program and not miscolour the panels?
Any insights are highly appreciated.
I think a vertical Box is the answer (actually 2, on both columns):
Box leftBox = Box.createVerticalBox();
Box rightBox = Box.createVerticalBox();
/* put them together */
setLayout(new GridLayout(2,1));
add(leftBox);
add(rightBox);
Also make sure, that the content of the scroll pane implements Scrollable and returns true, to scrollableTracksViewportWidth(). This will force equal widths.
I have a JList inside a JScrollPane that's placed in a JPanel (BorderLayout.CENTER) and putting that inside another JPanel's BorderLayout.EAST (this JPanel's CENTER contains another JPanel) and this whole JPanel is placed inside a JTabbedPane. Initially, it would look like this:
Now I add some books to the list:
If I go to another tab and come back, this happens:
What I don't understand is that, the JPanel containing the JList has both its minimum and maximum size set:
JPanel listPanel = new JPanel();
listPanel.setLayout(new BorderLayout());
listPanel.add(new JScrollPane(bookList), BorderLayout.CENTER);
listPanel.setMinimumSize(listPanel.getPreferredSize());
listPanel.setMaximumSize(listPanel.getPreferredSize());
checkOutPanel.add(listPanel, BorderLayout.EAST);
How can I prevent the JList from auto resizing?
Depending on what it is you trying archive, you can either use JList#setPrototypeCellValue or JList#setFixedCellWidth. These will feed back into the PeferredScrollableViewportSize method which will effect the scroll pane
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)
BorderLayout does something strange. If I add two panels to a Container with the same constraint (BorderLayout.CENTER for instance), then the first one goes away, even if the second one is deleted or made invisible
It seems as though it would make sense for it to "stack" each element on top of the previous ones.
Is this correct and by design? If so, is there some documentation on it?
Has anyone else been frustrated by it? Have you a solution, such as a custom LayoutManager?
Sample code:
JFrame frame = new JFrame();
frame.setSize(500, 500);
JPanel panel1 = new JPanel();
panel1.setBackground(Color.blue);
frame.getContentPane().add(panel1);
JPanel panel2 = new JPanel();
panel2.setBackground(Color.red);
frame.getContentPane().add(panel2);
panel2.setVisible(false); // Seems like it should allow us to see panel1.
frame.setVisible(true);
This creates and displays a 500x500 blank box.
BorderLayout was simply not designed to do what you want. Separation of responsibility. If you want that behavior you should compose: combine the BorderLayout with a CardLayout. Though for the actual stack behavior, you'll have to code something yourself (or find someone who already has.)
Is this correct and by design?
Yes.
You need to understand the basics of how layout managers work. One of the jobs of the layout manager is to set the "location" and "size" of the components added to the panel. In the case of a BorderLayout it only tracks 5 components so only the last component added to the CENTER is known by the layout manager.
Layout management is not done when components are added to the panel. It is done when the frame is packed, or made visible (or the revalidate() method is invoked) . In this case the blue panel is not part of the components managed by the BorderLayout so its size remains (0, 0), which means there is nothing to paint.
Try changing your code to:
JPanel panel1 = new JPanel();
panel1.setSize(200, 200);
and you will see the blue panel painted at the specified size.
Now try commenting out:
//panel2.setVisible(false);
and you will see both panels. This is because as components are added to the panel they are assigned a ZOrder. Basically the last component added is painted first, which is why the blue panel is painted on top of the red panel. Check out the setComponentZOrder() method of the Container class for more information.
The CardLayout is probably the layout manager you should be using, but you can check out the Overlap Layout as well.