JLayeredPane with JPanel - java

The problem: I have no control on implementing more into the histogram package, so I create an array of buttons and overlay them on top of the histogram using JLayeredPane. However, I cannot get both the histogram plot and the buttons panels to scale when the JFrame is enlarged or contracted.
The JLayedPane is composed of 2 JPanels, see MWE.
To repeat the issue, just run program and extend JFrame.
I have read the following on SO posts; jlayeredpane-with-gridlayout, jlayeredpane-with-a-layoutmanager, jlayeredpane-not-resizing-with-jframe, resize-jframe-to-jpanels-inside-jlayeredpane, automatic-content-resizing-of-jlayeredpane,
as well as the Oracle page on JLayeredPane which has some examples
As useful as these links were, I still cannot get both JPanels to extend/contract with the JFrame.
Question: Is there a way to get both JPanels in the JLayeredPane to rescale without implementing a new layout? If new layout is needed, would someone please provide a MWE on how to do such?
public class FrameDemo extends JPanel {
private JLayeredPane layeredPane;
private final int width = 800;
private final int height = 800;
private String[] layerStrings = { "Yellow (0)", "Magenta (1)", "Cyan (2)", "Red (3)", "Green (4)", "Blue (5)" };
private Color[] layerColors = { Color.yellow, Color.magenta, Color.cyan, Color.red, Color.green, Color.blue };
public FrameDemo() {
setLayout(new BorderLayout());
init();
addPanels();
add(layeredPane, BorderLayout.CENTER);
}
private void init() {
this.layeredPane = new JLayeredPane();
this.layeredPane.setPreferredSize(new Dimension(width, height));
this.layeredPane.setBorder(BorderFactory.createTitledBorder("Histogram should go here"));
this.layeredPane.setLayout(new BorderLayout());
}
private void addPanels() {
this.layeredPane.add(createHistogramPanel(), BorderLayout.CENTER, new Integer(1));
this.layeredPane.add(createButtonPanel(), BorderLayout.CENTER, new Integer(0));
this.layeredPane.addComponentListener(new ComponentAdapter() {
#Override
public void componentResized(ComponentEvent e) {
Dimension size = layeredPane.getSize(); // get size
createHistogramPanel().setSize(size); // push size through
createButtonPanel().setSize(size); // push size trhough
// otherChildOfLayers.setSize(size); // push size trhough
layeredPane.revalidate(); // revalidate to see updates
layeredPane.repaint(); // "Always invoke repaint after
// revalidate"
}
});
}
private JPanel createHistogramPanel() {
JPanel histpanel = new JPanel();
histpanel.setLayout(new GridLayout(2, 3));
for (int i = 0; i < layerStrings.length; i++) {
JLabel label = createColoredLabel(layerStrings[i], layerColors[i]);
histpanel.add(label);
}
histpanel.setOpaque(false);
histpanel.setBounds(10, 10, width, height);
return histpanel;
}
private JLabel createColoredLabel(String text, Color color) {
JLabel label = new JLabel("");
label.setVerticalAlignment(JLabel.TOP);
label.setHorizontalAlignment(JLabel.CENTER);
label.setOpaque(true);
label.setBackground(color);
label.setForeground(Color.black);
label.setBorder(BorderFactory.createLineBorder(Color.black));
label.setPreferredSize(new Dimension(120, 120));
return label;
}
private JPanel createButtonPanel() {
ButtonGroup buttons = new ButtonGroup();
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout(2, 3));
for (int i = 0; i < 6; i++) {
final int placer = i + 1;
JButton freshButton = new JButton();
freshButton.addActionListener(e -> {
System.out.println("Button " + placer + " clicked");
});
freshButton.setText("Button " + (i + 1));
freshButton.setOpaque(true);
freshButton.setContentAreaFilled(false);
freshButton.setBorderPainted(false);
freshButton.setBounds(new Rectangle(132, 75 + (i * 20), 40, 20));
buttonPanel.add(freshButton, null);
buttons.add(freshButton);
}
buttonPanel.setOpaque(false);
buttonPanel.setBounds(10, 10, width, height);
return buttonPanel;
}
private static void createAndShowGUI() {
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JComponent newContentPane = new FrameDemo();
newContentPane.setOpaque(true); // content panes must be opaque
frame.setContentPane(newContentPane);
frame.setLocationRelativeTo(null);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}

