I working on this assignment and I have a problem where I need to add this matrix to a JPanel. I made the matrix in another method because I thought it would be easier but can't find a solution. I also used this layout by following a tutorial on Oracles website if it look familiar.
The text also needs to be editable which is why I have buttons. I don't have there functions here either.
public static void addComponentsToPane(Container pane) {
if (RIGHT_TO_LEFT) {
pane.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
}
JPanel array;
JButton button;
pane.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
if (shouldFill) {
c.fill = GridBagConstraints.HORIZONTAL;
}
button = new JButton("Reset to 0");
pane.add(button, c);
// WHERE IT NEEDS TO BE ADDED***********************
array = new JPanel();
pane.add(array, c);
}
private static void createAndShowGUI() {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addComponentsToPane(frame.getContentPane());
frame.pack();
frame.setVisible(true);
}
public int[][] getRandomMatrix() {
int[][] randomMatrix = new int[10][10];
for (int r = 0; r < randomMatrix.length; r++) {
for (int c = 0; c < randomMatrix[r].length; c++) {
randomMatrix[r][c] = (int)(Math.random() * 2);
}
}
return randomMatrix;
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
From the question you outline, it looks like you want to add an additional method to JPanel.
Ok, that would require you to create a custom instance of a JPanel like this:
public class MyPanel extends JPanel {
public MyPanel() {
super();
}
public int[][] getRandomMatrix() {
int[][] randomMatrix = new int[10][10];
for (int r = 0; r < randomMatrix.length; r++) {
for (int c = 0; c < randomMatrix[r].length; c++) {
randomMatrix[r][c] = (int)(Math.random() * 2);
}
}
return randomMatrix;
}
}
And instead of adding a pre-rolled JPanel to the frame, you would add an instance of 'MyPanel' to the frame instead.
public static void addComponentsToPane(Container pane) {
if (RIGHT_TO_LEFT) {
pane.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
}
MyPanel array;
JButton button;
pane.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
if (shouldFill) {
c.fill = GridBagConstraints.HORIZONTAL;
}
button = new JButton("Reset to 0");
pane.add(button, c);
array = new MyPanel();
pane.add(myPanel, c);
}
private static void createAndShowGUI() {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addComponentsToPane(frame.getContentPane());
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
Related
I'm trying to create Connect 4 game which would look like on this picture:
I've been able to create a gridlayout with 42 buttons and now I need to add Reset button. I believe that I need to combine 2 layouts in one frame but I dont know how to do that and cant find any answer anywhere.
Thank you for your help and time.
public class ApplicationRunner {
public static void main(String[] args) {
new ConnectFour();
}
}
import javax.swing.*;
import java.awt.*;
public class ConnectFour extends JFrame {
private String buttonLbl = "X";
HashMap<String, JButton> buttons;
public ConnectFour() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(600, 600);
setTitle("Connect Four");
setLocationRelativeTo(null);
JButton resetButton = new JButton();
resetButton.setName("reset button");
resetButton.setText("Reset");
for (int i = 6; i > 0; i--) {
for (char c = 'A'; c <= 'G'; c++) {
String cell = "" + c + i;
JButton cellButton = new JButton(" ");
cellButton.setBackground(Color.LIGHT_GRAY);
cellButton.setName("Button" + cell);
add(cellButton);
}
}
GridLayout gl = new GridLayout(6, 7, 0, 0);
setLayout(gl);
setVisible(true);
}
}
One solution is to use two JPanel instances (with each having its own LayoutManager).
Then you add these two JPanel instances to your JFrame.
Example:
public class MyApplication extends JFrame {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
MyApplication app = new MyApplication();
app.setVisible(true);
}
});
}
private MyApplication() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(600, 600);
setTitle("Connect Four");
setLocationRelativeTo(null);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.Y_AXIS));
JButton resetButton = new JButton();
resetButton.setName("reset button");
resetButton.setText("Reset");
resetButton.setAlignmentX(Component.RIGHT_ALIGNMENT);
buttonPanel.add(resetButton);
// add buttonPanel to JFrame
add(buttonPanel, BorderLayout.SOUTH);
JPanel mainPanel = new JPanel(new GridLayout(6, 7, 0, 0));
for (int i = 6; i > 0; i--) {
for (char c = 'A'; c <= 'G'; c++) {
String cell = "" + c + i;
JButton cellButton = new JButton(" ");
cellButton.setBackground(Color.LIGHT_GRAY);
cellButton.setName("Button" + cell);
mainPanel.add(cellButton);
}
}
// add mainPanel to JFrame
add(mainPanel, BorderLayout.CENTER);
setVisible(true);
}
}
Problem: below some code to make a frame filled with buttons. After the button is clicked, I would need to know the coordinates of the button clicked. The program will afterwards check the status of that specific tile and depending on the status it should change to a certain color. I'm having some issues when retracting this coordinate, could someone help me? (I'm only just learning how to program in Java, so my code might not be ideal)
Code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GUIBoard {
JPanel buttonPanel = new JPanel();
JButton button = new JButton();
JFrame frame;
ButtonClicked clicked = new ButtonClicked();
public GUIBoard(String title, int nbRows, int nbColumns) {
frame = new JFrame(title);
buttonPanel.setLayout(new GridLayout(nbRows, nbColumns));
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;
for (int i = 0; i < nbRows; i++) {
for(int j = 0; j < nbColumns; j++) {
button = new JButton();
button.setBackground(Color.LIGHT_GRAY);
button.addActionListener(clicked);
gbc.gridx = j;
gbc.gridy = i;
buttonPanel.add(button, gbc);
}
}
frame.setPreferredSize(new Dimension(1000, 600));
frame.getContentPane().add(buttonPanel, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
private class ButtonClicked implements ActionListener{
#Override
public void actionPerformed(ActionEvent e) {
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run(){
new GUIBoard("Batlleship Board", 10,10);
}
});
}
}
If by coordinates you mean the actualx and y placement location of the button clicked upon then you can use this within your buttons ActionPerformed event:
public void actionPerformed(ActionEvent e) {
JButton btn = (JButton)e.getSource();
System.out.println(btn.getX() + ", " + btn.getY());
}
Will print the top left location of the button clicked upon. This isn't very helpful however since these locations can change if the Form is resized in any way.
If you mean by grid location as in the row and column of the button clicked upon then the easiest would be to ensure that an identifier is applied to each of the buttons by placing the grid location into the buttons Name property, when creating your buttons, for example:
for (int i = 0; i < nbRows; i++) {
for (int j = 0; j < nbColumns; j++) {
button = new JButton();
// Apply an identifier to the Button:
button.setName(new StringBuilder("Button_").append(i)
.append(",").append(j).toString());
button.setBackground(Color.LIGHT_GRAY);
button.addActionListener(clicked);
gbc.gridx = j;
gbc.gridy = i;
buttonPanel.add(button, gbc);
}
}
Then in your buttons ActionPerformed event:
public void actionPerformed(ActionEvent e) {
JButton btn = (JButton)e.getSource();
System.out.println(btn.getName());
}
Now that I think I have understood what you want to do I am going to give you a new and easier approach:
Here is the code, you just need to use the method getSource() to get an instance of the button which has been pressed. Then you change the color.
public class GUIBoar {
JPanel buttonPanel = new JPanel();
JButton button = new JButton();
JFrame frame;
public GUIBoar(String title, int nbRows, int nbColumns) {
frame = new JFrame(title);
buttonPanel.setLayout(new GridLayout(nbRows, nbColumns));
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;
for (int i = 0; i < nbRows; i++) {
for (int j = 0; j < nbColumns; j++) {
button = new JButton();
button.setBackground(Color.LIGHT_GRAY);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e){
Object source = e.getSource();
JButton b = (JButton)source;
b.setBackground(Color.RED); //IMAGINE THATS THE COLOR
}
});
gbc.gridx = j;
gbc.gridy = i;
buttonPanel.add(button, gbc);
}
}
frame.setPreferredSize(new Dimension(1000, 600));
frame.getContentPane().add(buttonPanel, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new GUIBoar("Batlleship Board", 10, 10);
}
});
}
}
Hey I could use help debugging this program. The code is not mine, it is from an answer to a question and I wanted to try it but I get a NullPointerException and can't figure out where the problem is. I think the problem may be image paths but I am not sure so I could use help.
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.border.*;
public class CircleImages {
private int score = 0;
private JTextField scoreField = new JTextField(10);
public CircleImages() {
scoreField.setEditable(false);
final ImageIcon[] icons = createImageIcons();
final JPanel iconPanel = createPanel(icons, 8);
JPanel bottomLeftPanel = new JPanel(new FlowLayout(FlowLayout.LEADING));
bottomLeftPanel.add(new JLabel("Score: "));
bottomLeftPanel.add(scoreField);
JPanel bottomRightPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING));
JButton newGame = new JButton("New Game");
bottomRightPanel.add(newGame);
JButton quit = new JButton("Quit");
bottomRightPanel.add(quit);
JPanel bottomPanel = new JPanel(new GridLayout(1, 2));
bottomPanel.add(bottomLeftPanel);
bottomPanel.add(bottomRightPanel);
newGame.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
reset(iconPanel, icons);
score = 0;
scoreField.setText(String.valueOf(score));
}
});
JFrame frame = new JFrame();
frame.add(iconPanel);
frame.add(bottomPanel, BorderLayout.PAGE_END);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void reset(JPanel panel, ImageIcon[] icons) {
Component[] comps = panel.getComponents();
Random random = new Random();
for(Component c : comps) {
if (c instanceof JLabel) {
JLabel button = (JLabel)c;
int index = random.nextInt(icons.length);
button.setIcon(icons[index]);
}
}
}
private JPanel createPanel(ImageIcon[] icons, int gridSize) {
Random random = new Random();
JPanel panel = new JPanel(new GridLayout(gridSize, gridSize));
for (int i = 0; i < gridSize * gridSize; i++) {
int index = random.nextInt(icons.length);
JLabel label = new JLabel(icons[index]);
label.addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent e) {
score += 1;
scoreField.setText(String.valueOf(score));
}
});
label.setBorder(new LineBorder(Color.GRAY, 2));
panel.add(label);
}
return panel;
}
private ImageIcon[] createImageIcons() {
String[] files = {"DarkGrayButton.png",
"BlueButton.png",
"GreenButton.png",
"LightGrayButton.png",
"OrangeButton.png",
"RedButton.png",
"YellowButton.png"
};
ImageIcon[] icons = new ImageIcon[files.length];
for (int i = 0; i < files.length; i++) {
icons[i] = new ImageIcon(getClass().getResource("/circleimages/" + files[i]));
}
return icons;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new CircleImages();
}
});
}
}
Your problem is here:
icons[i] = new ImageIcon(getClass().getResource("/circleimages/" + files[i]));
You don't have the required images in your project, so getClass().getResource() will return null and you will have a NullPointerException in the constructor of ImageIcon.
What you have to do is put the following files in your project:
/circleimages/DarkGrayButton.png
/circleimages/BlueButton.png
/circleimages/GreenButton.png
/circleimages/LightGrayButton.png
/circleimages/OrangeButton.png
/circleimages/RedButton.png
/circleimages/YellowButton.png
I am having problems understanding how to use an actionlistener to change the value of variables.
In my program I need to store the choices the user makes by selecting some radio buttons.
I have got a main class with a card layout, then several classes which each are different panels. In one of the panels I have some radio buttons, with an actionlistener as an inner class.
When I try to print the variable value in the main class, it is printed immediately, before the user has made a choice, as I instantiate the panel class and get the variable from it I get the variable before it has been changed by the user.
I know I should not think in a linear manner with Java, but how can I make sure that I fetch the variable after it has been changed by the user and not before? I will not be able to do that will I? I understand there is some flaw in my thinking but I haven't slept properly for ages and I just cannot get my head around this.
public class Screen3 extends JPanel{
JRadioButton addition = new JRadioButton("Addition");
JRadioButton subtraction = new JRadioButton("Subtraction");
JRadioButton multiplication = new JRadioButton("Multiplication");
JRadioButton division = new JRadioButton("Division");
JRadioButton all = new JRadioButton("All");
JRadioButton single = new JRadioButton("Single");
JRadioButton two = new JRadioButton("Double");
JRadioButton triple = new JRadioButton("Triple");
JRadioButton mix = new JRadioButton("Mix");
JRadioButton five = new JRadioButton("5");
JRadioButton ten = new JRadioButton("10");
private int type, digit, rounds;
public Screen3() {
JPanel firstButtonPanel = new JPanel();
JPanel secondButtonPanel = new JPanel();
ButtonGroup myFirstGroup = new ButtonGroup();
ButtonGroup mySecondGroup = new ButtonGroup();
myFirstGroup.add(addition);
myFirstGroup.add(subtraction);
myFirstGroup.add(multiplication);
myFirstGroup.add(division);
//myFirstGroup.add(all);
mySecondGroup.add(single);
mySecondGroup.add(two);
mySecondGroup.add(triple);
//mySecondGroup.add(mix);
firstButtonPanel.setLayout(new FlowLayout());
firstButtonPanel.add(addition);
firstButtonPanel.add(subtraction);
firstButtonPanel.add(multiplication);
firstButtonPanel.add(division);
//firstButtonPanel.add(all);
secondButtonPanel.setLayout(new FlowLayout());
secondButtonPanel.add(single);
secondButtonPanel.add(two);
secondButtonPanel.add(triple);
//secondButtonPanel.add(mix);
JPanel buttons = new JPanel();
buttons.setLayout(new BorderLayout());
buttons.add(selectionLabel, BorderLayout.NORTH);
buttons.add(firstButtonPanel, BorderLayout.CENTER);
buttons.add(secondButtonPanel, BorderLayout.SOUTH);
ButtonGroup myThirdGroup = new ButtonGroup();
JPanel endButtons = new JPanel();
myThirdGroup.add(five);
myThirdGroup.add(ten);
endButtons.add(five);
endButtons.add(ten);
endPanel.setLayout(new BorderLayout());
endPanel.add(rounds, BorderLayout.NORTH);
endPanel.add(endButtons, BorderLayout.CENTER);
setLayout(new BorderLayout());
add(buttons, BorderLayout.NORTH);
Selection sn = new Selection();
addition.addActionListener(sn);
subtraction.addActionListener(sn);
multiplication.addActionListener(sn);
division.addActionListener(sn);
single.addActionListener(sn);
two.addActionListener(sn);
triple.addActionListener(sn);
five.addActionListener(sn);
ten.addActionListener(sn);
}
public int getType() {
return type;
}
public int getDigit() {
return digit;
}
public int getRounds() {
return rounds;
}
public class Selection implements ActionListener {
public void actionPerformed(ActionEvent e) {
if(addition.isSelected()) {
type = 1;
}
else if(subtraction.isSelected()) {
type = 2;
}
else if(multiplication.isSelected())
type = 3;
else if(division.isSelected())
type = 4;
//else if(all.isSelected())
//type = 5;
if(single.isSelected()) {
digit = 1;
System.out.println("single");
}
else if(two.isSelected())
digit = 2;
else if(triple.isSelected())
digit = 3;
if(five.isSelected())
rounds = 5;
else if(ten.isSelected())
rounds = 10;
}
}
}
Here is the main class:
public class Driver {
public JFrame frame = new JFrame("Math Game");
public JPanel screens = new JPanel(new CardLayout());
int digit = 1;
int rounds = 1;
int type = 1;
Driver() {
}
public void show() {
JPanel buttonPanel = new JPanel();
JButton next = new JButton("Next");
JButton previous = new JButton("Previous");
buttonPanel.add(previous);
buttonPanel.add(next);
Screen1 screen1 = new Screen1();
Screen2 screen2 = new Screen2();
Screen3 screen3 = new Screen3();
screens.add(screen1, "welcome");
screens.add(screen2, "next");
screens.add(screen3, "selection");
frame.add(screens);
frame.add(buttonPanel, BorderLayout.PAGE_END);
frame.setSize(400, 500);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
next.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
CardLayout cl = (CardLayout)(screens.getLayout());
cl.next(screens);
}
});
previous.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
CardLayout cl = (CardLayout)(screens.getLayout());
cl.previous(screens);
}
});
}
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
Driver dr = new Driver();
dr.show();
}
});
}
}
I just try a test print of System.out.println(screen3.getType()); either in show() or main
Use JOptionPane/JDialog which has modality.
Have a read on How to Make Dialogs
In example here is only printed after JDialog is closed:
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JDialog jd = new JDialog();
jd.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
jd.setModal(true);
jd.pack();
jd.setVisible(true);
System.out.println("Here");
}
});
}
In this example here is only printed after JOptionPane is closed:
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JPanel panel=new JPanel();
panel.add(new JLabel("Hello, world!"));
JOptionPane.showMessageDialog(null, panel, "Panel Message",JOptionPane.PLAIN_MESSAGE);
System.out.println("Here");
}
});
}
I know I should not think in a linear manner with Java, but how can I
make sure that I fetch the variable after it has been changed by the
user and not before?
After using a modal JDialog/JOptionPane you would simply use public getters to access the variable contained within the class instance:
public class Test {
public static void main(String[] args) {
X x= new X();//will only return after dialog closed
System.out.println(x.getY());
}
}
class X {
private int y=0;//will be assigned during dialog/joptionpanes life span
public X() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
//creates and shows the modal dialog/optionpane which will allow modification of variable y through some input/controls
}
});
}
public int getY() {
return y;
}
}
I am trying to dynamically generate a form. Basically, I want to load a list of items for purchase, and generate a button for each. I can confirm that the buttons are being generated with the debugger, but they aren't being displayed. This is inside a subclass of JPanel:
private void generate() {
JButton b = new JButton("height test");
int btnHeight = b.getPreferredSize().height;
int pnlHeight = this.getPreferredSize().height;
int numButtons = pnlHeight / btnHeight;
setLayout(new GridLayout(numButtons, 1));
Iterator<Drink> it = DrinkMenu.iterator();
for (int i = 0; i <= numButtons; ++i) {
if (!it.hasNext()) {
break;
}
final Drink dr = it.next();
b = new DrinkButton(dr);
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
order.addDrink(dr);
}});
add(b);
}
revalidate();
}
DrinkButton is a subclass of JButton. Any ideas?
example about validate() revalidate() plus repaint(), look like as required for correct output to the GUI, layed by some of LayourManagers
EDIT: as trashgod noticed, I added Schedule a job for the EDT
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ValidateRevalidateRepaint {
private JPanel panel;
private GridBagConstraints gbc;
private boolean validate, revalidate, repaint;
public ValidateRevalidateRepaint() {
validate = revalidate = repaint = false;
panel = new JPanel(new GridBagLayout());
gbc = new GridBagConstraints();
gbc.insets = new Insets(0, 20, 0, 20);
panel.add(getFiller(), gbc);
JFrame f = new JFrame();
f.setJMenuBar(getMenuBar());
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(panel);
f.getContentPane().add(getRadioPanel(), "East");
f.getContentPane().add(getCheckBoxPanel(), "South");
f.setSize(400, 200);
f.setLocation(200, 200);
f.setVisible(true);
}
private JMenuBar getMenuBar() {
JMenu menu = new JMenu("change");
ActionListener l = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JMenuItem item = (JMenuItem) e.getSource();
int n = Integer.parseInt(item.getActionCommand());
makeChange(n);
}
};
for (int j = 1; j < 5; j++) {
String s = String.valueOf(j) + " component";
if (j > 1) {
s += "s";
}
JMenuItem item = new JMenuItem(s);
item.setActionCommand(String.valueOf(j));
item.addActionListener(l);
menu.add(item);
}
JMenuBar menuBar = new JMenuBar();
menuBar.add(menu);
return menuBar;
}
private JPanel getRadioPanel() {
JPanel panel1 = new JPanel(new GridBagLayout());
GridBagConstraints gbc1 = new GridBagConstraints();
gbc1.insets = new Insets(2, 2, 2, 2);
gbc1.weighty = 1.0;
gbc1.gridwidth = GridBagConstraints.REMAINDER;
ButtonGroup group = new ButtonGroup();
ActionListener l = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JRadioButton radio = (JRadioButton) e.getSource();
int n = Integer.parseInt(radio.getActionCommand());
makeChange(n);
}
};
for (int j = 0; j < 4; j++) {
String s = String.valueOf(j + 1);
JRadioButton radio = new JRadioButton(s);
radio.setActionCommand(s);
radio.addActionListener(l);
group.add(radio);
panel1.add(radio, gbc1);
}
return panel1;
}
private JPanel getCheckBoxPanel() {
final String[] operations = {"validate", "revalidate", "repaint"};
ActionListener l = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JCheckBox checkBox = (JCheckBox) e.getSource();
String ac = checkBox.getActionCommand();
boolean state = checkBox.isSelected();
if (ac.equals("validate")) {
validate = state;
}
if (ac.equals("revalidate")) {
revalidate = state;
}
if (ac.equals("repaint")) {
repaint = state;
}
}
};
JPanel panel2 = new JPanel();
for (int j = 0; j < operations.length; j++) {
JCheckBox check = new JCheckBox(operations[j]);
check.setActionCommand(operations[j]);
check.addActionListener(l);
panel2.add(check);
}
return panel2;
}
private void makeChange(int number) {
panel.removeAll();
for (int j = 0; j < number; j++) {
panel.add(getFiller(), gbc);
}
if (validate) {
panel.validate();
}
if (revalidate) {
panel.revalidate();
}
if (repaint) {
panel.repaint();
}
}
private JPanel getFiller() {
JPanel panel3 = new JPanel();
panel3.setBackground(Color.red);
panel3.setPreferredSize(new Dimension(40, 40));
return panel3;
}
public static void main(String[] args) {//added Schedule a job for the EDT
javax.swing.SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
ValidateRevalidateRepaint rVR = new ValidateRevalidateRepaint();
}
});
}
}
Works on my computer...
public class Panel extends JPanel {
public Panel() {
setLayout(new java.awt.GridLayout(4, 4));
for (int i = 0; i < 16; ++i) {
JButton b = new JButton(String.valueOf(i));
b.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e) {
//...
}
});
add(b);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run(){
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(new Dimension(300, 300));
frame.add(new Panel());
frame.setVisible(true);
}
});
}
}
As far as I remember your version was working as well, although I had to remove your "drinking" code. Start from this example (it shows nice 4x4 grid of buttons) and determine what is wrong with your code.
You can use revalidate(), as shown in this example.
Addendum: Here's my variation on #mKorbel's interesting answer that shows a similar result for GridLayout. It looks like repaint() may be necessary after revalidate().
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/** #see https://stackoverflow.com/questions/6395105 */
public class ValidateRevalidateRepaint {
private JPanel center;
private boolean validate = false;
private boolean revalidate = true;
private boolean repaint = true;
public ValidateRevalidateRepaint() {
center = new JPanel(new GridLayout(1, 0, 10, 10));
JFrame f = new JFrame();
f.setTitle("VRR");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(center, BorderLayout.CENTER);
f.add(getRadioPanel(), BorderLayout.EAST);
f.add(getCheckBoxPanel(), BorderLayout.SOUTH);
makeChange(4);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private JPanel getRadioPanel() {
JPanel panel = new JPanel(new GridLayout(0, 1));
ButtonGroup group = new ButtonGroup();
ActionListener l = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JRadioButton radio = (JRadioButton) e.getSource();
int n = Integer.parseInt(radio.getActionCommand());
makeChange(n);
}
};
for (int j = 0; j < 4; j++) {
String s = String.valueOf(j + 1);
JRadioButton radio = new JRadioButton(s);
radio.setActionCommand(s);
radio.addActionListener(l);
group.add(radio);
panel.add(radio);
if (j == 3) {
group.setSelected(radio.getModel(), true);
}
}
return panel;
}
private JPanel getCheckBoxPanel() {
final String[] operations = {"validate", "revalidate", "repaint"};
ActionListener l = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JCheckBox checkBox = (JCheckBox) e.getSource();
String ac = checkBox.getActionCommand();
boolean state = checkBox.isSelected();
if (ac.equals("validate")) {
validate = state;
}
if (ac.equals("revalidate")) {
revalidate = state;
}
if (ac.equals("repaint")) {
repaint = state;
}
}
};
JPanel panel = new JPanel();
for (int j = 0; j < operations.length; j++) {
JCheckBox check = new JCheckBox(operations[j]);
if (j == 0) {
check.setSelected(false);
} else {
check.setSelected(true);
}
check.setActionCommand(operations[j]);
check.addActionListener(l);
panel.add(check);
}
return panel;
}
private void makeChange(int number) {
center.removeAll();
for (int j = 0; j < number; j++) {
center.add(getFiller());
}
if (validate) {
center.validate();
}
if (revalidate) {
center.revalidate();
}
if (repaint) {
center.repaint();
}
}
private JPanel getFiller() {
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createLineBorder(Color.blue, 5));
panel.setBackground(Color.red);
panel.setPreferredSize(new Dimension(50, 50));
return panel;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new ValidateRevalidateRepaint();
}
});
}
}