JScrollPane is not Working in JPanel - java

I have to use JScrollPane in my Project but it is not working.
I have pasted my code where I use a JSCrollPane in my main JPanel.
frame = new JFrame();
frame.setBounds(100, 100, 1179, 733);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
JScrollPane scrollPane_1 = new JScrollPane();
scrollPane_1.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane_1.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
scrollPane_1.setBounds(0, 0, 1163, 694);
frame.getContentPane().add(scrollPane_1);
JPanel panel = new JPanel();
scrollPane_1.setViewportView(panel);
panel.setLayout(null);

Setting the layout to Null means you need to handle the placement manually --> Specify the pixel location and handle the size of the container.
A layout manager handles this placement for you. The manager calculates its preferred size based on its content. The ScrollPane uses this calculated size from the layout manager.
This means you should use a layout manager, place your components within it. The rest should work automatically.
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setSize(500, 500);
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(30, 15));
for (int row = 0; row < 30; row++) {
for (int col = 0; col < 15; col++) {
panel.add(new Button("Button" + row + "/" + col));
}
}
frame.getContentPane().add(new JScrollPane(panel));
frame.setVisible(true);
}

I am not sure which layout you are using, but you need to set your panel layout something like this
panel.setLayout(new FormLayout(
"default:grow",
"fill:default:grow"));

Related

Need advice for making a Grid with Java Swing

I am attempting to use Java Swing to create a Grid that allows me to access specific panels if I need to. The frame pulls up but there are no panels. I would like some advice on how to make the panels display in the frame while still allowing me to access the specific panel through the two dimensional array.
x=0;
y=0;
z=0;
JPanel[][] coordinate = new JPanel[5][5];
JFrame frame = new JFrame();
JPanel panel = new JPanel();
frame.setSize(550,550);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setResizable(false);
panel.setBackground(Color.WHITE);
panel.setLayout(new GridLayout(5,5));
for(int i = 0; i<25; i++) {
if(z == 5) {
z = 0;
x = 0;
y++;
}
coordinate[x][y] = new JPanel();
coordinate[x][y].setBorder(BorderFactory.createLineBorder(Color.BLACK, 10));
panel.add(coordinate[x][y]);
z++;
x++;
}
frame.add(panel);

Updating component's height also changes it's width

I have a GUI with one main JPanel and inside of it multiple rows, each row being another JPanel. Every row (of type JPanel) consists of 4 smaller JPanels and every panel out of those 4 has a component inside of it. The end result is a grid like interface.
Main panel has a BoxLayout and panels that are parts of a row have FlowLayout.
When I update height of some component (from row) using some listener, entire row becomes taller, which works as expected. But what happens is that not only height is changed, but also width of components (inside a row) is changed. I understand that BoxLayout is trying to layout the components using maxSize and minSize that I can set to be the same value and that worked, but then when I resize the window, other rows expand and the row with same minSize and maxSize doesn't and the grid structure becomes messed up.
What I want to achieve, is that I update only the height of the row. And when I resize the window, entire row expands, and the structure of grid is still the grid. Here is the Short, Self Contained, Correct (Compilable), Example:
Main class:
public class Main {
public static void main(String args[]) {
SwingUtilities.invokeLater(() -> {
new MainFrame(450,150);
});
}
}
MainFrame class:
public class MainFrame extends JFrame{
public MainFrame(int width, int height) {
super("Title");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(width, height);
setVisible(true);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
JScrollPane scrollPane = new JScrollPane(mainPanel);
add(scrollPane);
for(int i=0; i<50; i++) {
JPanel panel1 = new JPanel();
panel1.setLayout(new FlowLayout(FlowLayout.LEFT));
panel1.setBorder(BorderFactory.createMatteBorder(0, 1, 0, 1, Color.black));
panel1.setPreferredSize(new Dimension(70,35));
JPanel panel2 = new JPanel();
panel2.setLayout(new FlowLayout(FlowLayout.LEFT));
panel2.setBorder(BorderFactory.createMatteBorder(0, 0, 0, 1, Color.black));
panel2.setPreferredSize(new Dimension(70,35));
JPanel panel3 = new JPanel();
panel3.setLayout(new FlowLayout(FlowLayout.LEFT));
panel3.setBorder(BorderFactory.createMatteBorder(0, 0, 0, 1, Color.black));
panel3.setPreferredSize(new Dimension(70,35));
JTextArea area1 = new JTextArea("hello " + i);
area1.setPreferredSize(new Dimension(70,25));
panel1.add(area1);
JTextArea area2 = new JTextArea("hello " + i);
area2.setPreferredSize(new Dimension(70,25));
panel2.add(area2);
JTextArea area3 = new JTextArea("hello " + i);
area3.setPreferredSize(new Dimension(70,25));
panel3.add(area3);
JPanel row = new JPanel();
row.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, Color.black));
row.setLayout(new BoxLayout(row, BoxLayout.X_AXIS));
row.add(panel1);
row.add(panel2);
row.add(panel3);
JButton button = new JButton("Click me");
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
buttonPanel.setBorder(BorderFactory.createMatteBorder(0, 0, 0, 1, Color.black));
buttonPanel.setPreferredSize(new Dimension(70,35));
buttonPanel.add(button);
button.addActionListener(event -> {
panel1.setPreferredSize(new Dimension(panel1.getWidth(), panel1.getHeight() + 30));
area1.setPreferredSize(new Dimension(area1.getWidth(), area1.getHeight() + 30));
area1.updateUI();
});
row.add(buttonPanel);
mainPanel.add(row);
}
}
}
If you run this code and press button it will update not only row's height, but also row's width and grid is not aligned well anymore.
You are setting the "preferred size" based on the "size" of the component. The two can be different.
Your code should be something like:
//panel1.setPreferredSize(new Dimension(panel1.getWidth(), panel1.getHeight() + 30));
Dimension d = panel1.getPreferredSize();
panel1.setPreferredSize(new Dimension(d.width, d.height + 30));
Also, you should not be using updateUI(). That is a method used internally by Swing on a LAF change.
Instead, when you want to invoke the layout manager you invoke revalidate() on the top level component that was changed:
//area1.updateUI();
panel1.revalidate();