Your code won't work because in componentResized you're creating new panels and applying the size to them. You need to resize the existing panels added to the layered pane. This could be done by assigning histogramPanel and buttonPanel as instance variables.

Related

Why oh why, does my scrollPane not scroll to anywhere?

I can't figure out why this code doesn't make scrollbars appear. I'm a complete beginner at Swing so the scrollpanes are very confusing and I don't understand some of the solutions I have seen online. The annoying thing is this code briefly worked but I destroyed the successful part before backing it up when trying to add a component. Any help would be appreciated!
import javax.swing.*;
import java.awt.*;
public class Test extends JFrame
{
private JPanel leftPanel;
private JButton myButton;
private JPanel scrollPanel;
private JScrollPane scrollPane;
public static void main(String[] args)
{
System.setProperty("swing.defaultlaf", "com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
javax.swing.SwingUtilities.invokeLater(new Runnable()
{
public void run() {
new Test();
}
});
}
/**
* Constructor for objects of class Backup
*/
public Test()
{
this.setTitle("testy");
this.setSize(new Dimension(1280,622));
leftPanel = new JPanel();
leftPanel.setBackground(new Color(255,0,0));
leftPanel.setBounds(0, 100, 640, 558);
leftPanel.setEnabled(true);
this.add(leftPanel);
scrollPanel = new JPanel(null);
scrollPanel.setBackground(new Color(100,100,100));
scrollPanel.setPreferredSize(new Dimension(640, 550));
scrollPanel.setEnabled(true);
JScrollPane scrollPane = new JScrollPane(scrollPanel, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrollPane.setBounds(0, 0, 642, 550);
scrollPane.setEnabled(true);
leftPanel.add(scrollPane);
for (int i = 1; i < 30; i++)
{
scrollPanel.setLayout(new GridLayout(30, 1, 0, 1));
myButton = new JButton("AAAAAAAAAAAAAAAAAAAAA " + i);
myButton.setPreferredSize(new Dimension(630, 70));
scrollPanel.add(myButton);
}
this.setBackground(new Color(0,0,0));
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.pack();
this.setVisible(true);
}
}
I think I've massively improved it since then thanks to camickr
Here is the current version:
import javax.swing.*;
import java.awt.*;
public class Test extends JFrame
{
private JPanel leftPanel;
private JButton myButton;
private JPanel scrollPanel;
private JScrollPane scrollPane;
public static void main(String[] args)
{
System.setProperty("swing.defaultlaf",
"com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
javax.swing.SwingUtilities.invokeLater(new Runnable()
{
public void run() {
new Test();
}
});
}
public Test()
{
this.setTitle("testy");
this.setSize(new Dimension(1280,622));
leftPanel = new JPanel();
leftPanel.setBackground(new Color(255,0,0));
leftPanel.setBounds(0, 100, 640, 558);
this.add(leftPanel);
scrollPanel = new JPanel();
scrollPanel.setLayout(new GridLayout(70, 1, 0, 1));
//scrollPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20,
20));
scrollPanel.setBackground(new Color(100,100,100));
//scrollPanel.setPreferredSize(new Dimension(640, 550));
//JScrollPane scrollPane = new JScrollPane(scrollPanel);
JScrollPane scrollPane = new JScrollPane(scrollPanel,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
//scrollPane.setLayout(new GridLayout(30, 1, 0, 1));
//scrollPane.setBounds(0, 0, 642, 550);
scrollPane.setEnabled(true);
//scrollPanel.add(scrollPane);
leftPanel.add(scrollPanel);
for (int i = 1; i < 71; i++)
{
myButton = new JButton("AAAAAAAAAAAAAAAAAAAAA " + i);
//myButton.setPreferredSize(new Dimension(640, 80));
scrollPanel.add(myButton);
}
this.setBackground(new Color(0,0,0));
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.pack();
this.setVisible(true);
}}
Don't use a null layout.
Don't use setBounds().
Don't use setPreferredSize().
Each Swing component is responsible for determining its own preferred size. The layout manager will then set the size/location of each components added to the panel and it will then (dynamically) calculated the preferred size of the panel. The scroll bars will appear when the preferred size of the panel is greater than the size of the scroll pane.
scrollPanel = new JPanel(null);
scrollPanel.setBackground(new Color(100,100,100));
// scrollPanel.setPreferredSize(new Dimension(640, 550)); // delete
//scrollPanel.setEnabled(true); // not needed
...
for (int i = 1; i < 30; i++)
{
//scrollPanel.setLayout(new GridLayout(30, 1, 0, 1)); // set layout when panel created.
//myButton.setPreferredSize(new Dimension(630, 70)); // not needed.
The layout manager should be set outside the loop, when you create the panel. It should NOT be null.
Don't hard code the preferred size. It will not dynamically adjust as components are added.
Swing components are enabled by default to setEnabled is not needed.
Don't use the "leftPanel". Just add the scroll pane directly to the frame. This will allow the scrollpane to resize dynamically as the frame is resized. Then the scroll bars will appear when requirement.
Don't set the preferreid size of the button. The size will be determined based on the text and the Font of the button.

Drawing Circles on random JPanels by Pressing a JButton

I got a grid with JPanels, by pressing the Button on top I want a random generator to draw circles on 3 random Panels.
In theory I think I have to overwrite the PaintComponent of every JPanel with a circle, put the flag on false and when I press the button an action listener puts the flag of 3 random JPanels on true.
But I really have no idea how to do this. Is it possible to do it this way ? if yes, could you show me how, if no, could you tell me what else i have to do ? Thanks a lot. Here's my code so far:
package feld;
import javax.swing.*;
import java.awt.*;
public class Spielplan {
public static void main(String[] args) {
JFrame f1 = new JFrame();
f1.setLayout(new BorderLayout());
f1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f1.setPreferredSize(new Dimension(800, 800));
JButton tokens = new JButton("Spielsteine setzen");
f1.add(tokens, BorderLayout.NORTH);
JPanel p1 = new JPanel();
p1.setLayout(new GridLayout(3,3));
f1.add(p1, BorderLayout.CENTER);
JPanel g1 = new JPanel();
g1.setBorder(BorderFactory.createLineBorder(Color.BLACK));
g1.setPreferredSize(new Dimension(100, 100));
g1.setVisible(true);
p1.add(g1);
JPanel g2 = new JPanel();
g2.setBorder(BorderFactory.createLineBorder(Color.BLACK));
g2.setPreferredSize(new Dimension(100, 100));
g2.setVisible(true);
p1.add(g2);
JPanel g3 = new JPanel();
g3.setBorder(BorderFactory.createLineBorder(Color.BLACK));
g3.setPreferredSize(new Dimension(100, 100));
g3.setVisible(true);
p1.add(g3);
JPanel g4 = new JPanel();
g4.setBorder(BorderFactory.createLineBorder(Color.BLACK));
g4.setPreferredSize(new Dimension(100, 100));
g4.setVisible(true);
p1.add(g4);
JPanel g5 = new JPanel();
g5.setBorder(BorderFactory.createLineBorder(Color.BLACK));
g5.setPreferredSize(new Dimension(100, 100));
g5.setVisible(true);
p1.add(g5);
JPanel g6 = new JPanel();
g6.setBorder(BorderFactory.createLineBorder(Color.BLACK));
g6.setPreferredSize(new Dimension(100, 100));
g6.setVisible(true);
p1.add(g6);
JPanel g7 = new JPanel();
g7.setBorder(BorderFactory.createLineBorder(Color.BLACK));
g7.setPreferredSize(new Dimension(100, 100));
g7.setVisible(true);
p1.add(g7);
JPanel g8 = new JPanel();
g8.setBorder(BorderFactory.createLineBorder(Color.BLACK));
g8.setPreferredSize(new Dimension(100, 100));
g8.setVisible(true);
p1.add(g8);
JPanel g9 = new JPanel();
g9.setBorder(BorderFactory.createLineBorder(Color.BLACK));
g9.setPreferredSize(new Dimension(100, 100));
g9.setVisible(true);
p1.add(g9);
f1.pack();
f1.setVisible(true);
}
}
The simplest way I could think of is to create s subclass of JPanel with a boolean to determine whether the circle should be drawn. I named it CirclePanel:
public class CirclePanel extends JPanel{
public static final Color circleColor = Color.BLACK;
private boolean drawCircle;
public CirclePanel() {
drawCircle=false;
setBorder(BorderFactory.createLineBorder(Color.BLACK));
setBackground(Color.WHITE);
}
public void setDrawCircle(boolean drawCircle) {
this.drawCircle = drawCircle;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if(drawCircle) {
Graphics2D g2d = (Graphics2D) g;
Color tmp = g2d.getColor();
g2d.setColor(circleColor);
g2d.fillOval(0, 0, getWidth(), getHeight());
g2d.setColor(tmp);
}
}
}
Then I created a subclass of JFrame for the frame but you could also do it in a main method. I placed the circle panels in an array to avoid repeating code and placed them in a grid. When the button is clicked, a List of indices are created and three are removed at random. The list is then used to set the boolean variable of the panels. see below:
public class CircleGrid extends JFrame implements ActionListener{
private CirclePanel[] panels;
private JButton button;
public CircleGrid() {
super("Circle test");
setLayout(new BorderLayout());
panels = new CirclePanel[9];
JPanel center = new JPanel();
center.setLayout(new GridLayout(3, 3));
for (int i = 0; i < panels.length; i++) {
panels[i] = new CirclePanel();
center.add(panels[i]);
}
button = new JButton("Color in");
button.addActionListener(this);
this.add(button, BorderLayout.NORTH);
this.add(center, BorderLayout.CENTER);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(new Dimension(800, 800));
setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource().equals(button)) {
// select three random circle indices -
// https://stackoverflow.com/a/42353488/7015661
ArrayList<Integer> indices = new ArrayList<Integer>();
int numRandom = 3; // three indices
for (int i = 0; i < panels.length; i++) {
indices.add(i);
}
Random r = new Random();
for (int i = 0; i < numRandom; i++) {
int rndPos1 = r.nextInt(indices.size());
indices.remove(rndPos1); // remove three indices from the list
}
// change panel boolean
for (int i = 0; i < panels.length; i++) {
CirclePanel pi = panels[i];
if(indices.contains(i)) {
// no circle
pi.setDrawCircle(false);
}else {
//draw circle
pi.setDrawCircle(true);
}
}
repaint(); // redraw panels
}
}
public static void main(String[] args) {
new CircleGrid();
}
}
I end up with the following:
What you would do is essentially before your draw on your jPanel white out the entire panel then draw your circle apply the code below hopes in helps.
int name=(int) Math.random() * 100;
int name1=(int) Math.random() * 100;
Then you would draw the circle on the JPanels using the graphics method and the appropriate code. Below is the code that draws the circle in a random place:
g.draw/fillOval (name,name1,100,100);

JScrollPane does not react to scrollRectToVisible

I have the following window:
public class MyWindows extends JFrame {
private final JScrollPane pane;
public MyWindows(){
super();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container cp = getContentPane();
cp.setLayout(new BorderLayout());
JPanel panel = new JPanel();
pane = new JScrollPane(panel);
pane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
JButton left = new JButton("<");
left.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
moveLeft();
}
});
cp.add(left, BorderLayout.WEST);
panel.setLayout(new GridLayout(1,0));
for(int i = 1; i<20; i++) {
panel.add(new JButton("hallo nummer "+i));
}
cp.add(pane, BorderLayout.CENTER);
JButton right = new JButton(">");
cp.add(right, BorderLayout.EAST);
this.setLocationRelativeTo(null);
pack();
this.setSize(300, 100);
}
private void moveLeft() {
Rectangle rec = pane.getVisibleRect();
rec.setLocation((int)(rec.getX()+1000), (int)rec.getY());
System.out.println(rec);
pane.scrollRectToVisible(rec);
System.out.println(pane.getVisibleRect());
}
}
The idea was to scroll along the buttons in the center, using the buttons on the left and on the right.
Unfortunately, the moveLeft()-Method does exactly nothing when it comes to scrolling.
The target-rectangle is java.awt.Rectangle[x=1000,y=0,width=202,height=61]
To me, that looks like a rectangle the ScrollPane should be able to scroll to.
What am I missing?
Also, sorry about the wall of code, but I just have no idea where the error may be.
Call scrollRectToVisible method on desired component (JPanel in your case) but on JScrollPane object.
private JPanel panel;
...
private void moveLeft() {
Rectangle rec = panel.getVisibleRect();
rec.setLocation((int) (rec.getX() + 1000), (int) rec.getY());
System.out.println(rec);
panel.scrollRectToVisible(rec);
System.out.println(panel.getVisibleRect());
}

