Update Grid in GridLayout - java

I have an array of objects laid out through a GridLayout in a JPanel. I need to be able to recreate the object in an index in the array and have the GridLayout update to reflect this. As of yet, I cannot find anyway to "refresh" or redraw the GridLayout. Is it possible to refresh a GridLayout without creating the entire GridLayout or JPanel? Assume I do not have access to JFrame.
import javax.swing.*;
import java.awt.*;
public class Test
{
public static void main(String args[])
{
JFrame frame = new JFrame();
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(5,5));
JLabel[][] labels = new JLabel[5][5];
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
{
labels[j][i] = new JLabel("("+j+", "+i+")");
panel.add(labels[j][i]);
}
}
labels[0][0] = new JLabel("Hello World");
//Without doing it this way (cause my objects can't do this)
//labels[0][0].setText("Hello World!");
frame.add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setResizable(false);
frame.setVisible(true);
}
}

I don't understand why you can't just update the text on the label.
Why do you need to "recreate the object"? It makes no sense. But if you really need to do this then the code would be something like:
panel.remove(0);
panel.add(theNewLabel, 0);
panel.revalidate();
panel.repaint();

Related

How to place an array of JPanels into JScrollPane?

When I placed an array into mainJpanel it works correctly. I want to place an array into JScrollPane but it does not work. Please explain why.
import javax.swing.*;
import java.awt.*;
public class Window extends JFrame {
public Window() {
setLocation( 100,100);
setSize(300,300);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setTitle("FontView");
setVisible(true);
setLayout( new FlowLayout());
JPanel mainPanel = new JPanel();
setContentPane(mainPanel);
Method fontMassive = new Method();
//поехали
JPanel[] jPanels = new JPanel[3];
JLabel[] jLabels = new JLabel[3];
for (int i = 0; i < 3; i++) {
jPanels[i]=new JPanel();
jLabels[i] = new JLabel(fontMassive.getFonts(i));
jPanels[i].add(jLabels[i]);
}
JScrollPane scroll = new JScrollPane();
for (int i = 0; i < 3; i++) {
scroll.add(jPanels[i]);
}
mainPanel.add(scroll);
}
}
placed into mainPanel
placed into scroll
Just another Java programmer 's answer was right, i need to place an array into Panel and then place it into Srcoll.
Thank you guys for the answers.

Adding JButton by loop causes last Button to be oversized