Button creating another column in Panel

The button on the Panel was supposed to be below the last row of ovals but what it does was add a column:
Here is my Code
Panel p1 = new Panel();
JButton shiftLeft = new JButton("Shift Left");
JButton shiftRight = new JButton("Shift Right");
p1.setLayout(new GridLayout(Rows, Columns));
for (int i=0; i<Rows; i++) {
for (int j = 0; j < Columns; j++) {
arcs[i][j] = new ArcsPanel(i, j);
p1.add(arcs[i][j]);
arcs[i][j].addMouseListener(me);
}
}
p1.add(shiftRight);
add(p1, BorderLayout.CENTER);
this.pack();
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setVisible(true);
The button on the Panel was supposed to be below the last row of ovals
A GridLayout always adds components in rows/columns.
If you want the button separate from the GridLayout then you need to add the button to the frame directly:
//p1.add(shiftRight);
add(p1, BorderLayout.CENTER);
add(shiftRight, BorderLayout.PAGE_END);
Or if you don't want the button resized, then you need to wrap it in another panel first:
JPanel buttonPanel = new JPanel();
buttonPanel.add( shiftRight );
add(buttonPanel, BorderLayout.PAGE_END);
The point is to achieve desired layout you can use multiple panels each with different layouts. You are not force to use a single panel or layout manager.

java; basic way to add components in custom locations (jframe)

I need to use Custom Locations for my JFrame components, I have tried looking in Java's Document about Using the insets object for making a custom location but i dont really understand that well...
if you got any ways to add components in custom locations or a good tutorial/web/other that i can easily learn how to use custom locations.
if you haven't tried null layout, then check out this code, may be of help
public static void main(String[] args) {
SwingUtilities.invokeLater(NullLayout::new);
}
NullLayout() {
JFrame frame = new JFrame("Basket Game");
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
for (int i = 0; i < 4; i++) {
JPanel strip = new JPanel();
strip.setMaximumSize(new Dimension(Integer.MAX_VALUE, 50));
strip.setBorder(BorderFactory.createTitledBorder("Strip " + i));
strip.add(new JLabel("Strip " + i));
mainPanel.add(strip);
}
JPanel gamearea = new JPanel();
gamearea.setLayout(null);
mainPanel.add(gamearea);
for (int i = 0; i < 5; i++) {
int x = i * 100, y = i * 100;
JPanel basket = new JPanel();
basket.setSize(200, 50);
basket.setLocation(x, y);
basket.setBackground(Color.YELLOW);
basket.add(new JLabel("x = " + x + ", y = " + y));
gamearea.add(basket);
}
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(mainPanel);
frame.pack();
frame.setResizable(false);
frame.setSize(600, 600);
frame.setVisible(true);
}
}

Why setPreferredSize does not change the size of the button?

Here is the code:
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class TestGrid {
public static void main(String[] args) {
JFrame frame = new JFrame("Colored Trails");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(4, 9));
panel.setMaximumSize(new Dimension(9*30-20,4*30));
JButton btn;
for (int i=1; i<=4; i++) {
for (int j=1; j<=4; j++) {
btn = new JButton();
btn.setPreferredSize(new Dimension(30, 30));
panel.add(btn);
}
btn = new JButton();
btn.setPreferredSize(new Dimension(30, 10));
panel.add(btn);
for (int j=1; j<=4; j++) {
btn = new JButton();
btn.setPreferredSize(new Dimension(30, 30));
panel.add(btn);
}
}
mainPanel.add(panel);
frame.add(mainPanel);
frame.setSize(450,950);
frame.setVisible(true);
}
}
I suppose to have a table of buttons with 4 rows and 9 columns. And the middle column should be narrower that other columns. I tried Dimension(30, 10) and Dimension(30, 10) both have no effect on the width of the middle column. Why?
Layout managers are free to ignore the preferred size. Specifically, GridLayout will always make each cell in the grid exactly the same size (it's a pretty useless layout manager for that reason).
You'll have to use a different layout manager, such as nested BoxLayout or a GroupLayout.
GridLayout is quite inflexible in that each and every cell is the same size, typically honoring the largest height and width settings of any object added to the grid.
If the rows and/or columns need to have varying sizes you should use GridBagLayout.
setPreferredSize will not change the size of the button until dimension is set by using Dimension.
Example:-
Dimension dim = new Dimension(20,20), then use setPerferredSize(dim).

Categories