How do I resize these panels in my JFrame?

I'm creating a chess game where the main panel is using BorderLayout, there is a panel at NORTH for buttons, a panel at CENTER for the board itself (set to GridLayout) and a sidebar at East.
I have made the JFrame unresizable and I'd like the chessboard to fit the panels in so that the East panel is a lot wider (maybe 200 pixels) and the board remains a square. I can't figure out how to change the sizes of these components individually.
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
public class GameWindow extends JFrame {
private final JPanel playArea = new JPanel(new BorderLayout(3,3));
private final JButton[][] boardSquares = new JButton[8][8];
private final JPanel board;
private final JPanel sidebar = new JPanel();
private final JLabel message = new JLabel("Game by ...");
public GameWindow() {
playArea.setBorder(new EmptyBorder(5, 5, 5, 5));
JToolBar tools = new JToolBar();
tools.setFloatable(false);
playArea.add(tools, BorderLayout.PAGE_START);
tools.add(new JButton("New Game"));
tools.add(new JButton("Save"));
tools.add(new JButton("Restore"));
tools.addSeparator();
tools.add(new JButton("Resign"))
tools.addSeparator();
tools.add(message);
board = new JPanel(new GridLayout(0, 8));
board.setBorder(new LineBorder(Color.BLACK));
playArea.add(board, BorderLayout.CENTER);
playArea.add(sidebar, BorderLayout.EAST);
Insets buttonMargin = new Insets(0,0,0,0);
for (int i = 0; i < boardSquares.length; i++) {
for (int j = 0; j < boardSquares[i].length; j++) {
JButton square = new JButton();
square.setMargin(buttonMargin);
if ((i+j)%2 == 0) {
square.setBackground(Color.WHITE);
}
else {
square.setBackground(Color.BLACK);
}
board.setSize(600, 600);
board.add(boardSquares[j][i] = square);
}
}
}
public final JComponent getChessBoard() {
return board;
}
public final JComponent getGui() {
return playArea;
}
public static void main(String[] args) {
GameWindow window = new GameWindow();
JFrame frame = new JFrame("Checkers");
frame.setResizable(false);
frame.add(window.getGui());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
frame.setSize(800, 800);
frame.setVisible(true);
}
}
Firstly, since JDK 1.4, Java is encouraging the use of BorderLayout constants as BorderLayout.PAGE_START, BorderLayout.LINE_START, BorderLayout.CENTER, BorderLayout.LINE_END and BorderLayout.PAGE_END over the latter used by you.
Secondly you can simply override, the getPreferredSize() of the said JPanel, in order for it to give, some size that you feel like will work for your use case. Use of setPreferredSize() is restricted, since, not all LayoutManagers use to respect the Dimension specified by it.
Hence you could do something like:
private final JPanel sidebar = new JPanel() {
#Override
public Dimension getPreferredSize() {
return new Dimension(100, 100);
}
};
You can try this modified code:
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
public class GameWindow extends JFrame {
private final JPanel playArea = new CustomPanel(710, 710);
private final JButton[][] boardSquares = new JButton[8][8];
private final JPanel board;
private final JPanel sidebar = new CustomPanel(100, 100);
private final JLabel message = new JLabel("Game by ...");
public GameWindow() {
playArea.setLayout(new BorderLayout(3,3));
playArea.setBorder(new EmptyBorder(5, 5, 5, 5));
JToolBar tools = new JToolBar();
tools.setFloatable(false);
playArea.add(tools, BorderLayout.PAGE_START);
tools.add(new JButton("New Game"));
tools.add(new JButton("Save"));
tools.add(new JButton("Restore"));
tools.addSeparator();
tools.add(new JButton("Resign"));
tools.addSeparator();
tools.add(message);
board = new CustomPanel(600, 600);
board.setLayout(new GridLayout(0, 8));
board.setBorder(new LineBorder(Color.BLACK));
playArea.add(board, BorderLayout.CENTER);
playArea.add(sidebar, BorderLayout.LINE_START);
Insets buttonMargin = new Insets(0,0,0,0);
for (int i = 0; i < boardSquares.length; i++) {
for (int j = 0; j < boardSquares[i].length; j++) {
JButton square = new JButton();
square.setOpaque(true);
square.setMargin(buttonMargin);
if ((i+j)%2 == 0) {
square.setBackground(Color.WHITE);
}
else {
square.setBackground(Color.BLACK);
}
board.add(boardSquares[j][i] = square);
}
}
}
private class CustomPanel extends JPanel {
private int width;
private int height;
public CustomPanel(int width, int height) {
this.width = width;
this.height = height;
setOpaque(true);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(width, height);
}
}
public final JComponent getChessBoard() {
return board;
}
public final JComponent getGui() {
return playArea;
}
public static void main(String[] args) {
GameWindow window = new GameWindow();
JFrame frame = new JFrame("Checkers");
frame.setResizable(false);
frame.setContentPane(window.getGui());
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setLocationByPlatform(true);
frame.pack();
frame.setVisible(true);
}
}
Moreover, before setting the background of JButton, it would be wise to call button.setOpaque(true) property.
It's not difficult to set the size of a JPanel. Just call setPreferredSize(). In your case to resize your East JPanel, call:
sidebar.setPreferredSize(new Dimension(200, 200));
After that, your LayoutManager will set the size of your JPanel to 200,200.
To your other JPanel, board: It's impossible to make a Component (like a JPanel) remaining a square. They always fit into rectangles. You would need to make your own subclass of JComponent and only paint everything in the square, and leave the rest transparent. Therefore, overwrite the method JComponent.paintComponent(Graphics).