When I create a button using a loop, the last button has the size of the whole frame. How can I fix this?
package test;
import java.awt.*;
import javax.swing.*;
public class test{
private JFrame frame;
private static JButton[][] buttons = new JButton[4][4];
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
test window = new test();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public test() {
initialize();
}
private void initialize() {
frame = new JFrame();
frame.setBounds(200, 200, 600, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
for(int i=0; i < 4; i++){
for(int j=0; j < 4; j++){
JButton btn = new JButton("" + i+j);
btn.setBounds(60*i,60*j,60,60);
if((i+j)%2==1)
btn.setBackground(Color.BLACK);
buttons[i][j] = btn;
frame.add(btn);
}
}
}
}
Don't use setBounds(...) on the buttons. It is the job of the layout manager to determine the size/location of a component. The default layout manager for a JFrame is a BorderLayout. Only a single component can be added to the CENTER of the BorderLayout, so only the size/location of the last button added is being managed by the BorderLayout and the other buttons are ignored.
Use a different layout manager. I suspect you should be using the GridLayout. Read the section from the Swing tutorial on Using Layout Managers for more information and working examples.
Don't use setBounds on the frame either. After you add the buttons to the frame and before you invoke setVisible(..) you should use frame.pack() so the buttons will be displayed at their preferred size.
This looks like a good use for the Grid Bag Layout manager. Try something like this:
First, you need to import the GridBagConstraints class.
import java.awt.GridBagConstraints;
And then just make these changes to your for loops.
for(int i=0; i < 4; i++){
for(int j=0; j < 4; j++){
JButton btn = new JButton("" + i+j);
//btn.setBounds(60*i,60*j,60,60);
if((i+j)%2==1)
btn.setBackground(Color.BLACK);
buttons[i][j] = btn;
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = i;
gbc.gridy = j;
frame.add(btn, gbc);
}
}
The Grid Bag Layout manager is pretty tricky, but once you understand how it works, it's really useful. You can check out this tutorial on Oracle for more information.
Hope that helps.

Java JPanels not visible in Frame

Can someone please explain why my frame only shows p2 and not p1?
This happens to me often and I know I'm missing something.
public class Exercise_16_4 extends JFrame {
private static final long serialVersionUID = 1L;
JLabel[] labels = new JLabel[3];
JTextField[] textFields = new JTextField[3];
JButton[] buttons = new JButton[4];
String[] buttonText = {"Add", "Subtract", "Multiply", "Divide"};
String[] labelText = {"Number 1", "Number 2", "Result"};
JPanel p1 = new JPanel();
JPanel p2 = new JPanel();
public Exercise_16_4() {
for (int i = 0; i < labels.length; i++) {
labels[i] = new JLabel(labelText[i]);
textFields[i] = new JTextField();
p1.add(labels[i]);
p1.add(textFields[i]);
}
for (int i = 0; i < buttons.length; i++) {
buttons[i] = new JButton(buttonText[i]);
p2.add(buttons[i]);
}
add(p1);
add(p2);
}
public static void main(String[] args) {
Exercise_16_4 frame = new Exercise_16_4();
frame.setTitle("Exercise 16.4");
frame.pack();
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}//main
}//class
The default layout manager for the content pane of a JFrame is a BorderLayout.
By default when you add a component to the frame is will be added to the CENTER of the BorderLayout. The problem is only one component can be added so only the last one added is displayed.
You can try something like:
add(p1, BorderLayout.NORTH);
Or you can create a JPanel add the p1, p2 components to the panel and then add the panel to the frame.
Read the section from the Swing tutorial on Layout Managers for more information and examples of using layout managers as well as examples that show you how to create the GUI on the Event Dispatch Thread.

Java GridBagLayout and JPanel Error: cannot add to layout: constraint must be a string (or null) [duplicate]

This question already has an answer here:
getting Exception : java.lang.IllegalArgumentException: cannot add to layout: constraint must be a string (or null)
(1 answer)
Closed 9 years ago.
I have researched this error and I cannot seem to find a solution. I am trying to create a grid of 800 JButtons with 40 columns and 20 rows. This will eventually be used to control a domino setting up robot I am making that will tip over dominoes. I have already successfully created a grid using GridLayout, but due to the nature of the project, I would like every other row to be offset by half a button. By this I mean like how keys on a computer keyboard are set up. (I would have added a helpful picture of what I am trying to explain, but apparently beginners who have trouble explaining things aren't allowed to add pictures, whatever).
I try to do this by creating a JPanel array of 20 panels called panel. Then I add to the panel the 40 JButtons. Then I use GridBagConstraints to offset every other row. I read that you shouldn't mix awt and swing so that could be the problem, but i don't know. Here is the code, I figured this out from youtube tutorials as I am a very beginner. Forgive me if anything I have said does not make sense. Code:
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
public class OffsetGrid {
public static void main (String [] args){
JFrame Frame = new JFrame();
Frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GridLayout grid= new GridLayout();
GridBagConstraints gbca= new GridBagConstraints();
GridBagConstraints gbcb= new GridBagConstraints();
JPanel[] panel=new JPanel[20];
for (int row=0;row<20; row++){
panel[row]=new JPanel(new GridBagLayout());
gbca.gridx=1;
gbca.gridy=row;
gbcb.gridx=0;
gbcb.gridy=row;
for (int y=0; y<40;y++){
grid=new GridLayout(1,40);
panel[row].setLayout(grid);
JButton[] button = new JButton[40];
button[y]=new JButton();
button[y].setOpaque(true);
panel[row].add(button[y]);
}
if (row%2==0){
Frame.add(panel[row], gbcb);
}
else {
Frame.add(panel[row], gbca);
}
}
Frame.setVisible(true);
Frame.setLocationRelativeTo(null);
Frame.pack();
}
}
error:
Exception in thread "main" java.lang.IllegalArgumentException: cannot add to layout: constraint must be a string (or null)
at java.awt.BorderLayout.addLayoutComponent(BorderLayout.java:426)
at javax.swing.JRootPane$1.addLayoutComponent(JRootPane.java:531)
at java.awt.Container.addImpl(Container.java:1120)
at java.awt.Container.add(Container.java:998)
at javax.swing.JFrame.addImpl(JFrame.java:562)
at java.awt.Container.add(Container.java:966)
at OffsetGrid.main(OffsetGrid.java:38)
Please help me figure out the problem and get it working. Thanks
edit: I am still confused on exactly how to use gridbagconstraints so I don't even know if gridy and gridx are even the right things to use here. Or even if i should use gridbagconstraints. Please offer any suggestions to get the job done. Thanks
edit: this seems to work.
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
public class OffsetGrid {
public static void main (String [] args){
JFrame Frame = new JFrame();
Frame.setLayout(new GridBagLayout());
Frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GridLayout grid= new GridLayout();
GridBagConstraints gbca= new GridBagConstraints();
GridBagConstraints gbcb= new GridBagConstraints();
JPanel[] panel=new JPanel[20];
for (int row=0;row<20; row++){
panel[row]=new JPanel(new GridBagLayout());
gbca.insets=new Insets(0,100,0,0);
gbca.gridy=row;
gbcb.insets=new Insets(0,0,0,0);
gbcb.gridy=row;
for (int y=0; y<40;y++){
grid=new GridLayout(1,40);
panel[row].setLayout(grid);
JButton[] button = new JButton[40];
button[y]=new JButton();
button[y].setOpaque(true);
panel[row].add(button[y]);
}
if (row%2==0){
Frame.add(panel[row], gbcb);
}
else {
Frame.add(panel[row], gbca);
}
}
Frame.setVisible(true);
Frame.setLocationRelativeTo(null);
Frame.pack();
}
}
You did this:
Frame.add(panel[row], gbcb);
But you forgot to set the frame's layout:
JFrame Frame = new JFrame();
Frame.setLayout(new GridBagLayout());
Now the exception is not thrown. However......
I wonder if this is what you want:
I've made some change to my code in the case that user resize the window. You can still find the older code in revision
import static javax.swing.BorderFactory.createEmptyBorder;
import java.awt.GridLayout;
import java.awt.event.*;
import javax.swing.*;
public class OffsetGrid {
public static final int ROWS = 10;
public static final int COLUMNS = 10;
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setLayout(new GridLayout(ROWS, 1));
final JPanel[] panel = new JPanel[ROWS];
final JButton[][] button = new JButton[ROWS][COLUMNS];
for (int row = 0; row < ROWS; row++) {
panel[row] = new JPanel(new GridLayout(1, COLUMNS));
for (int y = 0; y < COLUMNS; y++) {
button[row][y] = new JButton(row + "-" + y);
button[row][y].setOpaque(true);
panel[row].add(button[row][y]);
}
int padding = button[row][0].getPreferredSize().width / 2;
if (row % 2 == 0)
panel[row].setBorder(createEmptyBorder(0, 0, 0, padding));
else
panel[row].setBorder(createEmptyBorder(0, padding, 0, 0));
frame.add(panel[row]);
}
frame.addComponentListener(new ComponentAdapter() {
#Override
public void componentResized(ComponentEvent e) {
for (int row = 0; row < ROWS; row++) {
int padding = button[row][0].getSize().width / 2;
panel[row].setBorder(createEmptyBorder(0, 0, 0, padding));
if (++row == ROWS)
break;
padding = button[row][0].getSize().width / 2;
panel[row].setBorder(createEmptyBorder(0, padding, 0, 0));
}
}
});
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}

grid layout panels in a jframe

How would i be able to use gridlayout and panels to create a frame that resembles a checkered board pattern? it would seem that i can't create two panels with two diferent colors within the one for-loop.
import javax.swing.*;
import java.awt.*;
#SuppressWarnings("serial")
public class test extends JFrame {
public test() {
this.setSize(400, 400);
JPanel content = new JPanel(new GridLayout(4,4));
for(int i = 0; i < 8; i++) {
JPanel panel = new JPanel();
panel.setBackground(Color.RED);
content.add(panel);
JPanel panel2 = new JPanel();
panel.setBackground(Color.BLUE);
content.add(panel2);
}
// for(int i = 0; i < 8; i++) {
// JPanel panel = new JPanel();
// panel.setBackground(Color.BLUE);
// content.add(panel);
// }
this.add(content);
}
public static void main(String[] args) {
test app = new test();
app.setVisible(true);
app.setResizable(false);
app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
#SuppressWarnings("serial")
static class Test extends JFrame {
public Test() {
this.setSize(400, 400);
int size = 8;
JPanel content = new JPanel(new GridLayout(size,size));
for (int i = 0; i < size*size; ++i) {
JPanel panel = new JPanel();
panel.setBackground( i % 2 == i/size % 2 ? Color.RED : Color.BLUE);
content.add(panel);
}
this.add(content);
}
}
You can work directly on indices, you have to switch between colors every cell and starting for a different color for every row.
Typo (note the 2 in panel2):
panel2.setBackground(Color.BLUE);

Categories

Resources