all individual panels are not shown inside root panel

I want to add multiple jpanels to jpanel.So i added a root panel to jscrollpane.and then added all individual jpanels to this root panel.I made jscrollpane's scrolling policy as needed.i.e HORIZONTAL_SCROLLBAR_AS_NEEDED,VERTICAL_SCROLLBAR_AS_NEEDED.
But the problem is all individual panels are not shown inside root panel.
Code:
JScrollPane scPanel=new JScrollPane();
JPanel rootPanel=new JPanel();
rootPanel.setLayout(new FlowLayout());
JPanel indPanel = new JPanel();
rootPanel.add(indPanel);
JPanel indPanel2 = new JPanel();
rootPanel.add(indPanel2);
//.....like this added indPanals to rootPanel.
scPanel.setViewPortView(rootPanel);
//scPanel.setHorizontalScrollPolicy(HORIZONTAL_SCROLLBAR_AS_NEEDED);
And one more thing is, as i scroll the scrollbar the panels are going out of jscrollpane area.
I am not able to see all individual panels,
Please suggest me.
Edit: code snippet from double post:
MosaicFilesStatusBean mosaicFilesStatusBean = new MosaicFilesStatusBean();
DefaultTableModel tableModel = null;
tableModel = mosaicFilesStatusBean.getFilesStatusBetweenDates(startDate, endDate);
if (tableModel != null) {
rootPanel.removeAll();
rootPanel.setLayout(new BoxLayout(rootPanel, BoxLayout.PAGE_AXIS));
for (int tempRow = 0; tempRow < tableModel.getRowCount(); tempRow++) {
int fileIdTemp = Integer.parseInt(tableModel.getValueAt(tempRow, 0).toString());
String dateFromTemp = tableModel.getValueAt(tempRow, 3).toString();
String dateToTemp = tableModel.getValueAt(tempRow, 4).toString();
int processIdTemp = Integer.parseInt(tableModel.getValueAt(tempRow, 5).toString());
int statusIdTemp = Integer.parseInt(tableModel.getValueAt(tempRow, 6).toString());
String operatingDateTemp = tableModel.getValueAt(tempRow, 7).toString();
MosaicPanel tempPanel =
new MosaicPanel(fileIdTemp, dateFromTemp, dateToTemp, processIdTemp, statusIdTemp, operatingDateTemp);
rootPanel.add(tempPanel);
}
rootPanel.revalidate();
}
The main reason, why you couldn't see your JPanel is that you are using FlowLayout as the LayoutManager for the rootPanel. And since your JPanel added to this rootPanel has nothing inside it, hence it will take it's size as 0, 0, for width and height respectively. Though using GridLayout such situation shouldn't come. Have a look at this code example attached :
import java.awt.*;
import javax.swing.*;
public class PanelAddition
{
private void createAndDisplayGUI()
{
JFrame frame = new JFrame("Panel Addition Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel contentPane = new JPanel();
contentPane.setLayout(new GridLayout(0, 1));
JScrollPane scroller = new JScrollPane();
CustomPanel panel = new CustomPanel(1);
contentPane.add(panel);
scroller.setViewportView(contentPane);
frame.getContentPane().add(scroller, BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
for (int i = 2; i < 20; i++)
{
CustomPanel pane = new CustomPanel(i);
contentPane.add(pane);
contentPane.revalidate();
contentPane.repaint();
}
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new PanelAddition().createAndDisplayGUI();
}
});
}
}
class CustomPanel extends JPanel
{
public CustomPanel(int num)
{
JLabel label = new JLabel("" + num);
add(label);
}
#Override
public Dimension getPreferredSize()
{
return (new Dimension(200, 50));
}
}
Don't use FlowLayout for the rootPanel. Instead consider using BoxLayout:
JPanel rootPanel=new JPanel();
// if you want to stack JPanels vertically:
rootPanel.setLayout(new BoxLayout(rootPanel, BoxLayout.PAGE_AXIS));
Edit 1
Here's an SSCCE that's loosely based on your latest code posted:
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.util.Random;
import javax.swing.*;
#SuppressWarnings("serial")
public class PanelsEg extends JPanel {
private static final int MAX_ROW_COUNT = 100;
private Random random = new Random();
private JPanel rootPanel = new JPanel();
public PanelsEg() {
rootPanel.setLayout(new BoxLayout(rootPanel, BoxLayout.PAGE_AXIS));
JScrollPane scrollPane = new JScrollPane(rootPanel);
scrollPane.setPreferredSize(new Dimension(400, 400)); // sorry kleopatra
add(scrollPane);
add(new JButton(new AbstractAction("Foo") {
#Override
public void actionPerformed(ActionEvent arg0) {
foo();
}
}));
}
public void foo() {
rootPanel.removeAll();
// rootPanel.setLayout(new BoxLayout(rootPanel, BoxLayout.PAGE_AXIS)); // only need to set layout once
int rowCount = random.nextInt(MAX_ROW_COUNT);
for (int tempRow = 0; tempRow < rowCount ; tempRow++) {
int fileIdTemp = tempRow;
String data = "Data " + (tempRow + 1);
MosaicPanel tempPanel =
new MosaicPanel(fileIdTemp, data);
rootPanel.add(tempPanel);
}
rootPanel.revalidate();
rootPanel.repaint(); // don't forget to repaint if removing
}
private class MosaicPanel extends JPanel {
public MosaicPanel(int fileIdTemp, String data) {
add(new JLabel(data));
}
}
private static void createAndShowGui() {
PanelsEg mainPanel = new PanelsEg();
JFrame frame = new JFrame("PanelsEg");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
This SSCCE works, in that it easily shows removing and adding JPanels to another JPanel that is held by a JScrollPane. If you're still having a problem, you should modify this SSCCE so that it shows your problem.

Categories

Resources